2013-03-30 189 views
151

这是我用3个引脚/标记来显示地图:谷歌地图API V3:自中心地图多个标记

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

我正在寻找的是要避免的方法“手动”找到中心的地图中心:new google.maps.LatLng(41.923,12.513)。有没有办法让地图自动以3个坐标为中心?

+0

的可能的复制[谷歌地图API第3版:我可以fitBounds后setZoom(http://stackoverflow.com/questions/ 2437683/google-maps-api-v3-can-i-setzoom-fit-fit) –

回答

320

有一个简单的方法,由而不是扩展空LatLngBounds从两点明确创建一个。 (详情请参见this question

应该是这个样子,添加到您的代码:

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

+0

谢谢,它的工作原理!唯一让我无法接受答案的是缩放级别不再受到尊重。你知道如何再次使用它吗? :) – MultiformeIngegno

+0

@MultiformeIngegno应该工作正常,如果你使用'setZoom'后'fitBounds' – metadept

+0

哦,看到你最新的编辑。我会尝试。 :) – MultiformeIngegno

18

我认为你必须计算latitudine分钟和经度分钟: 这里是与功能相关的例子使用居中你的观点:

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

要查找地图的正中心,你需要翻译的经/纬度坐标转换为像素坐标,然后找到像素中心和转换回成经/纬度坐标。

您可能没有注意到或不介意这个漂移取决于你在赤道北部或南部多远。您可以通过在setInterval内执行map.setCenter(map.getBounds()。getCenter())来查看漂移,漂移在接近赤道时会慢慢消失。

您可以使用以下命令在纬度/经度和像素坐标之间进行转换。像素坐标基于完全放大的整个世界的平面,但您可以找到其中心并将其切换回纬度/经度。

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 = lontotal/markercount;

0

我有一个情况我不能改变旧代码,所以添加了这个javascript函数来计算的中心点和缩放级别:

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

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

+8

你的代码伤害了我的眼睛:) –

0

这里是我拿到这个的情况下,任何人都会遇到这个问题:

这有助于防止非数字数据破坏确定latlng的最终变量。

它的工作原理是取出所有坐标,将它们解析为单独的数组latlng,然后确定每个坐标的平均值。这平均值应中心(并已在我的测试案例证明属实。)

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