ST_Buffer for those who want really round geographic circles

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 thoughts on “ST_Buffer for those who want really round geographic circles

  1. 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

    1. 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.

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 )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.