上下文:我正在使用PostgreSQL(10.6)数据库和PostGIS 2.5。
我需要帮助来创建一个函数,该函数将使用另一个表中的点来拆分表中每一行的线串,并将拆分后的部分插入到新表中。每条线都有其适当的点,并且这些点具有精确的顺序。
我知道如何使用ST_Line_Substring
(documentation here)分割线串,并且知道如何使用ST_LineLocatePoint
(documentation here)来分割线串。
我有2个问题:我不想在点的位置分割线,而是根据它们在线上的位置作为分数在每个点之间分割。因此,如果某个点位于线的0%处,下一个点位于该线的20%,则第一部分将从原始线的0%变为10%。这是一个快速的说明(如果很幼稚的话,很抱歉):
黑线代表原始线串,蓝色圆圈代表点,彩色“线”代表我想要哪种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中的索引遍历结果集或表以轻松访问上一个或下一个元素。
所以我的主要问题是,如何遍历每行的点表以同时访问上一个,当前和下一个点?
答案 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;