Beispiel #1
0
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
Beispiel #3
0
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