def regroupRasters(alg, parameters, context, src, group, subgroup=None, extFile=None): """ Group multiple input rasters into a group * If there is a subgroupField, a subgroup will automatically be created. * When an external file is provided, the file is copied into the respective directory of the subgroup. :param parameters: :param context: :param src: name of input parameter with multiple rasters. :param group: name of group. :param subgroup: name of subgroup. :param extFile: dict : parameterName:directory name """ # Create a group parameter groupName = 'group_{}'.format(os.path.basename(getTempFilename())) param = QgsProcessingParameterString(group, 'virtual group', groupName, False, False) alg.addParameter(param) # Create a subgroup subgroupName = None if subgroup: subgroupName = 'subgroup_{}'.format(os.path.basename(getTempFilename())) param = QgsProcessingParameterString(subgroup, 'virtual subgroup', subgroupName, False, False) alg.addParameter(param) # Compute raster names rasters = alg.parameterAsLayerList(parameters, src, context) rasterNames = [] for idx, raster in enumerate(rasters): name = '{}_{}'.format(src, idx) if name in alg.exportedLayers: rasterNames.append(alg.exportedLayers[name]) # Insert a i.group command command = 'i.group group={}{} input={}'.format( groupName, ' subgroup={}'.format(subgroupName) if subgroup else '', ','.join(rasterNames)) alg.commands.append(command) # Handle external files # if subgroupField and extFile: # for ext in extFile.keys(): # extFileName = new_parameters[ext] # if extFileName: # shortFileName = os.path.basename(extFileName) # destPath = os.path.join(Grass7Utils.grassMapsetFolder(), # 'PERMANENT', # 'group', new_parameters[group.name()], # 'subgroup', new_parameters[subgroup.name()], # extFile[ext], shortFileName) # copyFile(alg, extFileName, destPath) alg.removeParameter(src) return groupName, subgroupName
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 = QSettings() systemEncoding = settings.value('/UI/encoding', 'System') output = getTempFilename('shp') basename = removeInvalidChars(os.path.basename(layer.source())) if basename: if not basename.endswith("shp"): basename = basename + ".shp" output = getTempFilenameInTempFolder(basename) else: output = getTempFilename("shp") provider = layer.dataProvider() useSelection = 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) del writer return output else: isASCII = True try: str(layer.source()).decode('ascii') except UnicodeEncodeError: isASCII = False if not os.path.splitext(layer.source())[1].lower() in supported or not isASCII: writer = QgsVectorFileWriter( output, systemEncoding, layer.fields(), layer.wkbType(), layer.crs() ) for feat in layer.getFeatures(): writer.addFeature(feat) del writer return output else: return str(layer.source())
def processAlgorithm(self, parameters, context, feedback): # TODO: check correct num of bands inLayer = self.parameterAsRasterLayer(parameters, self.INPUT, context) input = inLayer.source() temp = getTempFilename(None).replace('.', '') basename = os.path.basename(temp) validChars = \ 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' safeBasename = ''.join(c for c in basename if c in validChars) temp = os.path.join(os.path.dirname(temp), safeBasename) r = self.parameterAsOutputLayer(parameters, self.R, context) g = self.parameterAsOutputLayer(parameters, self.G, context) b = self.parameterAsOutputLayer(parameters, self.B, context) commands = [] version = SagaUtils.getInstalledVersion(True) trailing = "" lib = "" commands.append('%sio_gdal 0 -GRIDS "%s" -FILES "%s"' % (lib, temp, input) ) commands.append('%sio_gdal 1 -GRIDS "%s_%s1.sgrd" -FORMAT 1 -TYPE 0 -FILE "%s"' % (lib, temp, trailing, r) ) commands.append('%sio_gdal 1 -GRIDS "%s_%s2.sgrd" -FORMAT 1 -TYPE 0 -FILE "%s"' % (lib, temp, trailing, g) ) commands.append('%sio_gdal 1 -GRIDS "%s_%s3.sgrd" -FORMAT 1 -TYPE 0 -FILE "%s"' % (lib, temp, trailing, b) ) SagaUtils.createSagaBatchJobFileFromSagaCommands(commands) SagaUtils.executeSaga(feedback) return {self.R: r, self.G: g, self.B: b}
def on_btnAuto_clicked(self): if self.layer is None: return relief = QgsRelief(self.layer, system.getTempFilename(), 'GTiff') colors = relief.calculateOptimizedReliefClasses() self.populateColors(colors)
def processCommand(alg, parameters): # We temporary remove the output out = alg.getOutputFromName('output') mapParam = alg.getParameterValue('map') alg.exportedLayers[out.value] = alg.exportedLayers[mapParam] alg.removeOutputFromName('output') txtRulesParam = alg.getParameterFromName(u'txtrules') rules = alg.getParameterFromName(u'rules') # Handle inline rules if txtRulesParam.value: # Creates a temporary txt file tempRulesName = getTempFilename('txt') # Inject rules into temporary txt file with codecs.open(tempRulesName, 'w', 'utf-8') as tempRules: tempRules.write(txtRulesParam.value) # Replace rules with temporary file rules.value = tempRulesName alg.parameters.remove(txtRulesParam) alg.processCommand() # We re-add the new output alg.addOutput(out)
def loadVectorLayer(self, name, layer, external=False): """ Creates a dedicated command to load a vector into temporary GRASS DB. :param name: name of the parameter :param layer: QgsMapLayer for the vector layer. :param external: use v.external (v.in.ogr if False). """ # TODO: support multiple input formats if external is None: external = ProcessingConfig.getSetting( Grass7Utils.GRASS_USE_VEXTERNAL) # safety check: we can only use external for ogr layers which support random read if external: ds = ogr.Open(layer.source()) if ds is not None: ogr_layer = ds.GetLayer() if ogr_layer is None or not ogr_layer.TestCapability(ogr.OLCRandomRead): external = False else: external = False self.inputLayers.append(layer) self.setSessionProjectionFromLayer(layer) destFilename = 'vector_{}'.format(os.path.basename(getTempFilename())) self.exportedLayers[name] = destFilename command = '{0}{1}{2} input="{3}" output="{4}" --overwrite -o'.format( 'v.external' if external else 'v.in.ogr', ' min_area={}'.format(self.minArea) if not external else '', ' snap={}'.format(self.snapTolerance) if not external else '', os.path.normpath(layer.source()), destFilename) self.commands.append(command)
def processCommand(alg, parameters, context, feedback): # Temporary remove outputs and add a virtual output parameter outputName = 'output_{}'.format(os.path.basename(getTempFilename())) param = QgsProcessingParameterString('output', 'virtual output', outputName, False, False) alg.addParameter(param) alg.processCommand(parameters, context, feedback, True)
def orderedInput(alg, parameters, context, src, tgt, numSeq=None): """Import multiple rasters in order :param alg: algorithm object. :param parameters: algorithm parameters dict. :param context: algorithm context. :param src: Name of the source parameter. :param tgt: Name of a new input parameter. :param numSeq: List of a sequence for naming layers. """ rootFilename = 'rast_{}.'.format(os.path.basename(getTempFilename())) #parameters[tgt] = rootFilename param = QgsProcessingParameterString(tgt, 'virtual input', rootFilename, False, False) alg.addParameter(param) rasters = alg.parameterAsLayerList(parameters, src, context) # Handle specific range if numSeq is None: numSeq = list(range(1, len(rasters) + 1)) for idx, raster in enumerate(rasters): rasterName = '{}{}'.format(rootFilename, numSeq[idx]) alg.loadRasterLayer(rasterName, raster, False, None, rasterName) # Don't forget to remove the old input parameter alg.removeParameter(src)
def test_SagaVectorAlgorithWithUnsupportedInputAndOutputFormat(self): """This tests both the exporting to shp and then the format change in the output layer. """ layer = processing.getObject(polygonsGeoJson()) feature = layer.getFeatures().next() selected = [feature.id()] layer.setSelectedFeatures(selected) outputs = processing.runalg('saga:polygoncentroids', polygonsGeoJson(), True, getTempFilename('geojson')) layer.setSelectedFeatures([]) output = outputs['CENTROIDS'] layer = dataobjects.getObjectFromUri(output, True) fields = layer.pendingFields() expectednames = ['ID', 'POLY_NUM_A', 'POLY_ST_A'] expectedtypes = ['Real', 'Real', 'String'] names = [unicode(f.name()) for f in fields] types = [unicode(f.typeName()) for f in fields] self.assertEqual(expectednames, names) self.assertEqual(expectedtypes, types) features = processing.features(layer) self.assertEqual(1, len(features)) feature = features.next() attrs = feature.attributes() expectedvalues = ['0', '1.1', 'string a'] values = [unicode(attr) for attr in attrs] self.assertEqual(expectedvalues, values) wkt = 'POINT(270787.49991451 4458955.46775295)' self.assertEqual(wkt, unicode(feature.geometry().exportToWkt()))
def processAlgorithm(self, feedback): # TODO: check correct num of bands input = self.getParameterValue(SplitRGBBands.INPUT) temp = getTempFilename(None).replace('.', '') basename = os.path.basename(temp) validChars = \ 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' safeBasename = ''.join(c for c in basename if c in validChars) temp = os.path.join(os.path.dirname(temp), safeBasename) r = self.getOutputValue(SplitRGBBands.R) g = self.getOutputValue(SplitRGBBands.G) b = self.getOutputValue(SplitRGBBands.B) commands = [] version = SagaUtils.getSagaInstalledVersion(True) # NOQA trailing = "" lib = "" commands.append('%sio_gdal 0 -GRIDS "%s" -FILES "%s"' % (lib, temp, input) ) commands.append('%sio_gdal 1 -GRIDS "%s_%s1.sgrd" -FORMAT 1 -TYPE 0 -FILE "%s"' % (lib, temp, trailing, r) ) commands.append('%sio_gdal 1 -GRIDS "%s_%s2.sgrd" -FORMAT 1 -TYPE 0 -FILE "%s"' % (lib, temp, trailing, g) ) commands.append('%sio_gdal 1 -GRIDS "%s_%s3.sgrd" -FORMAT 1 -TYPE 0 -FILE "%s"' % (lib, temp, trailing, b) ) SagaUtils.createSagaBatchJobFileFromSagaCommands(commands) SagaUtils.executeSaga(feedback)
def test_gdalogrsieveWithUnsupportedOutputFormat(self): outputs = processing.runalg('gdalogr:sieve', raster(), 2, 0, getTempFilename('img')) output = outputs['dst_filename'] self.assertTrue(os.path.isfile(output)) dataset = gdal.Open(output, GA_ReadOnly) strhash = hash(str(dataset.ReadAsArray(0).tolist())) self.assertEqual(strhash, -1353696889)
def test_SagaRasterAlgorithmWithUnsupportedOutputFormat(self): outputs = processing.runalg('saga:convergenceindex', raster(), 0, 0, getTempFilename('img')) output = outputs['RESULT'] self.assertTrue(os.path.isfile(output)) dataset = gdal.Open(output, GA_ReadOnly) strhash = hash(unicode(dataset.ReadAsArray(0).tolist())) self.assertEqual(strhash, 485390137)
def configFile(alg, parameters, context, feedback, outputTxt=False): """Handle inline configuration :param parameters: """ # Where is the GRASS7 user directory ? userGrass7Path = rliPath() if not os.path.isdir(userGrass7Path): mkdir(userGrass7Path) if not os.path.isdir(os.path.join(userGrass7Path, 'output')): mkdir(os.path.join(userGrass7Path, 'output')) # If we have a configuration file, we need to copy it into user dir if parameters['config']: fileName = alg.parameterAsString(parameters, 'config', context) configFilePath = os.path.join(userGrass7Path, os.path.basename(fileName)) # Copy the file shutil.copy(parameters['config'], configFilePath) # Change the parameter value parameters['config'] = os.path.basename(configFilePath) # Handle inline configuration elif parameters['config_txt']: # Creates a temporary txt file in user r.li directory tempConfig = os.path.basename(getTempFilename()) configFilePath = os.path.join(userGrass7Path, tempConfig) # Inject rules into temporary txt file with open(configFilePath, "w") as f: f.write(alg.parameterAsString(parameters, 'config_txt', context)) f.write("\n") # Use temporary file as rules file parameters['config'] = os.path.basename(configFilePath) alg.removeParameter('config_txt') # For ascii output, we need a virtual output if outputTxt: param = QgsProcessingParameterString( 'output', 'virtual output', 'a' + os.path.basename(getTempFilename()), False, False) alg.addParameter(param) alg.processCommand(parameters, context, feedback, outputTxt) # Remove Config file: removeConfigFile(alg, parameters, context)
def processCommand(alg, parameters, context, feedback): """ Handle data preparation for v.net.distance: * Integrate point layers into network vector map. * Make v.net.distance use those layers. * Delete the threshold parameter. * If where statement, connect to the db """ # Grab the point layer and delete this parameter lineLayer = alg.exportedLayers['input'] fromLayer = alg.exportedLayers['flayer'] toLayer = alg.exportedLayers['tlayer'] intLayer = 'bufnet' + os.path.basename(getTempFilename()) netLayer = 'net' + os.path.basename(getTempFilename()) threshold = alg.parameterAsDouble(parameters, 'threshold', context) # Create the v.net connect command for from_layer integration command = u"v.net input={} points={} output={} operation=connect threshold={} arc_layer=1 node_layer=2".format( lineLayer, fromLayer, intLayer, threshold) alg.commands.append(command) # Do it again with to_layer command = u"v.net input={} points={} output={} operation=connect threshold={} arc_layer=1 node_layer=3".format( intLayer, toLayer, netLayer, threshold) alg.commands.append(command) # Connect the point layer database to the layer 2 of the network command = u"v.db.connect -o map={} table={} layer=2".format(netLayer, fromLayer) alg.commands.append(command) command = u"v.db.connect -o map={} table={} layer=3".format(netLayer, toLayer) alg.commands.append(command) # remove undesired parameters alg.removeParameter('flayer') alg.removeParameter('tlayer') alg.removeParameter('threshold') alg.exportedLayers['input'] = netLayer # Add the two new parameters fLayer = QgsProcessingParameterString('from_layer', None, 2, False, False) alg.addParameter(fLayer) tLayer = QgsProcessingParameterString('to_layer', None, 3, False, False) alg.addParameter(tLayer) alg.processCommand(parameters, context, feedback)
def processAlgorithm(self, progress): if ProcessingConfig.getSetting(ProcessingConfig.USE_SELECTED): progress.setInfo("**********************************************************************\n"\ "WARNING: sDNA ignores your selection and will process the entire layer\n"\ "**********************************************************************") args = {} for outname,output in zip(self.outputnames,self.outputs): if hasattr(output,"getCompatibleFileName"): args[outname]=output.getCompatibleFileName(self) elif hasattr(output,"getValueAsCommandLineParameter"): args[outname]=output.getValueAsCommandLineParameter().replace('"','') # strip quotes - sdna adds them again else: assert False # don't know what to do with this output type for vn in self.varnames: args[vn]=self.getParameterValue(vn) if vn in self.selectvaroptions: args[vn] = self.selectvaroptions[vn][args[vn]] if args[vn]==None: args[vn]="" syntax = self.sdnatool.getSyntax(args) # convert inputs to shapefiles if necessary, renaming in syntax as appropriate converted_inputs={} for name,path in syntax["inputs"].iteritems(): if path: # convert inputs to shapefiles if they aren't already shp or csv # do this by hand rather than using dataobjects.exportVectorLayer(processing.getObject(path)) # as we want to ignore selection if present if path[-4:].lower() not in [".shp",".csv"]: progress.setInfo("Converting input to shapefile: "+path) tempfile = system.getTempFilename("shp") ret = QgsVectorFileWriter.writeAsVectorFormat(processing.getObject(path), tempfile, "utf-8", None, "ESRI Shapefile") assert(ret == QgsVectorFileWriter.NoError) converted_inputs[name]=tempfile else: converted_inputs[name]=path syntax["inputs"]=converted_inputs # figure out where the qgis python installation is qgisbase = os.path.dirname(os.path.dirname(sys.executable)) pythonexe = qgisbase+os.sep+"bin"+os.sep+"python.exe" pythonbase = qgisbase+os.sep+"apps"+os.sep+"python27"+os.sep pythonpath = ";".join([pythonbase+x for x in ["","Lib","Lib/site-packages"]]) retval = self.provider.runsdnacommand(syntax,self.provider.sdnapath,progress,pythonexe,pythonpath) if retval!=0: progress.setInfo("ERROR: PROCESS DID NOT COMPLETE SUCCESSFULLY")
def processCommand(alg, parameters, context, feedback): # handle inline points inlinePoints = alg.parameterAsString(parameters, 'inline_points', context) if inlinePoints: # Creates a temporary txt file pointsName = getTempFilename() # Inject rules into temporary txt file with open(pointsName, "w") as tempPoints: tempPoints.write(inlinePoints) alg.removeParameter('inline_points') parameters['points'] = tempPoints alg.processCommand(parameters, context, feedback, True)
def processCommand(alg, parameters, context, feedback): # Handle inline rules txtRules = alg.parameterAsString(parameters, 'txtrules', context) if txtRules: # Creates a temporary txt file tempRulesName = getTempFilename() # Inject rules into temporary txt file with open(tempRulesName, "w") as tempRules: tempRules.write(txtRules) alg.removeParameter('txtrules') parameters['rules'] = tempRulesName alg.processCommand(parameters, context, feedback, True)
def loadAttributeTable(self, name, layer, destName=None): """ Creates a dedicated command to load an attribute table into the temporary GRASS DB. :param name: name of the input parameter. :param layer: a layer object to import from. :param destName: force the name for the table into GRASS DB. """ self.inputLayers.append(layer) if not destName: destName = 'table_{}'.format(os.path.basename(getTempFilename())) self.exportedLayers[name] = destName command = 'db.in.ogr --overwrite input="{0}" output="{1}"'.format( os.path.normpath(layer.source()), destName) self.commands.append(command)
def loadVectorLayer(self, name, layer, external=False, feedback=None): """ Creates a dedicated command to load a vector into temporary GRASS DB. :param name: name of the parameter :param layer: QgsMapLayer for the vector layer. :param external: use v.external (v.in.ogr if False). :param feedback: feedback object """ # TODO: support multiple input formats if external is None: external = ProcessingConfig.getSetting( Grass7Utils.GRASS_USE_VEXTERNAL) source_parts = QgsProviderRegistry.instance().decodeUri('ogr', layer.source()) file_path = source_parts.get('path') layer_name = source_parts.get('layerName') # safety check: we can only use external for ogr layers which support random read if external: if feedback is not None: feedback.pushInfo('Attempting to use v.external for direct layer read') ds = ogr.Open(file_path) if ds is not None: ogr_layer = ds.GetLayer() if ogr_layer is None or not ogr_layer.TestCapability(ogr.OLCRandomRead): if feedback is not None: feedback.reportError('Cannot use v.external: layer does not support random read') external = False else: if feedback is not None: feedback.reportError('Cannot use v.external: error reading layer') external = False self.inputLayers.append(layer) self.setSessionProjectionFromLayer(layer) destFilename = 'vector_{}'.format(os.path.basename(getTempFilename())) self.exportedLayers[name] = destFilename command = '{0}{1}{2} input="{3}"{4} output="{5}" --overwrite -o'.format( 'v.external' if external else 'v.in.ogr', ' min_area={}'.format(self.minArea) if not external else '', ' snap={}'.format(self.snapTolerance) if not external else '', os.path.normpath(file_path), ' layer="{}"'.format(layer_name) if layer_name else '', destFilename) self.commands.append(command)
def incorporatePoints(alg, parameters, context, feedback, pointLayerName='points', networkLayerName='input'): """ incorporate points with lines to form a GRASS network """ # Grab the point layer and delete this parameter pointLayer = alg.parameterAsVectorLayer(parameters, pointLayerName, context) if pointLayer: # Create an intermediate GRASS layer which is the combination of network + centers intLayer = 'net' + os.path.basename(getTempFilename()) pointLayer = alg.exportedLayers[pointLayerName] # Grab the network layer lineLayer = alg.parameterAsVectorLayer(parameters, networkLayerName, context) if lineLayer: lineLayer = alg.exportedLayers[networkLayerName] else: raise QgsProcessingException( alg.tr('GRASS GIS 7 v.net requires a lines layer!')) threshold = alg.parameterAsDouble(parameters, 'threshold', context) # Create the v.net connect command for point layer integration command = u"v.net input={} points={} output={} operation=connect threshold={}".format( lineLayer, pointLayer, intLayer, threshold) alg.commands.append(command) # Connect the point layer database to the layer 2 of the network command = u"v.db.connect -o map={} table={} layer=2".format(intLayer, pointLayer) alg.commands.append(command) # remove undesired parameters alg.removeParameter(pointLayerName) # Use temp layer for input alg.exportedLayers[networkLayerName] = intLayer # Process the command if 'threshold' in parameters: alg.removeParameter('threshold') alg.processCommand(parameters, context, feedback)
def loadRasterLayer(self, name, layer, external=True, band=1): """ Creates a dedicated command to load a raster into the temporary GRASS DB. :param name: name of the parameter. :param layer: QgsMapLayer for the raster layer. :param external: True if using r.external. :param band: imports only specified band. None for all bands. """ self.inputLayers.append(layer) self.setSessionProjectionFromLayer(layer) destFilename = 'a' + os.path.basename(getTempFilename()) self.exportedLayers[name] = destFilename command = '{0} input="{1}" {2}output="{3}" --overwrite -o'.format( 'r.external' if external else 'r.in.gdal', os.path.normpath(layer.source()), 'band={} '.format(band) if band else '', destFilename) self.commands.append(command)
def test_gdalogrogr2ogrWrongExtension(self): outputs = processing.runalg('gdalogr:ogr2ogr', union(), 3, '', getTempFilename('wrongext')) output = outputs['OUTPUT_LAYER'] layer = dataobjects.getObjectFromUri(output, True) fields = layer.pendingFields() expectednames = [ 'id', 'poly_num_a', 'poly_st_a', 'id_2', 'poly_num_b', 'poly_st_b', ] expectedtypes = [ 'Integer', 'Real', 'String', 'Integer', 'Real', 'String', ] names = [str(f.name()) for f in fields] types = [str(f.typeName()) for f in fields] self.assertEqual(expectednames, names) self.assertEqual(expectedtypes, types) features = processing.features(layer) self.assertEqual(8, len(features)) feature = features.next() attrs = feature.attributes() expectedvalues = [ '1', '1.1', 'string a', '2', '1', 'string a', ] values = [str(attr) for attr in attrs] self.assertEqual(expectedvalues, values) wkt = 'POLYGON((270807.08580285 4458940.1594565,270798.42294527 4458914.62661676,270780.81854858 4458914.21983449,270763.52289518 4458920.715993,270760.3449542 4458926.6570575,270763.78234766 4458958.22561242,270794.30290024 4458942.16424502,270807.08580285 4458940.1594565))' self.assertEqual(wkt, str(feature.geometry().exportToWkt()))
def processAlgorithm(self, progress): # TODO: check correct num of bands input = self.getParameterValue(SplitRGBBands.INPUT) temp = getTempFilename(None).replace('.', '') basename = os.path.basename(temp) validChars = \ 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' safeBasename = ''.join(c for c in basename if c in validChars) temp = os.path.join(os.path.dirname(temp), safeBasename) r = self.getOutputValue(SplitRGBBands.R) g = self.getOutputValue(SplitRGBBands.G) b = self.getOutputValue(SplitRGBBands.B) commands = [] if isWindows(): commands.append('io_gdal 0 -GRIDS "' + temp + '" -FILES "' + input + '"') commands.append('io_gdal 1 -GRIDS "' + temp + '_0001.sgrd" -FORMAT 1 -TYPE 0 -FILE "' + r + '"' ) commands.append('io_gdal 1 -GRIDS "' + temp + '_0002.sgrd" -FORMAT 1 -TYPE 0 -FILE "' + g + '"' ) commands.append('io_gdal 1 -GRIDS "' + temp + '_0003.sgrd" -FORMAT 1 -TYPE 0 -FILE "' + b + '"' ) else: commands.append('libio_gdal 0 -GRIDS "' + temp + '" -FILES "' + input + '"') commands.append('libio_gdal 1 -GRIDS "' + temp + '_0001.sgrd" -FORMAT 1 -TYPE 0 -FILE "' + r + '"' ) commands.append('libio_gdal 1 -GRIDS "' + temp + '_0002.sgrd" -FORMAT 1 -TYPE 0 -FILE "' + g + '"' ) commands.append('libio_gdal 1 -GRIDS "' + temp + '_0003.sgrd" -FORMAT 1 -TYPE 0 -FILE "' + b + '"' ) SagaUtils.createSagaBatchJobFileFromSagaCommands(commands) SagaUtils.executeSaga(progress)
def testWrongformat(self): outputs = processing.runalg('qgis:countpointsinpolygon', polygons(), points(), 'NUMPOINTS', getTempFilename('wrongext')) output = outputs['OUTPUT'] self.assertTrue(output.endswith('shp')) layer = dataobjects.getObjectFromUri(output, True) fields = layer.pendingFields() expectednames = ['ID', 'POLY_NUM_A', 'POLY_ST_A', 'NUMPOINTS'] expectedtypes = ['Integer', 'Real', 'String', 'Real'] names = [unicode(f.name()) for f in fields] types = [unicode(f.typeName()) for f in fields] self.assertEqual(expectednames, names) self.assertEqual(expectedtypes, types) features = processing.features(layer) self.assertEqual(2, len(features)) feature = features.next() attrs = feature.attributes() expectedvalues = ['1', '1.1', 'string a', '6.0'] values = [unicode(attr) for attr in attrs] self.assertEqual(expectedvalues, values)
def createSummaryTable(self): createTable = False for out in self.algs[0].outputs: if isinstance(out, (OutputNumber, OutputString)): createTable = True break if not createTable: return outputFile = getTempFilename("html") with codecs.open(outputFile, "w", encoding="utf-8") as f: for alg in self.algs: f.write("<hr>\n") for out in alg.outputs: if isinstance(out, (OutputNumber, OutputString)): f.write("<p>{}: {}</p>\n".format(out.description, out.value)) f.write("<hr>\n") ProcessingResults.addResult("{} [summary]".format(self.algs[0].name), outputFile)
def processCommand(alg, parameters): """ Handle inline rules """ txtRules = alg.getParameterValue(u'txtrules') if txtRules: # Creates a temporary txt file tempRulesName = getTempFilename() # Inject rules into temporary txt file with open(tempRulesName, "w") as tempRules: tempRules.write(txtRules) raster = alg.getParameterValue(u'input') output = alg.getOutputFromName(u'output') alg.exportedLayers[output.value] = output.name + alg.uniqueSuffix if raster: raster = alg.exportedLayers[raster] command = u"r.reclass input={} rules=- output={} --overwrite < {}".format( raster, output.name + alg.uniqueSuffix, tempRulesName) alg.commands.append(command) else: alg.processCommand()
def runalgIterating(alg, paramToIter, progress): # Generate all single-feature layers settings = QSettings() systemEncoding = settings.value('/UI/encoding', 'System') layerfile = alg.getParameterValue(paramToIter) layer = dataobjects.getObjectFromUri(layerfile, False) feat = QgsFeature() filelist = [] outputs = {} provider = layer.dataProvider() features = vector.features(layer) for feat in features: output = getTempFilename('shp') filelist.append(output) writer = QgsVectorFileWriter(output, systemEncoding, provider.fields(), provider.geometryType(), layer.crs()) writer.addFeature(feat) del writer # store output values to use them later as basenames for all outputs for out in alg.outputs: outputs[out.name] = out.value # now run all the algorithms for i,f in enumerate(filelist): alg.setParameterValue(paramToIter, f) for out in alg.outputs: filename = outputs[out.name] if filename: filename = filename[:filename.rfind('.')] + '_' + unicode(i) \ + filename[filename.rfind('.'):] out.value = filename progress.setText(tr('Executing iteration %s/%s...' % (unicode(i), unicode(len(filelist))))) progress.setPercentage(i * 100 / len(filelist)) if runalg(alg): handleAlgorithmResults(alg, None, False) else: return False return True
def createSummaryTable(self, algorithm_results): createTable = False for out in self.algorithm().outputDefinitions(): if isinstance(out, (QgsProcessingOutputNumber, QgsProcessingOutputString)): createTable = True break if not createTable: return outputFile = getTempFilename('html') with codecs.open(outputFile, 'w', encoding='utf-8') as f: for res in algorithm_results: f.write('<hr>\n') for out in self.algorithm().outputDefinitions(): if isinstance(out, (QgsProcessingOutputNumber, QgsProcessingOutputString)) and out.name() in res: f.write('<p>{}: {}</p>\n'.format(out.description(), res[out.name()])) f.write('<hr>\n') resultsList.addResult(self.algorithm().icon(), '{} [summary]'.format(self.algorithm().name()), outputFile)
def executeIterating(alg, paramToIter, feedback): # Generate all single-feature layers settings = QgsSettings() systemEncoding = settings.value('/UI/encoding', 'System') layerfile = alg.getParameterValue(paramToIter) layer = dataobjects.getLayerFromString(layerfile, False) feat = QgsFeature() filelist = [] outputs = {} features = vector.features(layer) for feat in features: output = getTempFilename('shp') filelist.append(output) writer = QgsVectorFileWriter(output, systemEncoding, layer.fields(), layer.wkbType(), layer.crs()) writer.addFeature(feat) del writer # store output values to use them later as basenames for all outputs for out in alg.outputs: outputs[out.name] = out.value # now run all the algorithms for i, f in enumerate(filelist): alg.setParameterValue(paramToIter, f) for out in alg.outputs: filename = outputs[out.name] if filename: filename = filename[:filename.rfind('.')] + '_' + str(i) \ + filename[filename.rfind('.'):] out.value = filename feedback.setProgressText(tr('Executing iteration {0}/{1}...').format(i, len(filelist))) feedback.setProgress(i * 100 / len(filelist)) if execute(alg, feedback): handleAlgorithmResults(alg, None, False) else: return False return True
def exportTable(table): """Takes a QgsVectorLayer and returns the filename to refer to its attributes table, 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 isa remote one or db-based (non-file based) one. Currently, the output is restricted to DBF. It also export to a new file if the original one contains non-ascii characters. """ settings = QSettings() systemEncoding = settings.value('/UI/encoding', 'System') output = getTempFilename() provider = table.dataProvider() isASCII = True try: unicode(table.source()).decode('ascii') except UnicodeEncodeError: isASCII = False isDbf = unicode(table.source()).endswith('dbf') \ or unicode(table.source()).endswith('shp') if not isDbf or not isASCII: writer = QgsVectorFileWriter(output, systemEncoding, provider.fields(), QGis.WKBNoGeometry, QgsCoordinateReferenceSystem('4326')) for feat in table.getFeatures(): writer.addFeature(feat) del writer return output + '.dbf' else: filename = unicode(table.source()) if unicode(table.source()).endswith('shp'): return filename[:-3] + 'dbf' else: return filename
def write(self, msg): self.progress.setConsoleInfo(msg) @contextmanager def redirect_stdout(progress): oldout = sys.stdout sys.stdout = ProgressLogger(progress) try: yield finally: sys.stdout = oldout with redirect_stdout(progress): routing = RiverNetwork(MODEL_FILE) model = ModelFile(MODEL_FILE) # Get drainage network drains_to = routing.drains_to temp_file = getTempFilename("csv") geometry_file_creation.read_network_file(model, routing, temp_file) subreaches = pd.read_csv(temp_file, index_col='Subbasin') geometry_file_creation.write_geometry_file(subreaches=subreaches, model=model, drains_to=drains_to, geometry_file=GEOMETRY_FILE)
def processAlgorithm(self, progress): commands = list() self.exportedLayers = {} self.preProcessInputs() # 1: Export rasters to sgrd and vectors to shp # Tables must be in dbf format. We check that. for param in self.parameters: if isinstance(param, ParameterRaster): if param.value is None: continue value = param.value if not value.endswith('sgrd'): exportCommand = self.exportRasterLayer(value) if exportCommand is not None: commands.append(exportCommand) if isinstance(param, ParameterVector): if param.value is None: continue layer = dataobjects.getObjectFromUri(param.value, False) if layer: filename = dataobjects.exportVectorLayer(layer) self.exportedLayers[param.value] = filename elif not param.value.endswith('shp'): raise GeoAlgorithmExecutionException( self.tr('Unsupported file format')) if isinstance(param, ParameterTable): if param.value is None: continue table = dataobjects.getObjectFromUri(param.value, False) if table: filename = dataobjects.exportTable(table) self.exportedLayers[param.value] = filename elif not param.value.endswith('shp'): raise GeoAlgorithmExecutionException( self.tr('Unsupported file format')) if isinstance(param, ParameterMultipleInput): if param.value is None: continue layers = param.value.split(';') if layers is None or len(layers) == 0: continue if param.datatype == ParameterMultipleInput.TYPE_RASTER: for layerfile in layers: if not layerfile.endswith('sgrd'): exportCommand = self.exportRasterLayer(layerfile) if exportCommand is not None: commands.append(exportCommand) elif param.datatype == ParameterMultipleInput.TYPE_VECTOR_ANY: for layerfile in layers: layer = dataobjects.getObjectFromUri(layerfile, False) if layer: filename = dataobjects.exportVectorLayer(layer) self.exportedLayers[layerfile] = filename elif not layerfile.endswith('shp'): raise GeoAlgorithmExecutionException( self.tr('Unsupported file format')) # 2: Set parameters and outputs command = self.undecoratedGroup + ' "' + self.cmdname + '"' if self.hardcodedStrings: for s in self.hardcodedStrings: command += ' ' + s for param in self.parameters: if param.value is None: continue if isinstance(param, (ParameterRaster, ParameterVector, ParameterTable)): value = param.value if value in self.exportedLayers.keys(): command += ' -' + param.name + ' "' \ + self.exportedLayers[value] + '"' else: command += ' -' + param.name + ' "' + value + '"' elif isinstance(param, ParameterMultipleInput): s = param.value for layer in self.exportedLayers.keys(): s = s.replace(layer, self.exportedLayers[layer]) command += ' -' + param.name + ' "' + s + '"' elif isinstance(param, ParameterBoolean): if param.value: command += ' -' + param.name elif isinstance(param, ParameterFixedTable): tempTableFile = getTempFilename('txt') f = open(tempTableFile, 'w') f.write('\t'.join([col for col in param.cols]) + '\n') values = param.value.split(',') for i in range(0, len(values), 3): s = values[i] + '\t' + values[i + 1] + '\t' + values[i + 2] + '\n' f.write(s) f.close() command += ' -' + param.name + ' "' + tempTableFile + '"' elif isinstance(param, ParameterExtent): # 'We have to substract/add half cell size, since SAGA is # center based, not corner based halfcell = self.getOutputCellsize() / 2 offset = [halfcell, -halfcell, halfcell, -halfcell] values = param.value.split(',') for i in range(4): command += ' -' + self.extentParamNames[i] + ' ' \ + str(float(values[i]) + offset[i]) elif isinstance(param, (ParameterNumber, ParameterSelection)): command += ' -' + param.name + ' ' + str(param.value) else: command += ' -' + param.name + ' "' + str(param.value) + '"' for out in self.outputs: if isinstance(out, OutputRaster): filename = out.getCompatibleFileName(self) filename += '.sgrd' command += ' -' + out.name + ' "' + filename + '"' if isinstance(out, OutputVector): filename = out.getCompatibleFileName(self) command += ' -' + out.name + ' "' + filename + '"' if isinstance(out, OutputTable): filename = out.getCompatibleFileName(self) command += ' -' + out.name + ' "' + filename + '"' commands.append(command) # 3: Export resulting raster layers # optim = ProcessingConfig.getSetting(SagaUtils.SAGA_IMPORT_EXPORT_OPTIMIZATION) for out in self.outputs: if isinstance(out, OutputRaster): filename = out.getCompatibleFileName(self) filename2 = filename + '.sgrd' formatIndex = (4 if isWindows() else 1) sessionExportedLayers[filename] = filename2 # Do not export is the output is not a final output # of the model # dontExport = True # if self.model is not None and optim: # for subalg in self.model.algOutputs: # if out.name in subalg: # if subalg[out.name] is not None: # dontExport = False # break # if dontExport: # continue if self.cmdname == 'RGB Composite': commands.append('io_grid_image 0 -IS_RGB -GRID:"' + filename2 + '" -FILE:"' + filename + '"') else: commands.append('io_gdal 1 -GRIDS "' + filename2 + '" -FORMAT ' + str(formatIndex) + ' -TYPE 0 -FILE "' + filename + '"') # 4: Run SAGA commands = self.editCommands(commands) SagaUtils.createSagaBatchJobFileFromSagaCommands(commands) loglines = [] loglines.append(self.tr('SAGA execution commands')) for line in commands: progress.setCommand(line) loglines.append(line) if ProcessingConfig.getSetting(SagaUtils.SAGA_LOG_COMMANDS): ProcessingLog.addToLog(ProcessingLog.LOG_INFO, loglines) SagaUtils.executeSaga(progress)
def regroupRasters(alg, parameters, context, src, group, subgroup=None, extFile=None): """ Group multiple input rasters into a group * If there is a subgroupField, a subgroup will automatically be created. * When an external file is provided, the file is copied into the respective directory of the subgroup. :param parameters: :param context: :param src: name of input parameter with multiple rasters. :param group: name of group. :param subgroup: name of subgroup. :param extFile: dict : parameterName:directory name """ # Create a group parameter groupName = 'group_{}'.format(os.path.basename(getTempFilename())) param = QgsProcessingParameterString(group, 'virtual group', groupName, False, False) alg.addParameter(param) # Create a subgroup subgroupName = None if subgroup: subgroupName = 'subgroup_{}'.format(os.path.basename( getTempFilename())) param = QgsProcessingParameterString(subgroup, 'virtual subgroup', subgroupName, False, False) alg.addParameter(param) # Compute raster names rasters = alg.parameterAsLayerList(parameters, src, context) rasterNames = [] for idx, raster in enumerate(rasters): name = '{}_{}'.format(src, idx) if name in alg.exportedLayers: rasterNames.append(alg.exportedLayers[name]) # Insert a i.group command command = 'i.group group={}{} input={}'.format( groupName, ' subgroup={}'.format(subgroupName) if subgroup else '', ','.join(rasterNames)) alg.commands.append(command) # Handle external files # if subgroupField and extFile: # for ext in extFile.keys(): # extFileName = new_parameters[ext] # if extFileName: # shortFileName = os.path.basename(extFileName) # destPath = os.path.join(Grass7Utils.grassMapsetFolder(), # 'PERMANENT', # 'group', new_parameters[group.name()], # 'subgroup', new_parameters[subgroup.name()], # extFile[ext], shortFileName) # copyFile(alg, extFileName, destPath) alg.removeParameter(src) return groupName, subgroupName
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' if 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.parameterAsBool(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 processAlgorithm(self, parameters, context, feedback): commands = list() self.exportedLayers = {} self.preProcessInputs() # 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, ParameterRaster): if param.name( ) not in parameters or parameters[param.name()] is None: continue if parameters[param.name()].endswith('sdat'): parameters[ param.name()] = parameters[param.name()][:-4] + "sgrd" elif not parameters[param.name()].endswith('sgrd'): exportCommand = self.exportRasterLayer( parameters[param.name()]) if exportCommand is not None: commands.append(exportCommand) if isinstance(param, ParameterVector): if param.name( ) not in parameters or parameters[param.name()] is None: continue layer = QgsProcessingUtils.mapLayerFromString( parameters[param.name()], context, False) if layer: filename = dataobjects.exportVectorLayer(layer) self.exportedLayers[param.value] = filename elif not parameteres[param.name()].endswith('shp'): raise GeoAlgorithmExecutionException( self.tr('Unsupported file format')) if isinstance(param, ParameterTable): if param.name( ) not in parameters or parameters[param.name()] is None: continue table = QgsProcessingUtils.mapLayerFromString( parameters[param.name()], context, False) if table: filename = dataobjects.exportTable(table) self.exportedLayers[parameters[param.name()]] = filename elif not parameters[param.name()].endswith('shp'): raise GeoAlgorithmExecutionException( self.tr('Unsupported file format')) if isinstance(param, ParameterMultipleInput): if param.name( ) not in parameters or parameters[param.name()] is None: continue layers = param.value.split(';') if layers is None or len(layers) == 0: continue if param.datatype == dataobjects.TYPE_RASTER: for i, layerfile in enumerate(layers): if layerfile.endswith('sdat'): layerfile = param.value[:-4] + "sgrd" layers[i] = layerfile elif not layerfile.endswith('sgrd'): exportCommand = self.exportRasterLayer(layerfile) if exportCommand is not None: commands.append(exportCommand) param.value = ";".join(layers) elif param.datatype in [ dataobjects.TYPE_VECTOR_ANY, dataobjects.TYPE_VECTOR_LINE, dataobjects.TYPE_VECTOR_POLYGON, dataobjects.TYPE_VECTOR_POINT ]: for layerfile in layers: layer = QgsProcessingUtils.mapLayerFromString( layerfile, context, False) if layer: filename = dataobjects.exportVectorLayer(layer) self.exportedLayers[layerfile] = filename elif not layerfile.endswith('shp'): raise GeoAlgorithmExecutionException( self.tr('Unsupported file format')) # TODO - set minimum extent if not extent: extent = QgsProcessingUtils.combineLayerExtents([layer]) # 2: Set parameters and outputs command = self.undecoratedGroup + ' "' + self.cmdname + '"' command += ' ' + ' '.join(self.hardcodedStrings) for param in self.parameterDefinitions(): if not param.name() in parameters or parameters[ param.name()] is None: continue if isinstance(param, (ParameterRaster, ParameterVector, ParameterTable)): value = parameters[param.name()] if value in list(self.exportedLayers.keys()): command += ' -' + param.name() + ' "' \ + self.exportedLayers[value] + '"' else: command += ' -' + param.name() + ' "' + value + '"' elif isinstance(param, ParameterMultipleInput): s = parameters[param.name()] for layer in list(self.exportedLayers.keys()): s = s.replace(layer, self.exportedLayers[layer]) command += ' -' + param.name() + ' "' + s + '"' elif isinstance(param, ParameterBoolean): if parameters[param.name()]: command += ' -' + param.name().strip() + " true" else: command += ' -' + param.name().strip() + " false" elif isinstance(param, ParameterFixedTable): tempTableFile = getTempFilename('txt') with open(tempTableFile, 'w') as f: f.write('\t'.join([col for col in param.cols]) + '\n') values = parameters[param.name()].split(',') for i in range(0, len(values), 3): s = values[i] + '\t' + values[i + 1] + '\t' + values[ i + 2] + '\n' f.write(s) command += ' -' + param.name() + ' "' + tempTableFile + '"' elif isinstance(param, ParameterExtent): # 'We have to substract/add half cell size, since SAGA is # center based, not corner based halfcell = self.getOutputCellsize(parameters) / 2 offset = [halfcell, -halfcell, halfcell, -halfcell] values = parameters[param.name()].split(',') for i in range(4): command += ' -' + self.extentParamNames[i] + ' ' \ + str(float(values[i]) + offset[i]) elif isinstance(param, (ParameterNumber, ParameterSelection)): command += ' -' + param.name() + ' ' + str(param.value) else: command += ' -' + param.name() + ' "' + str(param.value) + '"' for out in self.outputs: command += ' -' + out.name + ' "' + out.getCompatibleFileName( self) + '"' commands.append(command) # special treatment for RGB algorithm # TODO: improve this and put this code somewhere else for out in self.outputs: if isinstance(out, OutputRaster): filename = out.getCompatibleFileName(self) filename2 = filename + '.sgrd' if self.cmdname == 'RGB Composite': commands.append('io_grid_image 0 -IS_RGB -GRID:"' + filename2 + '" -FILE:"' + 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'), QgsMessageLog.INFO) SagaUtils.executeSaga(feedback) if self.crs is not None: for out in self.outputs: if isinstance(out, (OutputVector, OutputRaster)): prjFile = os.path.splitext( out.getCompatibleFileName(self))[0] + ".prj" with open(prjFile, "w") as f: f.write(self.crs.toWkt())
def PreRun(self, parameters, context, feedback, executing=True): """Here is where the processing itself takes place.""" print('processAlgorithm') # === INPUT self.input_asc = self.parameterRasterAsFilePath( parameters, self.INPUT_ASC, context) self.cluster = self.parameterAsString(parameters, self.CLUSTER, context) clusterTypeValue = self.parameterAsInt(parameters, self.CLUSTER_TYPE, context) self.cluster_type = self.types_of_cluster[clusterTypeValue].split( ' ')[0] self.cluster_min_area = self.parameterAsString(parameters, self.CLUSTER_MIN_AREA, context) self.cluster_distance = self.parameterAsString( parameters, self.CLUSTER_DISTANCE, context) if clusterTypeValue in [2, 3] else None self.cluster_friction = self.parameterAsString( parameters, self.CLUSTER_FRICTION, context) if clusterTypeValue in [3] else None # === OUTPUT self.output_asc = self.parameterAsString(parameters, self.OUTPUT_ASC, context) self.output_csv = self.parameterAsString(parameters, self.OUTPUT_CSV, context) self.output_csv = ChloeUtils.adjustExtension(self.output_csv, self.output_asc) self.setOutputValue(self.OUTPUT_ASC, self.output_asc) self.setOutputValue(self.OUTPUT_CSV, self.output_csv) # Constrution des chemins de sortie des fichiers base_in = os.path.basename(self.input_asc) name_in = os.path.splitext(base_in)[0] #ext_in = os.path.splitext(base_in)[1] dir_out = os.path.dirname(self.output_asc) base_out = os.path.basename(self.output_asc) name_out = os.path.splitext(base_out)[0] #ext_out = os.path.splitext(base_out)[1] #feedback.pushInfo('self.f_path') # === SAVE_PROPERTIES f_save_properties = self.parameterAsString(parameters, self.SAVE_PROPERTIES, context) if f_save_properties: self.f_path = f_save_properties else: if not self.f_path: self.f_path = getTempFilename(ext="properties") # === Properties file self.createPropertiesTempFile() # Create Properties file (temp or chosed) # === CORE #commands = self.getConsoleCommandsJava(f_save_properties) #commands = self.getConsoleCommands(parameters, context, feedback, executing=True) #print('------- before') #ChloeUtils.runChole(commands, feedback) #print('------- after') # === Projection file f_prj = dir_out + os.sep + name_out + ".prj" self.createProjectionFile(f_prj)
#from processing.core.Processing import Processing #Processing.initialize() #versionSAGA = processing.algs.saga.SagaUtils.getInstalledVersion() #print( versionSAGA) import processing from qgis.core import QgsProcessingFeedback from processing.tools.system import getTempFilename info_extent = '796018.2658206049,796079.989864021, 6674128.609732771,6674254.041102098 [EPSG:2154]' mon_feedback = QgsProcessingFeedback() nom_raster_temp = getTempFilename("sdat") #raster_temp = QgsProcessingOutputRasterLayer( nom_raster_temp) # IDW_SAGA = { 'SHAPES': '/data/GIS/DATA/DATA_PHY/vecteur_point.shp', 'FIELD': 'DIAM', 'DW_WEIGHTING': 1, 'DW_IDW_POWER': 2, 'DW_IDW_OFFSET': False, 'DW_BANDWIDTH': 1, 'SEARCH_POINTS_ALL': 0, 'SEARCH_RANGE': 0, 'SEARCH_RADIUS': 10, 'SEARCH_POINTS_MIN': 1, 'SEARCH_POINTS_MAX': 10, 'SEARCH_DIRECTION': 0, 'OUTPUT_EXTENT': info_extent, 'TARGET_USER_SIZE': 1, 'TARGET_DEFINITION': 0, 'TARGET_USER_FITS': 0, 'TARGET_TEMPLATE': None, 'TARGET_OUT_GRID': nom_raster_temp
class TigContouringAlgorithm(QgsProcessingAlgorithm): """This is an example algorithm that takes a vector layer and creates a new one just with just those features of the input layer that are selected. It is meant to be used as an example of how to create your own algorithms and explain methods and variables used to do it. An algorithm like this will be available in all elements, and there is not need for additional work. All Processing algorithms should extend the GeoAlgorithm class. """ # Constants used to refer to parameters and outputs. They will be # used when calling the algorithm from another algorithm, or when # calling from the QGIS console. OUTPUT_LAYER = 'OUTPUT_LAYER' INPUT_LAYER = 'INPUT_LAYER1' INPUT_FAULT = 'INPUT_FAULT' INTERVAL = 'INTERVAL' def tr(self, string): return QCoreApplication.translate('Processing', string) def name(self): return 'TigContouringAlgorithm' def groupId(self): return 'PUMAplus' def group(self): return self.tr('Сетки') def displayName(self): """ Returns the translated algorithm name, which should be used for any user-visible display of the algorithm name. """ return self.tr('Создать изолинии') def createInstance(self): return TigContouringAlgorithm() def initAlgorithm(self, config): """Here we define the inputs and output of the algorithm, along with some other properties. """ # We add the input vector layer. It can have any kind of geometry # It is a mandatory (not optional) one, hence the False argument self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT_LAYER, self.tr('Растр'), [QgsProcessing.TypeRaster], '', False)) self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT_FAULT, self.tr('Разломы'), [QgsProcessing.TypeVectorLine], '', True)) self.addParameter(QgsProcessingParameterNumber(self.INTERVAL, self.tr('Интервал'), type=QgsProcessingParameterNumber.Double, defaultValue=10, optional=True)) # We add a vector layer as output self.addOutput(QgsProcessingParameterVectorDestination(self.OUTPUT_LAYER, self.tr('Output layer'))) def processAlgorithm(self, , parameters, context, feedback): inputFilename = self.getParameterValue(self.INPUT_LAYER) output = self.getOutputValue(self.OUTPUT_LAYER) faultLayer = self.self.parameterAsVectorLayer(parameters,self.INPUT_FAULT, context) self.Inter = self.getParameterValue(self.INTERVAL) rasterLayer = self.parameterAsRasterLayer(parameters, inputFilename, context) self.extent = rasterLayer.extent() self.plugin_dir = os.path.dirname(__file__) self.temp_path = tempfile.gettempdir() if faultLayer is not None: self.contourWithFaults(rasterLayer, faultLayer, output, feedback ) else: processing.runalg('gdalogr:contour', inputFilename, self.Inter, 'ELEV', None, output) self.grdFilename = getTempFilename('grd').replace("\\", "/") #self.temp_path.replace("\\", "/") + '/tempgrid.grd' self.outputFilename = output.replace("\\", "/") self.tclFilename = os.path.join(self.temp_path, 'tempjob.tcl')
##*ParameterBoolean|maskShadow|Mask FMask shadow pixels|True ##*ParameterBoolean|maskSnow|Mask FMask snow pixels|True ##*ParameterBoolean|maskWater|Mask FMask water pixels|False ##*ParameterBoolean|maskLand|Mask FMask land pixels|False ##OutputRaster|outputFile|Maked output image from processing.tools import dataobjects, system # Run GDAL warp to make sure that the mask file exactly aligns with the image file progress.setText("Aligning mask raster to image raster...") dataRaster = dataobjects.getObject(dataFile) proj = dataRaster.crs().authid() resolution = dataRaster.rasterUnitsPerPixelX() bandCount = dataRaster.bandCount() extent = dataobjects.extent([dataRaster]) warpMask = system.getTempFilename("tif") params = { "INPUT": maskFile, "DEST_SRS": proj, "TR": resolution, "USE_RASTER_EXTENT": True, "RASTER_EXTENT": extent, "EXTENT_CRS": proj, "METHOD": 0, "RTYPE": 0, "OUTPUT": warpMask, } processing.runalg("gdalogr:warpreproject", params) progress.setText("Applying mask to image...") # First reclassify fmask output into two classes
def getTempFilename(self): return system.getTempFilename()
def processAlgorithm(self, progress): currentOs = os.name msg = OTBUtils.checkOtbConfiguration() if msg: raise GeoAlgorithmExecutionException(msg) path = OTBUtils.otbPath() commands = [] commands.append(path + os.sep + self.cliName) self.roiVectors = {} self.roiRasters = {} for param in self.parameters: # get the given input(s) if param.name in ["-il", "-in"]: newparams = "" listeParameters = param.value.split(";") for inputParameter in listeParameters: # if HDF5 file if "HDF5" in inputParameter: if currentOs == "posix": data = inputParameter[6:] else: data = inputParameter[5:] dataset = data #on windows, there isn't " #if data[-1] == '"': if currentOs == "posix": data = data[:data.index('"')] else: data = data[:data.index('://')] #try : if currentOs == "posix": dataset.index('"') dataset = os.path.basename(data) + dataset[dataset.index('"'):] #except ValueError : else: #dataset = os.path.basename( data ) + '"' + dataset[dataset.index('://'):] dataset = dataset[dataset.index('://'):] #get index of the subdataset with gdal if currentOs == "posix": commandgdal = "gdalinfo " + data + " | grep '" + dataset + "$'" else: commandgdal = "gdalinfo " + data + " | findstr \"" + dataset + "$\"" resultGDAL = os.popen(commandgdal).readlines() indexSubdataset = -1 if resultGDAL: indexSubdatasetString = re.search("SUBDATASET_(\d+)_", resultGDAL[0]) if indexSubdatasetString: #match between () indexSubdataset = indexSubdatasetString.group(1) else: indexSubdataset = -1 else: #print "Error : no match of ", dataset, "$ in gdalinfo " + data indexSubdataset = -1 if not indexSubdataset == -1: indexSubdataset = int(indexSubdataset) - 1 newParam = "\'" + data + "?&sdataidx=" + unicode(indexSubdataset) + "\'" else: newParam = inputParameter newparams += newParam # no hdf5 else: newparams += inputParameter newparams += ";" if newparams[-1] == ";": newparams = newparams[:-1] param.value = newparams if param.value is None or param.value == "": continue if isinstance(param, ParameterVector): commands.append(param.name) if self.hasROI: roiFile = getTempFilename('shp') commands.append(roiFile) self.roiVectors[param.value] = roiFile else: commands.append("\"" + param.value + "\"") elif isinstance(param, ParameterRaster): commands.append(param.name) if self.hasROI: roiFile = getTempFilename('tif') commands.append(roiFile) self.roiRasters[param.value] = roiFile else: commands.append("\"" + param.value + "\"") elif isinstance(param, ParameterMultipleInput): commands.append(param.name) files = unicode(param.value).split(";") paramvalue = " ".join(["\"" + f + " \"" for f in files]) commands.append(paramvalue) elif isinstance(param, ParameterSelection): commands.append(param.name) idx = int(param.value) commands.append(unicode(param.options[idx])) elif isinstance(param, ParameterBoolean): if param.value: commands.append(param.name) commands.append(unicode(param.value).lower()) elif isinstance(param, ParameterExtent): self.roiValues = param.value.split(",") else: commands.append(param.name) commands.append(unicode(param.value)) for out in self.outputs: commands.append(out.name) commands.append('"' + out.value + '"') for roiInput, roiFile in self.roiRasters.items(): startX, startY = float(self.roiValues[0]), float(self.roiValues[1]) sizeX = float(self.roiValues[2]) - startX sizeY = float(self.roiValues[3]) - startY helperCommands = [ "otbcli_ExtractROI", "-in", roiInput, "-out", roiFile, "-startx", unicode(startX), "-starty", unicode(startY), "-sizex", unicode(sizeX), "-sizey", unicode(sizeY) ] ProcessingLog.addToLog(ProcessingLog.LOG_INFO, helperCommands) progress.setCommand(helperCommands) OTBUtils.executeOtb(helperCommands, progress) if self.roiRasters: supportRaster = self.roiRasters.itervalues().next() for roiInput, roiFile in self.roiVectors.items(): helperCommands = [ "otbcli_VectorDataExtractROIApplication", "-vd.in", roiInput, "-io.in", supportRaster, "-io.out", roiFile, "-elev.dem.path", OTBUtils.otbSRTMPath()] ProcessingLog.addToLog(ProcessingLog.LOG_INFO, helperCommands) progress.setCommand(helperCommands) OTBUtils.executeOtb(helperCommands, progress) loglines = [] loglines.append(self.tr('OTB execution command')) for line in commands: loglines.append(line) progress.setCommand(line) ProcessingLog.addToLog(ProcessingLog.LOG_INFO, loglines) import processing.algs.otb.OTBSpecific_XMLLoading module = processing.algs.otb.OTBSpecific_XMLLoading found = False if 'adapt%s' % self.appkey in dir(module): found = True commands = getattr(module, 'adapt%s' % self.appkey)(commands) else: the_key = 'adapt%s' % self.appkey if '-' in the_key: base_key = the_key.split("-")[0] if base_key in dir(module): found = True commands = getattr(module, base_key)(commands) if not found: ProcessingLog.addToLog(ProcessingLog.LOG_INFO, self.tr("Adapter for %s not found" % the_key)) #frames = inspect.getouterframes(inspect.currentframe())[1:] #for a_frame in frames: # frame,filename,line_number,function_name,lines,index = a_frame # ProcessingLog.addToLog(ProcessingLog.LOG_INFO, "%s %s %s %s %s %s" % (frame,filename,line_number,function_name,lines,index)) OTBUtils.executeOtb(commands, progress)
def ZonalStats( start_date, end_date, vec_name, sb_column, file_list, subcatchmap_res, corr_by_num=None, corr_by_fact=None, progress=None, ): if not os.path.isfile(vec_name): raise GeoAlgorithmExecutionException('No shapefile: "' + vec_name + '" ') if not file_list: raise GeoAlgorithmExecutionException("List of files is empty") # Creating a list of dates (year + julian day) dates = [] for n in range((end_date - start_date).days + 1): d = start_date + timedelta(days=n) dates.append(d.strftime("%Y%j")) # Initialising array for results layer = dataobjects.getObjectFromUri(vec_name) if layer.crs().toProj4() != "+proj=longlat +datum=WGS84 +no_defs": raise IOError("Vector file must be in geographic WGS 1984 projection") result_ts = np.ones([len(dates), layer.featureCount()]) * -99.0 # Extracting data and saving in array for file_name in file_list: if (file_name.endswith(".tif")) or (file_name.endswith(".tiff")): f = os.path.split(file_name)[1] file_date = date(int(f[0:4]), int(f[4:6]), int(f[6:8])) ind = dates.index( file_date.strftime("%Y%j")) # index in dates list else: continue if progress is not None: progress.setConsoleInfo("Processing %s..." % file_name) # Check the raster projection raster = dataobjects.getObjectFromUri(file_name) if raster.crs().toProj4() != "+proj=longlat +datum=WGS84 +no_defs": raise IOError( "Datafiles must be in geographic WGS 1984 projection") # Apply correction factors if given formula = "" if corr_by_num is not None: formula = "A+%f" % (corr_by_num) elif corr_by_fact is not None: formula = "A*%f" % (corr_by_fact) if formula: temp_rast_name = system.getTempFilename("tif") calculator_params = { "INPUT_A": file_name, "OUTPUT": temp_rast_name, "FORMULA": formula, } processing.runalg("gdalogr:rastercalculator", calculator_params) else: temp_rast_name = file_name # Resample raster to given resolution out_rast_name = system.getTempFilename("tif") warp_params = { "INPUT": temp_rast_name, "OUTPUT": out_rast_name, "DEST_SRS": "EPSG:4326", "METHOD": 1, "TR": subcatchmap_res, "USE_RASTER_EXTENT": True, "RASTER_EXTENT": dataobjects.extent([layer]), "EXTENT_CRS": "EPSG:4326", } processing.runalg("gdalogr:warpreproject", warp_params) # Run zonal stats zs_output_name = system.getTempFilename("shp") zonal_statistics_params = { "INPUT_RASTER": out_rast_name, "RASTER_BAND": 1, "INPUT_VECTOR": vec_name, "COLUMN_PREFIX": "stats_", "GLOBAL_EXTENT": False, "OUTPUT_LAYER": zs_output_name, } processing.runalg("qgis:zonalstatistics", zonal_statistics_params) # Save result zs_output = dataobjects.getObjectFromUri(zs_output_name) for feature in zs_output.getFeatures(): subbasin_id = feature[sb_column] subbasin_value = feature["stats_mean"] try: result_ts[ind, subbasin_id - 1] = subbasin_value except TypeError: result_ts[ind, subbasin_id - 1] = -99.0 # Return results return dates, result_ts
def processAlgorithm(self, parameters, context, feedback): self.mProgress = feedback in_tvd = self.parameterAsString(parameters, self.INPUT_LAYER, context) in_owc = self.parameterAsString(parameters, self.INPUT_POLYGON, context) out_Reserves = self.parameterAsFileOutput(parameters, self.OUTPUT_LAYER, context) # Initialise temporary variables # Polygons creared from lines rasterLayer = self.parameterAsRasterLayer(parameters, self.INPUT_LAYER, context) vectorLayer = self.parameterAsVectorLayer(parameters, self.INPUT_POLYGON, context) geometryType = vectorLayer.wkbType() owc_poly_tmp = in_owc if geometryType == QgsWkbTypes.LineString: owc_poly_tmp = getTempFilename('shp') processing.run("qgis:linestopolygons", { "INPUT": vectorLayer, "OUTPUT": owc_poly_tmp }, context=context, feedback=feedback) #Get raster info extent = rasterLayer.extent() provider = rasterLayer.dataProvider() rows = rasterLayer.rasterUnitsPerPixelY() cols = rasterLayer.rasterUnitsPerPixelX() block = provider.block(1, extent, rows, cols) noDataValue = block.noDataValue() cellSizeX = rasterLayer.rasterUnitsPerPixelX() cellSizeY = rasterLayer.rasterUnitsPerPixelY() cellArea = cellSizeX * cellSizeY # Clipped raster # tvd_clip_r = getTempFilename('tif')#scratch + "\\tvd_clip_r" points_v = getTempFilename('shp') #scratch + "\\out_r" # statistic = scratch + "\\statistic" #Raster to points self.mProgress.pushInfo('Convert raster to point node') self.mProgress.pushInfo(points_v) processing.run('saga:rastervaluestopoints', { "GRIDS": [in_tvd], "POLYGONS": owc_poly_tmp, "TYPE": 0, "SHAPES": points_v }, context=context, feedback=feedback) pointsLayer = QgsVectorLayer(points_v, 'nodes', 'ogr') # Process: Extract by Mask # processing.runalg('gdalogr:cliprasterbymasklayer', {"INPUT":in_tvd, # "MASK":owc_poly_tmp, # "NO_DATA": noDataValue, # "OUTPUT":tvd_clip_r} ) # progress.setInfo("Clipped raster:{}".format(tvd_clip_r)) try: fields = pointsLayer.fields() lastField = fields.count() - 1 lastFieldName = fields[lastField].name() tvdMAX = pointsLayer.maximumValue(lastField) tvdMIN = pointsLayer.minimumValue(lastField) except Exception as e: self.mProgress.setInfo(str(e)) return NoIntervals = 5 thick = int((float(tvdMAX) - float(tvdMIN)) / NoIntervals) # Write raster_area to a file # workfile=scratch + "\\raster_area.txt" f = open(out_Reserves, 'w') f.write("DEPTH;CumArea@F90;F50;F10 \n") f.close() # simple list list1 = [] # nested list outline = [] self.curVolume = 0 for i in range(NoIntervals + 1): slice = int(float(tvdMIN) / thick + i + 1) * thick expr = QgsExpression('\"{0}\">\'{1}\' AND \"{2}\"<=\'{3}\''.format( lastFieldName, slice - thick, lastFieldName, slice)) searchRes = pointsLayer.getFeatures(QgsFeatureRequest(expr)) num = 0 for f in searchRes: num += 1 list1.append(slice) list1.append(num * cellArea) outline.append(list1) list1 = [] f = open(out_Reserves, 'a') for i in range(len(outline)): if (i == 0): p90 = float(outline[0][1]) * 0.8 / 1000000 else: p90 = float(outline[i - 1][1]) / 1000000 if (i == len(outline) - 1): p10 = float(outline[i][1]) * 1.2 / 1000000 else: p10 = float(outline[i + 1][1]) / 1000000 output = str(outline[i][0]) + ";" + str(p90) + ";" + str( float(outline[i][1]) / 1000000) + ";" + str(p10) + "\n" f.write(output) f.close() return {self.OUTPUT_LAYER: out_Reserves}
def getOutputFile(self): if self.useTempFiles: return None else: return getTempFilename('shp')
def createSummaryTable(self, algorithm_results, errors): createTable = False for out in self.algorithm().outputDefinitions(): if isinstance( out, (QgsProcessingOutputNumber, QgsProcessingOutputString, QgsProcessingOutputBoolean)): createTable = True break if not createTable and not errors: return outputFile = getTempFilename('html') with codecs.open(outputFile, 'w', encoding='utf-8') as f: if createTable: for i, res in enumerate(algorithm_results): results = res['results'] params = res['parameters'] if i > 0: f.write('<hr>\n') f.write(self.tr('<h3>Parameters</h3>\n')) f.write('<table>\n') for param in self.algorithm().parameterDefinitions(): if not param.isDestination(): if param.name() in params: f.write( '<tr><th>{}</th><td>{}</td></tr>\n'.format( param.description(), params[param.name()])) f.write('</table>\n') f.write(self.tr('<h3>Results</h3>\n')) f.write('<table>\n') for out in self.algorithm().outputDefinitions(): if out.name() in results: f.write('<tr><th>{}</th><td>{}</td></tr>\n'.format( out.description(), results[out.name()])) f.write('</table>\n') if errors: f.write('<h2 style="color: red">{}</h2>\n'.format( self.tr('Errors'))) for i, res in enumerate(errors): errors = res['errors'] params = res['parameters'] if i > 0: f.write('<hr>\n') f.write(self.tr('<h3>Parameters</h3>\n')) f.write('<table>\n') for param in self.algorithm().parameterDefinitions(): if not param.isDestination(): if param.name() in params: f.write('<tr><th>{}</th><td>{}</td></tr>\n'.format( param.description(), params[param.name()])) f.write('</table>\n') f.write('<h3>{}</h3>\n'.format(self.tr('Error'))) f.write('<p style="color: red">{}</p>\n'.format( '<br>'.join(errors))) resultsList.addResult(icon=self.algorithm().icon(), name='{} [summary]'.format( self.algorithm().name()), timestamp=time.localtime(), result=outputFile)
def processAlgorithm(self, progress): commands = list() self.exportedLayers = {} self.preProcessInputs() # 1: Export rasters to sgrd and vectors to shp # Tables must be in dbf format. We check that. for param in self.parameters: if isinstance(param, ParameterRaster): if param.value is None: continue if param.value.endswith('sdat'): param.value = param.value[:-4] + "sgrd" elif not param.value.endswith('sgrd'): exportCommand = self.exportRasterLayer(param.value) if exportCommand is not None: commands.append(exportCommand) if isinstance(param, ParameterVector): if param.value is None: continue layer = dataobjects.getObjectFromUri(param.value, False) if layer: filename = dataobjects.exportVectorLayer(layer) self.exportedLayers[param.value] = filename elif not param.value.endswith('shp'): raise GeoAlgorithmExecutionException( self.tr('Unsupported file format')) if isinstance(param, ParameterTable): if param.value is None: continue table = dataobjects.getObjectFromUri(param.value, False) if table: filename = dataobjects.exportTable(table) self.exportedLayers[param.value] = filename elif not param.value.endswith('shp'): raise GeoAlgorithmExecutionException( self.tr('Unsupported file format')) if isinstance(param, ParameterMultipleInput): if param.value is None: continue layers = param.value.split(';') if layers is None or len(layers) == 0: continue if param.datatype == ParameterMultipleInput.TYPE_RASTER: for i, layerfile in enumerate(layers): if layerfile.endswith('sdat'): layerfile = param.value[:-4] + "sgrd" layers[i] = layerfile elif not layerfile.endswith('sgrd'): exportCommand = self.exportRasterLayer(layerfile) if exportCommand is not None: commands.append(exportCommand) param.value = ";".join(layers) elif param.datatype == ParameterMultipleInput.TYPE_VECTOR_ANY: for layerfile in layers: layer = dataobjects.getObjectFromUri(layerfile, False) if layer: filename = dataobjects.exportVectorLayer(layer) self.exportedLayers[layerfile] = filename elif not layerfile.endswith('shp'): raise GeoAlgorithmExecutionException( self.tr('Unsupported file format')) # 2: Set parameters and outputs command = self.undecoratedGroup + ' "' + self.cmdname + '"' if self.hardcodedStrings: for s in self.hardcodedStrings: command += ' ' + s for param in self.parameters: if param.value is None: continue if isinstance(param, (ParameterRaster, ParameterVector, ParameterTable)): value = param.value if value in self.exportedLayers.keys(): command += ' -' + param.name + ' "' \ + self.exportedLayers[value] + '"' else: command += ' -' + param.name + ' "' + value + '"' elif isinstance(param, ParameterMultipleInput): s = param.value for layer in self.exportedLayers.keys(): s = s.replace(layer, self.exportedLayers[layer]) command += ' -' + param.name + ' "' + s + '"' elif isinstance(param, ParameterBoolean): if param.value: command += ' -' + param.name elif isinstance(param, ParameterFixedTable): tempTableFile = getTempFilename('txt') f = open(tempTableFile, 'w') f.write('\t'.join([col for col in param.cols]) + '\n') values = param.value.split(',') for i in range(0, len(values), 3): s = values[i] + '\t' + values[i + 1] + '\t' + values[i + 2] + '\n' f.write(s) f.close() command += ' -' + param.name + ' "' + tempTableFile + '"' elif isinstance(param, ParameterExtent): # 'We have to substract/add half cell size, since SAGA is # center based, not corner based halfcell = self.getOutputCellsize() / 2 offset = [halfcell, -halfcell, halfcell, -halfcell] values = param.value.split(',') for i in range(4): command += ' -' + self.extentParamNames[i] + ' ' \ + str(float(values[i]) + offset[i]) elif isinstance(param, (ParameterNumber, ParameterSelection)): command += ' -' + param.name + ' ' + str(param.value) else: command += ' -' + param.name + ' "' + str(param.value) + '"' for out in self.outputs: command += ' -' + out.name + ' "' + out.getCompatibleFileName(self) + '"' commands.append(command) # special treatment for RGB algorithm #TODO: improve this and put this code somewhere else for out in self.outputs: if isinstance(out, OutputRaster): filename = out.getCompatibleFileName(self) filename2 = filename + '.sgrd' if self.cmdname == 'RGB Composite': commands.append('io_grid_image 0 -IS_RGB -GRID:"' + filename2 + '" -FILE:"' + filename + '"') # 3: Run SAGA commands = self.editCommands(commands) SagaUtils.createSagaBatchJobFileFromSagaCommands(commands) loglines = [] loglines.append(self.tr('SAGA execution commands')) for line in commands: progress.setCommand(line) loglines.append(line) if ProcessingConfig.getSetting(SagaUtils.SAGA_LOG_COMMANDS): ProcessingLog.addToLog(ProcessingLog.LOG_INFO, loglines) SagaUtils.executeSaga(progress)
def processAlgorithm(self, progress): """Here is where the processing itself takes place""" # === INPUT_LAYER # @inprogress test utf8 encoding strategy self.input_layer_asc = self.getParameterValue( self.INPUT_LAYER_ASC.encode('utf-8')) self.window_shape = self.types_of_shape[self.getParameterValue( self.WINDOW_SHAPE)] self.friction_file = self.getParameterValue( self.FRICTION_FILE.encode('utf-8')) self.window_sizes = self.getParameterValue( self.WINDOW_SIZES.encode('utf-8')) self.delta_displacement = self.getParameterValue( self.DELTA_DISPLACEMENT) self.b_interpolate_values = self.getParameterValue( self.INTERPOLATE_VALUES_BOOL) self.filter = self.getParameterValue(self.FILTER.encode('utf-8')) self.unfilter = self.getParameterValue(self.UNFILTER.encode('utf-8')) self.maximum_rate_missing_values = self.getParameterValue( self.MAXIMUM_RATE_MISSING_VALUES) self.metrics = self.getParameterValue(self.METRICS.encode('utf-8')) self.open_all_asc = self.getParameterValue(self.OPEN_ALL_ASC) # === SAVE_PROPERTIES #f_save_properties = self.getParameterValue(self.SAVE_PROPERTIES) f_save_properties = self.getOutputValue(self.SAVE_PROPERTIES) if f_save_properties: self.f_path = f_save_properties else: if not self.f_path: self.f_path = getTempFilename(ext="properties") # === OUTPUT_LAYER # self.output_csv = self.getOutputValue(self.OUTPUT_CSV) # self.output_asc = self.getOutputValue(self.OUTPUT_ASC) self.output_dir = self.getOutputValue( self.OUTPUT_DIR.encode('utf-8')).encode('utf-8') ## Constrution des chemin de sortie des fichiers base_in = os.path.basename(self.input_layer_asc) name_in = os.path.splitext(base_in)[0] ext_in = os.path.splitext(base_in)[1] # === Properties file self.createPropertiesTempFile( ) # Create Properties file (temp or chosed) # === CORE commands = self.getConsoleCommands() # Get args command ChloeUtils.runChole(commands, progress) # RUN # === Projection file for file in glob.glob(self.output_dir + "/*.asc"): dir_out_asc = os.path.dirname(file) base_out_asc = os.path.basename(file) name_out_asc = os.path.splitext(base_out_asc)[0] #ext_out_asc = os.path.splitext(base_out_asc)[1] f_prj = dir_out_asc + os.sep + name_out_asc + ".prj" self.createProjectionFile(f_prj)