Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

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

share|improve this question
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. –  lynxlynxlynx Feb 5 '13 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 '13 at 14:43
use the fTools 'true centroid' tool under geometry tools - docs.qgis.org/html/en/docs/user_manual/plugins/… –  Mapperz Feb 5 '13 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 '13 at 15:59
is this a duplicate of gis.stackexchange.com/questions/50029/… now? –  underdark Feb 5 '13 at 16:35
show 2 more comments

3 Answers

up vote 5 down vote accepted

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)
share|improve this answer
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 '13 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 '13 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 '13 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 '13 at 17:15
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 '13 at 8:57
show 5 more comments

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

share|improve this answer
add comment

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

share|improve this answer
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 '13 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 '13 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 '13 at 16:06
add comment

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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