Changes between Initial Version and Version 1 of UsersWikiplpgsqlfunctions


Ignore:
Timestamp:
Apr 13, 2009, 1:57:51 PM (15 years ago)
Author:
pierre
Comment:

Legend:

Unmodified
Added
Removed
Modified
  • UsersWikiplpgsqlfunctions

    v1 v1  
     1==  This is an area to put utility functions or wrappers around PostGIS ==
     2
     3 * '''Find UTM (WGS84)  SRID for a point (in any SRID)'''
     4
     5 {{{
     6 -- Function: utmzone(geometry)
     7 -- DROP FUNCTION utmzone(geometry);
     8
     9 CREATE OR REPLACE FUNCTION utmzone(geometry)
     10   RETURNS integer AS
     11 $BODY$
     12 DECLARE
     13     geomgeog geometry;
     14     zone int;
     15     pref int;
     16
     17 BEGIN
     18     geomgeog:=transform($1,4326);
     19
     20     IF (y(geomgeog))>0 THEN
     21        pref:=32600;
     22     ELSE
     23        pref:=32700;
     24     END IF;
     25
     26     zone:=floor((x(geomgeog)+180)/6)+1;
     27
     28     RETURN zone+pref;
     29 END;
     30 $BODY$ LANGUAGE 'plpgsql' IMMUTABLE
     31   COST 100;
     32}}}
     33
     34 * '''Find Length of Day for a given location and date'''
     35{{{
     36 CREATE OR REPLACE FUNCTION daylength(geometry, date)
     37 RETURNS double precision AS 'select 24*(ACOS(1-(1-TAN(radians(Y(transform($1,4326))))*TAN(.409088 * COS(.0172024 * extract(doy from $2)))))/PI());'
     38 LANGUAGE 'sql';
     39}}}
     40
     41 * '''Rotate Geometry around a point(geom,x,y)'''
     42{{{
     43CREATE OR REPLACE FUNCTION RotateAtPoint(geometry, double precision, double precision, double precision)
     44 RETURNS geometry AS 'SELECT translate( rotate( translate( $1, -1*$2, -1*$3), $4), $2, $3)'
     45   LANGUAGE 'sql';
     46}}}
     47
     48 * '''Create Ellipse (x,y,rx,ry,rotation,#of segments in 1/4 of ellipse)'''
     49{{{
     50CREATE OR REPLACE FUNCTION Ellipse(double precision, double precision, double precision, double precision, double precision, integer)
     51 RETURNS geometry AS
     52 'SELECT translate( rotate( scale( buffer(makepoint(0,0), 0.5, $6), $3, $4), $5), $1, $2)'
     53 LANGUAGE 'sql';
     54}}}
     55
     56 * '''Return a multilinestring consisting of the interior and exterior rings of a polygon/multipolygon'''
     57
     58''This already exists in PostGIS: see ST_Boundary(geometry)''
     59
     60{{{
     61Example use: - where the_geom is a multipolygon
     62 SELECT fnpoly_to_rings(the_geom)
     63 FROM sometable
     64
     65 CREATE OR REPLACE FUNCTION fnpoly_to_rings(geometry)
     66 RETURNS geometry AS
     67 $$
     68 SELECT collect(the_line)  as multiline
     69 FROM (SELECT ST_ExteriorRing(the_poly) as the_line
     70        FROM (SELECT ST_GeometryN($1, g.n) As the_poly
     71         FROM
     72            generate_series(1, ST_NumGeometries($1)) As g(n) ) As polys
     73        UNION ALL
     74        SELECT ST_InteriorRingN(the_poly,
     75        generate_series(1, ST_NumInteriorRings(the_poly))) as the_line
     76   FROM (SELECT ST_GeometryN($1, g.n) As the_poly
     77                FROM generate_series(1, ST_NumGeometries($1)) As g(n) ) As polys
     78        ) As all_lines
     79 $$
     80  LANGUAGE 'sql' IMMUTABLE;
     81COMMENT ON FUNCTION fnpoly_to_rings(geometry) IS 'Takes as argument a multipolygon or polygon and returns a multilinestring consisting of the interior and exterior rings of the polygon/multipolygon';
     82
     83  CREATE OR REPLACE FUNCTION upgis_!lineshift(centerline geometry, dist double precision)
     84  RETURNS geometry AS
     85  $$
     86  DECLARE
     87        delx float;
     88        dely float;
     89        x0 float;
     90        y0 float;
     91        x1 float;
     92        y1 float;
     93        az float;
     94        dir integer;
     95        line geometry;
     96  BEGIN
     97        az := ST_Azimuth (ST_!StartPoint(centerline), ST_!EndPoint(centerline));
     98        dir := CASE WHEN az < pi() THEN -1 ELSE 1 END;
     99        delx := ABS(COS(az)) * dist * dir;
     100        dely := ABS(SIN(az)) * dist * dir;
     101
     102        IF az > pi()/2 AND az < pi() OR az > 3 * pi()/2 THEN
     103                line := ST_Translate(centerline, delx, dely) ;
     104        ELSE
     105                line := ST_Translate(centerline, -delx, dely);
     106        END IF;
     107
     108        RETURN line;
     109  END;
     110  $$
     111  LANGUAGE 'plpgsql' IMMUTABLE;
     112  COMMENT ON FUNCTION upgis_lineshift(geometry, double precision) IS 'Takes a 2D line string and shifts it dist units along
     113 the perpendicular defined by the straight line between the start and end point
     114 Convention: (right is positive and left is negative.  right being defined as to right of observer
     115 standing at start point and looking down the end point)';
     116}}}
     117