web-dev-qa-db-fra.com

Carte auto-centrée avec plusieurs marqueurs dans Google Maps API v3

C’est ce que j’utilise pour afficher une carte avec 3 pins/markers:

<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 recherche, c’est un moyen d’éviter de chercher "manuellement" le centre de la carte avec center: new google.maps.LatLng(41.923, 12.513). Existe-t-il un moyen de centrer automatiquement la carte sur les trois coordonnées?

203
MultiformeIngegno

Il existe un moyen plus simple d’agrandir un LatLngBounds vide plutôt que d’en créer un explicitement à partir de deux points. (Voir cette question pour plus de détails)

Devrait ressembler à 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 et n'avez pas besoin de connaître l'ordre au préalable.

Démo jsFiddle ici: http://jsfiddle.net/x5R63/

416
metadept

Je pense que vous devez calculer latitudine min et 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)
));
25

Pour trouver le centre exact de la carte, vous devez convertir les coordonnées lat/lon en coordonnées pixel, puis trouver le centre et la reconvertir en coordonnées lat/lon.

Vous ne remarquerez peut-être pas la dérive en fonction de votre distance au nord ou au sud de l'équateur. Vous pouvez voir la dérive en faisant map.setCenter (map.getBounds (). GetCenter ()) à l'intérieur d'un setInterval, la dérive disparaîtra lentement à l'approche de l'équateur.

Vous pouvez utiliser ce qui suit pour convertir les coordonnées lat/lon en pixels. Les coordonnées des pixels sont basées sur un plan du monde entier entièrement zoomé, mais vous pouvez ensuite en trouver le centre et le remettre en lat/lon.

   var HALF_WORLD_CIRCUMFERENCE = 268435456; // in pixels at zoom level 21
   var WORLD_RADIUS = HALF_WORLD_CIRCUMFERENCE / Math.PI;

   function _latToY ( lat ) {
      var sinLat = Math.sin( _toRadians( lat ) );
      return HALF_WORLD_CIRCUMFERENCE - WORLD_RADIUS * Math.log( ( 1 + sinLat ) / ( 1 - sinLat ) ) / 2;
   }

   function _lonToX ( lon ) {
      return HALF_WORLD_CIRCUMFERENCE + WORLD_RADIUS * _toRadians( lon );
   }

   function _xToLon ( x ) {
      return _toDegrees( ( x - HALF_WORLD_CIRCUMFERENCE ) / WORLD_RADIUS );
   }

   function _yToLat ( y ) {
      return _toDegrees( Math.PI / 2 - 2 * Math.atan( Math.exp( ( y - HALF_WORLD_CIRCUMFERENCE ) / WORLD_RADIUS ) ) );
   }

   function _toRadians ( degrees ) {
      return degrees * Math.PI / 180;
   }

   function _toDegrees ( radians ) {
      return radians * 180 / Math.PI;
   }
1
Shadow Man

Voici ce que je pense au cas où quelqu'un tomberait sur ce fil de discussion:

Cela permet d'éviter que des données non numériques ne détruisent l'une ou l'autre de vos variables finales qui déterminent lat et lng.

Cela fonctionne en prenant toutes vos coordonnées, en les analysant dans les éléments lat et lng distincts d'un tableau, puis en déterminant la moyenne de chacune d'elles. Cette moyenne devrait être le centre (et a prouvé la vérité dans mes cas de test.)

var coords = "50.0160001,3.2840073|50.014458,3.2778274|50.0169713,3.2750587|50.0180745,3.276742|50.0204038,3.2733474|50.0217796,3.2781737|50.0293064,3.2712542|50.0319918,3.2580816|50.0243287,3.2582281|50.0281447,3.2451177|50.0307925,3.2443178|50.0278165,3.2343882|50.0326574,3.2289809|50.0288569,3.2237612|50.0260081,3.2230589|50.0269495,3.2210104|50.0212645,3.2133541|50.0165868,3.1977592|50.0150515,3.1977341|50.0147901,3.1965286|50.0171915,3.1961636|50.0130074,3.1845098|50.0113267,3.1729483|50.0177206,3.1705726|50.0210692,3.1670394|50.0182166,3.158297|50.0207314,3.150927|50.0179787,3.1485753|50.0184944,3.1470782|50.0273077,3.149845|50.024227,3.1340514|50.0244172,3.1236235|50.0270676,3.1244474|50.0260853,3.1184879|50.0344525,3.113806";

var filteredtextCoordinatesArray = coords.split('|');    

    centerLatArray = [];
    centerLngArray = [];


    for (i=0 ; i < filteredtextCoordinatesArray.length ; i++) {

      var centerCoords = filteredtextCoordinatesArray[i]; 
      var centerCoordsArray = centerCoords.split(',');

      if (isNaN(Number(centerCoordsArray[0]))) {      
      } else {
        centerLatArray.Push(Number(centerCoordsArray[0]));
      }

      if (isNaN(Number(centerCoordsArray[1]))) {
      } else {
        centerLngArray.Push(Number(centerCoordsArray[1]));
      }                    

    }

    var centerLatSum = centerLatArray.reduce(function(a, b) { return a + b; });
    var centerLngSum = centerLngArray.reduce(function(a, b) { return a + b; });

    var centerLat = centerLatSum / filteredtextCoordinatesArray.length ; 
    var centerLng = centerLngSum / filteredtextCoordinatesArray.length ;                                    

    console.log(centerLat);
    console.log(centerLng);

    var mapOpt = {      
    zoom:8,
    center: {lat: centerLat, lng: centerLng}      
    };
0
Brian Powell

j'ai eu une situation où je ne peux pas changer l'ancien code, donc ajouté cette fonction javascript pour calculer le point central et le niveau de zoom:

//input
var tempdata = ["18.9400|72.8200-19.1717|72.9560-28.6139|77.2090"];

function getCenterPosition(tempdata){
        var tempLat = tempdata[0].split("-");
        var latitudearray = [];
        var longitudearray = [];
        var i;
        for(i=0; i<tempLat.length;i++){
                var coordinates = tempLat[i].split("|");
                latitudearray.Push(coordinates[0]);
                longitudearray.Push(coordinates[1]);
        }
        latitudearray.sort(function (a, b) { return a-b; });
        longitudearray.sort(function (a, b) { return a-b; });
        var latdifferenece = latitudearray[latitudearray.length-1] - latitudearray[0];
        var temp = (latdifferenece / 2).toFixed(4) ;
        var latitudeMid = parseFloat(latitudearray[0]) + parseFloat(temp);
        var longidifferenece = longitudearray[longitudearray.length-1] - longitudearray[0];
        temp = (longidifferenece / 2).toFixed(4) ;
        var longitudeMid = parseFloat(longitudearray[0]) + parseFloat(temp);
        var maxdifference = (latdifferenece > longidifferenece)? latdifferenece : longidifferenece;
        var zoomvalue;  
        if(maxdifference >= 0 && maxdifference <= 0.0037)  //zoom 17
                zoomvalue='17';
        else if(maxdifference > 0.0037 && maxdifference <= 0.0070)  //zoom 16
                zoomvalue='16';
        else if(maxdifference > 0.0070 && maxdifference <= 0.0130)  //zoom 15
                zoomvalue='15';
        else if(maxdifference > 0.0130 && maxdifference <= 0.0290)  //zoom 14
                zoomvalue='14';
        else if(maxdifference > 0.0290 && maxdifference <= 0.0550)  //zoom 13
                zoomvalue='13';
        else if(maxdifference > 0.0550 && maxdifference <= 0.1200)  //zoom 12
                zoomvalue='12';
        else if(maxdifference > 0.1200 && maxdifference <= 0.4640)  //zoom 10
                zoomvalue='10';
        else if(maxdifference > 0.4640 && maxdifference <= 1.8580)  //zoom 8
                zoomvalue='8';
        else if(maxdifference > 1.8580 && maxdifference <= 3.5310)  //zoom 7
                zoomvalue='7';
        else if(maxdifference > 3.5310 && maxdifference <= 7.3367)  //zoom 6
                zoomvalue='6';
        else if(maxdifference > 7.3367 && maxdifference <= 14.222)  //zoom 5
                zoomvalue='5';
        else if(maxdifference > 14.222 && maxdifference <= 28.000)  //zoom 4
                zoomvalue='4';
        else if(maxdifference > 28.000 && maxdifference <= 58.000)  //zoom 3
                zoomvalue='3';
        else
                zoomvalue='1';
        return latitudeMid+'|'+longitudeMid+'|'+zoomvalue;
}
0
NEQSH

J'utilise la méthode ci-dessus pour définir les limites de la carte, puis, au lieu de réinitialiser le niveau de zoom, je calcule simplement la moyenne de la table LAT et de la moyenne de LON, puis le point central à cet emplacement. J'additionne toutes les valeurs de lat dans latTotal et toutes les valeurs de lon dans lontotal, puis je les divise par le nombre de marqueurs. J'ai ensuite défini le point central de la carte sur ces valeurs moyennes.

latCenter = latTotal/markercount; lonCenter = lontotal/markercount;

0
Stan Amditis