wake-up-neo.com

Karte mit mehreren Markierungen in Google Maps API v3 automatisch zentrieren

Dies ist, was ich benutze, um eine Karte mit 3 Stiften/Markierungen anzuzeigen:

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

Ich suche nach einer Möglichkeit, mit center: new google.maps.LatLng(41.923, 12.513) das Zentrum der Karte nicht "manuell" finden zu müssen. Gibt es eine Möglichkeit, die Karte automatisch auf die drei Koordinaten zu zentrieren?

203

Es gibt eine einfachere Möglichkeit, indem Sie ein leeres LatLngBounds erweitern, anstatt eines explizit aus zwei Punkten zu erstellen. (Siehe diese Frage für weitere Details)

Sollte ungefähr so ​​aussehen, hinzugefügt zu Ihrem 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);
});

Auf diese Weise können Sie eine beliebige Anzahl von Punkten verwenden und müssen die Reihenfolge nicht im Voraus kennen.

Demo jsFiddle hier: http://jsfiddle.net/x5R63/

416
metadept

Ich denke, Sie müssen die Längen- und Breitengrade berechnen: Hier ist ein Beispiel mit der Funktion, mit der Sie Ihren Punkt zentrieren können:

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

Um den genauen Mittelpunkt der Karte zu finden, müssen Sie die Lat/Lon-Koordinaten in Pixelkoordinaten umwandeln und dann den Pixelmittelpunkt suchen und ihn wieder in Lat/Lon-Koordinaten umwandeln.

Je nachdem, wie weit Sie sich nördlich oder südlich des Äquators befinden, werden Sie die Abweichung möglicherweise nicht bemerken oder bemerken. Sie können die Drift sehen, indem Sie map.setCenter (map.getBounds (). GetCenter ()) in einem setInterval ausführen. Die Drift verschwindet langsam, wenn sie sich dem Äquator nähert.

Sie können Folgendes verwenden, um zwischen Lat/Lon- und Pixelkoordinaten zu übersetzen. Die Pixelkoordinaten basieren auf einer Ebene der gesamten Welt, die vollständig vergrößert ist, aber Sie können dann die Mitte davon finden und sie wieder in lat/lon umschalten.

   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

Hier ist meine Meinung dazu, falls jemand auf diesen Thread stößt:

Dies schützt Sie vor nicht numerischen Daten, die eine Ihrer endgültigen Variablen zerstören, die lat und lng bestimmen.

Es funktioniert, indem Sie alle Ihre Koordinaten aufnehmen, sie in separate lat und lng Elemente eines Arrays zerlegen und dann den Durchschnitt von jedem bestimmen. Dieser Durchschnitt sollte im Mittelpunkt stehen (und hat sich in meinen Testfällen als richtig erwiesen).

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

ich hatte eine Situation, in der ich alten Code nicht ändern kann, also fügte ich diese Javascript-Funktion hinzu, um den Mittelpunkt und die Zoomstufe zu berechnen:

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

Ich verwende die obige Methode, um die Kartengrenzen festzulegen. Anstatt die Zoomstufe zurückzusetzen, berechne ich einfach die durchschnittliche LAT und die durchschnittliche LON und setze den Mittelpunkt auf diesen Ort. Ich addiere alle lat-Werte zu latTotal und alle lon-Werte zu lontotal und dividiere dann durch die Anzahl der Marker. Dann setze ich den Kartenmittelpunkt auf diese Durchschnittswerte.

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

0
Stan Amditis