Fitbounds () de Google Maps API () effectue un zoom arrière, mais jamais

J’ai créé une sorte de localisateur de magasin assez complexe. L’utilisateur entre son zip et une table renvoie les résultats avec les marqueurs correspondants sur une carte. Ils peuvent parcourir les résultats et les marqueurs se déplacent de plus en plus loin et la fonction fitbounds() fonctionne parfaitement pour effectuer un zoom arrière sur le niveau de zoom approprié pour s’adapter aux marqueurs. Le problème est que si vous retournez à des emplacements plus proches, l’ fitbounds() ne fait pas un zoom avant. Même si vous saisissez une nouvelle recherche, il ne fait pas un zoom autour de ces nouveaux marqueurs. c’était à précédemment. J’espère que cela a du sens. Si quelqu’un sait ce que j’ai besoin d’append pour le faire revenir en arrière sur des résultats plus proches, aidez-nous. Voici les fonctions google que j’appelle à la fin de ma fonction de repérage:

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

Merci!

Le problème est le suivant: nous mettons

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

afin que nous puissions ensuite adapter nos marqueurs à une zone délimitée sur la carte. GMaps effectuera toujours un zoom arrière de manière asynchrone sur fitBounds (), mais ne fera pas un zoom avant pour obtenir le même résultat (comme noté précédemment par @broady). Ce n’est pas idéal pour de nombreuses applications, car une fois que vous avez affiché une série de marqueurs sur la carte qui ont provoqué un zoom arrière (peut-être <10), elle ne fera pas un zoom avant sans que l'utilisateur le fasse manuellement.

GMaps continuera à utiliser les limites du statut de collection de marqueurs le plus zoomé (manque de mots meilleurs) (désolé). Régler sur ‘null’ avant chaque appel de nouveaux marqueurs vous donne une nouvelle carte à utiliser.

Pour effectuer un zoom automatique, définissez simplement LatLngBounds (); pour ‘null’ comme ceci (voir le pseudo exemple ci-dessous pour voir son emplacement):

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

Pseudo exemple:

 // 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?_=', 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 } 

Rien d’extraordinaire nécessaire ici. Commencez par ajuster les limites, puis effectuez un panoramique. Cela vous donnera le bon zoom et contiendra l’ensemble des limites.

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

En effet, fitBounds garantit uniquement que les limites fournies sont visibles. Il ne zoom pas à un niveau approprié.

Vous pouvez d’abord appeler setZoom(20) , puis fitBounds.

Hmm, intéressant .. J’utilise PHP pour parcourir toutes les coordonnées du marqueur (et être) et calculer les valeurs de southWest et northEast; les coords d’origine sont à mi-chemin entre les deux. Si toutes les coordonnées des marqueurs sont très proches les unes des autres, le facteur de zoom défini par fitBounds est beaucoup plus élevé (zoom avant) que les 15 utilisés lors de la création de la carte. C’est pourquoi j’ai ajouté cette dernière rangée ..

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

Donc, soit Google a reprogrammé la fonction depuis que vous avez posté la question ou .. J’ai besoin de plus d’informations sur votre code.

J’ai également eu un problème avec le zoom de la carte lorsque j’ai appelé fitBounds une seconde fois sur la même carte avec de nouveaux marqueurs. C’est la solution frankens qui fonctionne pour moi:

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

Lorsque vous appelez map.getBounds() il retourne la fenêtre d’affichage avec une petite marge autour des bords. Comme ces nouvelles limites sont plus grandes que les limites actuelles, la carte effectuera toujours un zoom arrière. J’ai pu résoudre ce problème en évitant d’utiliser les limites de la carte actuelle et en maintenant une variable LatLngBounds distincte. Chaque fois que j’ai ajouté un point, j’ai appelé:

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

Pour supprimer des points (je les ajoutais toujours), vous pouvez créer un nouvel object LatLngBounds avec le premier point, puis étendre chaque point restant pour obtenir vos nouvelles limites:

 var markersBounds = new google.maps.LatLngBounds(markers[0].getPosition(), markers[0].getPosition()); for(var i=1; i 
 map.setZoom(10); 

Je crois que la fourchette acceptable est 1-20. Les nombres entiers seulement, les nombres décimaux ont brisé la carte dans mon expérience.

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

Cela devrait aider, j’utilise cette méthode et fonctionne bien, sur la carte v2 d’une manière un peu différente.

J’ai rencontré ce problème général aujourd’hui, je pensais partager une solution. Je me rends compte que ceci est légèrement différent de votre problème de «localisateur de magasin», mais cela s’applique à bien des égards. Dans mon cas, j’ai une collection de marqueurs sur la carte et j’en ajoute une, et je veux m’assurer que tous les marqueurs sont maintenant visibles. Ce code vérifie chaque marqueur existant pour voir s’il se trouve dans la vue et, en cours de route, crée un nouveau cadre de sélection qui les contiendrait tous, si nécessaire. À la fin, s’il s’avère que certains ne sont pas visibles, la vue est réinitialisée et ils le sont tous.

(ceci utilise le module de tableau de Dojo, simplement un wrapper de commodité autour de l’itération de tableau de base)

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

On pourrait facilement modifier cela pour s’assurer que le nouveau marqueur est visible, en ne faisant pas de boucle et en effectuant simplement une vérification de contient () sur le nouveau marqueur.

Ce qui m’a aidé, c’est d’utiliser 0 padding comme second paramètre de fitBounds (bounds, padding):

 var worldBounds = new google.maps.LatLngBounds( new google.maps.LatLng(70.4043,-143.5291), //Top-left new google.maps.LatLng(-46.11251, 163.4288) //Bottom-right ); map.fitBounds(worldBounds, 0);