【问题标题】:Google Maps Api v3 - find nearest markersGoogle Maps Api v3 - 查找最近的标记
【发布时间】:2011-05-02 17:48:19
【问题描述】:

当我点击地图时,找到最近的一个或多个标记的最佳方式是什么? api中是否有一些功能可以帮助我做到这一点?

这是谷歌地图 api v3。

【问题讨论】:

  • 您是否使用任何数据库来存储标记的坐标?
  • 当然,标记位置存储在mysql数据库中。

标签: google-maps google-maps-api-3


【解决方案1】:

首先你必须添加事件监听器

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

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

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

【讨论】:

  • 不要打开旧线程,但我已经尝试实现这一点,它似乎向东搜索而不是找到最近的。因此,如果我搜索一个位置,它会向东搜索并找到最近的位置,即使在西边有一个真正的接近点。这有意义吗?
  • @Lee - 这是有道理的,但我无法复制这个问题
  • 是的,这对我来说根本不起作用 - 把我放在我们加利福尼亚的位置,我在纽约。我的位置有一个标记。不过它确实找到了一个标记!
  • @mheavers - 代码中有错误。从(i=1 更改为 from(i=0。它不包括第一个标记。
  • @Magico 你不能把 javascript 变成 php 代码。您可以编写一个生成 javascript 代码的 php 包装器,如答案中所示。如果自己做不到,就不要用php了……
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    我想扩展 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对象。

    【讨论】:

    • 很棒的答案!
    • 简洁明了的答案!
    • 这可以用来按距离对标记进行排序,而不是只返回一个吗?
    • 当然@Louis,查找过滤方法。您可以使用它对它们进行排序
    • 我通过删除位置对象上的位置来使其工作;像这样:computeDistanceBetween(location, prev.position) ... 因为 location 已经是一个 LatLng 对象。
    【解决方案4】:

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

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

    【讨论】:

    • 如何填充markers 数组?是通过使用var marker1 = new google.maps.Marker({ ... }) 创建标记吗?
    • @enchance 我必须这样做:map.markers = map.markers || []; 然后对于每个标记 map.markers.push(marker);
    【解决方案5】:

    你知道Mysql Spatial extensions吗?

    你可以使用MBRContains(g1,g2)之类的东西。

    【讨论】:

    • 再次 ^^ 都是 404 - 仅链接答案的问题。
    【解决方案6】:

    这是另一个对我很有用的函数,以公里为单位返回距离:

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

    【讨论】:

      【解决方案7】:

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

      步骤:-

      1. 在谷歌地图上创建标记。
        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());
            }
        

      访问this link 按照步骤操作。您将能够获得更接近您所在位置的标记。

      【讨论】:

        猜你喜欢
        • 2014-03-05
        • 2013-08-12
        • 1970-01-01
        • 1970-01-01
        • 2016-06-08
        • 1970-01-01
        • 2014-07-01
        • 2012-05-11
        相关资源
        最近更新 更多