Googleマップv3のfitBounds()ズームが1つのマーカーに近すぎる


92

の最大ズームレベルを設定する方法はありfitBounds()ますか?私の問題は、地図に1つの場所しか与えられていない場合、地図が可能な限り拡大され、実際には地図がコンテキストから外れて役に立たなくなることです。おそらく私は間違ったアプローチを取っていますか?

前もって感謝します!


2
stackoverflow.com/questions/4523023/…は、はるかに優れたソリューションです。特定の@Nequins回答
ケネット

回答:


138

私はmrtの解決策(特に、マッピングまたは調整するポイントの数がわからない場合)が好きですが、マーカーが消えてマップの中心から外れる点が異なります。緯度と経度から.01を引いた追加のポイントを追加するだけで、マーカーを中央に維持しています。素晴らしい作品、ありがとうmrt!

// Pan & Zoom map to show all markers
function fitToMarkers(markers) {

    var bounds = new google.maps.LatLngBounds();

    // Create bounds from markers
    for( var index in markers ) {
        var latlng = markers[index].getPosition();
        bounds.extend(latlng);
    }

    // Don't zoom in too far on only one marker
    if (bounds.getNorthEast().equals(bounds.getSouthWest())) {
       var extendPoint1 = new google.maps.LatLng(bounds.getNorthEast().lat() + 0.01, bounds.getNorthEast().lng() + 0.01);
       var extendPoint2 = new google.maps.LatLng(bounds.getNorthEast().lat() - 0.01, bounds.getNorthEast().lng() - 0.01);
       bounds.extend(extendPoint1);
       bounds.extend(extendPoint2);
    }

    map.fitBounds(bounds);

    // Adjusting zoom here doesn't work :/

}

4
元の中心を維持することについての良い考え。使用している場合、ズームレベルを確実に調整することができない理由fitBounds()ズームが非同期に発生しているので、この方法は次のとおりです。stackoverflow.com/questions/2989858/...
メトロスマーフ

1
これは私にとってはうまくいきました。マップ参照をV3の関数「function fitToMarkers(markers、map)」に渡す必要がありましたが、その後は魅力のように機能します!
シェーン

4
それ大好き。良い@ryan。私にとってはうまくいきましたが、私の場合は.01がズームアウトしすぎて、.001がスイートスポットに到達しました。
willdanceforfun 2013年

ありがとう。@willdanceforfunの場合と同じように、001がその場でヒットしました。
Goran Jakovljevic 2015年

1
私は、このソリューションの推薦stackoverflow.com/questions/2437683/...
NinjaOnSafari

38

あなたはとセットアップあなたのマップをすることができますmaxZoomMapOptions (API-参照)このように:

var map = new google.maps.Map(document.getElementById("map"), { maxZoom: 10 });

これfitBounds()により、使用時にマップがより深くズームしないようになり、ズームコントロールからズームレベルが削除されます。


@candlejack私の答えで説明されているとおりですか?
Flygenring

6
maxZoom境界をフィットする前にを設定してから、境界を変更することによって発生map.setOptions({ maxZoom: undefined })したidleイベントでそれを再び設定解除できます。これにより、idleイベントのズームインをリセットする代わりに、ズームイン、ズームアウトの影響を防ぐことができます。
El Yobo 2017年

29

別の解決策は、fitBounds()を実行する前に境界が小さすぎることを検出した場合に、境界を拡張することです。

var bounds = new google.maps.LatLngBounds();
// here you extend your bound as you like
// ...
if (bounds.getNorthEast().equals(bounds.getSouthWest())) {
   var extendPoint = new google.maps.LatLng(bounds.getNorthEast().lat() + 0.01, bounds.getNorthEast().lng() + 0.01);
   bounds.extend(extendPoint);
}
map.fitBounds(bounds);

19
var map = new google.maps.Map(document.getElementById("map"), { maxZoom: 10 });

MaxZoomオプションを使用すると、ズームして現在のマークに近づかないようにするのに最適です。


素晴らしい!ライフセーバー!
ジェイピー

18

すべての実際の境界を追加したら、これらの行を追加します

var offset = 0.002;     
var center = bounds.getCenter();                            
bounds.extend(new google.maps.LatLng(center.lat() + offset, center.lng() + offset));
bounds.extend(new google.maps.LatLng(center.lat() - offset, center.lng() - offset));

実際の境界の中心を取得し、中心の北東と南西に2つのポイントを追加します。

これは効果的に最小ズームを設定し、オフセットの値を変更してズームを増減します



11

あなたは使える

map.setOptions({
    maxZoom: [what u want],
    minZoom: [what u want]
});

このように、マップが初期化された後にマップのプロパティを設定します.... uは何回でも設定できます...しかし、場合によっては... uはそれらをfitBounds()の前に設定できます

幸運、ラルトゥ


7

地図が遠くにズームインしないようにするには、次のコード行を追加します。

var zoomOverride = map.getZoom();
        if(zoomOverride > 15) {
        zoomOverride = 15;
        }
      map.setZoom(zoomOverride);

この行の直後:

map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));

ズームレベルを、地図でズームしたくないレベルに変更してください。

問題や質問がある場合は、http://icode4you.net/creating-your-own-store-locator-map-how-to-prevent-the-に書き込んだブログ投稿にコメントを残してください。map-from-zooming-in-too-close-on-a-single-marker


1
私はこのソリューションが好きですが、毎回呼び出さないようにif内にsetzoomを挿入します。getzoom()から「未定義」を返すタイミングの副作用もある可能性があります。解決策:zoom = map.getZoom(); if(typeof zoom!== 'undefined' && zoom> 8)map.setZoom(8);
Le Droid 2013年

5

私はmrtのソリューションが本当に好きで、常に1つのポイントしか操作できなければ完璧に機能します。ただし、バウンディングボックスが1つのポイントに基づいていなくても、ポイントが非常に接近していると、マップがズームインしすぎる可能性があることがわかりました。

次に、ポイントが互いに定義された距離内にあるかどうかを最初に確認し、それらがその最小距離よりも小さい場合は、その最小距離で境界を拡張します。

var bounds = new google.maps.LatLngBounds();
// here you extend your bound as you like

// ...

var minDistance = 0.002;
var sumA = bounds.getNorthEast().lng() - bounds.getSouthWest().lng();
var sumB = bounds.getNorthEast().lat() - bounds.getSouthWest().lat();

if((sumA < minDistance && sumA > -minDistance) 
&& (sumB < minDistance && sumB > -minDistance)){
var extendPoint1 = new google.maps.LatLng(bounds.getNorthEast().lat() + minDistance, bounds.getNorthEast().lng() + minDistance);
    var extendPoint2 = new google.maps.LatLng(bounds.getNorthEast().lat() - minDistance, bounds.getNorthEast().lng() - minDistance);
    bounds.extend(extendPoint1);
    bounds.extend(extendPoint2);
}

これが誰かを助けることを願っています!


3

これにより、境界フィッティングでの最大許容ズームを直接制御できます。

var fitToMarkers = function(map, markers, maxZoom) {
    if (typeof maxZoom == 'undefined') maxZoom = 15;

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

    var bounds = new google.maps.LatLngBounds();
    for (var m = 0; m < markers.length; m++) {
        var marker = markers[m];
        var latlng = marker.getPosition();
        bounds.extend(latlng);
    }

    map.fitBounds(bounds);
};

3

私については、fitBoundsの後にアイドルイベントを作成して解決します。完璧に働いています。これがここで最もクリーンなソリューションの1つだと思います

var locations = [['loc', lat, lng], ['loc', lat, lng]];
.....
for (i = 0; i < locations.length; i++) { 
  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 10
  });
  .... create markers, etc.
}
....
map.fitBounds(bounds);  
google.maps.event.addListenerOnce(map, 'idle', function() {
  if (locations.length == 1) {
    map.setZoom(11);
  }
});

2

Google Maps V3はイベントドリブンなので、このチャンクで解決しました。

zoom_changedイベントがトリガーされたときに、ズームを適切な量に戻すようにAPIに指示できます。

var initial = true
google.maps.event.addListener(map, "zoom_changed", function() {
    if (intial == true){
       if (map.getZoom() > 11) {
         map.setZoom(11);
         intial = false;
       }
    }
}); 

最終的にfitBoundsが実行されたときに、マップをズームしすぎないように初期化を使用しました。これがないと、11を超えるズームイベントはユーザーには不可能です。


1

fitBounds()メソッドを呼び出した後、ズームレベルの設定を再試行してください。これにより、マップは適切な場所に中央揃えされながら、そのズームレベルになります。


0

境界を合わせるときに最大ズームを制限することに基づく解決策があります。私のために働く(Win 7-IE 9、FF 13、Chrome 19でテスト済み):

// When fitting bounds:
var bounds = new google.maps.LatLngBounds();
// ...
// extend bounds as you like
// ..

// now set global variable when fitting bounds
window.fittingBounds = true;
map.fitBounds(bounds);
window.fittingBounds = false;


// attach this event listener after map init
google.maps.event.addListener(map, 'zoom_changed', function() {
    // set max zoom only when fitting bounds
    if (window.fittingBounds && map.getZoom() > 16) {
        this.setZoom(16);
    }
});

0

そして..ここに別のものがあります。
mrtとRyanと同じ考えですが、

  • 境界サイズが正確にゼロでない場合にも機能します(*)
  • 極付近の歪みを防ぎます
  • getNorthEast()の代わりにgetCenter()を使用します

(*)注:ボックスがすでに十分に大きい場合、これらの2つの追加ポイントを追加しても効果はありません。したがって、これ以上のチェックは必要ありません。

function calcBounds(markers) {
  // bounds that contain all markers
  var bounds = new google.maps.LatLngBounds();
  // Using an underscore _.each(). Feel free to replace with standard for()
  _.each(markers, function(marker) {
    bounds.extend(marker.getPosition());
  });
  // prevent lat/lng distortion at the poles
  var lng0 = bounds.getNorthEast().lng();
  var lng1 = bounds.getSouthWest().lng();
  if (lng0 * lng1 < 0) {
    // Take the cos at the equator.
    var cos = 1;
  }
  else {
    var cos0 = Math.cos(lng0);
    var cos1 = Math.cos(lng1);
    // Prevent division by zero if the marker is exactly at the pole.
    var cos_safe = Math.max(cos0, cos1, 0.0001);
  }
  var cos0 = Math.cos(bounds.getNorthEast.lng() * Math.PI / 180);
  var cos1 = Math.cos(bounds.getSouthWest.lng() * Math.PI / 180);
  // "radius" in either direction.
  // 0.0006 seems to be an ok value for a typical city.
  // Feel free to make this value a function argument.
  var rLat = 0.0006;
  var rLng = rLat / cos_safe;
  // expand the bounds to a minimum width and height
  var center = bounds.getCenter();
  var p0 = new google.maps.LatLng(center.lat() - rLat, center.lng() - rLng);
  var p1 = new google.maps.LatLng(lat.center() + rLat, center.lng() + rLng);
  bounds.extend(p0);
  bounds.extend(p1);
  return bounds;
}

編集:私はメルカトル図法があることを考えると、比率の計算が正確かどうか正確にはわかりません。これを再編集するかもしれません。



-1

これが解決策です。2つのマーカーが非常に近い場合にも機能します。有効な最大ズームレベルは、両方の状況で同じです。したがって、マーカーが複数ある場合、不必要にズームアウトしてしまうことはありません。

この場合も、maxZoomオプションを使用せずに最大ズームが保証されます。これは、ユーザーがズームコントロールを使用してmaxZoomレベルを超えてズームできないようにするというおそらく望ましくない影響があります。

maxLat、minLat、maxLng、minLngを事前に計算しました...

var minLatSpan = 0.002;
if (maxLat - minLat < minLatSpan) {
  // ensures that we do not zoom in too much
  var delta = (minLatSpan - (maxLat - minLat)) / 2;
  maxLat += delta;
  minLat -= delta;
}

map.fitBounds({
  east: maxLng,
  west: minLng,
  north: maxLat,
  south: minLat,
});
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.