ポイントで表される風力タービンを作成する機能があります。基本的には、多少の変更はありますが、ポリゴン(固定)ツール内のランダムポイントからのコードを使用します。
目標は、指定された最小距離を考慮して、ポリゴン内にランダムなポイントを作成することです。これは特に、別のポリゴンに近接していないポリゴン(単一のポリゴンなど)で非常にうまく機能します。
ただし、ポリゴンが別のポリゴンに近接または隣接している場合(たとえば、以下に示すように)、各ポリゴンのポイントは、赤で示すように最小距離内にある可能性があります。
赤のポイントが近くのポリゴンの別のポイントに近づかないようにコードを変更するにはどうすればよいですか?
理想的には、複数のポイントを1つのポイントに置き換えたいです。
Pythonコンソールで再現できるコードを次に示します。関数を実行する前に、関連するCRSでポリゴンレイヤーを選択する必要があります。
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)
編集:
生成されたポイントが最小距離内にあるように見えるので、ポリゴンをディゾルブまたはシングルパートに変換することはあまり役に立たないようです。
QGIS 2.18.3でテスト済み。