| 145 | |
| 146 | Note that the result set will include resultants for areas which are in holes but which do not overlap any parent polygon. |
| 147 | If not desired these can be filtered out by keeping only records for which at least one id is non-NULL. |
| 148 | |
| 149 | == Worked Example == |
| 150 | |
| 151 | This is the SQL from the above function, with example data: |
| 152 | |
| 153 | {{{ |
| 154 | WITH poly_a(id, geom) AS (VALUES |
| 155 | ( 'a1', 'POLYGON ((10 40, 30 40, 30 10, 10 10, 10 40))'::geometry ), |
| 156 | ( 'a2', 'POLYGON ((70 10, 30 10, 30 90, 70 90, 70 10), (40 40, 60 40, 60 20, 40 20, 40 40), (40 80, 60 80, 60 60, 40 60, 40 80))'::geometry ), |
| 157 | ( 'a3', 'POLYGON ((40 40, 60 40, 60 20, 40 20, 40 40))'::geometry ) |
| 158 | ) |
| 159 | ,poly_b(id, geom) AS (VALUES |
| 160 | ( 'b1', 'POLYGON ((90 70, 90 50, 50 50, 50 70, 90 70))'::geometry ), |
| 161 | ( 'b2', 'POLYGON ((90 30, 50 30, 50 50, 90 50, 90 30))'::geometry ), |
| 162 | ( 'b2', 'POLYGON ((90 10, 70 10, 70 30, 90 30, 90 10))'::geometry ) |
| 163 | ) |
| 164 | ,lines AS ( |
| 165 | SELECT ST_Boundary(geom) AS geom FROM poly_a |
| 166 | UNION ALL |
| 167 | SELECT ST_Boundary(geom) AS geom FROM poly_b |
| 168 | ) |
| 169 | ,noded_lines AS ( SELECT St_Union(geom) AS geom FROM lines ) |
| 170 | ,resultants AS ( |
| 171 | SELECT geom, ST_PointOnSurface(geom) AS pip |
| 172 | FROM St_Dump( |
| 173 | ( SELECT ST_Polygonize(geom) AS geom FROM noded_lines )) |
| 174 | ) |
| 175 | SELECT a.id AS ida, b.id AS idb, r.geom |
| 176 | FROM resultants r |
| 177 | LEFT JOIN poly_a a ON St_Within(r.pip, a.geom) |
| 178 | LEFT JOIN poly_b b ON St_Within(r.pip, b.geom) |
| 179 | WHERE a.id IS NOT NULL OR b.id IS NOT NULL; |
| 180 | }}} |