有没有办法以编程方式确定应该作为 Bing 地图中心的 GPS 坐标?

Posted

技术标签:

【中文标题】有没有办法以编程方式确定应该作为 Bing 地图中心的 GPS 坐标?【英文标题】:Is there a way to programmatically determine the GPS Coordinate which should serve as the Center of a Bing Map? 【发布时间】:2021-03-15 16:47:57 【问题描述】:

这与我的问题 here 有点相似/相关,但不同之处足以保证一个单独的问题。

当以编程方式将 GPS 坐标数组添加到 Bing 地图时,我想将地图的中心设置为数组中所有 GPS 坐标之间的中点。例如,如果我想展示 Hannibal、Independence、Columbia、Jefferson City 和 St. Louis(都在密苏里州),那么中心应该在哥伦比亚附近。

我想一种方法可能是添加所有纬度并除以标记的位置数(在上述情况下为 5),然后添加所有经度并除以该数字。这两个平均值可以作为中心。

这是计算中心坐标的明智方法,还是有更好的方法?

我想在代码隐藏(在 C# 中)中执行此操作。

更新

这是我对(伪)代码可能是什么的想法:

int locationCount = GetNumberOfLocationsOnMap(currentMap);
double totalLatitude = GetTotalLatitudesOfLocationsOnMap(currentMap);
double totalLongitude = GetTotalLongitudesOfLocationsOnMap(currentMap);
double avgLatitude = totalLatitude div locationCount;
double avgLongitude = totalLongitude div locationCount;
map.Center = avgLatitude, avgLongitude;

如果有更简单和/或更好的方法,我想知道。

更新 2

这行得通,只有一个位置(基于 Duncan Lawler 的回答和链接):

private void Page_Loaded(object sender, RoutedEventArgs e)

    . . .
    SetInitialScene();


private async void SetInitialScene()

    // Set it to Monterey, California
    BasicGeoposition location = new BasicGeoposition();
    location.Latitude = 36.6002; 
    location.Longitude = -121.8947; 
    Geopoint geop = new Geopoint(location);
    await map.TrySetSceneAsync(MapScene.CreateFromLocation(geop));

【问题讨论】:

【参考方案1】:

如果您使用的是 UWP 地图控件,则有一个内置方法可以为您执行此操作。 打电话 MapControl.TrySetSceneAsync(MapScene.CreateFromLocations(yourListOfPointsHere)); https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.controls.maps.mapscene.createfromlocations 它将计算正确的视图并将地图移动到那里。如果您需要知道中心,您可以在 SetScene 调用完成后查询 Center 属性。

【讨论】:

【参考方案2】:

坐标边界框的中心似乎更适合此任务,因为在这种情况下,点可以在更高的缩放级别下适合屏幕。

var latitudes = currentMap.locations.Select(location => location.latitude);
var longitudes = currentMap.locations.Select(location => location.longitude);
centerLatitude = (latitudes.Min() + latitudes.Max()) / 2.0;
centerLongitude = (longitudes.Min() + longitudes.Max()) / 2.0;
map.Center = centerLatitude, centerLongitude;

但请注意靠近两极或经度 180 度附近的坐标,因为最小值和最大值不会提供有效的边界框。计算平均值时也存在同样的问题。

【讨论】:

是的,根据您的用例,抓住边界框的中心将比问题中的方法更好。问题中的方法将为您提供位置的加权平均值,因此如果您在城市中有很多点和一些外围点,它将以城市为中心。 另一件需要注意的事情是取决于您的显示投影,纬度/经度边界框的中心不会是显示区域的中心。例如,常用的网络墨卡托投影在纬度上是非线性的,因此显示的中心不是上纬度和下纬度之间的中点。 @DuncanLawler 好点!在这种情况下,最好将纬度和经度转换为墨卡托投影,然后才计算边界框 这取决于您所说的“中心”。正如其他人所提到的,纬度和经度是球面参考,但地图通常不是。对前者的测试是北纬 80 度和经度 0 和 180 度的两个点应该是北极(纬度 90 度)。但这可能不是你想要的。 那不适合我。我的地图名称只是“地图”,没有“位置”成员。可能是因为我的应用是 UWP?【参考方案3】:

如果您想让地图显示所有 GPS 点,则需要缩放级别才能与中心一致。缩放级别与地图的宽度和高度直接相关。这是我的旧代码示例中的代码块:

/// <summary>
/// Calculates the best map view for a list of locations for a map
/// </summary>
/// <param name="locations">List of location objects</param>
/// <param name="mapWidth">Map width in pixels</param>
/// <param name="mapHeight">Map height in pixels</param>
/// <param name="buffer">Width in pixels to use to create a buffer around the map. This is to keep pushpins from being cut off on the edge</param>
public static MapViewSpecification BestMapView(IList<Location> locations, double mapWidth, double mapHeight, int buffer, out double centerLat, double centerLon, out double zoomLevel )

    double zoomLevel = 0;

    double maxLat = -85;
    double minLat = 85;
    double maxLon = -180;
    double minLon = 180;

    //calculate bounding rectangle
    for (int i = 0; i < locations.Count; i++)
    
        if (locations[i].Latitude > maxLat)
        
            maxLat = locations[i].Latitude;
        

        if (locations[i].Latitude < minLat)
        
            minLat = locations[i].Latitude;
        

        if (locations[i].Longitude > maxLon)
        
            maxLon = locations[i].Longitude;
        

        if (locations[i].Longitude < minLon)
        
            minLon = locations[i].Longitude;
        
    

    centerLat = (maxLat + minLat) / 2;
    centerLon = (maxLon + minLon) / 2;

    double zoom1=0, zoom2=0;

    //Determine the best zoom level based on the map scale and bounding coordinate information
    if (maxLon != minLon && maxLat != minLat)
    
        //best zoom level based on map width
        zoom1 = Math.Log(360.0 / 256.0 * (mapWidth – 2*buffer) / (maxLon – minLon)) / Math.Log(2);
        //best zoom level based on map height
        zoom2 = Math.Log(180.0 / 256.0 * (mapHeight – 2*buffer) / (maxLat – minLat)) / Math.Log(2);
    

    //use the most zoomed out of the two zoom levels
    zoomLevel = (zoom1 < zoom2) ? zoom1 : zoom2;

【讨论】:

到达centerLat和centerLon后,map.Center如何分配? (假设“地图”是 Bing 地图的名称)。像这样:位置中心; center.latitude = centerLat; center.longitude = centerLon; map.SetView(center, zoomLevel); ?

以上是关于有没有办法以编程方式确定应该作为 Bing 地图中心的 GPS 坐标?的主要内容,如果未能解决你的问题,请参考以下文章

确定给定地图中的投影

有没有办法以编程方式确定字体文件是不是具有特定的 Unicode 字形?

在 OS X 中以编程方式打开地图应用

以编程方式查找机器上的内核数

在 bing 地图中查找相邻图块

有没有办法确定用户当前的地图查看区域?