Могу ли я немного откорректировать вид / расположение Rect/Bounding Box моей карты Bing?

Я использую этот код:

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

... чтобы увеличить карту, чтобы показать список местоположений, содержащихся в photosetLocationCollection.

PhotraxMap является BingMap. SetView () - это метод Bing Maps, а не мой собственный метод.

Проблема в том, что он работает слишком хорошо - он показывает все маркеры / кнопки, но едва ли - крайние места "обрезаны", как вы можете видеть здесь:

На скриншоте видно, что канцелярская кнопка к северу от Сан-Андреаса, а также кнопка в Колумбии, на юго-восточном краю карты, частично скрыты (та, что в Парди, также частично скрыта полем Тип карты, но Я считаю, что ничего не поделаешь).

Я хочу, чтобы у них была небольшая "комната для маневра". Это не просто косметическая проблема - "выпадающие" кнопки не могут быть выбраны, пока вы не перетащите карту вверх или вниз или влево или вправо.

Есть ли способ подстроить уровень масштабирования всего лишь чуть-чуть (а не полный уровень масштабирования выше)?

ОБНОВИТЬ

Основываясь на идеях в ответе ниже, я думаю, что попробую что-то вроде этого:

// Adapted from Brundritt and Boonaert: http://stackru.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;
    }
}

2 ответа

Решение

Для этого у вас есть как минимум два варианта, о которых я думаю.

  • Первый вариант: использование поддельных локаций

Вы выбираете произвольный отступ (дельта по широте и долготе), который добавляете или извлекаете в максимальном / минимальном местоположении, затем вы используете SetView(), чтобы установить вид на свои кнопки, а также другие добавленные местоположения, которые позволят превысить ваш Уровень масштабирования или установите вид правильно, чтобы отобразить все элементы.

Чтобы улучшить эту технику, вы можете рассчитать разрешение карты и соответствующую дельту для широты и дельту для долготы на основе размера в пикселях ваших кнопок и разрешения карты.

  • Второй вариант: вручную рассчитать лучший вид

В этом втором выпуске я предлагаю вам ознакомиться с тем, чем Рики поделился некоторое время назад, посмотрите сами: http://rbrundritt.wordpress.com/2009/07/21/determining-best-map-view-for-an-array-of-locations/

Код, который вам нужно будет адаптировать, находится здесь (потому что ответ со ссылками не подходит для Stackru):

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

Вы можете использовать массив местоположений, используемых для создания Pushpins, и передать их в функцию fromLocations класса Microsoft.Maps.LocationRect. Эта функция вернет LocationRect, который включает все переданные в него объекты Location. Затем этот LocationRect может быть передан свойству настройки границ при настройке вида карты. Некоторые разработчики могут заметить, что в результате некоторые кнопки срезаются по краю карты. Причина в том, что объект fromLocations Функция вычисляет ограничивающую рамку только на основе объектов Location, а не на дополнительной области, которую используют значки кнопок. Чтобы приспособиться к этому сценарию, настройку заполнения можно использовать для буферизации вида на указанное количество пикселей. Обычно установка этого значения в два раза больше ширины / высоты ваших значков кнопок работает хорошо. источник

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

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

И вуаля!:)

Более простым решением для этого было бы масштабирование maps.zoomlevel после использования Maps.setview

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

.85 означает уменьшить 15%

PS Я использую vb.net, кстати, но это та же концепция

Другие вопросы по тегам