Smathermather's Weblog

Remote Sensing, GIS, Ecology, and Oddball Techniques

ST_Buffer for those who want really round geographic circles

Posted by smathermather on January 8, 2016

A little functionality request from @antoniolocandro on twitter:

Ask and ye might receive. Let’s build a function that will take your input geography, how far you want to buffer (in local coordinates) number of segments you want in a quarter, and what local coordinate system you want to use for your buffer as an EPSG code.

CREATE OR REPLACE FUNCTION zz_buffer(g1 geography, radius_of_buffer float,
num_seg_quarter_circle integer, local_coord integer)
RETURNS geometry AS
$BODY$

WITH transformed AS (
SELECT ST_Transform(g1::geometry, local_coord) AS geom
),
buffered AS (
SELECT ST_Buffer(geom, radius_of_buffer, num_seg_quarter_circle) AS geom
FROM transformed
),
transformed_4326 AS (
SELECT ST_Transform(geom, 4326) AS geom FROM buffered
)
SELECT * FROM transformed_4326

$BODY$
LANGUAGE sql VOLATILE
COST 100;

Now let’s use this:

SELECT 0 AS id, zz_buffer(ST_GeomFromText ('POINT(-81 41)', 4326) , 15000, 2, 3734)
Image of 8 segment buffer from geography

Image of 8 segment buffer from geography.

Now, we can test which level of smoothness we like best:

SELECT 0 AS id, zz_buffer(ST_GeomFromText ('POINT(-81 41)', 4326) , 15000, generate_series, 3734)
FROM generate_series(1,50)
Square, Octagon, etc. generated from new buffer function.

Square, Octagon, etc. generated from new buffer function.

Zoom in of different buffer smoothnesses.

Zoom in of different buffer smoothnesses.

6 Responses to “ST_Buffer for those who want really round geographic circles”

  1. Daniel said

    Due to the fact that ::geography is internaly finding the best fitting projection its would be way easier to use just
    ST_Buffer(geom::geography, radius_of_buffer, num_seg_quarter_circle)::geometry

    • That doesn’t work because there is no ST_Buffer(geography, radius_of_buffer, num_seg_quarter_circle).


      ERROR: function st_buffer(geography, double precision, integer) does not exist
      LINE 4: SELECT ST_Buffer(geog, 5000.0::float, 1)::geometry FROM poin…
      ^
      HINT: No function matches the given name and argument types. You might need to add explicit type casts.

      You are correct however that this would be better to implement at a lower level so that geography supports num_seg_quarter_circle _because_ such a function could decide the best coordinate system for the user.

  2. […] ST_Buffer for those who want really round geographic circles […]

  3. Don’t forget _ST_BestSRID. This function tells you the best SRID for a geometry, allowing you to re-implement ST_Buffer(geography, N) with geometries

  4. […] to Paul Norman’s reminder in a previous post, we now have all the pieces we need to complete an ST_Buffer function that exposes all the […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: