10
votes

Google Maps API V3 Fitbounds () zooms mais jamais dans

J'ai créé un localisateur de magasins assez complexes. L'utilisateur entre dans leur zip et une table renvoie des résultats avec les marqueurs correspondants sur une carte. Ils peuvent utiliser des résultats et les marqueurs de plus en plus et plus loin et la fonction Fitbounds () fonctionne très bien pour zoomer sur le niveau de zoom approprié pour adapter les marqueurs. Le problème est que si vous revenez sur des localités de plus près, le Fitbounds () ne fait pas zoomer. Même si vous entrez une nouvelle recherche, il ne fait pas zoomer autour de ces nouveaux marqueurs - il est centré sur eux mais reste à n'importe quel niveau de zoom auparavant. J'espère que cela a du sens. Si quelqu'un sait ce que je dois ajouter pour l'obtenir pour effectuer un zoom avant sur des résultats plus proches, veuillez vous aider. Ce sont les fonctions Google que je appelle à la fin de ma marque de repousse de marqueur: xxx

merci!


0 commentaires

12 Réponses :


0
votes
map.setZoom(10);
I believe the acceptable range is 1-20. Whole numbers only, decimals broke the map in my experience.

0 commentaires

6
votes

C'est vrai, Fitbounds Seul garantit que les limites fournies sont visibles. Il ne fait pas zoomer à un niveau approprié.

Vous pouvez d'abord appeler setzoom (20) , puis Fitbounds.


1 commentaires

Pour que toute personne lise cela plus tard, Fitbounds zoomez avec les versions actuelles, Pantobounds ne correspond pas et correspond à ce qui est décrit ci-dessus.



4
votes

hmm, intéressant .. J'utilise php pour boucle à travers tous les coordonnées du marqueur (comme étant) et calculer les valeurs du sud-ouest et du nord-est; Les coordonnées d'origine sont à mi-chemin entre les deux. Si tous les coordonnées du marqueur sont très proches les uns des autres, le facteur de zoom défini par Fixtbounds est beaucoup plus élevé (zoomé dans) que les 15 utilisés dans la création de la carte. C'est pourquoi j'ai ajouté que la 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);
  });


1 commentaires

Merci seulement cette chose travaillée pour moi a essayé de nombreuses solutions modifiées peu avec mes exigences Google.maps.event.addlisteneronce (carte, "inactif", fonction () {if (map.getzoom ()



0
votes
fitBounds: function(bounds, mapId)
    {
        //bounds: bounds, id: map id
        if (bounds==null) return false;
        maps[mapId].fitBounds(bounds);
    },  
This should help, i use this method and works fine, on map v2 a little bit different way.

0 commentaires

11
votes

Rien de fantaisie nécessaire ici. Les premières limites d'ajustement sont alors plates. Cela vous donnera le zoom approprié et contient toutes les limites.

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


1 commentaires

Cela semble fonctionner. Je me demande ce que panobounds est censé faire sans Fitbounds .



10
votes

Le problème est celui-ci: nous définissons

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


1 commentaires

Merci John Smith! Votre suggestion était la seule façon de réaliser le mien pour effectuer un zoom avant après avoir supprimé un marqueur. J'apprécie les détails dans votre message.



2
votes

Il s'avère que lorsque vous appelez map.getbounds () Il renvoie la fenêtre avec une petite marge autour des bords. Étant donné que ces nouvelles limites sont plus grandes que les limites actuelles, la carte effectuera toujours un zoom arrière. J'ai été capable de le résoudre en évitant d'utiliser complètement les limites de la carte actuelle et en maintenant une variable distincte en letterbounds. Chaque fois que j'ai ajouté un point, j'ai appelé: xxx

pour supprimer les points (je les ajoutais toujours), vous pouvez créer un nouvel objet LATLNGBONDS avec le premier point, puis prolonger chaque point restant pour obtenir vos nouvelles limites: xxx


0 commentaires

3
votes

J'ai également eu un problème avec la carte de zoom de la carte lorsque vous appelez Fitbounds une seconde fois sur la même carte avec de nouveaux marqueurs. C'est la franchise de Frankensolution 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);
}


1 commentaires

Merci, vous avez travaillé de votre mise en œuvre en tant que service angulaire: Gist.github.com/zmijevik/047C40F4FC0BEA27FD7C



1
votes

J'ai rencontré ce problème général aujourd'hui, pensais que je partagerais une solution. Je me rends compte que cela 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 en ajoutant une, et souhaitez vous assurer que tous les marqueurs sont maintenant en vue. Ce code vérifie chaque marqueur existant pour voir si c'est à la vue et sur le chemin, crée une nouvelle boîte de sélection qui les contiendrait tous, si nécessaire. À la fin, le cas échéant, si vous n'avez pas été vu, la vue est réinitialisée afin qu'elles soient toutes.

(Ceci utilise le module de tableau de Dojo, simplement une enveloppe de commodité autour de l'itération de la matrice de base) p>

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


0 commentaires

4
votes

Qu'est-ce qui m'a aidé à utiliser 0 rembourrage comme deuxième paramètre sur Fixturations (limites, rembourrage), voici l'exemple de code complet:

function initMap() {
    var mapOptions = {
        center: new google.maps.LatLng(0, 0),
        zoom: 1,
        minZoom: 1
    };
    map = new google.maps.Map(document.getElementById('officeMap'), mapOptions);
    google.maps.event.addListenerOnce(map, 'idle', function() {
        //Map is ready
        worldViewFit(map);
    });
}
function worldViewFit(mapObj) {
    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
    );
    mapObj.fitBounds(worldBounds, 0);
    var actualBounds = mapObj.getBounds();
    if(actualBounds.getSouthWest().lng() == -180 && actualBounds.getNorthEast().lng() == 180) {
        mapObj.setZoom(mapObj.getZoom()+1);
    }
}


1 commentaires

Après avoir passé une journée de recherche et de débogage, cette réponse était la solution. Merci Tom.



0
votes

Assurez-vous qu'il n'y a pas d'animations CSS sur la largeur ou la hauteur de votre carte. Les animations interfèrent avec le comportement de zoom de Fitbound ()

J'ai passé la majeure partie de la journée sur ce problème hier, et j'ai rencontré cet article sur StackoverFlow au moins une douzaine de fois. Mais je devais finalement trouver le problème le problème difficile. p>

Suppression de la transition : toutes les 0,5% facilité; Code> La ligne ci-dessous résolue pour moi. P>

.google-map {
  width: 100%;
  height: 0px;
  transition: all 0.5s ease;
}

.google-map.loaded {
    height: 400px;
}


0 commentaires

1
votes

Vérifiez cette citation de la documentation GMAP sur marqueur.setmap (null); code> (utilisé pour supprimer les marqueurs d'une carte):

Notez que la méthode ci-dessus ne supprime pas fort> le marqueur. Il supprime le marqueur de la carte. Si au lieu de cela, vous souhaitez supprimer le marqueur, vous devrait l'enlever de la carte, puis réglez le marqueur lui-même sur NULL. P> BlockQuote>

Mon problème était que lorsque je retiens les marqueurs de la carte, ils étaient toujours stockés dans Map.Markers Code>. Donc lors de la réglage limites code>, il saisit tous les marqueurs précédents également: P> xxx pré>

console.logging limites code> a montré que les limites seraient Toujours accueillir toutes les limites antérieures à cause de cela. P>

Ma solution consistait à garder une trace des marqueurs dans un marqueurs code> tableau / objet qui stocke une clé unique pour chaque marqueur (dans mon Cas lié à un champ de saisie de Places Autocomplete) et retirez un marqueur de celui-ci lors de la suppression du marqueur d'une carte. De cette façon, je peux exécuter un chèque lors de la génération de limites code> pour voir si le marqueur actuel dans map.markers code> est dans le (Mise à jour) marqueurs Code> Array. P>

map.markers.forEach( (marker) => {
  // check if map marker is in this.markers (to make sure only current)
  for (const [key, value] of Object.entries(markers)) {
    if (marker == value) {
      var latlng = new google.maps.LatLng(marker.position.lat(), marker.position.lng())
      bounds.extend(latlng)
    }
  }
})


0 commentaires