2010-10-30 59 views
77

当我点击地图时,哪种方法可以找到最近的标记或标记?是否有一些函数可以帮助我做到这一点?Google Maps Api v3 - 查找最近的标记

这是google map api v3。

+1

您是否使用任何数据库来存储标记的坐标? – 2010-10-30 08:14:45

+0

当然,标记位置存储在MySQL数据库中。 – user198003 2010-10-31 11:11:46

回答

98

首先,你必须添加事件侦听

google.maps.event.addListener(map, 'click', find_closest_marker); 

然后创建通过标记列阵循环和使用haversine formula从点击计算每个标志物的距离的函数。

function rad(x) {return x*Math.PI/180;} 
function find_closest_marker(event) { 
    var lat = event.latLng.lat(); 
    var lng = event.latLng.lng(); 
    var R = 6371; // radius of earth in km 
    var distances = []; 
    var closest = -1; 
    for(i=0;i<map.markers.length; i++) { 
     var mlat = map.markers[i].position.lat(); 
     var mlng = map.markers[i].position.lng(); 
     var dLat = rad(mlat - lat); 
     var dLong = rad(mlng - lng); 
     var a = Math.sin(dLat/2) * Math.sin(dLat/2) + 
      Math.cos(rad(lat)) * Math.cos(rad(lat)) * Math.sin(dLong/2) * Math.sin(dLong/2); 
     var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
     var d = R * c; 
     distances[i] = d; 
     if (closest == -1 || d < distances[closest]) { 
      closest = i; 
     } 
    } 

    alert(map.markers[closest].title); 
} 

这跟踪最近的标记并提醒其标题。

我有我的标志作为数组我的地图对象

+0

很好的例子,但是,如果我点击芝加哥附近的标记,我会在警报窗口中看到纽约。是一个小错误,所以芝加哥没有正确列出,或其他? – user198003 2010-10-31 12:52:50

+0

是的,这是一个错误,我修正了它=) – Galen 2010-10-31 18:50:15

+2

不开放一个旧的线程,但我试图实现这一点,它似乎向东搜索,而不是找到最接近。因此,如果我搜索一个位置,它将向东搜索并找到最接近的位置,即使西面有一个REAL关闭。那有意义吗? – LeeR 2011-05-23 22:35:55

6

你知道的Mysql Spatial extensions

您可以使用类似MBRContains(g1,g2)的东西。

+1

页面未找到配对,所以您需要重新编辑第回答 – Val 2012-04-19 14:39:22

+0

@Val Done.Thanks – 2012-04-19 15:49:20

9

上面的公式并不适用于我,但我没有任何问题。通过您的当前位置的功能,并遍历标记的数组找到最接近:

function find_closest_marker(lat1, lon1) {  
    var pi = Math.PI; 
    var R = 6371; //equatorial radius 
    var distances = []; 
    var closest = -1; 

    for(i=0;i<markers.length; i++) { 
     var lat2 = markers[i].position.lat(); 
     var lon2 = markers[i].position.lng(); 

     var chLat = lat2-lat1; 
     var chLon = lon2-lon1; 

     var dLat = chLat*(pi/180); 
     var dLon = chLon*(pi/180); 

     var rLat1 = lat1*(pi/180); 
     var rLat2 = lat2*(pi/180); 

     var a = Math.sin(dLat/2) * Math.sin(dLat/2) + 
        Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(rLat1) * Math.cos(rLat2); 
     var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
     var d = R * c; 

     distances[i] = d; 
     if (closest == -1 || d < distances[closest]) { 
      closest = i; 
     } 
    } 

    // (debug) The closest marker is: 
    console.log(markers[closest]); 
} 
+1

如何填充'markers'数组?是通过使用'var marker1 = new google.maps.Marker({...})'创建一个标记吗? – enchance 2012-09-29 13:42:29

+1

@enchance我不得不这样做:'map.markers = map.markers || [];'然后为每个标记'map.markers.push(marker);' – travis 2012-10-24 19:31:53

59

可以在google.maps.geometry.spherical命名空间中的computeDistanceBetween()方法。

+1

+1这是迄今为止的最佳答案。 – bruchowski 2014-09-02 23:17:43

+0

这完全适合我 – ChrisRich 2014-10-21 00:28:33

+0

这个答案应该标记为 – 2016-03-30 07:03:19

2

这里是我的伟大工程的另一个函数,返回公里距离:

function distance(lat1, lng1, lat2, lng2) { 
     var radlat1 = Math.PI * lat1/180; 
     var radlat2 = Math.PI * lat2/180; 
     var radlon1 = Math.PI * lng1/180; 
     var radlon2 = Math.PI * lng2/180; 
     var theta = lng1 - lng2; 
     var radtheta = Math.PI * theta/180; 
     var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta); 
     dist = Math.acos(dist); 
     dist = dist * 180/Math.PI; 
     dist = dist * 60 * 1.1515; 

     //Get in in kilometers 
     dist = dist * 1.609344; 

     return dist; 
    } 
15

我想对雷欧的建议扩大对任何人对如何计算最近的位置和实际提供迷茫一个工作解决方案:

我在markers阵列中使用标记eg var markers = [];

然后让我们像下面的var location = new google.maps.LatLng(51.99, -0.74);

我们的立场,然后我们只是减少我们对标记我们有像这样的位置:

markers.reduce(function (prev, curr) { 

    var cpos = google.maps.geometry.spherical.computeDistanceBetween(location.position, curr.position); 
    var ppos = google.maps.geometry.spherical.computeDistanceBetween(location.position, prev.position); 

    return cpos < ppos ? curr : prev; 

}).position 

什么弹出是你最亲密的标志LatLng对象。

+0

真棒答案! – Wasa 2016-09-23 02:21:35

+0

@Wasa欢迎您:-) – Jonathan 2016-09-23 13:06:07

+0

整洁干净的答案! – TheeBen 2017-08-04 07:15:52

相关问题