在地理定位排序中显示距离(以英里为单位)

Posted

技术标签:

【中文标题】在地理定位排序中显示距离(以英里为单位)【英文标题】:Show distance in miles on a Geolocation sort 【发布时间】:2013-04-03 19:06:15 【问题描述】:

我想通过在下面的 sn-p 中使用 SPAN 标签执行类似的操作,以英里为单位显示每个列表项的距离,但我不确定如何。该脚本已经很好地排序并计算了距离,我只是不知道如何将其写入页面。我觉得这很简单,所以我希望有人能帮助我!

        <li>
            <div class="name">
                Moe Bar <span class="miles"></span></div>
            <div class="long">
                47.60357999999998</div>
            <div class="lat">
                -122.329454</div>
        </li>

完整代码 http://demos.thebeebs.co.uk/bars-in-seattle/的工作示例

<!DOCTYPE html>
<html>
<head>
    <title>Local Bars</title>
    <script src="http://ajax.microsoft.com/ajax/jquery/jquery-1.5.min.js"></script>
    <script>
        function findMe() 
            if (navigator.geolocation != undefined) 
                navigator.geolocation.watchPosition(onFound, onError);
            
        
        function onFound(pos) 
            var userLat = pos.coords.latitude;
            var userLong = pos.coords.longitude;
            $('ul li').each(function (index) 
                var locationLat = $(this).find('.lat').html();
                var locationLong = $(this).find('.long').html();
                var distance = getDistance(userLat, locationLat, userLong, locationLong);
                $(this).data("distance", distance);
            )

            reOrder();
        

        function onError(pos) 
            alert("Something Went wrong");
        

        function reOrder() 
            $('ul li').sort(sortAlpha).appendTo('ul');
        

        function sortAlpha(a, b) 
           return $(a).data('distance') > $(b).data('distance') ? 1 : -1;
        ;

        function getDistance(lat1, lat2, lon1, lon2) 
            var R = 6371; // km
            var d = Math.acos(Math.sin(lat1) * Math.sin(lat2) +
                  Math.cos(lat1) * Math.cos(lat2) *
                  Math.cos(lon2 - lon1)) * R;
            return d;

        ; 


    </script>
    <style>
        ul .long, ul .lat
        
            display: none;
        
    </style>
</head>
<body>
    <div>
        <a href="#" onclick="findMe()">Find Closest Pub</a>
        <ul>
            <li>
                <div class="name">
                    Moe Bar</div>
                <div class="long">
                    47.60357999999998</div>
                <div class="lat">
                    -122.329454</div>
            </li>
            <li>
                <div class="name">
                    Frontier Room</div>
                <div class="long">
                    47.61469022047056</div>
                <div class="lat">
                    -122.34816509008769</div>
            </li>
            <li>
                <div class="name">
                    See Sound</div>
                <div class="long">
                    47.6156159656448</div>
                <div class="lat">
                    -122.32593494177237</div>
            </li>
        </ul>
    </div>
</body>
</html>

【问题讨论】:

【参考方案1】:

这是一个实时工作示例:http://jsbin.com/ebeyaz/4/edit

假设:

在我的代码中,该列表更容易编码,并且解释假定以下代码:

<li data-lat="-122.34928138554072" data-lng="47.61370665587537">
    War Room
</li>

解释:

您正在使用您甚至没有的data 属性进行排序...所以,首先要附加这样的属性。

您已经有了当前的纬度和经度,您只需要使用 navigator.geolocation 坐标计算每个条之间的距离,为此,您应该将公式更新为

// Haversine formula
// http://www.movable-type.co.uk/scripts/latlong.html
function getDistance(lat1, lat2, lon1, lon2) 
  var R = 6371, // km
      dLat = (lat2-lat1).toRad(),
      dLon = (lon2-lon1).toRad();

  lat1 = parseFloat(lat1).toRad();
  lat2 = parseFloat(lat2).toRad();

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

然后,遍历所有并使用结果创建该属性,例如:

function addDistances(list, geoData)

  $(list).each(function() 
    var lat = $(this).data("lat"),
        lng = $(this).data("lng"),
        d = getDistance(lat, geodata.latitude, lng, geodata.longitude),
        km = (Math.floor(d * 100)/100),
        mi = (Math.floor((d*0.621371) * 100)/100);
    $(this)
      .attr("data-distance", d)
      .append(" <span>(" + km + "Km - " + mi + "Miles)</span>");
  );

那么你就可以使用你所拥有的正常排序了。

我的输出:

【讨论】:

Balexandre,非常好!感谢您抽出宝贵的时间。不过,它似乎只适用于 Chrome……尝试了 Firefox 和 Safari,但没有成功。有什么想法吗? 是的,我知道为什么...这是假设,Chrome 做得很好,但其他需要设置以了解他们从 Google API 接收的数据类型是 json,所以我们需要使用$.ajax 而不是短的$.get。示例已更新。 太棒了!你一直很有帮助,谢谢一百万!最后一个问题。如果我不想在页面加载时要求分享您的位置,而是只想在您单击“按最近的条形排序”时获取您的位置,我将如何实现这一点,理解我会失去关于“看起来你就在附近……' 那么您只需请求该click 事件的位置。例如。 $(document).delegate('a.show-pos', 'click', function() requestPosition(); ); 其中requestPosition 将是一个简单的function requestPosition() if (navigator.geolocation) navigator.geolocation.getCurrentPosition(success, error); else alert('Your device does not support GeoLocation!');

以上是关于在地理定位排序中显示距离(以英里为单位)的主要内容,如果未能解决你的问题,请参考以下文章

地理定位 API 在 android 中以本地语言显示地址

JavaScript 地理定位:检查距 2 gps 坐标的距离

猫鼬地理定位动态最大距离[重复]

HTML5地理位置定位Geolocation-API及Haversine地理空间距离算法

HTML5地理位置定位Geolocation-API及Haversine地理空间距离算法

如何找到地图中两个地理点之间的正确距离?