Question

J'ai un ensemble de points que je veux tracer sur une carte Google (API v3) intégré. Je voudrais les limites pour accueillir tous les points à moins que le niveau de zoom est trop faible (à savoir, trop zoomée beaucoup). Mon approche a été comme ceci:

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

// extend bounds with each point

gmap.fitBounds(bounds); 
gmap.setZoom( Math.max(6, gmap.getZoom()) );

Cela ne fonctionne pas. La dernière ligne « gmap.setZoom () » ne change pas le niveau de zoom de la carte si elle est appelée directement après fitBounds.

Y at-il un moyen d'obtenir le niveau de zoom d'une limite sans l'appliquer à la carte? D'autres idées pour résoudre ce problème?

Était-ce utile?

La solution

Modifier :. Voir le commentaire de Matt diamant ci-dessous

Je l'ai! Essayez ceci:

map.fitBounds(bounds);
var listener = google.maps.event.addListener(map, "idle", function() { 
  if (map.getZoom() > 16) map.setZoom(16); 
  google.maps.event.removeListener(listener); 
});

Modifier vos besoins.

Autres conseils

Je résolu un problème similaire dans l'une de mes applications. Je suis un peu confus par votre description du problème, mais je pense que vous avez le même objectif que j'avais ...

Dans mon application, je voulais tracer un un ou plusieurs marqueurs et assurer la carte leur montrait tout. Le problème était, si je comptais uniquement sur la méthode fitBounds, le niveau de zoom serait maximisé quand il y avait un seul point - c'était pas bon

.

La solution était d'utiliser fitBounds quand il y avait beaucoup de points, et setCenter + setZoom quand il n'y avait qu'un seul point.

if (pointCount > 1) {
  map.fitBounds(mapBounds);
}
else if (pointCount == 1) {
  map.setCenter(mapBounds.getCenter());
  map.setZoom(14);
}

Je suis venu à cette page plusieurs fois pour obtenir la réponse, et alors que toutes les réponses existantes étaient super utiles, ils n'ont pas résolu mon problème exactement.

google.maps.event.addListenerOnce(googleMap, 'zoom_changed', function() {
    var oldZoom = googleMap.getZoom();
    googleMap.setZoom(oldZoom - 1); //Or whatever
});

En fait, je trouve que l'événement « zoom_changed » a empêché l'interface utilisateur de la carte de « sauter » qui est arrivé quand j'attendu l'événement « ralenti ».

Espérons que cela aide quelqu'un!

Je viens fixé en réglant maxZoom à l'avance, puis de le retirer par la suite. Par exemple:

map.setOptions({ maxZoom: 15 });
map.fitBounds(bounds);
map.setOptions({ maxZoom: null });

Si je ne me trompe pas, je suppose que vous voulez que tous vos points soient visibles sur la carte avec le niveau de zoom le plus élevé possible. J'accompli ce en initialisant le niveau de zoom de la carte 16 (pas sûr que ce soit le niveau de zoom le plus élevé possible sur V3).

var map = new google.maps.Map(document.getElementById('map_canvas'), {
  zoom: 16,
  center: marker_point,
  mapTypeId: google.maps.MapTypeId.ROADMAP
});

Puis, après que je l'ai fait les choses de limites:

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

// You can have a loop here of all you marker points
// Begin loop
bounds.extend(marker_point);
// End loop

map.fitBounds(bounds);

Résultat:  Succès!

J'utilise:

gmap.setZoom(24); //this looks a high enough zoom value
gmap.fitBounds(bounds); //now the fitBounds should make the zoom value only less

utilisera la plus petite des 24 et le niveau de zoom nécessaire en fonction de votre code, mais il change probablement le zoom de toute façon et ne se soucie pas de combien vous avez sur.

J'ai eu le même problème et j'ai pu le résoudre en utilisant le code suivant. Cet écouteur événement (google.maps.addListenerOnce()) ne se tiré une fois, juste après map.fitBounds() est exécuté. Donc, il n'y a pas besoin de

  1. Gardez une trace de supprimer manuellement et l'auditeur, ou
  2. Attendez que la carte est idle.

Il définit le niveau de zoom approprié au départ et permet à l'utilisateur de zoomer et dézoomer au-delà du niveau de zoom initial car l'écouteur d'événement est arrivé à expiration. Par exemple, si seulement google.maps.addListener() a été appelé, l'utilisateur serait jamais pouvoir effectuer un zoom avant au-delà du niveau de zoom déclaré (dans le cas, 4). Depuis que nous avons mis en œuvre google.maps.addListenerOnce(), l'utilisateur sera en mesure de zoomer à tous les niveaux, il / elle choisit.

map.fitBounds(bounds);

var zoom_level_for_one_marker = 4;

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

eu le même problème, nécessaire pour adapter beaucoup de marqueurs sur la carte. Ceci a résolu mon cas:

  1. Déclarez limites
  2. régime d'utilisation fournies par koderoid (pour chaque ensemble de marqueurs bounds.extend(objLatLng))
  3. Exécuter fitbounds AFTER carte est terminée:

    google.maps.event.addListenerOnce(map, 'idle', function() { 
        map.fitBounds( bounds );
    });
    

Je l'ai trouvé une solution qui effectue la vérification avant d'appeler fitBounds afin que vous ne zoom pas et zoom tout à coup

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

// extend bounds with each point

var minLatSpan = 0.001;
if (bounds.toSpan().lat() > minLatSpan) {
    gmap.fitBounds(bounds); 
} else {
    gmap.setCenter(bounds.getCenter());
    gmap.setZoom(16);
}

Vous devez jouer avec la variable minLatSpan un peu pour obtenir où vous voulez. Elle varie en fonction à la fois au niveau de zoom et les dimensions de la toile de la carte.

Vous pouvez également utiliser la longitude au lieu de latitude

S'il vous plaît essayez ceci:

map.fitBounds(bounds);

// CHANGE ZOOM LEVEL AFTER FITBOUNDS
zoomChangeBoundsListener = google.maps.event.addListenerOnce(map, 'bounds_changed', function(event) {
  if (this.getZoom()){
    this.setZoom(15);
  }
});
setTimeout(function(){
  google.maps.event.removeListener(zoomChangeBoundsListener)
}, 2000);

J'ai vu de nombreuses solutions incorrectes ou trop compliquées, donc décidé de publier un travail , solution élégante .

La raison setZoom() ne fonctionne pas comme prévu est que fitBounds() est asynchrone, il ne donne aucune garantie qu'il immédiatement mettre à jour le zoom, mais votre appel à setZoom() repose sur ce point.

Qu'est-ce que vous pourriez envisager est de régler l'option carte minZoom avant d'appeler fitBounds() puis l'effacer après avoir terminé (de sorte que les utilisateurs peuvent toujours effectuer un zoom arrière manuellement s'ils veulent):

var bounds = new google.maps.LatLngBounds();
// ... (extend bounds with all points you want to fit)

// Ensure the map does not get too zoomed out when fitting the bounds.
gmap.setOptions({minZoom: 6});
// Clear the minZoom only after the map fits the bounds (note that
// fitBounds() is asynchronous). The 'idle' event fires when the map
// becomes idle after panning or zooming.
google.maps.event.addListenerOnce(gmap, 'idle', function() {
  gmap.setOptions({minZoom: null});
});

gmap.fitBounds(bounds);

En outre, si vous souhaitez limiter également le zoom maximum, vous pouvez appliquer la même astuce avec la propriété maxZoom.

Voir la MapOptions docs .

J'utilise ceci pour assurer le niveau de zoom ne dépasse pas un niveau déterminé de telle sorte que je sais des images satellite seront disponibles.

Ajouter un écouteur à l'événement zoom_changed. Cela a l'avantage de contrôler la commande de zoom sur l'interface utilisateur aussi.

Seulement exécuter setZoom si vous avez besoin, si une instruction if est préférable de Math.max ou Math.min

   google.maps.event.addListener(map, 'zoom_changed', function() { 
      if ( map.getZoom() > 19 ) { 
        map.setZoom(19); 
      } 
    });
    bounds = new google.maps.LatLngBounds( ... your bounds ... )
    map.fitBounds(bounds);

Pour éviter un zoom arrière trop loin:

   google.maps.event.addListener(map, 'zoom_changed', function() { 
      if ( map.getZoom() < 6 ) { 
        map.setZoom(6); 
      } 
    });
    bounds = new google.maps.LatLngBounds( ... your bounds ... )
    map.fitBounds(bounds);

Dans cette fonction, vous devez ajouter dynamiquement des métadonnées pour stocker le type de géométrie uniquement parce que la fonction accepte toute la géométrie.

"fitGeometries" est une fonction d'extension JSON un objet de la carte.

"géométries" est un tableau javascript générique pas MVCArray ().

geometry.metadata = { type: "point" };
var geometries = [geometry];

fitGeometries: function (geometries) {
    // go and determine the latLngBounds...
    var bounds = new google.maps.LatLngBounds();
    for (var i = 0; i < geometries.length; i++) {
        var geometry = geometries[i];
        switch (geometry.metadata.type)
        {
            case "point":
                var point = geometry.getPosition();
                bounds.extend(point);
                break;
            case "polyline":
            case "polygon": // Will only get first path
                var path = geometry.getPath();
                for (var j = 0; j < path.getLength(); j++) {
                    var point = path.getAt(j);
                    bounds.extend(point);
                }
                break;
        }
    }
    this.getMap().fitBounds(bounds);
},

de travail pour moi avec l'API v3 mais avec réglage du zoom fixe:

var bounds = new google.maps.LatLngBounds();
// extend bounds with each point

gmap.setCenter(bounds.getCenter()); 
gmap.setZoom( 6 );

Comme moi, si vous n'êtes pas prêt à jouer avec les auditeurs, c'est une solution simple, je suis venu avec: Ajouter une méthode sur la carte qui fonctionne strictement selon vos besoins comme celui-ci:

    map.fitLmtdBounds = function(bounds, min, max){
        if(bounds.isEmpty()) return;
        if(typeof min == "undefined") min = 5;
        if(typeof max == "undefined") max = 15;

        var tMin = this.minZoom, tMax = this.maxZoom;
        this.setOptions({minZoom:min, maxZoom:max});
        this.fitBounds(bounds);
        this.setOptions({minZoom:tMin, maxZoom:tMax});
    }

vous pouvez appeler map.fitLmtdBounds(bounds) au lieu de map.fitBounds(bounds) pour définir les limites dans la plage de zoom définie ou ... map.fitLmtdBounds(bounds,3,5) pour passer outre la plage de zoom ..

S'il vous plaît essayer.

// Find out what the map's zoom level is
zoom = map.getZoom();
if (zoom == 1) {
  // If the zoom level is that low, means it's looking around the
world.
  // Swap the sw and ne coords
  viewportBounds = new
google.maps.LatLngBounds(results[0].geometry.location, initialLatLng);
  map.fitBounds(viewportBounds);
}

si cela est utile pour vous.

Tous les meilleurs

Après calcul des boundries vous pouvez vérifier la distance entre le coin supérieur gauche et en bas à droite; alors vous pouvez comprendre le niveau de zoom en testant la distance (si la distance est trop loin du niveau de zoom serait faible), vous pouvez sélectionner wheter en utilisant la méthode setbound ou setZoom ..

Je ne veux pas dire, mais si vous doit essayer - premier appel

gmap.fitBounds(bounds);

Ensuite, créez un nouveau thread / AsyncTask, l'ont pour dormir 20-50ms ou si puis appelez

gmap.setZoom( Math.max(6, gmap.getZoom()) );

dans le thread d'interface utilisateur (utiliser un gestionnaire ou la méthode de onPostExecute pour AsyncTask).

Je ne sais pas si cela fonctionne, juste une suggestion. Autre que vous auriez à calculer en quelque sorte le niveau de zoom de vos points vous, vérifiez si elle est trop faible, le corriger et puis juste appeler gmap.setZoom(correctedZoom)

Si « bounds_changed » est pas correctement mise à feu (parfois Google ne semble pas accepter les coordonnées parfaitement), puis envisager d'utiliser « center_changed » à la place.

L'événement « center_changed » se déclenche à chaque fitBounds de temps () est appelée, même si elle fonctionne immédiatement et pas nécessairement après la carte est déplacée.

Dans les cas normaux, « ralenti » est toujours le meilleur écouteur d'événement, mais cela peut aider un couple de personnes en cours d'exécution dans des problèmes étranges avec leurs fitBounds () appelle.

Voir google maps fitBounds callback

Pour carillon avec une autre solution - je trouve que la « Ecoute de l'événement bounds_changed puis définir le nouveau zoom » approche ne fonctionne pas correctement pour moi. Je pense que je parfois appelais fitBounds avant que la carte avait été complètement initialisé, et l'initialisation causais un événement bounds_changed qui utiliserait l'auditeur, avant fitBounds a changé les limites et le niveau de zoom. J'ai fini avec ce code, qui semble fonctionner jusqu'à présent:

// If there's only one marker, or if the markers are all super close together,
// `fitBounds` can zoom in too far. We want to limit the maximum zoom it can
// use.
//
// `fitBounds` is asynchronous, so we need to wait until the bounds have
// changed before we know what the new zoom is, using an event handler.
//
// Sometimes this handler gets triggered by a different event, before
// `fitBounds` takes effect; that particularly seems to happen if the map
// hasn't been fully initialized yet. So we don't immediately remove the
// listener; instead, we wait until the 'idle' event, and remove it then.
//
// But 'idle' might happen before 'bounds_changed', so we can't set up the
// removal handler immediately. Set it up in the first event handler.

var removeListener = null;
var listener = google.maps.event.addListener(map, 'bounds_changed', () => {
  console.log(map.getZoom());
  if (map.getZoom() > 15) {
    map.setZoom(15);
  }

  if (!removeListener) {
    removeListener = google.maps.event.addListenerOnce(map, 'idle', () => {
      console.log('remove');
      google.maps.event.removeListener(listener);
    });
  }
});

Pour moi, la solution la plus simple est la suivante:

map.fitBounds(bounds);

function set_zoom() {
    if(map.getZoom()) {map.setZoom(map.getZoom() - 1);}
    else {setTimeout(set_zoom, 5);}
}
setTimeout(set_zoom, 5);
google.maps.event.addListener(marker, 'dblclick', function () {
    var oldZoom = map.getZoom(); 
    map.setCenter(this.getPosition());
    map.setZoom(parseInt(oldZoom) + 1);
});

Tout ce que je fait est:

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

Et cela fonctionne sur l'API V3.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top