Google Maps Api v3-查找最近的标记


Answers:


112

首先,您必须添加事件监听器

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

这样可以跟踪最接近的标记并提醒其标题。

我将标记作为数组放置在地图对象上


2
不是打开旧线程,而是我尝试实现了这一点,它似乎是向东搜索而不是找到最接近的线程。因此,如果我搜索一个位置,它将向东搜索并找到最接近的那个方向,即使在西边有一个REAL闭合点。那有意义吗?
LeeR 2011年

@李-这是有道理的,但我不能重复这个问题
盖伦

1
是的,这对我根本不起作用-将我带到我们在加利福尼亚的地点,我在纽约。而且在我的位置有一个标记。它确实找到了标记!
mheavers 2011年

@mheavers-代码中有错误。从(i = 1变为from(i = 0。不包括第一个标记。)
Galen

1
@Magico,您无法将javascript转换为php代码。您可以编写一个php包装程序,以生成javascript代码(如答案中所示)。如果您不能自己做,那就不要使用php ...
Daniel W.


30

对于任何对如何计算最近位置并实际提供可行解决方案感到困惑的人,我想扩展一下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
很棒的答案!
塞萨尔·阿隆索

干净整洁的答案!
TheeBen

可以将其用于按距离对标记进行排序,而不是仅返回一个吗?
路易W

确保@Louis,查找过滤器方法。您可以使用它来对它们进行排序
Jonathan

1
我通过移除位置对象上的位置使其工作。就像这样:computeDistanceBetween(location,prev.position)...因为location已经是一个LatLng对象。
holm50

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

1
@enchance我必须这样做:map.markers = map.markers || [];然后对于每个标记map.markers.push(marker);
travis


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

3

使用computeDistanceBetween()Google地图API方法来计算您的位置和谷歌地图上的标记列表之间的近标记。

脚步:-

  1. 在Google地图上创建标记。
    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. 在“鼠标”上,单击创建事件以获取经度,您的位置的较长时间,并将其传递给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());
        }
    

访问此链接,请按照以下步骤操作。您将可以更靠近您的位置标记。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.