Exemple #1
0
    def exportRasterLayer(self, parameterName, layer):
        global sessionExportedLayers
        if layer.source() in sessionExportedLayers:
            exportedLayer = sessionExportedLayers[layer.source()]
            if os.path.exists(exportedLayer):
                self.exportedLayers[parameterName] = exportedLayer
                return None
            else:
                del sessionExportedLayers[layer.source()]

        if layer:
            filename = layer.name()
        else:
            filename = os.path.basename(layer.source())

        validChars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789:'
        filename = ''.join(c for c in filename if c in validChars)

        if len(filename) == 0:
            filename = 'layer'

        destFilename = QgsProcessingUtils.generateTempFilename(filename + '.sgrd')
        sessionExportedLayers[layer.source()] = destFilename
        self.exportedLayers[parameterName] = destFilename

        return 'io_gdal 0 -TRANSFORM 1 -RESAMPLING 3 -GRIDS "{}" -FILES "{}"'.format(destFilename, layer.source())
Exemple #2
0
 def writeLayerParameterToTextFile(filename, alg, parameters, parameter_name, context, quote=True, executing=False):
     listFile = QgsProcessingUtils.generateTempFilename(filename)
     with open(listFile, 'w') as f:
         if executing:
             layers = []
             for l in alg.parameterAsLayerList(parameters, parameter_name, context):
                 if quote:
                     layers.append('"' + l.source() + '"')
                 else:
                     layers.append(l.source())
             f.write('\n'.join(layers))
     return listFile
Exemple #3
0
def exportVectorLayer(layer, supported=None):
    """Takes a QgsVectorLayer and returns the filename to refer to it,
    which allows external apps which support only file-based layers to
    use it. It performs the necessary export in case the input layer
    is not in a standard format suitable for most applications, it is
    a remote one or db-based (non-file based) one, or if there is a
    selection and it should be used, exporting just the selected
    features.

    Currently, the output is restricted to shapefiles, so anything
    that is not in a shapefile will get exported. It also export to
    a new file if the original one contains non-ascii characters.
    """

    supported = supported or ["shp"]
    settings = QgsSettings()
    systemEncoding = settings.value('/UI/encoding', 'System')

    output = getTempFilename('shp')
    basename = removeInvalidChars(os.path.basename(layer.source()))
    if basename:
        if not basename.endswith("shp"):
            basename = os.path.splitext(basename)[0] + ".shp"
        output = QgsProcessingUtils.generateTempFilename(basename)
    else:
        output = getTempFilename("shp")
    useSelection = False # TODO ProcessingConfig.getSetting(ProcessingConfig.USE_SELECTED)
    if useSelection and layer.selectedFeatureCount() != 0:
        writer = QgsVectorFileWriter(output, systemEncoding,
                                     layer.fields(),
                                     layer.wkbType(), layer.crs())
        selection = layer.selectedFeatures()
        for feat in selection:
            writer.addFeature(feat, QgsFeatureSink.FastInsert)
        del writer
        return output
    else:
        if not os.path.splitext(layer.source())[1].lower() in supported:
            writer = QgsVectorFileWriter(
                output, systemEncoding,
                layer.fields(), layer.wkbType(),
                layer.crs()
            )
            for feat in layer.getFeatures():
                writer.addFeature(feat, QgsFeatureSink.FastInsert)
            del writer
            return output
        else:
            return layer.source()
Exemple #4
0
    def getCompatibleFileName(self, alg):
        """Returns a filename that is compatible with the algorithm
        that is going to generate this output.

        If the algorithm supports the file format of the current
        output value, it returns that value. If not, it returns a
        temporary file with a supported file format, to be used to
        generate the output result.
        """

        ext = self.value[self.value.rfind('.') + 1:]
        if ext in alg.provider().supportedOutputTableExtensions():
            return self.value
        else:
            if self.compatible is None:
                self.compatible = QgsProcessingUtils.generateTempFilename(
                    self.name + '.' + alg.provider().supportedOutputTableExtensions()[0])
            return self.compatible
Exemple #5
0
    def getCompatibleFileName(self, alg):
        """Returns a filename that is compatible with the algorithm
        that is going to generate this output.

        If the algorithm supports the file format of the current
        output value, it returns that value. If not, it returns a
        temporary file with a supported file format, to be used to
        generate the output result.
        """

        ext = self.value[self.value.rfind('.') + 1:]
        if ext in alg.provider().supportedOutputTableExtensions():
            return self.value
        else:
            if self.compatible is None:
                self.compatible = QgsProcessingUtils.generateTempFilename(
                    self.name + '.' +
                    alg.provider().supportedOutputTableExtensions()[0])
            return self.compatible
Exemple #6
0
 def writeLayerParameterToTextFile(filename,
                                   alg,
                                   parameters,
                                   parameter_name,
                                   context,
                                   quote=True,
                                   executing=False):
     listFile = QgsProcessingUtils.generateTempFilename(filename)
     with open(listFile, 'w') as f:
         if executing:
             layers = []
             for l in alg.parameterAsLayerList(parameters, parameter_name,
                                               context):
                 if quote:
                     layers.append('"' + l.source() + '"')
                 else:
                     layers.append(l.source())
             f.write('\n'.join(layers))
     return listFile
    def exportRasterLayer(self, source):
        global sessionExportedLayers

        if source in sessionExportedLayers:
            self.exportedLayers[source] = sessionExportedLayers[source]
            return None

        fileName = os.path.basename(source)
        validChars = \
            "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
        fileName = ''.join(c for c in fileName if c in validChars)
        if len(fileName) == 0:
            fileName = 'layer'

        destFilename = QgsProcessingUtils.generateTempFilename("{}.asc".format(fileName))
        self.exportedLayers[source] = destFilename
        sessionExportedLayers[source] = destFilename

        return "gdal_translate -of AAIGrid {} {}".format(source, destFilename)
Exemple #8
0
 def runGrassDissolve(self,
                      inputLyr,
                      context,
                      feedback=None,
                      column=None,
                      outputLyr=None,
                      onFinish=None):
     """
     Runs dissolve from GRASS algorithm provider.
     :param inputLyr: (QgsVectorLayer) layer to be dissolved.
     :param context: (QgsProcessingContext) processing context.
     :param feedback: (QgsProcessingFeedback) QGIS object to keep track of progress/cancelling option.
     :param column: ()
     :param outputLyr: (str) URI to output layer.
     :param onFinish: (list-of-str) sequence of algs to be run after dissolve is executed, in execution order.
     :return: (QgsVectorLayer) dissolved (output) layer.
     """
     parameters = {
         'GRASS_MIN_AREA_PARAMETER':
         0.0001,
         'GRASS_OUTPUT_TYPE_PARAMETER':
         0,
         'GRASS_REGION_PARAMETER':
         None,
         'GRASS_SNAP_TOLERANCE_PARAMETER':
         -1,
         'GRASS_VECTOR_DSCO':
         '',
         'GRASS_VECTOR_EXPORT_NOCAT':
         False,
         'GRASS_VECTOR_LCO':
         '',
         'column':
         column,
         'input':
         inputLyr,
         'output':
         outputLyr or QgsProcessingUtils.generateTempFilename('output.shp')
     }
     output = processing.run('grass7:v.dissolve', parameters, onFinish,
                             feedback, context)
     return self.getGrassReturn(output, context)
Exemple #9
0
    def exportRasterLayer(self, source):
        global sessionExportedLayers

        if source in sessionExportedLayers:
            self.exportedLayers[source] = sessionExportedLayers[source]
            return None

        fileName = os.path.basename(source)
        validChars = \
            "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
        fileName = ''.join(c for c in fileName if c in validChars)
        if len(fileName) == 0:
            fileName = 'layer'

        destFilename = QgsProcessingUtils.generateTempFilename(
            "{}.asc".format(fileName))
        self.exportedLayers[source] = destFilename
        sessionExportedLayers[source] = destFilename

        return "gdal_translate -of AAIGrid {} {}".format(source, destFilename)
Exemple #10
0
    def getCompatibleFileName(self, alg):
        """
        Returns a filename that is compatible with the algorithm
        that is going to generate this output. If the algorithm
        supports the file format of the current output value, it
        returns that value. If not, it returns a temporary file with
        a supported file format, to be used to generate the output
        result.
        """

        ext = self.value[self.value.rfind('.') + 1:]
        if ext in alg.provider().supportedOutputRasterLayerExtensions():
            return self.value
        else:
            if self.compatible is None:
                supported = alg.provider().supportedOutputRasterLayerExtensions()
                default = ProcessingConfig.getSetting(ProcessingConfig.DEFAULT_OUTPUT_RASTER_LAYER_EXT, True)
                ext = default if default in supported else supported[0]
                self.compatible = QgsProcessingUtils.generateTempFilename(self.name + '.' + ext)
            return self.compatible
Exemple #11
0
    def getCompatibleFileName(self, alg):
        """
        Returns a filename that is compatible with the algorithm
        that is going to generate this output. If the algorithm
        supports the file format of the current output value, it
        returns that value. If not, it returns a temporary file with
        a supported file format, to be used to generate the output
        result.
        """

        ext = self.value[self.value.rfind('.') + 1:]
        if ext in alg.provider().supportedOutputRasterLayerExtensions():
            return self.value
        else:
            if self.compatible is None:
                supported = alg.provider().supportedOutputRasterLayerExtensions()
                default = ProcessingConfig.getSetting(ProcessingConfig.DEFAULT_OUTPUT_RASTER_LAYER_EXT, True)
                ext = default if default in supported else supported[0]
                self.compatible = QgsProcessingUtils.generateTempFilename(self.name + '.' + ext)
            return self.compatible
Exemple #12
0
    def prepare_sections(self, parameters, context, feedback):
        sections = self.parameterAsSource(parameters, self.SECTIONS, context)

        # Prefix layer fields by "Z" for TatooineMesher
        file = PreCourlisFileLine(sections)
        alg_params = {
            "INPUT":
            parameters[self.SECTIONS],
            "FIELDS_MAPPING": [
                {
                    "name": "sec_id",
                    "type": QVariant.Int,
                    "expression": '"sec_id"'
                },
                {
                    "name": "p_id",
                    "type": QVariant.Int,
                    "expression": '"p_id"'
                },
                {
                    "name": "Zzfond",
                    "type": QVariant.Double,
                    "expression": '"zfond"'
                },
            ] + [{
                "name": "Z{}".format(layer),
                "type": QVariant.Double,
                "expression": '"{}"'.format(layer),
            } for layer in file.layers()],
            "OUTPUT":
            QgsProcessingUtils.generateTempFilename("tatooine_input.shp"),
        }
        outputs = processing.run(
            "qgis:refactorfields",
            alg_params,
            context=context,
            feedback=feedback,
            is_child_algorithm=True,
        )
        return outputs["OUTPUT"]
Exemple #13
0
 def overlayCoverage(self, coverage, context):
     output = QgsProcessingUtils.generateTempFilename('output.shp')
     parameters = {
         'ainput': coverage,
         'atype': 0,
         'binput': coverage,
         'btype': 0,
         'operator': 0,
         'snap': 0,
         '-t': False,
         'output': output,
         'GRASS_REGION_PARAMETER': None,
         'GRASS_SNAP_TOLERANCE_PARAMETER': -1,
         'GRASS_MIN_AREA_PARAMETER': 0.0001,
         'GRASS_OUTPUT_TYPE_PARAMETER': 0,
         'GRASS_VECTOR_DSCO': '',
         'GRASS_VECTOR_LCO': ''
     }
     x = processing.run('grass7:v.overlay', parameters, context=context)
     lyr = QgsProcessingUtils.mapLayerFromString(x['output'], context)
     lyr.setCrs(coverage.crs())
     return lyr
Exemple #14
0
 def exportRasterLayer(self, source):
     global sessionExportedLayers
     context = dataobjects.createContext()
     if source in sessionExportedLayers:
         exportedLayer = sessionExportedLayers[source]
         if os.path.exists(exportedLayer):
             self.exportedLayers[source] = exportedLayer
             return None
         else:
             del sessionExportedLayers[source]
     layer = QgsProcessingUtils.mapLayerFromString(source, context, False)
     if layer:
         filename = str(layer.name())
     else:
         filename = os.path.basename(source)
     validChars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789:'
     filename = ''.join(c for c in filename if c in validChars)
     if len(filename) == 0:
         filename = 'layer'
     destFilename = QgsProcessingUtils.generateTempFilename(filename + '.sgrd')
     self.exportedLayers[source] = destFilename
     sessionExportedLayers[source] = destFilename
     return 'io_gdal 0 -TRANSFORM 1 -RESAMPLING 3 -GRIDS "' + destFilename + '" -FILES "' + source + '"'
Exemple #15
0
 def exportRasterLayer(self, source):
     global sessionExportedLayers
     context = dataobjects.createContext()
     if source in sessionExportedLayers:
         exportedLayer = sessionExportedLayers[source]
         if os.path.exists(exportedLayer):
             self.exportedLayers[source] = exportedLayer
             return None
         else:
             del sessionExportedLayers[source]
     layer = QgsProcessingUtils.mapLayerFromString(source, context, False)
     if layer:
         filename = str(layer.name())
     else:
         filename = os.path.basename(source)
     validChars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789:'
     filename = ''.join(c for c in filename if c in validChars)
     if len(filename) == 0:
         filename = 'layer'
     destFilename = QgsProcessingUtils.generateTempFilename(filename + '.sgrd')
     self.exportedLayers[source] = destFilename
     sessionExportedLayers[source] = destFilename
     return 'io_gdal 0 -TRANSFORM 1 -RESAMPLING 3 -GRIDS "' + destFilename + '" -FILES "' + source + '"'
    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 processAlgorithm(self, parameters, context, feedback):
     # Parameters
     reporting_mode = self.parameterAsEnum(parameters, self.REPORTING_MODE,
                                           context)
     lighting_source, lighting_layer = qgsTreatments.parameterAsSourceLayer(
         self, parameters, self.LIGHTING, context, feedback=feedback)
     self.fieldname = self.parameterAsString(parameters, FDA.FLUX_FIELD,
                                             context)
     roads_source, roads_layer = qgsTreatments.parameterAsSourceLayer(
         self, parameters, RE.ROADS, context, feedback=feedback)
     cadastre_source, cadastre_layer = qgsTreatments.parameterAsSourceLayer(
         self, parameters, RE.CADASTRE, context, feedback=feedback)
     hydro_source, hydro_layer = qgsTreatments.parameterAsSourceLayer(
         self, parameters, self.SURFACE_HYDRO, context, feedback=feedback)
     extent_source, extent_layer = qgsTreatments.parameterAsSourceLayer(
         self, parameters, RE.EXTENT_LAYER, context, feedback=feedback)
     clip_distance = self.parameterAsDouble(parameters, self.CLIP_DISTANCE,
                                            context)
     dissolve_step = self.parameterAsEnum(parameters, self.DISSOLVE_STEP,
                                          context)
     include_layers = self.parameterAsLayerList(parameters,
                                                RE.INCLUDE_LAYERS, context)
     diff_layers = self.parameterAsLayerList(parameters, RE.DIFF_LAYERS,
                                             context)
     output_surface = self.parameterAsOutputLayer(parameters,
                                                  self.OUTPUT_SURFACE,
                                                  context)
     self.output = self.parameterAsOutputLayer(parameters, self.OUTPUT,
                                               context)
     out_linear = reporting_mode == 1
     # Init steps
     nb_steps = 3 if out_linear else 2
     mf = QgsProcessingMultiStepFeedback(nb_steps, feedback)
     if out_linear:
         id_field = 'ID'
         if id_field not in roads_layer.fields().names():
             raise QgsProcessingException("No 'ID' field in roads layer")
     # Surface
     surface_params = parameters.copy()
     surface_params[RE.ROADS] = roads_layer
     surface_params[RE.CADASTRE] = cadastre_layer
     surface_params[RE.EXTENT_LAYER] = extent_layer
     surface_params[RE.INCLUDE_LAYERS] = include_layers
     surface_params[RE.DIFF_LAYERS] = diff_layers
     if hydro_source:
         surface_params[RE.DIFF_LAYERS] += [hydro_layer]
     surface_params[RE.DISSOLVE] = dissolve_step == 0
     surface_params[RE.OUTPUT] = output_surface
     surface = qgsTreatments.applyProcessingAlg('LPT',
                                                RE.ALG_NAME,
                                                surface_params,
                                                context=context,
                                                feedback=mf)
     mf.setCurrentStep(1)
     # Light surfacic density
     qgsTreatments.fixShapefileFID(surface, context=context, feedback=mf)
     density_params = parameters.copy()
     density_params[FDA.LIGHTING] = lighting_layer
     # density_params[FDA.REPORTING] = reporting_layer
     density_params[FDA.CLIP_DISTANCE] = clip_distance
     density_params[FDA.SURFACE] = surface
     density_params[RE.ROADS] = roads_layer
     density_params[FDA.DISSOLVE] = dissolve_step == 1
     density_params[FDA.SKIP_EMPTY] = True
     if out_linear:
         output_surf = QgsProcessingUtils.generateTempFilename(
             'output_surface.gpkg')
         density_params[FDA.REPORTING_FIELDS] = [id_field]
         density_params[FDA.OUTPUT] = output_surf
     else:
         density_params[FDA.OUTPUT] = self.output
     self.out_id = qgsTreatments.applyProcessingAlg('LPT',
                                                    DSFLSurface.ALG_NAME,
                                                    density_params,
                                                    context=context,
                                                    feedback=mf)
     mf.setCurrentStep(2)
     # Join if output linear
     if out_linear:
         copy_fields = [
             FDA.NB_LAMPS, FDA.FLUX_SUM, FDA.SURFACE_AREA, FDA.FLUX_DEN
         ]
         self.out_id = qgsTreatments.joinByAttribute(
             roads_layer,
             id_field,
             output_surf,
             id_field,
             copy_fields=copy_fields,
             out_layer=self.output,
             context=context,
             feedback=mf)
         mf.setCurrentStep(3)
     return {self.OUTPUT: self.output}
 def processAlgorithm(self, parameters, context, feedback):
     # Params
     reporting_mode = self.parameterAsEnum(parameters, self.REPORTING_MODE,
                                           context)
     lighting_source, lighting_layer = qgsTreatments.parameterAsSourceLayer(
         self, parameters, self.LIGHTING, context, feedback=feedback)
     self.fieldname = self.parameterAsString(parameters, FDA.FLUX_FIELD,
                                             context)
     surface_source, surface_layer = qgsTreatments.parameterAsSourceLayer(
         self, parameters, self.SURFACE, context, feedback=feedback)
     roads_source, roads_layer = qgsTreatments.parameterAsSourceLayer(
         self, parameters, RE.ROADS, context, feedback=feedback)
     # Advanced params
     clip_distance = self.parameterAsDouble(parameters, self.CLIP_DISTANCE,
                                            context)
     # Outputs
     self.output = self.parameterAsOutputLayer(parameters, self.OUTPUT,
                                               context)
     out_linear = reporting_mode == 1
     # Init steps
     nb_steps = 3 if out_linear else 2
     mf = QgsProcessingMultiStepFeedback(nb_steps, feedback)
     if out_linear:
         id_field = 'ID'
         if id_field not in roads_layer.fields().names():
             raise QgsProcessingException("No 'ID' field in roads layer")
     qgsTreatments.fixShapefileFID(surface_layer,
                                   context=context,
                                   feedback=feedback)
     # Reporting
     reporting_layer = QgsProcessingUtils.generateTempFilename(
         'reporting.gpkg')
     if reporting_mode == 3:  # voronoi
         if qgsUtils.isMultipartLayer(lighting_layer):
             in_voronoi = QgsProcessingUtils.generateTempFilename(
                 'lighting_single.gpkg')
             qgsTreatments.multiToSingleGeom(lighting_layer,
                                             in_voronoi,
                                             context=context,
                                             feedback=mf)
         else:
             in_voronoi = lighting_layer
         qgsTreatments.applyVoronoi(in_voronoi,
                                    reporting_layer,
                                    context=context,
                                    feedback=mf)
     else:
         reporting_params = parameters.copy()
         reporting_params[RR.ROADS] = roads_layer
         reporting_params[RR.BUFFER_EXPR] = RR.DEFAULT_BUFFER_EXPR
         reporting_params[RR.NAME_FIELD] = RR.DEFAULT_NAME_FIELD
         reporting_params[RR.END_CAP_STYLE] = 1  # Flat buffer cap style
         reporting_params[RR.DISSOLVE] = reporting_mode in [2]  # Roads
         reporting_params[RR.OUTPUT] = reporting_layer
         qgsTreatments.applyProcessingAlg('LPT',
                                          RR.ALG_NAME,
                                          reporting_params,
                                          context=context,
                                          feedback=mf)
     mf.setCurrentStep(1)
     # Light surfacic density
     density_params = parameters.copy()
     density_params[FDA.LIGHTING] = lighting_layer
     density_params[FDA.REPORTING] = reporting_layer
     density_params[FDA.CLIP_DISTANCE] = clip_distance
     density_params[FDA.SURFACE] = surface_layer
     if out_linear:
         output_surf = QgsProcessingUtils.generateTempFilename(
             'output_surface.gpkg')
         density_params[FDA.REPORTING_FIELDS] = [id_field]
         density_params[FDA.OUTPUT] = output_surf
     else:
         density_params[FDA.OUTPUT] = self.output
     self.out_id = qgsTreatments.applyProcessingAlg('LPT',
                                                    FDA.ALG_NAME,
                                                    density_params,
                                                    context=context,
                                                    feedback=mf)
     mf.setCurrentStep(3)
     # Join if output linear
     if out_linear:
         copy_fields = [
             FDA.NB_LAMPS, FDA.FLUX_SUM, FDA.SURFACE_AREA, FDA.FLUX_DEN
         ]
         self.out_id = qgsTreatments.joinByAttribute(
             roads_layer,
             id_field,
             output_surf,
             id_field,
             copy_fields=copy_fields,
             out_layer=self.output,
             context=context,
             feedback=mf)
     return {self.OUTPUT: self.output}
    def processAlgorithm(self, parameters, context, model_feedback):
        # Use a multi-step feedback, so that individual child algorithm progress reports are adjusted for the
        # overall progress through the model
        feedback = QgsProcessingMultiStepFeedback(7, model_feedback)
        results = {}
        outputs = {}

        iter = 1
        feedback.setCurrentStep(iter)
        if feedback.isCanceled():
            return {}
        iter = iter + 1


        # lasground1
        alg_params = {
            'ADDITIONAL_OPTIONS': '',
            'BY_FLIGHTLINE': False,
            'CPU64': False,
            'GRANULARITY': 4,
            'GUI': False,
            'HORIZONTAL_FEET': False,
            'IGNORE_CLASS1': 8,
            'INPUT_LASLAZ': parameters['InputFilelaslaz'],
            'NO_BULGE': False,
            'OUTPUT_LASLAZ': QgsProcessingUtils.generateTempFilename('lasground1.laz'),
            'TERRAIN': 4,
            'VERBOSE': True,
            'VERTICAL_FEET': False
        }
        outputs['Lasground1'] = processing.run('LAStools:lasground', alg_params, context=context, feedback=feedback,
                                               is_child_algorithm=True)
        lasground1file = alg_params['OUTPUT_LASLAZ']

        feedback.setCurrentStep(iter)
        if feedback.isCanceled():
            return {}
        iter = iter + 1

        # lasheight
        alg_params = {
            'ADDITIONAL_OPTIONS': '-ignore_class 0 1 3 4 5 6 7 8 9 10 11 12',
            'CPU64': False,
            'DROP_ABOVE': False,
            'DROP_ABOVE_HEIGHT': 100,
            'DROP_BELOW': False,
            'DROP_BELOW_HEIGHT': -2,
            'GUI': False,
            'IGNORE_CLASS1': 0,
            'IGNORE_CLASS2': 0,
            'INPUT_LASLAZ': lasground1file,
            'OUTPUT_LASLAZ': QgsProcessingUtils.generateTempFilename('lasheight.laz'),
            'REPLACE_Z': False,
            'VERBOSE': True
        }

        lasheightfile = alg_params['OUTPUT_LASLAZ']
        outputs['Lasheight'] = processing.run('LAStools:lasheight', alg_params, context=context, feedback=feedback,
                                              is_child_algorithm=True)

        feedback.setCurrentStep(iter)
        if feedback.isCanceled():
            return {}
        iter = iter + 1

        # lasclassify
        alg_params = {
            'ADDITIONAL_OPTIONS': '-small_trees',
            'CPU64': False,
            'GUI': False,
            'HORIZONTAL_FEET': False,
            'IGNORE_CLASS1': 0,
            'IGNORE_CLASS2': 0,
            'INPUT_LASLAZ': lasheightfile,
            'OUTPUT_LASLAZ': QgsProcessingUtils.generateTempFilename('lasclassify.laz'),
            'VERBOSE': True,
            'VERTICAL_FEET': False
        }
        lasclassifyfile = alg_params['OUTPUT_LASLAZ']
        outputs['Lasclassify'] = processing.run('LAStools:lasclassify', alg_params, context=context, feedback=feedback,
                                                is_child_algorithm=True)

        feedback.setCurrentStep(iter)
        if feedback.isCanceled():
            return {}
        iter = iter + 1


        if parameters['LowNoise']:
            #lasnoise
            alg_params = {
                'ADDITIONAL_OPTIONS': '-ignore_class 3; -ignore_class 4; -ignore_class 6;',
                'CLASSIFY_AS': 7,
                'CPU64': False,
                'GUI': False,
                'IGNORE_CLASS1': 0,
                'IGNORE_CLASS2': 0,
                'INPUT_LASLAZ': lasclassifyfile,
                'ISOLATED': 2,
                'OPERATION': 0,
                'STEP_XY': 0.5,
                'STEP_Z': 0.5,
                'VERBOSE': False,
                'OUTPUT_LASLAZ': QgsProcessingUtils.generateTempFilename('lasnoise.laz')
            }
            lasnoise = alg_params['OUTPUT_LASLAZ']
            outputs['lasnoise'] = processing.run('LAStools:lasnoise', alg_params, context=context, feedback=feedback,
                                                 is_child_algorithm=True)
        else:
            lasnoise = lasclassifyfile

        feedback.setCurrentStep(iter)
        if feedback.isCanceled():
            return {}
        iter = iter + 1

        # lasground2
        alg_params = {
            'ADDITIONAL_OPTIONS': '-ignore_class 6 7',
            'BY_FLIGHTLINE': False,
            'CPU64': False,
            'GRANULARITY': 4,
            'GUI': False,
            'HORIZONTAL_FEET': False,
            'IGNORE_CLASS1': 0,
            'INPUT_LASLAZ': lasnoise,
            'NO_BULGE': False,
            'OUTPUT_LASLAZ': QgsProcessingUtils.generateTempFilename('lasground2.laz'),
            'TERRAIN': 1,
            'VERBOSE': True,
            'VERTICAL_FEET': False
        }
        lasground2file = alg_params['OUTPUT_LASLAZ']
        outputs['Lasground2'] = processing.run('LAStools:lasground', alg_params, context=context, feedback=feedback,
                                               is_child_algorithm=True)

        feedback.setCurrentStep(iter)
        if feedback.isCanceled():
            return {}
        iter = iter + 1

        # lasheight_classify
        alg_params = {
            'ADDITIONAL_OPTIONS': '',
            'CLASSIFY_ABOVE': 6,
            'CLASSIFY_ABOVE_HEIGHT': 2,
            'CLASSIFY_BELOW': 8,
            'CLASSIFY_BELOW_HEIGHT': -0.25,
            'CLASSIFY_BETWEEN1': 3,
            'CLASSIFY_BETWEEN1_HEIGHT_FROM': -0.2,
            'CLASSIFY_BETWEEN1_HEIGHT_TO': 0.2,
            'CLASSIFY_BETWEEN2': 4,
            'CLASSIFY_BETWEEN2_HEIGHT_FROM': 0.5,
            'CLASSIFY_BETWEEN2_HEIGHT_TO': 2,
            'CPU64': False,
            'GUI': False,
            'IGNORE_CLASS1': 7,
            'IGNORE_CLASS2': 8,
            'INPUT_LASLAZ': lasground2file,
            'OUTPUT_LASLAZ': parameters['LAS'],
            'REPLACE_Z': False,
            'VERBOSE': True
        }
        lasheightclassifyfile = alg_params['OUTPUT_LASLAZ']
        outputs['Lasheight_classify'] = processing.run('LAStools:lasheight_classify', alg_params, context=context,
                                                       feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(iter)
        if feedback.isCanceled():
            return {}

        results['classifiedLAZ'] = lasheightclassifyfile
        return results
Exemple #20
0
 def _resolveTemporary(self, alg):
     ext = self.getDefaultFileExtension()
     return QgsProcessingUtils.generateTempFilename(self.name + '.' + ext)
Exemple #21
0
def filenamesToFile(files):
    listFile = QgsProcessingUtils.generateTempFilename("inputfiles.txt")
    with open(listFile, 'w', encoding='utf-8') as f:
        f.write('\n'.join(files))

    return listFile
Exemple #22
0
 def _resolveTemporary(self, alg):
     if alg.provider().supportsNonFileBasedOutput():
         return "memory:"
     else:
         ext = self.getDefaultFileExtension()
         return QgsProcessingUtils.generateTempFilename(self.name + '.' + ext)
Exemple #23
0
    def processAlgorithm(self, parameters, context, model_feedback):
        # Use a multi-step feedback, so that individual child algorithm progress reports are adjusted for the
        # overall progress through the model
        feedback = QgsProcessingMultiStepFeedback(6, model_feedback)
        results = {}
        outputs = {}

        feedback.setCurrentStep(1)
        if feedback.isCanceled():
            return {}

        if parameters['classLas'] == False:
            alg_params = {
                'InputFilelaslaz': parameters['InputFilelaslaz'],
                'LAS': QgsProcessingUtils.generateTempFilename('lasheightCl.las'),
                'LowNoise': parameters['LowNoise']
            }
            outputs['ClassifyLaslaz'] = processing.run('Open LiDAR Toolbox:ToClassLas', alg_params, context=context,
                                                       feedback=feedback, is_child_algorithm=True)
            lasheightclassifyfile = outputs['ClassifyLaslaz']['classifiedLAZ']
            results['LAS'] = outputs['ClassifyLaslaz']['classifiedLAZ']

        if parameters['classLas']:
            lasheightclassifyfile = parameters['InputFilelaslaz']

        feedback.setCurrentStep(2)
        if feedback.isCanceled():
            return {}

        # Create base data
        alg_params = {
            'CRS': parameters['CRS'],
            'GPD': False,
            'IDW': False,
            'LowNoise': parameters['LowNoise'],
            'InputFilelaslaz': lasheightclassifyfile,
            'LVD': False,
            'SetCellSize': parameters['SetCellSize'],
            'TIN': False,
            'prefix': parameters['prefix'],
            'classLas': parameters['classLas']
        }
        outputs['CreateBaseData'] = processing.run('Open LiDAR Toolbox:basedata', alg_params, context=context,
                                                   feedback=feedback, is_child_algorithm=True)


        feedback.setCurrentStep(3)
        if feedback.isCanceled():
            return {}

        # DFM Confidence Map
        alg_params = {
            'CRS': parameters['CRS'],
            'Createconfidencemapfor': [1],
            'DEMDFM': outputs['CreateBaseData']['DEM'],
            'Groundlayer': outputs['CreateBaseData']['GPD'],
            'LowVegetation': outputs['CreateBaseData']['LVD'],
            'SetCellSize': parameters['SetCellSize'],
            'loadCFM': False
        }
        outputs['DfmConfidenceMap'] = processing.run('Open LiDAR Toolbox:DFM confidence map', alg_params,
                                                     context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(4)
        if feedback.isCanceled():
            return {}


        # Hybrid Interpolation
        alg_params = {
            'CRS': parameters['CRS'],
            'CellSize': parameters['SetCellSize'],
            'ConfidenceMapRaster': outputs['DfmConfidenceMap']['CFM 0.5m'],
            'IDW': outputs['CreateBaseData']['IDW'],
            'REDgrowradiusinrastercells': 3,
            'TLI': outputs['CreateBaseData']['DEM'],
            'loadDFM': False
        }
        outputs['HybridInterpolation'] = processing.run('Open LiDAR Toolbox:Hybrid interpolation', alg_params,
                                                        context=context, feedback=feedback, is_child_algorithm=True)

        results['DFM'] = outputs['HybridInterpolation']['Dfm']

        feedback.setCurrentStep(5)
        if feedback.isCanceled():
            return {}

        if parameters['VisualisationDFM']:
            # Load result
            alg_params = {
                'INPUT': outputs['HybridInterpolation']['Dfm'],
                'NAME': parameters['prefix'] + 'DFM'
            }
            outputs['LoadResult'] = processing.run('native:loadlayer', alg_params, context=context, feedback=feedback,
                                                   is_child_algorithm=True)

        feedback.setCurrentStep(6)
        if feedback.isCanceled():
            return {}


        return results
Exemple #24
0
    def processAlgorithm(self, parameters, context, feedback):
        pname = self.matchAlgo("native:polygonize")
        spiname = self.matchAlgo("native:createspatialindex")
        jname = self.matchAlgo("native:joinattributesbylocation")

        source_lines = self.parameterAsSource(parameters, self.IN_LINES,
                                              context)

        source_pts = self.parameterAsSource(parameters, self.IN_POINTS,
                                            context)

        self.checkSavedState(parameters, context, self.IN_POINTS)
        self.checkSavedState(parameters, context, self.IN_LINES)

        # field = self.parameterAsString(parameters, self.MAIN_FIELD, context)
        distance = self.parameterAsDouble(parameters, self.EXT_DISTANCE,
                                          context)

        if source_lines is None:
            raise QgsProcessingException(
                self.invalidSourceError(parameters, self.IN_LINES))

        if source_pts is None:
            raise QgsProcessingException(
                self.invalidSourceError(parameters, self.IN_POINTS))

        if feedback.isCanceled():
            return {}

        nonnull = processing.run("native:removenullgeometries", {
            'INPUT': parameters[self.IN_LINES],
            'OUTPUT': 'memory:',
            'REMOVE_EMPTY': True
        },
                                 context=context,
                                 feedback=feedback,
                                 is_child_algorithm=True)

        nodups = processing.run("native:removeduplicatevertices", {
            'INPUT': nonnull["OUTPUT"],
            'OUTPUT': 'memory:',
            "TOLERANCE": 1e-06,
            'USE_Z_VALUE=': False
        },
                                context=context,
                                feedback=feedback,
                                is_child_algorithm=True)

        extended_layer = processing.run("native:extendlines", {
            'END_DISTANCE': distance,
            'INPUT': nodups["OUTPUT"],
            'OUTPUT': 'memory:',
            'START_DISTANCE': distance
        },
                                        context=context,
                                        feedback=feedback,
                                        is_child_algorithm=True)

        feedback.pushInfo(f"polygonizing")

        polygonized_layer = processing.run(pname, {
            'INPUT':
            extended_layer["OUTPUT"],
            "OUTPUT":
            QgsProcessingUtils.generateTempFilename("polygonize.gpkg")
        },
                                           context=context,
                                           feedback=feedback,
                                           is_child_algorithm=True)

        feedback.pushInfo(
            f"output of polygonize at {polygonized_layer['OUTPUT']}")
        feedback.pushInfo(f"processing {type(processing)}")

        feedback.pushInfo(f"generating spatial index")

        polygons_wspatial = processing.run(
            spiname, {"INPUT": polygonized_layer["OUTPUT"]},
            is_child_algorithm=True,
            feedback=feedback)

        points_wspatial = processing.run(spiname,
                                         {"INPUT": parameters[self.IN_POINTS]},
                                         is_child_algorithm=True,
                                         feedback=feedback)

        points_layer = self.parameterAsLayer(parameters, self.IN_POINTS,
                                             context)
        feedback.pushInfo(str(points_layer))

        drop = self.parameterAsBool(parameters, self.DROP_UNMATCHED, context)

        feedback.pushInfo(f"joining")
        joined_layer = processing.run(jname, {
            'DISCARD_NONMATCHING': drop,
            'INPUT': polygonized_layer["OUTPUT"],
            'JOIN': parameters[self.IN_POINTS],
            'JOIN_FIELDS': [],
            'METHOD': 1,
            'OUTPUT': "memory:",
            'PREDICATE': [0],
            'PREFIX': ''
        },
                                      context=context,
                                      feedback=feedback,
                                      is_child_algorithm=False)
        # feedback.pushInfo(f"layer is {joined_layer}")

        (sink, dest_id) = self.parameterAsSink(
            parameters,
            self.OUTPUT,
            context,
            joined_layer["OUTPUT"].fields(
            ),  # QgsFields() for an empty fields list or source_lines.fields()
            QgsWkbTypes.Polygon,
            source_lines.sourceCrs())

        # feedback.pushInfo(f"destination {dest_id}")
        #
        # # If sink was not created, throw an exception to indicate that the algorithm
        # # encountered a fatal error. The exception text can be any string, but in this
        # # case we use the pre-built invalidSinkError method to return a standard
        # # helper text for when a sink cannot be evaluated
        if sink is None:
            raise QgsProcessingException(
                self.invalidSinkError(parameters, self.OUTPUT))

        #
        for feature in joined_layer["OUTPUT"].getFeatures():
            sink.addFeature(feature, QgsFeatureSink.FastInsert)

        outlayer = self.parameterAsLayer(parameters, self.OUTPUT, context)
        feedback.pushInfo("->" + str(outlayer))

        # from qgismappy.qgismappy_dockwidget import resetCategoriesIfNeeded
        # resetCategoriesIfNeeded(sink, field)

        # Return the results of the algorithm. In this case our only result is
        # the feature sink which contains the processed features, but some
        # algorithms may return multiple feature sinks, calculated numeric
        # statistics, etc. These should all be included in the returned
        # dictionary, with keys matching the feature corresponding parameter
        # or output names.
        return {self.OUTPUT: dest_id}
    def processAlgorithm(self, parameters, context, model_feedback):
        # Use a multi-step feedback, so that individual child algorithm progress reports are adjusted for the
        # overall progress through the model
        feedback = QgsProcessingMultiStepFeedback(7, model_feedback)
        results = {}
        outputs = {}

        # Extraire par attribut
        alg_params = {
            "FIELD":
            parameters["h_field"],
            "INPUT":
            parameters["pointsresultats"],
            "OPERATOR":
            3,
            "VALUE":
            parameters["hmin"],
            "OUTPUT":
            QgsProcessingUtils.generateTempFilename("points_extraits.shp"),
        }
        outputs["ExtraireParAttribut"] = processing.run(
            "native:extractbyattribute",
            alg_params,
            context=context,
            feedback=feedback,
            is_child_algorithm=True,
        )

        feedback.setCurrentStep(1)
        if feedback.isCanceled():
            return {}

        alg_params = {
            "DISCARD_NONMATCHING": False,
            "FIELDS_TO_COPY": [str(parameters["sl_field"])[:10]],
            "INPUT": parameters["pointsresultats"],
            "INPUT_2": outputs["ExtraireParAttribut"]["OUTPUT"],
            "MAX_DISTANCE": None,
            "NEIGHBORS": 1,
            "PREFIX": "_______Z_w",
            "OUTPUT": QgsProcessingUtils.generateTempFilename("voisin.shp"),
        }
        outputs["JoindreLesAttributsParLePlusProche"] = processing.run(
            "native:joinbynearest",
            alg_params,
            context=context,
            feedback=feedback,
            is_child_algorithm=True)

        feedback.setCurrentStep(2)
        if feedback.isCanceled():
            return {}

        # Assigner une projection
        alg_params = {
            "CRS": "ProjectCrs",
            "INPUT": outputs["JoindreLesAttributsParLePlusProche"]["OUTPUT"],
            "OUTPUT": QgsProcessingUtils.generateTempFilename("reproj.shp"),
        }
        outputs["AssignerUneProjection"] = processing.run(
            "native:assignprojection",
            alg_params,
            context=context,
            feedback=feedback,
            is_child_algorithm=True,
        )

        feedback.setCurrentStep(3)
        if feedback.isCanceled():
            return {}

        # Ajouter les champs X/Y à la couche
        alg_params = {
            "CRS": "ProjectCrs",
            "INPUT": outputs["AssignerUneProjection"]["OUTPUT"],
            "PREFIX": "",
            "OUTPUT": QgsProcessingUtils.generateTempFilename("xy.shp"),
        }
        outputs["AjouterLesChampsXyLaCouche"] = processing.run(
            "native:addxyfields",
            alg_params,
            context=context,
            feedback=feedback,
            is_child_algorithm=True,
        )

        feedback.setCurrentStep(4)
        if feedback.isCanceled():
            return {}

        # Refactoriser les champs
        alg_params = {
            "FIELDS_MAPPING": [
                {
                    "expression": '"x"',
                    "length": 14,
                    "name": "X",
                    "precision": 4,
                    "type": 6,
                },
                {
                    "expression": '"y"',
                    "length": 14,
                    "name": "Y",
                    "precision": 4,
                    "type": 6,
                },
                {
                    "expression": '"_______Z_w"',
                    "length": 14,
                    "name": "Z_w",
                    "precision": 4,
                    "type": 6,
                },
            ],
            "INPUT":
            outputs["AjouterLesChampsXyLaCouche"]["OUTPUT"],
            "OUTPUT":
            QgsProcessingUtils.generateTempFilename("refac.shp"),
        }
        outputs["RefactoriserLesChamps"] = processing.run(
            "qgis:refactorfields",
            alg_params,
            context=context,
            feedback=feedback,
            is_child_algorithm=True,
        )

        layer = QgsProcessingUtils.mapLayerFromString(
            outputs["RefactoriserLesChamps"]["OUTPUT"], context=context)

        # Set the path for the output file
        tempTXT = QgsProcessingUtils.generateTempFilename("txt_temp.txt")
        tempLAS = QgsProcessingUtils.generateTempFilename("las_temp.las")
        output_file = open(tempTXT, "w")

        # Get the features and properly rewrite them as lines
        for feat in layer.getFeatures():
            output_file.write(
                "%s\t%s\t%s\n" %
                (str(feat["X"]), str(feat["Y"]), str(feat["Z_w"])))

        output_file.close()

        # txt2las
        alg_params = {
            "ADDITIONAL_OPTIONS": "",
            "CPU64": True,
            "EPSG_CODE": 25832,
            "GUI": False,
            "INPUT_GENERIC": tempTXT,
            "PARSE": "xyz",
            "PROJECTION": 0,
            "SCALE_FACTOR_XY": 0.01,
            "SCALE_FACTOR_Z": 0.01,
            "SKIP": 0,
            "SP": 0,
            "UTM": 0,
            "VERBOSE": False,
            "OUTPUT_LASLAZ": tempLAS,
        }
        outputs["Txt2las"] = processing.run(
            "LAStools:txt2las",
            alg_params,
            context=context,
            feedback=feedback,
            is_child_algorithm=True,
        )

        feedback.setCurrentStep(5)
        if feedback.isCanceled():
            return {}

        if parameters["Raster"] == "TEMPORARY_OUTPUT":
            parameters["Raster"] = QgsProcessingUtils.generateTempFilename(
                "tif_temp.tif")

        alg_params = {
            "ADDITIONAL_OPTIONS": "-kill " + str(parameters["las_kill"]),
            "ATTRIBUTE": 0,
            "CPU64": True,
            "FILTER_RETURN_CLASS_FLAGS1": 0,
            "GUI": False,
            "INPUT_LASLAZ": tempLAS,
            "PRODUCT": 0,
            "STEP": parameters["resolutiondurasterdusortie"],
            "USE_TILE_BB": False,
            "VERBOSE": False,
            "OUTPUT_RASTER": parameters["Raster"],
        }
        outputs["Blast2dem"] = processing.run(
            "LAStools:blast2dem",
            alg_params,
            context=context,
            feedback=feedback,
            is_child_algorithm=True,
        )

        feedback.setCurrentStep(6)
        if feedback.isCanceled():
            return {}

        # Charger la couche dans le projet
        pathCouche = parameters["Raster"]
        nomCouche = parameters["Raster"].split("/")[-1]
        rlayer = QgsRasterLayer(
            parameters["Raster"],
            parameters["Raster"].split("/")[-1],
            "gdal",
        )
        QgsProject.instance().addMapLayer(rlayer)

        return {}
Exemple #26
0
	def processAlgorithm(self, parameters, context, feedback):
		"""
		Here is where the processing itself takes place.
		"""
		
		# Retrieve the feature source and sink. The 'dest_id' variable is used
		# to uniquely identify the feature sink, and must be included in the
		# dictionary returned by the processAlgorithm function.
		source = self.parameterAsLayer(parameters, self.INPUT, context)
		
		barrier = self.parameterAsLayer(parameters, self.BARRIER, context)

		search_dist = self.parameterAsDouble(parameters, self.SEARCH_DIST, context)

		simplify_dist = self.parameterAsDouble(parameters, self.SIMPLIFY_DIST, context)

		dissolve_with_input = self.parameterAsBoolean(parameters, self.DISSOLVE_WITH_INPUT, context)
		
		(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT,
				context, QgsFields(), source.wkbType(), source.sourceCrs())
		
		# Check for identical CRS
		if barrier is None:
			(epsg, srid) = source.sourceCrs().authid().split(":")
		elif source.sourceCrs().authid() == barrier.sourceCrs().authid():
			(epsg, srid) = barrier.sourceCrs().authid().split(":")
		else:
			raise QgsProcessingException(self.tr("Inputs in different CRS are not supported!"))
		assert epsg == "EPSG"
		
		# TODO: more exception handling, more robust
		# TODO: more feedback.isCanceled() checks
		
		# connect to named spatialite-db and memory spatialite-db
		named_sqlite_path = QgsProcessingUtils.generateTempFilename("aggPoly.sqlite")
		named_sqlite = QgsVectorLayer(named_sqlite_path)
		con_n = self.getSpatialConnetion(named_sqlite_path)
		con_m = self.getSpatialConnetion(':memory:')
		
		# create cursor
		cur = con_m.cursor()
		
		# import INPUTs in spatialite
		processing.run("qgis:importintospatialite", {'INPUT': source, 'DATABASE': named_sqlite, 'TABLENAME': 'pol_layer', 'GEOMETRY_COLUMN': 'geometry', 'CREATEINDEX': True, 'FORCE_SINGLEPART': True})
		if not barrier is None:
			processing.run("qgis:importintospatialite", {'INPUT': barrier, 'DATABASE': named_sqlite, 'TABLENAME': 'barrier_layer', 'GEOMETRY_COLUMN': 'geometry', 'CREATEINDEX': True, 'FORCE_SINGLEPART': True})
		
		# TODO: use self.tr # Datenbank angelegt und Layer geladen.
		feedback.pushInfo("Database created and features imported.")
		
		### Execute SQL
		feedback.pushInfo("Create new tables and calculate distances.")
		cur.execute("""ATTACH '{}' AS named_sqlite;""".format(named_sqlite_path))
		cur.execute(self.sql["import"].format("pol_layer"))
		if not barrier is None:
			cur.execute(self.sql["import"].format("barrier_layer"))
			geomtype_barrier_layer = cur.execute(self.sql["get_geometrytype"].format(column = "geometry", table = "barrier_layer")).fetchall()[0][0]
		else: # TODO
			cur.execute("""CREATE TABLE barrier_layer (geometry BLOB);""")
			geomtype_barrier_layer = 'POLYGON' # Dummy
		
		# simplify: less vertices reduces processing time
		# segmentize: ensure enough vertices
		if simplify_dist > 0:
			cur.execute(self.sql["simplify_and_segmentize"].format(segmentize = search_dist, simplify = simplify_dist))
			cur.execute(self.sql["simplify_only"].format(table = "barrier_layer", simplify = simplify_dist)) 
		else:
			cur.execute(self.sql["segmentize_only"].format(search_dist))
		# drop invalid geometries and recover spatialindex
		cur.execute(self.sql["drop_invalid_geometry"].format(table = "barrier_layer", column = "geometry")) 
		cur.executescript(self.sql["recover_spatial"].format(table = "barrier_layer", column = "geometry", crs = srid, geometrytype = geomtype_barrier_layer))
		cur.execute(self.sql["drop_invalid_geometry"].format(table = "pol_layer", column = "geometry")) 
		geomtype_pol_layer = cur.execute(self.sql["get_geometrytype"].format(column = "geometry", table = "pol_layer")).fetchall()[0][0]
		cur.executescript(self.sql["recover_spatial"].format(table = "pol_layer", column = "geometry", crs = srid, geometrytype = geomtype_pol_layer))
		
		cur.execute(self.sql["c_polygon_distance"].format(search_dist))
		cur.executescript(self.sql["dissolve_points"])
		cur.executescript(self.sql["recover_spatial"].format(table = "pol_layer", column = "mpoi_geom", crs = srid, geometrytype = "MULTIPOINT"))
		cur.execute(self.sql["c_points"])
		cur.execute(self.sql["c_line"].format(search_dist))
		cur.executescript(self.sql["recover_spatial"].format(table = "poi_to_poi", column = "l_geom", crs = srid, geometrytype = "LINESTRING"))
		cur.execute(self.sql["c_intersec_lines"])
		cur.execute(self.sql["c_join_intersec"])
		n_poi = cur.execute(self.sql["s_n_points"]).fetchall()[0][0]
		cur.execute(self.sql["c_res"])
		###

		feedback.pushInfo("Tables created and distances calculated.")
		feedback.pushInfo("Building polygons ...")
		
		# TODO: multi-threading
		for p in range(1, n_poi + 1):
			# Stop the algorithm if cancel button has been clicked
			if feedback.isCanceled():
				break

			cur.execute(self.sql["c_view"].format(p))
			cur.execute(self.sql["c_triangles"].format(p))
			cur.executescript(self.sql["recover_spatial"].format(table = "triangles_sel", column = "triangle", crs = srid, geometrytype = "POLYGON"))
			cur.execute(self.sql["i_subset_res"])
			cur.executescript("""DROP TABLE triangles_sel; DROP VIEW poi_sel;""")
			
			progress_percent = (p/float(n_poi))*100
			feedback.setProgress(progress_percent)
		
		cur.close()
		
		# recover spatial column in named_sqlite
		cur = con_n.cursor()
		cur.executescript(self.sql["recover_spatial"].format(table = "pol_res", column = "geom", crs = srid, geometrytype = "MULTIPOLYGON"))
		cur.close()
		
		con_n.close()
		con_m.close()
		
		# create result-QgsVectorLayer 
		named_sqlite_result_uri = QgsDataSourceUri()
		named_sqlite_result_uri.setDatabase(named_sqlite_path)
		named_sqlite_result_uri.setDataSource('', 'pol_res', 'geom')
		named_sqlite_result = QgsVectorLayer(named_sqlite_result_uri.uri(), providerLib='spatialite')

		### post-processing
		# which features should be dissolved	
		if dissolve_with_input:
			do_be_dissolved = processing.run("native:mergevectorlayers", {'LAYERS': [named_sqlite_result, source], 'OUTPUT': 'memory:'})
		else:
			do_be_dissolved = {'OUTPUT': named_sqlite_result}

		# dissolve features
		dissolved = processing.run("native:dissolve", {'INPUT': do_be_dissolved['OUTPUT'], 'OUTPUT': 'memory:'})

		# singlepart features
		singleparts = processing.run("native:multiparttosingleparts", {'INPUT': dissolved['OUTPUT'], 'OUTPUT': 'memory:'})
		###

		### Copy features to sink
		# TODO: how to write directly from processing algorithm native:multiparttosinglepart to sink?
		feedback.pushInfo("Copy features to output.")
		
		result_features = singleparts['OUTPUT'].getFeatures()
		for current, feature in enumerate(result_features):
			# Stop the algorithm if cancel button has been clicked
			if feedback.isCanceled():
				return None
			
			# Add a feature in the sink
			sink.addFeature(feature, QgsFeatureSink.FastInsert)
			
			# TODO: Update the progress bar
			#feedback.setProgress(int(current * total))
		###

		# Return the results of the algorithm.
		return {self.OUTPUT: dest_id}
    def processAlgorithm(self, parameters, context, feedback):
        roads_source, roads_layer = qgsTreatments.parameterAsSourceLayer(
            self, parameters, self.ROADS, context, feedback=feedback)
        name_field = self.parameterAsString(parameters, self.NAME_FIELD,
                                            context)
        select_expr = self.parameterAsExpression(parameters, self.SELECT_EXPR,
                                                 context)
        buf_expr = self.parameterAsExpression(parameters, self.BUFFER_EXPR,
                                              context)
        end_cap_style = self.parameterAsEnum(parameters, self.END_CAP_STYLE,
                                             context)  #+ 1
        dissolve_flag = self.parameterAsBool(parameters, self.DISSOLVE,
                                             context)
        # include_null_flag = self.parameterAsBool(parameters,self.INCLUDE_NULL,context)
        join_expr = self.parameterAsExpression(parameters, self.JOIN_EXPR,
                                               context)
        output = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)
        output_linear = self.parameterAsOutputLayer(parameters,
                                                    self.OUTPUT_LINEAR,
                                                    context)
        join_flag = join_expr is not None and join_expr != ''
        nb_steps = 3 + (3 if join_flag else 0) + (3 if output_linear else 0)
        mf = QgsProcessingMultiStepFeedback(nb_steps, feedback)
        crs = roads_source.sourceCrs()
        # crs = input_layer.sourceCrs()
        distance = QgsProperty.fromExpression(buf_expr)

        # Extract selection
        if select_expr:
            selected = QgsProcessingUtils.generateTempFilename('selected.gpkg')
            qgsTreatments.extractByExpression(roads_layer,
                                              select_expr,
                                              selected,
                                              context=context,
                                              feedback=mf)
        else:
            selected = roads_layer
        mf.setCurrentStep(1)

        # Apply buffer
        buffered = QgsProcessingUtils.generateTempFilename(
            'buffered.gpkg') if dissolve_flag else output
        qgsTreatments.applyBufferFromExpr(selected,
                                          distance,
                                          buffered,
                                          cap_style=end_cap_style,
                                          context=context,
                                          feedback=mf)
        mf.setCurrentStep(2)

        # Dissolve
        if dissolve_flag:
            join_flag = join_expr is not None and join_expr != ''
            buffered_nojoin = QgsProcessingUtils.generateTempFilename(
                'buffered_nojoin.gpkg')
            buffered_join = QgsProcessingUtils.generateTempFilename(
                'buffered_join.gpkg')
            # null_expr = "" + name_field + " is NULL"
            if not join_flag:
                raise QgsProcessingException("No join expression specified")
            if name_field not in roads_layer.fields().names():
                raise QgsProcessingException(
                    "Field '" + str(name_field) +
                    "' does not exist, impossible to join by name")
            qgsTreatments.extractByExpression(buffered,
                                              join_expr,
                                              buffered_join,
                                              fail_out=buffered_nojoin,
                                              context=context,
                                              feedback=mf)
            mf.setCurrentStep(3)
            dissolved = QgsProcessingUtils.generateTempFilename(
                'dissolved.gpkg') if join_flag else output
            fields = [name_field]
            qgsTreatments.dissolveLayer(buffered_join,
                                        dissolved,
                                        fields=fields,
                                        context=context,
                                        feedback=mf)
            mf.setCurrentStep(4)
            layers = [buffered_nojoin, dissolved]
            qgsTreatments.mergeVectorLayers(layers,
                                            crs,
                                            output,
                                            context=context,
                                            feedback=mf)
            mf.setCurrentStep(5)

            if output_linear:
                roads_nojoin = QgsProcessingUtils.generateTempFilename(
                    'roads_nojoin.gpkg')
                roads_join = QgsProcessingUtils.generateTempFilename(
                    'roads_join.gpkg')
                qgsTreatments.extractByExpression(selected,
                                                  join_expr,
                                                  roads_join,
                                                  fail_out=roads_nojoin,
                                                  context=context,
                                                  feedback=mf)
                mf.setCurrentStep(6)
                qgsTreatments.dissolveLayer(roads_join,
                                            dissolved,
                                            fields=fields,
                                            context=context,
                                            feedback=mf)
                mf.setCurrentStep(7)
                layers = [roads_nojoin, dissolved]
                qgsTreatments.mergeVectorLayers(layers,
                                                crs,
                                                output_linear,
                                                context=context,
                                                feedback=mf)
                mf.setCurrentStep(8)

            # selected = dissolved
            # if include_null_flag:
            # merged = QgsProcessingUtils.generateTempFilename('merged.gpkg')
            # layers = [dissolved,roads_null]
            # qgsTreatments.mergeVectorLayers(layers,crs,merged,context=context,feedback=mf)
            # selected = merged

        # Apply buffer
        # qgsTreatments.applyBufferFromExpr(selected,distance,output,
        # cap_style=end_cap_style,context=context,feedback=mf)
        mf.setCurrentStep(nb_steps)

        return {self.OUTPUT: output}
    def processAlgorithm(self, parameters, context, feedback):
        arguments = []

        toolPath = prepairUtils.prepairPath()
        if toolPath == "":
            toolPath = self.name()

        arguments.append(toolPath)

        paradigm = self.parameterAsEnum(parameters, self.PARADIGM, context)
        if paradigm == 1:
            arguments.append("--setdiff")

        minArea = self.parameterAsDouble(parameters, self.MIN_AREA, context)
        if minArea > 0.0:
            arguments.append("--minarea")
            arguments.append("{}".format(minArea))

        snapRounding = self.parameterAsInt(parameters, self.SNAP_ROUNDING, context)
        if snapRounding > 0:
            arguments.append("--isr")
            arguments.append("{}".format(snapRounding))

        onlyInvalid = self.parameterAsBool(parameters, self.ONLY_INVALID, context)

        tmpFile = QgsProcessingUtils.generateTempFilename("prepair.shp")
        arguments.append("-f")
        arguments.append(tmpFile)

        source = self.parameterAsSource(parameters, self.INPUT, context)
        (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
                                               source.fields(), source.wkbType(), source.sourceCrs())

        features = source.getFeatures(QgsFeatureRequest(), QgsProcessingFeatureSource.FlagSkipGeometryValidityChecks)
        total = 100.0 / source.featureCount() if source.featureCount() else 0
        for current, feat in enumerate(features):
            if feedback.isCanceled():
                break

            geom = feat.geometry()
            if onlyInvalid and len(geom.validateGeometry()) == 0:
                feedback.pushInfo(
                    self.tr("Feature {} is valid, skipping…".format(feat.id())))
                feedback.setProgress(int(count * total))
                continue

            with open(tmpFile, "w") as f:
                f.write(geom.asWkt())

            result = prepairUtils.execute(arguments, feedback)

            if len(result) == 0:
                feedback.poushInfo(self.tr("Feature {} not repaired".format(feat.id())))
                feedback.setProgress(int(count * total))
                continue

            geom = QgsGeometry.fromWkt(result[0].strip())
            if geom is None or geom.isEmpty():
                feedback.pushInfo(self.tr("Empty geometry after repairing "
                                          "feature {}, skipping…".format(feat.id())))
                feedback.setProgress(int(count * total))
                continue

            feat.setGeometry(geom)
            sink.addFeature(feat, QgsFeatureSink.FastInsert)
            feedback.setProgress(int(current * total))

        return {self.OUTPUT: dest_id}
Exemple #29
0
    def processAlgorithm(self, parameters, context, feedback):
        layers = self.parameterAsLayerList(parameters, self.INPUT_DATASOURCES,
                                           context)
        query = self.parameterAsString(parameters, self.INPUT_QUERY, context)
        uid_field = self.parameterAsString(parameters, self.INPUT_UID_FIELD,
                                           context)
        geometry_field = self.parameterAsString(parameters,
                                                self.INPUT_GEOMETRY_FIELD,
                                                context)
        geometry_type = self.parameterAsEnum(parameters,
                                             self.INPUT_GEOMETRY_TYPE, context)
        geometry_crs = self.parameterAsCrs(parameters, self.INPUT_GEOMETRY_CRS,
                                           context)

        df = QgsVirtualLayerDefinition()
        for layerIdx, layer in enumerate(layers):

            # Issue https://github.com/qgis/QGIS/issues/24041
            # When using this algorithm from the graphic modeler, it may try to
            # access (thanks the QgsVirtualLayerProvider) to memory layer that
            # belongs to temporary QgsMapLayerStore, not project.
            # So, we write them to disk is this is the case.
            if context.project() and not context.project().mapLayer(
                    layer.id()):
                basename = "memorylayer." + QgsVectorFileWriter.supportedFormatExtensions(
                )[0]
                tmp_path = QgsProcessingUtils.generateTempFilename(basename)
                QgsVectorFileWriter.writeAsVectorFormat(
                    layer, tmp_path,
                    layer.dataProvider().encoding())
                df.addSource('input{}'.format(layerIdx + 1), tmp_path, "ogr")
            else:
                df.addSource('input{}'.format(layerIdx + 1), layer.id())

        if query == '':
            raise QgsProcessingException(
                self.
                tr('Empty SQL. Please enter valid SQL expression and try again.'
                   ))
        localContext = self.createExpressionContext(parameters, context)
        expandedQuery = QgsExpression.replaceExpressionText(
            query, localContext)
        df.setQuery(expandedQuery)

        if uid_field:
            df.setUid(uid_field)

        if geometry_type == 1:  # no geometry
            df.setGeometryWkbType(QgsWkbTypes.NoGeometry)
        else:
            if geometry_field:
                df.setGeometryField(geometry_field)
            if geometry_type > 1:
                df.setGeometryWkbType(geometry_type - 1)
            if geometry_crs.isValid():
                df.setGeometrySrid(geometry_crs.postgisSrid())

        vLayer = QgsVectorLayer(df.toString(), "temp_vlayer", "virtual")
        if not vLayer.isValid():
            raise QgsProcessingException(
                vLayer.dataProvider().error().message())

        if vLayer.wkbType() == QgsWkbTypes.Unknown:
            raise QgsProcessingException(self.tr("Cannot find geometry field"))

        (sink, dest_id) = self.parameterAsSink(
            parameters, self.OUTPUT, context, vLayer.fields(),
            vLayer.wkbType() if geometry_type != 1 else 1, vLayer.crs())
        if sink is None:
            raise QgsProcessingException(
                self.invalidSinkError(parameters, self.OUTPUT))

        features = vLayer.getFeatures()
        total = 100.0 / vLayer.featureCount() if vLayer.featureCount() else 0
        for current, inFeat in enumerate(features):
            if feedback.isCanceled():
                break

            sink.addFeature(inFeat, QgsFeatureSink.FastInsert)
            feedback.setProgress(int(current * total))
        return {self.OUTPUT: dest_id}
    def processAlgorithm(self, parameters, context, model_feedback):
        # Use a multi-step feedback, so that individual child algorithm progress reports are adjusted for the
        # overall progress through the model
        feedback = QgsProcessingMultiStepFeedback(9, model_feedback)
        results = {}
        outputs = {}

        iter = 1
        feedback.setCurrentStep(iter)
        if feedback.isCanceled():
            return {}

        if not parameters['classLas']:

            alg_params = {
                'InputFilelaslaz': parameters['InputFilelaslaz'],
                'LAS': QgsProcessingUtils.generateTempFilename('lasheightCl.las'),
                'LowNoise': parameters['LowNoise']
            }
            outputs['ClassifyLaslaz'] = processing.run('Open LiDAR Toolbox:ToClassLas', alg_params, context=context,
                                                       feedback=feedback, is_child_algorithm=True)
            lasheightclassifyfile = outputs['ClassifyLaslaz']['classifiedLAZ']
            results['LAS'] = outputs['ClassifyLaslaz']['classifiedLAZ']

        feedback.setCurrentStep(iter)
        if feedback.isCanceled():
            return {}
        iter = iter + 1

        if parameters['classLas']:
            lasheightclassifyfile = parameters['InputFilelaslaz']

        if parameters['LAS'] != 'TEMPORARY_OUTPUT':
            # laszip
            alg_params = {
                'ADDITIONAL_OPTIONS': '',
                'APPEND_LAX': False,
                'CPU64': False,
                'CREATE_LAX': False,
                'GUI': False,
                'INPUT_LASLAZ': lasheightclassifyfile,
                'REPORT_SIZE': False,
                'VERBOSE': False,
                'OUTPUT_LASLAZ': parameters['LAS']
            }
            outputs['Laszip'] = processing.run('LAStools:laszip', alg_params, context=context, feedback=feedback,
                                               is_child_algorithm=True)

        feedback.setCurrentStep(iter)
        if feedback.isCanceled():
            return {}
        iter = iter + 1

        # Create base data
        alg_params = {
            'CRS': parameters['CRS'],
            'GPD': parameters['GPD'],
            'IDW': False,
            'InputFilelaslaz': lasheightclassifyfile,
            'LVD': parameters['LVD'],
            'SetCellSize': parameters['SetCellSize'],
            'TIN': False,
            'prefix': parameters['prefix'],
            'classLas': True
        }
        outputs['CreateBaseData'] = processing.run('Open LiDAR Toolbox:basedata', alg_params, context=context,
                                                   feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(iter)
        if feedback.isCanceled():
            return {}
        iter = iter + 1

        # DFM Confidence Map
        alg_params = {
            'CRS': parameters['CRS'],
            'Createconfidencemapfor': [1],
            'DEMDFM': outputs['CreateBaseData']['DEM'],
            'Groundlayer': outputs['CreateBaseData']['GPD'],
            'LowVegetation': outputs['CreateBaseData']['LVD'],
            'SetCellSize': parameters['SetCellSize'],
            'loadCFM': False
        }
        outputs['DfmConfidenceMap'] = processing.run('Open LiDAR Toolbox:DFM confidence map', alg_params,
                                                     context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(iter)
        if feedback.isCanceled():
            return {}
        iter = iter + 1


        if parameters['VisualisationCM']:
            # Load result
            alg_params = {
                'INPUT': outputs['DfmConfidenceMap']['CFM 0.5m'],
                'NAME': parameters['prefix'] + 'DFM CM 0,5m'
            }
            outputs['LoadResult'] = processing.run('native:loadlayer', alg_params, context=context, feedback=feedback,
                                                   is_child_algorithm=True)

        feedback.setCurrentStep(iter)
        if feedback.isCanceled():
            return {}
        iter = iter + 1

        # Hybrid Interpolation
        alg_params = {
            'CRS': parameters['CRS'],
            'CellSize': parameters['SetCellSize'],
            'ConfidenceMapRaster': outputs['DfmConfidenceMap']['CFM 0.5m'],
            'IDW': outputs['CreateBaseData']['IDW'],
            'REDgrowradiusinrastercells': 3,
            'TLI': outputs['CreateBaseData']['DEM'],
            'loadDFM': False
        }
        outputs['HybridInterpolation'] = processing.run('Open LiDAR Toolbox:Hybrid interpolation', alg_params,
                                                        context=context, feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(iter)
        if feedback.isCanceled():
            return {}
        iter = iter + 1

        if parameters['VisualisationDFM']:
            # Load result
            alg_params = {
                'INPUT': outputs['HybridInterpolation']['Dfm'],
                'NAME': parameters['prefix'] + 'DFM'
            }
            outputs['LoadResult'] = processing.run('native:loadlayer', alg_params, context=context, feedback=feedback,
                                                   is_child_algorithm=True)

        feedback.setCurrentStep(iter)
        if feedback.isCanceled():
            return {}
        iter = iter + 1

        # Visualisations (from DFM)
        alg_params = {
            'DFMDEM': outputs['HybridInterpolation']['Dfm'],
            'VisualisationDfME': parameters['VisualisationDfME'],
            'VisualisationHS': parameters['VisualisationHS'],
            'VisualisationOPN': parameters['VisualisationOPN'],
            'VisualisationSVF': parameters['VisualisationSVF'],
            'VisualisationVAT': parameters['VisualisationVAT'],
            'prefix': parameters['prefix']
        }
        outputs['VisualisationsFromDfm'] = processing.run('Open LiDAR Toolbox:Visualise', alg_params,
                                                          context=context, feedback=feedback,
                                                          is_child_algorithm=True)

        feedback.setCurrentStep(iter)
        if feedback.isCanceled():
            return {}
        iter = iter + 1

        return results
Exemple #31
0
    def processAlgorithm(self, parameters, context, model_feedback):
        # Use a multi-step feedback, so that individual child algorithm progress reports are adjusted for the
        # overall progress through the model
        feedback = QgsProcessingMultiStepFeedback(5, model_feedback)
        results = {}
        outputs = {}
        model_feedback.pushConsoleInfo("start")

        inputLayer = self.parameterAsVectorLayer(parameters, "inputlayer",
                                                 context)

        agfields = self.parameterAsFields(parameters, 'agfield', context)

        cfields = self.parameterAsFields(parameters, 'cfield', context)

        # ret = inputLayer.aggregate(QgsAggregateCalculator.Sum, fieldOrExpression: str, parameters: QgsAggregateCalculator.AggregateParameters = QgsAggregateCalculator.AggregateParameters(), context: QgsExpressionContext = None, fids: object = None)
        # retar = sum(cfields[0], group_by:=agfields[0])

        # results['OUTPUT'] = outputs['Gdal_translate']['OUTPUT']

        #enc = self.parameterAsFile(
        #    parameters,
        #    self.ENCODING,
        #    context
        #
        #
        #)

        # enc = self.parameterAsInt( parameters,self.ENCODING, context )

        #encstring = self.encode[enc]
        #feedback.pushConsoleInfo( encstring)

        basename = "memorylayer.gpkg"
        tmp_path = QgsProcessingUtils.generateTempFilename(basename)

        conn = sqlite3.connect(tmp_path)
        # sqliteを操作するカーソルオブジェクトを作成
        cur = conn.cursor()

        entbl = "sample_tbl"

        key_fieldname = agfields[0]
        value_fieldname = cfields[0]
        feedback.pushConsoleInfo("field name " + key_fieldname)

        feedback.pushConsoleInfo("value field name " + value_fieldname)

        # 調査結果格納テーブルの作成
        crsql = 'CREATE TABLE \"' + entbl + '\"( \"' + key_fieldname + '\" STRING, \"' + value_fieldname + '\" NUMERIC);'
        cur.execute(crsql)

        # uri = csvfile

        #valueAsPythonString(
        # csv file read

        #    read input layer

        isql = 'insert into \"' + entbl + '\" values (?,?);'

        for f in inputLayer.getFeatures():

            # t = '(\'' + f[key_fieldname ] + '\',' + str(f[value_fieldname] ) + ',)'
            #feedback.pushConsoleInfo( "class  " + f[key_fieldname].__class__.__name__ + ' ' + f[value_fieldname].__class__.__name__ )

            sqv = []

            if isinstance(f[value_fieldname], (int, float)):

                if (type(f[key_fieldname]) is str):
                    sqv.append(f[key_fieldname])
                    sqv.append(f[value_fieldname])
                    cur.execute(isql, sqv)
            else:

                feedback.pushConsoleInfo("no value  ")

                if (type(f[key_fieldname]) is str):
                    sqv.append(f[key_fieldname])
                    sqv.append(0)
                    cur.execute(isql, sqv)

    # データベースへコミット。これで変更が反映される。
        conn.commit()

        sqlstr = 'create table temp_vlayer as select \"' + key_fieldname + '\", sum(\"' + value_fieldname + '\") vn from \"' + entbl + '\"  group by \"' + key_fieldname + '\";'
        # 町名別集計
        cur.execute(sqlstr)

        feedback.pushConsoleInfo("execute   " + sqlstr)

        result_def = tmp_path + '|layername=temp_vlayer'
        tgttable = "temp_vlayer"

        #results["OUTPUT"] = result_def

        #return results

        fields = QgsFields()
        fields.append(QgsField(key_fieldname, QVariant.String))
        fields.append(QgsField(value_fieldname, QVariant.Double))

        (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT,
                                               context, fields)

        feedback.pushConsoleInfo("create sink    ")

        # Compute the number of steps to display within the progress bar and
        # get features from source
        #total = 100.0 / resultlayer.featureCount() if resultlayer.featureCount() else 0
        #features = resultlayer.getFeatures()

        sqlstr = 'select \"' + key_fieldname + '\",' + 'vn from temp_vlayer;'

        c = conn.cursor()

        for row in c.execute(sqlstr):

            #for current, feature in enumerate(list1):
            # Stop the algorithm if cancel button has been clicked
            if feedback.isCanceled():
                break

            nfeature = QgsFeature(fields)

            nfeature[key_fieldname] = row[0]
            nfeature[value_fieldname] = row[1]
            sink.addFeature(nfeature, QgsFeatureSink.FastInsert)

            # Update the progress bar
            #feedback.setProgress(int(current * total))

        conn.close()

        # Return the results of the algorithm. In this case our only result is
        # the feature sink which contains the processed features, but some
        # algorithms may return multiple feature sinks, calculated numeric
        # statistics, etc. These should all be included in the returned
        # dictionary, with keys matching the feature corresponding parameter
        # or output names.
        return {self.OUTPUT: dest_id}
Exemple #32
0
    def processAlgorithm(self, parameters, context, feedback):
        """
        Here is where the processing itself takes place.
        """
        csvfile = self.parameterAsFile(parameters, self.INPUT, context)
        if csvfile is None:
            raise QgsProcessingException(self.tr('csv file error'))

        #df = QgsVirtualLayerDefinition()

        #enc = self.parameterAsFile(
        #    parameters,
        #    self.ENCODING,
        #    context
        #
        #
        #)

        enc = self.parameterAsInt(parameters, self.ENCODING, context)

        encstring = self.encode[enc]
        feedback.pushConsoleInfo(encstring)

        basename = "memorylayer.gpkg"
        tmp_path = QgsProcessingUtils.generateTempFilename(basename)

        conn = sqlite3.connect(tmp_path)
        # sqliteを操作するカーソルオブジェクトを作成
        cur = conn.cursor()

        entbl = "sample_tbl"

        # 調査結果格納テーブルの作成
        crsql = 'CREATE TABLE \"' + entbl + '\"( address STRING, vn  STRING);'
        cur.execute(crsql)

        uri = csvfile

        #valueAsPythonString(
        # csv file read
        with open(uri, 'r', encoding=encstring) as f:
            b = csv.reader(f)
            header = next(b)

            isql = 'insert into \"' + entbl + '\" values (?,?);'
            for t in b:

                cur.execute(isql, t)

    # データベースへコミット。これで変更が反映される。
        conn.commit()

        sqlstr = 'create table temp_vlayer as select address, count(*) vn from \"' + entbl + '\"  group by address;'
        # 町名別集計
        cur.execute(sqlstr)

        result_def = tmp_path + '|layername=temp_vlayer'
        tgttable = "temp_vlayer"

        fields = QgsFields()
        fields.append(QgsField("Address", QVariant.String))
        fields.append(QgsField("snum", QVariant.Int))

        (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT,
                                               context, fields)

        # Compute the number of steps to display within the progress bar and
        # get features from source
        #total = 100.0 / resultlayer.featureCount() if resultlayer.featureCount() else 0
        #features = resultlayer.getFeatures()

        sqlstr = 'select address, vn  from temp_vlayer;'

        c = conn.cursor()

        for row in c.execute(sqlstr):

            #for current, feature in enumerate(list1):
            # Stop the algorithm if cancel button has been clicked
            if feedback.isCanceled():
                break

            nfeature = QgsFeature(fields)

            nfeature['address'] = row[0]
            nfeature['snum'] = int(row[1])
            sink.addFeature(nfeature, QgsFeatureSink.FastInsert)

            # Update the progress bar
            #feedback.setProgress(int(current * total))

        conn.close()

        # Return the results of the algorithm. In this case our only result is
        # the feature sink which contains the processed features, but some
        # algorithms may return multiple feature sinks, calculated numeric
        # statistics, etc. These should all be included in the returned
        # dictionary, with keys matching the feature corresponding parameter
        # or output names.
        return {self.OUTPUT: dest_id}
Exemple #33
0
 def _resolveTemporary(self, alg):
     ext = self.getDefaultFileExtension()
     return QgsProcessingUtils.generateTempFilename(self.name + '.' + ext)
Exemple #34
0
    def processAlgorithm(self, parameters, context, feedback):
        commands = list()
        self.exportedLayers = {}

        self.preProcessInputs()
        extent = None
        crs = None

        # 1: Export rasters to sgrd and vectors to shp
        # Tables must be in dbf format. We check that.
        for param in self.parameterDefinitions():
            if isinstance(param, QgsProcessingParameterRasterLayer):
                if param.name() not in parameters or parameters[param.name()] is None:
                    continue

                if isinstance(parameters[param.name()], str):
                    if parameters[param.name()].lower().endswith('sdat'):
                        self.exportedLayers[param.name()] = parameters[param.name()][:-4] + 'sgrd'
                    elif parameters[param.name()].lower().endswith('sgrd'):
                        self.exportedLayers[param.name()] = parameters[param.name()]
                    else:
                        layer = self.parameterAsRasterLayer(parameters, param.name(), context)
                        exportCommand = self.exportRasterLayer(param.name(), layer)
                        if exportCommand is not None:
                            commands.append(exportCommand)
                else:
                    if parameters[param.name()].source().lower().endswith('sdat'):
                        self.exportedLayers[param.name()] = parameters[param.name()].source()[:-4] + 'sgrd'
                    if parameters[param.name()].source().lower().endswith('sgrd'):
                        self.exportedLayers[param.name()] = parameters[param.name()].source()
                    else:
                        exportCommand = self.exportRasterLayer(param.name(), parameters[param.name()])
                        if exportCommand is not None:
                            commands.append(exportCommand)
            elif isinstance(param, QgsProcessingParameterFeatureSource):
                if param.name() not in parameters or parameters[param.name()] is None:
                    continue

                if not crs:
                    source = self.parameterAsSource(parameters, param.name(), context)
                    if source is None:
                        raise QgsProcessingException(self.invalidSourceError(parameters, param.name()))

                    crs = source.sourceCrs()

                layer_path = self.parameterAsCompatibleSourceLayerPath(parameters, param.name(), context, ['shp'], 'shp', feedback=feedback)
                if layer_path:
                    self.exportedLayers[param.name()] = layer_path
                else:
                    raise QgsProcessingException(
                        self.tr('Unsupported file format'))
            elif isinstance(param, QgsProcessingParameterMultipleLayers):
                if param.name() not in parameters or parameters[param.name()] is None:
                    continue

                layers = self.parameterAsLayerList(parameters, param.name(), context)
                if layers is None or len(layers) == 0:
                    continue
                if param.layerType() == QgsProcessing.TypeRaster:
                    files = []
                    for i, layer in enumerate(layers):
                        if layer.source().lower().endswith('sdat'):
                            files.append(layer.source()[:-4] + 'sgrd')
                        if layer.source().lower().endswith('sgrd'):
                            files.append(layer.source())
                        else:
                            exportCommand = self.exportRasterLayer(param.name(), layer)
                            files.append(self.exportedLayers[param.name()])
                            if exportCommand is not None:
                                commands.append(exportCommand)

                    self.exportedLayers[param.name()] = files
                else:
                    for layer in layers:
                        temp_params = {}
                        temp_params[param.name()] = layer

                        if not crs:
                            source = self.parameterAsSource(temp_params, param.name(), context)
                            if source is None:
                                raise QgsProcessingException(self.invalidSourceError(parameters, param.name()))

                            crs = source.sourceCrs()

                        layer_path = self.parameterAsCompatibleSourceLayerPath(temp_params, param.name(), context, ['shp'], 'shp',
                                                                               feedback=feedback)
                        if layer_path:
                            if param.name() in self.exportedLayers:
                                self.exportedLayers[param.name()].append(layer_path)
                            else:
                                self.exportedLayers[param.name()] = [layer_path]
                        else:
                            raise QgsProcessingException(
                                self.tr('Unsupported file format'))

        # 2: Set parameters and outputs
        command = self.undecorated_group + ' "' + self.cmdname + '"'
        command += ' ' + ' '.join(self.hardcoded_strings)

        for param in self.parameterDefinitions():
            if not param.name() in parameters or parameters[param.name()] is None:
                continue
            if param.isDestination():
                continue

            if isinstance(param, (QgsProcessingParameterRasterLayer, QgsProcessingParameterFeatureSource)):
                command += ' -{} "{}"'.format(param.name(), self.exportedLayers[param.name()])
            elif isinstance(param, QgsProcessingParameterMultipleLayers):
                if parameters[param.name()]: # parameter may have been an empty list
                    command += ' -{} "{}"'.format(param.name(), ';'.join(self.exportedLayers[param.name()]))
            elif isinstance(param, QgsProcessingParameterBoolean):
                if self.parameterAsBoolean(parameters, param.name(), context):
                    command += ' -{} true'.format(param.name().strip())
                else:
                    command += ' -{} false'.format(param.name().strip())
            elif isinstance(param, QgsProcessingParameterMatrix):
                tempTableFile = getTempFilename('txt')
                with open(tempTableFile, 'w') as f:
                    f.write('\t'.join([col for col in param.headers()]) + '\n')
                    values = self.parameterAsMatrix(parameters, param.name(), context)
                    for i in range(0, len(values), 3):
                        s = '{}\t{}\t{}\n'.format(values[i], values[i + 1], values[i + 2])
                        f.write(s)
                command += ' -{} "{}"'.format(param.name(), tempTableFile)
            elif isinstance(param, QgsProcessingParameterExtent):
                # 'We have to substract/add half cell size, since SAGA is
                # center based, not corner based
                halfcell = self.getOutputCellsize(parameters, context) / 2
                offset = [halfcell, -halfcell, halfcell, -halfcell]
                rect = self.parameterAsExtent(parameters, param.name(), context)

                values = []
                values.append(rect.xMinimum())
                values.append(rect.xMaximum())
                values.append(rect.yMinimum())
                values.append(rect.yMaximum())

                for i in range(4):
                    command += ' -{} {}'.format(param.name().split(' ')[i], float(values[i]) + offset[i])
            elif isinstance(param, QgsProcessingParameterNumber):
                if param.dataType() == QgsProcessingParameterNumber.Integer:
                    command += ' -{} {}'.format(param.name(), self.parameterAsInt(parameters, param.name(), context))
                else:
                    command += ' -{} {}'.format(param.name(), self.parameterAsDouble(parameters, param.name(), context))
            elif isinstance(param, QgsProcessingParameterEnum):
                command += ' -{} {}'.format(param.name(), self.parameterAsEnum(parameters, param.name(), context))
            elif isinstance(param, (QgsProcessingParameterString, QgsProcessingParameterFile)):
                command += ' -{} "{}"'.format(param.name(), self.parameterAsFile(parameters, param.name(), context))
            elif isinstance(param, (QgsProcessingParameterString, QgsProcessingParameterField)):
                command += ' -{} "{}"'.format(param.name(), self.parameterAsString(parameters, param.name(), context))

        output_layers = []
        output_files = {}
        #If the user has entered an output file that has non-ascii chars, we use a different path with only ascii chars
        output_files_nonascii = {}
        for out in self.destinationParameterDefinitions():
            filePath = self.parameterAsOutputLayer(parameters, out.name(), context)
            if isinstance(out, (QgsProcessingParameterRasterDestination, QgsProcessingParameterVectorDestination)):
                output_layers.append(filePath)
                try:
                    filePath.encode('ascii')
                except UnicodeEncodeError:
                    nonAsciiFilePath = filePath
                    filePath = QgsProcessingUtils.generateTempFilename(out.name() + os.path.splitext(filePath)[1])
                    output_files_nonascii[filePath] = nonAsciiFilePath

            output_files[out.name()] = filePath
            command += ' -{} "{}"'.format(out.name(), filePath)
            commands.append(command)

        # special treatment for RGB algorithm
        # TODO: improve this and put this code somewhere else
        for out in self.destinationParameterDefinitions():
            if isinstance(out, QgsProcessingParameterRasterDestination):
                filename = self.parameterAsOutputLayer(parameters, out.name(), context)
                filename2 = os.path.splitext(filename)[0] + '.sgrd'
                if self.cmdname == 'RGB Composite':
                    commands.append('io_grid_image 0 -COLOURING 4 -GRID:"{}" -FILE:"{}"'.format(filename2, filename))

        # 3: Run SAGA
        commands = self.editCommands(commands)
        SagaUtils.createSagaBatchJobFileFromSagaCommands(commands)
        loglines = []
        loglines.append(self.tr('SAGA execution commands'))
        for line in commands:
            feedback.pushCommandInfo(line)
            loglines.append(line)
        if ProcessingConfig.getSetting(SagaUtils.SAGA_LOG_COMMANDS):
            QgsMessageLog.logMessage('\n'.join(loglines), self.tr('Processing'), Qgis.Info)
        SagaUtils.executeSaga(feedback)

        if crs is not None:
            for out in output_layers:
                prjFile = os.path.splitext(out)[0] + '.prj'
                with open(prjFile, 'w') as f:
                    f.write(crs.toWkt())

        for old, new in output_files_nonascii.items():
            oldFolder = os.path.dirname(old)
            newFolder = os.path.dirname(new)
            newName = os.path.splitext(os.path.basename(new))[0]
            files = [f for f in os.listdir(oldFolder)]
            for f in files:
                ext = os.path.splitext(f)[1]
                newPath = os.path.join(newFolder, newName + ext)
                oldPath = os.path.join(oldFolder, f)
                shutil.move(oldPath, newPath)

        result = {}
        for o in self.outputDefinitions():
            if o.name() in output_files:
                result[o.name()] = output_files[o.name()]
        return result
Exemple #35
0
 def _resolveTemporary(self, alg):
     if alg.provider().supportsNonFileBasedOutput():
         return "memory:"
     else:
         ext = self.getDefaultFileExtension()
         return QgsProcessingUtils.generateTempFilename(self.name + '.' + ext)
    def processAlgorithm(self, parameters, context, feedback):
        self.dest_id = None
        # Parameters
        # lighting = self.parameterAsVectorLayer(parameters, self.LIGHTING, context)
        lighting_source, lighting_layer = qgsTreatments.parameterAsSourceLayer(
            self, parameters, self.LIGHTING, context, feedback=feedback)
        if not lighting_source:
            raise QgsProcessingException("No lighting layer")
        fieldname = self.parameterAsString(parameters, self.FLUX_FIELD,
                                           context)
        if not fieldname:
            raise QgsProcessingException("No field given for light flux")
        flux_div_flag = self.parameterAsBool(parameters, self.FLUX_DIV,
                                             context)
        reporting, reporting_layer = qgsTreatments.parameterAsSourceLayer(
            self, parameters, self.REPORTING, context, feedback=feedback)
        if not reporting:
            raise QgsProcessingException("No reporting layer")
        init_reporting_fields = reporting_layer.fields().names()
        surface, surface_layer = qgsTreatments.parameterAsSourceLayer(
            self, parameters, self.SURFACE, context, feedback=feedback)
        dissolve_flag = self.parameterAsBool(parameters, self.DISSOLVE,
                                             context)
        clip_val = self.parameterAsInt(parameters, self.CLIP_DISTANCE, context)
        reporting_fields = self.parameterAsFields(parameters,
                                                  self.REPORTING_FIELDS,
                                                  context)
        skip_flag = self.parameterAsBool(parameters, self.SKIP_EMPTY, context)
        min_area = self.parameterAsDouble(parameters, self.MIN_AREA, context)
        min_lamps = self.parameterAsInt(parameters, self.MIN_NB_LAMPS, context)

        # Reprojection if needed
        light_crs = lighting_source.sourceCrs().authid()
        reporting_crs = reporting.sourceCrs()
        # reporting_crs = reporting.dataProvider().sourceCrs()
        if reporting_crs.isGeographic():
            raise QgsProcessingException(
                "Reporting CRS must be a projection (not lat/lon)")
        feedback.pushDebugInfo("reporting_crs = " + str(type(reporting_crs)))
        feedback.pushDebugInfo("reporting_crs = " + str(reporting_crs))
        reporting_crs_id = reporting_crs.authid()
        feedback.pushDebugInfo("reporting_crs_id = " +
                               str(type(reporting_crs_id)))
        feedback.pushDebugInfo("reporting_crs_id = " + str(reporting_crs_id))
        if light_crs != reporting_crs_id:
            lighting_path = QgsProcessingUtils.generateTempFilename(
                'light_reproj.gpkg')
            qgsTreatments.applyReprojectLayer(lighting_layer,
                                              reporting_crs,
                                              lighting_path,
                                              context=context,
                                              feedback=feedback)
            lighting_layer = lighting_path
        if surface:
            surface_crs = surface.sourceCrs().authid()
            if reporting_crs_id != surface_crs:
                surface_reproj = QgsProcessingUtils.generateTempFilename(
                    'surface_reproj.gpkg')
                qgsTreatments.applyReprojectLayer(surface_layer,
                                                  reporting_crs,
                                                  surface_reproj,
                                                  context=context,
                                                  feedback=feedback)
                surface_fixed = QgsProcessingUtils.generateTempFilename(
                    'surface_fixed.gpkg')
                qgsTreatments.fixGeometries(surface_reproj,
                                            surface_fixed,
                                            context=context,
                                            feedback=feedback)
                surface_layer = qgsUtils.loadVectorLayer(surface_fixed)
                qgsTreatments.createSpatialIndex(surface_layer,
                                                 context=context,
                                                 feedback=feedback)

        # Output fields initialization
        nb_lamps_field = QgsField(self.NB_LAMPS, QVariant.Int)
        flux_sum_field = QgsField(self.FLUX_SUM, QVariant.Double)
        surface_field = QgsField(self.SURFACE_AREA, QVariant.Double)
        flux_den_field = QgsField(self.FLUX_DEN, QVariant.Double)
        out_fields = QgsFields()
        for f in reporting_layer.fields():
            if f.name() in reporting_fields:
                # feedback.pushDebugInfo("f2 = " + str( f.name()))
                out_fields.append(f)
        out_fields.append(nb_lamps_field)
        out_fields.append(flux_sum_field)
        out_fields.append(surface_field)
        out_fields.append(flux_den_field)
        (sink, self.dest_id) = self.parameterAsSink(parameters, self.OUTPUT,
                                                    context, out_fields,
                                                    reporting.wkbType(),
                                                    reporting.sourceCrs())

        # Progess bar step
        nb_feats = reporting.featureCount()
        total = 100.0 / nb_feats if nb_feats else 0

        # Clip according to distance to lighting
        if clip_val:
            buffered_path = QgsProcessingUtils.generateTempFilename(
                'light_buf.gpkg')
            buffered = qgsTreatments.applyBufferFromExpr(lighting_layer,
                                                         clip_val,
                                                         buffered_path,
                                                         context=context,
                                                         feedback=feedback)
            clipped_path = QgsProcessingUtils.generateTempFilename(
                'reporting_clip.gpkg')
            qgsTreatments.createSpatialIndex(reporting_layer,
                                             context=context,
                                             feedback=feedback)
            clipped = qgsTreatments.applyVectorClip(reporting_layer,
                                                    buffered_path,
                                                    clipped_path,
                                                    context=context,
                                                    feedback=feedback)
            reporting_layer = clipped_path

        # Get reporting units count per light
        if flux_div_flag:
            if 'ID' in init_reporting_fields:
                id_field = 'ID'
            elif 'fid' in init_reporting_fields:
                id_field = 'fid'
            else:
                raise QgsProcessingException(
                    "ID field does not exist in reporting layer")
            qgsTreatments.createSpatialIndex(lighting_layer,
                                             context=context,
                                             feedback=feedback)
            joined_light_path = QgsProcessingUtils.generateTempFilename(
                'joined_light.gpkg')
            qgsTreatments.joinByLocSummary(lighting_layer,
                                           reporting_layer,
                                           joined_light_path, [id_field],
                                           summaries=[0],
                                           predicates=[0],
                                           context=context,
                                           feedback=feedback)
            joined_light_layer = qgsUtils.loadVectorLayer(joined_light_path)
            id_cpt_name = id_field + '_count'

            def funcDiv(f):
                if f[fieldname]:
                    try:
                        flux = float(f[fieldname])
                        nb_units = int(f[id_cpt_name])
                        return flux / nb_units
                    except ValueError:
                        return None
                else:
                    return None

            qgsUtils.createOrUpdateField(joined_light_layer, funcDiv,
                                         self.FLUX_DIV_FIELD)
            lighting_layer, fieldname = joined_light_layer, self.FLUX_DIV_FIELD
        # Join light points summary by reporting unit
        joined_path = QgsProcessingUtils.generateTempFilename('joined.gpkg')
        # SUM = 5
        summaries = [0, 1, 2, 3, 5, 6]
        qgsTreatments.createSpatialIndex(reporting_layer,
                                         context=context,
                                         feedback=feedback)
        joined = qgsTreatments.joinByLocSummary(reporting_layer,
                                                lighting_layer,
                                                joined_path, [fieldname],
                                                summaries,
                                                predicates=[0],
                                                context=context,
                                                feedback=feedback)
        joined_layer = qgsUtils.loadVectorLayer(joined_path)
        nb_lamps_fieldname = fieldname + "_count"
        flux_field_sum = fieldname + "_sum"

        # Set context and feedback
        if not context:
            context = QgsProcessingContext()
        context = context.setInvalidGeometryCheck(
            QgsFeatureRequest.GeometryNoCheck)
        multi_feedback = QgsProcessingMultiStepFeedback(nb_feats, feedback)

        # Iteration on each reporting unit
        qgsTreatments.createSpatialIndex(joined_layer,
                                         context=context,
                                         feedback=feedback)
        for current, feat in enumerate(joined_layer.getFeatures()):
            if feedback.isCanceled():
                break
            f_geom = feat.geometry()
            f_area = f_geom.area()
            f_id = feat.id()
            nb_lamps = feat[nb_lamps_fieldname]
            flux_sum = feat[flux_field_sum]
            if skip_flag and flux_sum == 0:
                continue
            if f_area < min_area:
                continue
            if nb_lamps < min_lamps:
                continue

            try:
                if surface:
                    # Clip surface layer to reporting feature boundaries to retrieve intersecting area
                    nb_steps = 4 if dissolve_flag else 3
                    mmf = QgsProcessingMultiStepFeedback(
                        nb_steps, multi_feedback)
                    joined_layer.selectByIds([f_id])
                    suffix = "_" + str(f_id) + ".gpkg"
                    input_feat = QgsProcessingUtils.generateTempFilename(
                        "selection" + suffix)
                    qgsTreatments.saveSelectedAttributes(joined_layer,
                                                         input_feat,
                                                         context=context,
                                                         feedback=mmf)
                    mmf.setCurrentStep(1)
                    # input_feat = QgsProcessingFeatureSourceDefinition(joined_layer.id(),True)
                    clipped_path = QgsProcessingUtils.generateTempFilename(
                        "clipped" + str(f_id) + ".gpkg")
                    clipped = qgsTreatments.applyVectorClip(surface_layer,
                                                            input_feat,
                                                            clipped_path,
                                                            context=context,
                                                            feedback=mmf)
                    mmf.setCurrentStep(2)
                    if dissolve_flag:
                        feat_surface_path = QgsProcessingUtils.generateTempFilename(
                            "dissolved" + str(f_id) + ".gpkg")
                        qgsTreatments.dissolveLayer(clipped,
                                                    feat_surface_path,
                                                    context=context,
                                                    feedback=mmf)
                        mmf.setCurrentStep(3)
                    else:
                        feat_surface_path = clipped_path
                    feat_surface_layer = qgsUtils.loadVectorLayer(
                        feat_surface_path)
                    joined_layer.removeSelection()

                    surface_area = 0
                    for surface_feat in feat_surface_layer.getFeatures():
                        surface_geom = surface_feat.geometry()
                        intersection = f_geom.intersection(surface_geom)
                        surface_area += intersection.area()
                    mmf.setCurrentStep(nb_steps)
                else:
                    surface_area = f_area

                # Output result feature
                new_feat = QgsFeature(out_fields)
                new_feat.setGeometry(feat.geometry())
                for report_field in reporting_fields:
                    new_feat[report_field] = feat[report_field]
                new_feat[self.NB_LAMPS] = nb_lamps
                new_feat[self.FLUX_SUM] = flux_sum
                new_feat[self.SURFACE_AREA] = surface_area
                new_feat[
                    self.
                    FLUX_DEN] = flux_sum / surface_area if surface_area > 0 else None
                sink.addFeature(new_feat, QgsFeatureSink.FastInsert)
            except Exception as e:
                feedback.reportError('Unexpected error : ' + str(e))
                raise e

            multi_feedback.setCurrentStep(current + 1)

        return {self.OUTPUT: self.dest_id}
    def processAlgorithm(self, parameters, context, model_feedback):
        # Use a multi-step feedback, so that individual child algorithm progress reports are adjusted for the
        # overall progress through the model
        feedback = QgsProcessingMultiStepFeedback(5, model_feedback)
        results = {}
        outputs = {}

        MNT = self.parameterAsRasterLayer(parameters, self.INPUT, context)
        emprise = self.parameterAsVectorLayer(parameters, self.EMPRISE,
                                              context)
        dZ = self.parameterAsDouble(parameters, self.DZ, context)
        fichier_html = self.parameterAsFileOutput(parameters, self.OUTPUT,
                                                  context)
        fichier_txt = "{}.txt".format(os.path.splitext(fichier_html)[0])

        if parameters[self.MAXZ] == None:
            maxZ = 99999
        else:
            maxZ = self.parameterAsDouble(parameters, self.MAXZ, context)

        # Découper un raster selon une couche de masquage
        alg_params = {
            "ALPHA_BAND": False,
            "CROP_TO_CUTLINE": True,
            "DATA_TYPE": 0,
            "EXTRA": "",
            "INPUT": MNT.source(),
            "KEEP_RESOLUTION": True,
            "MASK": emprise,
            "MULTITHREADING": False,
            "NODATA": None,
            "OPTIONS": "",
            "SET_RESOLUTION": False,
            "SOURCE_CRS": None,
            "TARGET_CRS": "ProjectCrs",
            "X_RESOLUTION": None,
            "Y_RESOLUTION": None,
            "OUTPUT": QgsProcessing.TEMPORARY_OUTPUT,
        }
        outputs["Clip"] = processing.run(
            "gdal:cliprasterbymasklayer",
            alg_params,
            context=context,
            feedback=feedback,
            is_child_algorithm=True,
        )

        feedback.setCurrentStep(1)
        if feedback.isCanceled():
            return {}

        # Polygones Courbes de niveau
        alg_params = {
            "BAND": 1,
            "CREATE_3D": False,
            "EXTRA": "",
            "FIELD_NAME_MAX": "ELEV_MAX",
            "FIELD_NAME_MIN": "ELEV_MIN",
            "IGNORE_NODATA": False,
            "INPUT": outputs["Clip"]["OUTPUT"],
            "INTERVAL": dZ,
            "NODATA": None,
            "OFFSET": 0,
            "OUTPUT": QgsProcessing.TEMPORARY_OUTPUT,
        }
        outputs["PolygonesCourbesDeNiveau"] = processing.run(
            "gdal:contour_polygon",
            alg_params,
            context=context,
            feedback=feedback,
            is_child_algorithm=True,
        )

        feedback.setCurrentStep(2)
        if feedback.isCanceled():
            return {}

        # Collecter les géométries
        alg_params = {
            "FIELD": ["ELEV_MIN"],
            "INPUT": outputs["PolygonesCourbesDeNiveau"]["OUTPUT"],
            "OUTPUT": QgsProcessing.TEMPORARY_OUTPUT,
        }
        outputs["CollectGeom"] = processing.run("native:collect",
                                                alg_params,
                                                context=context,
                                                feedback=feedback,
                                                is_child_algorithm=True)

        feedback.setCurrentStep(3)
        if feedback.isCanceled():
            return {}

        # Calcul "Surface"
        layer = QgsProcessingUtils.generateTempFilename("layer.shp")
        alg_params = {
            "FIELD_LENGTH": 12,
            "FIELD_NAME": "Surface",
            "FIELD_PRECISION": 2,
            "FIELD_TYPE": 0,
            "FORMULA": "$area",
            "INPUT": outputs["CollectGeom"]["OUTPUT"],
            "OUTPUT": layer,
        }
        outputs["CalculSurface"] = processing.run(
            "native:fieldcalculator",
            alg_params,
            context=context,
            feedback=feedback,
            is_child_algorithm=True,
        )

        feedback.setCurrentStep(4)
        if feedback.isCanceled():
            return {}

        fields = QgsFields()
        fields.append(QgsField("Z", QVariant.Double))
        fields.append(QgsField("Surface", QVariant.Double))
        fields.append(QgsField("Volume", QVariant.Double))
        (couche, dest_id) = self.parameterAsSink(
            parameters,
            self.OUTPUT2,
            context,
            fields,
            QgsWkbTypes.NoGeometry,
            QgsProject.instance().crs(),
        )

        with open(fichier_html, "w") as f_html, open(fichier_txt,
                                                     "w") as f_txt:
            f_html.write("""
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Courbe HSV</title>
    <style>
    html {
      font-family: sans-serif;
    }

    table {
      border-collapse: collapse;
      border: 2px solid rgb(200,200,200);
      letter-spacing: 1px;
      font-size: 0.8rem;
    }
    
    td, th {
      border: 1px solid rgb(190,190,190);
      padding: 10px 20px;
    }

    td {
      text-align: center;
    }

    caption {
      padding: 10px;
    }
    </style>
  </head>
  <body>
    <h1>Courbe HSV</h1>

    <table>
        <tr>
            <th>Z</th>
            <th>Surface (m&sup2;)</th>
            <th>Volume (m&sup3;)</th>
        </tr>
""")
            f_txt.write("Z\tSurface\tVolume\n")

            z = []
            surface = []
            volume = []

            vLayer = QgsVectorLayer(layer, "temp")

            request = QgsFeatureRequest()

            # Ordonner par ELEV_MIN ascendant
            clause = QgsFeatureRequest.OrderByClause("ELEV_MIN",
                                                     ascending=True)
            orderby = QgsFeatureRequest.OrderBy([clause])
            request.setOrderBy(orderby)

            for current, feat in enumerate(vLayer.getFeatures(request)):
                if feedback.isCanceled():
                    return {}
                if feat["ELEV_MAX"] > maxZ:
                    break
                if current == 0:
                    z.append(round(feat["ELEV_MAX"], 2))
                    surface.append(round(feat["Surface"], 2))
                    volume.append(round(feat["Surface"] * dZ / 2, 2))
                else:
                    z.append(round(feat["ELEV_MAX"], 2))
                    surface.append(round(surface[-1] + feat["Surface"], 2))
                    volume.append(
                        round(
                            feat["Surface"] * dZ / 2 + surface[-2] * dZ +
                            volume[-1], 2))

                self.writeHTMLTableLine(f_html, z[-1], surface[-1], volume[-1])
                f_txt.write("{}\t{}\t{}\n".format(z[-1], surface[-1],
                                                  volume[-1]))

                if couche is not None:
                    fet = QgsFeature()
                    tabAttr = [z[-1], surface[-1], volume[-1]]
                    fet.setAttributes(tabAttr)
                    couche.addFeature(fet)

            f_html.write("""
    </table>

  </body>
</html>
""")

        return {self.OUTPUT: fichier_html, self.OUTPUT2: dest_id}
    def processAlgorithm(self, parameters, context, model_feedback):
        # Use a multi-step feedback, so that individual child algorithm progress reports are adjusted for the
        # overall progress through the model
        feedback = QgsProcessingMultiStepFeedback(23, model_feedback)
        results = {}
        outputs = {}

        # r.resample CFM
        alg_params = {
            'GRASS_RASTER_FORMAT_META': '',
            'GRASS_RASTER_FORMAT_OPT': '',
            'GRASS_REGION_CELLSIZE_PARAMETER': parameters['CellSize'],
            'GRASS_REGION_PARAMETER': parameters['ConfidenceMapRaster'],
            'input': parameters['ConfidenceMapRaster'],
            'output': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['RresampleCfm'] = processing.run('grass7:r.resample', alg_params, context=context, feedback=feedback,
                                                 is_child_algorithm=True)

        feedback.setCurrentStep(1)
        iter = 1
        if feedback.isCanceled():
            return {}
        iter = iter + 1

        # r.resample TLI
        alg_params = {
            'GRASS_RASTER_FORMAT_META': '',
            'GRASS_RASTER_FORMAT_OPT': '',
            'GRASS_REGION_CELLSIZE_PARAMETER': parameters['CellSize'],
            'GRASS_REGION_PARAMETER': parameters['ConfidenceMapRaster'],
            'input': parameters['TLI'],
            'output': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['RresampleTli'] = processing.run('grass7:r.resample', alg_params, context=context, feedback=feedback,
                                                 is_child_algorithm=True)

        feedback.setCurrentStep(iter)
        if feedback.isCanceled():
            return {}
        iter = iter + 1

        # RedTmp classify
        alg_params = {
            'DATA_TYPE': 3,
            'INPUT_RASTER': outputs['RresampleCfm']['output'],
            'NODATA_FOR_MISSING': False,
            'NO_DATA': -9999,
            'RANGE_BOUNDARIES': 0,
            'RASTER_BAND': 1,
            'TABLE': [-0.001, 3, 1, 3, 6, 0],
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['RedtmpClassify'] = processing.run('native:reclassifybytable', alg_params, context=context,
                                                   feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(iter)
        if feedback.isCanceled():
            return {}
        iter = iter + 1

        # r.resample IDW
        alg_params = {
            'GRASS_RASTER_FORMAT_META': '',
            'GRASS_RASTER_FORMAT_OPT': '',
            'GRASS_REGION_CELLSIZE_PARAMETER': parameters['CellSize'],
            'GRASS_REGION_PARAMETER': parameters['ConfidenceMapRaster'],
            'input': parameters['IDW'],
            'output': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['RresampleIdw'] = processing.run('grass7:r.resample', alg_params, context=context, feedback=feedback,
                                                 is_child_algorithm=True)

        feedback.setCurrentStep(iter)
        if feedback.isCanceled():
            return {}
        iter = iter + 1

        # tmpRed Neighbours
        alg_params = {
            '-a': False,
            '-c': False,
            'GRASS_RASTER_FORMAT_META': '',
            'GRASS_RASTER_FORMAT_OPT': '',
            'GRASS_REGION_CELLSIZE_PARAMETER': 0,
            'GRASS_REGION_PARAMETER': None,
            'gauss': None,
            'input': outputs['RedtmpClassify']['OUTPUT'],
            'method': 1,
            'quantile': '',
            'selection': None,
            'size': 11,
            'weight': '',
            'output': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['TmpredNeighbours'] = processing.run('grass7:r.neighbors', alg_params, context=context,
                                                     feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(iter)
        if feedback.isCanceled():
            return {}
        iter = iter + 1

        # allToOne
        alg_params = {
            'DATA_TYPE': 5,
            'INPUT_RASTER': outputs['RresampleIdw']['output'],
            'NODATA_FOR_MISSING': False,
            'NO_DATA': -9999,
            'RANGE_BOUNDARIES': 0,
            'RASTER_BAND': 1,
            'TABLE': [-9998, 9999999999, 1],
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['Alltoone'] = processing.run('native:reclassifybytable', alg_params, context=context, feedback=feedback,
                                             is_child_algorithm=True)

        feedback.setCurrentStep(iter)
        if feedback.isCanceled():
            return {}
        iter = iter + 1

        # Reclassify redtmpOneNodata
        alg_params = {
            'DATA_TYPE': 3,
            'INPUT_RASTER': outputs['TmpredNeighbours']['output'],
            'NODATA_FOR_MISSING': True,
            'NO_DATA': -9999,
            'RANGE_BOUNDARIES': 2,
            'RASTER_BAND': 1,
            'TABLE': [1, 1, 1],
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['ReclassifyRedtmponenodata'] = processing.run('native:reclassifybytable', alg_params, context=context,
                                                              feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(iter)
        if feedback.isCanceled():
            return {}
        iter = iter + 1

        # Translate 1
        alg_params = {
            'COPY_SUBDATASETS': False,
            'DATA_TYPE': 5,
            'EXTRA': '',
            'INPUT': outputs['Alltoone']['OUTPUT'],
            'NODATA': 0,
            'OPTIONS': '',
            'TARGET_CRS': None,
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['Translate1'] = processing.run('gdal:translate', alg_params, context=context, feedback=feedback,
                                               is_child_algorithm=True)

        feedback.setCurrentStep(iter)
        if feedback.isCanceled():
            return {}
        iter = iter + 1

        # r.grow 2 cells tmpred
        alg_params = {
            '-m': False,
            'GRASS_RASTER_FORMAT_META': '',
            'GRASS_RASTER_FORMAT_OPT': '',
            'GRASS_REGION_CELLSIZE_PARAMETER': 0,
            'GRASS_REGION_PARAMETER': None,
            'input': outputs['ReclassifyRedtmponenodata']['OUTPUT'],
            'metric': 0,
            'new': 1,
            'old': 1,
            'radius': parameters['REDgrowradiusinrastercells'],
            'output': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['Rgrow2CellsTmpred'] = processing.run('grass7:r.grow', alg_params, context=context, feedback=feedback,
                                                      is_child_algorithm=True)

        feedback.setCurrentStep(iter)
        if feedback.isCanceled():
            return {}
        iter = iter + 1

        # Translate redGrow
        alg_params = {
            'COPY_SUBDATASETS': False,
            'DATA_TYPE': 0,
            'EXTRA': '',
            'INPUT': outputs['Rgrow2CellsTmpred']['output'],
            'NODATA': 0,
            'OPTIONS': '',
            'TARGET_CRS': None,
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['TranslateRedgrow'] = processing.run('gdal:translate', alg_params, context=context, feedback=feedback,
                                                     is_child_algorithm=True)

        feedback.setCurrentStep(iter)
        if feedback.isCanceled():
            return {}
        iter = iter + 1

        # Reclassify nodata to zero red
        alg_params = {
            'DATA_TYPE': 3,
            'INPUT_RASTER': outputs['TranslateRedgrow']['OUTPUT'],
            'NODATA_FOR_MISSING': False,
            'NO_DATA': -9999,
            'RANGE_BOUNDARIES': 2,
            'RASTER_BAND': 1,
            'TABLE': [-999999, 0.09, 0, 1, 1.01, 1, 2, 999999, 0],
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['ReclassifyNodataToZeroRed'] = processing.run('native:reclassifybytable', alg_params, context=context,
                                                              feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(iter)
        if feedback.isCanceled():
            return {}
        iter = iter + 1

        # OneZeroTable
        alg_params = {
            'DATA_TYPE': 3,
            'INPUT_RASTER': outputs['Translate1']['OUTPUT'],
            'NODATA_FOR_MISSING': False,
            'NO_DATA': -9999,
            'RANGE_BOUNDARIES': 2,
            'RASTER_BAND': 1,
            'TABLE': [-999999999, 0.9, 1, 1, 1, 0, 1.1, 9999999, 1],
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['Onezerotable'] = processing.run('native:reclassifybytable', alg_params, context=context,
                                                 feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(iter)
        if feedback.isCanceled():
            return {}
        iter = iter + 1

        # red minus idw Null
        alg_params = {
            'BAND_A': 1,
            'BAND_B': 1,
            'BAND_C': None,
            'BAND_D': None,
            'BAND_E': None,
            'BAND_F': None,
            'EXTRA': '',
            'FORMULA': 'A-B',
            'INPUT_A': outputs['ReclassifyNodataToZeroRed']['OUTPUT'],
            'INPUT_B': outputs['Onezerotable']['OUTPUT'],
            'INPUT_C': None,
            'INPUT_D': None,
            'INPUT_E': None,
            'INPUT_F': None,
            'NO_DATA': None,
            'OPTIONS': '',
            'RTYPE': 4,
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['RedMinusIdwNull'] = processing.run('gdal:rastercalculator', alg_params, context=context,
                                                    feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(iter)
        if feedback.isCanceled():
            return {}
        iter = iter + 1

        # MakeredNodata
        alg_params = {
            '-c': False,
            '-f': False,
            '-i': False,
            '-n': False,
            '-r': False,
            'GRASS_RASTER_FORMAT_META': '',
            'GRASS_RASTER_FORMAT_OPT': '',
            'GRASS_REGION_CELLSIZE_PARAMETER': parameters['CellSize'],
            'GRASS_REGION_PARAMETER': outputs['RresampleCfm']['output'],
            'map': outputs['RedMinusIdwNull']['OUTPUT'],
            'null': None,
            'setnull': '0',
            'output': QgsProcessingUtils.generateTempFilename('redforbuffer.tif')
        }
        redforbuffer = alg_params['output']
        outputs['Makerednodata'] = processing.run('grass7:r.null', alg_params, context=context, feedback=feedback,
                                                  is_child_algorithm=True)

        feedback.setCurrentStep(iter)
        if feedback.isCanceled():
            return {}
        iter = iter + 1

        # blueTmp reclass
        alg_params = {
            'DATA_TYPE': 3,
            'INPUT_RASTER': outputs['RedMinusIdwNull']['OUTPUT'],
            'NODATA_FOR_MISSING': False,
            'NO_DATA': -9999,
            'RANGE_BOUNDARIES': 2,
            'RASTER_BAND': 1,
            'TABLE': [1, 1, 0, 0, 0, 1],
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['BluetmpReclass'] = processing.run('native:reclassifybytable', alg_params, context=context,
                                                   feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(iter)
        if feedback.isCanceled():
            return {}
        iter = iter + 1

        # r.buffer
        alg_params = {
            '-z': False,
            'GRASS_RASTER_FORMAT_META': '',
            'GRASS_RASTER_FORMAT_OPT': '',
            'GRASS_REGION_CELLSIZE_PARAMETER': 0,
            'GRASS_REGION_PARAMETER': None,
            'distances': '1',
            'input': redforbuffer,
            'units': 0,
            'output': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['Rbuffer'] = processing.run('grass7:r.buffer', alg_params, context=context, feedback=feedback,
                                            is_child_algorithm=True)

        feedback.setCurrentStep(iter)
        if feedback.isCanceled():
            return {}
        iter = iter + 1

        # Translate (convert format)
        alg_params = {
            'COPY_SUBDATASETS': False,
            'DATA_TYPE': 0,
            'EXTRA': '',
            'INPUT': outputs['Rbuffer']['output'],
            'NODATA': 0,
            'OPTIONS': '',
            'TARGET_CRS': None,
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['TranslateConvertFormat'] = processing.run('gdal:translate', alg_params, context=context,
                                                           feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(iter)
        if feedback.isCanceled():
            return {}
        iter = iter + 1

        # Reclassify nodata to zero
        alg_params = {
            'DATA_TYPE': 3,
            'INPUT_RASTER': outputs['TranslateConvertFormat']['OUTPUT'],
            'NODATA_FOR_MISSING': False,
            'NO_DATA': -9999,
            'RANGE_BOUNDARIES': 0,
            'RASTER_BAND': 1,
            'TABLE': [-1, 1, 0, 1, 2, 1, 2, 256, 0],
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['ReclassifyNodataToZero'] = processing.run('native:reclassifybytable', alg_params, context=context,
                                                           feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(iter)
        if feedback.isCanceled():
            return {}
        iter = iter + 1

        # blueCalculator
        alg_params = {
            'BAND_A': 1,
            'BAND_B': 1,
            'BAND_C': None,
            'BAND_D': None,
            'BAND_E': None,
            'BAND_F': None,
            'EXTRA': '',
            'FORMULA': 'A-B',
            'INPUT_A': outputs['BluetmpReclass']['OUTPUT'],
            'INPUT_B': outputs['ReclassifyNodataToZero']['OUTPUT'],
            'INPUT_C': None,
            'INPUT_D': None,
            'INPUT_E': None,
            'INPUT_F': None,
            'NO_DATA': None,
            'OPTIONS': '',
            'RTYPE': 4,
            'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
        }
        outputs['Bluecalculator'] = processing.run('gdal:rastercalculator', alg_params, context=context,
                                                   feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(iter)
        if feedback.isCanceled():
            return {}
        iter = iter + 1

        # Raster calculator
        alg_params = {
            'BAND_A': 1,
            'BAND_B': 1,
            'BAND_C': 1,
            'BAND_D': 1,
            'BAND_E': 1,
            'BAND_F': None,
            'EXTRA': '',
            'FORMULA': '(C*A) + (D*B) + (((A+B)/2)*E)',
            'INPUT_A': outputs['RresampleTli']['output'],
            'INPUT_B': outputs['RresampleIdw']['output'],
            'INPUT_C': outputs['Bluecalculator']['OUTPUT'],
            'INPUT_D': outputs['RedMinusIdwNull']['OUTPUT'],
            'INPUT_E': outputs['ReclassifyNodataToZero']['OUTPUT'],
            'INPUT_F': None,
            'NO_DATA': None,
            'OPTIONS': '',
            'RTYPE': 5,
            'OUTPUT': QgsProcessingUtils.generateTempFilename('DFM_hybrid.tif')
        }
        DFM_hybrid = alg_params['OUTPUT']
        outputs['RasterCalculator'] = processing.run('gdal:rastercalculator', alg_params, context=context,
                                                     feedback=feedback, is_child_algorithm=True)

        feedback.setCurrentStep(iter)
        if feedback.isCanceled():
            return {}
        iter = iter + 1

        # r.patch
        alg_params = {
            '-z': False,
            'GRASS_RASTER_FORMAT_META': '',
            'GRASS_RASTER_FORMAT_OPT': '',
            'GRASS_REGION_CELLSIZE_PARAMETER': 0,
            'GRASS_REGION_PARAMETER': None,
            'input': [DFM_hybrid, outputs['RresampleTli']['output']],
            'output': QgsProcessingUtils.generateTempFilename('dfmpatched.tif')
        }
        outputs['Rpatch'] = processing.run('grass7:r.patch', alg_params, context=context, feedback=feedback,
                                           is_child_algorithm=True)
        DFMPatched = outputs['Rpatch']['output']

        feedback.setCurrentStep(iter)
        if feedback.isCanceled():
            return {}
        iter = iter + 1

        # Warp (reproject)
        alg_params = {
            'DATA_TYPE': 0,
            'EXTRA': '',
            'INPUT': DFMPatched,
            'MULTITHREADING': False,
            'NODATA': None,
            'OPTIONS': '',
            'RESAMPLING': 0,
            'SOURCE_CRS': parameters['CRS'],
            'TARGET_CRS': parameters['CRS'],
            'TARGET_EXTENT': None,
            'TARGET_EXTENT_CRS': None,
            'TARGET_RESOLUTION': None,
            'OUTPUT': QgsProcessingUtils.generateTempFilename('dfmpatched.tif')
        }

        outputs['WarpReproject'] = processing.run('gdal:warpreproject', alg_params, context=context,
                                                  feedback=feedback,
                                                  is_child_algorithm=True)
        DFMPatched = outputs['WarpReproject']['OUTPUT']

        feedback.setCurrentStep(iter)
        if feedback.isCanceled():
            return {}
        iter = iter + 1

        if parameters['loadDFM']:
            # Load layer into project
            alg_params = {
                'INPUT': DFMPatched,
                'NAME': parameters['prefix'] + 'DFM'
            }


            outputs['LoadLayerIntoProject'] = processing.run('native:loadlayer', alg_params, context=context,
                                                         feedback=feedback, is_child_algorithm=True)

        results['Dfm'] = DFMPatched

        feedback.setCurrentStep(iter)
        if feedback.isCanceled():
            return {}
        iter = iter + 1

        return results
Exemple #39
0
 def applyItemWithContext(self, item, context, feedback):
     mode = int(item.dict["mode"])
     friction_layer_path = self.bdModel.getOrigPath(item.dict["friction"])
     pond_layer_path = self.bdModel.getOrigPath(item.dict["ponderation"])
     out_layer_path = self.bdModel.getOrigPath(item.dict["out_layer"])
     feedback.setProgressText("weighted layer " + item.dict["out_layer"])
     weighting_params = {
         'INPUT_LAYER': friction_layer_path,
         'WEIGHT_LAYER': pond_layer_path,
         'RESAMPLING': None,
         'OUTPUT': out_layer_path
     }
     if mode == self.MULT_MODE:
         weighting_params['OPERATOR'] = 2
         qgsTreatments.applyProcessingAlg('BioDispersal',
                                          'weightingbasics',
                                          weighting_params,
                                          context=context,
                                          feedback=feedback)
     elif mode == self.INTERVALS_MODE:
         ival_model = PondValueIvalModel.fromStr(item.dict["intervals"])
         matrix = ival_model.toProcessingMatrix()
         weighting_params['INTERVALS'] = matrix
         qgsTreatments.applyProcessingAlg('BioDispersal',
                                          'weightingbyintervals',
                                          weighting_params,
                                          context=context,
                                          feedback=feedback)
     elif mode == self.BUFFER_MODE:
         ival_model = PondBufferIvalModel.fromStr(item.dict["intervals"])
         matrix = ival_model.toProcessingMatrix()
         weighting_params['INTERVALS'] = matrix
         tmp_path = QgsProcessingUtils.generateTempFilename(
             'buffer_tmp.tif')
         weighting_params['OUTPUT'] = tmp_path
         qgsTreatments.applyProcessingAlg('BioDispersal',
                                          'weightingbydistance',
                                          weighting_params,
                                          context=context,
                                          feedback=feedback)
         qgsTreatments.applyTranslate(tmp_path,
                                      out_layer_path,
                                      context=context,
                                      feedback=feedback)
     elif mode == self.MAX_MODE:
         weighting_params['OPERATOR'] = 1
         qgsTreatments.applyProcessingAlg('BioDispersal',
                                          'weightingbasics',
                                          weighting_params,
                                          context=context,
                                          feedback=feedback)
     elif mode == self.MIN_MODE:
         weighting_params['OPERATOR'] = 0
         qgsTreatments.applyProcessingAlg('BioDispersal',
                                          'weightingbasics',
                                          weighting_params,
                                          context=context,
                                          feedback=feedback)
     else:
         utils.internal_error("Unexpected ponderation mode '" + str(mode) +
                              "'")
     loaded_layer = qgsUtils.loadRasterLayer(out_layer_path,
                                             loadProject=True)
     data_type = loaded_layer.dataProvider().dataType(1)
     feedback.pushDebugInfo("data_type = " + str(data_type))
     if qgsUtils.qgisTypeIsInteger(data_type):
         styles.setRendererPalettedGnYlRd(loaded_layer)
     else:
         styles.setRendererPalettedGnYlRd(loaded_layer)
 def processAlgorithm(self, parameters, context, feedback):
     # Parameters
     input_source, input_layer = qgsTreatments.parameterAsSourceLayer(self,
         parameters,self.INPUT,context,feedback=feedback)
     modes = self.parameterAsEnums(parameters,self.MODE,context)
     input_raster = self.parameterAsRasterLayer(parameters,self.INPUT_RASTER,context)
     band = self.parameterAsInt(parameters,self.BAND,context)
     pop_field = self.parameterAsString(parameters,self.POPULATION_FIELD,context)
     # surf_field = self.parameterAsString(parameters,self.SURFACE_FIELD,context)
     # output = self.parameterAsOutputLayer(parameters,self.OUTPUT,context)
     # Init
     input_crs = input_source.sourceCrs().authid()
     raster_crs = input_raster.dataProvider().crs().authid()
     pop_mode, surf_mode = 0 in modes, 1 in modes
     nb_feats = input_layer.featureCount()
     multi_feedback = QgsProcessingMultiStepFeedback(nb_feats * 2,feedback)
     # CRS
     if (input_crs != raster_crs):
         raster_reprojected = QgsProcessingUtils.generateTempFilename('raster_reproj.tif')
         qgsTreatments.applyWarpReproject(input_raster,raster_reprojected,
             dst_crs=input_crs,context=context,feedback=multi_feedback)
         input_raster = qgsUtils.loadRasterLayer(raster_reprojected)
         multi_feedback.setCurrentStep(1)
     pixel_size = input_raster.rasterUnitsPerPixelX() * input_raster.rasterUnitsPerPixelY()
     # Zonal stats
     prefix = 'rad_'
     zonal_stats = QgsProcessingUtils.generateTempFilename('zonal_stats.gpkg')
     qgsTreatments.rasterZonalStats(input_layer,input_raster,zonal_stats,
         prefix=prefix,band=band,context=context,feedback=multi_feedback)
     multi_feedback.setCurrentStep(nb_feats)
     # Fields
     stats_layer = qgsUtils.loadVectorLayer(zonal_stats)
     stats_fields = stats_layer.fields()
     stats_fieldnames = stats_fields.names()
     if pop_mode and pop_field not in stats_fieldnames:
         raise QgsProcessingException("No population field '" + str(pop_field) + "' in input layer")
     # if surf_field_mode and surf_field not in stats_fieldnames:
         # raise QgsProcessingException("No area field '" + str(surf_field) + "' in input layer")
     rad_pop_field = QgsField(self.RAD_POP_FIELDNAME, QVariant.Double)
     rad_surf_field = QgsField(self.RAD_SURF_FIELDNAME, QVariant.Double)
     out_fields = QgsFields(stats_fields)
     out_fields.append(rad_pop_field)
     out_fields.append(rad_surf_field)
     (sink, self.dest_id) = self.parameterAsSink(parameters, self.OUTPUT,
         context, out_fields, input_source.wkbType(), input_source.sourceCrs())
     # Division
     stats_layer = qgsUtils.loadVectorLayer(zonal_stats)
     for current, feat in enumerate(stats_layer.getFeatures()):
         new_feat = QgsFeature(out_fields)
         new_feat.setGeometry(feat.geometry())
         for field in stats_layer.fields().names():
             if field != 'fid':
                 new_feat[field] = feat[field]
         rad_sum = float(feat[prefix + 'sum'])
         rad_mean = float(feat[prefix + 'mean'])
         if (pop_mode and feat[pop_field]):
             new_feat[self.RAD_POP_FIELDNAME] = (rad_sum / feat[pop_field]) * 1000
         if surf_mode:
             new_feat[self.RAD_SURF_FIELDNAME] = (rad_mean / pixel_size) * 1000000
         sink.addFeature(new_feat, QgsFeatureSink.FastInsert)
         self.pop_mode, self.surf_mode = pop_mode, surf_mode
         multi_feedback.setCurrentStep(current + nb_feats)
         
     return { self.OUTPUT : self.dest_id }
Exemple #41
0
    def processAlgorithm(self, parameters, context, feedback):  # pylint: disable=missing-docstring,too-many-statements,too-many-branches,too-many-locals
        commands = []
        self.exportedLayers = {}

        self.preProcessInputs()
        crs = None

        # 1: Export rasters to sgrd and vectors to shp
        # Tables must be in dbf format. We check that.
        for param in self.parameterDefinitions():  # pylint:disable=too-many-nested-blocks
            if isinstance(param, QgsProcessingParameterRasterLayer):
                if param.name(
                ) not in parameters or parameters[param.name()] is None:
                    continue

                if isinstance(parameters[param.name()], str):
                    if parameters[param.name()].lower().endswith('sdat'):
                        self.exportedLayers[param.name(
                        )] = parameters[param.name()][:-4] + 'sgrd'
                    elif parameters[param.name()].lower().endswith('sgrd'):
                        self.exportedLayers[param.name()] = parameters[
                            param.name()]
                    else:
                        layer = self.parameterAsRasterLayer(
                            parameters, param.name(), context)
                        exportCommand = self.exportRasterLayer(
                            param.name(), layer)
                        if exportCommand is not None:
                            commands.append(exportCommand)
                else:
                    if parameters[param.name()].source().lower().endswith(
                            'sdat'):
                        self.exportedLayers[param.name(
                        )] = parameters[param.name()].source()[:-4] + 'sgrd'
                    if parameters[param.name()].source().lower().endswith(
                            'sgrd'):
                        self.exportedLayers[param.name()] = parameters[
                            param.name()].source()
                    else:
                        exportCommand = self.exportRasterLayer(
                            param.name(), parameters[param.name()])
                        if exportCommand is not None:
                            commands.append(exportCommand)
            elif isinstance(param, QgsProcessingParameterFeatureSource):
                if param.name(
                ) not in parameters or parameters[param.name()] is None:
                    continue

                if not crs:
                    source = self.parameterAsSource(parameters, param.name(),
                                                    context)
                    if source is None:
                        raise QgsProcessingException(
                            self.invalidSourceError(parameters, param.name()))

                    crs = source.sourceCrs()

                layer_path = self.parameterAsCompatibleSourceLayerPath(
                    parameters,
                    param.name(),
                    context, ['shp'],
                    'shp',
                    feedback=feedback)
                if layer_path:
                    self.exportedLayers[param.name()] = layer_path
                else:
                    raise QgsProcessingException(
                        self.tr('Unsupported file format'))
            elif isinstance(param, QgsProcessingParameterMultipleLayers):
                if param.name(
                ) not in parameters or parameters[param.name()] is None:
                    continue

                layers = self.parameterAsLayerList(parameters, param.name(),
                                                   context)
                if layers is None or len(layers) == 0:
                    continue
                if param.layerType() == QgsProcessing.TypeRaster:
                    files = []
                    for i, layer in enumerate(layers):
                        if layer.source().lower().endswith('sdat'):
                            files.append(layer.source()[:-4] + 'sgrd')
                        elif layer.source().lower().endswith('sgrd'):
                            files.append(layer.source())
                        else:
                            exportCommand = self.exportRasterLayer(
                                param.name(), layer)
                            files.append(self.exportedLayers[param.name()])
                            if exportCommand is not None:
                                commands.append(exportCommand)

                    self.exportedLayers[param.name()] = files
                else:
                    for layer in layers:
                        temp_params = {param.name(): layer}
                        if not crs:
                            source = self.parameterAsSource(
                                temp_params, param.name(), context)
                            if source is None:
                                raise QgsProcessingException(
                                    self.invalidSourceError(
                                        parameters, param.name()))

                            crs = source.sourceCrs()

                        layer_path = self.parameterAsCompatibleSourceLayerPath(
                            temp_params,
                            param.name(),
                            context, ['shp'],
                            'shp',
                            feedback=feedback)
                        if layer_path:
                            if param.name() in self.exportedLayers:
                                self.exportedLayers[param.name()].append(
                                    layer_path)
                            else:
                                self.exportedLayers[param.name()] = [
                                    layer_path
                                ]
                        else:
                            raise QgsProcessingException(
                                self.tr('Unsupported file format'))

        # 2: Set parameters and outputs
        command = self.undecorated_group + ' "' + self.cmdname + '"'
        command += ' ' + ' '.join(self.hardcoded_strings)

        for param in self.parameterDefinitions():
            if param.name(
            ) not in parameters or parameters[param.name()] is None:
                continue
            if param.isDestination():
                continue

            if isinstance(param, (QgsProcessingParameterRasterLayer,
                                  QgsProcessingParameterFeatureSource)):
                command += ' -{} "{}"'.format(
                    param.name(), self.exportedLayers[param.name()])
            elif isinstance(param, QgsProcessingParameterMultipleLayers):
                if parameters[
                        param.name()]:  # parameter may have been an empty list
                    command += ' -{} "{}"'.format(
                        param.name(),
                        ';'.join(self.exportedLayers[param.name()]))
            elif isinstance(param, QgsProcessingParameterBoolean):
                if self.parameterAsBoolean(parameters, param.name(), context):
                    command += ' -{} true'.format(param.name().strip())
                else:
                    command += ' -{} false'.format(param.name().strip())
            elif isinstance(param, QgsProcessingParameterMatrix):
                tempTableFile = getTempFilename('txt')
                with open(tempTableFile, 'w', encoding='utf-8') as f:
                    f.write('\t'.join(param.headers()) + '\n')
                    values = self.parameterAsMatrix(parameters, param.name(),
                                                    context)
                    for i in range(0, len(values), 3):
                        s = '{}\t{}\t{}\n'.format(values[i], values[i + 1],
                                                  values[i + 2])
                        f.write(s)
                command += ' -{} "{}"'.format(param.name(), tempTableFile)
            elif isinstance(param, QgsProcessingParameterExtent):
                # 'We have to subtract/add half cell size, since SAGA is
                # center based, not corner based
                halfcell = self.getOutputCellsize(parameters, context) / 2
                offset = [halfcell, -halfcell, halfcell, -halfcell]
                rect = self.parameterAsExtent(parameters, param.name(),
                                              context)

                values = [
                    rect.xMinimum(),
                    rect.xMaximum(),
                    rect.yMinimum(),
                    rect.yMaximum(),
                ]

                for i in range(4):
                    command += ' -{} {}'.format(param.name().split(' ')[i],
                                                float(values[i]) + offset[i])
            elif isinstance(param, QgsProcessingParameterNumber):
                if param.dataType() == QgsProcessingParameterNumber.Integer:
                    command += ' -{} {}'.format(
                        param.name(),
                        self.parameterAsInt(parameters, param.name(), context))
                else:
                    command += ' -{} {}'.format(
                        param.name(),
                        self.parameterAsDouble(parameters, param.name(),
                                               context))
            elif isinstance(param, QgsProcessingParameterEnum):
                command += ' -{} {}'.format(
                    param.name(),
                    self.parameterAsEnum(parameters, param.name(), context))
            elif isinstance(
                    param,
                (QgsProcessingParameterString, QgsProcessingParameterFile)):
                command += ' -{} "{}"'.format(
                    param.name(),
                    self.parameterAsFile(parameters, param.name(), context))
            elif isinstance(
                    param,
                (QgsProcessingParameterString, QgsProcessingParameterField)):
                command += ' -{} "{}"'.format(
                    param.name(),
                    self.parameterAsString(parameters, param.name(), context))

        output_layers = []
        output_files = {}
        # If the user has entered an output file that has non-ascii chars, we use a different path with only ascii chars
        output_files_nonascii = {}
        for out in self.destinationParameterDefinitions():
            filePath = self.parameterAsOutputLayer(parameters, out.name(),
                                                   context)
            if isinstance(out, (QgsProcessingParameterRasterDestination,
                                QgsProcessingParameterVectorDestination)):
                output_layers.append(filePath)
                try:
                    filePath.encode('ascii')
                except UnicodeEncodeError:
                    nonAsciiFilePath = filePath
                    filePath = QgsProcessingUtils.generateTempFilename(
                        out.name() + os.path.splitext(filePath)[1])
                    output_files_nonascii[filePath] = nonAsciiFilePath

            output_files[out.name()] = filePath
            command += ' -{} "{}"'.format(out.name(), filePath)
        commands.append(command)

        # special treatment for RGB algorithm
        # TODO: improve this and put this code somewhere else
        if self.cmdname == 'RGB Composite':
            for out in self.destinationParameterDefinitions():
                if isinstance(out, QgsProcessingParameterRasterDestination):
                    filename = self.parameterAsOutputLayer(
                        parameters, out.name(), context)
                    filename2 = os.path.splitext(filename)[0] + '.sgrd'
                    commands.append(
                        'io_grid_image 0 -COLOURING 4 -GRID:"{}" -FILE:"{}"'.
                        format(filename2, filename))

        # 3: Run SAGA
        commands = self.editCommands(commands)
        SagaUtils.createSagaBatchJobFileFromSagaCommands(commands)
        loglines = [self.tr('SAGA execution commands')]
        for line in commands:
            feedback.pushCommandInfo(line)
            loglines.append(line)
        if ProcessingConfig.getSetting(SagaUtils.SAGA_LOG_COMMANDS):
            QgsMessageLog.logMessage('\n'.join(loglines),
                                     self.tr('Processing'), Qgis.Info)
        SagaUtils.executeSaga(feedback)

        if crs is not None:
            for out in output_layers:
                prjFile = os.path.splitext(out)[0] + '.prj'
                with open(prjFile, 'wt', encoding='utf-8') as f:
                    f.write(crs.toWkt())

        for old, new in output_files_nonascii.items():
            oldFolder = os.path.dirname(old)
            newFolder = os.path.dirname(new)
            newName = os.path.splitext(os.path.basename(new))[0]
            files = list(os.listdir(oldFolder))
            for f in files:
                ext = os.path.splitext(f)[1]
                newPath = os.path.join(newFolder, newName + ext)
                oldPath = os.path.join(oldFolder, f)
                shutil.move(oldPath, newPath)

        return {
            o.name(): output_files[o.name()]
            for o in self.outputDefinitions() if o.name() in output_files
        }
def writeConfiguration():
    cfg = configparser.ConfigParser()

    cfg["Options for advanced mode"] = {}
    section = cfg["Options for advanced mode"]
    section["ground_file_is_resistances"] = "True"
    section["remove_src_or_gnd"] = "keepall"
    section["ground_file"] = ""
    section["use_unit_currents"] = "False"
    section["source_file"] = ""
    section["use_direct_grounds"] = "False"

    cfg["Mask file"] = {}
    section = cfg["Mask file"]
    section["mask_file"] = ""
    section["use_mask"] = "False"

    cfg["Calculation options"] = {}
    section = cfg["Calculation options"]
    section["low_memory_mode"] = "False"
    section["parallelize"] = "False"
    section["solver"] = "cg+amg"
    section["print_timings"] = "True"
    section["preemptive_memory_release"] = str(ProcessingConfig.getSetting(PREEMPT_MEMORY))
    section["print_rusages"] = "False"
    section["max_parallel"] = "0"

    cfg["Short circuit regions (aka polygons)"] = {}
    section = cfg["Short circuit regions (aka polygons)"]
    section["polygon_file"] = ""
    section["use_polygons"] = "False"

    cfg["Options for one-to-all and all-to-one modes"] = {}
    section = cfg["Options for one-to-all and all-to-one modes"]
    section["use_variable_source_strengths"] = "False"
    section["variable_source_file"] = ""

    cfg["Output options"] = {}
    section = cfg["Output options"]
    section["set_null_currents_to_nodata"] = "False"
    section["set_focal_node_currents_to_zero"] = str(ProcessingConfig.getSetting(ZERO_FOCAL))
    section["set_null_voltages_to_nodata"] = "False"
    section["compress_grids"] = str(ProcessingConfig.getSetting(COMPRESS_OUTPUT))
    section["write_cur_maps"] = "True"
    section["write_volt_maps"] = "True"
    section["output_file"] = ""
    section["write_cum_cur_map_only"] = str(ProcessingConfig.getSetting(CUM_MAX_MAPS))
    section["log_transform_maps"] = str(ProcessingConfig.getSetting(LOG_TRANSFORM))
    section["write_max_cur_maps"] = str(ProcessingConfig.getSetting(MAX_CURRENT_MAPS))

    cfg["Options for reclassification of habitat data"] = {}
    section = cfg["Options for reclassification of habitat data"]
    section["reclass_file"] = ""
    section["use_reclass_table"] = "False"

    cfg["Logging Options"] = {}
    section = cfg["Logging Options"]
    section["log_level"] = "INFO"
    section["log_file"] = "None"
    section["profiler_log_file"] = "None"
    section["screenprint_log"] = "False"

    cfg["Options for pairwise and one-to-all and all-to-one modes"] = {}
    section = cfg["Options for pairwise and one-to-all and all-to-one modes"]
    section["included_pairs_file"] = ""
    section["use_included_pairs"] = "False"
    section["point_file"] = ""

    cfg["Connection scheme for raster habitat data"] = {}
    section = cfg["Connection scheme for raster habitat data"]
    section["connect_using_avg_resistances"] = str(ProcessingConfig.getSetting(AVERAGE_CONDUCTANCE))
    section["connect_four_neighbors_only"] = str(ProcessingConfig.getSetting(FOUR_NEIGHBOURS))

    cfg["Habitat raster or graph"] = {}
    section = cfg["Habitat raster or graph"]
    section["habitat_map_is_resistances"] = "True"
    section["Habitat raster or graph"] = "habitat_file"

    cfg["Circuitscape mode"] = {}
    section["data_type"] = "raster"
    section["scenario"] = ""

    iniPath = QgsProcessingUtils.generateTempFilename("circuitscape.ini")
    with open(iniPath, "w") as f:
        cfg.write(f)

    return iniPath