[postgis-users] Degrees of a linestring segment
Flavio Perri
FPERRI at it.ibm.com
Wed May 2 06:52:33 PDT 2007
Thanks a lot for this hint, I will try it soon.
Just another question about line_interpolate_point(). Is it useful to
retrieve the distance between a line and a point? Or should I also use that
new function?
I used this query:
select distance_sphere(point,line_interpolate_point(line,
line_locate_point(line, point))) from linetable, pointtable
Bye
Flavio
postgis-users-bounces at postgis.refractions.net wrote on 27/04/2007 17.25.13:
> Flavio
> This will not work because line_interpolate_point and line_locate_point
do
> not give the vertex locations, only points and locations along the line.
> Say you have a linestring with three segments (and four points). If you
use
> line_locate_point(the_line,my_point) where my_line is your line and
my_point
> is your point that is close to the middle of the line, the result will be
> 0.5 or half way along the line. It will not tell you which vertex it is
> closest to. It you then use line_interpolate_point(my_line,0.5) you will
> get a new point halfway along your line or in the middle of the middle
> segment.
> The good news is it can be done with a new function called
> line_locate_vertex(linestring,point) that will give you the closest
vertex
> to the point. I wrote this to split polygons into four sides for section
> lines recently. The function is:
>
--------------------------------------------------------------------------
>
> -- Function: line_locate_vertex(geometry, geometry)
>
> -- DROP FUNCTION line_locate_vertex(geometry, geometry);
>
> CREATE OR REPLACE FUNCTION line_locate_vertex(geometry, geometry)
> RETURNS integer AS
> $BODY$
> DECLARE
> dist double precision;
> n_dist double precision;
> i integer;
> p integer;
> BEGIN
> dist = 9999999999999;
>
> IF (GeometryType($1) != 'LINESTRING') THEN
> raise notice 'First Geometry type must be a LINESTRING';
> RETURN -1;
> END IF;
> IF (GeometryType($2) != 'POINT') THEN
> raise notice 'Second Geometry type must be a POINT';
> RETURN -1;
> END IF;
>
> FOR i IN 1 .. numPoints($1)
> LOOP
> n_dist = distance($2,pointN($1,i));
> IF (n_dist < dist) THEN
> p = i;
> dist = n_dist;
> END IF;
> END LOOP;
>
> RETURN p;
>
> END;
> $BODY$
> LANGUAGE 'plpgsql' VOLATILE;
> ALTER FUNCTION line_locate_vertex(geometry, geometry) OWNER TO postgres;
>
> -------------------------------------------------------------------------
>
> Using this function, the result of line_locate_vertex(my_line,my_point)
will
> give the index of the vertex closest to your point. You then have to
figure
> out if you need the next vertex or the previous vertex for your line
> segment. This can be done using line_locate_point. First get the
location
> your closest vertex along the line:
>
> index = line_locate_vertex(my_line,my_point)
>
> Then find the location of that vertex along the line:
>
> indx_loc = line_locate_point(pointN(my_line,index))
>
> Then find the location of your point along the line:
>
> pnt_loc = line_locate_point(my_line,my_point)
>
> If pn_loc is less than indx_loc your line segment goes from
> pointN(my_line,index-1) to pointN(my_line,index).
>
> If pn_loc is greater than indx_loc your line segment goes from
> pointN(my_line,index) to pointN(my_line,index+1).
>
> Hope this helps!
>
> Bruce Rindahl
>
>
More information about the postgis-users
mailing list