4

When I go to Vector > Research Tools > Random Points in Polygons in QGIS, I can specify a specific number of points I can add randomly into each feature (each polygon for me). So if I have 15 polygons, and I choose 1 point, I will find 1 point placed in each polygon in a random location.

However, I want to pre-specify a global number of points which are randomly added across all polygons. So for example, let's say I have 20 polygons and I specify 30 points to be randomly added across all of them (with an equal probability of appearing in each polygon). In this case, on average each polygon will end up with 1.5 points, but some may, by random chance, have 3, some may have 0 etc. Also, let's say I have 20 polygons and I specify 15 points. In this case, I will find out that by random chance at least 5 of my polygons end up with no points, and probably more than 5 because again, by random chance, probably a few polygons will end up with two or more points.

Is there a way to do this with QGIS?

2
  • 3
    Dissolve your polygons into a temporary single polygon/multipolygon, then create random points in that poly?
    – user2856
    Jul 30, 2022 at 3:51
  • @user2856 I considered that. Unfortunately this would bias the appearance of random points into polygons with greater area, whereas I want each of my polygons to have an equal chance of having a point appear in them.
    – arara
    Jul 30, 2022 at 4:24

2 Answers 2

4

You can use pyqgis.

This will list all features, select from the list n times and create a sample list, randomly place a point within each sample:

import random
layer = QgsProject.instance().mapLayersByName('ok_an_riks')[0]
sample_size = 50

features = [f for f in layer.getFeatures()] #List all features

#Sample
sampled = [] #A list to add randomly selected features to


for _ in range(0, sample_size): #For the number of sample size
    rand = random.randint(0, len(features)-1) #Pick one random integer between 0 and the number of features in the layer
    sampled.append(features[rand]) #Append this feature to the sampled list

#ids = sorted([f.id() for f in sampled])
#[2, 2, 3, 4, 4, 5, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9, 9, 10, 10, 11, 12, 12, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 15, 16, 17, 18, 18, 18, 21, 21, 22, 23, 23, 23, 23, 25, 25, 25]
#So polygon 2 will get 2 points, 3 one point, ... 

def randpoint(feature):
    """Creates one randomly located point within an input polygon"""
    success = 0
    polygeom = feature.geometry() #Find the input features polygon geometry
    box = polygeom.boundingBox() #Find its bounding box
      
    while success != 1: #Do the following until ...
        xrand = random.uniform(box.xMinimum(), box.xMaximum()) #A random x coord within the bounding box
        yrand = random.uniform(box.yMinimum(), box.yMaximum()) #And y
        randompoint = QgsGeometry.fromPointXY(QgsPointXY(xrand, yrand)) #Create a point geometry
        if randompoint.within(polygeom): #Check if it is within the polygon (not only within the bounding box)
            success = 1 #... If within, stop iterating and move on to the next sampled feature
        
    return randompoint
    
#random_points = []

#Create the point layer
pointlayer = QgsVectorLayer("Point?crs={}&index=yes".format(layer.crs().authid()), "myLayer", "memory")
provider = pointlayer.dataProvider()
for sample in sampled:
    f = QgsFeature()
    f.setGeometry(randpoint(sample))
    provider.addFeature(f)

QgsProject.instance().addMapLayer(pointlayer)

print('Done')

enter image description here

0
1

For a total target of N points, you can create N random points within each polygon, then, from all these points, select N final points.

enter image description here

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.