根据纬度和经度列表计算的中心点与实际略有不同

imd*_*sen 6 c# geocoding latitude-longitude openlayers

我正在使用 C# 计算可用纬度/经度列表的中心纬度/经度并在 OpenLayer 地图上渲染。

我观察到获取中心 lat/lng 的计算会给我带来 lat/lng 的轻微差异。我参考此链接进行计算计算 多个纬度/经度坐标对的中心点

C# 代码:

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);
        }
Run Code Online (Sandbox Code Playgroud)

JavaScript 代码:

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
Run Code Online (Sandbox Code Playgroud)

我用粉色标记渲染 6 个不同的位置,用绿色标记渲染中心。

请参阅下图以获取更多说明。 在此输入图像描述

现在已经绘制了方框以了解实际上不是中心的中心标记(绿色)。我认为它应该位于绿色水平线和垂直线交叉的绿点上。

  • 谁能告诉我,我的中心点计算是否正确?
  • 为什么它不显示在框的中央?

我还添加了标尺来计算中心点。

请帮助我找到实际的解决方案,如果您需要更多详细信息,请告诉我。

DrK*_*och 4

正确的中心实际上取决于中心的定义,有几种可能性:

  1. 人们可能会计算包含所有点的最小矩形,并使用该矩形的中心,就像处理绿线和绿点一样。(这很不寻常)

  2. 人们可能会问哪个点距离所有其他点最近,即找到一个中心点,使得该中心与所有其他点之间的所有距离最小(abs-norm,用于实际问题)

  3. 人们可能会问哪个中心点导致的误差最小,即到所有其他点的最小二次距离(总和) (用于数学、统计等)

您会看到,根据定义,您将必须使用不同的算法并到达不同的中心点

您在问题中显示的算法似乎可以计算 (2.)