[postgis-users] Extending Linestrings
Julio Galindo
juliogalindoq at gmail.com
Mon Apr 16 22:21:19 PDT 2007
Leticia,
I note that it can be improved a little bit, the first loop starts in 0
instead of 1:
CREATE OR REPLACE FUNCTION ExtendLine(eje_ geometry, bound_ geometry)
RETURNS geometry AS $$
-- version: alfa , by Julio A. Galindo, April 17, 2007:
juliogalindoq at gmail.com
DECLARE
b_ geometry = 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 GeometryType(eje_) NOT LIKE 'LINESTRING'
OR GeometryType(bound_) NOT LIKE 'POLYGON' THEN RETURN NULL; END IF;
-- First Search how far is the boundary: (worst case)
pto_1 := StartPoint(eje_);
pto_2 := EndPoint(eje_);
FOR i IN 1..NumPoints(b_)-1 LOOP
dist := distance(PointN(b_,i),pto_1);
IF dist > max_dist THEN max_dist := dist; END IF;
dist := distance(PointN(b_,i),pto_2);
IF dist > max_dist THEN max_dist := dist; END IF;
END LOOP;
-- Now extent the linestring:
pto_2 := PointN(eje_,2);
u_1 := X(pto_2)-X(pto_1);
u_2 := Y(pto_2)-Y(pto_1);
norm := sqrt(u_1^2 + u_2^2);
first_pto := MakePoint(X(pto_1)-u_1/norm*dist,Y(pto_1)-u_2/norm*dist);
n_points := nPoints(eje_);
IF n_points > 2 THEN
pto_1 := PointN(eje_,n_points-1);
pto_2 := PointN(eje_,n_points);
u_1 := X(pto_2)-X(pto_1);
u_2 := Y(pto_2)-Y(pto_1);
norm := sqrt(u_1^2 + u_2^2);
END IF;
last_pto := MakePoint(X(pto_2)+u_1/norm*dist,Y(pto_2)+u_2/norm*dist);
result := result || X(first_pto) || ' ' || Y(first_pto) || ',';
FOR i IN 1..NumPoints(eje_) LOOP
result := result || X(PointN(eje_,i)) || ' ' || Y(PointN(eje_,i)) || ',';
END LOOP;
result := result || X(last_pto) || ' ' || Y(last_pto) || ')';
-- Find the final Linestring:
b_ := intersection(GeomFromText(result,SRID(eje_)),bound_);
RETURN b_;
END $$
LANGUAGE plpgsql
STABLE
RETURNS NULL ON NULL INPUT;
On 4/17/07, Leticia <lgomez at itba.edu.ar> wrote:
>
> Julio, THANKS!
>
>
>
>
>
>
> ------------------------------
>
> *From:* postgis-users-bounces at postgis.refractions.net [mailto:
> postgis-users-bounces at postgis.refractions.net] *On Behalf Of *Julio
> Galindo
> *Sent:* Tuesday, April 17, 2007 1:53 AM
> *To:* PostGIS Users Discussion
> *Subject:* Re: [postgis-users] Extending Linestrings
>
>
>
> Hi Leticia,
>
>
>
> I create the following function for your problem, please test it
> carefully, I only made two test (at the end):
>
>
>
> CREATE OR REPLACE FUNCTION ExtendLine(eje_ geometry, bound_ geometry)
> RETURNS geometry AS $$
> -- version: alfa , by Julio A. Galindo, April 17, 2007: juliogalindoq at gmail.com
>
> DECLARE
> b_ geometry = 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 GeometryType(eje_) NOT LIKE 'LINESTRING'
> OR GeometryType(bound_) NOT LIKE 'POLYGON' THEN RETURN NULL; END IF;
> -- First Search how far is the boundary: (worst case)
> pto_1 := StartPoint(eje_);
> pto_2 := EndPoint(eje_);
> FOR i IN 0..NumPoints(b_)-1 LOOP
> dist := distance(PointN(b_,i),pto_1);
> IF dist > max_dist THEN max_dist := dist; END IF;
> dist := distance(PointN(b_,i),pto_2);
> IF dist > max_dist THEN max_dist := dist; END IF;
> END LOOP;
> -- Now extent the linestring:
> pto_2 := PointN(eje_,2);
> u_1 := X(pto_2)-X(pto_1);
> u_2 := Y(pto_2)-Y(pto_1);
> norm := sqrt(u_1^2 + u_2^2);
> first_pto :=
> MakePoint(X(pto_1)-u_1/norm*dist,Y(pto_1)-u_2/norm*dist);
> n_points := nPoints(eje_);
> IF n_points > 2 THEN
> pto_1 := PointN(eje_,n_points-1);
> pto_2 := PointN(eje_,n_points);
> u_1 := X(pto_2)-X(pto_1);
> u_2 := Y(pto_2)-Y(pto_1);
> norm := sqrt(u_1^2 + u_2^2);
> END IF;
> last_pto := MakePoint(X(pto_2)+u_1/norm*dist,Y(pto_2)+u_2/norm*dist);
>
> result := result || X(first_pto) || ' ' || Y(first_pto) || ',';
> FOR i IN 1..NumPoints(eje_) LOOP
> result := result || X(PointN(eje_,i)) || ' ' || Y(PointN(eje_,i)) ||
> ',';
> END LOOP;
> result := result || X(last_pto) || ' ' || Y(last_pto) || ')';
> -- Find the final Linestring:
> b_ := intersection(GeomFromText(result,SRID(eje_)),bound_);
> RETURN b_;
> END $$
> LANGUAGE plpgsql
> STABLE
> RETURNS NULL ON NULL INPUT;
>
>
>
>
> Test 1:
>
>
>
> select asText(extendLine(geomFromText('LINESTRING(5 5, 12
> 12)',-1),GeomFromText('POLYGON((0 0,15 0,15 20,0 20,0 0))',-1)));
>
>
>
> astext
> ---------------------------------
> LINESTRING(0 0,5 5,12 12,15 15)
>
>
> The solution is good, because the line is at 45 degress
>
>
>
> And the same function can work with a general linestring (many points):
>
>
>
> select asText(extendLine(geomFromText('LINESTRING(5 5, 12 12, 13
> 12)',-1),GeomFromText('POLYGON((0 0,15 0,15 20,0 20,0 0))',-1)));
> astext
> ---------------------------------------
> LINESTRING(0 0,5 5,12 12,13 12,15 12)
>
>
>
> Let me know if you improve this simple function.
>
>
>
> Regards,
>
>
>
> Julio A. Galindo Q.
>
> Topogen Ltda.
>
> La Paz, Bolivia
>
>
>
> On 4/16/07, *Leticia* <lgomez at itba.edu.ar> wrote:
>
>
>
> Hi community,
>
>
>
> 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.
>
>
>
> Is there a simple method to do this?
>
>
>
>
>
> -------------
>
> | |
>
> | | |
>
> | | |
>
> | |
>
> -------------
>
>
>
>
>
> I need the other one:
>
>
>
>
>
> -------|-----
>
> | | |
>
> | | |
>
> | | |
>
> | | |
>
> -------|-----
>
>
>
> The original linestring is not always vertical u horizontal.
>
>
>
>
>
> Thanks in advance,
>
> Leticia
>
>
>
>
>
>
>
>
> _______________________________________________
> postgis-users mailing list
> postgis-users at postgis.refractions.net
> http://postgis.refractions.net/mailman/listinfo/postgis-users
>
>
>
> _______________________________________________
> postgis-users mailing list
> postgis-users at postgis.refractions.net
> http://postgis.refractions.net/mailman/listinfo/postgis-users
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/postgis-users/attachments/20070417/1c919621/attachment.html>
More information about the postgis-users
mailing list