/* Function to create a line based on dynamic segmentation. INPUT: linestring to segmentate, startpoint in percent of line (0..1) endpoint in percent of line (0..1) OUTPUT: dynseg linestring Dr. Horst Düster, Solothurn 5.5.2004 */ CREATE OR REPLACE FUNCTION dynseg (GEOMETRY, DOUBLE PRECISION,DOUBLE PRECISION) RETURNS GEOMETRY AS ' DECLARE theLine ALIAS FOR $1; fmeas ALIAS FOR $2; tmeas ALIAS FOR $3; npoints INTEGER; fuzzy double precision := 0.1; start_pnt GEOMETRY; end_pnt GEOMETRY; lineSeg GEOMETRY; tempLineString GEOMETRY; result_geom GEOMETRY; test GEOMETRY; test_start BOOLEAN := ''f''; test_end BOOLEAN := ''f''; first BOOLEAN := ''t''; last BOOLEAN := ''f''; BEGIN -- Identify the number of vertex points SELECT numpoints(theLine) INTO npoints; -- Identify the coordinates of start- and endpoint start_pnt := line_interpolate_point(theLine,fmeas); end_pnt := line_interpolate_point(theLine,tmeas); -- generate the first linesegment tempLineString := geomfromtext(''LINESTRING(''|| x(pointn(theLine,1))||'' ''||y(pointn(theLine,1))||'',''||x(pointn(theLine,2))||'' ''||y(pointn(theLine,2))||'')'',srid(theLine)); -- test if start- or/and endpoint touching the linesegment SELECT distance(start_pnt,tempLineString) < fuzzy INTO test_start; SELECT distance(end_test,tempLineString) < fuzzy INTO test_end; -- do for all other linesegments FOR i IN 2..npoints LOOP -- if startpoint is touching the linesegment begin aggregate all following linesegments to the -- dynseg line until linesegment touching endpoint is reached IF test_start AND first THEN result_geom := geomfromtext(''LINESTRING(''|| x(start_pnt)||'' ''||y(start_pnt)||'',''||x(pointn(tempLineString,2))||'' ''||y(pointn(tempLineString,2))||'')'',srid(tempLineString)); first := ''f''; tempLineString := geomfromtext(''LINESTRING(''|| x(pointn(theLine,i))||'' ''||y(pointn(theLine,i))||'',''||x(pointn(theLine,i+1))||'' ''||y(pointn(theLine,i+1))||'')'',srid(theLine)); SELECT intersects(end_test,tempLineString) INTO test_end; ELSIF not test_end AND test_start THEN result_geom := geomunion(result_geom,tempLineString); tempLineString := geomfromtext(''LINESTRING(''|| x(pointn(theLine,i))||'' ''||y(pointn(theLine,i))||'',''||x(pointn(theLine,i+1))||'' ''||y(pointn(theLine,i+1))||'')'',srid(theLine)); SELECT intersects(end_test,tempLineString) INTO test_end; ELSIF not last AND test_end AND test_start THEN result_geom := geomunion(result_geom,tempLineString); tempLineString := geomfromtext(''LINESTRING(''|| x(pointn(theLine,i))||'' ''||y(pointn(theLine,i))||'',''||x(end_pnt)||'' ''||y(end_pnt)||'')'',srid(theLine)); result_geom := geomunion(result_geom,tempLineString); last := ''t''; ELSE tempLineString := geomfromtext(''LINESTRING(''|| x(pointn(theLine,i))||'' ''||y(pointn(theLine,i))||'',''||x(pointn(theLine,i+1))||'' ''||y(pointn(theLine,i+1))||'')'',srid(theLine)); SELECT intersects(start_test,tempLineString) INTO test_start; END IF; END LOOP; RETURN result_geom; END; ' LANGUAGE plpgsql;