8

在 PHP 中,我有以下代码用于计算两个位置之间的距离:

<?php
function distance($lat1, $long1, $lat2, $long2) {
    // DEGREE TO RADIAN
    $latitude1 = $lat1/180*pi();
    $longitude1 = $long1/180*pi();
    $latitude2 = $lat2/180*pi();
    $longitude2 = $long2/180*pi();
    // FORMULA: e = ARCCOS ( SIN(Latitude1) * SIN(Latitude2) + COS(Latitude1) * COS(Latitude2) * COS(Longitude2-Longitude1) ) * EARTH_RADIUS
    $distance = acos(sin($latitude1)*sin($latitude2)+cos($latitude1)*cos($latitude2)*cos($longitude2-$longitude1))*6371;
    return $distance;
}
echo distance(9.9921962, 53.5534074, 9.1807688, 48.7771056); // Hamburg, DE - Stuttgart, DE
?>

但是现在,我想通过 PHP 从我的 MySQL 数据库中选择靠近给定位置的位置:

  • 用户进入家乡
  • 我的脚本通过 Google API 获取纬度/经度值
  • 在我的数据库中,我有大约 200 个位置,其中一个字段用于纬度值,一个字段用于经度值
  • 我需要 PHP 和 MySQL 的代码来选择离用户家乡最近的 10 个位置

我希望你能帮助我。提前致谢!

4

7 回答 7

8

MySQL 大圆距离(Haversine 公式)完全符合您的需要。

但是,只有 200 条记录,您不妨将它们全部加载并用代码检查它们。数据集真的太小了,不能过多地担心数据库与代码或任何其他此类优化。

在 PHP 中计算邮政编码之间的距离有几个该算法的 PHP 实现。

地理邻近搜索与您遇到的问题几乎完全相同。

于 2009-05-24T00:53:34.413 回答
4

也许像

SELECT field1, field2, ...,
    ACOS(SIN(latitude / 180 * PI()) * SIN(:1) + COS(latitude / 180 * PI()) * COS(:2) * COS(:2 - longtidude)) * 6371 AS distance
    ORDER BY distance ASC;

或者

SELECT field1, field2, ...,
    ACOS(SIN(RADIANS(latitude)) * SIN(:1) + COS(RADIANS(latitude)) * COS(:2) * COS(:2 - longtidude)) * 6371 AS distance
    ORDER BY distance ASC;

(直接翻译自PHP代码)

:1:2$lat2/180*pi()$long2/180*pi()分别。

于 2009-05-24T01:41:52.460 回答
1

这就是哈弗辛公式。您可以将 PHP 直接转换为 SQL,以便在空间上查询数据库(另一种方法是将每条记录从数据库中拉出并通过 PHP 运行数据)。MySQL 提供了您需要的所有数学函数。

我是为一个提供基于邮政/邮政编码的距离查找的商业网站这样做的,因此如果没有特定的 GIS 功能,它肯定是可能的。

于 2009-05-23T23:57:13.187 回答
0

有一些 MySQL 函数可用于执行此操作。

http://dev.mysql.com/doc/refman/5.0/en/gis-introduction.html

于 2009-05-21T19:41:12.987 回答
0

MySQL 具有地理空间索引行的能力。你可能不需要自己做这个数学(你可以让 MySQL 计算两个地理对象之间的距离并按它排序......)。

见: http: //forums.mysql.com/read.php?23,159205,159205

于 2009-05-21T19:41:47.573 回答
0

刚刚跨过这个话题。也许有人会对这个功能感兴趣,在 MySql 5.7 中测试过:

    create function GetDistance(lat1 real, lng1 real, lat2 real, lng2 real) returns real no sql
    return ATAN2(SQRT(POW(COS(RADIANS(lat2)) * SIN(RADIANS(lng1 - lng2)), 2) + 
                POW(COS(RADIANS(lat1)) * SIN(RADIANS(lat2)) - SIN(RADIANS(lat1)) *
                COS(RADIANS(lat2)) *  COS(RADIANS(lng1 - lng2)), 2)), 
                (SIN(RADIANS(lat1)) * SIN(RADIANS(lat2)) + COS(RADIANS(lat1)) *
                COS(RADIANS(lat2)) * COS(RADIANS(lng1 - lng2)))) * 6372.795;

来电:

select GetDistance(your_latitude, your_longitude, table_field_lat,
                   table_field_lng) as dist from [your_table] limit 5;
于 2018-06-14T13:08:15.373 回答
-1

为什么不使用 MySQL 的地理空间功能...?不只是在开玩笑。

如果 200 条记录是实际的地方,如城镇等,那么作为替代方案,您可以使用 GeoNames 的 API 吗?

以下 Web 服务将提供与所提供的 lat 和 lng 最接近的 10 个位置:

http://ws.geonames.org/findNearby?lat=47.3&lng=9

来源:http ://www.geonames.org/export/web-services.html#findNearbyPlaceName

完整列表:http ://www.geonames.org/export/ws-overview.html

于 2009-05-23T23:48:23.500 回答