[PostGIS] #5776: ST_LineSubstring 3D support
PostGIS
trac at osgeo.org
Fri Sep 6 00:08:35 PDT 2024
#5776: ST_LineSubstring 3D support
----------------------+---------------------------
Reporter: vla123 | Owner: pramsey
Type: defect | Status: new
Priority: medium | Milestone: PostGIS 3.4.4
Component: postgis | Version: 3.4.x
Resolution: | Keywords:
----------------------+---------------------------
Comment (by vla123):
For those who want to split 3D LINESTRING, here is a plpgsql function :
{{{
CREATE or REPLACE FUNCTION ST_3DLineSubstring(
line_geom geometry, start_fraction float, end_fraction float
)
RETURNS setof geometry AS $$
DECLARE
srid INTEGER = st_srid(line_geom);
n_pts INTEGER;
vertex geometry;
next_vertex geometry;
vertices geometry [];
i INTEGER;
distance float = 0.0;
d float;
fraction float;
start_length float = st_3dlength(line_geom) * start_fraction;
end_length float = st_3dlength(line_geom) * end_fraction;
start_vertex geometry;
end_vertex geometry;
new_x float;
new_y float;
new_z float;
start_added bool = false;
BEGIN
if line_geom is null then return next
NULL;
else
n_pts := ST_NPoints(line_geom) -1;
for i in 1..n_pts LOOP
vertex := ST_PointN(line_geom, i);
next_vertex := ST_PointN(line_geom, i + 1);
d := abs(ST_3DDistance(vertex, next_vertex));
-- vertex between start and end
if distance < end_length and distance > start_length then
vertices := array_append(vertices, vertex);
end if;
-- first vertex
if distance + d > start_length and start_added is false then
fraction := (start_length - distance)/d;
new_x := st_x(vertex) + (st_x(next_vertex) - st_x(vertex)) *
fraction;
new_y := st_y(vertex) + (st_y(next_vertex) - st_y(vertex)) *
fraction;
new_z := st_z(vertex) + (st_z(next_vertex) - st_z(vertex)) *
fraction;
start_vertex := st_setsrid(st_makepoint(new_x, new_y, new_z),
srid);
start_added := true;
end if;
-- last vertex
if distance + d >= end_length then
fraction := (end_length - distance)/d;
new_x := st_x(vertex) + (st_x(next_vertex) - st_x(vertex)) *
fraction;
new_y := st_y(vertex) + (st_y(next_vertex) - st_y(vertex)) *
fraction;
new_z := st_z(vertex) + (st_z(next_vertex) - st_z(vertex)) *
fraction;
end_vertex := st_setsrid(st_makepoint(new_x, new_y, new_z), srid);
EXIT;
end if;
distance := distance + d;
END LOOP;
vertices := array_append(vertices, end_vertex);
vertices := array_prepend(start_vertex, vertices);
return QUERY
select(st_makeline(vertices));
end if;
END;
$$ LANGUAGE plpgsql;
}}}
--
Ticket URL: <https://trac.osgeo.org/postgis/ticket/5776#comment:2>
PostGIS <http://trac.osgeo.org/postgis/>
The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project.
More information about the postgis-tickets
mailing list