谷歌地图API V3 - 查找最近的标记点

97

当我点击地图时,最好的方法是找到最近的标记或标记吗? 是否有API中的一些函数可以帮助我做到这一点?

这是Google地图API V3。


1
你使用任何数据库来存储标记的坐标吗? - Argiropoulos Stavros
当然,标记位置存储在MySQL数据库中。 - user198003
7个回答

116

首先你需要添加事件监听器

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

然后创建一个函数,循环遍历标记数组并使用haversine公式来计算每个标记与点击位置之间的距离。

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

这个功能会跟踪最近的标记并发送它的标题。

我将我的标记作为一个数组放在我的地图对象上。


3
不要重新打开旧的话题,但是我已经尝试实施这个功能,看起来它好像在向东搜索而不是找到最近的地点。所以,如果我搜索一个地点,它会向东搜索并找到那个方向上最接近的地点,即使在西边有一个真正更近的地点。这说得通吗? - LeeR
@Lee - 这很有道理,但我无法复制这个问题。 - Galen
2
是的,这对我完全没用 - 它把我放在了我们加利福尼亚的位置,而我在纽约。并且我的位置上有一个标记。不过它确实找到了一个标记! - mheavers
1
@Magico 你不能将JavaScript转换为PHP代码。你可以编写一个生成JavaScript代码的PHP包装器,就像回答中所示。如果你无法自行完成,请不要使用PHP... - Daniel W.
@Galen,这些是驾车距离还是直线距离? - Web User
显示剩余4条评论

79

37

我想扩展Leor的建议并提供一个可行的解决方案:

我在一个markers数组中使用标记,例如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 对象。


1
太棒了的回答! - Cesar Alonso
整洁明了的答案! - TheBen
这个能用来按距离排序标记吗,而不仅仅返回一个标记? - Louis W
当然,@Louis,请查找过滤器方法。您可以使用它来对它们进行排序。 - Jonathan
1
我通过在位置对象上删除位置来使其工作;像这样:computeDistanceBetween(location,prev.position)...因为位置已经是一个LatLng对象。 - holm50

10

对我来说上面的公式不起作用,但是我使用了以下这种方法没有任何问题。将您当前的位置传递给函数,并循环遍历标记数组以找到最近的标记:

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
1
@enchance 我不得不这样做:map.markers = map.markers || []; 然后对于每个标记 map.markers.push(marker); - travis

5

1
再次 ^^ 两者都是404 - 链接唯一答案的问题。 - treyBake

5
使用computeDistanceBetween()方法Google地图API来计算你的位置与Google地图上标记列表之间的近距离标记。 步骤:
  1. Create marker on google map.
    function addMarker(location) { var marker = new google.maps.Marker({ title: 'User added marker', icon: { path: google.maps.SymbolPath.BACKWARD_CLOSED_ARROW, scale: 5 }, position: location, map: map }); }

  2. On Mouse click create event for getting lat, long of your location and pass that to find_closest_marker().

    function find_closest_marker(event) {
          var distances = [];
          var closest = -1;
          for (i = 0; i < markers.length; i++) {
            var d = google.maps.geometry.spherical.computeDistanceBetween(markers[i].position, event.latLng);
            distances[i] = d;
            if (closest == -1 || d < distances[closest]) {
              closest = i;
            }
          }
          alert('Closest marker is: ' + markers[closest].getTitle());
        }
    

访问此链接,按照步骤操作,即可在您的位置附近找到标记。


4

这是另一个对我非常有效的函数,以千米为单位返回距离:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接