256 votes

Centrage automatique de la carte avec plusieurs marqueurs dans l'API Google Maps v3

C'est ce que j'utilise pour afficher une carte avec 3 épingles/marqueurs :

<script>
  function initialize() {
    var locations = [
      ['DESCRIPTION', 41.926979, 12.517385, 3],
      ['DESCRIPTION', 41.914873, 12.506486, 2],
      ['DESCRIPTION', 41.918574, 12.507201, 1]
    ];

    var map = new google.maps.Map(document.getElementById('map'), {
      zoom: 15,
      center: new google.maps.LatLng(41.923, 12.513),
      mapTypeId: google.maps.MapTypeId.ROADMAP
    });

    var infowindow = new google.maps.InfoWindow();

    var marker, i;

    for (i = 0; i < locations.length; i++) {
      marker = new google.maps.Marker({
        position: new google.maps.LatLng(locations[i][1], locations[i][2]),
        map: map
      });

      google.maps.event.addListener(marker, 'click', (function(marker, i) {
        return function() {
          infowindow.setContent(locations[i][0]);
          infowindow.open(map, marker);
        }
      })(marker, i));
    }
  }

  function loadScript() {
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = 'https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&' + 'callback=initialize';
    document.body.appendChild(script);
  }

  window.onload = loadScript;
</script>

<div id="map" style="width: 900px; height: 700px;"></div>

Ce que je cherche, c'est un moyen d'éviter d'avoir à trouver "manuellement" le centre de la carte avec center: new google.maps.LatLng(41.923, 12.513) . Existe-t-il un moyen de faire en sorte que la carte soit automatiquement centrée sur les trois coordonnées ?

0 votes

507voto

metadept Points 2343

Il existe une méthode plus simple, qui consiste à étendre un fichier vide LatLngBounds plutôt que d'en créer un explicitement à partir de deux points. (Voir cette question pour plus de détails)

Cela devrait ressembler à quelque chose comme ceci, ajouté à votre code :

//create empty LatLngBounds object
var bounds = new google.maps.LatLngBounds();
var infowindow = new google.maps.InfoWindow();    

for (i = 0; i < locations.length; i++) {  
  var marker = new google.maps.Marker({
    position: new google.maps.LatLng(locations[i][1], locations[i][2]),
    map: map
  });

  //extend the bounds to include each marker's position
  bounds.extend(marker.position);

  google.maps.event.addListener(marker, 'click', (function(marker, i) {
    return function() {
      infowindow.setContent(locations[i][0]);
      infowindow.open(map, marker);
    }
  })(marker, i));
}

//now fit the map to the newly inclusive bounds
map.fitBounds(bounds);

//(optional) restore the zoom level after the map is done scaling
var listener = google.maps.event.addListener(map, "idle", function () {
    map.setZoom(3);
    google.maps.event.removeListener(listener);
});

De cette façon, vous pouvez utiliser un nombre arbitraire de points, sans avoir besoin de connaître l'ordre à l'avance.

Démonstration de jsFiddle ici : http://jsfiddle.net/x5R63/

0 votes

Merci, ça marche ! La seule chose qui m'empêche d'accepter la réponse est que le niveau de zoom n'est plus respecté. Savez-vous comment le faire fonctionner à nouveau ? :)

0 votes

@MultiformeIngegno devrait fonctionner correctement si vous utilisez setZoom APRÈS fitBounds

0 votes

@MultiformeIngegno Calling it right after fitBounds a fonctionné pour moi lors d'un bref test ; faites-moi savoir si vous avez encore des problèmes.

35voto

Je pense que vous devez calculer la latitudine min et la longitude min : Voici un exemple avec la fonction à utiliser pour centrer votre point :

//Example values of min & max latlng values
var lat_min = 1.3049337;
var lat_max = 1.3053515;
var lng_min = 103.2103116;
var lng_max = 103.8400188;

map.setCenter(new google.maps.LatLng(
  ((lat_max + lat_min) / 2.0),
  ((lng_max + lng_min) / 2.0)
));
map.fitBounds(new google.maps.LatLngBounds(
  //bottom left
  new google.maps.LatLng(lat_min, lng_min),
  //top right
  new google.maps.LatLng(lat_max, lng_max)
));

4voto

Txai Potier Points 11

Une autre mise en œuvre, basée sur les réponses précédentes, mais plus légère :

export class MapComponent {
    @ViewChild(GoogleMap) map: GoogleMap;

    markerList = [
        {
            lat: 41.926979,
            lng: 12.517385
        },
        {
            lat: 41.914873,
            lng: 12.506486
        },
        {
            lat: 41.918574, 
            lng: 12.507201
        }
    ]

    centralize() {
        const bounds = new google.maps.LatLngBounds();
        this.markerList.forEach((marker) => {
            bounds.extend(new google.maps.LatLng(marker.lat, marker.lng))
        })
        this.map.fitBounds(bounds)
    }
}

Vous n'avez pas besoin de créer un "google.maps.Marker", vous pouvez simplement créer une instance de LatLng et la passer directement en paramètre à la fonction bounds extend.

2voto

Cela fonctionne pour moi dans Angular 9 :

  import {GoogleMap, GoogleMapsModule} from "@angular/google-maps";
  @ViewChild('Map') Map: GoogleMap; /* Element Map */

  locations = [
   { lat: 7.423568, lng: 80.462287 },
   { lat: 7.532321, lng: 81.021187 },
   { lat: 6.117010, lng: 80.126269 }
  ];

  constructor() {
   var bounds = new google.maps.LatLngBounds();
    setTimeout(() => {
     for (let u in this.locations) {
      var marker = new google.maps.Marker({
       position: new google.maps.LatLng(this.locations[u].lat, 
       this.locations[u].lng),
      });
      bounds.extend(marker.getPosition());
     }

     this.Map.fitBounds(bounds)
    }, 200)
  }

Et il centre automatiquement la carte en fonction des positions indiquées.

Résultat :

enter image description here

2voto

J'ai essayé toutes les réponses de ce sujet, mais seule la réponse ci-dessous a fonctionné correctement sur mon projet.

Angular 7 et AGM Core 1.0.0-beta.7

<agm-map [latitude]="lat" [longitude]="long" [zoom]="zoom" [fitBounds]="true">
  <agm-marker latitude="{{localizacao.latitude}}" longitude="{{localizacao.longitude}}" [agmFitBounds]="true"
    *ngFor="let localizacao of localizacoesTec">
  </agm-marker>
</agm-map>

Les propriétés [agmFitBounds]="true" à l'adresse agm-marker y [fitBounds]="true" à l'adresse agm-map fait le travail

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X