def handleAlgorithmResults(alg, context, feedback=None, showResults=True): wrongLayers = [] if feedback is None: feedback = QgsProcessingFeedback() feedback.setProgressText(QCoreApplication.translate('Postprocessing', 'Loading resulting layers')) i = 0 for l, details in context.layersToLoadOnCompletion().items(): if feedback.isCanceled(): return False if len(context.layersToLoadOnCompletion()) > 2: # only show progress feedback if we're loading a bunch of layers feedback.setProgress(100 * i / float(len(context.layersToLoadOnCompletion()))) try: layer = QgsProcessingUtils.mapLayerFromString(l, context, typeHint=details.layerTypeHint) if layer is not None: set_layer_name(layer, details) style = None if details.outputName: style = RenderingStyles.getStyle(alg.id(), details.outputName) if style is None: if layer.type() == QgsMapLayer.RasterLayer: style = ProcessingConfig.getSetting(ProcessingConfig.RASTER_STYLE) else: if layer.geometryType() == QgsWkbTypes.PointGeometry: style = ProcessingConfig.getSetting(ProcessingConfig.VECTOR_POINT_STYLE) elif layer.geometryType() == QgsWkbTypes.LineGeometry: style = ProcessingConfig.getSetting(ProcessingConfig.VECTOR_LINE_STYLE) else: style = ProcessingConfig.getSetting(ProcessingConfig.VECTOR_POLYGON_STYLE) if style: layer.loadNamedStyle(style) details.project.addMapLayer(context.temporaryLayerStore().takeMapLayer(layer)) if details.postProcessor(): details.postProcessor().postProcessLayer(layer, context, feedback) else: wrongLayers.append(str(l)) except Exception: QgsMessageLog.logMessage(QCoreApplication.translate('Postprocessing', "Error loading result layer:") + "\n" + traceback.format_exc(), 'Processing', Qgis.Critical) wrongLayers.append(str(l)) i += 1 feedback.setProgress(100) if wrongLayers: msg = QCoreApplication.translate('Postprocessing', "The following layers were not correctly generated.") msg += "<ul>" + "".join(["<li>%s</li>" % lay for lay in wrongLayers]) + "</ul>" msg += QCoreApplication.translate('Postprocessing', "You can check the 'Log Messages Panel' in QGIS main window to find more information about the execution of the algorithm.") feedback.reportError(msg) return len(wrongLayers) == 0
def handleAlgorithmResults(alg, context, feedback=None, showResults=True): wrongLayers = [] if feedback is None: feedback = QgsProcessingFeedback() feedback.setProgressText(QCoreApplication.translate('Postprocessing', 'Loading resulting layers')) i = 0 for l, details in context.layersToLoadOnCompletion().items(): if feedback.isCanceled(): return False if len(context.layersToLoadOnCompletion()) > 2: # only show progress feedback if we're loading a bunch of layers feedback.setProgress(100 * i / float(len(context.layersToLoadOnCompletion()))) try: layer = QgsProcessingUtils.mapLayerFromString(l, context) if layer is not None: if not ProcessingConfig.getSetting(ProcessingConfig.USE_FILENAME_AS_LAYER_NAME): layer.setName(details.name) style = None if details.outputName: style = RenderingStyles.getStyle(alg.id(), details.outputName) if style is None: if layer.type() == QgsMapLayer.RasterLayer: style = ProcessingConfig.getSetting(ProcessingConfig.RASTER_STYLE) else: if layer.geometryType() == QgsWkbTypes.PointGeometry: style = ProcessingConfig.getSetting(ProcessingConfig.VECTOR_POINT_STYLE) elif layer.geometryType() == QgsWkbTypes.LineGeometry: style = ProcessingConfig.getSetting(ProcessingConfig.VECTOR_LINE_STYLE) else: style = ProcessingConfig.getSetting(ProcessingConfig.VECTOR_POLYGON_STYLE) if style: layer.loadNamedStyle(style) details.project.addMapLayer(context.temporaryLayerStore().takeMapLayer(layer)) if details.postProcessor(): details.postProcessor().postProcessLayer(layer, context, feedback) else: wrongLayers.append(str(l)) except Exception: QgsMessageLog.logMessage(QCoreApplication.translate('Postprocessing', "Error loading result layer:") + "\n" + traceback.format_exc(), 'Processing', Qgis.Critical) wrongLayers.append(str(l)) i += 1 feedback.setProgress(100) if wrongLayers: msg = QCoreApplication.translate('Postprocessing', "The following layers were not correctly generated.") msg += "<ul>" + "".join(["<li>%s</li>" % lay for lay in wrongLayers]) + "</ul>" msg += QCoreApplication.translate('Postprocessing', "You can check the 'Log Messages Panel' in QGIS main window to find more information about the execution of the algorithm.") feedback.reportError(msg) return len(wrongLayers) == 0
def handleAlgorithmResults(alg, feedback=None, showResults=True): wrongLayers = [] htmlResults = False if feedback is None: feedback = QgsProcessingFeedback() feedback.setProgressText( QCoreApplication.translate('Postprocessing', 'Loading resulting layers')) i = 0 for out in alg.outputs: feedback.setProgress(100 * i / float(len(alg.outputs))) if out.hidden or not out.open: continue if isinstance(out, (OutputRaster, OutputVector, OutputTable)): try: if hasattr(out, "layer") and out.layer is not None: out.layer.setName(out.description) QgsProject.instance().addMapLayers([out.layer]) else: if ProcessingConfig.getSetting( ProcessingConfig.USE_FILENAME_AS_LAYER_NAME): name = os.path.basename(out.value) else: name = out.description dataobjects.load( out.value, name, alg.crs, RenderingStyles.getStyle(alg.commandLineName(), out.name)) except Exception: ProcessingLog.addToLog( ProcessingLog.LOG_ERROR, "Error loading result layer:\n" + traceback.format_exc()) wrongLayers.append(out.description) elif isinstance(out, OutputHTML): ProcessingResults.addResult(out.description, out.value) htmlResults = True i += 1 QApplication.restoreOverrideCursor() if wrongLayers: msg = "The following layers were not correctly generated.<ul>" msg += "".join(["<li>%s</li>" % lay for lay in wrongLayers]) + "</ul>" msg += "You can check the log messages to find more information about the execution of the algorithm" feedback.reportError(msg) if showResults and htmlResults and not wrongLayers: dlg = ResultsDialog() dlg.exec_() return len(wrongLayers) == 0
def handleAlgorithmResults(alg, context, feedback=None, showResults=True): wrongLayers = [] if feedback is None: feedback = QgsProcessingFeedback() feedback.setProgressText( QCoreApplication.translate('Postprocessing', 'Loading resulting layers')) i = 0 for out in alg.outputs: feedback.setProgress(100 * i / float(len(alg.outputs))) if out.hidden or not out.open: continue if isinstance(out, (OutputRaster, OutputVector, OutputTable)): try: layer = QgsProcessingUtils.mapLayerFromString( out.value, context) if layer: layer.setName(out.description) QgsProject.instance().addMapLayer( context.temporaryLayerStore().takeMapLayer(layer)) else: if ProcessingConfig.getSetting( ProcessingConfig.USE_FILENAME_AS_LAYER_NAME): name = os.path.basename(out.value) else: name = out.description isRaster = True if isinstance(out, OutputRaster) else False dataobjects.load( out.value, name, alg.crs, RenderingStyles.getStyle(alg.id(), out.name), isRaster) except Exception: QgsMessageLog.logMessage( "Error loading result layer:\n" + traceback.format_exc(), 'Processing', QgsMessageLog.CRITICAL) wrongLayers.append(out.description) elif isinstance(out, OutputHTML): resultsList.addResult(alg.icon(), out.description, out.value) i += 1 QApplication.restoreOverrideCursor() if wrongLayers: msg = "The following layers were not correctly generated.<ul>" msg += "".join(["<li>%s</li>" % lay for lay in wrongLayers]) + "</ul>" msg += "You can check the log messages to find more information about the execution of the algorithm" feedback.reportError(msg) return len(wrongLayers) == 0
def handleAlgorithmResults(alg, feedback=None, showResults=True): wrongLayers = [] htmlResults = False if feedback is None: feedback = QgsProcessingFeedback() feedback.setProgressText(QCoreApplication.translate('Postprocessing', 'Loading resulting layers')) i = 0 for out in alg.outputs: feedback.setProgress(100 * i / float(len(alg.outputs))) if out.hidden or not out.open: continue if isinstance(out, (OutputRaster, OutputVector, OutputTable)): try: if hasattr(out, "layer") and out.layer is not None: out.layer.setName(out.description) QgsProject.instance().addMapLayers([out.layer]) else: if ProcessingConfig.getSetting( ProcessingConfig.USE_FILENAME_AS_LAYER_NAME): name = os.path.basename(out.value) else: name = out.description dataobjects.load(out.value, name, alg.crs, RenderingStyles.getStyle(alg.commandLineName(), out.name)) except Exception: ProcessingLog.addToLog(ProcessingLog.LOG_ERROR, "Error loading result layer:\n" + traceback.format_exc()) wrongLayers.append(out.description) elif isinstance(out, OutputHTML): ProcessingResults.addResult(out.description, out.value) htmlResults = True i += 1 QApplication.restoreOverrideCursor() if wrongLayers: msg = "The following layers were not correctly generated.<ul>" msg += "".join(["<li>%s</li>" % lay for lay in wrongLayers]) + "</ul>" msg += "You can check the log messages to find more information about the execution of the algorithm" feedback.reportError(msg) if showResults and htmlResults and not wrongLayers: dlg = ResultsDialog() dlg.exec_() return len(wrongLayers) == 0
def handleAlgorithmResults(alg, context, feedback=None, showResults=True, parameters={}): wrongLayers = [] if feedback is None: feedback = QgsProcessingFeedback() feedback.setProgressText( QCoreApplication.translate('Postprocessing', 'Loading resulting layers')) i = 0 for l, details in context.layersToLoadOnCompletion().items(): if feedback.isCanceled(): return False if len(context.layersToLoadOnCompletion()) > 2: # only show progress feedback if we're loading a bunch of layers feedback.setProgress( 100 * i / float(len(context.layersToLoadOnCompletion()))) try: layer = QgsProcessingUtils.mapLayerFromString( l, context, typeHint=details.layerTypeHint) if layer is not None: set_layer_name(layer, details) '''If running a model, the execution will arrive here when an algorithm that is part of that model is executed. We check if its output is a final otuput of the model, and adapt the output name accordingly''' outputName = details.outputName expcontext = QgsExpressionContext() scope = QgsExpressionContextScope() expcontext.appendScope(scope) for out in alg.outputDefinitions(): if out.name() not in parameters: continue outValue = parameters[out.name()] if hasattr(outValue, "sink"): outValue = outValue.sink.valueAsString(expcontext)[0] else: outValue = str(outValue) if outValue == l: outputName = out.name() break style = None if outputName: style = RenderingStyles.getStyle(alg.id(), outputName) if style is None: if layer.type() == QgsMapLayerType.RasterLayer: style = ProcessingConfig.getSetting( ProcessingConfig.RASTER_STYLE) else: if layer.geometryType() == QgsWkbTypes.PointGeometry: style = ProcessingConfig.getSetting( ProcessingConfig.VECTOR_POINT_STYLE) elif layer.geometryType() == QgsWkbTypes.LineGeometry: style = ProcessingConfig.getSetting( ProcessingConfig.VECTOR_LINE_STYLE) else: style = ProcessingConfig.getSetting( ProcessingConfig.VECTOR_POLYGON_STYLE) if style: layer.loadNamedStyle(style) details.project.addMapLayer( context.temporaryLayerStore().takeMapLayer(layer)) if details.postProcessor(): details.postProcessor().postProcessLayer( layer, context, feedback) else: wrongLayers.append(str(l)) except Exception: QgsMessageLog.logMessage( QCoreApplication.translate( 'Postprocessing', "Error loading result layer:") + "\n" + traceback.format_exc(), 'Processing', Qgis.Critical) wrongLayers.append(str(l)) i += 1 feedback.setProgress(100) if wrongLayers: msg = QCoreApplication.translate( 'Postprocessing', "The following layers were not correctly generated.") msg += "<ul>" + "".join(["<li>%s</li>" % lay for lay in wrongLayers]) + "</ul>" msg += QCoreApplication.translate( 'Postprocessing', "You can check the 'Log Messages Panel' in QGIS main window to find more information about the execution of the algorithm." ) feedback.reportError(msg) return len(wrongLayers) == 0
def handleAlgorithmResults(alg, context, feedback=None, showResults=True, parameters={}): wrongLayers = [] if feedback is None: feedback = QgsProcessingFeedback() feedback.setProgressText(QCoreApplication.translate('Postprocessing', 'Loading resulting layers')) i = 0 for l, details in context.layersToLoadOnCompletion().items(): if feedback.isCanceled(): return False if len(context.layersToLoadOnCompletion()) > 2: # only show progress feedback if we're loading a bunch of layers feedback.setProgress(100 * i / float(len(context.layersToLoadOnCompletion()))) try: layer = QgsProcessingUtils.mapLayerFromString(l, context, typeHint=details.layerTypeHint) if layer is not None: set_layer_name(layer, details) '''If running a model, the execution will arrive here when an algorithm that is part of that model is executed. We check if its output is a final otuput of the model, and adapt the output name accordingly''' outputName = details.outputName expcontext = QgsExpressionContext() scope = QgsExpressionContextScope() expcontext.appendScope(scope) for out in alg.outputDefinitions(): if out.name() not in parameters: continue outValue = parameters[out.name()] if hasattr(outValue, "sink"): outValue = outValue.sink.valueAsString(expcontext)[0] else: outValue = str(outValue) if outValue == l: outputName = out.name() break style = None if outputName: style = RenderingStyles.getStyle(alg.id(), outputName) if style is None: if layer.type() == QgsMapLayer.RasterLayer: style = ProcessingConfig.getSetting(ProcessingConfig.RASTER_STYLE) else: if layer.geometryType() == QgsWkbTypes.PointGeometry: style = ProcessingConfig.getSetting(ProcessingConfig.VECTOR_POINT_STYLE) elif layer.geometryType() == QgsWkbTypes.LineGeometry: style = ProcessingConfig.getSetting(ProcessingConfig.VECTOR_LINE_STYLE) else: style = ProcessingConfig.getSetting(ProcessingConfig.VECTOR_POLYGON_STYLE) if style: layer.loadNamedStyle(style) details.project.addMapLayer(context.temporaryLayerStore().takeMapLayer(layer)) if details.postProcessor(): details.postProcessor().postProcessLayer(layer, context, feedback) else: wrongLayers.append(str(l)) except Exception: QgsMessageLog.logMessage(QCoreApplication.translate('Postprocessing', "Error loading result layer:") + "\n" + traceback.format_exc(), 'Processing', Qgis.Critical) wrongLayers.append(str(l)) i += 1 feedback.setProgress(100) if wrongLayers: msg = QCoreApplication.translate('Postprocessing', "The following layers were not correctly generated.") msg += "<ul>" + "".join(["<li>%s</li>" % lay for lay in wrongLayers]) + "</ul>" msg += QCoreApplication.translate('Postprocessing', "You can check the 'Log Messages Panel' in QGIS main window to find more information about the execution of the algorithm.") feedback.reportError(msg) return len(wrongLayers) == 0
def handleAlgorithmResults(alg, context, feedback=None, showResults=True): wrongLayers = [] if feedback is None: feedback = QgsProcessingFeedback() feedback.setProgressText(QCoreApplication.translate('Postprocessing', 'Loading resulting layers')) i = 0 for l, details in context.layersToLoadOnCompletion().items(): if feedback.isCanceled(): return False if len(context.layersToLoadOnCompletion()) > 2: # only show progress feedback if we're loading a bunch of layers feedback.setProgress(100 * i / float(len(context.layersToLoadOnCompletion()))) try: layer = QgsProcessingUtils.mapLayerFromString(l, context) if layer is not None: layer.setName(details.name) details.project.addMapLayer(context.temporaryLayerStore().takeMapLayer(layer)) else: name = details.name if ProcessingConfig.getSetting( ProcessingConfig.USE_FILENAME_AS_LAYER_NAME): name = os.path.basename(l) dataobjects.load(l, name, alg.crs, RenderingStyles.getStyle(alg.id(), l)) except Exception: QgsMessageLog.logMessage("Error loading result layer:\n" + traceback.format_exc(), 'Processing', QgsMessageLog.CRITICAL) #wrongLayers.append(out.description()) wrongLayers.append(l) # for out in alg.outputs: # feedback.setProgress(100 * i / float(len(alg.outputs))) # if out.flags() & QgsProcessingParameterDefinition.FlagHidden or not out.open: # continue # if isinstance(out, (OutputRaster, OutputVector, OutputTable)): # try: # layer = QgsProcessingUtils.mapLayerFromString(out.value, context) # if layer: # layer.setName(out.description) # QgsProject.instance().addMapLayer(context.temporaryLayerStore().takeMapLayer(layer)) # else: # if ProcessingConfig.getSetting( # ProcessingConfig.USE_FILENAME_AS_LAYER_NAME): # name = os.path.basename(out.value) # else: # name = out.description # # isRaster = True if isinstance(out, OutputRaster) else False # dataobjects.load(out.value, name, alg.crs, # RenderingStyles.getStyle(alg.id(), out.name), # isRaster) # except Exception: # QgsMessageLog.logMessage("Error loading result layer:\n" + traceback.format_exc(), 'Processing', QgsMessageLog.CRITICAL) # wrongLayers.append(out.description) # elif isinstance(out, OutputHTML): # resultsList.addResult(alg.icon(), out.description, out.value) i += 1 QApplication.restoreOverrideCursor() if wrongLayers: msg = "The following layers were not correctly generated.<ul>" msg += "".join(["<li>%s</li>" % lay for lay in wrongLayers]) + "</ul>" msg += "You can check the log messages to find more information about the execution of the algorithm" feedback.reportError(msg) return len(wrongLayers) == 0
def create_feature_from_observation( self, observation: Observation, geometriobjekter: Dict[str, GeometriObjekt], idents: Dict[str, str], feedback: QgsProcessingFeedback, ): observation_id = observation.objektid fikspunkt1_id = observation.opstillingspunktid fikspunkt1_ident = "uuid:" + fikspunkt1_id if fikspunkt1_id in idents: fikspunkt1_ident = idents[fikspunkt1_id] fikspunkt2_id = observation.sigtepunktid fikspunkt2_ident = "uuid:" + fikspunkt2_id if fikspunkt2_id in idents: fikspunkt2_ident = idents[fikspunkt2_id] geometriobjekt1 = geometriobjekter[fikspunkt1_id] geometriobjekt2 = geometriobjekter[fikspunkt2_id] line_geometry = self.create_line_geometry_from_geometriobjekter( geometriobjekt1, geometriobjekt2, feedback) if line_geometry: # create the feature fet = QgsFeature() fet.setGeometry(line_geometry) # Felter, der skal gemmes på feature: # [QgsField("observation_id", QVariant.String), # QgsField("observation_type_id", QVariant.Double) # QgsField("fikspunkt1_id", QVariant.String), # QgsField("fikspunkt1_ident", QVariant.String), # QgsField("fikspunkt2_id", QVariant.String), # QgsField("fikspunkt2_ident", QVariant.String), # QgsField("registrering_fra", QVariant.DateTime), # QgsField("registrering_fra_iso", QVariant.String), # QgsField("koteforskel", QVariant.Double), # QgsField("nivellementslaengde", QVariant.Double), # QgsField("antal_opstillinger", QVariant.Double), Value3 # QgsField("afstandsafhaengig_varians", QVariant.Double), (value5 for id=1, value4 for id=2) # QgsField("afstandsuafhaengig_varians", QVariant.Double), (value6 for id=1, value5 for id=2) # QgsField("Praecisionsnivellement", QVariant.Double)], (value7 for id=1, 0 for id=2) observation_type_id = observation.observationstypeid registrering_fra = QDateTime(observation.registreringfra) registrering_fra_iso = registrering_fra.toString(Qt.ISODate) koteforskel = observation.value1 nivellementslaengde = observation.value2 antal_opstillinger = observation.value3 if observation_type_id == 1: afstandsafhaengig_varians = observation.value5 afstandsuafhaengig_varians = observation.value6 Praecisionsnivellement = observation.value7 elif observation_type_id == 2: afstandsafhaengig_varians = observation.value4 afstandsuafhaengig_varians = observation.value5 Praecisionsnivellement = 0 else: # Observationstypeid > 2 feedback.setProgressText( "observation_type_id > 2 for observation med id = {id}. Springes over" .format(id=observation_id)) return None # create the feature feature = QgsFeature() feature.setGeometry(line_geometry) feature.setAttributes([ observation_id, observation_type_id, fikspunkt1_id, fikspunkt1_ident, fikspunkt2_id, fikspunkt2_ident, registrering_fra, registrering_fra_iso, koteforskel, nivellementslaengde, antal_opstillinger, afstandsafhaengig_varians, afstandsuafhaengig_varians, Praecisionsnivellement, ]) return feature else: # A geometry could not be established feedback.setProgressText( "En liniegeometri kunne IKKE opettes for observation med id = {id}" .format(id=observation_id)) return None
def processAlgorithm(self, parameters, context, feedback: QgsProcessingFeedback): # Input / Output source = self.parameterAsSource(parameters, self.INPUT, context) (sink, dest_id) = self.create_output_sink(parameters, context, source.sourceCrs()) # Filter parameters observation_type_indices = self.parameterAsEnums( parameters, self.OBSERVATION_TYPE, context) observation_types = list( map(lambda i: self.OBSERVATION_TYPES[i][0], observation_type_indices)) from_date = None from_date_string = self.parameterAsString(parameters, self.FROM_DATE, context) if from_date_string: from_date = datetime.fromisoformat(from_date_string) to_date = None to_date_string = self.parameterAsString(parameters, self.TO_DATE, context) if to_date_string: to_date = datetime.fromisoformat(to_date_string) fire_connection_string = self.settings.value("fire_connection_string") fireDb = FireDb(fire_connection_string, debug=True) features = list(source.getFeatures()) total_num_features = len(features) total_num_features_processed = 0 # for current, feature in enumerate(features): for feature in features: if feedback.isCanceled(): return {} wkt = feature.geometry().asWkt().upper() geometry = Geometry(wkt) observations = fireDb.hent_observationer_naer_geometri( geometri=geometry, afstand=0, tidfra=from_date, tidtil=to_date) pid_list = self.get_pids_from_observations(observations) geometriobjekter = self.get_geometriobjekter_from_pids( fireDb, pid_list) idents = self.get_idents_from_pids(fireDb, pid_list) feedback.setProgressText( "Fandt {antal} observationer".format(antal=len(observations))) feedback.setProgressText("Fandt {antal} geometriobjekter".format( antal=len(geometriobjekter))) feedback.setProgressText( "Fandt {antal} idents".format(antal=len(idents))) for current, observation in enumerate(observations): observation_type_id = observation.observationstypeid if observation_type_id in observation_types: feature = self.create_feature_from_observation( observation, geometriobjekter, idents, feedback) if feature: sink.addFeature(feature, QgsFeatureSink.FastInsert) total_num_features_processed = total_num_features_processed + 1 feedback.setProgress(total_num_features_processed / total_num_features) if feedback.isCanceled(): return {} apply_theme = self.parameterAsBool(parameters, self.APPLY_THEME, context) if apply_theme: style_file = os.path.join(os.path.dirname(__file__), "..", "styles", "observation.qml") alg_params = {"INPUT": dest_id, "STYLE": style_file} processing.run( "qgis:setstyleforvectorlayer", alg_params, context=context, feedback=feedback, is_child_algorithm=True, ) return {self.OUTPUT: dest_id}
def handleAlgorithmResults(alg, context, feedback=None, showResults=True): wrongLayers = [] if feedback is None: feedback = QgsProcessingFeedback() feedback.setProgressText( QCoreApplication.translate('Postprocessing', 'Loading resulting layers')) i = 0 for l, details in context.layersToLoadOnCompletion().items(): if feedback.isCanceled(): return False if len(context.layersToLoadOnCompletion()) > 2: # only show progress feedback if we're loading a bunch of layers feedback.setProgress( 100 * i / float(len(context.layersToLoadOnCompletion()))) try: layer = QgsProcessingUtils.mapLayerFromString(l, context) if layer is not None: layer.setName(details.name) details.project.addMapLayer( context.temporaryLayerStore().takeMapLayer(layer)) else: name = details.name if ProcessingConfig.getSetting( ProcessingConfig.USE_FILENAME_AS_LAYER_NAME): name = os.path.basename(l) dataobjects.load(l, name, alg.crs, RenderingStyles.getStyle(alg.id(), l)) except Exception: QgsMessageLog.logMessage( "Error loading result layer:\n" + traceback.format_exc(), 'Processing', QgsMessageLog.CRITICAL) #wrongLayers.append(out.description()) wrongLayers.append(l) # for out in alg.outputs: # feedback.setProgress(100 * i / float(len(alg.outputs))) # if out.flags() & QgsProcessingParameterDefinition.FlagHidden or not out.open: # continue # if isinstance(out, (OutputRaster, OutputVector, OutputTable)): # try: # layer = QgsProcessingUtils.mapLayerFromString(out.value, context) # if layer: # layer.setName(out.description) # QgsProject.instance().addMapLayer(context.temporaryLayerStore().takeMapLayer(layer)) # else: # if ProcessingConfig.getSetting( # ProcessingConfig.USE_FILENAME_AS_LAYER_NAME): # name = os.path.basename(out.value) # else: # name = out.description # # isRaster = True if isinstance(out, OutputRaster) else False # dataobjects.load(out.value, name, alg.crs, # RenderingStyles.getStyle(alg.id(), out.name), # isRaster) # except Exception: # QgsMessageLog.logMessage("Error loading result layer:\n" + traceback.format_exc(), 'Processing', QgsMessageLog.CRITICAL) # wrongLayers.append(out.description) # elif isinstance(out, OutputHTML): # resultsList.addResult(alg.icon(), out.description, out.value) i += 1 QApplication.restoreOverrideCursor() if wrongLayers: msg = "The following layers were not correctly generated.<ul>" msg += "".join(["<li>%s</li>" % lay for lay in wrongLayers]) + "</ul>" msg += "You can check the log messages to find more information about the execution of the algorithm" feedback.reportError(msg) return len(wrongLayers) == 0
def processAlgorithm(self, parameters, context: QgsProcessingContext, feedback: QgsProcessingFeedback): """Here is where the processing itself takes place.""" feedback.setProgress(0) # init params reach_layer = self.parameterAsVectorLayer(parameters, self.REACH_LAYER, context) wastewater_node_layer = self.parameterAsVectorLayer( parameters, self.WASTEWATER_NODE_LAYER, context) value_expression = self.parameterAsExpression(parameters, self.VALUE_EXPRESSION, context) reach_pk_name = self.parameterAsFields(parameters, self.REACH_PK_NAME, context)[0] node_pk_name = self.parameterAsFields(parameters, self.NODE_PK_NAME, context)[0] node_from_fk_name = self.parameterAsFields(parameters, self.NODE_FROM_FK_NAME, context)[0] node_to_fk_name = self.parameterAsFields(parameters, self.NODE_TO_FK_NAME, context)[0] branch_behavior = self.parameterAsEnum(parameters, self.BRANCH_BEHAVIOR, context) create_loop_layer = self.parameterAsBool(parameters, self.CREATE_LOOP_LAYER, context) if branch_behavior == 0: aggregate_method = lambda values: min(values) if values else 0 elif branch_behavior == 1: aggregate_method = lambda values: max(values) if values else 0 elif branch_behavior == 2: aggregate_method = lambda values: statistics.mean( values) if values else 0 else: aggregate_method = lambda values: feedback.pushError( 'Aggregate method not implemented') # create feature sink fields = wastewater_node_layer.fields() fields.append(QgsField('value', QVariant.Double)) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, fields, QgsWkbTypes.Point, reach_layer.sourceCrs()) loop_sink = None loop_dest_id = None if create_loop_layer: (loop_sink, loop_dest_id) = self.parameterAsSink(parameters, self.LOOP_OUTPUT, context, fields, QgsWkbTypes.Point, reach_layer.sourceCrs()) if sink is None: raise QgsProcessingException( self.invalidSinkError(parameters, self.OUTPUT)) feature_count = reach_layer.featureCount() reaches_by_from_node = dict() reaches_by_id = dict() expression = QgsExpression(value_expression) context = QgsExpressionContext( QgsExpressionContextUtils.globalProjectLayerScopes(reach_layer)) expression.prepare(context) progress = 0 feedback.setProgressText(self.tr('Indexing reaches')) for reach in reach_layer.getFeatures(QgsFeatureRequest()): if reach[node_from_fk_name] == NULL: continue context.setFeature(reach) value = expression.evaluate(context) reach_obj = Reach(reach[node_from_fk_name], reach[node_to_fk_name], value, reach.geometry()) reaches_by_from_node.setdefault(reach_obj.from_id, []).append(reach_obj) reaches_by_id[reach[reach_pk_name]] = reach_obj feedback.setProgress(progress / feature_count * 10) progress += 1 loop_nodes = [] current_feature = 0 calculated_values = {} feedback.setProgressText(self.tr('Analyzing network')) for node in wastewater_node_layer.getFeatures(): from_node_id = node[node_pk_name] processed_nodes = [] times = [] if from_node_id in reaches_by_from_node.keys(): for reach in reaches_by_from_node[from_node_id]: times.append( self.calculate_branch(reach, reaches_by_from_node, reaches_by_id, list(processed_nodes), calculated_values, aggregate_method, loop_nodes, feedback)) if times: time = aggregate_method(times) else: time = 0 current_feature += 1 calculated_values[node[node_pk_name]] = time new_node = QgsFeature(node) new_node.setFields(fields) new_node.setAttributes(node.attributes() + [time]) sink.addFeature(new_node, QgsFeatureSink.FastInsert) if create_loop_layer and from_node_id in loop_nodes: loop_sink.addFeature(node, QgsFeatureSink.FastInsert) feedback.setProgress(10 + current_feature / feature_count * 90) result = {self.OUTPUT: dest_id} if create_loop_layer: result[self.LOOP_OUTPUT] = loop_dest_id return result