web-dev-qa-db-ja.com

Google Maps v3-表示可能な領域とズームレベルを制限する

googleマップv3を特定のエリアに制限することは可能ですか?一部の地域(国など)のみの表示を許可し、ユーザーが他の場所にスライドできないようにしたい。また、ズームレベルを制限したい-例えばレベル6と9の間のみです。そして、すべてのベースマップタイプを使用したいと思います。

これを達成する方法はありますか?

StyledMapを使用してズームレベルを制限することで部分的に成功しましたが、ROADMAPを制限することでのみ成功し、この方法で他の基本的なタイプのズームを制限することはできませんでした。

助けてくれてありがとう

93
Tomik

dragendイベントをリッスンできます。マップが許可された境界の外側にドラッグされた場合は、内側に戻します。 LatLngBounds オブジェクトで許可された境界を定義し、contains()メソッドを使用して、新しい緯度/経度の中心が境界内にあるかどうかを確認できます。

ズームレベルを非常に簡単に制限することもできます。

次の例を考えてみましょう。 Fiddle Demo

<!DOCTYPE html>
<html> 
<head> 
   <meta http-equiv="content-type" content="text/html; charset=UTF-8"/> 
   <title>Google Maps JavaScript API v3 Example: Limit Panning and Zoom</title> 
   <script type="text/javascript" 
           src="http://maps.google.com/maps/api/js?sensor=false"></script>
</head> 
<body> 
   <div id="map" style="width: 400px; height: 300px;"></div> 

   <script type="text/javascript"> 

   // This is the minimum zoom level that we'll allow
   var minZoomLevel = 5;

   var map = new google.maps.Map(document.getElementById('map'), {
      zoom: minZoomLevel,
      center: new google.maps.LatLng(38.50, -90.50),
      mapTypeId: google.maps.MapTypeId.ROADMAP
   });

   // Bounds for North America
   var strictBounds = new google.maps.LatLngBounds(
     new google.maps.LatLng(28.70, -127.50), 
     new google.maps.LatLng(48.85, -55.90)
   );

   // Listen for the dragend event
   google.maps.event.addListener(map, 'dragend', function() {
     if (strictBounds.contains(map.getCenter())) return;

     // We're out of bounds - Move the map back within the bounds

     var c = map.getCenter(),
         x = c.lng(),
         y = c.lat(),
         maxX = strictBounds.getNorthEast().lng(),
         maxY = strictBounds.getNorthEast().lat(),
         minX = strictBounds.getSouthWest().lng(),
         minY = strictBounds.getSouthWest().lat();

     if (x < minX) x = minX;
     if (x > maxX) x = maxX;
     if (y < minY) y = minY;
     if (y > maxY) y = maxY;

     map.setCenter(new google.maps.LatLng(y, x));
   });

   // Limit the zoom level
   google.maps.event.addListener(map, 'zoom_changed', function() {
     if (map.getZoom() < minZoomLevel) map.setZoom(minZoomLevel);
   });

   </script> 
</body> 
</html>

上記の例のスクリーンショット。この場合、ユーザーはさらに南または極東にドラッグできません。

Google Maps JavaScript API v3 Example: Force stop map dragging

118
Daniel Vassallo

ズームレベルを制限するより良い方法は、イベントに反応するのではなく、minZoom/maxZoomオプションを使用することです。

var opt = { minZoom: 6, maxZoom: 9 };
map.setOptions(opt);

または、マップの初期化中にオプションを指定できます。例:

var map = new google.maps.Map(document.getElementById('map-canvas'), opt);

参照: Google Maps JavaScript API V3リファレンス

175
ChrisV

良いニュース。 2019年2月14日にリリースされたMaps JavaScript APIのバージョン3.35以降、新しいrestrictionオプションを使用して、マップのビューポートを制限できます。

ドキュメントによると

MapRestrictionインターフェイス

マップに適用できる制限。マップのビューポートはこれらの制限を超えません。

ソース: https://developers.google.com/maps/documentation/javascript/reference/3.35/map#MapRestriction

したがって、マップの初期化中に制限オプションを追加するだけです。ビューポートをスイスに制限する次の例をご覧ください

var map;
function initMap() {
  map = new google.maps.Map(document.getElementById('map'), {
    center: {lat: 46.818188, lng: 8.227512},
    minZoom: 7,
    maxZoom: 14,
    zoom: 7,
    restriction: {
      latLngBounds: {
        east: 10.49234,
        north: 47.808455,
        south: 45.81792,
        west: 5.95608
      },
      strictBounds: true
    },
  });
}
#map {
  height: 100%;
}
html, body {
  height: 100%;
  margin: 0;
  padding: 0;
}
<div id="map"></div>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDztlrk_3CnzGHo7CFvLFqE_2bUKEq1JEU&callback=initMap" async defer></script>

これがお役に立てば幸いです!

8
xomena

V.3 +でズームを制限します。マップ設定でデフォルトのズームレベルを追加し、minZoomまたはmaxZoom(または必要に応じて両方)のズームレベルは0〜19です。制限が必要な場合は、デフォルトのズームレベルを宣言する必要があります。すべて大文字と小文字が区別されます!

function initialize() {
   var mapOptions = {
      maxZoom:17,
      minZoom:15,
      zoom:15,
      ....
6
DEEP-SILVER

範囲を制限するはるかに良い方法...上記のポスターの包含ロジックを使用しました。

var dragStartCenter;

google.maps.event.addListener(map, 'dragstart', function(){
                                       dragStartCenter = map.getCenter();
                                         });

google.maps.event.addListener(this.googleMap, 'dragend', function(){
                            if (mapBounds.contains(map.getCenter())) return;
                    map.setCenter(this.dragStart);
                           });
3
Pat

これを使用して、マップを特定の場所に再センタリングできます。それは私が必要としたものです。

    var MapBounds = new google.maps.LatLngBounds(
    new google.maps.LatLng(35.676263, 13.949096),
    new google.maps.LatLng(36.204391, 14.89038));

    google.maps.event.addListener(GoogleMap, 'dragend', function ()
    {
        if (MapBounds.contains(GoogleMap.getCenter()))
        {
            return;
        }
        else
        {
            GoogleMap.setCenter(new google.maps.LatLng(35.920242, 14.428825));
        }
    });
1
myOptions = {
        center: myLatlng,
        minZoom: 6,
        maxZoom: 9,
        styles: customStyles,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
1
Anup

1つの解決策は、特定の緯度経度を知っている場合です。

google.maps.event.addListener(map, 'idle', function() {

    map.setCenter(new google.maps.LatLng(latitude, longitude));
    map.setZoom(8);

});

特定の緯度/経度がない場合

google.maps.event.addListener(map, 'idle', function() {

    map.setCenter(map.getCenter());
    map.setZoom(8);

});

または

google.maps.event.addListener(map, 'idle', function() {

    var bounds = new google.maps.LatLngBounds();
    map.setCenter(bounds.getCenter());
    map.setZoom(8);

});
0
Jaison

何らかの理由で

if (strictBounds.contains(map.getCenter())) return;

私のために働かなかった(たぶん南半球の問題)。次のように変更する必要がありました。

    function checkBounds() {
        var c = map.getCenter(),
            x = c.lng(),
            y = c.lat(),
            maxX = strictBounds.getNorthEast().lng(),
            maxY = strictBounds.getNorthEast().lat(),
            minX = strictBounds.getSouthWest().lng(),
            minY = strictBounds.getSouthWest().lat();

        if(x < minX || x > maxX || y < minY || y > maxY) {
            if (x < minX) x = minX;
            if (x > maxX) x = maxX;
            if (y < minY) y = minY;
            if (y > maxY) y = maxY;
            map.setCenter(new google.maps.LatLng(y, x));
        }
    }

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

0
Mayko

これは、表示可能領域の制限の問題を解決するための私のバリアントです。

        google.maps.event.addListener(this.map, 'idle', function() {
            var minLat = strictBounds.getSouthWest().lat();
            var minLon = strictBounds.getSouthWest().lng();
            var maxLat = strictBounds.getNorthEast().lat();
            var maxLon = strictBounds.getNorthEast().lng();
            var cBounds  = self.map.getBounds();
            var cMinLat = cBounds.getSouthWest().lat();
            var cMinLon = cBounds.getSouthWest().lng();
            var cMaxLat = cBounds.getNorthEast().lat();
            var cMaxLon = cBounds.getNorthEast().lng();
            var centerLat = self.map.getCenter().lat();
            var centerLon = self.map.getCenter().lng();

            if((cMaxLat - cMinLat > maxLat - minLat) || (cMaxLon - cMinLon > maxLon - minLon))
            {   //We can't position the canvas to strict borders with a current zoom level
                self.map.setZoomLevel(self.map.getZoomLevel()+1);
                return;
            }
            if(cMinLat < minLat)
                var newCenterLat = minLat + ((cMaxLat-cMinLat) / 2);
            else if(cMaxLat > maxLat)
                var newCenterLat = maxLat - ((cMaxLat-cMinLat) / 2);
            else
                var newCenterLat = centerLat;
            if(cMinLon < minLon)
                var newCenterLon = minLon + ((cMaxLon-cMinLon) / 2);
            else if(cMaxLon > maxLon)
                var newCenterLon = maxLon - ((cMaxLon-cMinLon) / 2);
            else
                var newCenterLon = centerLon;

            if(newCenterLat != centerLat || newCenterLon != centerLon)
                self.map.setCenter(new google.maps.LatLng(newCenterLat, newCenterLon));
        });

strictBoundsnew google.maps.LatLngBounds()タイプのオブジェクトです。 self.gmapはGoogleマップオブジェクトを保存します(new google.maps.Map())。

それは本当に機能しますが、境界がそれらをカバーしている場合、0番目の子午線と平行線を伴うwithを考慮することを忘れないでください。

2016年半ばの時点で、可視領域を制限する公式の方法はありません。ただし、境界を制限するアドホックソリューションのほとんどには欠陥があります。これは、マップビューにぴったり合うように境界を制限するのではなく、マップの中心が指定された範囲外にある場合にのみ制限するためです。私のようなオーバーレイ画像に境界を制限したい場合、下図のような動作が発生する可能性があります。この場合、オーバーレイ画像は画像オーバーレイの下に表示されます。

enter image description here

この問題に取り組むために、オーバーレイをパンできないように境界を正常に制限する library を作成しました。

ただし、他の既存のソリューションと同様に、「振動」の問題があります。ユーザーがマウスの左ボタンを放した後、マップを積極的にパンすると、マップはそれ自体でパンを続け、徐々に遅くなります。私は常にマップを境界に戻しますが、それは一種の振動をもたらします。このパニング効果は、現時点ではJs APIが提供する手段では停止できません。 googleがmap.stopPanningAnimation()などのサポートを追加するまで、スムーズなエクスペリエンスを作成することはできないようです。

上記のライブラリを使用した例、私が得ることができた最もスムーズな厳密な境界体験:

function initialise(){
  
  var myOptions = {
     zoom: 5,
     center: new google.maps.LatLng(0,0),
     mapTypeId: google.maps.MapTypeId.ROADMAP,
  };
  var map = new google.maps.Map(document.getElementById('map'), myOptions);
  
  addStrictBoundsImage(map);
}

function addStrictBoundsImage(map){
        var bounds = new google.maps.LatLngBounds(
                new google.maps.LatLng(62.281819, -150.287132),
                new google.maps.LatLng(62.400471, -150.005608));

        var image_src = 'https://developers.google.com/maps/documentation/' +
                'javascript/examples/full/images/talkeetna.png';

        var strict_bounds_image = new StrictBoundsImage(bounds, image_src, map);
}
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
      <script type="text/javascript">
        google.load("maps", "3",{other_params:"sensor=false"});
      </script>
<body style="margin:0px; padding:0px;" onload="initialise()">
         <div id="map" style="height:400px; width:500px;"></div>
     <script  type="text/javascript"src="https://raw.githubusercontent.com/matej-pavla/StrictBoundsImage/master/StrictBoundsImage.js"></script>
</body>

ライブラリは、最小ズーム制限を自動的に計算することもできます。次に、minZoomマップの属性を使用してズームレベルを制限します。

うまくいけば、これが与えられた境界を完全に尊重し、それらの外へのパンを許可したくない解決策を望む人を助けるでしょう。

0
Matej P.