Ich habe eine Funktion, die Photovolatische Solarmodule erstellt, die als Polygone dargestellt werden. Im Wesentlichen wird ein rechteckiges Raster erstellt, in dem der Benutzer die folgenden Parameter angeben kann:
- Länge
- Breite
- Horizontaler Abstand
- Vertikale Entfernung
Der Code basiert auf dem Plugin FeatureGridCreator , konzentriert sich jedoch nur auf den Polygonaspekt. Es funktioniert größtenteils gut, insbesondere beim Erstellen von Polygonen mit großen Abmessungen (z. B. 10 m Länge und Breite; 10 m horizontale und vertikale Abstände).
Aber ich habe ein paar Probleme bemerkt:
Bei der Angabe von Polygonen für Abmessungen von weniger als 2 m für Länge und Breite wurden keine Polygone erstellt.
Bei der Angabe von Polygonen mit unterschiedlichen Abmessungen (z. B. 5 m Länge und 7 m Breite) waren die Abmessungen bei der Messung mit dem Werkzeug " Linie messen" nicht dieselben . Für diese Abmessungen wurden Länge und Breite von 4 m bzw. 6 m gezeigt.
Das CRS, das sowohl für die Projektion als auch für die Ebene verwendet wird, ist EPSG: 27700, obwohl ich nicht gedacht hätte, dass dies ein Problem sein würde.
Hat jemand eine Idee, was diese Probleme verursachen könnte? Ich bin auch offen für Vorschläge, wie der Code verbessert oder sogar durch eine bessere Alternative ersetzt werden könnte.
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:
from PyQt4.QtCore import QVariant
from math import ceil
def generate_pv_panels(length, width, distance_x, distance_y):
# Define layer properties
layer = iface.activeLayer()
crs = layer.crs()
memory_lyr = QgsVectorLayer("Polygon?crs=epsg:" + unicode(crs.postgisSrid()) + "&index=yes", "PV panels for " + str(layer.name()), "memory")
QgsMapLayerRegistry.instance().addMapLayer(memory_lyr)
memory_lyr.startEditing()
provider = memory_lyr.dataProvider()
provider.addAttributes([QgsField("ID", QVariant.Int)])
fid = 0
start_x = 0
start_y = 0
# Ensure polygons are not created 'within each other'
if distance_x < (length / 1000):
distance_x = (length / 1000)
if distance_y < (width / 1000):
distance_y = (width / 1000)
fts = []
for f in layer.getFeatures():
fid += 1
bbox = f.geometry().boundingBox()
start_x = bbox.xMinimum() + float(distance_x / 2)
start_y = bbox.yMinimum() + float(distance_y / 2)
for row in range(0, int(ceil(bbox.height() / distance_y))):
for column in range(0, int(ceil(bbox.width() / distance_x))):
fet = QgsFeature()
geom_type = pv_panel_size(length, width, start_x, start_y)
if f.geometry().contains(geom_type):
fet.setGeometry(geom_type)
fet.setAttributes([fid])
fts.append(fet)
start_x += distance_x + (length / 1000)
start_x = bbox.xMinimum() + float(distance_x / 2)
start_y += distance_y + (width / 1000)
provider.addFeatures(fts)
memory_lyr.updateFields()
memory_lyr.commitChanges()
def pv_panel_size(length, width, x, y):
# Length & width measured in mm; x & y measured in m
l = length / 2000
w = width / 2000
return QgsGeometry.fromRect(QgsRectangle(x - l, y - w, x + l, y + w))
generate_pv_panels(10000, 10000, 100, 100)
Dank @radouxju ist hier der endgültige Code, der auch berücksichtigt, dass die horizontalen und vertikalen Abstände Null sind:
Verwenden von
generate_pv_panels(5500, 5000, 20, 1)
:Verwenden von
generate_pv_panels(5500, 5000, 20, 0)
:quelle