[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