web-dev-qa-db-ja.com

Google Maps API V3でfitBounds()を使用した後にsetZoom()を使用する

FitBounds()を使用して、現在表示されているすべてのマーカーを含むズームレベルをマップに設定しています。ただし、マーカーが1つしか表示されていない場合、ズームレベルは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レベルを設定することを考えています。

72

わかった、わかった。どうやら、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);

更新:タイムアウトを必要としないより良いソリューションについては、addListenerOnceを使用して@Nequinの回答を参照してください。

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

このソリューションは、タイムアウトを待ってリスナーを削除するのではなく、うまく機能します。 fitBoundsを使用する前に、これを直接呼び出します(あとで呼び出しても機能すると思います)。

95
Nequin

追加のズームは少し耳障りであることがわかりました。 fitBoundsを呼び出す前にmaxZoomオプションを設定した場合(そしてコールバックで設定を解除した場合)、それを回避できます。

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
    });
});
16
Emery Lapinski

私はシンプルで汚い解決策を持っています。
If if else ...

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++;
2
Vishwanath

関数addBounds(position)に1行追加しただけで、次のように修正されました。

    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;
    },
1
Mirek Komárek

正しい方法は、map.fitBounds(bounds)の後にズームレベルを設定する必要があると思います。 map.setZoom(16)の後にmap.fitBounds(bounds)を追加するだけです。それは私のためにうまく機能します。

0

イベントリスナーを使用したすべてのソリューションが機能しませんでした(this.getZoom()は常にコールバックで未定義であり、this.setZoom()は効果がありません)。

私はうまくいったこの解決策を思いつきました:

function set_zoom() {
    if(map.getZoom()) {map.setZoom(map.getZoom() - 1);}
    else {setTimeout(set_zoom, 5);}
}
setTimeout(set_zoom, 5);
0
horace