I am trying to perform what I thought ought to be a simple operation in PostGIS. I would like to use a set of circle polygons to split a set of square polygons and extract the resulting non-overlapping polygons. I have drawn a simplistic version of this below. I would like to extract non-overlapping polygons representing areas A, B, C, D, E, F, and G. Note that the datasets involved are large with tens of thousands of circles.
I have tried using ST_Intersection but that gives me overlapping polygons. I have tried reducing those overlapping polygons to lines and re-creating non-overlapping polygons (using ST_Boundary, ST_Union and ST_Polygonize) this works initially but then gives me Topology exceptions ('ERROR: GEOSUnaryUnion: TopologyException: found non-noded intersection between LINESTRING xx and LINESTRING xx'. I'm guessing due to issues with excess coordinate places) when I start running it for very large numbers of circles. I have tried getting rid of the topology errors using ST_MakeValid, ST_Node, ST_Buffer(geom,0), ST_SnapToGrid etc. as suggested elsewhere on here, all with no success.
So can anyone provide an alterative approach to solving this, seemingly simple problem? I get the feeling I'm missing something obvious here and getting too lost in trying to unpick the topology exception when I think there ought to be a simplier solution to the intersect.
st_difference
? To use it, you would union all the geom for the circles, then set the geom on the polygons tost_difference(poly.geom, allcircles.geom)
select st_difference(poly.geom, allcircles.geom), poly.id from your_poly_table poly, (select st_union(geom) from your_circles_table) allcircles;
st_split
may actually be useful. Something like thisselect st_split(poly.geom, circlelines.geom), poly.id from your_poly_table poly, (select st_union(st_exteriorring(geom)) from your_circle_table) circlelines;
st_collectionextract(st_split(poly.geom, allcircles.geom), 3)
or(st_dump(st_split(poly.geom, allcircles.geom))).geom