Google Maps: Zoom to Fit Markers no funciona cuando el mapa no es visible
-
23-09-2019 - |
Pregunta
Estoy usando la API V2 de Google Maps. Agrego marcadores al mapa y luego zoom para que se ajuste a esos marcadores. Esto funciona bien si el mapa es visible, hago esto. Pero si no, por ejemplo, si tengo un TabStrip, y la pestaña del mapa no se selecciona cuando la página se carga, cuando muestro el mapa, el nivel de zoom y el centro están equivocados.
Aquí hay un caso de prueba simple (usa jQuery):
<script type="text/javascript">
var scale = Math.random() * 20;
$(document).ready(function() {
var $container = $('#container');
// $container.hide();
var map = new GMap2($('#map')[0]);
$container.show();
var markerBounds = new GLatLngBounds();
for (var i = 0; i < 10; i++) {
var randomPoint = new GLatLng(38.935394 + (Math.random() - 0.5) * scale, -77.061382 + (Math.random() - 0.5) * scale);
map.addOverlay(new GMarker(randomPoint));
markerBounds.extend(randomPoint);
}
map.setCenter(markerBounds.getCenter(), map.getBoundsZoomLevel(markerBounds));
});
</script>
<div id="container">
<div id="map" style="margin: 100px; width: 450px; height: 300px;"></div>
</div>
Esto funciona bien como está, pero si te descompone $container.hide()
Todo está golpeado.
¿Hay alguna manera de hacer que la API de Google Maps funcione correctamente en un DIV que no sea visible?
Solución
Todo lo que tendrías que hacer es crear el GMaps2()
antes de nada. Entonces puedes hide()
el contenedor, agregue los puntos, obtenga el getBoundsZoomLevel()
, show()
De nuevo, y debería funcionar bien.
Prueba lo siguiente:
$(document).ready(function() {
var $container = $('#container');
// First create the Map.
var map = new GMap2($('#map')[0]);
// The container can be hidden immediately afterwards.
$container.hide();
// Now you can do whatever you like!
var markerBounds = new GLatLngBounds();
for (var i = 0; i < 10; i++) {
var randomPoint = new GLatLng( 38.935394 + (Math.random() - 0.5) * scale,
-77.061382 + (Math.random() - 0.5) * scale);
map.addOverlay(new GMarker(randomPoint));
markerBounds.extend(randomPoint);
}
map.setCenter(markerBounds.getCenter(), map.getBoundsZoomLevel(markerBounds));
// Finally unhide the container.
$container.show();
});
Otros consejos
Esto es lo que terminé haciendo, por lo que vale.
$(".TabPanel").watch("display,visibility", function() {
$(".MapContainer", this).each(function() {
if ($(this).is(":visible") == true) {
$(this).zoomToFitMarkers();
};
});
});
Esto usa El complemento de monitoreo de Rick Strahl para jQuery Para ver el panel de pestaña para obtener cambios de visibilidad y luego vuelve a aplicar la lógica de Zoom.
Para completar aquí está mi zoomToFitMarkers
extensión:
$.fn.zoomToFitMarkers = function() {
var map = this[0];
map.gmap.checkResize();
map.bounds = new GLatLngBounds();
if (!!map.gmap.getOverlays) {
for (i = 0; i < map.gmap.getOverlays.length; i++) {
map.bounds.extend(map.gmap.getOverlays[i].getLatLng());
}
if (map.bounds && !map.bounds.isEmpty()) {
var zoomLevel = map.gmap.getBoundsZoomLevel(map.bounds);
zoomLevel = zoomLevel > 9 ? 9 : zoomLevel;
zoomLevel = zoomLevel < 2 ? 2 : zoomLevel;
map.gmap.setCenter(map.bounds.getCenter(), zoomLevel);
}
}
map.gmap.checkResize();
};
Esto se basa en un par de convenciones:
El objeto GMAP2 se almacena en
map.gmap
, dóndemap
es el elemento DOM objetivo:var map= $("div#MapTarget")[0]; map.gmap = new google.maps.Map2(map);
Cada vez que se agrega un marcador al mapa, se almacena en una matriz para uso futuro:
var marker = new GMarker(point); map.gmap.addOverlay(marker); // Keep track of new marker in getOverlays array if (!map.gmap.getOverlays) map.gmap.getOverlays = new Array(); map.gmap.getOverlays.push(marker);