php - 使用 SQLite 计算大圆距离

标签 php sqlite pdo geospatial haversine

这是我的问题,我有一个包含位置和纬度/经度的 SQLite 表。基本上我需要:

SELECT location, HAVERSINE(lat, lon) AS distance FROM location ORDER BY distance ASC;

HAVERSINE() 是一个 PHP 函数,它应该返回 Great-Circle Distance (以英里或公里为单位)给定一对纬度和经度值。 其中一对应由 PHP 提供,另一对应由 locations 表中可用的每个纬度/经度行提供

由于 SQLite 没有任何地理空间扩展(AFAIK SpatiaLite 存在但仍然......)我猜最好的方法是使用具有任一 PDO 方法的自定义函数:

我认为对于这种情况 PDO::sqliteCreateFunction() 就足够了,但是我对这个函数的有限经验可以简化为类似于 PHP 手册中提供的使用案例:

$db = new PDO('sqlite:geo.db');

function md5_and_reverse($string) { return strrev(md5($string)); }

$db->sqliteCreateFunction('md5rev', 'md5_and_reverse', 1);
$rows = $db->query('SELECT md5rev(filename) FROM files')->fetchAll();

我在弄清楚如何让 SQLite 用户定义的函数同时处理来自 PHP 的数据和表数据时遇到了一些问题,如果有人能帮我解决这个问题,我将不胜感激问题,同时也更好地理解 SQLite UDF(SQLite IMO 的一大胜利)。

提前致谢!

最佳答案

到目前为止我只能想到这个解决方案:

$db = new PDO('sqlite:geo.db');

$db->sqliteCreateFunction('ACOS', 'acos', 1);
$db->sqliteCreateFunction('COS', 'cos', 1);
$db->sqliteCreateFunction('RADIANS', 'deg2rad', 1);
$db->sqliteCreateFunction('SIN', 'sin', 1);

然后执行以下冗长的查询:

SELECT "location",
       (6371 * ACOS(COS(RADIANS($latitude)) * COS(RADIANS("latitude")) * COS(RADIANS("longitude") - RADIANS($longitude)) + SIN(RADIANS($latitude)) * SIN(RADIANS("latitude")))) AS "distance"
FROM "locations"
HAVING "distance" < $distance
ORDER BY "distance" ASC
LIMIT 10;

如果有人能想到更好的解决方案,请告诉我。


我只是found this interesting link ,我明天试试。

关于php - 使用 SQLite 计算大圆距离,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2083182/

相关文章:

sql - 如何在具有唯一 ID 的 SQLite 中插入重复行?

php - PDO MYSQL 更新不工作

php - 将消失的默认文本 Your Name 添加到文本输入框

php - 如果 mysql 行 A 值存在,则使用 PHP 将行 B 值更改为 1

php - laravel 数据库种子在 easyPHP 中失败

python - 使用odo将数据迁移到SQL

sql - 连接sqlite中未知数量的值

php - 数组值在表中插入为 0

php - MySQL 更新返回值

PHP SQL 上一个和下一个日期导航