从纬度和经度列表计算中心点的方法与实际略有不同。

6

我将使用C#计算可用Lat/Lng列表的中心点并在OpenLayer地图上呈现。

我注意到获取中心点Lat/Lng的计算会给我略微不同的Lat/Lng。我参考了这个链接进行计算 Calculate the center point of multiple latitude/longitude coordinate pairs.

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);
        }

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

我正在使用粉色标记渲染6个不同的位置,并使用绿色标记作为中心。

请查看下面的图片以获得更多的解释。 enter image description here

现在,我已经画了一个框来了解中心标记(绿色)的位置,但它实际上并不是中心。我认为它应该位于被绿色水平和垂直线穿过的绿点上。

  • 有人能告诉我,我的中心点是否计算正确吗?
  • 为什么它没有显示在框的中心位置?

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

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


Imdadhusen,你最终使用的公式代码是什么? - Depechie
1个回答

4
正确的“中心”实际上取决于“中心”的定义,有几种可能:
1. 可以计算包含所有点的最小矩形,并使用该矩形的中心作为您在绿线和绿点中所做的那样(这很不寻常)。 2. 可以询问哪个点最接近所有其他点,即找到一个中心点,使得该中心点与所有其他点之间的距离都最小(绝对值范数,用于实际问题)。 3. 可以询问哪个中心点会导致最小误差,即与所有其他点的(总和)二次距离最小(用于数学、统计等)。
您看,根据定义,您将不得不使用不同的算法,并到达不同的“中心”点。
您在问题中展示的算法似乎计算了(2.)。

非常感谢您的澄清。 - imdadhusen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接