= Buffer geodetic geometry using meters = Constructs a buffer of a geodetic (lat/long) geometry using a distance in meters. Uses a transformation to a suitable UTM zone, so only works for geometries with extent less than a few degrees of longitude. Note: not sure if this is better than simply casting to `geography`? Sources: * https://blog.datapolitan.com/2013/11/22/st_buffer_meters/ * [https://gist.github.com/datapolitan/9ef9489eac5686ca3b34 st_buffer_meters.sql] * [https://gist.github.com/datapolitan/ffdeb086b3c4531d9f4e utmzone.sql] {{{ /* Function: ST_Buffer_Meters(geometry, double precision) DROP FUNCTION ST_Buffer_Meters(geometry, double precision); Usage: SELECT ST_Buffer_Meters(the_geom, num_meters) FROM sometable; */ CREATE OR REPLACE FUNCTION ST_Buffer_Meters(geometry, double precision) RETURNS geometry AS $BODY$ DECLARE orig_srid int; utm_srid int; BEGIN orig_srid:= ST_SRID($1); utm_srid:= utmzone(ST_Centroid($1)); RETURN ST_transform(ST_Buffer(ST_transform($1, utm_srid), $2), orig_srid); END; $BODY$ LANGUAGE 'plpgsql' IMMUTABLE COST 100; /* Function: utmzone(geometry) DROP FUNCTION utmzone(geometry); Usage: SELECT ST_Transform(the_geom, utmzone(ST_Centroid(the_geom))) FROM sometable; */ CREATE OR REPLACE FUNCTION utmzone(geometry) RETURNS integer AS $BODY$ DECLARE geomgeog geometry; zone int; pref int; BEGIN geomgeog:= ST_Transform($1,4326); IF (ST_Y(geomgeog))>0 THEN pref:=32600; ELSE pref:=32700; END IF; zone:=floor((ST_X(geomgeog)+180)/6)+1; RETURN zone+pref; END; $BODY$ LANGUAGE 'plpgsql' IMMUTABLE COST 100; }}}