ฉันมีฟังก์ชั่นที่สร้างแผงเซลล์แสงอาทิตย์ Photovolatic ที่แสดงเป็นรูปหลายเหลี่ยม โดยพื้นฐานแล้วมันจะสร้างกริดสี่เหลี่ยมที่ผู้ใช้สามารถระบุพารามิเตอร์ต่อไปนี้:
- ความยาว
- ความกว้าง
- ระยะทางแนวนอน
- ระยะทางแนวตั้ง
รหัสนี้เป็นไปตามปลั๊กอินFeatureGridCreatorแต่เน้นเฉพาะในรูปหลายเหลี่ยม ใช้ได้ดีกับส่วนใหญ่โดยเฉพาะเมื่อสร้างรูปหลายเหลี่ยมที่มีขนาดใหญ่ (เช่นความยาวและความกว้าง 10 ม. ระยะทางแนวนอนและแนวตั้ง 10 ม.)
แต่ฉันสังเกตเห็นสองประเด็น:
เมื่อระบุรูปหลายเหลี่ยมสำหรับขนาดที่น้อยกว่า 2 เมตรสำหรับทั้งความยาวและความกว้างจะไม่สร้างรูปหลายเหลี่ยม
เมื่อระบุรูปหลายเหลี่ยมที่มีขนาดต่างกัน (เช่นความยาว 5 ม. และความกว้าง 7 ม.) ขนาดนั้นไม่เหมือนกันเมื่อวัดด้วยเครื่องมือวัดเส้น สำหรับมิติเหล่านี้ความยาวและความกว้างถูกแสดงเป็น 4m และ 6m ตามลำดับ
CRS ที่ใช้สำหรับการฉายภาพและเลเยอร์คือEPSG: 27700แม้ว่าฉันจะไม่คิดว่ามันจะเป็นปัญหา
ดังนั้นใครบ้างมีความคิดใด ๆ ที่อาจทำให้เกิดปัญหาเหล่านี้ ฉันยังเปิดให้คำแนะนำเกี่ยวกับวิธีการปรับปรุงรหัสหรือแทนที่ด้วยทางเลือกที่ดีกว่า
นี่คือรหัสที่สามารถทำซ้ำได้ในPython Consoleต้องเลือกเลเยอร์รูปหลายเหลี่ยมด้วย CRS ที่เกี่ยวข้องก่อนเรียกใช้ฟังก์ชัน:
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)