[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