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

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

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

setZoom(zoom:number)

а также

setCenter(latlng:LatLng)

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

enter image description here

Ответ 1

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

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

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.

Ответ 2

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

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)
}

UPDATE:
Дальнейшие исследования в этой теме показывают, что fitBounds() является асинхронным и лучше всего сделать манипуляцию Zoom с слушателем, определенным перед вызовом 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);

Ответ 3

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

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

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

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

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

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

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

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

Ответ 4

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

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