Postgis

累積計算沿線的距離

  • October 27, 2020

我正在使用 Postgis 來:

  • 計算沿線的累積距離(以米為單位)
  • 將累積距離儲存在“m”中

我有一張表,這條線上有一個點,每一行都有緯度和經度座標。所有行的“m”值為 0。

下面的程式碼很好地讓我知道了第一個點和下一個點之間的距離。

SELECT a.geom
FLOOR(
ST_Distance(ST_Transform(a.geom, 3857), ST_Transform(b.geom, 3857)) * cosd(42.3521))
AS dist
FROM line a
LEFT JOIN line b
ON a.id = b.id + 1

但是,它並沒有加起來,也沒有更新“m”值。

我嘗試了以下的一組排列,但它們都沒有儲存前一行的“m”值的累積總和,再加上這一點與前一點之間距離的計算。

WITH next AS (
   SELECT
   ST_Distance(ST_Transform(a.geom, 3857), ST_Transform(b.geom, 3857)) * cosd(42.3521)
   AS dist,
   a.id AS rowid,
   FROM line a
   JOIN line b
   ON a.id = b.id + 1
)
UPDATE line a
SET m = FLOOR(next.m + next.dist)
FROM next
WHERE a.id = next.rowid
RETURNING a.m, next.dist;

或者

update line a
   set m = FLOOR(a.m + prev.dist) 
   from (select
           l.*,
           ST_Distance(ST_Transform(
               lag(geom) over (order by l.id asc)
           , 3857), ST_Transform(geom, 3857)) * cosd(42.3521) as dist
           from line l
         ) AS prev
   where prev.id = a.id - 1
   returning prev.m, prev.dist, a.m

有任何想法嗎?

擺弄cosd()是愚蠢的,尤其是當您不知道實際緯度時。ST_Distance可以直接計算所需的值,如果你給它地理值;如果你有 lon/lat 幾何圖形,你可以簡單地投射它們。

要逐步累加長度,請使用遞歸 CTE:

WITH RECURSIVE cum(id, geom, dist) AS (
 SELECT id,
        geom,
        0::double precision
 FROM line
 WHERE id = 1

 UNION ALL

 SELECT line.id,
        line.geom,
        cum.dist + ST_Distance(cum.geom::geography, line.geom::geography)
 FROM cum
 JOIN line ON cum.id + 1 = line.id
)
UPDATE line
SET m = dist
FROM cum
WHERE line.id = cum.id;

引用自:https://dba.stackexchange.com/questions/278713