【问题标题】:mysql calculate distance for returnning locationmysql计算返回位置的距离
【发布时间】:2019-10-13 22:47:55
【问题描述】:

这不是以下内容的重复: Find distance between two points using latitude and longitude in mysql

我尝试了查询,但它不起作用,我得到空数据集和 0 作为 答案。

查看答案,这就是解决方案,我不知道为什么这个问题被标记为来自 Shadow 的重复

我有一个结构如下的表:

table: distance
id int(10) primary key
lat float,
lon float,
time timestamp

我有一个 android 应用程序,它可以 ping 我的服务器并在每次更改位置时添加一条记录。

例如

id:1, lat:40.753979, lon:-111.881721, time = 1571004620
id:2, lat:40.753979, lon:-111.883721, time = 1571004630
id:3, lat:40.753979, lon:-111.885721, time = 1571004640

如果我走一个方向,我可以计算总距离:

/* in my python script*/
startLat,startLon = select lat,lon from distance where time >= 1571004620 order by time limit 1;
endLat,endLon = select lat,lon from distance where time <= 1571004640 order by time desc limit limit 1;

然后我可以减去两个坐标,最终得到0.004000的经度距离

问题:

如果我添加:

id:4, lat:40.753979, lon:-111.881721, time = 1571004650

那么我应该得到:0.008000

但我得到 0,因为位置 1 与位置 4 相同

【问题讨论】:

  • 考虑到您所说的问题的答案不重复确实有效,您确实应该解释您尝试过的内容以及您遇到的错误消息或意外行为。
  • 我运行了查询,它没有返回预期的结果,它适用于非返回位置
  • @Shadow 我得到:空集(0.00 秒)第一个答案,我得到 0 第二个答案
  • 由于我不知道您正在运行什么查询,因此我无法评论您的尝试出了什么问题。这就是为什么你应该在你的问题中包含这些尝试的确切代码。

标签: python mysql mysql-5.7 mysql-spatial


【解决方案1】:

您可以利用 MySQL 空间支持(自 5.7 起提供)在数据库中执行整个计算。函数ST_Distance_Sphere()可用于计算距离。

您实际上需要距离的累积总和(这需要窗口函数,自 MySQL 8.0 起可用)。

考虑:

SELECT
    id,
    time,
    SUM(
        CASE WHEN lag_lat IS NULL 
            THEN 0
            ELSE ST_Distance_Sphere(point(lag_lon, lag_lat), point(lon, lat))
        END
    ) OVER (ORDER BY time) cumulative_distance
FROM (
    SELECT
        d.*,
        LAG(lat) OVER(ORDER BY time) lag_lat,
        LAG(lon) OVER(ORDER BY time) lag_lon
    FROM distance d
)  x

Demo on DB Fiddle

| id  | time       | cumulative_distance |
| --- | ---------- | ------------------- |
| 1   | 1571004620 | 0                   |
| 2   | 1571004630 | 168.37177423236415  |
| 3   | 1571004640 | 336.7435484657999   |
| 4   | 1571004650 | 673.4870969097663   |

在 MySQL 的早期版本中,您需要模拟窗口函数:

  • LAG() 可以替换为带有NOT EXISTS 条件的self-LEFT JOINON 条件中的相关子查询

  • 变量可以模拟累加SUM

查询:

SELECT
    id,
    time,
    @running_distance := @running_distance + CASE
        WHEN lag_lat IS NULL THEN 0
        ELSE ST_Distance_Sphere(point(lag_lon, lag_lat), point(lon, lat))
    END running_distance
FROM (
    SELECT
        d.id,
        d.time,
        d.lat,
        d.lon,
        d_lag.lat lag_lat,
        d_lag.lon lag_lon   
    FROM distance d
    LEFT JOIN distance d_lag
        ON  d_lag.time < d.time
        AND NOT EXISTS (
            SELECT 1 
            FROM distance d1
            WHERE d1.time < d.time AND d1.time > d_lag.time
        )
    ORDER BY d.time
) x
CROSS JOIN (SELECT @running_distance := 0) y

Demo on DB Fiddle:结果与上述相同。

【讨论】:

  • MySQL server version for the right syntax to use near '(ORDER BY time
  • 你用的是哪个版本的mysql?我提到这使用窗口函数,仅从 8.0 开始可用
  • 我正在使用版本:5.7.27,我无法升级到 v 8
  • @yenk:我用 MySQL
  • 它确保当前记录和正在加入的记录之间没有记录。换句话说,它确保我们正在加入紧接在前的记录。
猜你喜欢
  • 2014-01-05
  • 2011-04-03
  • 1970-01-01
  • 2018-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-16
  • 2019-03-08
相关资源
最近更新 更多