如何遍历点以在PgSQL中将线串拆分为多个部分?

时间:2019-05-03 08:56:34

标签: sql postgresql loops geometry postgis

上下文:我正在使用PostgreSQL(10.6)数据库和PostGIS 2.5。

我需要帮助来创建一个函数,该函数将使用另一个表中的点来拆分表中每一行的线串,并将拆分后的部分插入到新表中。每条线都有其适当的点,并且这些点具有精确的顺序。

我知道如何使用ST_Line_Substringdocumentation here)分割线串,并且知道如何使用ST_LineLocatePointdocumentation here)来分割线串。


我有2个问题:我不想在点的位置分割线,而是根据它们在线上的位置作为分数在每个点之间分割。因此,如果某个点位于线的0%处,下一个点位于该线的20%,则第一部分将从原始线的0%变为10%。这是一个快速的说明(如果很幼稚的话,很抱歉):enter image description here

黑线代表原始线串,蓝色圆圈代表点,彩色“线”代表我想要哪种line_substring。

我想到的解决方案是将线上的前一个点和当前点的分数相加,然后除以2作为该部分的起点,对当前点和下一个点进行相同的处理,如下所述:

ST_Line_Substring(line.geom, (
    ((ST_LineLocatePoint(line.geom, previous_point.geom) + ST_LineLocatePoint(line.geom, current_point.geom)) / 2),
    ((ST_LineLocatePoint(line.geom, current_point.geom) + ST_LineLocatePoint(line.geom, next_point.geom)) / 2)
)

第二个问题,我不知道如何从包含点的表中访问上一个和下一个点。最初,我想使用某种循环机制,但是我从其他主题中看到了很多答案,说这不是最佳选择,最好避免使用它们,而且我发现没有什么看起来像SQL中的索引遍历结果集或表以轻松访问上一个或下一个元素。

所以我的主要问题是,如何遍历每行的点表以同时访问上一个,当前和下一个点?

1 个答案:

答案 0 :(得分:1)

我找到了一个解决方案,我使用了一个游标,然后使用了RELATIVE选项,它使我可以访问除我要遍历的行之外的其他索引,这就是我的函数:

CREATE OR REPLACE FUNCTION splitLine(
    id character varying,
    linestring geometry(POINT,4326)
    )
RETURNS VOID AS $$

DECLARE
prior_point RECORD;
current_point RECORD;
next_point RECORD;
cursor_point SCROLL CURSOR FOR  SELECT id, line_id, line_order, geom
                                  FROM points
                                  WHERE id LIKE line_id
                                  ORDER BY line_order;

BEGIN

    OPEN cursor_points;

    LOOP

        FETCH FROM cursor_point INTO prior_point;
        FETCH RELATIVE 1 FROM cursor_point INTO current_point;
        FETCH RELATIVE 2 FROM cursor_point INTO next_point;

        -- Operations on my points and line 

    END LOOP;

    CLOSE cursor_point;
END; $$

LANGUAGE plpgsql;