[postgis-users] Finding closet intersect point along direction of line
adrian.kitchingman at dse.vic.gov.au
adrian.kitchingman at dse.vic.gov.au
Wed Apr 10 23:51:14 PDT 2013
Thanks for the code Simon. After a few tweaks I got it working perfectly
in PostGIS2.
Here's the updated code.
Adrian
CREATE OR REPLACE FUNCTION ST_Extend(eje_ geometry, bound_ geometry)
RETURNS geometry
AS $$
-- Use Case: I need to "extend" a linestring in another one. The new
linestring must be
-- obtained such as their new extremes are the intersection of it with a
-- polygon that contains it. The original linestring is composed of only a
-- linear segment.
-- version: alfa , by Julio A. Galindo, April 17, 2007: juliogalindoq at
gmail.com
DECLARE
b_ geometry = st_boundary(bound_);
dist float;
max_dist float = 0;
n_points int;
pto_1 geometry;
pto_2 geometry;
first_pto geometry;
last_pto geometry;
u_1 float;
u_2 float;
norm float;
result text = 'LINESTRING(';
BEGIN
IF st_GeometryType(eje_) NOT LIKE 'ST_LineString' OR
st_GeometryType(bound_) NOT LIKE 'ST_Polygon' THEN
RETURN NULL;
END IF;
-- First Search how far is the boundary: (worst case)
pto_1 := st_StartPoint(eje_);
pto_2 := st_EndPoint(eje_);
FOR i IN 1..st_NumPoints(b_)-1 LOOP
dist := st_distance(st_PointN(b_,i),pto_1);
IF dist > max_dist THEN max_dist := dist; --END IF;
max_dist := dist;
END IF;
dist := st_distance(st_PointN(b_,i),pto_2);
IF dist > max_dist THEN max_dist := dist; --END IF;
max_dist := dist;
END IF;
END LOOP;
-- Now extent the linestring:
pto_2 := st_PointN(eje_,2);
u_1 := st_X(pto_2)-st_X(pto_1);
u_2 := st_Y(pto_2)-st_Y(pto_1);
norm := sqrt(u_1^2 + u_2^2);
first_pto :=
st_MakePoint(st_X(pto_1)-u_1/norm*dist,st_Y(pto_1)-u_2/norm*dist);
n_points := st_nPoints(eje_);
IF n_points > 2 THEN
pto_1 := st_PointN(eje_,n_points-1);
pto_2 := st_PointN(eje_,n_points);
u_1 := st_X(pto_2)-st_X(pto_1);
u_2 := st_Y(pto_2)-st_Y(pto_1);
norm := sqrt(u_1^2 + u_2^2);
END IF;
last_pto :=
st_MakePoint(st_X(pto_2)+u_1/norm*dist,st_Y(pto_2)+u_2/norm*dist);
result := result || st_X(first_pto) || ' ' || st_Y(first_pto) ||
',';
FOR i IN 1..st_NumPoints(eje_) LOOP
result := result || st_X(st_PointN(eje_,i)) || ' ' ||
st_Y(st_PointN(eje_,i)) || ',';
END LOOP;
result := result || st_X(last_pto) || ' ' || st_Y(last_pto) || ')';
-- Find the final Linestring:
b_ := st_intersection(st_GeomFromText(result,st_SRID(eje_)),bound_);
RETURN b_;
END $$
LANGUAGE plpgsql
STABLE
RETURNS NULL ON NULL INPUT;
Notice:
This email and any attachments may contain information that is personal, confidential,
legally privileged and/or copyright. No part of it should be reproduced, adapted or communicated without the prior written consent of the copyright owner.
It is the responsibility of the recipient to check for and remove viruses.
If you have received this email in error, please notify the sender by return email, delete it from your system and destroy any copies. You are not authorised to use, communicate or rely on the information contained in this email.
Please consider the environment before printing this email.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/postgis-users/attachments/20130411/7b9313c8/attachment.html>
More information about the postgis-users
mailing list