Domanda

Ho una serie di punti che voglio tracciare su un incorporato Google Map API (v3). Mi piacerebbe i limiti per accogliere tutti i punti a meno che il livello di zoom è troppo basso (vale a dire, ingrandito troppo tanto). Il mio approccio è stato simile a questo:

var bounds = new google.maps.LatLngBounds();

// extend bounds with each point

gmap.fitBounds(bounds); 
gmap.setZoom( Math.max(6, gmap.getZoom()) );

Questo non funziona. L'ultima riga "gmap.setZoom ()" non cambia il livello di zoom della mappa se chiamato direttamente dopo fitBounds.

C'è un modo per ottenere il livello di zoom di un campo senza applicarlo alla mappa? Altre idee per risolvere questo?

È stato utile?

Soluzione

Modifica :. Si veda il commento di Matt diamante seguente

Ci sono! Prova questo:

map.fitBounds(bounds);
var listener = google.maps.event.addListener(map, "idle", function() { 
  if (map.getZoom() > 16) map.setZoom(16); 
  google.maps.event.removeListener(listener); 
});

Modifica alle vostre esigenze.

Altri suggerimenti

ho risolto un problema simile in una delle mie applicazioni. Ero un po 'confuso dalla tua descrizione del problema, ma penso che tu abbia lo stesso obiettivo che ho avuto ...

Nella mia app ho voluto tracciare un uno o più indicatori e garantire la mappa mostrava tutti. Il problema era, se mi sono affidato esclusivamente sul metodo fitBounds, quindi il livello di zoom sarebbe maxed quando c'era un unico punto - che non era un buon

.

La soluzione era quella di utilizzare fitBounds quando c'era molti punti, e setCenter + setZoom quando c'era un solo punto.

if (pointCount > 1) {
  map.fitBounds(mapBounds);
}
else if (pointCount == 1) {
  map.setCenter(mapBounds.getCenter());
  map.setZoom(14);
}

Sono venuto a questa pagina più volte per ottenere la risposta, e mentre tutte le risposte esistenti erano super disponibile, non hanno risolvere il mio problema esattamente.

google.maps.event.addListenerOnce(googleMap, 'zoom_changed', function() {
    var oldZoom = googleMap.getZoom();
    googleMap.setZoom(oldZoom - 1); //Or whatever
});

In pratica ho scoperto che l'evento 'zoom_changed' impedito l'interfaccia utente della mappa da "saltare", che è accaduto quando ho aspettato per l'evento 'inattivo'.

Spero che questo aiuti qualcuno!

Ho appena riparato questo impostando maxZoom in anticipo, quindi rimuoverlo in seguito. Ad esempio:

map.setOptions({ maxZoom: 15 });
map.fitBounds(bounds);
map.setOptions({ maxZoom: null });

Se non mi sbaglio, sto assumendo si desidera che tutti i punti siano visibili sulla mappa con il più alto livello di zoom possibile. Ho compiuto questo inizializzando il livello di zoom della mappa per 16 (non so se è il più alto livello di zoom possibile in V3).

var map = new google.maps.Map(document.getElementById('map_canvas'), {
  zoom: 16,
  center: marker_point,
  mapTypeId: google.maps.MapTypeId.ROADMAP
});

Poi, dopo che ho fatto la roba limiti:

var bounds = new google.maps.LatLngBounds();

// You can have a loop here of all you marker points
// Begin loop
bounds.extend(marker_point);
// End loop

map.fitBounds(bounds);

Risultato:  Successo!

Io uso:

gmap.setZoom(24); //this looks a high enough zoom value
gmap.fitBounds(bounds); //now the fitBounds should make the zoom value only less

Questa utilizzerà il più piccolo di 24 e il livello di zoom necessario in base al codice, però probabilmente cambia lo zoom in ogni caso e non si preoccupa di quanto si ingrandito.

Ho avuto lo stesso problema e sono stato in grado di risolverlo utilizzando il seguente codice. Questo ascoltatore (google.maps.addListenerOnce()) evento otterrà solo sparato una volta, subito dopo map.fitBounds() viene eseguito. Quindi, non v'è alcuna necessità di

  1. Tenere traccia di e rimuovere manualmente l'ascoltatore, o
  2. Attendere che la mappa è idle.

Si imposta il livello di zoom appropriato inizialmente e permette all'utente di ingrandire e rimpicciolire oltre il livello di zoom iniziale, perché il listener di eventi è scaduto. Ad esempio, se solo google.maps.addListener() è stato chiamato, quindi l'utente non in grado di zoom-in oltre il livello di zoom dichiarato (nel caso, 4). Dal momento che abbiamo implementato google.maps.addListenerOnce(), l'utente sarà in grado di zoomare a qualsiasi livello che lui / lei sceglie.

map.fitBounds(bounds);

var zoom_level_for_one_marker = 4;

google.maps.event.addListenerOnce(map, 'bounds_changed', function(event){
   if (this.getZoom() >= zoom_level_for_one_marker){  
       this.setZoom(zoom_level_for_one_marker) 
   }
});

avuto lo stesso problema, necessario per adeguarsi ad innumerevoli icone sulla mappa. Ciò ha risolto il mio caso:

  1. Dichiarare limiti
  2. schema Usa fornito da koderoid (per ogni set bounds.extend(objLatLng) marcatore)
  3. Esegui fitbounds DOPO mappa è completato:

    google.maps.event.addListenerOnce(map, 'idle', function() { 
        map.fitBounds( bounds );
    });
    

ho trovato una soluzione che fa il controllo prima di chiamare fitBounds in modo da non lo zoom in e zoom out improvviso

var bounds = new google.maps.LatLngBounds();

// extend bounds with each point

var minLatSpan = 0.001;
if (bounds.toSpan().lat() > minLatSpan) {
    gmap.fitBounds(bounds); 
} else {
    gmap.setCenter(bounds.getCenter());
    gmap.setZoom(16);
}

Dovrete giocare con la variabile minLatSpan un po 'per arrivare dove vuoi. Essa può variare in base sia livello di zoom e le dimensioni della mappa.

Si potrebbe anche usare al posto di longitudine latitudine

Si prega di provare questo:

map.fitBounds(bounds);

// CHANGE ZOOM LEVEL AFTER FITBOUNDS
zoomChangeBoundsListener = google.maps.event.addListenerOnce(map, 'bounds_changed', function(event) {
  if (this.getZoom()){
    this.setZoom(15);
  }
});
setTimeout(function(){
  google.maps.event.removeListener(zoomChangeBoundsListener)
}, 2000);

Ho visto molte soluzioni errate o troppo complicati, così ha deciso di inviare un di lavoro, soluzione elegante .

Il motivo setZoom() non funziona come ci si aspetta è che fitBounds() è asincrona, quindi dà alcuna garanzia che avrebbe aggiornare immediatamente lo zoom, ma la chiamata per setZoom() si basa su questo.

Che cosa si potrebbe prendere in considerazione è impostando l'opzione minZoom mappa prima di chiamare fitBounds() e poi cancellarlo dopo aver completato (in modo che gli utenti possono comunque diminuire manualmente se vogliono):

var bounds = new google.maps.LatLngBounds();
// ... (extend bounds with all points you want to fit)

// Ensure the map does not get too zoomed out when fitting the bounds.
gmap.setOptions({minZoom: 6});
// Clear the minZoom only after the map fits the bounds (note that
// fitBounds() is asynchronous). The 'idle' event fires when the map
// becomes idle after panning or zooming.
google.maps.event.addListenerOnce(gmap, 'idle', function() {
  gmap.setOptions({minZoom: null});
});

gmap.fitBounds(bounds);

Inoltre, se si desidera limitare anche lo zoom massimo, è possibile applicare lo stesso trucco con la proprietà maxZoom.

Vedere la MapOptions docs .

Io lo uso per garantire il livello di zoom non superi un determinato livello in modo che io conosco le immagini satellitari saranno disponibili.

Aggiungi un listener per l'evento zoom_changed. Questo ha il vantaggio di controllare il controllo dello zoom sulla UI anche.

execute Solo setZoom se è necessario, in modo da una dichiarazione if è preferibile Math.max o Math.min

   google.maps.event.addListener(map, 'zoom_changed', function() { 
      if ( map.getZoom() > 19 ) { 
        map.setZoom(19); 
      } 
    });
    bounds = new google.maps.LatLngBounds( ... your bounds ... )
    map.fitBounds(bounds);

Per evitare lo zoom troppo:

   google.maps.event.addListener(map, 'zoom_changed', function() { 
      if ( map.getZoom() < 6 ) { 
        map.setZoom(6); 
      } 
    });
    bounds = new google.maps.LatLngBounds( ... your bounds ... )
    map.fitBounds(bounds);

In questa funzione, è necessario aggiungere dinamicamente i metadati per memorizzare il tipo di geometria solo perché la funzione accetta qualsiasi geometria.

"fitGeometries" è una funzione JSON estendentesi un oggetto della mappa.

"geometrie" è un array JavaScript non generico un MVCArray ().

geometry.metadata = { type: "point" };
var geometries = [geometry];

fitGeometries: function (geometries) {
    // go and determine the latLngBounds...
    var bounds = new google.maps.LatLngBounds();
    for (var i = 0; i < geometries.length; i++) {
        var geometry = geometries[i];
        switch (geometry.metadata.type)
        {
            case "point":
                var point = geometry.getPosition();
                bounds.extend(point);
                break;
            case "polyline":
            case "polygon": // Will only get first path
                var path = geometry.getPath();
                for (var j = 0; j < path.getLength(); j++) {
                    var point = path.getAt(j);
                    bounds.extend(point);
                }
                break;
        }
    }
    this.getMap().fitBounds(bounds);
},

di questo lavoro per me con API v3, ma con l'impostazione di zoom fisso:

var bounds = new google.maps.LatLngBounds();
// extend bounds with each point

gmap.setCenter(bounds.getCenter()); 
gmap.setZoom( 6 );

Come me, se non siete disposti a giocare con gli ascoltatori, questa è una soluzione semplice, mi venne in mente: Aggiungere un metodo sulla mappa che funziona rigorosamente in base alle proprie esigenze come questo:

    map.fitLmtdBounds = function(bounds, min, max){
        if(bounds.isEmpty()) return;
        if(typeof min == "undefined") min = 5;
        if(typeof max == "undefined") max = 15;

        var tMin = this.minZoom, tMax = this.maxZoom;
        this.setOptions({minZoom:min, maxZoom:max});
        this.fitBounds(bounds);
        this.setOptions({minZoom:tMin, maxZoom:tMax});
    }

allora si può chiamare map.fitLmtdBounds(bounds) al posto di map.fitBounds(bounds) per impostare i limiti sotto gamma di zoom definito ... o map.fitLmtdBounds(bounds,3,5) per ignorare la portata dello zoom ..

Si prega di provare questo.

// Find out what the map's zoom level is
zoom = map.getZoom();
if (zoom == 1) {
  // If the zoom level is that low, means it's looking around the
world.
  // Swap the sw and ne coords
  viewportBounds = new
google.maps.LatLngBounds(results[0].geometry.location, initialLatLng);
  map.fitBounds(viewportBounds);
}

Se tale volontà utile a voi.

Tutti i migliori

Dopo il calcolo dei boundries è possibile controllare la distanza in alto a sinistra e in basso a destra; allora si può capire il livello di zoom testando la distanza (se la distanza è troppo lontano il livello di zoom sarebbe basso) quindi è possibile selezionare anche depurato con il metodo setbound o setZoom ..

Non mi piace suggerire, ma se si deve provare - prima convocazione

gmap.fitBounds(bounds);

Quindi creare un nuovo thread / AsyncTask, farlo dormire per 20-50ms o giù di lì e quindi chiamare

gmap.setZoom( Math.max(6, gmap.getZoom()) );

dal thread UI (utilizzare un gestore o il metodo per onPostExecute AsyncTask).

Non so se funziona, solo un suggerimento. Diverso da quello che ci si deve calcolare in qualche modo il livello di zoom dai vostri punti da soli, controllare se è troppo basso, correggerla e poi basta chiamare gmap.setZoom(correctedZoom)

Se 'bounds_changed' non è sparare correttamente (a volte Google non sembra accettare perfettamente coordinate), quindi prendere in considerazione utilizzando 'center_changed' invece.

L'evento 'center_changed' spara ogni volta fitBounds () viene chiamato, anche se viene eseguito immediatamente e non necessariamente dopo che la mappa si è spostato.

In casi normali, 'inattivo' è ancora il migliore listener di eventi, ma questo può aiutare un paio di persone in esecuzione in problemi con i loro strani fitBounds () chiama.

google maps fitBounds callback

Per carillon con un'altra soluzione - ho trovato che l'approccio "ascoltare evento bounds_changed e quindi impostare nuovo zoom" non ha funzionato in modo affidabile per me. Penso che mi è stato a volte chiamando fitBounds prima che la mappa era stato completamente inizializzato, e l'inizializzazione stavo provocando un evento bounds_changed che avrebbe utilizzato l'ascoltatore, prima di fitBounds cambiato i confini e livello di zoom. Ho finito con questo codice, che sembra funzionare finora:

// If there's only one marker, or if the markers are all super close together,
// `fitBounds` can zoom in too far. We want to limit the maximum zoom it can
// use.
//
// `fitBounds` is asynchronous, so we need to wait until the bounds have
// changed before we know what the new zoom is, using an event handler.
//
// Sometimes this handler gets triggered by a different event, before
// `fitBounds` takes effect; that particularly seems to happen if the map
// hasn't been fully initialized yet. So we don't immediately remove the
// listener; instead, we wait until the 'idle' event, and remove it then.
//
// But 'idle' might happen before 'bounds_changed', so we can't set up the
// removal handler immediately. Set it up in the first event handler.

var removeListener = null;
var listener = google.maps.event.addListener(map, 'bounds_changed', () => {
  console.log(map.getZoom());
  if (map.getZoom() > 15) {
    map.setZoom(15);
  }

  if (!removeListener) {
    removeListener = google.maps.event.addListenerOnce(map, 'idle', () => {
      console.log('remove');
      google.maps.event.removeListener(listener);
    });
  }
});

Per me la soluzione più semplice era questa:

map.fitBounds(bounds);

function set_zoom() {
    if(map.getZoom()) {map.setZoom(map.getZoom() - 1);}
    else {setTimeout(set_zoom, 5);}
}
setTimeout(set_zoom, 5);
google.maps.event.addListener(marker, 'dblclick', function () {
    var oldZoom = map.getZoom(); 
    map.setCenter(this.getPosition());
    map.setZoom(parseInt(oldZoom) + 1);
});

Tutto quello che ho fatto è:

map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));

E funziona su V3 API.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top