2009-06-16 18 views
7

Estoy tratando de obtener los límites de un mapa después de que el zoom haya cambiado, pero el evento zoom_changed se activa antes de los límites se han vuelto a calcular. Entonces en el manejador zoom_changed obtienes los límites previos, no los nuevos límites.Obtener los límites de un mapa de Google v3 después del cambio de zoom

¿Hay alguna manera de obtener los límites adecuados para el cambio de zoom?

Respuesta

3

Desde el API documentation:

Si usted está tratando de detectar un cambio en la vista, asegúrese de utilizar el evento específico en lugar de bounds_changed constituyente zoom_changed y eventos center_changed. Debido a que la API de Maps dispara estos últimos eventos de forma independiente, get_bounds() puede no informar los resultados útiles hasta después de que la ventana gráfica haya cambiado de forma autorizada. Si desea obtener get_bounds() después de tal evento, asegúrese de escuchar el evento bounds_changed en su lugar.

+0

usando el evento bounds_changed en lugar de zoom_changed en este caso no tiene sentido. Se disparará en cualquier ocasión cuando se cambien los límites, pero solo le interesan los casos en los que se cambia el zoom. – TMS

+1

@ tomas-t No estoy de acuerdo con que el manejo del evento bounds_changed sea 'sin sentido'. Si está después de los límites cuando el zoom cambió, ¿no podría verificar getZoom en su controlador bounds_change? La documentación que publiqué justifica el comportamiento (error de borde del caso), pero la solución parece bastante simple para mí. – RedBlueThing

+0

por supuesto que puede hacerlo, pero para el caso en que OP quiere manejar el evento bounds_changed en lugar de zoom_changed es innecesario overkill, porque el evento se dispararía incluso durante el paneo, etc. Mire la solución en mi respuesta. – TMS

17

Este es un bug por favor, este número si está interesado.

Hay una solución fea para él:

google.maps.event.addListener(map, 'zoom_changed', function() { 
    google.maps.event.addListenerOnce(map, 'bounds_changed', function (e) { 
      my_zoom_handler(); // do your job here 
    }); 
}); 
+0

+1 Acepto que es un error y que la API no es intuitiva para este caso. Sería bueno si el zoom_change se envió una vez que se calcularon los nuevos límites. – RedBlueThing

+0

Este código no funcionará si el evento 'bounds_changed' llega antes del evento de zoom. 'Maps API dispara estos últimos eventos de forma independiente'. – mgPePe

+0

Gran solución. Cambié el evento interno-oyente a ''inactivo' 'en lugar de a' 'límites_cambiado'' ya que el evento'' bounds_changed'' se desencadena durante la animación. Creo que el OP quería que se activara después. – Todd

2

Para enlazar bounds_changed y trabajar con marcadores/mapa zoom cosas después de utilizar este:

google.maps.event.addListener(map, 'zoom_changed', function() { 
    this.zoomChanged = true; 
}); 

google.maps.event.addListener(map,"bounds_changed",function() { 
    if (this.zoomChanged) { 
     this.zoomChanged = false; 
     // DO YOUR STUFF 
    } 
}); 
0

tenía este mismo problema. Esto es lo que finalmente funcionó para resolver varios de los problemas que tuve con otras soluciones.

* hace cumplir correctamente los límites independientemente de si utiliza las teclas de flecha o el ratón

* no se detiene por debajo del borde si mantenga pulsado las teclas de flecha, debido a la aceleración bandeja haciendo que se "exceso" de la borde en un solo paso, por lo que se detiene en corto (intente mantener presionada la tecla de flecha en una dirección hasta llegar al borde, luego suéltela y presiónela nuevamente, y con algunas soluciones, se desplazará un poco más)

* No se "recupera" cuando toca el borde

* Impone correctamente los límites en el cambio de zoom

EDITAR: Ok, entonces funciona cuando se cambia el zoom con la rueda de desplazamiento, pero no con el control del zoom. Déjame jugar un poco con esto, y veré si puedo hacerlo funcionar también ...

EDIT 2: Resulta que el problema se debe a que eliminé el control de panorama. Siempre que el control de panorama esté presente, funciona bien, tanto con la rueda de desplazamiento como con el control del zoom.

EDIT 3: No ... eso no fue todo. Actualicé el código para manejar el control de zoom.

// bounds of the desired area 
var allowedBounds = new google.maps.LatLngBounds(
        new google.maps.LatLng(-64, -64), 
        new google.maps.LatLng(64, 64) 
        ); 

var zoomChanged = false; 

google.maps.event.addListener(map, 'center_changed', function() { 
    var mapBounds = map.getBounds(); 

    if(mapBounds.getNorthEast().lat() > allowedBounds.getNorthEast().lat()) { 
    var newCenter = new google.maps.LatLng(map.getCenter().lat() - 
              (mapBounds.getNorthEast().lat() - 
              allowedBounds.getNorthEast().lat()), 
              map.getCenter().lng(), true); 
    map.panTo(newCenter); 
    return; 
    } 

    if(mapBounds.getNorthEast().lng() > allowedBounds.getNorthEast().lng()) { 
    var newCenter = new google.maps.LatLng(map.getCenter().lat(), 
              map.getCenter().lng() - 
              (mapBounds.getNorthEast().lng() - 
              allowedBounds.getNorthEast().lng()), true); 
    map.panTo(newCenter); 
    return; 
    } 

    if(mapBounds.getSouthWest().lat() < allowedBounds.getSouthWest().lat()) { 
    var newCenter = new google.maps.LatLng(map.getCenter().lat() + 
              (allowedBounds.getSouthWest().lat() - 
              mapBounds.getSouthWest().lat()), 
              map.getCenter().lng(), true); 
    map.panTo(newCenter); 
    return; 
    } 

    if(mapBounds.getSouthWest().lng() < allowedBounds.getSouthWest().lng()) { 
    var newCenter = new google.maps.LatLng(map.getCenter().lat(), 
              map.getCenter().lng() + 
              (allowedBounds.getSouthWest().lng() - 
              mapBounds.getSouthWest().lng()), true); 
    map.panTo(newCenter); 
    return; 
    } 
}, this); 

google.maps.event.addListener(map, 'zoom_changed', function() { 
    zoomChanged = true; 
}, this); 

google.maps.event.addListener(map, 'bounds_changed', function() { 
    if(zoomChanged) { 
    var mapBounds = map.getBounds(); 

    if(mapBounds.getNorthEast().lat() > allowedBounds.getNorthEast().lat()) { 
     var newCenter = new google.maps.LatLng(map.getCenter().lat() - 
              (mapBounds.getNorthEast().lat() - 
              allowedBounds.getNorthEast().lat()), 
              map.getCenter().lng(), true); 
     map.panTo(newCenter); 
     return; 
    } 

    if(mapBounds.getNorthEast().lng() > allowedBounds.getNorthEast().lng()) { 
     var newCenter = new google.maps.LatLng(map.getCenter().lat(), 
              map.getCenter().lng() - 
              (mapBounds.getNorthEast().lng() - 
              allowedBounds.getNorthEast().lng()), true); 
     map.panTo(newCenter); 
     return; 
    } 

    if(mapBounds.getSouthWest().lat() < allowedBounds.getSouthWest().lat()) { 
     var newCenter = new google.maps.LatLng(map.getCenter().lat() + 
              (allowedBounds.getSouthWest().lat() - 
              mapBounds.getSouthWest().lat()), 
              map.getCenter().lng(), true); 
     map.panTo(newCenter); 
     return; 
    } 

    if(mapBounds.getSouthWest().lng() < allowedBounds.getSouthWest().lng()) { 
     var newCenter = new google.maps.LatLng(map.getCenter().lat(), 
              map.getCenter().lng() + 
              (allowedBounds.getSouthWest().lng() - 
              mapBounds.getSouthWest().lng()), true); 
     map.panTo(newCenter); 
     return; 
    } 

    zoomChanged = false; 
    } 
}, this); 
+0

Con este enfoque recibo errores de "demasiada recursividad". Si, en cambio, solo escucho el evento bounds_changed (ignorando center_changed y zoom_changed), este error desaparece. Por otro lado, los movimientos no son 100% perfectos, ya que todavía hay un rebote. –

+0

@ JoseGómez parece haber un problema específico de Google Chrome, pruébelo en Firefox. Lo busco más a fondo para ver si puedo corregir el problema. Vea esta pregunta: http://stackoverflow.com/questions/15671480/uncaught-rangeerror-maximum-call-stack-size-exceeded-google-maps-when-i-try-to – qwertymodo

+0

@ JoseGómez He resuelto el problema estableciendo v = 3 en la cadena de consulta para la secuencia de comandos API incluye línea. es decir, '' – qwertymodo

Cuestiones relacionadas