J'ai une fonction qui crée des panneaux solaires photovoltaïques représentés comme des polygones. Essentiellement, il crée une grille rectangulaire où l'utilisateur peut spécifier les paramètres suivants:
- Longueur
- Largeur
- Distance horizontale
- Distance verticale
Le code est basé sur le plugin FeatureGridCreator mais en se concentrant uniquement sur l'aspect polygone. Cela fonctionne bien pour la plupart, en particulier lors de la création de polygones de grandes dimensions (par exemple 10 m de longueur et de largeur; 10 m de distances horizontales et verticales).
Mais j'ai remarqué quelques problèmes:
Lors de la spécification de polygones pour des dimensions inférieures à 2 m pour la longueur et la largeur, aucun polygone n'a été créé.
Lors de la spécification de polygones avec des dimensions différentes (par exemple 5 m de longueur et 7 m de largeur), les dimensions n'étaient pas les mêmes lorsqu'elles étaient mesurées avec l' outil Mesurer la ligne . Pour ces dimensions, la longueur et la largeur étaient respectivement de 4 m et 6 m.
Le CRS utilisé à la fois pour la projection et la couche est EPSG: 27700 bien que je n'aurais pas pensé que ce serait un problème.
Alors, quelqu'un a-t-il une idée de ce qui pourrait causer ces problèmes? Je suis également ouvert aux suggestions sur la façon dont le code pourrait être amélioré ou même remplacé par une meilleure alternative.
Voici le code qui peut être reproduit dans la console Python , une couche polygonale doit être sélectionnée avec un CRS approprié avant d'exécuter la fonction:
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)
Grâce à @radouxju , voici le code final qui prend également en compte les distances horizontales et verticales nulles:
En utilisant
generate_pv_panels(5500, 5000, 20, 1)
:En utilisant
generate_pv_panels(5500, 5000, 20, 0)
:la source