Карта автоцентру з декількома маркерами в API Google Maps v3


225

Це те, що я використовую для відображення карти з 3 штифтами / маркерами:

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

Що я шукаю, це спосіб уникнути необхідності «вручну» знайти центр карти center: new google.maps.LatLng(41.923, 12.513). Чи існує спосіб автоматичного центрування карти на трьох координатах?


Відповіді:


448

Існує простіший спосіб - розширити порожній, LatLngBoundsа не створювати явно з двох точок. (Детальніше див. У цьому питанні )

Має виглядати приблизно так, додане до коду:

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

Таким чином, ви можете використовувати довільну кількість очок, і не потрібно заздалегідь знати замовлення.

Демонстраційний jsFiddle тут: http://jsfiddle.net/x5R63/


Дякую, це працює! Єдине, що не дозволяє мені прийняти відповідь, це те, що рівень масштабування вже не дотримується. Чи знаєте ви, як змусити його знову працювати? :)
MultiformeIngegno

@MultiformeIngegno має добре працювати, якщо ви використовуєте setZoomПІСЛЯfitBounds
метадепт

@MultiformeIngegno Називаючи це відразу після того, як fitBoundsпрацювали для мене в короткому тесті; дайте мені знати, якщо у вас все ще виникають проблеми.
метадепт

2
@metadept Як я можу встановити маркер для цього центрального положення? Це можливо отримати latLng меж?
Vitor Guerreiro

1
map.panToBounds(bounds);призначений для автоматичного збільшення.
намал

28

Я думаю, що ви повинні обчислити latitudine min та довготу min: Ось приклад з функцією, яка використовується для центрування точки:

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

1

Щоб знайти точний центр карти, вам потрібно буде перекласти координати lat / lon в піксельні координати, а потім знайти піксельний центр і перетворити його назад у координати lat / lon.

Ви, можливо, не помічаєте або не помічаєте дрейфу залежно від того, наскільки далеко ви північ чи південь від екватора. Ви можете бачити дрейф, виконуючи map.setCenter (map.getBounds (). GetCenter ()) всередині набору Інтервал, дрейф повільно зникне, коли він наблизиться до екватора.

Ви можете використовувати наступне для перекладу між координатами lat / lon та пікселів. Координати пікселів базуються на площині цілого світу, яка повністю збільшена, але ви можете знайти центр цього і переключити його назад у 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;
   }

0

Я використовую вищевказаний метод для встановлення меж карти, тоді замість скидання рівня масштабування я просто обчислюю середню LAT та середню LON і встановлюю центральну точку в цьому місці. Я додаю всі значення lat в latTotal, а всі значення lon на lontotal, а потім ділю на кількість маркерів. Потім я встановлюю центральну точку на карті середніми значеннями.

latCenter = latTotal / markercount; lonCenter = лонтотальний / розмітка;


0

У мене виникла ситуація, коли я не можу змінити старий код, тому додав цю функцію JavaScript для обчислення точки точки та рівня масштабування:

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

Ось я прийму це на випадок, якщо хтось стикається з цією темою:

Це допомагає захистити від нечислових даних, знищуючи будь-яку з ваших кінцевих змінних, що визначають latі lng.

Він працює, приймаючи всі ваші координати, розбираючи їх на окремі latта lngелементи масиву, а потім визначаючи середнє значення кожного. Цей середній рівень повинен бути центром (і це виявилося правдою в моїх тестових випадках.)

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}      
    };
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.