javascript Google Maps API v3 中带有多个标记的自动居中地图
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15719951/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Auto-center map with multiple markers in Google Maps API v3
提问by MultiformeIngegno
This is what I use to display a map with 3 pins/markers:
这是我用来显示带有 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>
What I'm looking for is a way to avoid having to “manually” find the center of the map with center: new google.maps.LatLng(41.923, 12.513)
. Is there a way to automatically have the map centered on the three coordinates?
我正在寻找的是一种避免“手动”找到地图中心的方法center: new google.maps.LatLng(41.923, 12.513)
。有没有办法让地图自动以三个坐标为中心?
回答by metadept
There's an easier way, by extending an empty LatLngBounds
rather than creating one explicitly from two points. (See this questionfor more details)
有一种更简单的方法,通过扩展一个空LatLngBounds
而不是从两个点明确地创建一个。(有关更多详细信息,请参阅此问题)
Should look something like this, added to your 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);
});
This way, you can use an arbitrary number of points, and don't need to know the order beforehand.
这样,您可以使用任意数量的点,而无需事先知道顺序。
Demo jsFiddle here: http://jsfiddle.net/x5R63/
演示 jsFiddle 在这里:http: //jsfiddle.net/x5R63/
回答by Alessandro Minoccheri
I think you have to calculate latitudine min and longitude min: Here is an Example with the function to use to center your 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)
));
回答by Shadow Man
To find the exact center of the map you'll need to translate the lat/lon coordinates into pixel coordinates and then find the pixel center and convert that back into lat/lon coordinates.
要找到地图的确切中心,您需要将纬度/经度坐标转换为像素坐标,然后找到像素中心并将其转换回纬度/经度坐标。
You might not notice or mind the drift depending how far north or south of the equator you are. You can see the drift by doing map.setCenter(map.getBounds().getCenter()) inside of a setInterval, the drift will slowly disappear as it approaches the equator.
您可能不会注意到或介意漂移,具体取决于您在赤道以北或以南的距离。您可以通过在 setInterval 中执行 map.setCenter(map.getBounds().getCenter()) 来查看漂移,漂移会在接近赤道时慢慢消失。
You can use the following to translate between lat/lon and pixel coordinates. The pixel coordinates are based on a plane of the entire world fully zoomed in, but you can then find the center of that and switch it back into 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;
}
回答by Stan Amditis
I use the method above to set the map boundaries, then, instead of resetting the zoom level, I just calculate the average LAT and average LON and set the center point to that location. I add up all the lat values into latTotal and all the lon values into lontotal and then divide by the number of markers. I then set the map center point to those average values.
我使用上面的方法设置地图边界,然后,我只是计算平均 LAT 和平均 LON 并将中心点设置为该位置,而不是重置缩放级别。我将所有经纬度值加到 latTotal 中,将所有 lon 值加到 lontotal 中,然后除以标记的数量。然后我将地图中心点设置为这些平均值。
latCenter = latTotal / markercount; lonCenter = lontotal / markercount;
latCenter = latTotal / 标记计数;lonCenter = lontotal / 标记计数;
回答by NEQSH
i had a situation where i can't change old code, so added this javascript function to calculate center point and zoom level:
我遇到了无法更改旧代码的情况,因此添加了此 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;
}
回答by Brian Powell
Here's my take on this in case anyone comes across this thread:
这是我对此的看法,以防有人遇到此线程:
This helps protect against non-numerical data destroying either of your final variables that determine lat
and lng
.
这有助于防止非数字数据破坏确定lat
和 的最终变量lng
。
It works by taking in all of your coordinates, parsing them into separate lat
and lng
elements of an array, then determining the average of each. That average should be the center (and has proven true in my test cases.)
它的工作原理,采取在所有的坐标,把它们解析成单独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}
};