I have a function which creates Wind Turbines represented as points. Essentially, it uses the code from the Random points inside polygons (fixed) tool albeit with some slight changes.
The goal is to create random points inside polygons taking into account the minimum distance specified. This works very well especially with polygons which are not close to another (e.g. a single polygon):
However, if the polygon is close to or adjoined to another polygon (e.g. as shown below), the points from each polygon can be within the minimum distance as shown in red:
How could I change the code so that those points in red are not close to another from a nearby polygon?
Ideally, I would like multiple points to be replaced by a single point:
Here is the code which can be reproduced in the Python Console, a polygon layer must be selected with a relevant CRS before running the function:
import random from PyQt4.QtCore import QVariant def checkMinDistance(point, index, distance, points): if distance == 0: return True neighbors = index.nearestNeighbor(point, 1) if len(neighbors) == 0: return True if neighbors in points: np = points[neighbors] if np.sqrDist(point) < (distance * distance): return False return True def generate_wind_turbines(spacing): layer = iface.activeLayer() crs = layer.crs() # Memory layer memory_lyr = QgsVectorLayer("Point?crs=epsg:" + unicode(crs.postgisSrid()) + "&index=yes", "Wind turbines for " + str(layer.name()), "memory") QgsMapLayerRegistry.instance().addMapLayer(memory_lyr) memory_lyr.startEditing() provider = memory_lyr.dataProvider() provider.addAttributes([QgsField("ID", QVariant.Int)]) # Variables point_density = 0.0001 fid = 1 distance_area = QgsDistanceArea() # List of features fts =  # Create points for f in layer.getFeatures(): fGeom = QgsGeometry(f.geometry()) bbox = fGeom.boundingBox() pointCount = int(round(point_density * distance_area.measure(fGeom))) index = QgsSpatialIndex() points = dict() nPoints = 0 fid += 1 nIterations = 0 maxIterations = pointCount * 200 random.seed() while nIterations < maxIterations and nPoints < pointCount: rx = bbox.xMinimum() + bbox.width() * random.random() ry = bbox.yMinimum() + bbox.height() * random.random() pnt = QgsPoint(rx, ry) geom = QgsGeometry.fromPoint(pnt) if geom.within(fGeom) and checkMinDistance(pnt, index, spacing, points): f = QgsFeature(nPoints) f.setAttributes([fid]) f.setGeometry(geom) fts.append(f) index.insertFeature(f) points[nPoints] = pnt nPoints += 1 nIterations += 1 provider.addFeatures(fts) memory_lyr.updateFields() memory_lyr.commitChanges() generate_wind_turbines(500)
Dissolving and/or converting the polygons to singleparts does not seem to help much as the generated points still seem to fall within the minimum distance.
Tested on QGIS 2.18.3.