Google Maps v3 - Beschränkung des sichtbaren Bereichs und der Zoomstufe

97

Ist es möglich, Google Map v3 auf einen bestimmten Bereich zu beschränken? Ich möchte zulassen, dass nur ein Bereich (z. B. ein Land) angezeigt wird, und dem Benutzer nicht erlauben, an eine andere Stelle zu wechseln. Außerdem möchte ich die Zoomstufe einschränken - z. B. nur zwischen den Stufen 6 und 9. Und ich möchte alle Basiskartentypen verwenden.

Gibt es eine Möglichkeit, dies zu erreichen?

Ich hatte teilweise Erfolg mit der Begrenzung der Zoomstufe mithilfe von StyledMap, aber es gelang mir nur, ROADMAP einzuschränken. Auf diese Weise konnte ich den Zoom für andere Basistypen nicht einschränken.

Vielen Dank für jede Hilfe

Tomik
quelle

Antworten:

119

Sie können das dragendEreignis anhören. Wenn die Karte außerhalb der zulässigen Grenzen gezogen wird, verschieben Sie sie wieder hinein. Sie können Ihre zulässigen Grenzen in einem LatLngBoundsObjekt definieren und dann mithilfe der contains()Methode überprüfen, ob sich das neue Lat / Lng-Zentrum innerhalb der Grenzen befindet.

Sie können die Zoomstufe auch sehr einfach einschränken.

Betrachten Sie das folgende Beispiel: 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>

Screenshot aus dem obigen Beispiel. In diesem Fall kann der Benutzer nicht weiter nach Süden oder Fernost ziehen:

Google Maps JavaScript API v3 Beispiel: Erzwingen Sie das Ziehen der Karte

Daniel Vassallo
quelle
2
Die Entscheidung sieht nicht sauber aus. Warum if (x < minX) x = minX;und if (x > maxX) x = maxX;nicht ausschließen? Warum zentrieren Sie die Leinwand auf minX / maxX- und maxX / maxY-Koordinaten, obwohl sie keine Koordinaten der Mitte sind?
Alexander Palamarchuk
1
Anstelle eines dragendEreignisses, das Sie draggable: falseauf einer Karteninstanz verwenden könnten ( Arbeitsbeispiel )
machineaddict
Dies ist keine gute Technik, um das Ereignis "zoom_changed" zu verwenden, um den Benutzer einzuschränken. Da es beim ersten Mal immer über die Min-Ebene hinausgeht und dann Ihren Code verwendet, stellen Sie den Min-Zoom erneut ein, wodurch der Bildschirm angezeigt wird.
Jitendra Pancholi
check zillow.com/homes/for_sale/days_sort/… Sie haben es richtig gemacht, nicht sicher wie.
Jitendra Pancholi
1
Dies funktionierte perfekt für mich, wenn ich statt zum center_changedEvent wechselte dragend.
Johan B
182

Eine bessere Möglichkeit, die Zoomstufe einzuschränken, besteht darin, die Optionen minZoom/ maxZoomzu verwenden, anstatt auf Ereignisse zu reagieren.

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

Oder die Optionen können während der Karteninitialisierung angegeben werden, z.

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

Siehe: Google Maps JavaScript API V3-Referenz

ChrisV
quelle
3
Dies ist sicherlich der beste Weg, um die Zoomstufe einzuschränken. Als ich den Beitrag schrieb, war die Funktion in Maps API v3 nicht vorhanden. Zum Glück verbessern sie die API weiter.
Tomik
2
Dies funktioniert perfekt, dies sollte die beste Antwort für den Zoom sein.
paullb
3
Dies sollte als Antwort für diejenigen markiert werden, die nur die gewählte Antwort betrachten.
ErJab
9
Das Einstellen der Zoomstufe hat keine Auswirkung auf das Schwenken.
Simpatico
1
Auf jeden Fall der beste Weg
ChrisRich
16

Gute Nachrichten. Ab der Version 3.35 der Maps JavaScript API, die am 14. Februar 2019 gestartet wurde, können Sie eine neue restrictionOption verwenden, um das Ansichtsfenster der Karte einzuschränken.

Laut Dokumentation

MapRestriction-Schnittstelle

Eine Einschränkung, die auf die Karte angewendet werden kann. Das Ansichtsfenster der Karte überschreitet diese Einschränkungen nicht.

Quelle: https://developers.google.com/maps/documentation/javascript/reference/map#MapRestriction

Jetzt fügen Sie einfach eine Einschränkungsoption während einer Karteninitialisierung hinzu und das ist es. Schauen Sie sich das folgende Beispiel an, das das Ansichtsfenster auf die Schweiz beschränkt

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>

Ich hoffe das hilft!

Xomena
quelle
1
Dokumentationslink behoben.
Xomena
Vielen Dank, dieser Code hat irgendwie funktioniert. Das heißt, wenn Sie den Zoom mit minZoom und maxZoom auf nur eine Stufe beschränken. Es scheint, dass Sie für jede Zoomstufe unterschiedliche Einstellungen für Süd, West, Noth, Ost vornehmen müssen, falls dies wie beabsichtigt funktioniert. Es wäre schön, für jede Zoomstufe eine andere Einschränkungseinstellung zu haben. Ich habe mich für meine maximale verkleinerte Ebene entschieden und die Koordinaten von dort aus definiert, sodass es möglich ist, beim Verkleinern und anschließenden Schwenken weit außerhalb der Grenzen zu schwenken.
Kim Steinhaug
6

So begrenzen Sie den Zoom auf Version 3 +. Fügen Sie in Ihrer Karteneinstellung die Standardzoomstufe hinzu, und die Zoomstufen minZoom oder maxZoom (oder beide, falls erforderlich) liegen zwischen 0 und 19. Sie müssen die Deaktivierungszoomstufe angeben, wenn eine Einschränkung erforderlich ist. Alle unterscheiden zwischen Groß- und Kleinschreibung!

function initialize() {
   var mapOptions = {
      maxZoom:17,
      minZoom:15,
      zoom:15,
      ....
TIEFES SILBER
quelle
3

Viel besserer Weg, um den Bereich zu begrenzen ... verwendet die enthält Logik von oben Poster.

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);
                           });
Klopfen
quelle
Warum fügst du this.googleMapstatt mapfür den zweiten Hörer hinzu? Sollte auch nicht dragStartsein dragStartCenter? Was ist zuletzt mapBounds?
hobbes3
2
Sicherlich ist alles, was der Benutzer daran hindert, in einer Zugbewegung zu weit zu ziehen? Sie könnten immer noch viele kleine Drags machen und irgendwo landen, nein?
James
1

Dies kann verwendet werden, um die Karte an einem bestimmten Ort neu zu zentrieren. Welches ist, was ich brauchte.

    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));
        }
    });
Jonathan Busuttil
quelle
1
myOptions = {
        center: myLatlng,
        minZoom: 6,
        maxZoom: 9,
        styles: customStyles,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
Anup
quelle
1
Dies beantwortet die Frage nicht.
Kit Sunde
0

Hier ist meine Variante, um das Problem der Einschränkung des sichtbaren Bereichs zu lösen.

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

strictBoundsist ein Objekt vom new google.maps.LatLngBounds()Typ. self.gmapspeichert ein Google Map-Objekt ( new google.maps.Map()).

Es funktioniert wirklich, aber vergessen Sie nicht nur, die Hämorrhoiden beim Überschreiten der 0. Meridiane und Parallelen zu berücksichtigen, wenn Ihre Grenzen sie abdecken.

Alexander Palamarchuk
quelle
Akzeptiert Daniel Vassallos Algorithmus funktioniert bei mir nicht richtig. Hier gibt es mehrere Hauptunterschiede.
Alexander Palamarchuk
0

Aus irgendeinem Grund

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

hat bei mir nicht funktioniert (vielleicht ein Problem der südlichen Hemisphäre). Ich musste es ändern zu:

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

Hoffe es wird jemandem helfen.

Mayko
quelle
0

Eine Lösung ist wie, wenn Sie die spezifische lat / lng kennen.

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

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

});

Wenn Sie kein bestimmtes Lat / Lng haben

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

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

});

oder

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

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

});
Jaison
quelle
0

Ab Mitte 2016 gibt es keine offizielle Möglichkeit, den sichtbaren Bereich einzuschränken. Die meisten Ad-hoc-Lösungen zum Einschränken der Grenzen weisen jedoch einen Fehler auf, da sie die Grenzen nicht genau auf die Kartenansicht beschränken, sondern nur einschränken, wenn die Mitte der Karte außerhalb der angegebenen Grenzen liegt. Wenn Sie die Grenzen auf das Überlagern von Bildern wie mich beschränken möchten, kann dies zu einem Verhalten wie unten dargestellt führen, bei dem die Unterlagekarte unter unserer Bildüberlagerung sichtbar ist:

Geben Sie hier die Bildbeschreibung ein

Um dieses Problem zu beheben, habe ich eine Bibliothek erstellt , die die Grenzen erfolgreich einschränkt, damit Sie nicht aus dem Overlay herausschwenken können.

Wie bei anderen vorhandenen Lösungen tritt jedoch ein "vibrierendes" Problem auf. Wenn der Benutzer die Karte aggressiv genug schwenkt, schwenkt die Karte nach dem Loslassen der linken Maustaste von selbst weiter und verlangsamt sich allmählich. Ich bringe die Karte immer wieder an die Grenzen zurück, aber das führt zu Vibrationen. Dieser Panning-Effekt kann derzeit nicht mit den von der Js-API bereitgestellten Mitteln gestoppt werden. Es scheint, dass wir erst dann ein reibungsloses Erlebnis schaffen können, wenn Google Unterstützung für etwas wie map.stopPanningAnimation () hinzufügt.

Beispiel unter Verwendung der erwähnten Bibliothek, die glatteste Erfahrung mit strengen Grenzen, die ich bekommen konnte:

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>

Die Bibliothek kann auch die minimale Zoombeschränkung automatisch berechnen. Anschließend wird die Zoomstufe mit eingeschränktminZoom des Kartenattributs eingeschränkt.

Hoffentlich hilft dies jemandem, der eine Lösung sucht, die die vorgegebenen Grenzen vollständig einhält und nicht zulässt, dass sie aus ihnen herausschwenken.

Matej P.
quelle
-4

Dies kann hilfreich sein.

  var myOptions = {
      center: new google.maps.LatLng($lat,$lang),
      zoom: 7,
      disableDefaultUI: true,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    };

Die Zoomstufe kann je nach Anforderung angepasst werden.

Samir Dash
quelle
Dies geht nicht auf die ursprüngliche Frage zur Beschränkung der Zoomstufe auf einen Bereich ein e.g. only between levels 6 and 9, sondern legt die Standardzoomstufe fest und entfernt die Standardbenutzeroberfläche (dh +/ -), die ein wenig übertrieben ist.
Alastair