Google Maps v3: min. zoomniveau bij gebruik van fitBounds

Ik teken een reeks markeringen op een kaart (met v3 van de maps api).

In v2 had ik de volgende code:

 bounds = new GLatLngBounds();
  ... loop thru and put markers on map ...
  bounds.extend(point);
  ... end looping
  map.setCenter(bounds.getCenter());
  var level = map.getBoundsZoomLevel(bounds);
  if ( level == 1 ) 
    level = 5;
  map.setZoom(level > 6 ? 6 : level);

En dat werkt prima om ervoor te zorgen dat er altijd een passend detailniveau op de kaart wordt weergegeven.

Ik probeer deze functionaliteit in v3 te dupliceren, maar de setZoom en fitBounds lijken niet samen te werken:

... loop thru and put markers on the map
  var ll = new google.maps.LatLng(p.lat,p.lng);
  bounds.extend(ll);
... end loop
var zoom = map.getZoom();
map.setZoom(zoom > 6 ? 6 : zoom);
map.fitBounds(bounds);

Ik heb verschillende permutaties geprobeerd (bijvoorbeeld het verplaatsen van de fitBounds voor de setZoom) maar niets wat ik doe met setZoom lijkt de kaart te beïnvloeden. Mis ik iets? Is er een manier om dit te doen?


Antwoord 1, autoriteit 100%

Bij deze discussie over Google DiscussiegroepenIk ontdekte dat wanneer je een fitBounds doet, de zoom asynchroon gebeurt, dus je moet de zoom en de wijziging van de grenzen vastleggen. De code in het laatste bericht werkte voor mij met een kleine wijziging… zoals het er nu uitziet, kun je niet meer dan 15 volledig zoomen, dus gebruikte het idee van het vierde bericht om een ​​vlag te hebben ingesteld om het alleen de eerste keer te doen.

// Do other stuff to set up map
var map = new google.maps.Map(mapElement, myOptions);
// This is needed to set the zoom after fitbounds, 
google.maps.event.addListener(map, 'zoom_changed', function() {
    zoomChangeBoundsListener = 
        google.maps.event.addListener(map, 'bounds_changed', function(event) {
            if (this.getZoom() > 15 && this.initialZoom == true) {
                // Change max/min zoom here
                this.setZoom(15);
                this.initialZoom = false;
            }
        google.maps.event.removeListener(zoomChangeBoundsListener);
    });
});
map.initialZoom = true;
map.fitBounds(bounds);

Hopelijk helpt dat,

Anthony.


Antwoord 2, autoriteit 46%

Zonder het te proberen, zou ik zeggen dat je het zou moeten kunnen doen door gewoon fitBounds()te hebben voordat je het zoomniveau krijgt, d.w.z.

map.fitBounds(bounds);
var zoom = map.getZoom();
map.setZoom(zoom > 6 ? 6 : zoom);

Als je dat wel hebt geprobeerd en het niet werkte, kun je je kaart instellen met minZoomin de MapOptions(api-reference)als volgt:

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

Hierdoor zou de kaart niet verder uitzoomen bij gebruik van fitBounds().


Antwoord 3, autoriteit 14%

Anthony’s oplossing is erg mooi. Ik hoefde alleen de zoom voor het aanvankelijke laden van de pagina te corrigeren (ervoor zorgen dat je niet te ver was ingezoomd om mee te beginnen) en dit deed de truc voor mij:

var zoomChangeBoundsListener =
    google.maps.event.addListener(map, 'bounds_changed', function(event) {
        google.maps.event.removeListener(zoomChangeBoundsListener);
        map.setZoom( Math.min( 15, map.getZoom() ) );
    });
map.fitBounds( zoomBounds );

Antwoord 4, autoriteit 13%

Je kunt ook de maxZoom-optie instellen net voordat je fitBounds() aanroept en de waarde daarna opnieuw instellen:

if(!bounds.isEmpty()) {
    var originalMaxZoom = map.maxZoom;
    map.setOptions({maxZoom: 18});
    map.fitBounds(bounds);
    map.setOptions({maxZoom: originalMaxZoom});
}

Antwoord 5, autoriteit 8%

Als je map.fitBounds() op één item aanroept, kan de kaart te sterk inzoomen. Om dit op te lossen, voegt u eenvoudig ‘maxZoom’ toe aan mapOptions…

var mapOptions = {
  maxZoom: 15
};

Antwoord 6, autoriteit 6%

In mijn geval wilde ik gewoon het zoomniveau instellen op één minder dan wat Google Maps voor mij koos tijdens fitBounds. Het doel was om fitBounds te gebruiken, maar ook om ervoor te zorgen dat er geen markeringen waren onder kaarttools, enz.

Mijn kaart is vroeg gemaakt en dan hebben een aantal andere dynamische componenten van de pagina de mogelijkheid om markeringen toe te voegen, waarbij na elke toevoeging fitBounds wordt aangeroepen.

Dit is in het eerste blok waar het kaartobject oorspronkelijk is gemaakt…

var mapZoom = null;

Vervolgens wordt dit toegevoegd aan elk blok waar een markering wordt toegevoegd, vlak voordat de map.fitBounds wordt aangeroepen…

google.maps.event.addListenerOnce(map, 'bounds_changed', function() { 
    if (mapZoom != map.getZoom()) { 
        mapZoom = (map.getZoom() - 1); 
        map.setZoom(mapZoom); 
    } 
});

Bij gebruik van ‘bounds_changed’ zonder het inchecken, zoomde de kaart één keer uit voor elke markering, ongeacht of het nodig was of niet. Omgekeerd, als ik ‘zoom_changed’ gebruikte, had ik soms markeringen onder kaarthulpmiddelen omdat de zoom niet echt veranderde. Nu wordt het altijd geactiveerd, maar de controle zorgt ervoor dat het slechts één keer uitzoomt en alleen wanneer dat nodig is.

Hopelijk helpt dit.


Antwoord 7, autoriteit 2%

Aangezien Google Maps V3 gebeurtenisgestuurd is, kunt u de API vertellen dat de zoom moet worden teruggezet op een juiste hoeveelheid wanneer de gebeurtenis zoom_changedwordt geactiveerd:

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

Ik heb initialgebruikt om ervoor te zorgen dat de kaart niet te veel zoomt wanneer de uiteindelijke fitBounds worden gepermorfeerd, maar om de gebruiker zoveel te laten zoomen als hij/zij wil. Zonder de voorwaarde zou elke zoomgebeurtenis groter dan 11 voor de gebruiker mogelijk zijn.


Antwoord 8

Ik vond het volgende heel goed werken. Het is een variant op het antwoordvan Ryan op https://stackoverflow.com/questions/3334729/…. Het garandeert een oppervlakte van ten minste twee keer de waarde van offsetin graden.

const center = bounds.getCenter()
const offset = 0.01
const northEast = new google.maps.LatLng(
    center.lat() + offset,
    center.lng() + offset
)
const southWest = new google.maps.LatLng(
    center.lat() - offset,
    center.lng() - offset
)
const minBounds = new google.maps.LatLngBounds(southWest, northEast)
map.fitBounds(bounds.union(minBounds))

Antwoord 9

Ik had net dezelfde taak om op te lossen en gebruikte een eenvoudige functie om het op te lossen.

het maakt niet uit hoeveel markeringen er binnen de grenzen zijn – als er veel zijn en de zoom is al ver weg, zoomt dit een beetje uit, maar als er maar één markering is (of veel heel dichtbij elkaar), dan is de uitzoom aanzienlijk (aanpasbaar met de variabele extendBy):

var extendBounds = function() {
  // Extends the Bounds so that the Zoom Level on fitBounds() is a bit farer away
  var extendBy = 0.005;
  var point1 = new google.maps.LatLng(
    bounds.getNorthEast().lat() + extendBy,
    bounds.getNorthEast().lng() + extendBy
  )
  var point2 = new google.maps.LatLng(
    bounds.getSouthWest().lat() - extendBy,
    bounds.getSouthWest().lng() - extendBy
  )
  bounds.extend(point1);
  bounds.extend(point2);
}

Om het te gebruiken, gebruik ik een eigen functie om de fitBounds():
te doen
kaart is mijn GoogleMap-object

var refreshBounds = function() {
  extendBounds();
  map.fitBounds(bounds);
}

Other episodes