Skip to content

Commit 1f71f63

Browse files
committed
Add possibility to upload vector layer for imperviousness (sub-basins preprocessing)
1 parent 397e0e2 commit 1f71f63

File tree

3 files changed

+157
-11
lines changed

3 files changed

+157
-11
lines changed

QTalsim/qtalsim.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1808,6 +1808,10 @@ def createSoilLayer(self):
18081808
self.start_operation()
18091809
#self.dlg.progressbar.setValue(0)
18101810
#Dissolve the layer using the talsim soil parameters
1811+
if not self.soilLayerIntermediate:
1812+
self.log_to_qtalsim_tab("Soil layer was deleted or not yet created. Please create the soil layer.", Qgis.Critical)
1813+
self.end_operation()
1814+
return
18111815
try:
18121816
resultDissolve = processing.run("native:dissolve", {'INPUT':self.soilLayerIntermediate,'FIELD': self.soilFieldNames,'SEPARATE_DISJOINT':True,'OUTPUT':'TEMPORARY_OUTPUT'}, feedback=None)
18131817
self.soilTalsim = resultDissolve['OUTPUT']
@@ -2386,6 +2390,10 @@ def createLanduseLayer(self):
23862390
'''
23872391
try:
23882392
self.start_operation()
2393+
if not self.landuseTalsim:
2394+
self.log_to_qtalsim_tab("Land use layer was deleted or not yet created. Please create the land use layer.", Qgis.Critical)
2395+
self.end_operation()
2396+
return
23892397
#Dissolve the layer using the talsim landuse parameters
23902398
try:
23912399
resultDissolve = processing.run("native:dissolve", {'INPUT':self.landuseTalsim,'FIELD': self.selected_landuse_parameters,'SEPARATE_DISJOINT':True,'OUTPUT':'TEMPORARY_OUTPUT'})

QTalsim/qtalsim_subbasin.ui

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<x>0</x>
88
<y>0</y>
99
<width>789</width>
10-
<height>458</height>
10+
<height>489</height>
1111
</rect>
1212
</property>
1313
<property name="windowTitle">
@@ -182,7 +182,7 @@
182182
</size>
183183
</property>
184184
<property name="text">
185-
<string>Select DEM Layer</string>
185+
<string>Select DEM Raster Layer</string>
186186
</property>
187187
</widget>
188188
</item>
@@ -226,16 +226,50 @@
226226
</layout>
227227
</item>
228228
<item>
229-
<layout class="QHBoxLayout" name="horizontalLayout_7">
229+
<layout class="QVBoxLayout" name="verticalLayout_6">
230230
<item>
231-
<widget class="QLabel" name="labelImpervious">
232-
<property name="text">
233-
<string>Optional: Select Imperviousness Layer [%]</string>
234-
</property>
235-
</widget>
231+
<layout class="QHBoxLayout" name="horizontalLayout_7">
232+
<item>
233+
<widget class="QLabel" name="labelImpervious">
234+
<property name="text">
235+
<string>Optional: Select Imperviousness Layer [%]</string>
236+
</property>
237+
</widget>
238+
</item>
239+
<item>
240+
<widget class="QComboBox" name="comboboxImperviousness"/>
241+
</item>
242+
</layout>
236243
</item>
237244
<item>
238-
<widget class="QComboBox" name="comboboxImperviousness"/>
245+
<layout class="QHBoxLayout" name="horizontalLayout_11">
246+
<item>
247+
<spacer name="horizontalSpacer_4">
248+
<property name="orientation">
249+
<enum>Qt::Horizontal</enum>
250+
</property>
251+
<property name="sizeType">
252+
<enum>QSizePolicy::Fixed</enum>
253+
</property>
254+
<property name="sizeHint" stdset="0">
255+
<size>
256+
<width>50</width>
257+
<height>20</height>
258+
</size>
259+
</property>
260+
</spacer>
261+
</item>
262+
<item>
263+
<widget class="QLabel" name="labelImperviousnessField">
264+
<property name="text">
265+
<string>Select Imperviousness-Field</string>
266+
</property>
267+
</widget>
268+
</item>
269+
<item>
270+
<widget class="QComboBox" name="comboboxImperviousnessField"/>
271+
</item>
272+
</layout>
239273
</item>
240274
</layout>
241275
</item>

QTalsim/qtalsim_subbasin_dialog.py

Lines changed: 106 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ def initialize_parameters(self):
7070
#Fill Comboboxes
7171
self.comboboxUISubBasin.clear()
7272
self.comboboxNameField.clear()
73+
self.comboboxImperviousnessField.setVisible(False)
74+
self.labelImperviousnessField.setVisible(False)
7375
self.fillLayerComboboxes()
7476

7577
def safeConnect(self, signal: pyqtSignal, slot):
@@ -146,10 +148,13 @@ def fillLayerComboboxes(self):
146148
self.comboboxWaterNetwork.addItem(self.noLayerSelected)
147149
self.comboboxWaterNetwork.addItems([layer.name() for layer in self.lineLayers])
148150

149-
#Imperviousness layer
151+
#Imperviousness layer - raster and vector
150152
self.comboboxImperviousness.clear()
151153
self.comboboxImperviousness.addItem(self.noLayerSelected)
152154
self.comboboxImperviousness.addItems([layer.name() for layer in self.rasterLayers])
155+
self.comboboxImperviousness.addItems([layer.name() for layer in self.polygonLayers])
156+
self.safeConnect(self.comboboxImperviousness.currentIndexChanged, self.on_imperviousness_layer_changed)
157+
self.comboboxImperviousnessField
153158

154159
def on_subbasin_layer_changed(self):
155160
'''
@@ -169,6 +174,27 @@ def on_subbasin_layer_changed(self):
169174
self.comboboxNameField.addItems(["Select Name-Field"])
170175
self.comboboxNameField.addItems([str(field) for field in self.fieldsSubbasinLayer])
171176

177+
def on_imperviousness_layer_changed(self):
178+
'''
179+
If the imperviousness layer is a vector layer, fill the field-combobox with the fields of this layer.
180+
'''
181+
selected_layer_name = self.comboboxImperviousness.currentText() #Get the selected layer name
182+
183+
if selected_layer_name is not None and selected_layer_name != self.noLayerSelected: #imperviousness is optional
184+
self.imperviousnessLayer = QgsProject.instance().mapLayersByName(selected_layer_name)[0]
185+
if self.imperviousnessLayer.type() == QgsMapLayer.RasterLayer: #check if raster
186+
self.comboboxImperviousnessField.setVisible(False)
187+
self.labelImperviousnessField.setVisible(False)
188+
elif self.imperviousnessLayer.type() == QgsMapLayer.VectorLayer:
189+
self.comboboxImperviousnessField.setVisible(True)
190+
self.labelImperviousnessField.setVisible(True)
191+
self.comboboxImperviousnessField.clear()
192+
field_names = [field.name() for field in self.imperviousnessLayer.fields()]
193+
self.comboboxImperviousnessField.addItems(field_names)
194+
else:
195+
self.comboboxImperviousnessField.setVisible(False)
196+
self.labelImperviousnessField.setVisible(False)
197+
172198
def runSubBasinPreprocessing(self):
173199
'''
174200
Core function to run all processing-steps of the sub-basins layer.
@@ -334,7 +360,85 @@ def calculateImperviousness(self, sub_basins_layer, imperviousness_layer):
334360
'''
335361
Calculates average impervious area per sub-basin.
336362
'''
337-
self.subBasinLayerProcessed = processing.run("native:zonalstatisticsfb", {'INPUT': sub_basins_layer,'INPUT_RASTER': imperviousness_layer,'RASTER_BAND':1,'COLUMN_PREFIX':'Imp_','STATISTICS':[2],'OUTPUT':'TEMPORARY_OUTPUT'})['OUTPUT']
363+
if imperviousness_layer.type() == QgsMapLayer.VectorLayer:
364+
fieldNameImperviousness = self.comboboxImperviousnessField.currentText()
365+
intersection_result = processing.run(
366+
"native:intersection",
367+
{
368+
"INPUT": sub_basins_layer,
369+
"OVERLAY": imperviousness_layer,
370+
"INPUT_FIELDS": [],
371+
"OUTPUT": "memory:"
372+
}
373+
)
374+
intersection_layer = intersection_result["OUTPUT"]
375+
376+
#Calculate area & weighted imperviousness for each polygon
377+
intersection_layer.startEditing()
378+
if "weighted_imp" not in [f.name() for f in intersection_layer.fields()]:
379+
intersection_layer.dataProvider().addAttributes([
380+
QgsField("weighted_imp", QVariant.Double),
381+
QgsField("area_m2", QVariant.Double)
382+
])
383+
intersection_layer.updateFields()
384+
385+
for feature in intersection_layer.getFeatures():
386+
geom = feature.geometry()
387+
area = geom.area()
388+
imperv_val = feature[fieldNameImperviousness]
389+
if imperv_val is None:
390+
imperv_val = 0
391+
feature["area_m2"] = area
392+
feature["weighted_imp"] = area * float(imperv_val)
393+
intersection_layer.updateFeature(feature)
394+
intersection_layer.commitChanges()
395+
396+
#Aggregate by sub-basin ID
397+
aggregate_result = processing.run(
398+
"native:aggregate",
399+
{
400+
"INPUT": intersection_layer,
401+
"GROUP_BY": self.subbasinUIField,
402+
"AGGREGATES": [
403+
{"aggregate": "first_value", "delimiter": ",", "input": self.subbasinUIField, "length": 50, "precision": 0, "name": self.subbasinUIField, 'type': 10, 'type_name': 'text', "sub_type": 0},
404+
{"aggregate": "sum", "delimiter": ",", "input": "weighted_imp", "length": 10, "precision": 3, "name": "sum_weighted", "type": 6, "type_name": "double precision", "sub_type": 0},
405+
{"aggregate": "sum", "delimiter": ",", "input": "area_m2", "length": 10, "precision": 3, "name": "sum_area", "type": 6, "type_name": "double precision", "sub_type": 0}
406+
],
407+
"OUTPUT": "TEMPORARY_OUTPUT"
408+
}
409+
)
410+
aggregate_layer = aggregate_result["OUTPUT"]
411+
#Calculate mean imperviousness and join to sub-basins
412+
aggregate_layer.startEditing()
413+
if self.imperviousFieldName not in [f.name() for f in aggregate_layer.fields()]:
414+
aggregate_layer.dataProvider().addAttributes([QgsField(self.imperviousFieldName, QVariant.Double)])
415+
aggregate_layer.updateFields()
416+
417+
for feature in aggregate_layer.getFeatures():
418+
sum_area = feature["sum_area"]
419+
sum_weighted = feature["sum_weighted"]
420+
if sum_area and sum_area > 0:
421+
feature[self.imperviousFieldName] = sum_weighted / sum_area
422+
else:
423+
feature[self.imperviousFieldName] = 0
424+
aggregate_layer.updateFeature(feature)
425+
aggregate_layer.commitChanges()
426+
427+
joinResult = processing.run(
428+
"native:joinattributestable",
429+
{
430+
"INPUT": sub_basins_layer,
431+
"FIELD": self.subbasinUIField,
432+
"INPUT_2": aggregate_layer,
433+
"FIELD_2": self.subbasinUIField,
434+
"FIELDS_TO_COPY": [self.imperviousFieldName],
435+
"METHOD": 1,
436+
"OUTPUT": 'TEMPORARY_OUTPUT'
437+
}
438+
)
439+
self.subBasinLayerProcessed = joinResult['OUTPUT']
440+
elif imperviousness_layer.type() == QgsMapLayer.RasterLayer:
441+
self.subBasinLayerProcessed = processing.run("native:zonalstatisticsfb", {'INPUT': sub_basins_layer,'INPUT_RASTER': imperviousness_layer,'RASTER_BAND':1,'COLUMN_PREFIX':'Imp_','STATISTICS':[2],'OUTPUT':'TEMPORARY_OUTPUT'})['OUTPUT']
338442

339443
return self.subBasinLayerProcessed
340444

0 commit comments

Comments
 (0)