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

时间:2015-02-04 06:42:20

标签: c# openlayers geocoding latitude-longitude

我正在使用C#计算可用Lat / Lng的中心Lat / Lng前端列表并在OpenLayer Map上渲染。

我观察到获得中心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);
        }

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

我使用粉红色标记渲染6个不同的位置,并以绿色标记居中。

请参阅下图以获得更多说明。 enter image description here

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

  • 任何人都可以告诉我,我的中心点是否正确计算 不是吗?
  • 为什么它不显示在盒子的中央?

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

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

1 个答案:

答案 0 :(得分:2)

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

  1. 可以计算包含所有点的最小矩形 像使用绿线一样使用此矩形的中心 和绿点。 (这很不寻常)

  2. 有人可能会问哪个点最接近到所有其他点,即 找到一个中心点,以便在此中心和之间所有距离 所有其他点都是最小的(绝对范数,用于实际 问题)

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

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

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