问题
I am calculating center Lat/Lng fron list of available Lat/Lng using C# and rendering on OpenLayer Map.
I observed the calculation of getting center lat/lng will give me slightly difference in lat/lng. I am referring this link for the calculation Calculate the center point of multiple latitude/longitude coordinate pairs.
C# Code:
static void Main(string[] args)
{
List<GeoCoordinate> listCoordinate = new List<GeoCoordinate>();
listCoordinate.Add(new GeoCoordinate() { Latitude = 22.9833, Longitude = 72.5000 }); //Sarkhej
listCoordinate.Add(new GeoCoordinate() { Latitude = 18.9750, Longitude = 72.8258 }); //Mumbai
listCoordinate.Add(new GeoCoordinate() { Latitude = 22.3000, Longitude = 73.2003 }); //Vadodara
listCoordinate.Add(new GeoCoordinate() { Latitude = 26.9260, Longitude = 75.8235 }); //Jaipur
listCoordinate.Add(new GeoCoordinate() { Latitude = 28.6100, Longitude = 77.2300 }); //Delhi
listCoordinate.Add(new GeoCoordinate() { Latitude = 22.3000, Longitude = 70.7833 }); //Rajkot
GeoCoordinate centerCoordinate = GetCentralGeoCoordinate(listCoordinate); //Output (Latitude:23.696708071960074, Longitude:73.681549202080149)
Console.WriteLine("Lat:" + centerCoordinate.Latitude + ",Lon:" + centerCoordinate.Longitude);
Console.ReadKey();
}
public static GeoCoordinate GetCentralGeoCoordinate(List<GeoCoordinate> geoCoordinates)
{
if (geoCoordinates.Count == 1)
{
return geoCoordinates.Single();
}
double x = 0, y = 0, z = 0;
foreach (var geoCoordinate in geoCoordinates)
{
var latitude = geoCoordinate.Latitude * Math.PI / 180;
var longitude = geoCoordinate.Longitude * Math.PI / 180;
x += Math.Cos(latitude) * Math.Cos(longitude);
y += Math.Cos(latitude) * Math.Sin(longitude);
z += Math.Sin(latitude);
}
var total = geoCoordinates.Count;
x = x / total;
y = y / total;
z = z / total;
var centralLongitude = Math.Atan2(y, x);
var centralSquareRoot = Math.Sqrt(x * x + y * y);
var centralLatitude = Math.Atan2(z, centralSquareRoot);
return new GeoCoordinate(centralLatitude * 180 / Math.PI, centralLongitude * 180 / Math.PI);
}
Javascrip Code:
var arrLonLat = [
{'Lon' : 72.5000, 'Lat' : 22.9833},
{'Lon' : 72.8258, 'Lat' : 18.9750},
{'Lon' : 73.2003, 'Lat' : 22.3000},
{'Lon' : 75.8235, 'Lat' : 26.9260},
{'Lon' : 77.2300, 'Lat' : 28.6100},
{'Lon' : 70.7833, 'Lat' : 22.3000}];
var centerLonLat = getCenterLonLat(arrLonLat);
var lonLatSarkhej = new OpenLayers.LonLat(arrLonLat[0].Lon,arrLonLat[0].Lat).transform(epsg4326,projectTo);
var lonLatMumbai = new OpenLayers.LonLat(arrLonLat[1].Lon,arrLonLat[1].Lat).transform(epsg4326,projectTo);
var lonLatVadodara = new OpenLayers.LonLat(arrLonLat[2].Lon,arrLonLat[2].Lat).transform(epsg4326,projectTo);
var lonLatJaipur = new OpenLayers.LonLat(arrLonLat[3].Lon,arrLonLat[3].Lat).transform(epsg4326,projectTo);
var lonLatDelhi = new OpenLayers.LonLat(arrLonLat[4].Lon,arrLonLat[4].Lat).transform(epsg4326,projectTo);
var lonLatRajkot = new OpenLayers.LonLat(arrLonLat[5].Lon,arrLonLat[5].Lat).transform(epsg4326,projectTo);
//Center Point of Average Markers
var lonLatCenter = new OpenLayers.LonLat(73.681549202080149,23.696708071960074).transform(epsg4326,projectTo);
var markers = new OpenLayers.Layer.Markers("Markers");
map.addLayer(markers);
var size = new OpenLayers.Size(24,24);
var offset = new OpenLayers.Pixel(-(size.w/2), -size.h);
var icon = new OpenLayers.Icon('icon/Marker-Pink.png', size, offset);
var iconCenter = new OpenLayers.Icon('icon/Marker-Green.png', size, offset);
markers.addMarker(new OpenLayers.Marker(lonLatSarkhej,icon)); //Sarkhej
markers.addMarker(new OpenLayers.Marker(lonLatMumbai,icon.clone())); //Mumbai
markers.addMarker(new OpenLayers.Marker(lonLatVadodara,icon.clone())); //Vadodara
markers.addMarker(new OpenLayers.Marker(lonLatJaipur,icon.clone())); //Jaipur
markers.addMarker(new OpenLayers.Marker(lonLatDelhi,icon.clone())); //Delhi
markers.addMarker(new OpenLayers.Marker(lonLatRajkot,icon.clone())); //Rajkot
I am rendering 6 different location with Pink marker, and center with Green marker.
Please see below image for more clarification.
Now have drawn box to get idea about the center marker (Green) which is not actually center. I think it should be positioned on Green dot which is crossed by green Horizontal and Vertical line.
- Can anybody let me know, does my center point is calculated correctly or not?
- Why it is not display at center of the box?
I have also added Ruler for calculation of center point.
Please help me to find the actual solution, please do let me know if you need more details for the same.
回答1:
The correct center depends actually on the definition for center and there are several possibilites:
One might calculate the smallest rectangle containing all points and use the center of this rectangle as you did with your green lines and green point. (This is unusual)
One might ask which point is closest to all other points, i.e. find a center point so that all distances between this center and all other points are smallest (abs-norm, used for practical problems)
One might ask which center point results in the least error, i.e. the smallest (sum of) quadratic distances to all other points (used ins math, statistics, etc)
You see, depending on the definition, you'll have to use a different algorithm and will arrive on a different center point.
The algorithm you show in your question seems to calculate (2.)
来源:https://stackoverflow.com/questions/28315027/calculation-of-center-point-from-list-of-latitude-and-longitude-are-slightly-dif