Ho una funzione che crea pannelli fotovoltaici fotovoltaici rappresentati come poligoni. In sostanza, crea una griglia rettangolare in cui l'utente può specificare i seguenti parametri:
- Lunghezza
- Larghezza
- Distanza orizzontale
- Distanza verticale
Il codice si basa sul plugin FeatureGridCreator ma si concentra solo sull'aspetto poligonale. Funziona bene per la maggior parte, specialmente quando si creano poligoni di grandi dimensioni (ad es. 10 m di lunghezza e larghezza; 10 m di distanza orizzontale e verticale).
Ma ho notato un paio di problemi:
Quando si specificavano poligoni per dimensioni inferiori a 2 m per lunghezza e larghezza, non venivano creati poligoni.
Quando si specificavano poligoni con dimensioni diverse (ad es. Lunghezza 5m e larghezza 7m), le dimensioni non erano le stesse se misurate con lo strumento Misura linea . Per queste dimensioni, la lunghezza e la larghezza sono state mostrate rispettivamente a 4m e 6m.
Il CRS utilizzato sia per la proiezione che per il livello è EPSG: 27700 anche se non avrei pensato che questo sarebbe stato un problema.
Qualcuno ha idea di cosa potrebbe causare questi problemi? Sono anche aperto a suggerimenti su come il codice potrebbe essere migliorato o addirittura sostituito con un'alternativa migliore.
Ecco il codice che può essere riprodotto in Python Console , un layer poligonale deve essere selezionato con un CRS rilevante prima di eseguire la funzione:
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)