diff --git a/avaframeConnector_commonFunc.py b/avaframeConnector_commonFunc.py index 45e1fe8..00bc386 100644 --- a/avaframeConnector_commonFunc.py +++ b/avaframeConnector_commonFunc.py @@ -141,8 +141,37 @@ def getAlphaBetaResults(targetDir, useSmallAva=False): abResultsLayer = QgsVectorLayer(str(abResultsFile), "AlphaBeta (com2)", "ogr") return abResultsLayer else: - return "None" - + return 'None' + +def getDFAPathResults(targetDir): + '''Get results from path generation + + Parameters + ----------- + targetDir: pathlib path + to avalanche directory + Returns + ------- + DFAPathResults : massAvgPath and splitPoint + ''' + from qgis.core import (QgsVectorLayer) + avaDir = pathlib.Path(str(targetDir)) + pathDir = avaDir / 'Outputs' / 'ana5Utils' / 'DFAPath' + allDFAPathLayers = [] + + # Collect all path shapefiles + for file in pathDir.glob('massAvgPath*.shp'): + pathLayer = QgsVectorLayer(str(file), f"Mass Average Path - {file.stem}", "ogr") + if pathLayer.isValid(): + allDFAPathLayers.append(pathLayer) + + # Collect all split point shapefiles + for file in pathDir.glob('splitPointParabolicFit*.shp'): + splitPointLayer = QgsVectorLayer(str(file), f"Split Point - {file.stem}", "ogr") + if splitPointLayer.isValid(): + allDFAPathLayers.append(splitPointLayer) + + return allDFAPathLayers def getAna4ProbAnaResults(targetDir): """Get results of ana4PropAna diff --git a/avaframeConnector_provider.py b/avaframeConnector_provider.py index 3b9d3de..3c09ed9 100644 --- a/avaframeConnector_provider.py +++ b/avaframeConnector_provider.py @@ -95,6 +95,7 @@ def find_python(): from .runCom6RockAvalanche_algorithm import runCom6RockAvalancheAlgorithm from .runAna4ProbAna_algorithm import runAna4ProbAnaAlgorithm from .runAna4ProbDirOnly_algorithm import runAna4ProbDirOnlyAlgorithm +from .runAna5DFAPathGeneration_algorithm import runAna5DFAPathGenerationAlgorithm from .runIn1RelInfo_algorithm import runIn1RelInfoAlgorithm from .update_algorithm import updateAlgorithm @@ -129,6 +130,7 @@ def loadAlgorithms(self): self.addAlgorithm(runCom6RockAvalancheAlgorithm()) self.addAlgorithm(runAna4ProbAnaAlgorithm()) self.addAlgorithm(runAna4ProbDirOnlyAlgorithm()) + self.addAlgorithm(runAna5DFAPathGenerationAlgorithm()) self.addAlgorithm(getVersionAlgorithm()) self.addAlgorithm(updateAlgorithm()) self.addAlgorithm(runIn1RelInfoAlgorithm()) diff --git a/pb_tool.cfg b/pb_tool.cfg index 75b383b..c84530b 100644 --- a/pb_tool.cfg +++ b/pb_tool.cfg @@ -52,13 +52,14 @@ python_files: __init__.py avaframeConnector.py avaframeConnector_provider.py avaframeConnector_algorithm.py layerRename_algorithm.py getVersion_algorithm.py - update_algorithm.py + update_algorithm.py runCom1DFA_algorithm.py runCom2AB_algorithm.py - runAna4ProbAna_algorithm.py - runAna4ProbDirOnly_algorithm.py runCom5SnowSlide_algorithm.py runCom6RockAvalanche_algorithm.py + runAna4ProbAna_algorithm.py + runAna4ProbDirOnly_algorithm.py + runAna5DFAPathGeneration_algorithm.py runIn1RelInfo_algorithm.py avaframeConnector_commonFunc.py diff --git a/runAna5DFAPathGeneration_algorithm.py b/runAna5DFAPathGeneration_algorithm.py new file mode 100644 index 0000000..ba22e9a --- /dev/null +++ b/runAna5DFAPathGeneration_algorithm.py @@ -0,0 +1,210 @@ +# -*- coding: utf-8 -*- + +""" +/*************************************************************************** + AvaFrameRunComputeDFAPath + A QGIS plugin + Connects to AvaFrame + Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/ + ------------------- + begin : 2021-08-26 + copyright : (C) 2021 by AvaFrame Team + email : felix@avaframe.org + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +""" + +__author__ = 'AvaFrame Team' +__date__ = '2022' +__copyright__ = '(C) 2022 by AvaFrame Team' + +# This will get replaced with a git SHA1 when you do a git archive + +__revision__ = '$Format:%H$' + +import subprocess + +from qgis.PyQt.QtCore import QCoreApplication +from qgis.core import (QgsProcessing, + QgsProcessingException, + QgsProcessingAlgorithm, + QgsProcessingParameterFeatureSource, + QgsProcessingParameterRasterLayer, + QgsProcessingParameterMultipleLayers, + QgsProcessingParameterFolderDestination, + QgsProcessingOutputVectorLayer, + QgsProcessingParameterBoolean, + QgsProcessingOutputMultipleLayers + ) + + +class runAna5DFAPathGenerationAlgorithm(QgsProcessingAlgorithm): + """ + This is the AvaFrame Connection, i.e. the part running with QGis. For this + connector to work, more installation is needed. See instructions at docs.avaframe.org + """ + + DEM = 'DEM' + REL = 'REL' + FOLDEST = 'FOLDEST' + OUTPUT = 'OUTPUT' + OUTPPR = 'OUTPPR' + + def initAlgorithm(self, config): + """ + Here we define the inputs and output of the algorithm, along + with some other properties. + """ + + self.addParameter(QgsProcessingParameterRasterLayer( + self.DEM, + self.tr("DEM layer"))) + + self.addParameter(QgsProcessingParameterMultipleLayers( + self.REL, + self.tr('Release layer(s)'), + layerType=QgsProcessing.TypeVectorAnyGeometry + )) + + self.addParameter(QgsProcessingParameterFolderDestination( + self.FOLDEST, + self.tr('Destination folder') + )) + + self.addOutput(QgsProcessingOutputVectorLayer( + self.OUTPUT, + self.tr("Output layer"), + QgsProcessing.TypeVectorAnyGeometry)) + + self.addOutput(QgsProcessingOutputMultipleLayers( + self.OUTPPR, + )) + + def flags(self): + return super().flags() + # return super().flags() | QgsProcessingAlgorithm.FlagNoThreading + + def processAlgorithm(self, parameters, context, feedback): + """ + Here is where the processing itself takes place. + """ + + import avaframe.version as gv + from . import avaframeConnector_commonFunc as cF + + feedback.pushInfo('AvaFrame Version: ' + gv.getVersion()) + + targetADDTONAME = '' + + sourceDEM = self.parameterAsRasterLayer(parameters, self.DEM, context) + if sourceDEM is None: + raise QgsProcessingException(self.invalidSourceError(parameters, self.DEM)) + + # Release files + allREL = self.parameterAsLayerList(parameters, self.REL, context) + if allREL is None: + raise QgsProcessingException(self.invalidSourceError(parameters, self.REL)) + + relDict = {} + if allREL: + relDict = {lyr.source(): lyr for lyr in allREL} + + sourceFOLDEST = self.parameterAsFile(parameters, self.FOLDEST, context) + + # create folder structure (targetDir is the tmp one) + finalTargetDir, targetDir = cF.createFolderStructure(sourceFOLDEST) + + feedback.pushInfo(sourceDEM.source()) + + # copy DEM + cF.copyDEM(sourceDEM, targetDir) + + # copy all release shapefile parts + cF.copyMultipleShp(relDict, targetDir / 'Inputs' / 'REL', targetADDTONAME) + + feedback.pushInfo('Starting path generation') + feedback.pushInfo('See console for progress') + + # Prepare command for subprocess call + command = ['python', '-m', 'avaframe.runAna5DFAPathGeneration', str(targetDir)] + + cF.runAndCheck(command, self, feedback) + feedback.pushInfo('Done, start loading the results') + + # Move input, log and output folders to finalTargetDir + cF.moveInputAndOutputFoldersToFinal(targetDir, finalTargetDir) + + # Get path and split point shapefiles to return to QGIS + try: + pathResults = cF.getDFAPathResults(finalTargetDir) + except: + raise QgsProcessingException(self.tr('Something went wrong with path generation, please check log files')) + + context = cF.addLayersToContext(context, pathResults, self.OUTPPR) + + feedback.pushInfo('\n---------------------------------') + feedback.pushInfo('Done, find results and logs here:') + feedback.pushInfo(str(targetDir.resolve())) + feedback.pushInfo('---------------------------------\n') + + return {self.OUTPUT: pathResults} + + def name(self): + """ + Returns the algorithm name, used for identifying the algorithm. This + string should be fixed for the algorithm, and must not be localised. + The name should be unique within each provider. Names should contain + lowercase alphanumeric characters only and no spaces or other + formatting characters. + """ + return 'dfapath' + + def displayName(self): + """ + Returns the translated algorithm name, which should be used for any + user-visible display of the algorithm name. + """ + return self.tr('Generate mass average path (ana5, com1)') + + def group(self): + """ + Returns the name of the group this algorithm belongs to. This string + should be localised. + """ + return self.tr(self.groupId()) + + def groupId(self): + """ + Returns the unique ID of the group this algorithm belongs to. This + string should be fixed for the algorithm, and must not be localised. + The group id should be unique within each provider. Group id should + contain lowercase alphanumeric characters only and no spaces or other + formatting characters. + """ + return 'Experimental' + + def tr(self, string): + return QCoreApplication.translate('Processing', string) + + def shortHelpString(self) -> str: + hstring = ('Generates the mass average path from a dense flow simulation via module ana5Utils.\n\ + For more information go to (or use the help button below): \n\ + AvaFrame Documentation: https://docs.avaframe.org\n\ + Homepage: https://avaframe.org\n\ + Praxisleitfaden: https://avaframe.org/reports\n') + + return self.tr(hstring) + + def helpUrl(self): + return "https://docs.avaframe.org/en/latest/connector.html" + + def createInstance(self): + return runAna5DFAPathGenerationAlgorithm()