Центр / Установить масштаб карты, чтобы покрыть все видимые маркеры?

352

Я устанавливаю несколько маркеров на своей карте, и я могу статически устанавливать уровни масштабирования и центр, но я хочу, чтобы охватить все маркеры и максимально увеличить масштаб, чтобы были видны все рынки.

Доступны следующие методы

setZoom(zoom:number)

а также

setCenter(latlng:LatLng)

Не setCenterподдерживает множественный ввод или ввод массива Location, а также setZoomне имеет такой функциональности

введите описание изображения здесь

Trikaldarshi
источник
Вы должны добавлять объект latlngк boundsобъекту каждый раз, когда добавляете маркер и настраиваете свою карту в соответствии с конечными границами. Смотрите ответ здесь: stackoverflow.com/questions/1556921/…
Суви Виньяраджа

Ответы:

678

Вам нужно использовать fitBounds()метод.

var markers = [];//some array
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < markers.length; i++) {
 bounds.extend(markers[i]);
}

map.fitBounds(bounds);

Документация от developers.google.com/maps/documentation/javascript :

fitBounds(bounds[, padding])

Параметры:

`bounds`:  [`LatLngBounds`][1]|[`LatLngBoundsLiteral`][1]
`padding` (optional):  number|[`Padding`][1]

Возвращаемое значение: Нет

Устанавливает область просмотра, чтобы содержать данные границы.
Примечание . Когда для карты установлено значение display: none, fitBoundsфункция считывает размер карты как 0x0и, следовательно, ничего не делает. Чтобы изменить область просмотра, пока карта скрыта, установите карту на visibility: hidden, тем самым гарантируя, что div карты имеет фактический размер.

Адам
источник
3
Откуда появился этот getPositionметод?
Pratheep
6
@Pratheep - это часть класса google.maps.Marker; developers.google.com/maps/documentation/javascript/…
Адам
Работал как шарм! Спасибо
Джозеф Н.
9
Точно так же, как и для новичков, с тем же вопросом, что и Pratheep ... Вы знаете это, если у вас есть опыт работы с API Карт, но вы всегда можете передать LatLngLiteralвместо того, чтобы иметь экземпляр Marker. например, bounds.extend({lat: 123, lng: 456}).
Кайл Бейкер
1
Дополнительный совет для всех, кто заинтересован. Вы можете определить отступ, используя fitBounds(bounds, int)который позволит вам иметь небольшое пространство между маркерами и краями карты (или меньше места, если вам нужно). См. Документацию
МайклсонМайкл
178

Чтобы расширить данный ответ несколькими полезными приемами:

var markers = //some array;
var bounds = new google.maps.LatLngBounds();
for(i=0;i<markers.length;i++) {
   bounds.extend(markers[i].getPosition());
}

//center the map to a specific spot (city)
map.setCenter(center); 

//center the map to the geometric center of all markers
map.setCenter(bounds.getCenter());

map.fitBounds(bounds);

//remove one zoom level to ensure no marker is on the edge.
map.setZoom(map.getZoom()-1); 

// set a minimum zoom 
// if you got only 1 marker or all markers are on the same address map will be zoomed too much.
if(map.getZoom()> 15){
  map.setZoom(15);
}

//Alternatively this code can be used to set the zoom for just 1 marker and to skip redrawing.
//Note that this will not cover the case if you have 2 markers on the same address.
if(count(markers) == 1){
    map.setMaxZoom(15);
    map.fitBounds(bounds);
    map.setMaxZoom(Null)
}

ОБНОВЛЕНИЕ:
Дальнейшие исследования в этой теме показывают, что fitBounds () является асинхронным, и лучше всего выполнять манипуляции с масштабированием с помощью определенного слушателя перед вызовом Fit Bounds.
Спасибо @Tim, @ xr280xr, больше примеров по теме: SO: setzoom-after-fitbounds

google.maps.event.addListenerOnce(map, 'bounds_changed', function(event) {
  this.setZoom(map.getZoom()-1);

  if (this.getZoom() > 15) {
    this.setZoom(15);
  }
});
map.fitBounds(bounds);
d.raev
источник
4
Хорошие дополнения. Спасибо!
paneer_tikka
1
Я получил неопределенное возвращено .getZoom (). Этот ответ помог мне решить эту проблему, используя addListenerOnceon, zoom_changedчтобы установить масштаб после того, как его значение было инициализировано.
xr280xr
1
Спасибо @ d.raev, но установка максимального увеличения, когда границы уже установлены, не работает. Что вы должны сделать, это установить параметр «maxZoom» при инициализации карты. developers.google.com/maps/documentation/javascript/… ..
Тим
1
В части о манипуляциях с масштабированием ( ОБНОВЛЕНИЕ ) вы смешиваете пару переменных и областей видимости. Вы используете yourMap, mapи this. Может быть, это хорошая идея, чтобы сделать его более последовательным.
Густаво Штраубе
11

Размер массива должен быть больше нуля. Иначе у вас будут неожиданные результаты.

function zoomeExtends(){
  var bounds = new google.maps.LatLngBounds();
  if (markers.length>0) { 
      for (var i = 0; i < markers.length; i++) {
         bounds.extend(markers[i].getPosition());
        }    
        myMap.fitBounds(bounds);
    }
}
Fotis. Tsilfoglou
источник
8

Эта MarkerClustererутилита на стороне клиента доступна для Google Map, как указано здесь в статьях для разработчиков Google Map. Вот краткое описание ее использования:

Есть много подходов для выполнения того, что вы просили:

  • Грид-кластеризация
  • Дистанционная кластеризация
  • Управление маркерами видового экрана
  • Fusion Tables
  • Маркер кластер
  • MarkerManager

Вы можете прочитать о них по предоставленной ссылке выше.

Marker Clustererиспользует кластеризацию на основе сетки для кластеризации всех маркеров, желающих сетку. Кластеризация на основе сетки работает путем разделения карты на квадраты определенного размера (размер изменяется при каждом увеличении), а затем группирования маркеров в каждый квадрат сетки.

Перед кластеризацией Перед кластеризацией

После кластеризации После кластеризации

Я надеюсь, что это то, что вы искали, и это решит вашу проблему :)

iyogeshjoshi
источник