【问题标题】:Can I adjust my Bing Map's View/LocationRect/Bounding Box by a small amount?我可以少量调整我的 Bing 地图视图/位置矩形/边界框吗?
【发布时间】:2015-01-12 06:42:14
【问题描述】:

我正在使用此代码:

photraxMap.SetView(new LocationRect(App.photosetLocationCollection));

...缩放地图以显示包含在 photosetLocationCollection 中的位置列表。

photraxMap 是一个 BingMap。 SetView() 是 Bing Maps 方法,不是我自己的自定义方法。

问题在于它很好地工作 - 它显示了所有标记/图钉,但只是勉强 - 正如您在此处看到的那样,极端位置被“剪裁”了:

在尖叫声中,您可以看到圣安地列斯以北的图钉以及位于地图东南边缘的哥伦比亚的图钉被部分遮挡(Pardee 的图钉也被地图类型部分遮挡)框,但我认为这无济于事)。

我希望他们有一点“回旋余地”。这不仅仅是一个表面问题——“异常值”图钉在您向上或向下或向左或向右拖动一点点之前是无法选择的。

有没有办法将缩放级别调整到只有很小的一点(而不是更高的完整缩放级别)?

更新

根据下面答案中的想法,我想我会尝试这样的事情:

// Adapted from Brundritt and Boonaert: http://stackoverflow.com/questions/26937358/can-i-adjust-my-bing-maps-view-locationrect-bounding-box-by-a-small-amount
// Before passing the locations to set view, call this twice, to add bogus NW and SE locations that will stretch 
// the viewable area of the map a little, like so:
// Location nwShim = GetAShimLocation(locs, true);
// Location seShim = GetAShimLocation(locs, false);
// locs.Add(nwShim); locs.Add(seShim);
public static Location GetAShimLocation(IList<Location> locations, bool IsForNorthwestCorner)
{
    const int MAP_CUSHION = 1; // Is 1 a comfortable enough cushion?
    // I don't know why the Lats are 85 instead of 90
    double maxLat = -85;
    double minLat = 85;
    double maxLon = -180;
    double minLon = 180;

    foreach (Location loc in locations)
    {
        if (loc.Latitude > maxLat)
        {
            maxLat = loc.Latitude;
        }

        if (loc.Latitude < minLat)
        {
            minLat = loc.Latitude;
        }

        if (loc.Longitude > maxLon)
        {
            maxLon = loc.Longitude;
        }

        if (loc.Longitude < minLon)
        {
            minLon = loc.Longitude;
        }
    }

    Location retLoc = new Location();
    // I'm not sure this logic/math is right - test it later
    if (IsForNorthwestCorner)
    {
        retLoc.Latitude = maxLat - MAP_CUSHION;
        retLoc.Longitude = maxLon - MAP_CUSHION;
    }
    else // SouthEast corner - stretch a little both directions
    {
        retLoc.Latitude = minLat + MAP_CUSHION;
        retLoc.Longitude = minLon + MAP_CUSHION;
    }
}

【问题讨论】:

    标签: c# bing-maps pushpin


    【解决方案1】:

    您可以使用一组位置来创建图钉,并将它们传递到 Microsoft.Maps.LocationRect 类的 fromLocations 函数中。此函数将返回一个 LocationRect,其中包含传递给它的所有 Location 对象。然后可以在设置地图视图时将此 LocationRect 传递给边界设置属性。一些开发人员可能会注意到,这会导致地图边缘的一些图钉被切断。原因是 fromLocations 函数仅根据 Location 对象计算边界框,而不是图钉图标使用的附加区域。为了适应这种情况,可以使用填充设置将视图缓冲指定数量的像素。通常将此值设置为图钉图标宽度/高度的两倍效果很好。 source

    var locs = [array of Microsoft.Maps.Location];
    var rect = Microsoft.Maps.LocationRect.fromLocations(locs);
    
    map.setView({ bounds: rect, padding: 80 });
    

    等等! :)

    【讨论】:

    • 附带说明,我发现使用map.setView() 以使填充起作用很重要。在地图构造方法中设置填充似乎对我不起作用。
    【解决方案2】:

    为了做到这一点,你至少有两个我正在考虑的选择。

    • 第一种选择:使用虚假位置

    您选择将在最大/最小位置添加或检索的任意填充(纬度和经度的增量),然后使用 SetView() 设置图钉上的视图以及允许的其他添加位置超过您的缩放级别或正确设置视图以显示您的所有项目。

    要改进此技术,您可以根据图钉的像素大小和地图的分辨率计算地图的分辨率以及相应的纬度增量和经度增量。

    • 第二个选项:手动计算最佳视图

    对于第二个,我建议您阅读 Ricky 不久前分享的内容,自己看看:http://rbrundritt.wordpress.com/2009/07/21/determining-best-map-view-for-an-array-of-locations/

    你需要修改的代码在这里(因为链接的答案不适合 StackOverflow):

       /// <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>
    /// <returns>Returns a MapViewSpecification with the best map center point and zoom level for the given set of locations</returns>
    public static MapViewSpecification BestMapView(IList<Location> locations, double mapWidth, double mapHeight, int buffer)
    {
        MapViewSpecification mapView;
        Location center = new Location();
        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;
            }
        }
    
        center.Latitude = (maxLat + minLat) / 2;
        center.Longitude = (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;
    
        mapView = new MapViewSpecification(center, zoomLevel);
    
        return mapView;
    }
    

    如果您发现任何困难,请告诉我们,我相信我们能够为您提供一点帮助。

    • 还有一个帮助:

    另外,我发现了我写的关于带填充的最佳地图视图的旧代码,我无法将整个上下文发送给你,但你会明白的:

    //Determine the best zoom level based on the map scale and bounding coordinate information
    if ((mapView.Bounds.SouthEast.Longitude != mapView.Bounds.NorthWest.Longitude) &&
        (mapView.Bounds.NorthWest.Latitude != mapView.Bounds.SouthEast.Latitude))
    {
        Padding padding = mapView.Padding;
    
        //best zoom level based on map width
        zoom1 = (Math.Log(360.0 / 256.0 * (mapView.MapSize.Width - (padding.Left + padding.Right)) / (mapView.Bounds.SouthEast.Longitude - mapView.Bounds.NorthWest.Longitude)) / Math.Log(2));
        //best zoom level based on map height
        zoom2 = Math.Log(180.0 / 256.0 * (mapView.MapSize.Height - (padding.Top + padding.Bottom)) / (mapView.Bounds.NorthWest.Latitude - mapView.Bounds.SouthEast.Latitude)) / Math.Log(2);
    }
    
    //use the most zoomed out of the two zoom levels
    mapView.ZoomLevel = (int)Math.Floor((zoom1 < zoom2) ? zoom1 : zoom2);
    

    【讨论】:

    • 假设“mapView”是 Bing 地图的名称,我没有可用的 MapSize 属性...
    • MapView 是一种自定义实体,具有 MapSize 或 Padding 等自定义属性。它是一个实体,用于描述您希望获得的最终结果。
    • 是的,它是我自己创建的一个类。如果需要,我将使用自定义类更新我的代码。
    • 不用担心 - 我在这里的相关问题上得到了很好的答案/解决方案:stackoverflow.com/questions/26948104/…
    【解决方案3】:

    一个更简单的解决方案是在使用 Maps.setview 之后缩放 maps.zoomlevel

    bingMap.SetView(New LocationRect(locList))
    bingMap.ZoomLevel = bingMap.ZoomLevel * 0.85
    

    .85 表示缩小 15%

    附言我正在使用 vb.net btw 但它是相同的概念

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多