I am trying to generate label points from my polygons. The Polygon->Centroid works great except that if the centroid happens to land in a hole it is still returned. I need to get a single point (Centroid if that point is within the polygon) a point within the polygon if the centroid happens to be outside of the polygon.
2 Answers
I found a better solution, using OGR. The following will create a point that always falls on the surface of the polygon:
ogr2ogr PointonSurface.shp InputPolygons.shp -dialect sqlite -sql “SELECT ST_PointOnSurface(geometry) from InputPolygons”
You can see some examples here.
-
I'd seen your blogpost about this, and in general it gives a really nice result. One shape I've found it's less than optimal on, though (especially for points used for labels) is L-shapes, because often the points end up very close to the boundary, instead of more in the middle of the L's corner area.– neuhausrNov 18, 2013 at 15:56
-
Thanks neuhausr; I'm not sure how to avoid that--I suppose the st_pointonsurface command isn't exactly optimized for what you are trying to do, but I'm not sure what else would be! Nov 18, 2013 at 19:27
-
definitely a hack, but for a majority of polygon features it gives a better result than ESRI's Feature to Point tool– neuhausrNov 19, 2013 at 17:44
I have a (somewhat convoluted) solution.
- Create centroids using the default centroids tool
- Select polygons that do not contain a centroid (the irregular shaped ones) and create a new layer
- Use the Vector > Research Tools > Random Points tool on your new layer
- Merge the two point layers
I wish this was an option in the Centroids tool (with a checkbox to 'force inside' or create a 'true' centroid) but hopefully this solution works for you for now.
Another method (if you have GRASS installed, which you can run via QGIS) is to import your polygons into GRASS. You will see that after you do so, a layer called topo_point is created, which you can save out to a shapefile.