D3 Topojson Circle with Radius Scaled in Miles

后端 未结 1 480
我在风中等你
我在风中等你 2021-01-27 05:03

(assuming existing projection/topojson)

What I\'m trying to do is create a circle at a point ([long,lat]) of radius (r) in miles. I know there is a d3.geo function for t

相关标签:
1条回答
  • 2021-01-27 05:36

    Why not use the built-in circle generator d3.geoCircle()?

    Returns a new GeoJSON geometry object of type “Polygon” approximating a circle on the surface of a sphere, with the current center, radius and precision. Any arguments are passed to the accessors.

    The only task left to you is to calculate the radius of the circle in degrees. Because earth is not a perfect sphere this can become quite challenge of its own. But for many applications an approximation will suffice. Taking just the mean radius of 3,958 mi into account, the calculations can be written as:

    var EARTH_RADIUS = 3959;                         // mean radius in miles
    var radiusMi     = 5;                            // radius to be drawn in miles
    var radiusDeg    = radiusMi / EARTH_RADIUS * 90; // radius in degrees for circle generator
    

    This can then be passed to the circle generator:

    var circle = d3.geoCircle().radius(radiusDeg);
    

    Finally, the circle generator is used to pass its output via data binding to an appropriate path generator taking into account the projection:

    svg.append("path")
      .datum(circle)
        .attr("d", path);
    

    Have a look at this Block which features circles of 50 miles radius each at various positions around the globe. The circle generator in combination with the projection will take control of the correct sizing and the correct appearance of the circle.


    D3 v3

    If you are still stuck to D3 v3 the example works as well. However, you need to adjust the names accordingly:

    • d3.geo.circle ↦ d3.geoCircle

    In addition to that, some of the circle generator's methods have been renamed:

    • circle.origin() ↦ circle.center()
    • circle.angle() ↦ circle.radius()

    Applying those adjustments to my above linked Block, this works for v3 just as well: v3 Block.


    This approach gets to play to its strengths when it comes to unusual projections having severe distortions. Just by changing the projection in the Block to d3.geoGnomonic() this becomes easily visible. The following screenshot from the updated Block still shows the same circles as above having a radius of 50 miles each:

    0 讨论(0)
提交回复
热议问题