有没有办法以编程方式确定应作为 Bing 地图中心的 GPS 坐标?
Is there a way to programmatically determine the GPS Coordinate which should serve as the Center of a Bing Map?
这有点 similar/related 我的问题 ,但差异足以保证单独的问题。
当以编程方式将 GPS 坐标数组添加到 Bing 地图时,我想将地图的中心设置为数组中所有 GPS 坐标之间的中点。例如,如果我想展示汉尼拔、独立城、哥伦比亚、杰斐逊城和圣路易斯(都在密苏里州),中心应该在哥伦比亚附近。
我想这样做的一种方法可能是将所有纬度相加并除以标记位置的数量(在上述情况下为 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;
如果有更简单的and/or更好的方法,我很想知道。
更新 2
这有效,只有一个位置(基于 Duncan Lawler 的回答和 link):
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));
}
似乎坐标边界框的中心更适合此任务,因为在这种情况下点可以在更高的缩放级别适合屏幕。
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 度经度的坐标,因为最小值和最大值不会提供有效的边界框。当您计算平均值时也存在同样的问题。
如果您想让您的地图显示所有 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;
}
如果您使用的是 UWP 地图控件,则有一个内置方法可以为您执行此操作。
只需打电话
MapControl.TrySetSceneAsync(MapScene.CreateFromLocations(你的点数列表));
https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.controls.maps.mapscene.createfromlocations
它将计算正确的视图并将地图移动到那里。如果您需要知道中心,您可以在 SetScene 调用完成后查询中心 属性。
这有点 similar/related 我的问题
当以编程方式将 GPS 坐标数组添加到 Bing 地图时,我想将地图的中心设置为数组中所有 GPS 坐标之间的中点。例如,如果我想展示汉尼拔、独立城、哥伦比亚、杰斐逊城和圣路易斯(都在密苏里州),中心应该在哥伦比亚附近。
我想这样做的一种方法可能是将所有纬度相加并除以标记位置的数量(在上述情况下为 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;
如果有更简单的and/or更好的方法,我很想知道。
更新 2
这有效,只有一个位置(基于 Duncan Lawler 的回答和 link):
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));
}
似乎坐标边界框的中心更适合此任务,因为在这种情况下点可以在更高的缩放级别适合屏幕。
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 度经度的坐标,因为最小值和最大值不会提供有效的边界框。当您计算平均值时也存在同样的问题。
如果您想让您的地图显示所有 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;
}
如果您使用的是 UWP 地图控件,则有一个内置方法可以为您执行此操作。 只需打电话 MapControl.TrySetSceneAsync(MapScene.CreateFromLocations(你的点数列表)); https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.controls.maps.mapscene.createfromlocations 它将计算正确的视图并将地图移动到那里。如果您需要知道中心,您可以在 SetScene 调用完成后查询中心 属性。