2010-09-29 23 views
82

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 der Benutzer nicht anderswo rutschen kann. Ich möchte auch die Zoomstufe einschränken - z. nur zwischen den Ebenen 6 und 9. Und ich möchte alle Basiskartenarten verwenden.Google Maps v3 - Anzeigebereich und Zoomstufe einschränken

Gibt es eine Möglichkeit, dies zu erreichen?

Ich hatte einen Teilerfolg mit der Begrenzung der Zoomstufe mit StyledMap, aber es gelang mir nur mit Einschränkung ROADMAP, konnte ich Zoom auf andere grundlegende Arten auf diese Weise nicht begrenzen.

Vielen Dank für jede Hilfe

Antwort

112

Sie zum dragend Ereignisse hören, und wenn die Karte außerhalb der erlaubten Grenzen gezogen wird, bewegen sie wieder hinein. Sie können Ihre zulässigen Grenzen in einem LatLngBounds Objekt definieren und dann die Methode verwenden, um zu überprüfen, ob das neue lat/lng Zentrum innerhalb der Grenzen ist.

Sie können die Zoomstufe auch sehr einfach begrenzen.

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. Der Benutzer wird nicht weiter nach Süden in der Lage zu ziehen, oder nach Osten weit in diesem Fall:

Google Maps JavaScript API v3 Example: Force stop map dragging

+2

Die Entscheidung sieht nicht sauber aus.Warum 'if (x maxX) x = maxX;' schließt sich nicht aus? Warum zentrierst du die Leinwand auf MinX/MaxX- und MaxX/MaxY-Koordinaten, obwohl sie keine Koordinaten der Mitte sind? –

+1

Anstelle von 'dragend' können Sie' draggable: false' auf der Karteninstanz verwenden ([funktionierendes Beispiel] (http://jsfiddle.net/32pc6f5v/)) – machineaddict

+0

Dies ist keine gute Methode, um das "zoom_changed" -Ereignis zu verwenden Beschränke den Benutzer. Weil es das erste Mal immer über die Min-Ebene hinausgeht und Sie dann Ihren Code verwenden, stellen Sie den Min-Zoom erneut ein, der den Bildschirm flirren wird. –

164

bessere Art und Weise Zoomstufe beschränken könnte die minZoom/maxZoom Optionen zu verwenden, anstatt auf Ereignisse reagieren?

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

Oder die Optionen können während der Initialisierung der Karte angegeben werden, zB:

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

See: Google Maps JavaScript API V3 Reference

+2

Nun ist dies sicherlich der beste Weg, um die Zoomstufe zu beschränken. Als ich den Post schrieb, war das Feature in Maps API v3 nicht vorhanden. Zum Glück verbessern sie ständig die API. – Tomik

+2

Dies funktioniert perfekt, das sollte die beste Antwort für den Zoom sein. – paullb

+3

Dies sollte als die Antwort für diejenigen markiert werden, die nur auf die gewählte Antwort schauen. – ErJab

3

viel bessere Möglichkeit, den Bereich zu begrenzen ... verwendete enthält Logik von oben Plakat .

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

Warum fügen Sie 'this.googleMap' anstelle von' map' für den zweiten Listener hinzu? Sollte 'DragStart' nicht' dragStartCenter' sein? Zuletzt was ist mapBounds? – hobbes3

+2

Sicherlich genügt es, den Benutzer zu stoppen, wenn er mit einer Ziehbewegung zu weit zieht. Sie könnten noch viele kleine Ziehungen machen und irgendwo landen, oder? – James

0

Hier ist meine Variante, das Problem der Einschränkung der sichtbaren Bereich 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)); 
     }); 

strictBounds ist ein Ziel der new google.maps.LatLngBounds() Typ. self.gmap speichert ein Google Map-Objekt (new google.maps.Map()).

Es funktioniert wirklich, aber vergessen Sie nicht nur die Hämorrhoiden mit Kreuzung 0th Meridiane und Parallelen zu berücksichtigen, wenn Ihre Grenzen sie decken.

+0

Akzeptiert Der Algorithmus von Daniel Vassallo funktioniert nicht richtig für mich. Es gibt hier einige prinzipielle Unterschiede. –

0

Aus irgendeinem Grund

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

funktionierte nicht für mich (vielleicht eine südliche Hemisphäre Ausgabe). Ich musste es ändern:

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

Ich hoffe, es wird jemandem helfen.

-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.

+0

Dies betrifft nicht die ursprüngliche Frage zum Beschränken der Zoomstufe auf einen Bereich von z.B. nur zwischen den Ebenen 6 und 9 ', setzt es die * Standard * Zoomstufe und entfernt die Standardbenutzeroberfläche (d.h. '+'/'-'), was etwas übertrieben ist. – Alastair

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 keine bestimmten haben lat/lng

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

}); 
6

den Zoom auf v.3 + zu begrenzen. Fügen Sie in Ihrer Karteneinstellung die Standardzoomstufe und minZoom oder maxZoom (oder beide bei Bedarf) hinzu. Zoomstufen sind 0 bis 19. Sie müssen die Zoomstufe "taubul" deklarieren, wenn eine Einschränkung erforderlich ist. alle sind case sensitive!

function initialize() { 
    var mapOptions = { 
     maxZoom:17, 
     minZoom:15, 
     zoom:15, 
     .... 
1

Dies kann verwendet werden, um die Karte an einem bestimmten Ort neu zu zentrieren. 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)); 
     } 
    }); 
2
myOptions = { 
     center: myLatlng, 
     minZoom: 6, 
     maxZoom: 9, 
     styles: customStyles, 
     mapTypeId: google.maps.MapTypeId.ROADMAP 
    }; 
+0

Dies beantwortet die Frage nicht. –

0

Ab Mitte 2016, gibt es keinen offiziellen Weg sichtbaren Bereich zu beschränken. Die meisten Ad-hoc-Lösungen zur Einschränkung der Grenzen haben jedoch einen Fehler, da sie die Grenzen nicht genau auf die Kartenansicht beschränken, sondern sie nur einschränken, wenn die Mitte der Karte außerhalb der angegebenen Grenzen liegt. Wenn Sie die Grenzen zu überlagern Bild wie mir beschränken wollen, kann dies in einem Verhalten führen, wie unten dargestellt, wobei die darunter liegende Karte unter unserer Bildüberlagerung sichtbar ist:

enter image description here

Um dieses Problem zu bewältigen, ich habe Es wurde ein library erstellt, der die Grenzen erfolgreich einschränkt, sodass Sie das Overlay nicht verschieben können.

Wie andere bestehende Lösungen hat es jedoch ein "vibrierendes" Problem. Wenn der Benutzer die Karte aggressiv schwenkt, nachdem er die linke Maustaste losgelassen hat, wird die Karte weiterhin selbst geschwenkt und verlangsamt sich allmählich. Ich gebe die Karte immer zurück an die Grenzen, aber das führt zu einer Art Vibration. Dieser Panning-Effekt kann derzeit nicht mit irgendwelchen Mitteln gestoppt werden, die von der Js-API bereitgestellt werden. Es scheint, dass bis Google Unterstützung für etwas wie map.stopPanningAnimation() hinzufügen wird, können wir keine glatte Erfahrung erstellen.

Beispiel der erwähnten Bibliothek, die glatteste strenge Grenzen Erfahrung konnte ich bekommen mit: die minimale Zoom Einschränkung

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){ 
 
\t var bounds = new google.maps.LatLngBounds(
 
\t \t new google.maps.LatLng(62.281819, -150.287132), 
 
\t \t new google.maps.LatLng(62.400471, -150.005608)); 
 

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

 
\t 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()"> 
 
\t <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 ist auch in der Lage automatisch zu berechnen. Dann wird die Zoomstufe unter Verwendung des Kartenattributs minZoom eingeschränkt.

Hoffentlich hilft dies jemandem, der eine Lösung wünscht, die die gegebenen Grenzen vollständig respektiert und nicht zulassen will, dass sie aus ihnen herauswachsen.