Can I adjust my Bing Map's View/LocationRect/Bounding Box by a small amount?

我与影子孤独终老i 提交于 2019-12-05 19:20:29
Nicolas Boonaert

In order to do this, you have at least two options that I'm thinking about.

  • First option: using fake locations

You choose an arbitrary padding (delta in latitude and longitude) that you will add or retrieve on the maximum/minimum location then you use SetView() to set the view on your pushpins as well as the other added locations that will permit to exceed your zoom level or set the view correctly to display all of you items.

To improve this technique, you can calculate the map's resolution and the corresponding delta for latitude and delta for longitude based on the size in pixel of your pushpins and the map's resolution.

  • Second option: manually calculating the best view

For this second one, I suggest you take a read at what Ricky shared a while back now, see for yourself: http://rbrundritt.wordpress.com/2009/07/21/determining-best-map-view-for-an-array-of-locations/

The code you will need to adapt is here (because answer with links are not good for 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;
}

If you find any difficulty, let us know, I'm sure we'll be able to help you a little bit.

  • Yet another help:

Also, I found an old code that I wrote regarding the best mapview with padding, I can't send you the whole context but you'll get the idea:

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

An Easier solution to this would be to scale the maps.zoomlevel after using Maps.setview

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

the .85 means to zoom out 15%

p.s. I am using vb.net btw but it is the same concept

You can use an array of locations used to create the Pushpins, and pass them into the fromLocations function on the Microsoft.Maps.LocationRect class. This function will return a LocationRect that encloses all the Location objects passed into it. This LocationRect can then be passed to the bounds setting property when setting the map view. Some developers may notice that this results in some pushpins being cut off at the maps edge. The reason for this is that the fromLocations function only calculates the bounding box based on the Location objects, and not on the additional area that the pushpin icons use. To accommodate this scenario, the padding setting can be used to buffer the view by a specified number of pixels. Generally setting this value to twice as large as the width/height of your pushpin icons works well. source

var locs = [array of Microsoft.Maps.Location];
var rect = Microsoft.Maps.LocationRect.fromLocations(locs);

map.setView({ bounds: rect, padding: 80 });

Et voilà ! :)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!