I m using QGIS 1.8 Lisboa. After calculating the centroids from a polygon shapefile, if some of them lie outside the polygon outlines, I'd like to move them on the polygon they came from. The criterion should be univocal as I must use them to extract coordinates to be used as the identification code of the polygon itself. Therefore, the procedure should output the same point location each time it runs for the same polygon (not a random position like the one given by "random points" function, that gives a new result each times it's ran).
You could use the Shapely python library, which provides a function
representative_point() that is guaranteed to lie within the polygon.
Here's a Python script that can be run in the QGIS Python console. The polygon layer for which you want to create the attribute should be selected. The function takes the name of the attribute you want to update. The attribute has to exist in your layer already, it has to be string type, and it should be long enough (30 characters).
Here's an example of the points the algorithm found:
import shapely.wkb def setIDPoint(attributename): layer = qgis.utils.iface.activeLayer() provider = layer.dataProvider() fields = provider.fields() provider.select(provider.attributeIndexes() ) attributeID = provider.fieldNameIndex(attributename) feature = QgsFeature() layer.startEditing() while provider.nextFeature(feature): wkb = feature.geometry().asWkb() polygon = shapely.wkb.loads(wkb) reprPoint = ','.join([str(polygon.representative_point().x), str(polygon.representative_point().y)] ) feature.changeAttribute(attributeID, reprPoint) layer.updateFeature(feature) layer.commitChanges()
The ftools centroid tool can place the centroid outside the polygon if it is concave.
ST_PointOnSurface will definitely do what you want. You can use the command from inside QGIS if you have installed by using SPIT to get your shapefile into PostGIS and then use the PgQuery plugin to run the query.
Alternatively, if installing PostGIS is a bit much for a one-off use, you could use Spatialite from within QGIS. You can then use the QSpatiaLite plugin to import your data to SpatiaLite and run the query (SpatialLite honours
realcentroids plugin, available to install through Plugins > Manage and Install Plugins worked for me in QGIS 2.2 to generate centroid-like points, forced inside each polygon if concave (the point will lie very close to the edge). I tried the Random points tool as suggested by Kurt, and although I specified 1 point per polygon, it generates two instead. An added disadvantage is that in most cases, the points don't represent the centroid as they are random.