I have two polygon layers, one which defines subregions of the other. However, the layers do not line up exactly, so there are minor discrepancies along the edges. I would like to select all minor polygons which lie within the major polygon layer. What is the best way to do this in PostGIS?

Sample of map below. You can see the blue subregions on top of the larger yellow region, with seemingly exact "jigsaw" edging. I have tried using ST_Within to select polygons, with the result being the purple polygons. These are clearly a subset of what I am looking for.

enter image description here

Zooming in, you can see that the edges do not align properly.

enter image description here

What is the best way to select under these circumstances?


Since you know your smaller regions are contained inside the larger, you can cheat by converting the smaller regions to points and then testing:

FROM ecosystems AS eco, biomes
WHERE ST_Within(ST_PointOnSuface(eco.geom),biomes.geom) AND biomes.biomename = 'Grassland';
  • What a cunning idea! Computationally it's much better, but I imagine it might be prone to false positives? I have a polygon count for your method, but I'm still waiting for my buffer to finish! I'll test more tomorrow. – rudivonstaden Mar 25 '13 at 20:47
  • Your query finished in 10 min, while my buffer query is still running 11 hours later. I have visually checked the result, and could find no false positives or false negatives. I did find a few areas where the selected polygons extended beyond the biome edge, and these were selected correctly (buffering would not select these). So at least based on my data, this is the way that works! – rudivonstaden Mar 26 '13 at 7:56

I have found one way that seems to work (buffering by a small amount and then using ST_Within), but it takes more than 10 hours on my computer (compared to 70 seconds for a ST_Within or ST_Intersects query). I would be interested in hearing other (hopefully faster) approaches.

FROM ecosystems AS eco, biomes
WHERE ST_Within(eco.geom,ST_Buffer(biomes.geom,0.003)) AND biomes.biomename = 'Grassland';

I selected the 0.003 buffer radius through a sample of sliver measurements using the ruler tool in qgis but there may be a more rigorous approach? I suppose it would really depend on the data, and the balance between false positives (incorrectly selecting small polygons on the edge) and false negatives (not selecting polygons because they extend beyond the sliver buffer).

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.