Могу ли я немного откорректировать вид / расположение 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, кстати, но это та же концепция