在 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 个位置

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

有帮助吗?

解决方案

MySQL 大圆距离(半正矢公式) 正是您所需要的。

然而,只有 200 条记录,您也可以加载所有记录并使用代码检查它们。数据集确实太小了,无法过多担心数据库与代码或任何其他此类优化。

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

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

其他提示

也许像

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() 分别。

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

我为一个商业网站执行此操作,该网站提供基于邮政/邮政编码的距离查找,因此在没有特定 GIS 功能的情况下当然是可能的。

MySQL 中有一些函数可以用来完成此任务。

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

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

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

刚刚跨过这个话题。也许有人会对这个函数感兴趣,在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;

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

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

以下网络服务将提供距离所提供的纬度和经度最近的 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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top