Tengo una función que crea Solar Photovolatic paneles representado como los polígonos. En esencia, se crea una cuadrícula rectangular donde el usuario puede especificar el siguientes parámetros:
- Longitud
- Ancho
- Distancia Horizontal
- Distancia Vertical
El código está basado en el plugin FeatureGridCreator pero centrándose únicamente en el polígono de aspecto. Funciona bien para la mayoría, especialmente a la hora de crear polígonos con grandes dimensiones (por ejemplo, 10 m de longitud y anchura; 10m distancias horizontal y vertical).
Pero me di cuenta un par de cuestiones:
Cuando la especificación de los polígonos para las dimensiones de menos de 2m de longitud y anchura, no de los polígonos que fueron creados.
Cuando la especificación de los polígonos con diferentes dimensiones (por ejemplo, de 5m de longitud y 7 metros de ancho), las dimensiones no eran los mismos cuando se mide con la Medida de la Línea de la herramienta. Para estas dimensiones, la longitud y la anchura se muestra para ser 4m y 6m respectivamente.
El CRS utiliza tanto para la proyección y la capa es EPSG:27700 aunque yo no hubiera pensado que esto sería un problema.
Así que ¿alguien tiene alguna idea de lo que podría ser la causa de estos problemas? También estoy abierto a sugerencias en cuanto a cómo el código podría ser mejorado o incluso sustituido con una mejor alternativa.
Aquí está el código que se puede reproducir en la Consola de Python, una capa de polígono debe ser seleccionado con un relevante CRS antes de ejecutar la función:
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)