Использование setZoom() после использования fitBounds() с помощью API Карт Google V3

Я использую fitBounds(), чтобы установить уровень масштабирования на моей карте, также включать все отображаемые в данный момент маркеры. Однако, когда у меня есть только один маркер, уровень масштабирования составляет 100% (... который, как мне кажется, 20-го уровня...). Тем не менее, я не хочу, чтобы он был настолько увеличен, чтобы пользователь мог отрегулировать положение маркера без необходимости уменьшения масштаба.

У меня есть следующий код:

var marker = this.map.createMarker(view.latlng, this.markerNumber);
this.map.bounds.extend(view.latlng);
this.map.map.setCenter(this.map.bounds.getCenter());
this.map.map.fitBounds(this.map.bounds);
if (this.markerNumber === 1) {
  this.map.map.setZoom(16);
}
this.markerNumber++;

где this.map.bounds ранее определялось как:

this.map.bounds = new google.maps.LatLngBounds();

Однако проблема заключается в том, что строка this.map.map.setZoom(16); не работает, если я использую this.map.map.fitBounds(this.map.bounds);, однако я знаю, что строка кода верна, потому что, когда я прокомментирую строку fitBound(), setZoom() волшебным образом начинает работать.

Любые идеи, как я это разрешаю? Я думаю об установке уровня maxZoom в качестве альтернативы, если я не могу заставить это работать.

Ответ 1

Хорошо, я понял это. По-видимому, fitbounds() происходит асинхронно, поэтому вам нужно ждать события bounds_changed, прежде чем устанавливать масштаб.

map = this.map.map;

map.fitBounds(this.map.bounds);
zoomChangeBoundsListener = 
    google.maps.event.addListenerOnce(map, 'bounds_changed', function(event) {
        if (this.getZoom()){
            this.setZoom(16);
        }
});
setTimeout(function(){google.maps.event.removeListener(zoomChangeBoundsListener)}, 2000);

Обновить. См. ответ @Nequin с помощью addListenerOnce для лучшего решения, которое не требует тайм-аута.

Ответ 2

google.maps.event.addListenerOnce(yourMap, 'bounds_changed', function(event) {
  if (this.getZoom() > 15) {
    this.setZoom(15);
  }
});

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

Ответ 3

Я обнаружил, что дополнительный зум будет немного раздражать. Если вы установите параметр maxZoom перед вызовом fitBounds (а затем отключите его в обратном вызове), вы можете избежать этого:

map.setOptions({
    maxZoom: 10
});

map.setCenter(new google.maps.LatLng(-89, -179)); // make sure it changes so the idle listener gets called back

map.fitBounds(bounds);

var listener = google.maps.event.addListenerOnce(map, "idle", function()
{
    map.setOptions({
        maxZoom: 999
    });
});

Ответ 4

У меня есть простое и грязное решение.
Использовать, если еще...

var marker = this.map.createMarker(view.latlng, this.markerNumber);
this.map.bounds.extend(view.latlng);
this.map.map.setCenter(this.map.bounds.getCenter()); 
if (this.markerNumber === 1) {
  this.map.map.setZoom(16);
} else {
   this.map.map.fitBounds(this.map.bounds);
}       
this.markerNumber++;

Ответ 5

Я просто добавил одну строку к функции addBounds(position), и она исправила ее, как показано ниже:

    addBounds: function(position) {
        this.get('bounds', new google.maps.LatLngBounds()).extend(this._latLng(position));
        this.get('map').fitBounds(this.get('bounds'));
        this.get('map').setZoom(16);//line added
        return this;
    },