1

A slightly theoretical PostGIS question. If you have a polygon, perform a positive buffer on it, then perform the same buffer operation but negative, you end up with a slightly different polygon than you started with. For example

SELECT sum(st_area(st_setsrid(ST_GeomFromText('POLYGON ((50 50, 50 150, 150 150, 150 50, 50 50))'),4326)))
--1000

SELECT sum(st_area(st_buffer(st_buffer(st_setsrid(ST_GeomFromText('POLYGON ((50 50, 50 150, 150 150, 150 50, 50 50))'),4326),0.01),-0.01)))
--9999.99

I've played around a little with mitre and capstyle settings to get the result closer. But is there some way to make the result exactly what it was before? I'm guessing not.

Here is my real-world code by the way:

SELECT  sum(st_area(geom))
FROM    emea_eu_neu.table_4
-- 6.1945218013261

SELECT  sum(st_area(st_buffer(st_buffer(geom,0.00001,
                              'endcap=flat join=mitre mitre_limit=2'),-0.00001,
                              'endcap=flat join=mitre mitre_limit=2')))
FROM    emea_eu_neu.table_4
-- 6.19452224786773
5
  • 1
    no, if the buffer of a line/vertex falls inside the buffer of another line/vertex, you won't be able to recover it with a negative buffer. (example: a large polygon, one edge being a straight line with a narrow spike pointing inside the polygon) – JGH Jun 10 at 14:45
  • 1
    Buffer converts lines and points into polygons but probably not back to points/lines. I wonder if ST_Scale postgis.net/docs/ST_Scale.html could be usable and reversible for some kind of geometries. – user30184 Jun 10 at 15:48
  • 2
    Except in rare/lucky cases, the buffer operation is not invertible. I'm curious why you would want to? – dr_jts Jun 10 at 17:19
  • @dr_jts I need to union groups of polygons & use the result of this as an input to st_difference. For example st_difference(big_polygon, group_of_unioned_polygons). However sometimes I end up with geometry errors when I try to do the union of the grouped polygons. Everyone suggests using st_buffer to fix this issue. But if I do, then I will be making an input which is (fractionally) larger than it should be for the subsequent st_difference operation. I've been doing this but it's not ideal as stated: st_buffer(st_unaryunion(st_buffer(st_collect(st_buffer(geom,0.000001)),0)),-0.000001) – TheRealJimShady Jun 10 at 21:29
  • @TheRealJimShady the latest version of PostGIS has much improved robustness for union (and the other overlay operations). Have you tried that? Using buffer to do union is not the recommended strategy now. – dr_jts Jun 11 at 17:12
3

As discussed in the comments a buffer operation can't always be reversed. However you can buffer by zero. This will fix invalid geoms. For example compare the following (geom is a figure-8):

SELECT st_isvalid(ST_GeomFromText('POLYGON ((50 50, 150 150, 50 150, 150 50, 50 50))'),4326);
-- False

`SELECT st_isvalid(st_buffer(ST_GeomFromText('POLYGON ((50 50, 150 150, 50 150, 150 50, 50 50))'),4326),0);
-- True

In terms of your use case, it might also be worth exploring ST_MakeValid.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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