Bản đồ trung tâm tự động với nhiều điểm đánh dấu trong Google Maps API v3


225

Đây là những gì tôi sử dụng để hiển thị bản đồ với 3 chân / điểm đánh dấu:

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

Những gì tôi đang tìm kiếm là một cách để tránh phải thủ công bằng cách tìm trung tâm của bản đồ center: new google.maps.LatLng(41.923, 12.513). Có cách nào để tự động có bản đồ tập trung vào ba tọa độ không?


Câu trả lời:


448

Có một cách dễ dàng hơn, bằng cách mở rộng một khoảng trống LatLngBoundsthay vì tạo một cách rõ ràng từ hai điểm. (Xem câu hỏi này để biết thêm chi tiết)

Nếu trông giống như thế này, hãy thêm vào mã của bạn:

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

Bằng cách này, bạn có thể sử dụng số điểm tùy ý và không cần biết thứ tự trước.

Demo jsFiddle tại đây: http://jsfiddle.net/x5R63/


Cảm ơn, nó hoạt động! Điều duy nhất ngăn tôi chấp nhận câu trả lời là mức thu phóng không còn được tôn trọng. Bạn có biết làm thế nào để nó hoạt động trở lại? :)
MultiformeIngegno 30/03/13

@MultiformeIngegno sẽ hoạt động tốt nếu bạn sử dụng setZoomSAUfitBounds
metadept

@MultiformeIngegno Gọi ngay sau khi fitBoundslàm việc cho tôi trong một thử nghiệm ngắn; cho tôi biết nếu bạn vẫn gặp sự cố.
metadept

2
@metadept làm cách nào tôi có thể đặt điểm đánh dấu vào vị trí trung tâm này? Nó có thể có được latLng của giới hạn?
Vitor Guerreiro

1
map.panToBounds(bounds);là để thu phóng tự động.
namal

28

Tôi nghĩ bạn phải tính toán latitudine min và kinh độ tối thiểu: Dưới đây là một ví dụ với chức năng sử dụng để tập trung vào điểm của bạn:

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

Để tìm trung tâm chính xác của bản đồ, bạn cần dịch tọa độ lat / lon thành tọa độ pixel và sau đó tìm trung tâm pixel và chuyển đổi lại thành tọa độ lat / lon.

Bạn có thể không nhận thấy hoặc chú ý đến sự trôi dạt tùy thuộc vào phía bắc hoặc phía nam của đường xích đạo. Bạn có thể thấy sự trôi dạt bằng cách thực hiện map.setCenter (map.getBound (). GetCenter ()) bên trong setInterval, sự trôi dạt sẽ từ từ biến mất khi đến gần đường xích đạo.

Bạn có thể sử dụng cách sau để dịch giữa tọa độ lat / lon và pixel. Các tọa độ pixel dựa trên một mặt phẳng của toàn bộ thế giới được phóng to hoàn toàn, nhưng sau đó bạn có thể tìm trung tâm của nó và chuyển nó trở lại thành 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

Tôi sử dụng phương pháp trên để đặt ranh giới bản đồ, sau đó, thay vì đặt lại mức thu phóng, tôi chỉ tính LAT trung bình và LON trung bình và đặt điểm trung tâm đến vị trí đó. Tôi cộng tất cả các giá trị lat vào latTotal và tất cả các giá trị lon thành lontotal và sau đó chia cho số lượng điểm đánh dấu. Sau đó tôi đặt điểm trung tâm bản đồ tới các giá trị trung bình đó.

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


0

tôi gặp tình huống không thể thay đổi mã cũ, vì vậy đã thêm chức năng javascript này để tính điểm trung tâm và mức thu phóng:

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

Đây là của tôi về điều này trong trường hợp bất cứ ai đi qua chủ đề này:

Điều này giúp bảo vệ chống lại dữ liệu phi số phá hủy một trong hai biến cuối cùng của bạn xác định latlng.

Nó hoạt động bằng cách lấy tất cả các tọa độ của bạn, phân tích chúng thành các phần tử latlngphần tử riêng biệt của một mảng, sau đó xác định mức trung bình của mỗi phần. Trung bình đó phải là trung tâm (và đã được chứng minh là đúng trong các trường hợp thử nghiệm của tôi.)

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}      
    };
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.