2010-07-15 33 views
6

He creado un tipo de localizador de tiendas bastante complejo. El usuario ingresa su código postal y una tabla muestra los resultados con los marcadores correspondientes en un mapa. Pueden desplazarse a través de los resultados y los marcadores se mueven cada vez más y la función fitbounds() funciona muy bien para alejar al nivel de zoom apropiado para ajustarse a los marcadores. El problema es que si retrocede a ubicaciones más cercanas, el fitbounds() no se acerca. Incluso si ingresa una nueva búsqueda, no se acerca a esos nuevos marcadores, sino que se centra en ellos, pero permanece en el nivel de zoom que fue en previamente. Espero que esto tenga sentido. Si alguien sabe lo que necesito agregar para que vuelva a enfocar los resultados, por favor ayuda. Estas son las funciones de Google que estoy llamada al final de mi marcador de función de empuje:Google Maps API V3 fitbounds() se aleja pero nunca en

map.setCenter(bounds.getCenter()); 
    map.panToBounds(bounds); 
    map.fitBounds(bounds); 

Gracias!

Respuesta

0
map.setZoom(10); 

Creo que el rango aceptable es 1-20. Solo números enteros, decimales rompieron el mapa en mi experiencia.

4

Así es, fitBounds solo asegura que que los límites proporcionados son visibles. No amplía a un nivel apropiado.

Primero puede llamar al setZoom(20), luego fitBounds.

3

Hmm, interesante ... Utilizo PHP para recorrer todas las coordenadas del marcador (a ser) y calcular los valores de suroeste y noreste; los coords de origen están a medio camino entre los dos. Si todas las coordenadas del marcador están muy cerca la una de la otra, el factor de zoom establecido por fitBounds es mucho más alto (amplificado) que los 15 utilizados en la creación del mapa. Es por eso que he añadido la última fila ..

var map; 

function mapInit() { 
    var origin = new google.maps.LatLng(59.33344615, 18.0678188); 
    var options = { 
    zoom: 15, 
    center: origin, 
    mapTypeControlOptions: { 
     mapTypeIds: [google.maps.MapTypeId.ROADMAP, google.maps.MapTypeId.HYBRID] 
    }, 
    mapTypeId: google.maps.MapTypeId.ROADMAP 
    }; 

    map = new google.maps.Map(document.getElementById("googlemap"), options); 

    var southWest = new google.maps.LatLng(59.3308415, 18.0643054); 
    var northEast = new google.maps.LatLng(59.3360508, 18.0713322); 
    var bounds = new google.maps.LatLngBounds(southWest, northEast); 
    map.fitBounds(bounds); 

    google.maps.event.addListenerOnce(map, "idle", function() { 
    if (map.getZoom() > 16) map.setZoom(16); 
    }); 

Así que, ya sea Google ha reprogramado la función, ya que envió la pregunta o .. Necesito más información acerca de su código.

0
fitBounds: function(bounds, mapId) 
    { 
     //bounds: bounds, id: map id 
     if (bounds==null) return false; 
     maps[mapId].fitBounds(bounds); 
    }, 

Esto debería ayudar, utilizo este método y funciona bien, en el mapa v2 una manera un poco diferente.

7

No se necesita nada especial aquí. Primero ajuste los límites y luego desplácese hacia él. Esto le dará el zoom adecuado y contiene los límites completos.

map.fitBounds(bounds); 
map.panToBounds(bounds); 
+1

Esto parece funcionar. Me pregunto qué se supone que 'panToBounds' debe hacer sin' fitBounds'. – dbkaplun

9

El problema es el siguiente: nos propusimos

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

para que podamos encajar más tarde nuestros marcadores a un área delimitada en el mapa. GMaps siempre alejará de forma asíncrona a fitBounds() en consecuencia, pero no hará zoom para lograr lo mismo (como notado previamente por @broady). Esto no es ideal para muchas aplicaciones ya que una vez que se ha ido y muestra una serie de marcadores en el mapa que causaron que el mapa se aleje (quizás < 10), no volverá a acercarse sin que el usuario lo haga manualmente.

GMaps continuará utilizando los límites de la (falta de mejores palabras) la mayoría del estado de la colección de marcadores omitidos (lo siento). Establecer en 'nulo' antes de cada llamada de nuevos marcadores le brinda un mapa nuevo para trabajar.

Para acercar automáticamente, simplemente configure LatLngBounds(); a 'nulo' como tal (véase el ejemplo de pseudo continuación para ver su colocación):

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

Pseudo ejemplo:

// map stuff/initiation 
... 

var bounds = new google.maps.LatLngBounds(); 
var gmarkers = []; 

function CreateMarker (obj) { 
    myLatLng = new google.maps.LatLng(obj['latitude'], obj['longitude']); 
    marker = new google.maps.Marker({ 
     position: myLatLng, 
     map: map 
    }); 
    google.maps.event.addListener(marker, 'click', (function(marker, i) { 
     return function() { 
      infowindow.setContent(obj['job']); 
      infowindow.open(map, marker); 
     } 
    })(marker, i)); 
    bounds.extend(myLatLng); 
    gmarkers.push(marker); 
} 

.... 

// here's an AJAX method I use to grab marker coords from a database: 

$.ajax({ 
    beforeSend: function() { 
     clear_markers(gmarkers); // see below for clear_markers() function declaration 
    }, 
    cache: false, 
    data: params, 
    dataType: 'json', 
    timeout: 0, 
    type: 'POST', 
    url: '/map/get_markers.php?_=<?php echo md5(session_id() . time() . mt_rand(1,9999)); ?>', 
    success: function(data) { 
     if (data) { 
      if (data['count'] > 0) { 
       var obj; 
       var results = data['results']; 

       // Plot the markers 
       for (r in results) { 
        if (r < (data['count'])) { 
         CreateMarker(results[r]); 
        } 
       } 
      } 
     } 
    }, 
    complete: function() { 
     map.fitBounds(bounds); 
    } 
}); 

// clear_markers() 
function clear_markers(a) { 
    if (a) { 
     for (i in a) { 
      a[i].setMap(null); 
     } 
     a.length = 0; 
    } 
    bounds = new google.maps.LatLngBounds(null); // this is where the magic happens; setting LatLngBounds to null resets the current bounds and allows the new call for zoom in/out to be made directly against the latest markers to be plotted on the map 
} 
+0

¡Gracias John Smith! Tu sugerencia fue la única forma en que pude hacer que los míos volvieran a enfocar después de eliminar un marcador. Agradezco los detalles en tu publicación. – gorelog

+0

Gracias, hombre ... me salvaste el día :-) – Legionar

1

Resulta que cuando se llama a map.getBounds() devuelve la ventana gráfica con un poco de margen alrededor de los bordes. Como estos nuevos límites son más grandes que los límites actuales, el mapa siempre se alejará. Pude resolverlo evitando usar los límites del mapa actual y mantener una variable LatLngBounds por separado. Cada vez que he añadido un punto que llama:

markersBounds.extend(newMarkersLatLng); 
map.fitBounds(markersBounds); 
map.panToBounds(markersBounds); 

Para quitar puntos (que siempre estaba añadiendo ellos), usted podría hacer una nueva LatLngBounds objeto con el primer punto, luego se extienden cada punto restante para obtener sus nuevos límites:

var markersBounds = new google.maps.LatLngBounds(markers[0].getPosition(), 
               markers[0].getPosition()); 
for(var i=1; i<markers.length; i++){ 
    markersBounds.extend(markers[i].getPosition()); 
} 

map.fitBounds(markersBounds); 
map.panToBounds(markersBounds); 
1

también tuve un problema con el mapa zoom salida al llamar fitBounds por segunda vez en el mismo mapa con nuevos marcadores. Esta es la resolución de Frank que funciona para mí:

// This is a stationary point tho dynamic will work too 

var myLat = someLat, 
    myLng = someLong; 

var map = false, 
    markersArray = []; 

function makeOrderMap(lat, lng) { // pass in dynamic point when updating map 

    var mapOptions = { 
     center: new google.maps.LatLng(myLat, myLng), 
     zoom: 16, 
     mapTypeId: google.maps.MapTypeId.ROADMAP 
    }; 
    deleteOverlays(); // remove any existing markers.. 
    if(!map) { 
    map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions); 
    } 

    // Find the mid-point to center the map 

    midLat = (parseFloat(lat) + parseFloat(myLat))/2; 
    midLng = (parseFloat(lng) + parseFloat(myLng))/2; 
    map.setCenter(new google.maps.LatLng(midLat, midLng)); 
    var newSpot = new google.maps.LatLng(lat, lng); 

    placeMarker(mapOptions.center);  
    placeMarker(newSpot); 

    // determine the distance between points for deciding the zoom level 

    var dist = distHaversine(mapOptions.center, newSpot); 

    var zoom = 10; 
    if(dist < 1.25) { 
    zoom = 15; 
    } else if(dist < 2.5) { 
    zoom = 14; 
    } else if(dist < 5) { 
    zoom = 13; 
    } else if(dist < 10) { 
    zoom = 12; 
    } else if(dist < 20) { 
    zoom = 11; 
    } 
    map.setZoom(zoom); 
} 


rad = function(x) {return x*Math.PI/180;} 

distHaversine = function(p1, p2) { 
    var R = 6371; // earth's mean radius in km 
    var dLat = rad(p2.lat() - p1.lat()); 
    var dLong = rad(p2.lng() - p1.lng()); 

    var a = Math.sin(dLat/2) * Math.sin(dLat/2) + 
      Math.cos(rad(p1.lat())) * Math.cos(rad(p2.lat())) * Math.sin(dLong/2) * Math.sin(dLong/2); 
    var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
    var d = R * c; 

    return d.toFixed(3); 
} 

function deleteOverlays() { 
    if (markersArray) { 
     for (i in markersArray) { 
      markersArray[i].setMap(null); 
     } 
    markersArray = [];  
    markersArray.length = 0; 
    }  
} 

function placeMarker(location, alt_icon) { 

    var marker = new google.maps.Marker({ 
     position: location, 
     map: map 
     }); 

    // add marker in markers array 
    markersArray.push(marker); 
} 
+0

Gracias, lo conseguí trabajando desde tu implementación como un servicio angular: https://gist.github.com/zmijevik/047c40f4fc0bea27fd7c –

0

Hoy encontré este problema general, pensé en compartir una solución. Me doy cuenta de que esto es ligeramente diferente a su problema de 'localizador de tiendas', pero se aplica de muchas maneras. En mi caso, tengo una colección de marcadores en el mapa y estoy agregando uno, y quiero asegurarme de que todos los marcadores estén a la vista. Este código verifica cada marcador existente para ver si está en la vista, y en el camino, construye un nuevo cuadro delimitador que los contendría a todos, si es necesario. Al final, si se ha encontrado que alguno no está a la vista, la vista se restablece para que todos estén.

(este utiliza el módulo conjunto de Dojo, simplemente un envoltorio de conveniencia alrededor de iteración básica matriz)

var origBounds = map.getBounds(), 
    newBounds = new google.maps.LatLngBounds(null), 
    anyFailed = false; 
array.forEach(markers, function (m) { 
    newBounds.extend(m.position); 
    if (!origBounds.contains(m.position)) { 
     anyFailed = true; 
    } 
}); 
if (anyFailed) { 
    map.setCenter(newBounds.getCenter()); 
    map.fitBounds(newBounds); 
} 

uno podría fácilmente modificar esto para no garantizan más nuevo marcador está a la vista, al no bucle y sólo hacer una contiene() verificar el nuevo marcador.

Cuestiones relacionadas