Pregunta

Tengo un conjunto de puntos que desea trazar en una mapa de Google insertado (versión 3 del API). Me gustaría que los límites para dar cabida a todos los puntos menos que el nivel de zoom es demasiado baja (es decir, está reducida demasiado). Mi enfoque ha sido la siguiente:

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

// extend bounds with each point

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

Esto no funciona. La última línea "gmap.setZoom ()" no cambia el nivel de zoom del mapa si es llamado directamente después fitBounds.

¿Hay una manera de conseguir el nivel de zoom de un rival sin aplicarla al mapa? Otras ideas para resolver esto?

¿Fue útil?

Solución

Editar . Véase el comentario de Matt rombo debajo de

¡Gracias! Prueba esto:

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

Modificar a sus necesidades.

Otros consejos

He resuelto un problema similar en una de mis aplicaciones. Yo estaba un poco confundido por su descripción del problema, pero creo que tiene el mismo objetivo que tenía ...

En mi aplicación que quería trazar un uno o más marcadores y garantizar el mapa estaba mostrando a todos. El problema era que, si se basó únicamente en el método fitBounds, entonces el nivel de zoom estaría al tope cuando había un solo punto - que no era bueno

.

La solución fue usar fitBounds cuando había muchos puntos, y setCenter + setZoom cuando sólo había un punto.

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

Me han llegado a esta página varias veces para obtener la respuesta, y mientras todas las respuestas existentes eran muy útiles, no han conseguido solucionar mi problema exactamente.

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

Básicamente me encontré con que el evento 'zoom_changed' impidió que la interfaz de usuario del mapa de "saltar", que ocurrió cuando esperaba para el evento 'inactivo'.

Espero que esto ayude a alguien!

He acaba de arreglar esto mediante el establecimiento MaxZoom por adelantado, después de retirarlo después. Por ejemplo:

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

Si no estoy equivocado, estoy asumiendo que usted desea que todos sus puntos sean visibles en el mapa con el más alto nivel de zoom posible. He logrado esto mediante la inicialización del nivel de zoom del mapa para 16 (no estoy seguro si es el más alto nivel de zoom posible en V3).

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

A continuación, después de que hice lo límites cosas:

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

Resultado:  Éxito!

Yo uso:

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

Esto utilizará el menor de 24 y el nivel de zoom necesario de acuerdo con su código, sin embargo es probable que cambie el zoom de todos modos y no se preocupa por cuánto has alejado.

Yo tenía el mismo problema y que era capaz de resolverlo usando el siguiente código. Este evento (google.maps.addListenerOnce()) escucha solamente será despedida una vez, justo después de que se ejecute map.fitBounds(). Por lo tanto, no hay necesidad de

  1. No pierda de vista y quitar manualmente el oyente, o
  2. Espere hasta que el mapa es idle.

Se establece el nivel de zoom adecuado inicialmente y permite al usuario hacer zoom dentro y fuera más allá del nivel de zoom inicial, porque el detector de eventos ha expirado. Por ejemplo, si sólo se google.maps.addListener() fue llamado, a continuación, el usuario no ser capaz de acercarse con el zoom más allá del nivel de zoom indicado (en el caso, 4). Desde que implementamos google.maps.addListenerOnce(), el usuario será capaz de acercar a cualquier nivel que él / ella elija.

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

tenía el mismo problema, es necesario para adaptarse a muchos marcadores en el mapa. Esto resolvió mi caso:

  1. Declarar límites
  2. Uso esquema proporcionado por koderoid (para cada bounds.extend(objLatLng) marcador conjunto)
  3. Ejecutar fitbounds DESPUÉS mapa se completó:

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

He encontrado una solución que hace el cheque antes de llamar fitBounds por lo que no acercar y alejar la imagen de repente

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

Vas a tener que jugar un poco con la variable minLatSpan un poco para conseguir el lugar que desee. Se puede variar en función de zoom tanto nivel y las dimensiones de la vista del mapa.

También puede utilizar la longitud en lugar de latitud

Por favor, intente lo siguiente:

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

vi muchas soluciones incorrectas o demasiado complicados, por lo que decidió publicar un trabajo, solución elegante .

La razón setZoom() no funciona como se espera es que fitBounds() es asíncrona, por lo que no da ninguna garantía de que sería actualizar inmediatamente el zoom, pero su llamada a setZoom() se basa en eso.

Lo que se podría considerar el establecimiento de la opción mapa minZoom antes de llamar fitBounds() y luego borrarlo después de que se completa (de modo que los usuarios pueden hacer zoom de forma manual si quieren):

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

Además, si desea limitar también el zoom máximo, se puede aplicar el mismo truco con la propiedad maxZoom.

Vea la MapOptions docs .

Lo utilizo para garantizar el nivel de zoom no exceda de un nivel establecido para que yo sepa imágenes de satélite estarán disponibles.

Añada un receptor para el evento zoom_changed. Esto tiene la ventaja añadida de controlar el control de zoom en la interfaz de usuario también.

Sólo ejecutar setZoom si es necesario, por lo que una declaración if es preferible Math.max o para 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);

Para evitar el zoom alejado demasiado:

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

En esta función, es necesario agregar dinámicamente metadatos para almacenar el tipo de geometría sólo porque la función acepta cualquier geometría.

"fitGeometries" es una función JSON se extiende un objeto de mapa.

"geometrías" es un no array javascript genérico 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);
},

de este trabajo para mí con versión 3 del API pero con ajuste de zoom fijo:

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

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

Al igual que yo, si no está dispuesto a jugar con los oyentes, esta es una solución sencilla me ocurrió: Añadir un método en el mapa que funciona estrictamente de acuerdo a sus necesidades como ésta:

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

A continuación, puede llamar a map.fitLmtdBounds(bounds) en lugar de map.fitBounds(bounds) para establecer los límites por debajo del rango de zoom definido ... o map.fitLmtdBounds(bounds,3,5) para anular el intervalo de zoom ..

Por favor, intente esto.

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

Si esta voluntad de utilidad.

Todo lo mejor

Después del cálculo de los limites se puede comprobar la distancia entre la esquina superior izquierda y abajo a la derecha; a continuación, se puede entender el nivel de zoom mediante pruebas de la distancia (si la distancia es demasiado nivel de zoom sería baja), entonces usted puede seleccionar wheter utilizando el método SetBound o setZoom ..

No me gusta sugerir, pero si debe tratar - primera llamada

gmap.fitBounds(bounds);

A continuación, crear un nuevo Tema / AsyncTask, tienen que dormir por 20-50ms más o menos y luego llamar

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

desde el hilo de interfaz de usuario (utilizar un controlador o el método onPostExecute para AsyncTask).

No sé si funciona, sólo una sugerencia. Aparte de eso habría que calcular de alguna manera el nivel de zoom en sus puntos de ti mismo, y comprueba si es demasiado baja, corregirlo y luego simplemente llamar gmap.setZoom(correctedZoom)

Si (no parece a veces Google para aceptar las coordenadas perfectamente) 'bounds_changed' no se activan correctamente, a continuación, considere el uso de 'center_changed' en su lugar.

El evento 'center_changed' dispara cada vez que fitBounds () se llama, a pesar de que se ejecuta inmediatamente y no necesariamente después de que el mapa se ha movido.

En los casos normales, 'inactivo' sigue siendo el mejor detector de eventos, pero esto puede ayudar a un par de personas se produzcan problemas extraños con sus fitBounds () llama.

google maps fitBounds callback

Para meter su cuchara con otra solución - He encontrado que el enfoque de "escuchar para el evento bounds_changed a continuación, establecer nuevo zoom" no funciona de forma fiable para mí. Creo que a veces me estaba llamando fitBounds antes de que el mapa había sido totalmente inicializado, y la inicialización estaba causando un evento bounds_changed que utilizaría el oyente, antes fitBounds cambió los límites y el nivel de zoom. Terminé con este código, que parece funcionar hasta el momento:

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

Para mí la solución más fácil era la siguiente:

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

Todo lo que hice es:

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

Y funciona en API V3.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top