[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