Changes between Initial Version and Version 1 of UserWikiBufferMeters


Ignore:
Timestamp:
Apr 14, 2020, 3:14:16 PM (4 years ago)
Author:
mdavis
Comment:

Legend:

Unmodified
Added
Removed
Modified
  • UserWikiBufferMeters

    v1 v1  
     1= Buffer geodetic geometry using meters =
     2
     3Constructs a buffer of a geodetic (lat/long) geometry using a distance in meters.
     4Uses a transformation to a suitable UTM zone, so only works for geometries with extent less than a few degrees of longitude.
     5
     6Note: not sure if this is better than simply casting to `geography`?
     7
     8Sources:
     9* https://blog.datapolitan.com/2013/11/22/st_buffer_meters/
     10* [https://gist.github.com/datapolitan/9ef9489eac5686ca3b34 st_buffer_meters.sql]
     11* [https://gist.github.com/datapolitan/ffdeb086b3c4531d9f4e utmzone.sql]
     12
     13{{{
     14/* Function: ST_Buffer_Meters(geometry, double precision)
     15DROP FUNCTION ST_Buffer_Meters(geometry, double precision);
     16Usage: SELECT ST_Buffer_Meters(the_geom, num_meters) FROM sometable; */
     17 
     18 
     19CREATE OR REPLACE FUNCTION ST_Buffer_Meters(geometry, double precision)
     20RETURNS geometry AS
     21$BODY$
     22DECLARE
     23orig_srid int;
     24utm_srid int;
     25 
     26BEGIN
     27orig_srid:= ST_SRID($1);
     28utm_srid:= utmzone(ST_Centroid($1));
     29 
     30RETURN ST_transform(ST_Buffer(ST_transform($1, utm_srid), $2), orig_srid);
     31END;
     32$BODY$ LANGUAGE 'plpgsql' IMMUTABLE
     33COST 100;
     34
     35/* Function: utmzone(geometry)
     36DROP FUNCTION utmzone(geometry);
     37Usage: SELECT ST_Transform(the_geom, utmzone(ST_Centroid(the_geom))) FROM sometable; */
     38 
     39CREATE OR REPLACE FUNCTION utmzone(geometry)
     40RETURNS integer AS
     41$BODY$
     42DECLARE
     43geomgeog geometry;
     44zone int;
     45pref int;
     46 
     47BEGIN
     48geomgeog:= ST_Transform($1,4326);
     49 
     50IF (ST_Y(geomgeog))>0 THEN
     51pref:=32600;
     52ELSE
     53pref:=32700;
     54END IF;
     55 
     56zone:=floor((ST_X(geomgeog)+180)/6)+1;
     57 
     58RETURN zone+pref;
     59END;
     60$BODY$ LANGUAGE 'plpgsql' IMMUTABLE
     61COST 100;
     62}}}
     63