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())
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 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()
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
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
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)
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)
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)
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
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
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"]
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
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 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
def _resolveTemporary(self, alg): ext = self.getDefaultFileExtension() return QgsProcessingUtils.generateTempFilename(self.name + '.' + ext)
def filenamesToFile(files): listFile = QgsProcessingUtils.generateTempFilename("inputfiles.txt") with open(listFile, 'w', encoding='utf-8') as f: f.write('\n'.join(files)) return listFile
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, 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
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 {}
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}
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
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}
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}
def _resolveTemporary(self, alg): ext = self.getDefaultFileExtension() return QgsProcessingUtils.generateTempFilename(self.name + '.' + ext)
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
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²)</th> <th>Volume (m³)</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
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 }
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