I'd like to form a 500 meter buffer around a coordinate. That coordinate is in WGS 84.

I've been playing with this for a little and seem to have a solution, but is seems way too complicated:

SELECT ST_AsText(ST_Transform(ST_Buffer((ST_Transform(ST_GeomFromText('POINT(-71.104 42.315)', 4326), 3857)), 500), 4326))

In this solution I first transform the point to a metric coordinates system (EPSG:3857) so the buffer distance is metric. Then I generate the buffer and then I transform the buffer back into WGS, as I need the result in WGS.

Isn't there a simpler solution?

  • 5
    Do not use Web Mercator for buffer or any other distance-related operations. It is known to be very inaccurate, especially at high latitudes (which is why Greenland is shown larger than South America when it is actually a seventh of the area). While the operation would be correct with an equal-area projection, you can also cast to geography and let ST_Buffer calculate a geodetic circle -- SELECT ST_AsText(ST_Buffer(ST_GeomFromText('POINT(-71.104 42.315)', 4326)::geography, 500)) – Vince Sep 30 '18 at 13:10
  • I was just using Web Mercator for testing, but you are right, this should not be used for such calculations! I was looking into casting but could not quite figure out how to use it. You should post the code as an answer so I can accept it. Thank you for the rapid help! – BritishSteel Sep 30 '18 at 13:23
  • 2
    I'm pretty sure this question has been asked before, but locating the duplicate isn't on this morning's agenda. – Vince Sep 30 '18 at 14:32
  • Do you really want to create a buffer? Or do you want to do a distance-based search? See gis.stackexchange.com/questions/77688/… for example. – Martin F Sep 30 '18 at 18:32

Your result might not be what you expected.

There is a difference between these two queries:

SELECT ST_Transform(ST_Buffer((ST_Transform(ST_GeomFromText('POINT(-71.104 42.315)', 4326), 3857)), 500), 4326)


SELECT ST_Buffer(ST_GeomFromText('POINT(-71.104 42.315)', 4326)::geography, 500)

Check the output, using QGIS.

Comparing st_transform and st_buffer

The result of the first query, displayed in red, that you mentioned in your question, has a minor area and the radius is about 740 meters.

The second query, displayed in green has a radius of 1000 meters. The second query uses the geography ST_Buffer(geography g1, float radius_of_buffer_in_meters) function (with a geography as the first argument).

If you want to compute the area, also use the float ST_Area(geography geog, boolean use_spheroid=true) function (with a geography as the first argument).

I've also computed the areas of both results to make sure the the second way of calculating the buffer is the correct one.

So, in summary, use the provided ST_Buffer function with a geography as the argument:

SELECT ST_Buffer(ST_GeomFromText('POINT(-71.104 42.315)', 4326)::geography, 500)

  • Beautiful explanation, thank you @jgrocha ! – Timothy Dalton Jul 20 '19 at 7:49

Not the answer you're looking for? Browse other questions tagged or ask your own question.