In V2 gab es eine Möglichkeit, das Schwenken / Ziehen einzuschränken, damit die Karte innerhalb bestimmter Grenzen bleibt. Wie geht das in V3?
Angenommen, ich möchte, dass die Benutzer nur Europa betrachten. Ich habe den Zoom bereits eingeschränkt, aber wenn ich das Ziehen zulasse (was in diesem Fall aus anderen Gründen erforderlich ist), kann der Benutzer über den Bereich hinaus schwenken, den ich anzeigen möchte.
Bitte geben Sie ein funktionierendes Beispiel oder einen Code-Ausschnitt an - ich bin kein erfahrener Programmierer ...
restriction
Option verwenden, um das Ansichtsfenster der Karte einzuschränken. Schauen Sie sich Beispiele und Erklärungen unter stackoverflow.com/a/54717220/5140781 an .Antworten:
Ich schätze, ich bin ein bisschen zu spät zur Party, aber da dies genau das war, was ich gerade brauchte UND ich es verbessert habe, dachte ich, ich würde trotzdem eine Antwort posten.
Mit den Antworten von Daniel Vassallo und brendo kann der Benutzer weiterhin den Pan-Regler (falls aktiviert) verwenden, um sich vom gewünschten Bereich zu entfernen. Das Ding @ Yauhen.F in einem Kommentar erwähnt.
Anstatt das Dragend-Ereignis zu verwenden, verwende ich das center_changed-Ereignis. Dies wird während des Ziehens kontinuierlich ausgelöst und jedes Mal, wenn jemand die Schwenksteuerung verwendet.
// bounds of the desired area var allowedBounds = new google.maps.LatLngBounds( new google.maps.LatLng(70.33956792419954, 178.01171875), new google.maps.LatLng(83.86483689701898, -88.033203125) ); var lastValidCenter = map.getCenter(); google.maps.event.addListener(map, 'center_changed', function() { if (allowedBounds.contains(map.getCenter())) { // still within valid bounds, so save the last valid position lastValidCenter = map.getCenter(); return; } // not valid anymore => return to last valid position map.panTo(lastValidCenter); });
Durch kontinuierliches Speichern der letzten gültigen Position während des Ziehens wird die Bewegung nur gestoppt, sobald sie außerhalb der Grenzen liegt, anstatt nach dem Ende des Ziehens zurückzuziehen. ......
quelle
center_changed
Veranstaltung ist der Schlüssel. Auf Mobilgeräten (iOS) gibt es jedoch noch einige Probleme.map.setCenter(...);
angemessener alsmap.panTo(...);
? Letzteres scheint potenziell extravagant (von der CPU) zu sein, da sein Zweck darin besteht, nichts weiter zu tun, als das Schwenken in seinen Spuren zu stoppen.Der Trick besteht darin, das
dragend
Ereignis anzuhören. Wenn die Karte außerhalb der zulässigen Grenzen gezogen wird, verschieben Sie sie wieder hinein. Wenn Sie Ihre zulässigen Grenzen alsLatLngBounds
Objekt definieren, können Sie diecontains()
Methode verwenden, da sie true zurückgibt, wenn das angegebene lat / lng-Argument innerhalb der Grenzen liegt.Es ist auch wichtig, die Zoomstufe zu begrenzen, aber anscheinend tun Sie dies bereits.
Daher möchten Sie möglicherweise das folgende Beispiel ausprobieren:
<!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"/> <title>Google Maps JavaScript API v3 Example: Limit Panning</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"> 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 allowedBounds = 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 (allowedBounds.contains(map.getCenter())) return; // Out of bounds - Move the map back within the bounds var c = map.getCenter(), x = c.lng(), y = c.lat(), maxX = allowedBounds.getNorthEast().lng(), maxY = allowedBounds.getNorthEast().lat(), minX = allowedBounds.getSouthWest().lng(), minY = allowedBounds.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:
quelle
Meine Version basiert auf der von @HenningJ, aber mit einigen Modifikationen der
lastValidCenter
, um ein reibungsloses Ziehen entlang der Kanten der Grenzen zu ermöglichen.<!DOCTYPE html> <html> <head> <style type="text/css"> html { height: 100% } body { height: 100%; margin: 0; padding: 0 } #map-canvas { height: 100% } </style> <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> </script> <script type="text/javascript"> function initialize() { var mapOptions = { center: new google.maps.LatLng(28.70, -127.50), zoom: 4, mapTypeId: google.maps.MapTypeId.ROADMAP }; var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions); // bounds of the desired area var allowedBounds = new google.maps.LatLngBounds( new google.maps.LatLng(28.70, -127.50), new google.maps.LatLng(48.85, -55.90) ); var boundLimits = { maxLat : allowedBounds.getNorthEast().lat(), maxLng : allowedBounds.getNorthEast().lng(), minLat : allowedBounds.getSouthWest().lat(), minLng : allowedBounds.getSouthWest().lng() }; var lastValidCenter = map.getCenter(); var newLat, newLng; google.maps.event.addListener(map, 'center_changed', function() { center = map.getCenter(); if (allowedBounds.contains(center)) { // still within valid bounds, so save the last valid position lastValidCenter = map.getCenter(); return; } newLat = lastValidCenter.lat(); newLng = lastValidCenter.lng(); if(center.lng() > boundLimits.minLng && center.lng() < boundLimits.maxLng){ newLng = center.lng(); } if(center.lat() > boundLimits.minLat && center.lat() < boundLimits.maxLat){ newLat = center.lat(); } map.panTo(new google.maps.LatLng(newLat, newLng)); }); } google.maps.event.addDomListener(window, 'load', initialize); </script> </head> <body> <div id="map-canvas"/> </body> </html>
Geige hier: http://jsfiddle.net/koenpunt/n7h6t/
quelle
Hier ist eine nette Erweiterung des oben Gesagten, die die Mitte der Karte durch Abhören des Dragstart-Ereignisses auf die letzte gültige Position zurücksetzt.
// Limit panning var lastCenter = map.getCenter(); google.maps.event.addListener(map, 'dragstart', function() { lastCenter = map.getCenter(); }); google.maps.event.addListener(map, 'dragend', function() { if(allowedBounds.contains(map.getCenter())) return; map.setCenter(lastCenter); });
quelle
Die beste Methode zum Einschränken ist, die Zoomstufe und den Mittelpunkt einzustellen und die Steuerelemente wie Zoomen, Scrollen usw. wie unten deaktiviert.
var latlng = new google.maps.LatLng(18.283078,84.047556); var myOptions = { zoom: 12, center: latlng, zoomControl: false, mapTypeId: google.maps.MapTypeId.ROADMAP, scrollwheel: false, navigationControl: false, mapTypeControl: false, scaleControl: false, draggable: false, disableDoubleClickZoom: true, }; map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
quelle
Hier ist eine Lösung, die die Antwort von Tom Andersen und die derzeit akzeptierte Antwort von HenningJ zusammenführt. Dies hat den Vorteil, dass 1) ein sanfteres Scrollen entlang der Kanten möglich ist (mit der HenningJs Lösung klobig zu sein schien) und 2) keine Probleme beim Vergrößern eines Bereichs auftreten (auch hier schien HenningJs Antwort beim Vergrößern zu brechen und in der Nähe der Grenzen).
Toms Antwort war kurz davor, für mich zu arbeiten, außer dass der abgesperrte Bereich in der Mitte des Bildschirms positioniert war, was für die Anwendung, an der ich arbeitete, nicht akzeptabel war.
// bounds of the desired area var allowedBounds = new google.maps.LatLngBounds( new google.maps.LatLng(70.33956792419954, 178.01171875), new google.maps.LatLng(83.86483689701898, -88.033203125) ); var lastValidCenter = map.getCenter(); google.maps.event.addListener(map, 'center_changed', function() { var mapBounds = map.getBounds(); var mapNe = mapBounds.getNorthEast(); var mapSw = mapBounds.getSouthWest(); var center = map.getCenter(); if( allowedBounds.contains(mapNe) && allowedBounds.contains(mapSw) ) { //the user is scrolling within the bounds. lastValidCenter = center; return; } //the user has scrolled beyond the edge. var mapWidth = mapNe.lng() - mapSw.lng(); var mapHeight = mapNe.lat() - mapSw.lat(); var x = center.lng(); var y = center.lat(); var maxX = allowedBounds.getNorthEast().lng(); var maxY = allowedBounds.getNorthEast().lat(); var minX = allowedBounds.getSouthWest().lng(); var minY = allowedBounds.getSouthWest().lat(); //shift the min and max dimensions by 1/2 of the screen size, so the bounds remain at the edge of the screen maxX -= (mapWidth / 2); minX += (mapWidth / 2); maxY -= (mapHeight / 2); minY += (mapHeight / 2); if (x < minX) { x = minX; } if (x > maxX) { x = maxX; } if (y < minY){ y = minY; } if (y > maxY){ y = maxY; } map.panTo(new google.maps.LatLng(y, x)); });
quelle
Die neue Version der Google Map API bietet jetzt eine Möglichkeit, Grenzen einzuschränken. Geben Sie einfach Ihre Einschränkungsgrenzen an, wenn Sie die Karte initialisieren. Wenn Sie beispielsweise die Grenze nur auf Newzeland beschränken möchten, gehen Sie folgendermaßen vor:
<body> <div id="map"></div> <script> var map; var NEW_ZEALAND_BOUNDS = { north: -34.36, south: -47.35, west: 166.28, east: -175.81, }; var AUCKLAND = {lat: -37.06, lng: 174.58}; function initMap() { map = new google.maps.Map(document.getElementById('map'), { center: AUCKLAND, restriction: { latLngBounds: NEW_ZEALAND_BOUNDS, strictBounds: false, }, zoom: 7, }); } </script> <script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap"> </script> </body>
Zu Ihrer Information: Um die Karte der ganzen Welt einzuschränken, können Sie die folgenden Grenzen verwenden. Der schwierige Teil hier ist zu verwenden
strictBounds:true
. Dadurch wird sichergestellt, dass der Benutzer das Weltbild nicht verkleinern kann:map = new google.maps.Map(document.getElementById('map'), { restriction: { latLngBounds: { north: 85, south: -85, west: -180, east: 180 }, strictBounds: true, }, zoom: 7, });
quelle
Es gibt noch einen anderen Thread zu diesem Thema, der ebenfalls sehr gut ist. Das Problem, das ich lösen musste, war, dass ich anstelle des manuellen Festlegens von Grenzen und des Überprüfens der Center-Eindämmung eine beim Laden der Seite festgelegte Grenze wollte und dann beim Vergrößern das Ziehen an den Rand zuließ.
Also habe ich beim Laden der Karte einmal Schwenkgrenzen festgelegt. Dann überprüfe ich, ob die Karte noch den maximalen Zoom aufweist, und gebe in diesem Fall die ursprüngliche Mitte zurück. Beim Vergrößern möchte ich zum Rand der Anfangsgrenzen schwenken und nicht nur prüfen, ob CENTER enthalten ist, da dies das zulässige Schwenken um die Hälfte des Ansichtsfensters erweitern würde.
Obwohl dies die Arbeit erledigt und beim langsamen Schwenken gut funktioniert, ist es leider etwas ruckelig, wenn Sie schnell schwenken.
Wenn Sie Vorschläge haben, wie dies vermieden werden kann, wäre ich Ihnen dankbar.
map = new google.maps.Map( // defaults document.getElementById("map22"), { disableDefaultUI : true, zoomControl : true, zoom : 7, minZoom : 7, maxZoom : 10, center : new google.maps.LatLng( 64.99473104134819, -19.22332763671875 ), mapTypeId : google.maps.MapTypeId.ROADMAP } ); function borders(){ return { maxLat : map.getBounds().getNorthEast().lat(), maxLng : map.getBounds().getNorthEast().lng(), minLat : map.getBounds().getSouthWest().lat(), minLng : map.getBounds().getSouthWest().lng(), center : map.getCenter() } } google.maps.event.addListenerOnce(map,'idle',function() { limit = borders(); }); google.maps.event.addListener(map,'drag',function() { if(map.getZoom() == 7) return map.setCenter(limit.center); current = borders(); if( current.maxLng < limit.maxLng && current.minLng > limit.minLng ) activeCenterLng = current.center.lng(); if( current.maxLat < limit.maxLat && current.minLat > limit.minLat ) activeCenterLat = current.center.lat(); map.setCenter( new google.maps.LatLng( activeCenterLat, activeCenterLng ) ); });
quelle
Ich versuchte die Antwort von HenningJ und die Karte hörte nicht auf zu schwenken, bis sich das Zentrum in einer Ecke der Grenzen befand, was nicht ideal war. Hier ist meine Lösung:
google.maps.event.addListener(map, 'center_changed', function() { var mapBounds = map.getBounds(); if(allowedBounds.contains(mapBounds.getNorthEast()) && allowedBounds.contains(mapBounds.getSouthWest())) { lastCenter = map.getCenter(); return; } map.panTo(lastCenter); }, this));
quelle
Hier ist eine einfache Lösung, die auf Mobilgeräten und Desktops funktioniert. Dadurch wird das Schwenken der Karte über den maximalen oder minimalen Breitengrad der Welt hinaus gestoppt und es kann eine minimale Zoomstufe festgelegt werden, mit der verhindert werden kann, dass Grauzonen durch zu weites Zoomen sichtbar werden (abhängig von der Größe, die Sie für Ihre Karte festgelegt haben):
(Ich empfehle Vorsicht bei der Verwendung des Ereignisses center_changed, wie in der von HenningJ akzeptierten Antwort vorgeschlagen. In meinem Fall hat die Anzahl der Ereignisse, die dadurch verursacht werden, Stapelüberlauffehler in Google Chrome verursacht. Stattdessen kann das Ereignis "dragend" verwendet werden - obwohl dies zulässig ist Der Benutzer muss außerhalb der Bereiche ziehen und wird dann sofort zu einem gültigen Bereich der Karte zurückkehren.
var lastValidCenter; var minZoomLevel = 2; setOutOfBoundsListener(); function setOutOfBoundsListener() { google.maps.event.addListener(map, 'dragend', function () { checkLatitude(map); }); google.maps.event.addListener(map, 'idle', function () { checkLatitude(map); }); google.maps.event.addListener(map, 'zoom_changed', function () { checkLatitude(map); }); }; function checkLatitude(map) { if (this.minZoomLevel) { if (map.getZoom() < minZoomLevel) { map.setZoom(parseInt(minZoomLevel)); } } var bounds = map.getBounds(); var sLat = map.getBounds().getSouthWest().lat(); var nLat = map.getBounds().getNorthEast().lat(); if (sLat < -85 || nLat > 85) { //the map has gone beyone the world's max or min latitude - gray areas are visible //return to a valid position if (this.lastValidCenter) { map.setCenter(this.lastValidCenter); } } else { this.lastValidCenter = map.getCenter(); } }
quelle
Wenn ich Drag oder Dragend oder was auch immer verwende, springt die Karte zurück in zulässige Grenzen, anstatt einfach die Überlaufbewegung einzuschränken. Ändern Sie einfach das Ereignis in 'center_changed', um zu verhindern, dass es so herumspringt.
Modifizierte jsfiddle: http://jsfiddle.net/Vjdde/1/
Bearbeiten: Ich bin mir nicht sicher, warum die Geige keinen Stapelüberlauf erzeugt, sollte es aber, da setCenter wieder center_changed aufruft. Pass auf
quelle
Die Lösungen hier ließen mich mit 2 Problemen zurück. Wenn Sie die Pfeiltaste gedrückt halten, damit sie schnell zu schwenken beginnt, wenn sie auf die Kante trifft, geht sie zunächst nicht bis zur Kante, da aufgrund der Schwenkbeschleunigung große "Schritte" ausgeführt werden. Schritt "wäre über die Grenzen hinausgegangen, so dass dieser letzte" Schritt "nicht erforderlich ist. Sobald es angehalten hat, können Sie die Pfeiltaste loslassen und dann erneut drücken, und es wird nur ein wenig weiter geschwenkt. Zweitens enthielten diese Lösungen das Schwenken nach einer Zoomänderung nicht richtig. Ich habe beides gelöst und meine Lösung in einem anderen Thread veröffentlicht , aber ich dachte, ich würde sie hier verlinken, da dies der Thread war, der mich zuerst in die richtige Richtung geführt hat.
quelle
Dies ist HenningJ - aber HenningJ auf ios verwendet lastValidCentre - was nicht gut ist, da es alt ist, also klemme ich, was es unter iOS besser macht.
var mapObject = plugin_map.gmap3('get'); var allowedBounds = new google.maps.LatLngBounds( new google.maps.LatLng(41.3957556, -88.4345472), new google.maps.LatLng(49.4010417, -78.4286389) ); google.maps.event.addListener(mapObject, 'center_changed', function() { if (allowedBounds.contains(mapObject.getCenter())) { // still within valid bounds, so save the last valid position return; } // not valid anymore => return to last valid position var c = mapObject.getCenter(), x = c.lng(), y = c.lat(), maxX = allowedBounds.getNorthEast().lng(), maxY = allowedBounds.getNorthEast().lat(), minX = allowedBounds.getSouthWest().lng(), minY = allowedBounds.getSouthWest().lat(); if (x < minX) x = minX; if (x > maxX) x = maxX; if (y < minY) y = minY; if (y > maxY) y = maxY; //mapObject.setCenter(new google.maps.LatLng(y, x)); mapObject.panTo(new google.maps.LatLng(y, x)); });
quelle
Ich werde meine Antwort veröffentlichen, falls sich jemand dafür interessiert, weil ich mit keiner der anderen hier veröffentlichten Lösungen das erreichen konnte, was ich brauchte.
Was ich brauchte, war, die vertikalen Grenzen (Breitengrad) der Karte zu beschränken, damit der Benutzer nicht über die Breitengradgrenzen der Erde (~ +/- 85 Grad) hinaus schwenken kann, aber alle anderen Grenzen würden auch funktionieren.
Dieser Ansatz verwendet dasselbe
center_changed
Ereignis wie an anderer Stelle beschrieben und fixiert einfach das Zentrum, falls Teile der verbotenen Grenzen angezeigt werden.Dieser Mechanismus funktioniert nur, wenn der minimale Zoom der Karte so eingestellt ist, dass beim Herauszoomen niemals mehr Fläche als innerhalb der zulässigen Grenzen angezeigt werden kann.
Arbeitsbeispiel: http://jsbin.com/vizihe
function initMap() { // sample bounds, can be anything and goes hand in hand with minZoom var northBoundary = 40 var southBoundary = -40 var map = new google.maps.Map(document.getElementById('map'), { center: {lat: 0, lng: 0}, zoom: 4, // it's important to set this to a large enough value // so that zooming out does not show an area larger than allowed minZoom: 4 }) map.addListener('center_changed', function () { var bounds = map.getBounds(); var ne = bounds.getNorthEast() var sw = bounds.getSouthWest() var center = map.getCenter() if(ne.lat() > northBoundary) { map.setCenter({lat: center.lat() - (ne.lat() - northBoundary), lng: center.lng()}) } if(sw.lat() < southBoundary) { map.setCenter({lat: center.lat() - (sw.lat() - southBoundary), lng: center.lng()}) } }) }
html, body, #map { height: 100%; margin: 0; padding: 0; }
<!DOCTYPE html> <html> <head> <meta name="description" content="limit google map panning"> <title>Simple Map</title> <meta name="viewport" content="initial-scale=1.0"> <meta charset="utf-8"> </head> <body> <div id="map"></div> <script src="https://maps.googleapis.com/maps/api/js?callback=initMap" async defer></script> </body> </html>
quelle
Ich weiß, dass ich etwas spät zur Party komme, aber es scheint, dass ab Mitte 2016 keinen offiziellen Weg gibt, den sichtbaren Bereich einzuschränken.
Es gibt einige Lösungen, um die Grenzen einzuschränken (einige davon in dieser Frage), aber für mich haben sie einen Fehler, da sie die Grenzen nicht genau auf die Kartenansicht beschränken, sondern nur das Kartenzentrum einschränken, das in der enthalten ist spezifizierte Grenzen. 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:
Um dieses Problem zu beheben, habe ich eine Bibliothek erstellt , die die Grenzen erfolgreich einschränkt, sodass 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 weiterhin von selbst weiter und verlangsamt sich allmählich. Ich bringe die Karte immer wieder an die Grenzen zurück, aber das führt zu einer Art Vibration, die sich nach einem Moment einstellt. 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:500px; width:1000px;"></div> <script type="text/javascript"src="https://raw.githubusercontent.com/matej-pavla/StrictBoundsImage/master/StrictBoundsImage.js"></script> </body>
quelle