Я использую этот код:
photraxMap.SetView(new LocationRect(App.photosetLocationCollection));
... чтобы увеличить карту, чтобы отобразить список местоположений, содержащийся в photosetLocationCollection.
photraxMap - это BingMap. SetView() - это метод Bing Maps, а не мой собственный метод.
Проблема в том, что он работает слишком хорошо - он отображает все маркеры/кнопки, но едва ли - крайние места "обрезаны", как вы можете видеть здесь:
В крикшоте вы можете видеть, что кандагар к северу от Сан-Андреаса, а также тот, который находится в Колумбии, на юго-восточном краю карты, частично затушеваны (тот, который у Парди также частично скрыт, в окне "Тип карты", но Я считаю, что это не поможет).
Я хочу, чтобы у них была небольшая "комната для маневра". Это не просто косметическая проблема - кнопки "outlier" не выбираются, пока вы не перетащите карту вверх или вниз или влево или вправо.
Есть ли способ настроить уровень масштабирования только на битве с мягким мышлением (не полный уровень увеличения выше)?
Основываясь на идеях в ответе ниже, я думаю, что я попробую что-то вроде этого:
// 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;
}
}
Для этого у вас есть как минимум два варианта, о которых я думаю.
Вы выбираете произвольное заполнение (дельта в широте и долготе), которое вы добавите или получите в максимальном/минимальном месте, затем вы используете SetView(), чтобы установить вид на ваших клавишах, а также другие добавленные местоположения, которые позволят превысить ваши масштабирования или правильно настроить отображение всех элементов.
Чтобы улучшить эту технику, вы можете рассчитать разрешение карты и соответствующую дельта для широты и дельта для долготы на основе размера в пикселях ваших кнопок и разрешения карты.
Для этой второй, я предлагаю вам прочитать, что Рики поделилось некоторое время назад, убедитесь сами: http://rbrundritt.wordpress.com/2009/07/21/determining-best-map-view-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;
}
Если вы найдете какие-либо трудности, сообщите нам, я уверен, что мы сможем вам немного помочь.
Кроме того, я нашел старый код, который я написал относительно наилучшего 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);
Более простым решением для этого было бы масштабирование maps.zoomlevel после использования Maps.setview
bingMap.SetView(New LocationRect(locList))
bingMap.ZoomLevel = bingMap.ZoomLevel * 0.85
.85 означает уменьшение 15%
ps Я использую vb.net btw, но это та же концепция
Вы можете использовать массив местоположений, используемых для создания 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 });
И вуаля ! :)