2010-07-26 32 views
65

¿Hay alguna forma de establecer un nivel de zoom máximo para fitBounds()? Mi problema es que cuando el mapa solo se alimenta con una ubicación, se acerca todo lo que puede, lo que realmente saca el mapa del contexto y lo deja inútil. Tal vez estoy tomando el enfoque equivocado?Google Maps v3 fitBounds() Zoom demasiado cerca para marcador individual

¡Gracias de antemano!

+2

http: // stackoverflow.com/questions/4523023/using-setzoom-after-using-fitbounds-with-google-maps-api-v3 es una solución mucho mejor. Particular @Nequins respuesta – Kennet

Respuesta

10

Si se trata de una única ubicación, puede usar setCenter() y setZoom() en su lugar.

+0

La solución más fácil –

21

Otra solución es ampliar los límites si detecta que son demasiado pequeños antes de ejecutar fitBounds():

var bounds = new google.maps.LatLngBounds(); 
// here you extend your bound as you like 
// ... 
if (bounds.getNorthEast().equals(bounds.getSouthWest())) { 
    var extendPoint = new google.maps.LatLng(bounds.getNorthEast().lat() + 0.01, bounds.getNorthEast().lng() + 0.01); 
    bounds.extend(extendPoint); 
} 
map.fitBounds(bounds); 
+0

funciona perfectamente en mi caso. – trungk18

98

me gusta la solución de MRT (especialmente cuando no se sabe la cantidad de puntos que será mapeado o ajustando para), excepto que tira el marcador de manera que ya no esté en el centro del mapa. Simplemente lo extendí por un punto adicional restando .01 del lat y lng también, por lo que mantiene el marcador en el centro. Funciona muy bien, gracias mrt!

// Pan & Zoom map to show all markers 
function fitToMarkers(markers) { 

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

    // Create bounds from markers 
    for(var index in markers) { 
     var latlng = markers[index].getPosition(); 
     bounds.extend(latlng); 
    } 

    // Don't zoom in too far on only one marker 
    if (bounds.getNorthEast().equals(bounds.getSouthWest())) { 
     var extendPoint1 = new google.maps.LatLng(bounds.getNorthEast().lat() + 0.01, bounds.getNorthEast().lng() + 0.01); 
     var extendPoint2 = new google.maps.LatLng(bounds.getNorthEast().lat() - 0.01, bounds.getNorthEast().lng() - 0.01); 
     bounds.extend(extendPoint1); 
     bounds.extend(extendPoint2); 
    } 

    map.fitBounds(bounds); 

    // Adjusting zoom here doesn't work :/ 

} 
+3

Buena idea para mantener el centro original. La razón por la que el nivel de zoom no se puede ajustar de manera confiable cuando se utiliza el método 'fitBounds()' es porque el zoom se está produciendo de forma asíncrona: http://stackoverflow.com/questions/2989858/google-maps-v3-enforcing-min-zoom -level-when-using-fitbounds/2990316 # 2990316 –

+1

Esto funcionó muy bien para mí. Tuve que pasar la referencia del mapa a la función "function fitToMarkers (marcadores, mapa)" en V3, ¡pero funciona como un amuleto después de eso! – Shane

+2

Me encanta eso. Bueno, @ryan. Funcionó muy bien para mí, pero .01 en mi caso se alejó demasiado, .001 tocó el punto óptimo. – willdanceforfun

24

Usted puede configurar su mapa con maxZoom en el MapOptions(api-reference) así:

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

Esto mantendría el mapa de zoom más profundo cuando se utiliza fitBounds() e incluso elimina los niveles de zoom de la control de zoom

+0

Este usuario no puede configurar manualmente el zoom. – candlejack

+0

@candlejack ¿Exactamente como se describe en mi respuesta? – Flygenring

+2

Puede establecer el 'maxZoom' antes de ajustar los límites y luego volver a desactivarlo usando' map.setOptions ({maxZoom: undefined}) 'en el evento' inactivo 'disparado al cambiar los límites. Esto evita el efecto de acercar, alejar o restablecer el zoom en el evento 'inactivo'. –

6

La forma evito el mapa de acercamiento a la medida es mediante la adición de esta línea de código:

var zoomOverride = map.getZoom(); 
     if(zoomOverride > 15) { 
     zoomOverride = 15; 
     } 
     map.setZoom(zoomOverride); 

Inmediatamente después de esta línea:

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

Siéntase libre para cambiar el nivel de zoom para sea ​​cual sea el nivel, no quiere que el mapa se acerque.

Si tiene algún problema o pregunta, me acaba de dejar un comentario en el blog que escribí sobre esto en http://icode4you.net/creating-your-own-store-locator-map-how-to-prevent-the-map-from-zooming-in-too-close-on-a-single-marker

+1

Me gusta esta solución, pero inserte el setzoom dentro si no lo llama cada vez. También podría haber un efecto secundario de tiempo que devuelva 'indefinido' de getzoom(). Solución: zoom = map.getZoom(); if (typeof zoom! == 'undefined' && zoom> 8) map.setZoom (8); –

3

me gusta mucho la solución de MRT y funciona perfectamente si has siempre sólo tiene un punto a trabajar con. Sin embargo, encontré que si el cuadro delimitador no se basaba en un punto, sino que los puntos estaban muy juntos, esto aún podría hacer que el mapa se acercara demasiado.

Aquí está una manera comprobar primero si los puntos están a una distancia definida entre sí, a continuación, si son más pequeñas que la distancia mínima, se extienden los límites de esa distancia mínima:

var bounds = new google.maps.LatLngBounds(); 
// here you extend your bound as you like 

// ... 

var minDistance = 0.002; 
var sumA = bounds.getNorthEast().lng() - bounds.getSouthWest().lng(); 
var sumB = bounds.getNorthEast().lat() - bounds.getSouthWest().lat(); 

if((sumA < minDistance && sumA > -minDistance) 
&& (sumB < minDistance && sumB > -minDistance)){ 
var extendPoint1 = new google.maps.LatLng(bounds.getNorthEast().lat() + minDistance, bounds.getNorthEast().lng() + minDistance); 
    var extendPoint2 = new google.maps.LatLng(bounds.getNorthEast().lat() - minDistance, bounds.getNorthEast().lng() - minDistance); 
    bounds.extend(extendPoint1); 
    bounds.extend(extendPoint2); 
} 

Espero que esto ayude ¡alguien!

0

Tengo una salsa basada en la limitación del zoom máximo al ajustar los límites. Funciona para mí (probado en Windows 7 - IE 9, 13 FF, Chrome 19):

// When fitting bounds: 
var bounds = new google.maps.LatLngBounds(); 
// ... 
// extend bounds as you like 
// .. 

// now set global variable when fitting bounds 
window.fittingBounds = true; 
map.fitBounds(bounds); 
window.fittingBounds = false; 


// attach this event listener after map init 
google.maps.event.addListener(map, 'zoom_changed', function() { 
    // set max zoom only when fitting bounds 
    if (window.fittingBounds && map.getZoom() > 16) { 
     this.setZoom(16); 
    } 
}); 
16
var map = new google.maps.Map(document.getElementById("map"), { maxZoom: 10 }); 

Mediante la opción MaxZoom funciona mejor para no hacer zoom para cerrar a las marcas que tiene.

+1

+1 directo! – Tamir

+0

simple y excelente ... – Lupin

+0

mejor y más fácil solución. ¡Gracias! –

0

Y ... aquí hay otro.
La misma idea que MRT y Ryan, pero

  • también funciona si el tamaño de los límites no es exactamente igual a cero (*)
  • evita la distorsión cerca de los polos
  • utiliza getCenter() en lugar de getNorthEast()

(*) Nota: Si el cuadro es ya lo suficientemente grande, a continuación, añadir los dos puntos extra debería tener ningún efecto. Entonces no necesitamos ninguna verificación adicional.

function calcBounds(markers) { 
    // bounds that contain all markers 
    var bounds = new google.maps.LatLngBounds(); 
    // Using an underscore _.each(). Feel free to replace with standard for() 
    _.each(markers, function(marker) { 
    bounds.extend(marker.getPosition()); 
    }); 
    // prevent lat/lng distortion at the poles 
    var lng0 = bounds.getNorthEast().lng(); 
    var lng1 = bounds.getSouthWest().lng(); 
    if (lng0 * lng1 < 0) { 
    // Take the cos at the equator. 
    var cos = 1; 
    } 
    else { 
    var cos0 = Math.cos(lng0); 
    var cos1 = Math.cos(lng1); 
    // Prevent division by zero if the marker is exactly at the pole. 
    var cos_safe = Math.max(cos0, cos1, 0.0001); 
    } 
    var cos0 = Math.cos(bounds.getNorthEast.lng() * Math.PI/180); 
    var cos1 = Math.cos(bounds.getSouthWest.lng() * Math.PI/180); 
    // "radius" in either direction. 
    // 0.0006 seems to be an ok value for a typical city. 
    // Feel free to make this value a function argument. 
    var rLat = 0.0006; 
    var rLng = rLat/cos_safe; 
    // expand the bounds to a minimum width and height 
    var center = bounds.getCenter(); 
    var p0 = new google.maps.LatLng(center.lat() - rLat, center.lng() - rLng); 
    var p1 = new google.maps.LatLng(lat.center() + rLat, center.lng() + rLng); 
    bounds.extend(p0); 
    bounds.extend(p1); 
    return bounds; 
} 

EDIT: no estoy muy seguro de si mi relación de cálculo correctamente, teniendo en cuenta que tenemos una proyección de Mercator. Podría volver a editar este ..

9

u puede utilizar

map.setOptions({ 
    maxZoom: [what u want], 
    minZoom: [what u want] 
}); 

esta manera u establezca las propiedades del mapa después de que el mapa se ha inicializado .... u puede establecer tantas veces como u quieren ... pero en caso de ur ... u puede establecer antes de fitBounds()

buena suerte, rarutu

+0

¡Perfecto! Gracias ;) – RevConcept

2

Esto le da un control directo sobre máximo permitido de zoom en los límites de ajuste.

var fitToMarkers = function(map, markers, maxZoom) { 
    if (typeof maxZoom == 'undefined') maxZoom = 15; 

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

    var bounds = new google.maps.LatLngBounds(); 
    for (var m = 0; m < markers.length; m++) { 
     var marker = markers[m]; 
     var latlng = marker.getPosition(); 
     bounds.extend(latlng); 
    } 

    map.fitBounds(bounds); 
}; 
2

he resuelto con este trozo, ya que Google Maps V3 es dirigido por eventos:

se puede decir de la API de hacer retroceder el zoom a una cantidad adecuada cuando el zoom_changed activadores de eventos:

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

Yo usé intial hacer que el mapa no se acerque demasiado cuando se cargan los eventuales fitBeads permorfed, sin ningún evento de zoom sobre 11 sería imposible para el usuario.

7

Una vez añadidos todos los bienes límites añaden estas líneas

var offset = 0.002;  
var center = bounds.getCenter();        
bounds.extend(new google.maps.LatLng(center.lat() + offset, center.lng() + offset)); 
bounds.extend(new google.maps.LatLng(center.lat() - offset, center.lng() - offset)); 

que llegar al centro de los límites reales se le añaden dos puntos adicionales uno al noreste y uno al suroeste de centrar

Esto establece efectivamente el mínimo de zoom, cambiar el val ue de desplazamiento para aumentar o disminuir el zoom

0

Después de llamar fitBounds() método, tratar de nivel de zoom de instalación de nuevo. Obligará al mapa a estar en ese nivel de zoom mientras está centrado en el lugar correcto.

0

En cuanto a mí chicos lo resuelvo mediante la creación de un evento de inactividad después fitBounds. Funcionando perfectamente Supongo que es una de las soluciones más limpias aquí

var locations = [['loc', lat, lng], ['loc', lat, lng]]; 
..... 
for (i = 0; i < locations.length; i++) { 
    var map = new google.maps.Map(document.getElementById('map'), { 
    zoom: 10 
    }); 
    .... create markers, etc. 
} 
.... 
map.fitBounds(bounds); 
google.maps.event.addListenerOnce(map, 'idle', function() { 
    if (locations.length == 1) { 
    map.setZoom(11); 
    } 
}); 
Cuestiones relacionadas