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).

  • 1
    Sounds like two questions. If I understand correctly, you want to (a) add random points inside a polygon and (b) give them or the polygon a unique ID based on this. The simplest thing that comes to mind for (a) is to use the existing random point capabilities in QGIS and then just intersect that point cloud with your polygon. Feb 5, 2013 at 13:26
  • using "random points" function different times with the same polygons leads to different results (namely, the position of the points derived from each polygon is different at each new use of the function), and I want to create a method which would give me always the same point per polygon from where I could extract coordinates that I want to use as identification code for the polygons themselves.
    – umbe1987
    Feb 5, 2013 at 14:43
  • use the fTools 'true centroid' tool under geometry tools - docs.qgis.org/html/en/docs/user_manual/plugins/…
    – Mapperz
    Feb 5, 2013 at 15:48
  • it just gives me the centroid, but this could also lie outside the poligon, which I must avoid. I need to move them on the polygon they derive from, using a function like minimum distance (but I'm not interested in the distance, I want it to be moved). In another blog someone told me to use ST_PointOnSurface of PostGIS (but I'm using QGIS).
    – umbe1987
    Feb 5, 2013 at 15:59
  • 2
    is this a duplicate of gis.stackexchange.com/questions/50029/… now?
    – underdark
    Feb 5, 2013 at 16:35

5 Answers 5


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()
 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)
  • I'm trying to test it, seems exactly what I was looking for. I'll let You know as soon as I run it!
    – umbe1987
    Feb 5, 2013 at 16:38
  • one thing I didn't get about it is what do you mean with "it has to be string type, and it should be long enough (30 characters)". Is this library working directly on polygon shpfiles? If so, am I supposed to create a new string type field in the Att Tab with 30 charachters at least, and this would be the one to be updated?
    – umbe1987
    Feb 5, 2013 at 16:52
  • @user9518: Yes, the way the function is written at the moment you have to create the attribute in the table yourself, and then only pass the name of the field to the function. The script could also quite easily be adapted to create the required field itself, if that's what's needed.
    – Jake
    Feb 5, 2013 at 16:56
  • I just miss one thing. It seems now I'm defining a function (or a class) by typing "def", but then when I end in writing the script it doesn't happen anything. How can I finally have the result in my table?
    – umbe1987
    Feb 5, 2013 at 17:15
  • 1
    It worked perfectly!!! I imagine the coordinates are written according to the coordinate system of the layer and that if I want to have the points I need to create a shp with those coordinates, right? If You were here I would offer You 3 beers at least! Thank You so much for Your efforts!!!
    – umbe1987
    Feb 6, 2013 at 8:57

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 ST_PointOnSurface).

  • There is now a native point on surface algorithm available in QGIS. Jan 19 at 17:58

when I understand you right, use: Vector->Research Tools_>Random Points. Now select under "Stratified Sampling Design (Individual polygons)" use value from input field and use approriate field, which gives numerical value of points, which should be genereated for each different polygon

  • what do You mean with "appropriate field"? I was thinking to use the centroid and then link it to the nearest part of the polygon it refers to, if it lays outside the outline, by (for instance) calculating the minimum distance of that point to its nearest polygon. The purpose is then to extract that point coordinates in order to use them as the polygon's unique specific identificaion code.
    – umbe1987
    Feb 5, 2013 at 14:39
  • Basically what I'm trying to do is to assign each centroid to its relative polygon and move it to lie inside its polygon (or at least to touch its borderline).
    – umbe1987
    Feb 5, 2013 at 15:16
  • @user9518: sorry, I did misunderstand your question. I thought you want a specific number of random points within each poly, e.g. 2 points fpr poly 1, 10 points within poly2 etc. therefore the term "appropriate field". of course you could select 1 for "use this number of points" to generate only one point for every poly. this point is inside the poly or at least touches its borderline. but this point still is found per random, so when you redo the procedure you get other points :-(
    – Kurt
    Feb 5, 2013 at 16:06

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.



As of QGIS 3.28, there is a native Point on Surface algorithm available. Just look for "Point on Surface" in the processing toolbox. The parameters look a lot like Centroid. Select your input, your overlay and whether you want separate points for each polygon.


I believe this uses the same algorithm as ST_PointOnSurface mentioned by MappaGnosis above, so you should get similar results.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.