在一系列 GPS 数据中寻找最近的经过点
Finding the closest passing points in a series of GPS data
我有一个具有以下架构的 table:
Table "public.gps_log"
Column | Type
---------------------------+-----------------------------
id | integer
logged_at | timestamp without time zone
lonlat | geography(Point,4326)
另一个具有以下架构:
Table "public.waypoint"
Column | Type
---------------------------+-----------------------------
id | integer
lonlat | geography(Point,4326)
range | numeric
gps_log
包含来自 GPS 的每分钟位置报告,waypoint
包含一组 waypoints 及其位置。
我有以下查询:
SELECT gps_log.id as id1, waypoint.id as id2, ST_Distance(gps_log.lonlat, waypoint.lonlat) as dist
FROM gps_log, waypoint
WHERE ST_DWithin(gps_log.lonlat, waypoint.lonlat, waypoint.range)
ORDER BY id1;
return结果如下:
id1 | id2 | dist
-------+------+----------------
4499 | 1118 | 2580.557160943 <- first and closest dist in this cluster of id2=1118
4500 | 1118 | 2580.557160943
4501 | 1119 | 3861.038787463 <- etc. ...
4502 | 1119 | 3861.038787463
4503 | 1118 | 885.481236082 <-
4504 | 1118 | 885.481236082
4505 | 1119 | 2114.289192152 <-
4506 | 1119 | 2114.289192152
4507 | 1118 | 3209.147139384
4508 | 1118 | 3209.147139384
4510 | 1118 | 2194.494307877 <-
4511 | 1118 | 2194.494307877
4514 | 1118 | 2253.163728865
4515 | 1117 | 3155.907772254 <-
4518 | 1117 | 3875.930499045
4519 | 1118 | 3834.344459575 <-
4522 | 1117 | 2025.333877603 <-
4523 | 1117 | 2025.333877603
4603 | 1116 | 1075.801799628
4604 | 1116 | 1075.801799628
4607 | 1116 | 663.907042351
4608 | 1116 | 663.907042351
4611 | 1116 | 319.142003353 <-
4612 | 1116 | 319.142003353
4614 | 1116 | 535.03813233
4615 | 1116 | 535.03813233
4630 | 1132 | 2134.348193208
4631 | 1181 | 2165.19731156 <-
4784 | 1134 | 337.398349813 <-
4785 | 1134 | 337.398349813
4788 | 1135 | 1388.859874755 <-
4789 | 1135 | 1388.859874755
我最终希望查询到return最近通过每个航点的GPS位置报告,并且一个航点可以多次通过。
上面的箭头代表我想return作为查询结果的记录——基本上每次有一个新的路点ID集群,离路点最近距离的位置报告是returned.
现在,我的解决方案是 运行 上面的查询,然后在代码中处理结果以循环遍历数组并找到正确的值。
这是 "gaps-and-islands" 问题的变体。您可以使用不同的行号来标识组。然后,您可以使用 DISTINCT ON
:
提取具有最小距离的行
WITH d as (
SELECT gps_log.id as id1, w.id as id2, ST_Distance(gl.lonlat, w.lonlat) as dist
FROM gps_log gl JOIN
waypoint w
ON ST_DWithin(ol.lonlat, w.lonlat, w.range)
)
SELECT DISTINCT ON (id2, grp) d.*
FROM (SELECT d.*,
(ROW_NUMBER() OVER (ORDER BY id1) -
ROW_NUMBER() OVER (PARTITION BY id2 ORDER BY id1)
) as grp
FROM d
) d
ORDER BY id2, grp, dist;
理解为什么行号的差异起作用是相当棘手的。我建议您 运行 子查询生成两个行数值。然后您可以看到差异如何定义您想要的组。
我有一个具有以下架构的 table:
Table "public.gps_log"
Column | Type
---------------------------+-----------------------------
id | integer
logged_at | timestamp without time zone
lonlat | geography(Point,4326)
另一个具有以下架构:
Table "public.waypoint"
Column | Type
---------------------------+-----------------------------
id | integer
lonlat | geography(Point,4326)
range | numeric
gps_log
包含来自 GPS 的每分钟位置报告,waypoint
包含一组 waypoints 及其位置。
我有以下查询:
SELECT gps_log.id as id1, waypoint.id as id2, ST_Distance(gps_log.lonlat, waypoint.lonlat) as dist
FROM gps_log, waypoint
WHERE ST_DWithin(gps_log.lonlat, waypoint.lonlat, waypoint.range)
ORDER BY id1;
return结果如下:
id1 | id2 | dist
-------+------+----------------
4499 | 1118 | 2580.557160943 <- first and closest dist in this cluster of id2=1118
4500 | 1118 | 2580.557160943
4501 | 1119 | 3861.038787463 <- etc. ...
4502 | 1119 | 3861.038787463
4503 | 1118 | 885.481236082 <-
4504 | 1118 | 885.481236082
4505 | 1119 | 2114.289192152 <-
4506 | 1119 | 2114.289192152
4507 | 1118 | 3209.147139384
4508 | 1118 | 3209.147139384
4510 | 1118 | 2194.494307877 <-
4511 | 1118 | 2194.494307877
4514 | 1118 | 2253.163728865
4515 | 1117 | 3155.907772254 <-
4518 | 1117 | 3875.930499045
4519 | 1118 | 3834.344459575 <-
4522 | 1117 | 2025.333877603 <-
4523 | 1117 | 2025.333877603
4603 | 1116 | 1075.801799628
4604 | 1116 | 1075.801799628
4607 | 1116 | 663.907042351
4608 | 1116 | 663.907042351
4611 | 1116 | 319.142003353 <-
4612 | 1116 | 319.142003353
4614 | 1116 | 535.03813233
4615 | 1116 | 535.03813233
4630 | 1132 | 2134.348193208
4631 | 1181 | 2165.19731156 <-
4784 | 1134 | 337.398349813 <-
4785 | 1134 | 337.398349813
4788 | 1135 | 1388.859874755 <-
4789 | 1135 | 1388.859874755
我最终希望查询到return最近通过每个航点的GPS位置报告,并且一个航点可以多次通过。
上面的箭头代表我想return作为查询结果的记录——基本上每次有一个新的路点ID集群,离路点最近距离的位置报告是returned.
现在,我的解决方案是 运行 上面的查询,然后在代码中处理结果以循环遍历数组并找到正确的值。
这是 "gaps-and-islands" 问题的变体。您可以使用不同的行号来标识组。然后,您可以使用 DISTINCT ON
:
WITH d as (
SELECT gps_log.id as id1, w.id as id2, ST_Distance(gl.lonlat, w.lonlat) as dist
FROM gps_log gl JOIN
waypoint w
ON ST_DWithin(ol.lonlat, w.lonlat, w.range)
)
SELECT DISTINCT ON (id2, grp) d.*
FROM (SELECT d.*,
(ROW_NUMBER() OVER (ORDER BY id1) -
ROW_NUMBER() OVER (PARTITION BY id2 ORDER BY id1)
) as grp
FROM d
) d
ORDER BY id2, grp, dist;
理解为什么行号的差异起作用是相当棘手的。我建议您 运行 子查询生成两个行数值。然后您可以看到差异如何定义您想要的组。