【问题标题】:Finding nearest locations using Google Maps API使用 Google Maps API 查找最近的位置
【发布时间】:2013-05-15 09:22:58
【问题描述】:

您好,我正在编写一个显示地址附近的自行车站的应用。我有服务中每个自行车站的纬度和经度位置列表。

我可以标记我当前的位置,或到目前为止的任何地址。如何在地图上显示我所在位置附近的所有自行车站。我是否首先从当前位置获取最近的 Google 地点,然后访问数据库以获取自行车位置并在地图上做标记?最好的方法是什么?

【问题讨论】:

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


    【解决方案1】:

    如果您已经拥有自行车站的坐标并且您信任这些数据,那么只需使用它来绘制标记即可。现在您必须定义“近”的含义。

    您对此有不同的解决方案。您可以选择为地图范围内的所有自行车站绘制标记(但根据缩放级别可能需要绘制许多标记,或者您必须阻止脚本在达到某个缩放级别之前绘制标记)或者您可以在某个位置周围 n 公里范围内绘制标记(可以是用户位置、地图中心坐标等)。

    对于第二种解决方案,如果您将自行车站存储在 MySQL 数据库中,您可以执行如下查询:

    $sql = "SELECT *, ( 6371 * acos( cos( radians(" . $db->real_escape_string($lat) . ") ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(" . $db->real_escape_string($lng) . ") ) + sin( radians(" . $db->real_escape_string($lat) . ") ) * sin( radians( lat ) ) ) ) AS distance FROM your_table_name HAVING distance < 15";
    

    $lat$lng 是您的中心坐标

    latlng 是您的 MySQL 列名

    15 是您坐标周围的半径(以公里为单位)

    这使用Haversine 公式。好的资料可以找here

    希望这会有所帮助,但我们并不真正了解您是如何在应用中组织数据的。如果您需要更多帮助,请向我们提供更多信息!

    【讨论】:

    • 感谢您的 sql 查询。我有所有自行车站的位置及其纬度和经度,我从服务中提取并可以将其存储在 sql 表中。我要试试你的解决方案。在某处看到,您可以将所有经纬度放入一个数组并使用 Haversine 公式。我有近 3000 条记录,不想将所有这些都加载到数组中并搜索最近的记录。我想我将尝试您的第二个解决方案并在此处更新有效的方法。干杯。
    • 如果我有 3K 条记录,我会使用这种方法。会好的。我正在处理超过 15 万条记录,并且运行良好。使用 AJAX!你将拥有一个很棒的应用程序! :-)
    • 非常感谢。对我帮助很大。
    • 它也帮助了我:)
    【解决方案2】:

    以防万一有人在 2016 年寻找正确答案。

    谷歌创建了一个非常有用的library,几何库有许多不同的方法可以帮助解决这个问题:

    computeDistanceBetween()

    这个answer准确地解释了如何使用它。

    这通常会计算两个通过的 LatLng 对象之间的距离。

    所以你可以简单地:

    • 获取所有自行车站点的位置。
    • 将它们存储在数组中。
    • 查找用户当前位置。
    • 循环您的阵列,并使用上述方法将位置转换为距离。
    • 对数组进行排序以获得最小距离。

    距离结果以米为单位。

    之前的算法可能没有优化,因为我们中的一些人可能有一个包含数千个坐标的数组,这其中 containsLocation() 方法变得很方便,因为您可以通过指定来缩小搜索区域您可以在其中搜索的多边形。

    这可能不是找到最近位置的最佳方法,但我相信如果您的数据库中有合理数量的站点,它就可以完成这项工作。

    【讨论】:

    • 您还应该考虑性能和 API 调用/配额。当 OP 提到他正在处理几千个位置时,我认为这不是一个合适的答案,尤其是当您可以通过一个数据库查询完成所有这些时。
    • @MrUpsidown 我希望你在发表评论之前仔细阅读答案:)
    • 是哪一部分?这两种方法都需要对每个点进行 API 调用。我错了吗?
    【解决方案3】:

    我有同样的任务,我用haversine解决了 公式。 这是我在 PHP 中的示例

    private function distance($latA, $lngA,$latB, $lngB) {
        $R = 6371000;
        $radiansLAT_A = deg2rad($latA);
        $radiansLAT_B = deg2rad($latB);
        $variationLAT = deg2rad($latB - $latA);
        $variationLNG = deg2rad($lngB - $lngA);
    
        $a = sin($variationLAT/2) * sin($variationLAT/2) 
                    + cos($radiansLAT_A) * cos($radiansLAT_B) * sin($variationLNG/2) * sin($variationLNG/2);
    
        $c = 2 * atan2(sqrt($a), sqrt(1-$a));
    
        $d = $R * $c;
    
        return $d;
    }  
    

    为了测试我使用了这些坐标

    $distance = $this->distance(-12.0972,-77.0267,-13.160616,-74.227440);
    

    结果应该是325932.546518,以米为单位。如果你想以公里为单位,只需除以325932.546518/1000 = 325.932546518km

    同样的公式可以按照指南haversine翻译成javascript

    【讨论】:

    • 这个数据的作用是什么 $R = 6371000; ?那是静态的吗?
    • @DimasAdiAndrea $R 是地球的半径 ;)
    • 我已经将此公式与谷歌地图的 computeDistanceBetween 函数进行了比较,并将两者都设置为 6378137 地球半径,该公式的结果是:812.3261185522,谷歌地图函数的结果是 812.3261185526761,这对我来说是可以接受的精度。所以最后我选择在我的项目中使用这个公式。谢谢
    【解决方案4】:

    Google 可能已经有these 结果, 但是,如果您已经有了这些地点的坐标,那么仅绘制点似乎会更直接。

    【讨论】:

    • 感谢您的回答。好像我需要另一个用于 google 地方的 api 密钥。我已经在使用 Android Maps 密钥来访问 Maps api,这让我有点困惑,需要阅读更多内容。
    • 是的,你是对的。虽然 Google 可以为您提供大量有用的数据,但如果您可以使用其他可信来源(您自己的数据、其他提供商等),请务必使用它们!这样您就不会依赖 Google 进行数据更新(这可能会很困难),而且在许多情况下您无论如何也不能。
    猜你喜欢
    • 2016-06-08
    • 2014-07-01
    • 2014-05-06
    • 1970-01-01
    • 1970-01-01
    • 2015-12-07
    • 1970-01-01
    • 2014-03-05
    • 2011-05-02
    相关资源
    最近更新 更多