Ich habe eine Funktion, die Windturbinen erzeugt, die als Punkte dargestellt werden. Im Wesentlichen wird der Code aus dem Werkzeug Zufällige Punkte in Polygonen (fest) verwendet, allerdings mit einigen geringfügigen Änderungen.
Ziel ist es, zufällige Punkte innerhalb von Polygonen unter Berücksichtigung des angegebenen Mindestabstands zu erstellen. Dies funktioniert sehr gut, insbesondere bei Polygonen, die nicht nahe beieinander liegen (z. B. ein einzelnes Polygon):
Wenn sich das Polygon jedoch in der Nähe eines anderen Polygons befindet oder an dieses angrenzt (z. B. wie unten gezeigt), können sich die Punkte von jedem Polygon innerhalb des Mindestabstands befinden, wie in rot dargestellt:
Wie kann ich den Code so ändern, dass diese Punkte in Rot nicht in der Nähe eines anderen aus einem nahe gelegenen Polygon liegen?
Idealerweise möchte ich, dass mehrere Punkte durch einen einzelnen Punkt ersetzt werden:
Hier ist der Code, der in der Python-Konsole reproduziert werden kann. Vor dem Ausführen der Funktion muss eine Polygonebene mit einem relevanten CRS ausgewählt werden:
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[0] in points:
np = points[neighbors[0]]
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)
Bearbeiten:
Das Auflösen und / oder Konvertieren der Polygone in einzelne Teile scheint nicht viel zu helfen, da die erzeugten Punkte immer noch innerhalb des Mindestabstands zu liegen scheinen.
Getestet mit QGIS 2.18.3 .