Context : I'm working with a PostgreSQL (10.6) database and PostGIS 2.5.
I need help creating a function that'll split the linestring of each row from a table using points from another table, and insert the split portions into a new table. Each line has it's proper points and the points have a precise order.
I know how to split a linestring using ST_Line_Substring
( documentation here ), and I know how to do it using a point using ST_LineLocatePoint
( documentation here ).
I have 2 problems : I don't want to split the line at a point's location, but rather in between each point according to their position on the line as fraction. So if there is a point at 0% and the next one is at 20% of the line, the first portion would go from 0% to 10% of the original line. Here's a quick illustration (sorry if it looks childish) :
The black line represent the original linestring, the blue circles are the points, and the colored "lines" represent what kind of line_substring I want.
The solution I came up with this problem is just just adding the fraction of the previous point and current point on the line and dividing by 2 for the start of the portion, and same thing with the current point and the next one, for the end of the portion, as written below :
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)
)
My 2nd problem, I have no idea how to access the previous and next point from the table containing the points. At first I wanted to use some kind of loop mechanism but I've seen a lot of answers from other topics saying this isn't something optimal and it's better to avoid them, and I've found nothing looking like an index in SQL to iterate over a result set or a table to easily access previous or next element.
So my main question is, how do I iterate over my points table, for each line, to access previous, current, and next point at the same time ?
I found a solution, I'm using a cursor and then the RELATIVE option, which allows me to access other indexes than the row I'm iterating over, here's what my function looks like :
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;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.