def _set_output_layer_style(layerName: str, layer: QgsMapLayer, alg: QgsProcessingAlgorithm, details: 'QgsProcessingContext::LayerDetails', context: QgsProcessingContext, parameters) -> None: """ Set layer style Original code is from python/plugins/processing/gui/Postprocessing.py """ '''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 if parameters: 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 == layerName: outputName = out.name() break style = None if outputName: # If a style with the same name as the outputName exists # in workdir then use it style = os.path.join(context.workdir, outputName + '.qml') if not os.path.exists(style): style = RenderingStyles.getStyle(alg.id(), outputName) LOGGER.debug("Getting style for %s: %s <%s>", alg.id(), outputName, style) # Get defaults styles 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: LOGGER.debug("Adding style '%s' to layer %s (outputName %s)", style, details.name, outputName) layer.loadNamedStyle(style) LOGGER.debug("Layer name set to %s <details name: %s>", layer.name(), details.name)
def __init__(self, algorithm_spec, sdna_path, run_sdna_command): QgsProcessingAlgorithm.__init__(self) self.outputs = [] self.varnames = [] self.outputnames = [] self.selectvaroptions = {} self.sdna_path = sdna_path self.run_sdna_command = run_sdna_command self.algorithm_spec = algorithm_spec
def parse_output_definitions( alg: QgsProcessingAlgorithm, context: MapContext) -> Generator[WPSOutput, None, None]: """ Parse algorithm inputs definitions """ for param in alg.outputDefinitions(): try: yield parse_output_definition(param, alg, context=context) except ProcessingTypeParseError as e: LOGGER.error("%s: unsupported output param %s", alg.id(), e)
def parse_input_definitions( alg: QgsProcessingAlgorithm, context: MapContext) -> Generator[WPSInput, None, None]: """ Parse algorithm inputs definitions """ for param in alg.parameterDefinitions(): try: if not _is_hidden(param): yield parse_input_definition(param, alg, context=context) else: LOGGER.info("%s: dropping hidden param: %s", alg.id(), param.name()) except ProcessingTypeParseError as e: LOGGER.error("%s: unsupported param %s", alg.id(), e)
def write_outputs(alg: QgsProcessingAlgorithm, results: Mapping[str, Any], outputs: Mapping[str, WPSOutput], output_uri: str = None, context: QgsProcessingContext = None) -> None: """ Set wps outputs and write project """ for outdef in alg.outputDefinitions(): out = outputs.get(outdef.name()) if out: processing_to_output(results[outdef.name()], outdef, out, output_uri, context) if context is not None: context.write_result(context.workdir, alg.name())
def parse_file_output( outdef: QgsProcessingOutputDefinition, kwargs, alg: QgsProcessingAlgorithm=None ) -> ComplexOutput: """ Parse file output definition QgsProcessingOutputDefinition metadata will be checked to get wps parameter settings: - 'wps:as_reference': boolean, True if the file will be sent as reference. If false, the file will included in the body of the response. Default is True. """ as_reference = confservice.getboolean('server','outputfile_as_reference') if isinstance(outdef, QgsProcessingOutputHtml): mime = mimetypes.types_map.get('.html') return ComplexOutput(supported_formats=[Format(mime)],**kwargs) elif isinstance(outdef, QgsProcessingOutputFile): # Try to get a corresponding inputFileDefinition # See https://qgis.org/pyqgis/master/core/QgsProcessingParameterFileDestination.html mime = None if alg: inputdef = alg.parameterDefinition(outdef.name()) if isinstance(inputdef, QgsProcessingParameterFileDestination): mime = mimetypes.types_map.get("."+inputdef.defaultFileExtension()) as_reference = inputdef.metadata().get('wps:as_reference',as_reference) if mime is None: LOGGER.warning("Cannot set file type for output %s", outdef.name()) mime = "application/octet-stream" return ComplexOutput(supported_formats=[Format(mime)], as_reference=as_reference, **kwargs)
def parse_file_output(outdef: QgsProcessingOutputDefinition, kwargs, alg: QgsProcessingAlgorithm = None) -> ComplexOutput: """ Parse file output definition """ if isinstance(outdef, QgsProcessingOutputHtml): mime = mimetypes.types_map.get('.html') return ComplexOutput(supported_formats=[Format(mime)], **kwargs) elif isinstance(outdef, QgsProcessingOutputFile): # Try to get a corresponding inputFileDefinition mime = None if alg: inputdef = alg.parameterDefinition(outdef.name()) if isinstance(inputdef, QgsProcessingParameterFileDestination): mime = mimetypes.types_map.get("." + inputdef.defaultFileExtension()) if mime is None: LOGGER.warning("Cannot set file type for output %s", outdef.name()) mime = "application/octet-stream" return ComplexOutput(supported_formats=[Format(mime)], **kwargs)
def input_to_processing(identifier: str, inp: WPSInput, alg: QgsProcessingAlgorithm, context: ProcessingContext) -> Tuple[str, Any]: """ Convert wps input to processing param see https://qgis.org/api/classQgsProcessingOutputLayerDefinition.html see https://qgis.org/api/qgsprocessingparameters_8cpp_source.html#L272 see ./python/plugins/processing/tools/general.py:111 see ./python/plugins/processing/gui/Postprocessing.py:50 see ./python/plugins/processing/core/Processing.py:126 """ param = alg.parameterDefinition(identifier) value = layersio.get_processing_value(param, inp, context) or \ filesio.get_processing_value(param, inp, context) or \ datetimeio.get_processing_value(param, inp, context) or \ geometryio.get_processing_value(param, inp, context) or \ get_processing_value(param, inp, context) return param.name(), value
def flags(self): if self._flags is not None: return QgsProcessingAlgorithm.Flags(self._flags) else: return QgsProcessingAlgorithm.flags(self)
def validateInputCrs(self, parameters, context): if self.noCRSWarning: return True else: return QgsProcessingAlgorithm.validateInputCrs(self, parameters, context)
def input_to_processing(identifier: str, inp: WPSInput, alg: QgsProcessingAlgorithm, context: ProcessingContext) -> Tuple[str, Any]: """ Convert wps input to processing param see https://qgis.org/api/classQgsProcessingOutputLayerDefinition.html see https://qgis.org/api/qgsprocessingparameters_8cpp_source.html#L272 see ./python/plugins/processing/tools/general.py:111 see ./python/plugins/processing/gui/Postprocessing.py:50 see ./python/plugins/processing/core/Processing.py:126 """ param = alg.parameterDefinition(identifier) typ = param.type() if isinstance(param, DESTINATION_LAYER_TYPES): # Do not supports memory: layer since we are storing destination project to file param.setSupportsNonFileBasedOutput(False) # Enforce pushing created layers to layersToLoadOnCompletion list sink = "./%s.%s" % (param.name(), param.defaultFileExtension()) value = QgsProcessingOutputLayerDefinition(sink, context.destination_project) value.destinationName = inp[0].data elif isinstance(param, QgsProcessingParameterFeatureSource): # Support feature selection value, has_selection = parse_layer_spec(inp[0].data, context, allow_selection=True) value = QgsProcessingFeatureSourceDefinition( value, selectedFeaturesOnly=has_selection) elif isinstance(param, INPUT_LAYER_TYPES): if len(inp) > 1: value = [parse_layer_spec(i.data, context)[0] for i in inp] else: value, _ = parse_layer_spec(inp[0].data, context) elif typ == 'enum': # XXX Processing wants the index of the value in option list if param.allowMultiple() and len(inp) > 1: opts = param.options() value = [opts.index(d.data) for d in inp] else: value = param.options().index(inp[0].data) elif typ == 'extent': value = input_to_extent(inp) elif typ == 'crs': # XXX CRS may be expressed as EPSG (or QgsProperty ?) value = inp[0].data elif typ in ('fileDestination', 'folderDestination'): # Normalize path value = basename(normpath(inp[0].data)) if value != inp[0].data: LOGGER.warning( "Value for file or folder destination '%s' has been truncated from '%s' to '%s'", identifier, inp[0].data, value) elif len(inp): # Return raw value value = inp[0].data else: # Return undefined value if not _is_optional(param): LOGGER.warning("Required input %s has no value", identifier) value = None return param.name(), value
def _is_hidden( a: QgsProcessingAlgorithm ) -> bool: return (int(a.flags()) & QgsProcessingAlgorithm.FlagHideFromToolbox) !=0
def __init__(self): self.curr_suffix = "" QgsProcessingAlgorithm.__init__(self)
def __init__(self, descriptionfile): QgsProcessingAlgorithm.__init__(self) self.descriptionFile = descriptionfile self.defineCharacteristicsFromFile()
def validateInputCrs(self, parameters, context): if self.noCRSWarning: return True else: return QgsProcessingAlgorithm.validateInputCrs( self, parameters, context)
def __init__(self, settings): QgsProcessingAlgorithm.__init__(self) self.settings = settings