提问人:janicans 提问时间:10/31/2023 更新时间:10/31/2023 访问量:24
PYGIS:创建新的属性表并向其添加值
PYGIS: Creating new attribute table and adding values to it
问:
我正在为QGIS使用pygis,并且对属性表及其值有疑问。我可以很好地创建新的属性表,但无法向其添加任何值。 我是侏儒的新手,不确定我做错了什么。另一个论坛中的有人建议将 dataProvider() 方法与图层编辑一起使用可能会导致该错误,但我仍然不确定如何修复它。
有问题的部分:
output_lyr.startEditing()
output_lyr.addAttribute(QgsField('EW_new', QVariant.Double))
output_lyr.updateFields()
output_lyr.commitChanges()
# ...
# Annahme: Der Vektorlayer "FPG_count" wurde bereits erstellt, und das Feld "EW_new" ist vorhanden.
# Iteriere durch die GEB_ID-Listen und berechne EW_new-Werte
for geb_id, feature_ids in geb_id_lists.items():
num_elements = len(feature_ids)
# Überprüfen, ob die GEB_ID im Dictionary "geb_id_to_ew" existiert
if geb_id in geb_id_to_ew:
ew_value = geb_id_to_ew[geb_id]
# Überprüfen, ob "EW" nicht 0 ist, bevor die Berechnung ausgeführt wird
if num_elements != 0:
result = ew_value / num_elements
# Den berechneten Wert in das Feld "EW_new" schreiben
for feature_id in feature_ids:
output_lyr.dataProvider().changeAttributeValues({feature_id: {output_lyr.fields().indexFromName('EW_new'): result}})
output_lyr.updateExtents()
else:
# Wenn num_elements gleich 0 ist, wird ein Platzhalterwert eingefügt
for feature_id in feature_ids:
output_lyr.dataProvider().changeAttributeValues({feature_id: {output_lyr.fields().indexFromName('EW_new'): 0}})
完整代码
# Lädt alle notwendigen Bibliotheken (libaries) in das Skript
from qgis.core import QgsProject, QgsVectorLayer, QgsVectorFileWriter, QgsField
from PyQt5.QtCore import QVariant
#Greift auf das aktuelle GIS Projekt zu
project = QgsProject.instance()
#Definiert Namen in Python für die jeweiligen Layer im Projekt.
fpg = project.mapLayersByName('FPG_cut')[0]
wgf = project.mapLayersByName('WGF_cut')[0]
output_lyr = QgsVectorLayer(f'Point?crs={fpg.crs().authid()}', 'FPG_count', 'memory')
output_lyr.dataProvider().addAttributes(fpg.fields())
output_lyr.updateFields()
# Feld das gesammelt werden soll
field_name = 'GEB_ID'
# Python dictionary um die IDs zu sammeln
geb_id_lists = {}
# Iteriert durch die features des Punkte Layers
for feature in fpg.getFeatures():
geb_id = feature[field_name]
if geb_id not in geb_id_lists:
geb_id_lists[geb_id] = []
geb_id_lists[geb_id].append(feature.id())
# Zähle und drucke die Anzahl der Listen
print(f"Number of unique 'GEB_ID' lists: {len(geb_id_lists)}")
# Sortieren und Filtern jeder Liste nach den Feldern "LDEN", "VAR" und "FPG".
for geb_id, feature_ids in geb_id_lists.items():
# Sortieren nach dem Feld "LDEN" in absteigender Reihenfolge - buggy
sorted_feature_ids = sorted(feature_ids, key=lambda id: fpg.getFeature(id)['LDEN'], reverse=False)
# Filter nach "VAR"-Feld (nur "+" behalten) und "FPG"-Feld (nur "Wohngeb" behalten)
filtered_feature_ids = [id for id in sorted_feature_ids if fpg.getFeature(id)['VAR'] == '+' and fpg.getFeature(id)['FPG'] == 'Wohngeb']
geb_id_lists[geb_id] = filtered_feature_ids
# Feststellen, ob die Anzahl der Werte gerade oder ungerade ist
for geb_id, feature_ids in geb_id_lists.items():
count = len(feature_ids)
if count % 2 == 1: # Wenn die Anzahl ungerade ist, wird der kleinste Wert entfernt. Hier der erste Wert weil die Liste mit den kleinsten Werten beginnt.
feature_ids.remove(geb_id_lists[geb_id][0])
# Entfernen Sie die untere Hälfte der Werte aus jeder Liste.
for geb_id, feature_ids in geb_id_lists.items():
count = len(feature_ids)
if count > 1: # Mindestens ein Wert bleibt in der Liste
half_index = count // 2
geb_id_lists[geb_id] = feature_ids[half_index:]
# Verteilung der Bewohner auf die verbleibende größere Hälfte des Hauses
# Annahme: Der Vektorlayer "FPG_count" wurde bereits erstellt, und das Feld "EW_new" ist vorhanden.
output_lyr.startEditing()
output_lyr.addAttribute(QgsField('EW_new', QVariant.Double))
output_lyr.updateFields()
output_lyr.commitChanges()
# ...
# Iteriere durch die GEB_ID-Listen und berechne EW_new-Werte
for geb_id, feature_ids in geb_id_lists.items():
num_elements = len(feature_ids)
# Überprüfen, ob die GEB_ID im Dictionary "geb_id_to_ew" existiert
if geb_id in geb_id_to_ew:
ew_value = geb_id_to_ew[geb_id]
# Überprüfen, ob "EW" nicht 0 ist, bevor die Berechnung ausgeführt wird
if num_elements != 0:
result = ew_value / num_elements
# Den berechneten Wert in das Feld "EW_new" schreiben
for feature_id in feature_ids:
output_lyr.dataProvider().changeAttributeValues({feature_id: {output_lyr.fields().indexFromName('EW_new'): result}})
output_lyr.updateExtents()
else:
# Wenn num_elements gleich 0 ist, wird ein Platzhalterwert eingefügt
for feature_id in feature_ids:
output_lyr.dataProvider().changeAttributeValues({feature_id: {output_lyr.fields().indexFromName('EW_new'): 0}})
sum_result = sum(result_values)
# ...
# Grenzwert
threshold_lden = 55
# Punkte mit "LDEN"-Werten unterhalb des Schwellenwerts herausfiltern
for geb_id, feature_ids in geb_id_lists.items():
feature_ids = [id for id in feature_ids if fpg.getFeature(id)['LDEN'] >= threshold_lden]
geb_id_lists[geb_id] = feature_ids
# Fügen Sie die Merkmale zur Ergebnisebene hinzu.
for geb_id, feature_ids in geb_id_lists.items():
for feature_id in feature_ids:
output_lyr.dataProvider().addFeatures([fpg.getFeature(feature_id)])
# Berechnen Sie die Gesamtzahl der Punkte in der Ausgabeschicht.
num_points_output_layer = output_lyr.featureCount()
# Druckt die Gesamtzahl der Punkte
print(f"Total number of points in the output layer: {num_points_output_layer}")
project.addMapLayer(output_lyr)
# Aktualisiert die Karte
iface.mapCanvas().refreshAllLayers()
我尝试删除“output_lyr.commitChanges()”行并添加类似 output_lyr.updateFeature(feature) 的行,但它似乎没有更新或将值添加到我的新属性字段。
答: 暂无答案
评论