Saya memiliki fungsi yang membuat panel Solar Photovolatic direpresentasikan sebagai poligon. Pada dasarnya, ini menciptakan kotak persegi panjang di mana pengguna dapat menentukan parameter berikut:
- Panjangnya
- Lebar
- Jarak horizontal
- Jarak vertikal
Kode ini didasarkan pada plugin FeatureGridCreator tetapi berfokus hanya pada aspek poligon. Ini berfungsi dengan baik untuk sebagian besar, terutama ketika membuat poligon dengan dimensi besar (misalnya panjang dan lebar 10m; jarak horizontal dan vertikal 10m).
Tapi saya perhatikan beberapa masalah:
Saat menentukan poligon untuk dimensi kurang dari 2m untuk panjang dan lebar, tidak ada poligon yang dibuat.
Saat menentukan poligon dengan dimensi berbeda (mis. Panjang 5 m dan lebar 7 m), dimensi tidak sama ketika diukur dengan alat Garis Ukur . Untuk dimensi ini, panjang dan lebar masing-masing ditampilkan 4m dan 6m.
CRS yang digunakan untuk proyeksi dan layer adalah EPSG: 27700 meskipun saya tidak akan berpikir ini akan menjadi masalah.
Jadi, adakah yang tahu apa yang menyebabkan masalah ini? Saya juga terbuka untuk saran bagaimana kode dapat ditingkatkan atau bahkan diganti dengan alternatif yang lebih baik.
Berikut adalah kode yang dapat direproduksi dalam Konsol Python , lapisan poligon harus dipilih dengan CRS yang relevan sebelum menjalankan fungsi:
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)
Berkat @radouxju , berikut adalah kode terakhir yang juga memperhitungkan jarak horizontal dan vertikal menjadi nol:
Menggunakan
generate_pv_panels(5500, 5000, 20, 1)
:Menggunakan
generate_pv_panels(5500, 5000, 20, 0)
:sumber