Tôi có một chức năng tạo ra các tấm quang điện mặt trời được biểu diễn dưới dạng đa giác. Về cơ bản, nó tạo ra một lưới hình chữ nhật nơi người dùng có thể chỉ định các tham số sau:
- Chiều dài
- Chiều rộng
- Khoảng cách ngang
- Khoảng cách dọc
Mã này dựa trên plugin FeatureGridCreator nhưng chỉ tập trung vào khía cạnh đa giác. Nó hoạt động tốt đối với hầu hết các phần, đặc biệt là khi tạo đa giác với kích thước lớn (ví dụ: chiều dài và chiều rộng 10m; khoảng cách ngang và dọc 10m).
Nhưng tôi nhận thấy một vài vấn đề:
Khi chỉ định đa giác cho kích thước nhỏ hơn 2m cho cả chiều dài và chiều rộng, không có đa giác nào được tạo.
Khi chỉ định đa giác với các kích thước khác nhau (ví dụ: chiều dài 5m và chiều rộng 7m), kích thước không giống nhau khi được đo bằng công cụ Đường đo . Đối với các kích thước này, chiều dài và chiều rộng được hiển thị lần lượt là 4m và 6m.
CRS được sử dụng cho cả hình chiếu và lớp là EPSG: 27700 mặc dù tôi không nghĩ đây sẽ là một vấn đề.
Vì vậy, có ai có bất kỳ ý tưởng những gì có thể gây ra những vấn đề này? Tôi cũng sẵn sàng để đề xuất về cách mã có thể được cải thiện hoặc thậm chí thay thế bằng một sự thay thế tốt hơn.
Đây là mã có thể được sao chép trong Bảng điều khiển Python , một lớp đa giác phải được chọn với CRS có liên quan trước khi chạy chức năng:
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)