I need to be able to take a set of lat/lon coordinates and draw a circular "fence" around those coordinates on a map, where the number of points in the circular shape and the radius of the circle are both configurable. My goal is to be able to input the point, the radius of the shape and the number of points I would like it to have and to receive an output containing a List of lat/long coordinates that would complete a shape around the center point if connected.
I've been able to come up with a workable solution that does most of what I need it to, but there are a few things about it that don't work how I expect, and my understanding of the underlying mathematics is weak enough that I'm not sure how to resolve them.
I referenced this post from CSharpHelper to produce the points in a circle around my starting point, and math from this StackOverflow answer to try and convert my miles radius to degrees Lat and Long. Here is the code that I have so far:
public readonly struct LocationPoint
{
public LocationPoint(double lat, double lon)
{
Lat = lat;
Lon = lon;
}
public double Lat { get; }
public double Lon { get; }
}
private static List<LocationPoint> GetZoneCoordinates(LocationPoint center,
double radiusInMiles,
int numberOfPoints)
{
// Convert input miles to degrees latitude and longitude.
var radiusKm = radiusInMiles * 0.621371;
var radiusLon = 1 / (111.319 * Math.Cos(center.Lat)) * radiusKm;
var radiusLat = 1 / 110.574 * radiusKm;
// Calculate amount to increment angle for number of points.
var dTheta = 2 * Math.PI / numberOfPoints;
double theta = 0;
// Produce points.
var points = new List<LocationPoint>();
for (var i = 0; i < numberOfPoints; i++)
{
points.Add(new LocationPoint
(
center.Lat + radiusLat * Math.Sin(theta),
center.Lon + radiusLon * Math.Cos(theta)
));
theta += dTheta;
}
return points;
}
The code above works well to create a circular shape with the number of points that I give it. I'll use a center point at JFK International as an example. If I run the above with a radius of .5 miles and 8 points, I get a set of coordinates that map out to the following points:
There are two things wrong with this shape:
- It's a vertical ellipse (though I'm not sure if this is actually a problem, might just be the result of mapping on a sphere and displaying on a 2D map)
- The actual radius is much smaller than my input. I in put a radius of .5 miles for the above set of points, and the diameter from right to left is actually closer to .25 miles.
What am I doing wrong here?