我有以下查询,它对位置进行聚类,并返回一个聚类ID,以及一个包含该聚类中原始点的结构:
SELECT
cluster_id,
ST_AsGeoJSON(ST_Collect(origin)) AS points
FROM (
SELECT
origin,
ST_ClusterDBSCAN(origin, eps := 0.01, minPoints := 5) OVER(ORDER BY id) AS cluster_id
FROM
ride
WHERE
region_id = 1 AND
created_at > now() - interval '1 week'
) a
WHERE cluster_id IS NOT NULL
GROUP BY cluster_id
示例输出:
3 {"type":"MultiPoint","coordinates":[ ... ]}
4 {"type":"MultiPoint","coordinates":[ ... ]}
我不想返回原始点,而是要返回聚类的边界圆(中心和半径),可以使用ST_MinimumBoundingRadius
完成此操作:
SELECT
ST_AsGeoJSON(center),
radius
FROM
ST_MinimumBoundingRadius(
ST_GeomFromGeoJSON('{"type":"MultiPoint","coordinates":[ ... ]}')
)
示例输出:
{"type":"Point","coordinates":[ ... ]} 0.002677744742706528
但是,由于ST_MinimumBoundingRadius
返回两列,因此以下内容会引发错误:
SELECT
cluster_id,
ST_MinimumBoundingRadius(ST_Collect(origin))
FROM (
...
) a
WHERE cluster_id IS NOT NULL
GROUP BY cluster_id;
我发现了this个问题,其中提到使用LATERAL
,但是我无法获得有效的查询。
正确的方法是什么?
答案 0 :(得分:2)
尝试另一个子选择:
SELECT q.cluster_id,
(q.mbr).radius,
(q.mbr).center
FROM (
SELECT cluster_id,
ST_MinimumBoundingRadius(
ST_Collect(origin)
) AS mbr
FROM (
...
) AS a
) AS q;
答案 1 :(得分:0)
最后真的很简单,不知道我怎么没想到这一点。
SELECT
cluster_id,
(ST_MinimumBoundingRadius(ST_Collect(origin))).*
FROM (
SELECT
origin,
ST_ClusterDBSCAN(origin, eps := 0.01, minPoints := 5) OVER(ORDER BY id) AS cluster_id
FROM
ride
WHERE
region_id = 1 AND
created_at > now() - interval '1 week'
) a
WHERE cluster_id IS NOT NULL
GROUP BY cluster_id