(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
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.
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: