3232
3333import traceback
3434from pathlib import Path
35+ from datetime import datetime
3536
3637from qgis .core import (
3738 Qgis ,
4950 QgsProcessingParameterRasterLayer ,
5051 QgsProcessingParameterString ,
5152 QgsProject ,
53+ QgsVectorLayer ,
54+ QgsProcessingOutputFile ,
5255)
5356from qgis .PyQt .QtCore import QCoreApplication
5457
5558from ..REMEDY_GIS_RiskTool .BegrensSkade import mainBegrensSkade_Excavation
56- from ..utilities .AddLayersTask import AddLayersTask
5759from ..utilities .gui import GuiUtils
5860from ..utilities .logger import CustomLogger
5961from ..utilities .methodslib import (
@@ -117,7 +119,6 @@ def __init__(self):
117119 self .feature_name = None # Default value
118120 self .layers_info = {}
119121 self .styles_dir_path = Path ()
120- self .add_layers_task = AddLayersTask ()
121122 self .logger .info ("__INIT__ - Finished initialize BegrensSkadeExcavation " )
122123
123124 def tr (self , string ):
@@ -205,15 +206,10 @@ def __getstate__(self):
205206 "RASTER_ROCK_SURFACE" ,
206207 "Input raster of depth to bedrock" ,
207208 ]
208- POREPRESSURE_ENUM = ["POREPRESSURE_ENUM" , "Pore pressure reduction curves" ]
209- enum_porepressure = [
210- "Lav poretrykksreduksjon" ,
211- "Middels poretrykksreduksjon" ,
212- "Høy poretrykksreduksjon" ,
213- ]
214- POREPRESSURE_REDUCTION = [
215- "POREPRESSURE_REDUCTION" ,
216- "Porepressure reduction [kPa]" ,
209+
210+ POREWP_REDUCTION_M = [
211+ "POREWP_REDUCTION_M" ,
212+ "Porewater pressure reduction [m]" ,
217213 ]
218214 DRY_CRUST_THICKNESS = [
219215 "DRY_CRUST_THICKNESS" ,
@@ -287,7 +283,7 @@ def initAlgorithm(self, config):
287283 self .EXCAVATION_DEPTH [0 ],
288284 self .tr (f"{ self .EXCAVATION_DEPTH [1 ]} " ),
289285 QgsProcessingParameterNumber .Double ,
290- defaultValue = 0 ,
286+ defaultValue = 10 ,
291287 minValue = 0 ,
292288 )
293289 param .setFlags (QgsProcessingParameterDefinition .FlagAdvanced )
@@ -322,24 +318,16 @@ def initAlgorithm(self, config):
322318 | QgsProcessingParameterDefinition .FlagOptional
323319 )
324320 self .addParameter (param )
325-
326- param = QgsProcessingParameterEnum (
327- self .POREPRESSURE_ENUM [0 ],
328- self .tr (f"{ self .POREPRESSURE_ENUM [1 ]} " ),
329- self .enum_porepressure ,
330- defaultValue = 1 ,
331- allowMultiple = False ,
332- )
333- param .setFlags (QgsProcessingParameterDefinition .FlagAdvanced )
334- self .addParameter (param )
321+
335322 param = QgsProcessingParameterNumber (
336- self .POREPRESSURE_REDUCTION [0 ],
337- self .tr (f"{ self .POREPRESSURE_REDUCTION [1 ]} " ),
338- defaultValue = 50 ,
323+ self .POREWP_REDUCTION_M [0 ],
324+ self .tr (f"{ self .POREWP_REDUCTION_M [1 ]} " ),
325+ defaultValue = 10 ,
339326 minValue = 0 ,
340327 )
341328 param .setFlags (QgsProcessingParameterDefinition .FlagAdvanced )
342329 self .addParameter (param )
330+
343331 param = QgsProcessingParameterNumber (
344332 self .DRY_CRUST_THICKNESS [0 ],
345333 self .tr (f"{ self .DRY_CRUST_THICKNESS [1 ]} " ),
@@ -462,8 +450,9 @@ def initAlgorithm(self, config):
462450 self .OUTPUT_FEATURE_NAME ,
463451 self .tr (
464452 "Naming Conventions for Analysis and Features (Output feature name appended to file-names)"
465- ),
466- )
453+ )
454+ ),
455+ createOutput = True
467456 )
468457 self .addParameter (
469458 QgsProcessingParameterCrs (
@@ -478,6 +467,24 @@ def initAlgorithm(self, config):
478467 self .tr ("Output Folder" ),
479468 )
480469 )
470+ self .addOutput (
471+ QgsProcessingOutputFile (
472+ self .OUTPUT_BUILDING ,
473+ self .tr ("Output Buildings Shapefile" ),
474+ )
475+ )
476+ self .addOutput (
477+ QgsProcessingOutputFile (
478+ self .OUTPUT_WALL ,
479+ self .tr ("Output Walls Shapefile" ),
480+ )
481+ )
482+ self .addOutput (
483+ QgsProcessingOutputFile (
484+ self .OUTPUT_CORNER ,
485+ self .tr ("Output Corners Shapefile" ),
486+ )
487+ )
481488
482489 self .logger .info ("initAlgorithm - Done setting up the inputs." )
483490
@@ -661,10 +668,6 @@ def processAlgorithm(self, parameters, context, feedback):
661668 )
662669 return {}
663670
664- porepressure_index = self .parameterAsEnum (
665- parameters , self .POREPRESSURE_ENUM [0 ], context
666- )
667- pw_reduction_curve = self .enum_porepressure [porepressure_index ]
668671 dry_crust_thk = self .parameterAsDouble (
669672 parameters , self .DRY_CRUST_THICKNESS [0 ], context
670673 )
@@ -675,8 +678,8 @@ def processAlgorithm(self, parameters, context, feedback):
675678 parameters , self .SOIL_DENSITY [0 ], context
676679 )
677680 ocr_value = self .parameterAsDouble (parameters , self .OCR [0 ], context )
678- porewp_red = self .parameterAsInt (
679- parameters , self .POREPRESSURE_REDUCTION [0 ], context
681+ porewp_red_m = self .parameterAsInt (
682+ parameters , self .POREWP_REDUCTION_M [0 ], context
680683 )
681684 janbu_ref_stress = self .parameterAsInt (
682685 parameters , self .JANBU_REF_STRESS [0 ], context
@@ -693,12 +696,11 @@ def processAlgorithm(self, parameters, context, feedback):
693696
694697 else :
695698 path_source_raster_rock_surface = None
696- pw_reduction_curve = None
697699 dry_crust_thk = None
698700 dep_groundwater = None
699701 density_sat = None
700702 ocr_value = None
701- porewp_red = None
703+ porewp_red_m = None
702704 janbu_ref_stress = None
703705 janbu_const = None
704706 janbu_m = None
@@ -769,12 +771,11 @@ def processAlgorithm(self, parameters, context, feedback):
769771 feedback .pushInfo (
770772 f"PROCESS - Param: dtb_raster = { path_source_raster_rock_surface } "
771773 )
772- feedback .pushInfo (f"PROCESS - Param: pw_reduction_curve = { pw_reduction_curve } " )
773774 feedback .pushInfo (f"PROCESS - Param: dry_crust_thk = { dry_crust_thk } " )
774775 feedback .pushInfo (f"PROCESS - Param: dep_groundwater = { dep_groundwater } " )
775776 feedback .pushInfo (f"PROCESS - Param: density_sat = { density_sat } " )
776777 feedback .pushInfo (f"PROCESS - Param: OCR = { ocr_value } " )
777- feedback .pushInfo (f"PROCESS - Param: porewp_red = { porewp_red } " )
778+ feedback .pushInfo (f"PROCESS - Param: porewp_red_m = { porewp_red_m } " )
778779 feedback .pushInfo (f"PROCESS - Param: janbu_ref_stress = { janbu_ref_stress } " )
779780 feedback .pushInfo (f"PROCESS - Param: janbu_const = { janbu_const } " )
780781 feedback .pushInfo (f"PROCESS - Param: janbu_m = { janbu_m } " )
@@ -797,12 +798,11 @@ def processAlgorithm(self, parameters, context, feedback):
797798 short_term_curve = short_term_curve ,
798799 bLongterm = bLongterm ,
799800 dtb_raster = str (path_source_raster_rock_surface ),
800- pw_reduction_curve = pw_reduction_curve ,
801801 dry_crust_thk = dry_crust_thk ,
802802 dep_groundwater = dep_groundwater ,
803803 density_sat = density_sat ,
804804 OCR = ocr_value ,
805- porewp_red = porewp_red ,
805+ porewp_red_m = porewp_red_m ,
806806 janbu_ref_stress = janbu_ref_stress ,
807807 janbu_const = janbu_const ,
808808 janbu_m = janbu_m ,
@@ -821,7 +821,7 @@ def processAlgorithm(self, parameters, context, feedback):
821821 return {}
822822
823823 #################### HANDLE THE RESULT ###############################
824- feedback .setProgress (80 )
824+ feedback .setProgress (90 )
825825 self .logger .info (f"PROCESS - OUTPUT BUILDINGS: { output_shapefiles [0 ]} " )
826826 self .logger .info (f"PROCESS - OUTPUT WALL: { output_shapefiles [1 ]} " )
827827 self .logger .info (f"PROCESS - OUTPUT CORNER: { output_shapefiles [2 ]} " )
@@ -840,80 +840,89 @@ def processAlgorithm(self, parameters, context, feedback):
840840 "shape_path" : output_shapefiles [1 ],
841841 "style_name" : "WALL-ANGLE.qml" ,
842842 },
843- "BUILDING-TOTAL-SETTLMENT" : {
844- "shape_path" : output_shapefiles [0 ],
845- "style_name" : "BUILDING-TOTAL-SETTLMENT_sv_tot.qml" ,
846- },
847843 "BUILDING-TOTAL-ANGLE" : {
848844 "shape_path" : output_shapefiles [0 ],
849845 "style_name" : "BUILDING-TOTAL-ANGLE_max_angle.qml" ,
850846 },
847+ "BUILDING-TOTAL-SETTLMENT" : {
848+ "shape_path" : output_shapefiles [0 ],
849+ "style_name" : "BUILDING-TOTAL-SETTLMENT_sv_tot.qml" ,
850+ }
851851 }
852852 if bVulnerability :
853853 self .layers_info .update (
854854 {
855- "BUILDING-RISK-SETTLMENT" : {
856- "shape_path" : output_shapefiles [0 ],
857- "style_name" : "BUILDING-TOTAL-RISK-SELLMENT_risk_tots.qml" ,
858- },
859855 "BUILDING-RISK-ANGLE" : {
860856 "shape_path" : output_shapefiles [0 ],
861857 "style_name" : "BUILDING-TOTAL-RISK-ANGLE_risk_angle.qml" ,
862858 },
859+ "BUILDING-RISK-SETTLMENT" : {
860+ "shape_path" : output_shapefiles [0 ],
861+ "style_name" : "BUILDING-TOTAL-RISK-SELLMENT_risk_tots.qml" ,
862+ }
863863 }
864864 )
865865
866- feedback .setProgress (90 )
866+ feedback .setProgress (100 )
867867 feedback .pushInfo ("PROCESS - Finished processing!" )
868+
868869 # Return the results of the algorithm.
869- return {
870- self .OUTPUT_BUILDING : output_shapefiles [0 ],
871- self .OUTPUT_WALL : output_shapefiles [1 ],
872- self . OUTPUT_CORNER : output_shapefiles [ 2 ],
873- }
874-
870+ return {self . OUTPUT_BUILDING : output_shapefiles [ 0 ],
871+ self .OUTPUT_WALL : output_shapefiles [1 ],
872+ self .OUTPUT_CORNER : output_shapefiles [2 ],
873+
874+ }
875+
875876 def postProcessAlgorithm (self , context , feedback ):
876877 """
877- Handles the post-processing steps of the algorithm, specifically adding output layers to the QGIS project.
878-
879- This method creates and executes a process to add layers to the QGIS interface, applying predefined styles
880- and organizing them within a specified group. It leverages the `AddLayersTask` class to manage layer
881- addition in a way that ensures thread safety and proper GUI updates.
882-
883- Parameters:
884- - context (QgsProcessingContext): The context of the processing, providing access to the QGIS project and other relevant settings.
885- - feedback (QgsProcessingFeedback): The object used to report progress and log messages back to the user.
886-
887- Returns:
888- - dict: An empty dictionary. This method does not produce output parameters but instead focuses on the side effect of adding layers to the project.
889-
890- Note:
891- This method sets up a task for layer addition, defining success and failure callbacks to provide user feedback.
892- It manually starts the process and handles its completion.
878+ This method is called after processAlgorithm finishes.
879+ Here, we manually load the output shapefiles, apply QML styles,
880+ and place them under a custom group in the layer tree.
893881 """
894- ######### EXPERIMENTAL ADD LAYERS TO GUI #########
895- # Create the task
896- self .add_layers_task .setParameters (
897- self .layers_info ,
898- self .feature_name ,
899- self .styles_dir_path ,
900- self .logger ,
901- )
902-
903- # Define a slot to handle the task completion
904- def onTaskCompleted (success ):
905- if success :
906- feedback .pushInfo ("POSTPROCESS - Layers added successfully." )
907- feedback .setProgress (100 )
882+ project = context .project ()
883+ root = project .layerTreeRoot ()
884+
885+ # Create (or find) a group at the top level named by 'self.feature_name'.
886+ group_name = self .feature_name
887+ group = root .findGroup (group_name )
888+ if not group :
889+ group = root .insertGroup (0 , group_name )
890+
891+ # 2) Loop through the entries stored in 'self.layers_info' defined during processAlgorithm
892+ for layer_label , layer_info in self .layers_info .items ():
893+ shape_path = layer_info ["shape_path" ] # e.g. "C:/somefolder/buildings.shp"
894+ style_name = layer_info ["style_name" ] # e.g. "BUILDING-TOTAL-SETTLMENT_sv_tot.qml"
895+
896+ # Generate a unique layer name with timestamp
897+ timestamp = datetime .now ().strftime ("%Y%m%d_%H%M" )
898+ final_layer_name = f"{ layer_label } _{ timestamp } "
899+
900+ # Create the QgsVectorLayer from the file path
901+ layer = QgsVectorLayer (shape_path , final_layer_name , "ogr" )
902+ if not layer .isValid ():
903+ feedback .reportError (f"Could not load layer from file: { shape_path } " )
904+ continue
905+
906+ # Load the QML style if it exists
907+ style_path = self .styles_dir_path / style_name # e.g. /path/to/styles/BUILDING-TOTAL-SETTLMENT_sv_tot.qml
908+ if style_path .is_file ():
909+ layer .loadNamedStyle (str (style_path ))
910+ layer .triggerRepaint ()
908911 else :
909- feedback .reportError ("POSTPROCESS - Failed to add layers." )
910- feedback .setProgress (100 )
912+ feedback .reportError (f"Style file not found: { style_path } " )
913+
914+ # Add the layer to the project (layer registry) *without* adding to the root TOC
915+ QgsProject .instance ().addMapLayer (layer , False )
916+
917+ # Place the layer under the group at the bottom
918+ group .insertLayer (- 1 , layer )
911919
912- # Connect the task's completed signal to the slot
913- self .add_layers_task .taskCompleted .connect (onTaskCompleted )
920+ # Ensure the new layer node is visible
921+ node = group .findLayer (layer .id ())
922+ if node :
923+ node .setItemVisibilityChecked (True )
914924
915- # Start the task
916- success = self .add_layers_task .run ()
917- self .add_layers_task .finished (success )
925+ feedback .pushInfo (f"Loaded and styled layer '{ final_layer_name } ' in group '{ group_name } '." )
918926
919- return {}
927+ feedback .pushInfo ("postProcessAlgorithm complete." )
928+ return {}
0 commit comments