def get_processing_value(param: QgsProcessingParameterDefinition, inp: WPSInput, context: ProcessingContext) -> Any: """ Return processing values from WPS input data """ if isinstance(param, DESTINATION_LAYER_TYPES): # # Destination layer: a new layer is created as file with the input name. # Do not supports memory layer because we need persistence # param.setSupportsNonFileBasedOutput(False) # # Enforce pushing created layers to layersToLoadOnCompletion list # i.e layer will be stored in the destination project # get extension from input metadata (should always exist for destination) extension = get_metadata(inp[0], 'processing:extension')[0] destination = inp[0].data if confservice.getboolean('processing', 'unsafe.raw_destination_input_sink'): sink, destination = parse_root_destination_path( param, destination, extension) else: # Use canonical file name sink = "./%s.%s" % (get_valid_filename(param.name()), extension) value = QgsProcessingOutputLayerDefinition(sink, context.destination_project) value.destinationName = destination LOGGER.debug("Handling destination layer: %s, details name: %s", param.name(), value.destinationName) 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) else: value = None return value
def processAlgorithm(self, parameters, context, model_feedback): feedback = QgsProcessingMultiStepFeedback(4, model_feedback) results = {} outputs = {} sections = self.parameterAsSource(parameters, self.SECTIONS, context) # Retreive first section longitudinal abscissa request = (QgsFeatureRequest().setFlags( QgsFeatureRequest.NoGeometry | QgsFeatureRequest.SubsetOfAttributes).setSubsetOfAttributes( ["abs_long"], sections.fields()).addOrderBy('"sec_id"', True, True).setLimit(1)) first_section = next(sections.getFeatures(request)) first_abs_long = first_section.attribute("abs_long") # Lines to points alg_params = { "INPUT": parameters[self.SECTIONS], "OUTPUT": QgsProcessingUtils.generateTempFilename("lines_to_points.shp"), } outputs["LinesToPoints"] = processing.run( "precourlis:lines_to_points", alg_params, context=context, feedback=feedback, is_child_algorithm=True, ) current = outputs["LinesToPoints"]["OUTPUT"] feedback.setCurrentStep(1) if feedback.isCanceled(): return {} # Interpolate points alg_params = { "SECTIONS": current, "AXIS": parameters[self.AXIS], "CONSTRAINT_LINES": parameters.get(self.CONSTRAINT_LINES), "LONG_STEP": parameters[self.LONG_STEP], "LAT_STEP": parameters[self.LAT_STEP], "ATTR_CROSS_SECTION": "sec_id", "OUTPUT": QgsProcessingUtils.generateTempFilename("interpolate_points.shp"), } outputs["InterpolatePoints"] = processing.run( "precourlis:interpolate_points", alg_params, context=context, feedback=feedback, is_child_algorithm=True, ) current = outputs["InterpolatePoints"]["OUTPUT"] feedback.setCurrentStep(2) if feedback.isCanceled(): return {} # assignprojection alg_params = { "INPUT": current, "CRS": sections.sourceCrs(), "OUTPUT": QgsProcessing.TEMPORARY_OUTPUT, } outputs["AssignProjection"] = processing.run( "native:assignprojection", alg_params, context=context, feedback=feedback, is_child_algorithm=True, ) current = outputs["AssignProjection"]["OUTPUT"] feedback.setCurrentStep(3) if feedback.isCanceled(): return {} output = QgsProcessingOutputLayerDefinition(parameters[self.OUTPUT]) output.destinationName = self.tr("Interpolated") # Points to lines alg_params = { "INPUT": current, "AXIS": parameters[self.AXIS], "FIRST_SECTION_ABS_LONG": first_abs_long, "GROUP_FIELD": "abs_long", "ORDER_FIELD": "p_id", "OUTPUT": output, } outputs["PointsToLines"] = processing.run( "precourlis:points_to_lines", alg_params, context=context, feedback=feedback, is_child_algorithm=True, ) current = outputs["PointsToLines"]["OUTPUT"] results["OUTPUT"] = current return results
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