[processing] cleanup files from unused code and remove some files

This commit is contained in:
Alexander Bruy 2017-11-27 16:03:14 +02:00
parent ee8435a789
commit 3d4a59bb8b
31 changed files with 42 additions and 1806 deletions

View File

@ -26,15 +26,10 @@ __copyright__ = '(C) 2015, Giovanni Manghi'
__revision__ = '$Format:%H$'
from processing.algs.gdal.GdalAlgorithm import GdalAlgorithm
from processing.core.parameters import ParameterString
from processing.core.parameters import ParameterRaster
from processing.core.parameters import ParameterSelection
from processing.core.outputs import OutputRaster
from processing.algs.gdal.GdalUtils import GdalUtils
from processing.tools.system import isWindows
from processing.algs.gdal.GdalUtils import GdalUtils
class gdalcalc(GdalAlgorithm):

View File

@ -27,12 +27,6 @@ __revision__ = '$Format:%H$'
from qgis.core import QgsSettings
from processing.core.parameters import ParameterString
from processing.core.parameters import ParameterTable
from processing.core.parameters import ParameterSelection
from processing.core.parameters import ParameterBoolean
from processing.core.parameters import ParameterTableField
from processing.algs.gdal.GdalAlgorithm import GdalAlgorithm
from processing.algs.gdal.GdalUtils import GdalUtils

View File

@ -25,15 +25,6 @@ __copyright__ = '(C) 2012, Victor Olaya'
__revision__ = '$Format:%H$'
from processing.core.parameters import ParameterVector
from processing.core.parameters import ParameterString
from processing.core.parameters import ParameterCrs
from processing.core.parameters import ParameterSelection
from processing.core.parameters import ParameterBoolean
from processing.core.parameters import ParameterExtent
from processing.core.parameters import ParameterTableField
from processing.algs.gdal.GdalAlgorithm import GdalAlgorithm
from processing.algs.gdal.GdalUtils import GdalUtils

View File

@ -30,14 +30,6 @@ import os
from qgis.PyQt.QtGui import QIcon
from processing.core.parameters import (ParameterVector,
ParameterExtent,
ParameterTableField,
ParameterSelection,
ParameterNumber,
ParameterString)
from processing.core.outputs import OutputRaster
from processing.algs.gdal.GdalAlgorithm import GdalAlgorithm
from processing.algs.gdal.GdalUtils import GdalUtils

View File

@ -31,10 +31,6 @@ from qgis.core import QgsProcessingUtils
from qgis.PyQt.QtGui import QIcon
from processing.core.parameters import ParameterVector
from processing.core.parameters import ParameterRaster
from processing.core.parameters import ParameterTableField
from processing.algs.gdal.GdalAlgorithm import GdalAlgorithm
from processing.algs.gdal.GdalUtils import GdalUtils

View File

@ -36,7 +36,6 @@ from processing.core.ProcessingConfig import (ProcessingConfig, Setting)
from .Grass7Utils import Grass7Utils
from .Grass7Algorithm import Grass7Algorithm
from processing.tools.system import isWindows, isMac
#from .nviz7 import nviz7
pluginPath = os.path.normpath(os.path.join(
os.path.split(os.path.dirname(__file__))[0], os.pardir))
@ -109,7 +108,6 @@ class Grass7AlgorithmProvider(QgsProcessingProvider):
except Exception as e:
QgsMessageLog.logMessage(
self.tr('Could not open GRASS GIS 7 algorithm: {0}\n{1}').format(descriptionFile, str(e)), self.tr('Processing'), QgsMessageLog.CRITICAL)
#algs.append(nviz7())
return algs
def loadAlgorithms(self):

View File

@ -1,196 +0,0 @@
# -*- coding: utf-8 -*-
"""
***************************************************************************
nviz7.py
---------------------
Date : August 2012
Copyright : (C) 2012 by Victor Olaya
Email : volayaf at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************
"""
__author__ = 'Victor Olaya'
__date__ = 'August 2012'
__copyright__ = '(C) 2012, Victor Olaya'
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'
import os
import time
from qgis.PyQt.QtGui import QIcon
from qgis.core import (QgsProcessingAlgorithm,
QgsRasterLayer,
QgsProcessingUtils)
from processing.core.GeoAlgorithm import GeoAlgorithm
from processing.core.parameters import ParameterMultipleInput
from processing.core.parameters import ParameterExtent
from processing.core.parameters import ParameterNumber
from processing.core.parameters import ParameterRaster
from .Grass7Utils import Grass7Utils
from processing.tools.system import getNumExportedLayers
from processing.tools import dataobjects
pluginPath = os.path.normpath(os.path.join(
os.path.split(os.path.dirname(__file__))[0], os.pardir))
class nviz7(GeoAlgorithm):
ELEVATION = 'ELEVATION'
VECTOR = 'VECTOR'
COLOR = 'COLOR'
GRASS_REGION_EXTENT_PARAMETER = 'GRASS_REGION_PARAMETER'
GRASS_REGION_CELLSIZE_PARAMETER = 'GRASS_REGION_CELLSIZE_PARAMETER'
def icon(self):
return QIcon(os.path.join(pluginPath, 'images', 'grass.png'))
def flags(self):
return QgsProcessingAlgorithm.FlagHideFromModeler
def __init__(self):
super().__init__()
self.addParameter(ParameterMultipleInput(
nviz7.ELEVATION,
self.tr('Raster file(s) for elevation'),
dataobjects.TYPE_RASTER, True))
self.addParameter(ParameterMultipleInput(
nviz7.VECTOR,
self.tr('Vector lines/areas overlay file(s)'),
dataobjects.TYPE_VECTOR_ANY, True))
self.addParameter(ParameterMultipleInput(
nviz7.COLOR,
self.tr('Raster file(s) for color'),
dataobjects.TYPE_RASTER, True))
self.addParameter(ParameterExtent(
nviz7.GRASS_REGION_EXTENT_PARAMETER,
self.tr('GRASS region extent')))
self.addParameter(ParameterNumber(
self.GRASS_REGION_CELLSIZE_PARAMETER,
self.tr('GRASS region cellsize (leave 0 for default)'),
0, None, 0.0))
def name(self):
return 'nviz7'
def displayName(self):
return self.tr('nviz7')
def group(self):
return self.tr('Visualization(NVIZ)')
def processAlgorithm(self, parameters, context, feedback):
commands = []
vector = self.getParameterValue(self.VECTOR)
elevation = self.getParameterValue(self.ELEVATION)
color = self.getParameterValue(self.COLOR)
region = \
str(self.getParameterValue(self.GRASS_REGION_EXTENT_PARAMETER))
if not region:
region = QgsProcessingUtils.combineLayerExtents(layers)
regionCoords = region.split(',')
command = 'g.region '
command += 'n=' + str(regionCoords[3])
command += ' s=' + str(regionCoords[2])
command += ' e=' + str(regionCoords[1])
command += ' w=' + str(regionCoords[0])
cellsize = self.getParameterValue(self.GRASS_REGION_CELLSIZE_PARAMETER)
if cellsize:
command += ' res=' + str(cellsize)
else:
command += ' res=' + str(self.getDefaultCellsize(parameters, context))
commands.append(command)
command = 'nviz7'
if vector:
layers = vector.split(';')
for layer in layers:
(cmd, newfilename) = self.exportVectorLayer(layer)
commands.append(cmd)
vector = vector.replace(layer, newfilename)
command += ' vector=' + vector.replace(';', ',')
if color:
layers = color.split(';')
for layer in layers:
(cmd, newfilename) = self.exportRasterLayer(layer)
commands.append(cmd)
color = color.replace(layer, newfilename)
command += ' color=' + color.replace(';', ',')
if elevation:
layers = elevation.split(';')
for layer in layers:
(cmd, newfilename) = self.exportRasterLayer(layer)
commands.append(cmd)
elevation = elevation.replace(layer, newfilename)
command += ' elevation=' + elevation.replace(';', ',')
if elevation is None and vector is None:
command += ' -q'
commands.append(command)
Grass7Utils.createTempMapset()
Grass7Utils.executeGrass7(commands, feedback)
def getTempFilename(self):
filename = 'tmp' + str(time.time()).replace('.', '') \
+ str(getNumExportedLayers())
return filename
def exportVectorLayer(self, layer):
destFilename = self.getTempFilename()
command = 'v.in.ogr'
command += ' min_area=-1'
command += ' input="' + os.path.dirname(layer) + '"'
command += ' layer=' + os.path.basename(layer)[:-4]
command += ' output=' + destFilename
command += ' --overwrite -o'
return (command, destFilename)
def exportRasterLayer(self, layer):
destFilename = self.getTempFilename()
command = 'r.in.gdal'
command += ' input="' + layer + '"'
command += ' band=1'
command += ' out=' + destFilename
command += ' --overwrite -o'
return (command, destFilename)
def getDefaultCellsize(self, parameters, context):
cellsize = 0
for param in self.parameterDefinitions():
if param.name() in parameters:
value = parameters[param.name()]
if isinstance(param, ParameterRaster):
if isinstance(value, QgsRasterLayer):
layer = value
else:
layer = QgsProcessingUtils.mapLayerFromString(value, context)
cellsize = max(cellsize, (layer.extent().xMaximum() -
layer.extent().xMinimum()) /
layer.width())
elif isinstance(param, ParameterMultipleInput):
layers = value.split(';')
for layername in layers:
layer = QgsProcessingUtils.mapLayerFromString(layername, context)
if isinstance(layer, QgsRasterLayer):
cellsize = max(cellsize, (
layer.extent().xMaximum() -
layer.extent().xMinimum()) /
layer.width())
if cellsize == 0:
cellsize = 1
return cellsize

View File

@ -35,7 +35,6 @@ from qgis.core import (QgsRasterFileWriter,
QgsProcessingParameterNumber,
QgsProcessingParameterRasterDestination)
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
from processing.tools.dataobjects import exportRasterLayer
pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
@ -70,7 +69,7 @@ class Aspect(QgisAlgorithm):
return self.tr('Aspect')
def processAlgorithm(self, parameters, context, feedback):
inputFile = exportRasterLayer(self.parameterAsRasterLayer(parameters, self.INPUT, context))
inputFile = self.parameterAsRasterLayer(parameters, self.INPUT, context).source()
zFactor = self.parameterAsDouble(parameters, self.Z_FACTOR, context)
outputFile = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)

View File

@ -35,7 +35,6 @@ from qgis.core import (QgsRasterFileWriter,
QgsProcessingParameterNumber,
QgsProcessingParameterRasterDestination)
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
from processing.tools.dataobjects import exportRasterLayer
pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
@ -78,7 +77,7 @@ class Hillshade(QgisAlgorithm):
return self.tr('Hillshade')
def processAlgorithm(self, parameters, context, feedback):
inputFile = exportRasterLayer(self.parameterAsRasterLayer(parameters, self.INPUT, context))
inputFile = self.parameterAsRasterLayer(parameters, self.INPUT, context).source()
zFactor = self.parameterAsDouble(parameters, self.Z_FACTOR, context)
azimuth = self.parameterAsDouble(parameters, self.AZIMUTH, context)
vAngle = self.parameterAsDouble(parameters, self.V_ANGLE, context)

View File

@ -43,7 +43,6 @@ from qgis.core import (QgsRectangle,
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
from processing.tools import raster
from processing.tools.dataobjects import exportRasterLayer
class HypsometricCurves(QgisAlgorithm):
@ -82,7 +81,7 @@ class HypsometricCurves(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
raster_layer = self.parameterAsRasterLayer(parameters, self.INPUT_DEM, context)
target_crs = raster_layer.crs()
rasterPath = exportRasterLayer(raster_layer)
rasterPath = raster_layer.source()
source = self.parameterAsSource(parameters, self.BOUNDARY_LAYER, context)
step = self.parameterAsDouble(parameters, self.STEP, context)

View File

@ -41,7 +41,6 @@ from qgis.core import (QgsFeature,
QgsProcessingParameterFeatureSink)
from processing.tools import raster
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
from processing.tools.dataobjects import exportRasterLayer
class PointsFromLines(QgisAlgorithm):
@ -74,7 +73,7 @@ class PointsFromLines(QgisAlgorithm):
source = self.parameterAsSource(parameters, self.INPUT_VECTOR, context)
raster_layer = self.parameterAsRasterLayer(parameters, self.INPUT_RASTER, context)
rasterPath = exportRasterLayer(raster_layer)
rasterPath = raster_layer.source()
rasterDS = gdal.Open(rasterPath, gdal.GA_ReadOnly)
geoTransform = rasterDS.GetGeoTransform()

View File

@ -42,7 +42,6 @@ from qgis.core import (QgsFeatureRequest,
from qgis.PyQt.QtCore import QVariant
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
from processing.tools import raster
from processing.tools.dataobjects import exportRasterLayer
class PointsFromPolygons(QgisAlgorithm):
@ -74,7 +73,7 @@ class PointsFromPolygons(QgisAlgorithm):
source = self.parameterAsSource(parameters, self.INPUT_VECTOR, context)
raster_layer = self.parameterAsRasterLayer(parameters, self.INPUT_RASTER, context)
rasterPath = exportRasterLayer(raster_layer)
rasterPath = raster_layer.source()
rasterDS = gdal.Open(rasterPath, gdal.GA_ReadOnly)
geoTransform = rasterDS.GetGeoTransform()

View File

@ -39,7 +39,6 @@ from qgis.core import (QgsProcessingParameterDefinition,
QgsRasterFileWriter,
QgsProcessingException)
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
from processing.tools.dataobjects import exportRasterLayer
pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
@ -126,7 +125,7 @@ class Relief(QgisAlgorithm):
return self.tr('Relief')
def processAlgorithm(self, parameters, context, feedback):
inputFile = exportRasterLayer(self.parameterAsRasterLayer(parameters, self.INPUT, context))
inputFile = self.parameterAsRasterLayer(parameters, self.INPUT, context).source()
zFactor = self.parameterAsDouble(parameters, self.Z_FACTOR, context)
automaticColors = self.parameterAsBool(parameters, self.AUTO_COLORS, context)
outputFile = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)

View File

@ -35,7 +35,6 @@ from qgis.core import (QgsRasterFileWriter,
QgsProcessingParameterNumber,
QgsProcessingParameterRasterDestination)
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
from processing.tools.dataobjects import exportRasterLayer
pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
@ -71,7 +70,7 @@ class Ruggedness(QgisAlgorithm):
return self.tr('Ruggedness index')
def processAlgorithm(self, parameters, context, feedback):
inputFile = exportRasterLayer(self.parameterAsRasterLayer(parameters, self.INPUT, context))
inputFile = self.parameterAsRasterLayer(parameters, self.INPUT, context).source()
zFactor = self.parameterAsDouble(parameters, self.Z_FACTOR, context)
outputFile = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)

View File

@ -35,8 +35,6 @@ from qgis.core import (QgsRasterFileWriter,
QgsProcessingParameterNumber,
QgsProcessingParameterRasterDestination)
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
from processing.tools.dataobjects import exportRasterLayer
pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
@ -71,7 +69,7 @@ class Slope(QgisAlgorithm):
return self.tr('Slope')
def processAlgorithm(self, parameters, context, feedback):
inputFile = exportRasterLayer(self.parameterAsRasterLayer(parameters, self.INPUT, context))
inputFile = self.parameterAsRasterLayer(parameters, self.INPUT, context).source()
zFactor = self.parameterAsDouble(parameters, self.Z_FACTOR, context)
outputFile = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)

View File

@ -1,22 +1,25 @@
from qgis.core import (QgsProcessingUtils,
QgsProcessingParameterDefinition,
QgsProject)
from processing.gui.wrappers import WidgetWrapper, DIALOG_STANDARD, DIALOG_BATCH
from processing.tools import dataobjects
from processing.tools.system import userFolder
from processing.gui.BatchInputSelectionPanel import BatchInputSelectionPanel
from qgis.PyQt.QtWidgets import (QLineEdit, QPushButton, QLabel,
QComboBox, QSpacerItem, QSizePolicy)
from qgis.PyQt.QtGui import QTextCursor
from processing.core.outputs import OutputRaster
from processing.core.parameters import ParameterRaster
from processing.gui.wrappers import InvalidParameterValue
import os
from qgis.PyQt import uic
from functools import partial
import re
import json
from qgis.PyQt import uic
from qgis.PyQt.QtGui import QTextCursor
from qgis.PyQt.QtWidgets import (QLineEdit, QPushButton, QLabel,
QComboBox, QSpacerItem, QSizePolicy)
from qgis.core import (QgsProcessingUtils,
QgsProcessingParameterDefinition,
QgsProject)
from processing.gui.wrappers import WidgetWrapper, DIALOG_STANDARD, DIALOG_BATCH
from processing.gui.BatchInputSelectionPanel import BatchInputSelectionPanel
from processing.tools import dataobjects
from processing.tools.system import userFolder
from processing.gui.wrappers import InvalidParameterValue
pluginPath = os.path.dirname(__file__)
WIDGET_ADD_NEW, BASE_ADD_NEW = uic.loadUiType(
os.path.join(pluginPath, 'AddNewExpressionDialog.ui'))
@ -183,7 +186,7 @@ class ExpressionWidgetWrapper(WidgetWrapper):
elif self.dialogType == DIALOG_BATCH:
return QLineEdit()
else:
layers = self.dialog.getAvailableValuesOfType(ParameterRaster, OutputRaster)
layers = self.dialog.getAvailableValuesOfType([QgsProcessingParameterRasterLayer], [QgsProcessingOutputRasterLayer])
options = {self.dialog.resolveValueDescription(lyr): "{}@1".format(lyr) for lyr in layers}
return self._panel(options)

View File

@ -1,340 +0,0 @@
# -*- coding: utf-8 -*-
"""
***************************************************************************
GeoAlgorithm.py
---------------------
Date : August 2012
Copyright : (C) 2012 by Victor Olaya
Email : volayaf at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************
"""
__author__ = 'Victor Olaya'
__date__ = 'August 2012'
__copyright__ = '(C) 2012, Victor Olaya'
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'
import os.path
import traceback
import subprocess
import copy
from qgis.PyQt.QtCore import QCoreApplication
from qgis.core import (QgsProcessingFeedback,
QgsSettings,
QgsProcessingAlgorithm,
QgsProject,
QgsProcessingUtils,
QgsProcessingException,
QgsProcessingParameterDefinition,
QgsMessageLog)
from qgis.gui import QgsHelp
from processing.core.ProcessingConfig import ProcessingConfig
from processing.core.parameters import ParameterRaster, ParameterVector, ParameterMultipleInput, ParameterTable, Parameter
from processing.core.outputs import OutputVector, OutputRaster, OutputTable, OutputHTML, Output
from processing.algs.gdal.GdalUtils import GdalUtils
from processing.tools import dataobjects
class GeoAlgorithm(QgsProcessingAlgorithm):
def __init__(self):
super().__init__()
# Outputs generated by the algorithm
self.outputs = list()
# The crs taken from input layers (if possible), and used when
# loading output layers
self.crs = None
# If the algorithm is run as part of a model, the parent model
# can be set in this variable, to allow for customized
# behavior, in case some operations should be run differently
# when running as part of a model
self.model = None
# methods to overwrite when creating a custom geoalgorithm
def processAlgorithm(self, parameters, context, feedback):
"""Here goes the algorithm itself.
There is no return value from this method.
A QgsProcessingException should be raised in case
something goes wrong.
:param parameters:
:param context:
"""
pass
def getCustomModelerParametersDialog(self, modelAlg, algName=None):
"""If the algorithm has a custom parameters dialog when called
from the modeler, it should be returned here, ready to be
executed.
"""
return None
def processBeforeAddingToModeler(self, alg, model):
"""Add here any task that has to be performed before adding an algorithm
to a model, such as changing the value of a parameter depending on value
of another one"""
pass
# =========================================================
def execute(self, parameters, context=None, feedback=None, model=None):
"""The method to use to call a processing algorithm.
Although the body of the algorithm is in processAlgorithm(),
it should be called using this method, since it performs
some additional operations.
Raises a QgsProcessingException in case anything goes
wrong.
:param parameters:
"""
if feedback is None:
feedback = QgsProcessingFeedback()
if context is None:
context = dataobjects.createContext(feedback)
self.model = model
try:
self.setOutputCRS()
self.resolveOutputs()
self.runPreExecutionScript(feedback)
self.processAlgorithm(parameters, context, feedback)
feedback.setProgress(100)
self.convertUnsupportedFormats(context, feedback)
self.runPostExecutionScript(feedback)
except QgsProcessingException as gaee:
lines = [self.tr('Error while executing algorithm')]
lines.append(traceback.format_exc())
QgsMessageLog.logMessage(gaee.msg, self.tr('Processing'), QgsMessageLog.CRITICAL)
raise QgsProcessingException(gaee.msg, lines, gaee)
except Exception as e:
# If something goes wrong and is not caught in the
# algorithm, we catch it here and wrap it
lines = [self.tr('Uncaught error while executing algorithm')]
lines.append(traceback.format_exc())
QgsMessageLog.logMessage('\n'.join(lines), self.tr('Processing'), QgsMessageLog.CRITICAL)
raise QgsProcessingException(str(e) + self.tr('\nSee log for more details'), lines, e)
def runPostExecutionScript(self, feedback):
scriptFile = ProcessingConfig.getSetting(
ProcessingConfig.POST_EXECUTION_SCRIPT)
self.runHookScript(scriptFile, feedback)
def runPreExecutionScript(self, feedback):
scriptFile = ProcessingConfig.getSetting(
ProcessingConfig.PRE_EXECUTION_SCRIPT)
self.runHookScript(scriptFile, feedback)
def runHookScript(self, filename, feedback):
if filename is None or not os.path.exists(filename):
return
try:
script = 'import processing\n'
ns = {}
ns['feedback'] = feedback
ns['alg'] = self
with open(filename) as f:
lines = f.readlines()
for line in lines:
script += line
exec(script, ns)
except Exception as e:
QgsMessageLog.logMessage("Error in hook script: " + str(e), self.tr('Processing'), QgsMessageLog.WARNING)
# A wrong script should not cause problems, so we swallow
# all exceptions
pass
def convertUnsupportedFormats(self, context, feedback):
i = 0
feedback.setProgressText(self.tr('Converting outputs'))
for out in self.outputs:
if isinstance(out, OutputVector):
if out.compatible is not None:
layer = QgsProcessingUtils.mapLayerFromString(out.compatible, context)
if layer is None:
# For the case of memory layer, if the
# getCompatible method has been called
continue
writer = out.getVectorWriter(layer.fields(), layer.wkbType(), layer.crs(), context)
features = QgsProcessingUtils.getFeatures(layer, context)
for feature in features:
writer.addFeature(feature, QgsFeatureSink.FastInsert)
elif isinstance(out, OutputRaster):
if out.compatible is not None:
layer = QgsProcessingUtils.mapLayerFromString(out.compatible, context)
format = self.getFormatShortNameFromFilename(out.value)
orgFile = out.compatible
destFile = out.value
crsid = layer.crs().authid()
settings = QgsSettings()
path = str(settings.value('/GdalTools/gdalPath', ''))
envval = str(os.getenv('PATH'))
if not path.lower() in envval.lower().split(os.pathsep):
envval += '%s%s' % (os.pathsep, path)
os.putenv('PATH', envval)
command = 'gdal_translate -of %s -a_srs %s %s %s' % (format, crsid, orgFile, destFile)
if os.name == 'nt':
command = command.split(" ")
else:
command = [command]
proc = subprocess.Popen(
command,
shell=True,
stdout=subprocess.PIPE,
stdin=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=False,
)
proc.communicate()
elif isinstance(out, OutputTable):
if out.compatible is not None:
layer = QgsProcessingUtils.mapLayerFromString(out.compatible, context)
writer = out.getTableWriter(layer.fields())
features = QgsProcessingUtils.getFeatures(layer, context)
for feature in features:
writer.addRecord(feature)
feedback.setProgress(100 * i / float(len(self.outputs)))
def getFormatShortNameFromFilename(self, filename):
ext = filename[filename.rfind('.') + 1:]
supported = GdalUtils.getSupportedRasters()
for name in list(supported.keys()):
exts = supported[name]
if ext in exts:
return name
return 'GTiff'
def resolveOutputs(self):
"""Sets temporary outputs (output.value = None) with a
temporary file instead. Resolves expressions as well.
"""
try:
for out in self.outputs:
out.resolveValue(self)
except ValueError as e:
raise QgsProcessingException(str(e))
def setOutputCRS(self):
context = dataobjects.createContext()
layers = QgsProcessingUtils.compatibleLayers(QgsProject.instance())
for param in self.parameterDefinitions():
if isinstance(param, (ParameterRaster, ParameterVector, ParameterMultipleInput)):
if param.value:
if isinstance(param, ParameterMultipleInput):
inputlayers = param.value.split(';')
else:
inputlayers = [param.value]
for inputlayer in inputlayers:
for layer in layers:
if layer.source() == inputlayer:
self.crs = layer.crs()
return
p = QgsProcessingUtils.mapLayerFromString(inputlayer, context)
if p is not None:
self.crs = p.crs()
p = None
return
try:
from qgis.utils import iface
if iface is not None:
self.crs = iface.mapCanvas().mapSettings().destinationCrs()
except:
pass
def addOutput(self, output):
# TODO: check that name does not exist
if isinstance(output, Output):
self.outputs.append(output)
def addParameter(self, param):
# TODO: check that name does not exist
if isinstance(param, Parameter):
self.parameters.append(param)
def setOutputValue(self, outputName, value):
for out in self.outputs:
if out.name == outputName:
out.setValue(value)
def removeOutputFromName(self, name):
for out in self.outputs:
if out.name == name:
self.outputs.remove(out)
def getOutputFromName(self, name):
for out in self.outputs:
if out.name == name:
return out
def getParameterValue(self, name):
for param in self.parameters:
if param.name == name:
return param.value
return None
def getOutputValue(self, name):
for out in self.outputs:
if out.name == name:
return out.value
return None
def tr(self, string, context=''):
if context == '':
context = self.__class__.__name__
return QCoreApplication.translate(context, string)
def trAlgorithm(self, string, context=''):
if context == '':
context = self.__class__.__name__
return string, QCoreApplication.translate(context, string)
def executeAlgorithm(alg, parameters, context=None, feedback=None, model=None):
"""The method to use to call a processing algorithm.
Although the body of the algorithm is in processAlgorithm(),
it should be called using this method, since it performs
some additional operations.
Raises a QgsProcessingException in case anything goes
wrong.
:param parameters:
"""
if feedback is None:
feedback = QgsProcessingFeedback()
if context is None:
context = dataobjects.createContext(feedback)
#self.model = model
#self.setOutputCRS()
#self.resolveOutputs()
#self.evaluateParameterValues()
#self.runPreExecutionScript(feedback)
result, ok = alg.run(parameters, context, feedback)
#self.processAlgorithm(parameters, context, feedback)
feedback.setProgress(100)
return result, ok
#self.convertUnsupportedFormats(context, feedback)
#self.runPostExecutionScript(feedback)

View File

@ -47,7 +47,6 @@ from qgis.core import (QgsMessageLog,
import processing
from processing.script.ScriptUtils import ScriptUtils
from processing.core.ProcessingConfig import ProcessingConfig
from processing.core.GeoAlgorithm import GeoAlgorithm
from processing.gui.MessageBarProgress import MessageBarProgress
from processing.gui.RenderingStyles import RenderingStyles
from processing.gui.Postprocessing import handleAlgorithmResults

View File

@ -25,16 +25,8 @@ __copyright__ = '(C) 2012, Victor Olaya'
__revision__ = '$Format:%H$'
import os
import sys
from qgis.PyQt.QtCore import QCoreApplication
from processing.core.ProcessingConfig import ProcessingConfig
from processing.tools.system import isWindows, getTempDirInTempFolder
from processing.tools.vector import TableWriter, NOGEOMETRY_EXTENSIONS
from processing.tools import dataobjects
from qgis.core import (QgsExpressionContext,
QgsExpressionContextUtils,
QgsExpression,
@ -53,341 +45,6 @@ from qgis.core import (QgsExpressionContext,
QgsProcessingOutputFolder)
def _expressionContext(alg):
context = QgsExpressionContext()
context.appendScope(QgsExpressionContextUtils.globalScope())
context.appendScope(QgsExpressionContextUtils.projectScope(QgsProject.instance()))
processingScope = QgsExpressionContextScope()
for param in alg.parameters:
processingScope.setVariable('%s_value' % param.name, '')
context.appendScope(processingScope)
return context
class Output:
def __init__(self, name='', description='', hidden=False):
self.name = name
# The value of an output is a string representing the location
# of the output. For a file based output, it should be the
# filepath to it.
self.value = None
def __str__(self):
return u'{} <{}>'.format(self.name, self.__class__.__name__)
def getValueAsCommandLineParameter(self):
if self.value is None:
return str(None)
else:
if not isWindows():
return '"' + str(self.value) + '"'
else:
return '"' + str(self.value).replace('\\', '\\\\') + '"'
def setValue(self, value):
try:
if value is not None and isinstance(value, str):
value = value.strip()
self.value = value
return True
except:
return False
def _resolveTemporary(self, alg):
ext = self.getDefaultFileExtension()
return QgsProcessingUtils.generateTempFilename(self.name + '.' + ext)
def _supportedExtensions(self):
return []
def resolveValue(self, alg):
if self.flags() & QgsProcessingParameterDefinition.FlagHidden:
return
if not bool(self.value):
self.value = self._resolveTemporary(alg)
else:
exp = QgsExpression(self.value)
if not exp.hasParserError():
value = exp.evaluate(_expressionContext(alg))
if not exp.hasEvalError():
self.value = value
if ":" not in self.value:
if not os.path.isabs(self.value):
self.value = os.path.join(ProcessingConfig.getSetting(ProcessingConfig.OUTPUT_FOLDER),
self.value)
supported = self._supportedExtensions()
if supported:
idx = self.value.rfind('.')
if idx == -1:
self.value = self.value + '.' + self.getDefaultFileExtension()
else:
ext = self.value[idx + 1:]
if ext not in supported:
self.value = self.value + '.' + self.getDefaultFileExtension()
def expressionContext(self, alg):
return _expressionContext(alg)
def tr(self, string, context=''):
if context == '':
context = 'Output'
return QCoreApplication.translate(context, string)
class OutputDirectory(Output):
def resolveValue(self, alg):
self.value = getTempDirInTempFolder()
class OutputExtent(Output):
def __init__(self, name='', description=''):
self.name = name
self.value = None
self.setFlags(self.flags() | QgsProcessingParameterDefinition.FlagHidden)
def setValue(self, value):
try:
if value is not None and isinstance(value, str):
value = value.strip()
else:
self.value = ','.join([str(v) for v in value])
return True
except:
return False
class OutputCrs(Output):
def __init__(self, name='', description=''):
Output.__init__(self, name, description, True)
class OutputFile(Output):
def __init__(self, name='', description='', ext=None):
Output.__init__(self, name, description)
self.ext = ext
def getFileFilter(self, alg):
if self.ext is None:
return self.tr('All files (*.*)', 'OutputFile')
else:
return self.tr('{0} files (*.{1})', 'OutputFile').format(self.ext, self.ext)
def getDefaultFileExtension(self):
return self.ext or 'file'
class OutputHTML(Output):
def getFileFilter(self, alg):
return self.tr('HTML files (*.html)', 'OutputHTML')
def getDefaultFileExtension(self):
return 'html'
class OutputNumber(Output):
def __init__(self, name='', description=''):
Output.__init__(self, name, description, True)
class OutputRaster(Output):
compatible = None
def getFileFilter(self, alg):
exts = dataobjects.getSupportedOutputRasterLayerExtensions()
for i in range(len(exts)):
exts[i] = self.tr('{0} files (*.{1})', 'OutputVector').format(exts[i].upper(), exts[i].lower())
return ';;'.join(exts)
def getDefaultFileExtension(self):
return ProcessingConfig.getSetting(ProcessingConfig.DEFAULT_OUTPUT_RASTER_LAYER_EXT, True)
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
class OutputString(Output):
def __init__(self, name='', description=''):
Output.__init__(self, name, description, True)
class OutputTable(Output):
encoding = None
compatible = None
def getFileFilter(self, alg):
exts = ['dbf']
for i in range(len(exts)):
exts[i] = self.tr("{0} files (*.{1})").format(exts[i].upper(), exts[i].lower())
return ';;'.join(exts)
def getDefaultFileExtension(self):
return "dbf"
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 getTableWriter(self, fields):
"""
Returns a suitable writer to which records can be added as a
result of the algorithm. Use this to transparently handle
output values instead of creating your own method.
@param fields a list of field titles
@return writer instance of the table writer class
"""
if self.encoding is None:
settings = QgsSettings()
self.encoding = settings.value('/Processing/encoding', 'System')
return TableWriter(self.value, self.encoding, fields)
class OutputVector(Output):
encoding = None
compatible = None
def __init__(self, name='', description='', hidden=False, base_input=None, datatype=[-1]):
Output.__init__(self, name, description, hidden)
self.base_input = base_input
self.base_layer = None
if isinstance(datatype, int):
datatype = [datatype]
elif isinstance(datatype, str):
datatype = [int(t) for t in datatype.split(',')]
self.datatype = datatype
def hasGeometry(self):
if self.base_layer is None:
return True
return self.base_layer.isSpatial()
def getSupportedOutputVectorLayerExtensions(self):
exts = QgsVectorFileWriter.supportedFormatExtensions()
if not self.hasGeometry():
exts = ['dbf'] + [ext for ext in exts if ext in NOGEOMETRY_EXTENSIONS]
return exts
def getFileFilter(self, alg):
exts = self.getSupportedOutputVectorLayerExtensions()
for i in range(len(exts)):
exts[i] = self.tr('{0} files (*.{1})', 'OutputVector').format(exts[i].upper(), exts[i].lower())
return ';;'.join(exts)
def getDefaultFileExtension(self):
if self.hasGeometry():
default = ProcessingConfig.getSetting(ProcessingConfig.DEFAULT_OUTPUT_VECTOR_LAYER_EXT, True)
else:
default = 'dbf'
return default
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().supportedOutputVectorLayerExtensions():
return self.value
else:
if self.compatible is None:
default = self.getDefaultFileExtension()
supported = alg.provider().supportedOutputVectorLayerExtensions()
ext = default if default in supported else supported[0]
self.compatible = QgsProcessingUtils.generateTempFilename(self.name + '.' + ext)
return self.compatible
def getVectorWriter(self, fields, geomType, crs, context):
"""Returns a suitable writer to which features can be added as
a result of the algorithm. Use this to transparently handle
output values instead of creating your own method.
Executing this method might modify the object, adding additional
information to it, so the writer can be later accessed and
processed within QGIS. It should be called just once, since a
new call might result in previous data being replaced, thus
rendering a previously obtained writer useless.
@param fields a list of QgsField
@param geomType a suitable geometry type, as it would be passed
to a QgsVectorFileWriter constructor
@param crs the crs of the layer to create
@return writer instance of the vector writer class
:param context:
"""
if self.encoding is None:
settings = QgsSettings()
self.encoding = settings.value('/Processing/encoding', 'System', str)
w, w_dest = QgsProcessingUtils.createFeatureSink(self.value, context, fields, geomType, crs, {'fileEncoding': self.encoding})
self.value = w_dest
return w
def dataType(self):
return dataobjects.vectorDataType(self)
def _resolveTemporary(self, alg):
if alg.provider().supportsNonFileBasedOutput():
return "memory:"
else:
ext = self.getDefaultFileExtension()
return QgsProcessingUtils.generateTempFilename(self.name + '.' + ext)
def getOutputFromString(s):
try:
if "|" in s and s.startswith("Output"):

View File

@ -26,21 +26,17 @@ __copyright__ = '(C) 2012, Victor Olaya'
__revision__ = '$Format:%H$'
import sys
import os
import math
from inspect import isclass
from copy import deepcopy
import numbers
from qgis.core import QgsProcessingUtils
from qgis.PyQt.QtCore import QCoreApplication
from qgis.core import (QgsRasterLayer, QgsVectorLayer, QgsMapLayer, QgsCoordinateReferenceSystem,
from qgis.core import (QgsRasterLayer,
QgsVectorLayer,
QgsMapLayer,
QgsCoordinateReferenceSystem,
QgsExpression,
QgsProject,
QgsRectangle,
QgsVectorFileWriter,
QgsProcessing,
QgsProcessingUtils,
QgsProcessingParameters,
QgsProcessingParameterDefinition,
QgsProcessingParameterRasterLayer,
@ -63,522 +59,6 @@ from qgis.core import (QgsRasterLayer, QgsVectorLayer, QgsMapLayer, QgsCoordinat
QgsProcessingParameterFeatureSource,
QgsProcessingParameterNumber)
from processing.tools.vector import resolveFieldIndex
from processing.tools import dataobjects
from processing.core.outputs import OutputNumber, OutputRaster, OutputVector
def parseBool(s):
if s is None or s == str(None).lower():
return None
return str(s).lower() == str(True).lower()
def _splitParameterOptions(line):
tokens = line.split('=', 1)
if tokens[1].lower().strip().startswith('optional'):
isOptional = True
definition = tokens[1].strip()[len('optional') + 1:]
else:
isOptional = False
definition = tokens[1]
return isOptional, tokens[0], definition
class Parameter:
"""
Base class for all parameters that a geoalgorithm might
take as input.
"""
def __init__(self, name='', description='', default=None, optional=False,
metadata={}):
self.value = default
def __str__(self):
return u'{} <{}>'.format(self.name(), self.__class__.__name__)
def todict(self):
o = deepcopy(self.__dict__)
del o['metadata']
return o
def tr(self, string, context=''):
if context == '':
context = 'Parameter'
return QCoreApplication.translate(context, string)
class ParameterBoolean(Parameter):
def __init__(self, name='', description='', default=None, optional=False, metadata={}):
Parameter.__init__(self, name, description, parseBool(default), optional, metadata)
class ParameterCrs(Parameter):
def __init__(self, name='', description='', default=None, optional=False, metadata={}):
'''The value is a string that uniquely identifies the
coordinate reference system. Typically it is the auth id of the CRS
(if the authority is EPSG) or proj4 string of the CRS (in case
of other authorities or user defined projections).'''
Parameter.__init__(self, name, description, default, optional, metadata)
if self.value == 'ProjectCrs':
self.value = QgsProject.instance().crs().authid()
class ParameterExtent(Parameter):
USE_MIN_COVERING_EXTENT = 'USE_MIN_COVERING_EXTENT'
def __init__(self, name='', description='', default=None, optional=True):
Parameter.__init__(self, name, description, default, optional)
# The value is a string in the form "xmin, xmax, ymin, ymax"
self.skip_crs_check = False
class ParameterPoint(Parameter):
def __init__(self, name='', description='', default=None, optional=False):
Parameter.__init__(self, name, description, default, optional)
# The value is a string in the form "x, y"
class ParameterFile(Parameter):
def __init__(self, name='', description='', isFolder=False, optional=True, ext=None):
Parameter.__init__(self, name, description, None, parseBool(optional))
self.ext = ext
self.isFolder = parseBool(isFolder)
class ParameterFixedTable(Parameter):
def __init__(self, name='', description='', numRows=3,
cols=['value'], fixedNumOfRows=False, optional=False):
Parameter.__init__(self, name, description, None, optional)
self.cols = cols
if isinstance(cols, str):
self.cols = self.cols.split(";")
self.numRows = int(numRows)
self.fixedNumOfRows = parseBool(fixedNumOfRows)
@staticmethod
def tableToString(table):
tablestring = ''
for i in range(len(table)):
for j in range(len(table[0])):
tablestring = tablestring + table[i][j] + ','
tablestring = tablestring[:-1]
return tablestring
class ParameterMultipleInput(Parameter):
"""A parameter representing several data objects.
Its value is a string with substrings separated by semicolons,
each of which represents the data source location of each element.
"""
exported = None
def __init__(self, name='', description='', datatype=-1, optional=False, metadata={}):
Parameter.__init__(self, name, description, None, optional, metadata=metadata)
self.datatype = int(float(datatype))
self.exported = None
self.minNumInputs = 0
""" Set minimum required number of inputs for parameter
By default minimal number of inputs is set to 1
@type _minNumInputs: numeric type or None
@param _minNumInputs: required minimum number of inputs for parameter. \
If user will pass None as parameter, we will use default minimal number of inputs (1)
@return: result, if the minimum number of inputs were set.
"""
def setMinNumInputs(self, _minNumInputs):
if _minNumInputs is None:
self.minNumInputs = 0
return True
if _minNumInputs < 1 and not self.flags() & QgsProcessingParameterDefinition.FlagOptional:
# don't allow setting negative or null number of inputs if parameter isn't optional
return False
self.minNumInputs = int(_minNumInputs)
return True
""" Get minimum required number of inputs for parameter
@return: minimum number of inputs required for this parameter
@see: setMinNumInputs()
"""
def getMinNumInputs(self):
return self.minNumInputs
def getSafeExportedLayers(self):
"""
Returns not the value entered by the user, but a string with
semicolon-separated filenames which contains the data of the
selected layers, but saved in a standard format (currently
shapefiles for vector layers and GeoTiff for raster) so that
they can be opened by most external applications.
If there is a selection and QGIS is configured to use just the
selection, it exports the layer even if it is already in a
suitable format.
Works only if the layer represented by the parameter value is
currently loaded in QGIS. Otherwise, it will not perform any
export and return the current value string.
If the current value represents a layer in a suitable format,
it does no export at all and returns that value.
Currently, it works just for vector layer. In the case of
raster layers, it returns the parameter value.
The layers are exported just the first time the method is
called. The method can be called several times and it will
always return the same string, performing the export only the
first time.
"""
context = dataobjects.createContext()
if self.exported:
return self.exported
self.exported = self.value
layers = self.value.split(';')
if layers is None or len(layers) == 0:
return self.value
if self.datatype == dataobjects.TYPE_RASTER:
for layerfile in layers:
layer = QgsProcessingUtils.mapLayerFromString(layerfile, context, False)
if layer:
filename = dataobjects.exportRasterLayer(layer)
self.exported = self.exported.replace(layerfile, filename)
return self.exported
elif self.datatype == dataobjects.TYPE_FILE:
return self.value
else:
for layerfile in layers:
layer = QgsProcessingUtils.mapLayerFromString(layerfile, context, False)
if layer:
filename = dataobjects.exportVectorLayer(layer)
self.exported = self.exported.replace(layerfile, filename)
return self.exported
def getAsString(self, value):
if self.datatype == dataobjects.TYPE_RASTER:
if isinstance(value, QgsRasterLayer):
return str(value.dataProvider().dataSourceUri())
else:
s = str(value)
layers = QgsProcessingUtils.compatibleRasterLayers(QgsProject.instance())
for layer in layers:
if layer.name() == s:
return str(layer.dataProvider().dataSourceUri())
return s
if self.datatype == dataobjects.TYPE_FILE:
return str(value)
else:
if isinstance(value, QgsVectorLayer):
return str(value.source())
else:
s = str(value)
if self.datatype != dataobjects.TYPE_VECTOR_ANY:
layers = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance(), [self.datatype], False)
else:
layers = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance(), [], False)
for layer in layers:
if layer.name() == s:
return str(layer.source())
return s
def dataType(self):
if self.datatype == dataobjects.TYPE_VECTOR_POINT:
return 'points'
elif self.datatype == dataobjects.TYPE_VECTOR_LINE:
return 'lines'
elif self.datatype == dataobjects.TYPE_VECTOR_POLYGON:
return 'polygons'
elif self.datatype == dataobjects.TYPE_RASTER:
return 'rasters'
elif self.datatype == dataobjects.TYPE_FILE:
return 'files'
else:
return 'any vectors'
class ParameterNumber(Parameter):
def __init__(self, name='', description='', minValue=None, maxValue=None,
default=None, optional=False, metadata={}):
Parameter.__init__(self, name, description, default, optional, metadata)
if default is not None:
try:
self.default = int(str(default))
self.isInteger = True
except ValueError:
self.default = float(default)
self.isInteger = False
else:
self.isInteger = False
if minValue is not None:
self.min = int(float(minValue)) if self.isInteger else float(minValue)
else:
self.min = None
if maxValue is not None:
self.max = int(float(maxValue)) if self.isInteger else float(maxValue)
else:
self.max = None
self.value = self.default
def _layerVariables(self, element, alg=None):
variables = {}
context = createContext()
layer = QgsProcessingUtils.mapLayerFromString(element.value, context)
if layer is not None:
name = element.name if alg is None else "%s_%s" % (alg.name, element.name)
variables['@%s_minx' % name] = layer.extent().xMinimum()
variables['@%s_miny' % name] = layer.extent().yMinimum()
variables['@%s_maxx' % name] = layer.extent().yMaximum()
variables['@%s_maxy' % name] = layer.extent().yMaximum()
if isinstance(element, (ParameterRaster, OutputRaster)):
stats = layer.dataProvider().bandStatistics(1)
variables['@%s_avg' % name] = stats.mean
variables['@%s_stddev' % name] = stats.stdDev
variables['@%s_min' % name] = stats.minimumValue
variables['@%s_max' % name] = stats.maximumValue
return variables
class ParameterRange(Parameter):
def __init__(self, name='', description='', default=None, optional=False):
Parameter.__init__(self, name, description, default, optional)
if default is not None:
values = default.split(',')
try:
int(values[0])
int(values[1])
self.isInteger = True
except:
self.isInteger = False
else:
self.isInteger = False
class ParameterRaster(Parameter):
def __init__(self, name='', description='', optional=False, showSublayersDialog=True):
Parameter.__init__(self, name, description, None, optional)
self.showSublayersDialog = parseBool(showSublayersDialog)
class ParameterSelection(Parameter):
def __init__(self, name='', description='', options=[], default=None, isSource=False,
multiple=False, optional=False, metadata={}):
Parameter.__init__(self, name, description, default, optional, metadata)
self.multiple = multiple
isSource = parseBool(isSource)
self.options = options
if isSource:
self.options = []
layer = QgsVectorLayer(options[0], "layer", "ogr")
if layer.isValid():
try:
index = resolveFieldIndex(layer, options[1])
feats = QgsProcessingUtils.getFeatures(layer, dataobjects.createContext())
for feature in feats:
self.options.append(str(feature.attributes()[index]))
except ValueError:
pass
elif isinstance(self.options, str):
self.options = self.options.split(";")
# compute options as (value, text)
options = []
for i, option in enumerate(self.options):
if option is None or isinstance(option, str):
options.append((i, option))
else:
options.append((option[0], option[1]))
self.options = options
self.values = [option[0] for option in options]
self.value = None
@classmethod
def fromScriptCode(self, line):
isOptional, name, definition = _splitParameterOptions(line)
descName = QgsProcessingParameters.descriptionFromName(name)
if definition.lower().strip().startswith('selectionfromfile'):
options = definition.strip()[len('selectionfromfile '):].split(';')
return ParameterSelection(name, descName, options, isSource=True, optional=isOptional)
elif definition.lower().strip().startswith('selection'):
options = definition.strip()[len('selection '):].split(';')
return ParameterSelection(name, descName, options, optional=isOptional)
elif definition.lower().strip().startswith('multipleselectionfromfile'):
options = definition.strip()[len('multipleselectionfromfile '):].split(';')
return ParameterSelection(name, descName, options, isSource=True,
multiple=True, optional=isOptional)
elif definition.lower().strip().startswith('multipleselection'):
options = definition.strip()[len('multipleselection '):].split(';')
return ParameterSelection(name, descName, options, multiple=True, optional=isOptional)
class ParameterEvaluationException(Exception):
def __init__(self, param, msg):
Exception.__init__(msg)
self.param = param
class ParameterString(Parameter):
def __init__(self, name='', description='', default=None, multiline=False,
optional=False, evaluateExpressions=False, metadata={}):
Parameter.__init__(self, name, description, default, optional, metadata)
self.multiline = parseBool(multiline)
class ParameterExpression(Parameter):
def __init__(self, name='', description='', default=None, optional=False, parent_layer=None):
Parameter.__init__(self, name, description, default, optional)
self.parent_layer = parent_layer
class ParameterTable(Parameter):
def __init__(self, name='', description='', optional=False):
Parameter.__init__(self, name, description, None, optional)
self.exported = None
def getSafeExportedTable(self):
"""Returns not the value entered by the user, but a string with
a filename which contains the data of this table, but saved in
a standard format (currently always a DBF file) so that it can
be opened by most external applications.
Works only if the table represented by the parameter value is
currently loaded in QGIS. Otherwise, it will not perform any
export and return the current value string.
If the current value represents a table in a suitable format,
it does not export at all and returns that value.
The table is exported just the first time the method is called.
The method can be called several times and it will always
return the same file, performing the export only the first
time.
"""
context = dataobjects.createContext()
if self.exported:
return self.exported
table = QgsProcessingUtils.mapLayerFromString(self.value, context, False)
if table:
self.exported = dataobjects.exportTable(table)
else:
self.exported = self.value
return self.exported
class ParameterTableField(Parameter):
"""A parameter representing a table field.
Its value is a string that represents the name of the field.
"""
DATA_TYPE_NUMBER = 0
DATA_TYPE_STRING = 1
DATA_TYPE_DATETIME = 2
DATA_TYPE_ANY = -1
def __init__(self, name='', description='', parent=None, datatype=-1,
optional=False, multiple=False):
Parameter.__init__(self, name, description, None, optional)
self.parent = parent
self.multiple = multiple
self.datatype = int(datatype)
def __str__(self):
return self.name() + ' <' + self.__module__.split('.')[-1] + ' from ' \
+ self.parent + '>'
def dataType(self):
if self.datatype == self.DATA_TYPE_NUMBER:
return 'numeric'
elif self.datatype == self.DATA_TYPE_STRING:
return 'string'
elif self.datatype == self.DATA_TYPE_DATETIME:
return 'datetime'
else:
return 'any'
class ParameterVector(Parameter):
def __init__(self, name='', description='', datatype=[-1],
optional=False):
Parameter.__init__(self, name, description, None, optional)
if isinstance(datatype, int):
datatype = [datatype]
elif isinstance(datatype, str):
datatype = [int(t) for t in datatype.split(',')]
self.datatype = datatype
self.exported = None
self.allowOnlyOpenedLayers = False
def getSafeExportedLayer(self):
"""Returns not the value entered by the user, but a string with
a filename which contains the data of this layer, but saved in
a standard format (currently always a shapefile) so that it can
be opened by most external applications.
If there is a selection and QGIS is configured to use just the
selection, if exports the layer even if it is already in a
suitable format.
Works only if the layer represented by the parameter value is
currently loaded in QGIS. Otherwise, it will not perform any
export and return the current value string.
If the current value represents a layer in a suitable format,
it does not export at all and returns that value.
The layer is exported just the first time the method is called.
The method can be called several times and it will always
return the same file, performing the export only the first
time.
"""
context = dataobjects.createContext()
if self.exported:
return self.exported
layer = QgsProcessingUtils.mapLayerFromString(self.value, context, False)
if layer:
self.exported = dataobjects.exportVectorLayer(layer)
else:
self.exported = self.value
return self.exported
def dataType(self):
return dataobjects.vectorDataType(self)
paramClasses = [c for c in list(sys.modules[__name__].__dict__.values()) if isclass(c) and issubclass(c, Parameter)]
def getParameterFromString(s):
# Try the parameter definitions used in description files
@ -715,12 +195,3 @@ def getParameterFromString(s):
param = QgsProcessingParameters.parameterFromScriptCode(s)
if param:
return param
# try Python duck-typed method
for paramClass in paramClasses:
try:
param = paramClass.fromScriptCode(s)
if param is not None:
return param
except:
pass

View File

@ -55,11 +55,6 @@ from processing.gui.AlgorithmDialogBase import AlgorithmDialogBase
from processing.gui.AlgorithmExecutor import executeIterating
from processing.gui.Postprocessing import handleAlgorithmResults
from processing.core.parameters import ParameterRaster
from processing.core.parameters import ParameterVector
from processing.core.parameters import ParameterExtent
from processing.core.parameters import ParameterMultipleInput
from processing.tools import dataobjects

View File

@ -35,20 +35,10 @@ from qgis.core import (QgsApplication,
QgsSettings,
QgsProcessingParameterDefinition)
from qgis.gui import QgsMessageBar
from processing.gui.wrappers import WidgetWrapperFactory
from processing.gui.wrappers import WidgetWrapperFactory
from processing.gui.BatchOutputSelectionPanel import BatchOutputSelectionPanel
from processing.core.parameters import ParameterFile # NOQA
from processing.core.parameters import ParameterRaster # NOQA
from processing.core.parameters import ParameterTable # NOQA
from processing.core.parameters import ParameterVector # NOQA
from processing.core.parameters import ParameterExtent # NOQA
from processing.core.parameters import ParameterCrs # NOQA
from processing.core.parameters import ParameterPoint # NOQA
from processing.core.parameters import ParameterSelection # NOQA
from processing.core.parameters import ParameterFixedTable # NOQA
from processing.core.parameters import ParameterMultipleInput # NOQA
from processing.tools import dataobjects
pluginPath = os.path.split(os.path.dirname(__file__))[0]

View File

@ -97,28 +97,13 @@ from qgis.gui import (
from qgis.PyQt.QtCore import pyqtSignal, QObject, QVariant, Qt
from qgis.utils import iface
from processing.core.ProcessingConfig import ProcessingConfig
from processing.modeler.MultilineTextPanel import MultilineTextPanel
from processing.gui.NumberInputPanel import NumberInputPanel, ModellerNumberInputPanel
from processing.gui.RangePanel import RangePanel
from processing.modeler.MultilineTextPanel import MultilineTextPanel
from processing.gui.PointSelectionPanel import PointSelectionPanel
from processing.core.parameters import (ParameterBoolean,
ParameterPoint,
ParameterFile,
ParameterRaster,
ParameterVector,
ParameterNumber,
ParameterString,
ParameterExpression,
ParameterTable,
ParameterTableField,
ParameterExtent,
ParameterFixedTable,
ParameterCrs)
from processing.core.ProcessingConfig import ProcessingConfig
from processing.gui.FileSelectionPanel import FileSelectionPanel
from processing.core.outputs import (OutputFile, OutputRaster, OutputVector,
OutputString, OutputTable, OutputExtent)
from processing.tools import dataobjects
from processing.gui.CheckboxesPanel import CheckboxesPanel
from processing.gui.MultipleInputPanel import MultipleInputPanel
from processing.gui.BatchInputSelectionPanel import BatchInputSelectionPanel
@ -126,6 +111,8 @@ from processing.gui.FixedTablePanel import FixedTablePanel
from processing.gui.ExtentSelectionPanel import ExtentSelectionPanel
from processing.gui.ParameterGuiUtils import getFileFilter
from processing.tools import dataobjects
DIALOG_STANDARD = 'standard'
DIALOG_BATCH = 'batch'
DIALOG_MODELER = 'modeler'

View File

@ -68,7 +68,7 @@ class ModelerParametersDialog(QDialog):
def __init__(self, alg, model, algName=None):
QDialog.__init__(self)
self.setModal(True)
# The algorithm to define in this dialog. It is an instance of GeoAlgorithm
# The algorithm to define in this dialog. It is an instance of QgsProcessingModelAlgorithm
self._alg = alg
# The model this algorithm is going to be added to
self.model = model

View File

@ -39,7 +39,6 @@ from qgis.core import (QgsExpressionContextUtils,
from qgis.PyQt.QtCore import (QCoreApplication)
from processing.core.GeoAlgorithm import GeoAlgorithm
from processing.gui.Help2Html import getHtmlFromHelpFile
from processing.core.parameters import getParameterFromString
from processing.core.outputs import getOutputFromString

View File

@ -7,7 +7,6 @@ PLUGIN_INSTALL(processing tests/testdata ${TEST_DATA_FILES})
IF(ENABLE_TESTS)
INCLUDE(UsePythonTest)
ADD_PYTHON_TEST(ProcessingGuiTest GuiTest.py)
ADD_PYTHON_TEST(ProcessingParametersTest ParametersTest.py)
ADD_PYTHON_TEST(ProcessingModelerTest ModelerTest.py)
ADD_PYTHON_TEST(ProcessingToolsTest ToolsTest.py)
ADD_PYTHON_TEST(ProcessingQgisAlgorithmsTest QgisAlgorithmsTest.py)

View File

@ -1,124 +0,0 @@
# -*- coding: utf-8 -*-
"""
***************************************************************************
ParametersTest
---------------------
Date : March 2013
Copyright : (C) 2013 by Victor Olaya
Email : volayaf at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************
"""
__author__ = 'Victor Olaya'
__date__ = 'March 2013'
__copyright__ = '(C) 2013, Victor Olaya'
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'
import sys
from inspect import isclass
from qgis.testing import start_app, unittest
from processing.core.parameters import (Parameter,
ParameterBoolean,
ParameterCrs,
ParameterExtent,
ParameterFile,
ParameterFixedTable,
ParameterMultipleInput,
ParameterNumber,
ParameterPoint,
ParameterString,
ParameterVector,
ParameterTable,
ParameterTableField,
ParameterSelection,
ParameterExpression,
getParameterFromString)
from processing.tools import dataobjects
from processing.tests.TestData import points
from qgis.core import (QgsRasterLayer,
QgsVectorLayer)
start_app()
class ParameterSelectionTest(unittest.TestCase):
def testTupleOptions(self):
options = (
('o1', 'option1'),
('o2', 'option2'),
('o3', 'option3'))
optionalParameter = ParameterSelection('myName', 'myDesc', options, default='o1')
self.assertEqual(optionalParameter.value, 'o1')
optionalParameter.setValue('o2')
self.assertEqual(optionalParameter.value, 'o2')
optionalParameter = ParameterSelection('myName', 'myDesc', options, default=['o1', 'o2'], multiple=True)
self.assertEqual(optionalParameter.value, ['o1', 'o2'])
optionalParameter.setValue(['o2'])
self.assertEqual(optionalParameter.value, ['o2'])
class TestParameterFixedTable(unittest.TestCase):
def testTableToString(self):
table = [
['a0', 'a1', 'a2'],
['b0', 'b1', 'b2']
]
self.assertEqual(ParameterFixedTable.tableToString(table), 'a0,a1,a2,b0,b1,b2')
table = [['a0']]
self.assertEqual(ParameterFixedTable.tableToString(table), 'a0')
table = [[]]
self.assertEqual(ParameterFixedTable.tableToString(table), '')
class ParameterMultipleInputTest(unittest.TestCase):
def testGetAsStringWhenRaster(self):
parameter = ParameterMultipleInput('myName', 'myDesc', datatype=dataobjects.TYPE_RASTER)
# With Path
self.assertEqual(parameter.getAsString('/some/path'), '/some/path')
# With Layer
layer = QgsRasterLayer('/path/to/myRaster.tif', 'myRaster')
self.assertEqual(parameter.getAsString(layer), '/path/to/myRaster.tif')
# TODO With Layer Name, instead of Layer object
def testGetAsStringWhenFile(self):
parameter = ParameterMultipleInput('myName', 'myDesc', datatype=dataobjects.TYPE_FILE)
self.assertEqual(parameter.getAsString('/some/path'), '/some/path')
def testGetAsStringWhenVector(self):
parameter = ParameterMultipleInput('myName', 'myDesc', datatype=dataobjects.TYPE_VECTOR_ANY)
# With Path
self.assertEqual(parameter.getAsString('/some/path'), '/some/path')
# With Layer
layer = QgsVectorLayer('/path/to/myVector.shp', 'myVector', 'memory')
self.assertEqual(parameter.getAsString(layer), '/path/to/myVector.shp')
# TODO With Layer Name, instead of Layer object
if __name__ == '__main__':
unittest.main()

View File

@ -6,7 +6,7 @@
##INPUT_LAYER=source
##OUTPUT_LAYER=sink point
from qgis.core import QgsWkbTypes, QgsProcessingUtils
from qgis.core import QgsWkbTypes, QgsProcessingUtils, QgsProcessingException
fields = INPUT_LAYER.fields()
@ -16,7 +16,7 @@ fields = INPUT_LAYER.fields()
features = INPUT_LAYER.getFeatures()
count = INPUT_LAYER.featureCount()
if count == 0:
raise GeoAlgorithmExecutionException('Input layer contains no features.')
raise QgsProcessingException('Input layer contains no features.')
total = 100.0 / count

View File

@ -183,113 +183,6 @@ def load(fileName, name=None, crs=None, style=None, isRaster=False):
return qgslayer
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 exportRasterLayer(layer):
"""Takes a QgsRasterLayer 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.
Currently, the output is restricted to geotiff, but not all other
formats are exported. Only those formats not supported by GDAL are
exported, so it is assumed that the external app uses GDAL to read
the layer.
"""
# TODO: Do the conversion here
return str(layer.source())
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 = QgsSettings()
systemEncoding = settings.value('/UI/encoding', 'System')
output = getTempFilename()
isASCII = True
try:
str(table.source()).decode('ascii')
except UnicodeEncodeError:
isASCII = False
isDbf = str(table.source()).endswith('dbf') \
or str(table.source()).endswith('shp')
if not isDbf or not isASCII:
writer = QgsVectorFileWriter(output, systemEncoding,
table.fields(), QgsWkbTypes.NullGeometry,
QgsCoordinateReferenceSystem('4326'))
for feat in table.getFeatures():
writer.addFeature(feat, QgsFeatureSink.FastInsert)
del writer
return output + '.dbf'
else:
filename = str(table.source())
if str(table.source()).endswith('shp'):
return filename[:-3] + 'dbf'
else:
return filename
def getRasterSublayer(path, param):
layer = QgsRasterLayer(path)
@ -342,18 +235,3 @@ def getRasterSublayer(path, param):
except:
# If the layer is not a raster layer, then just return the input path
return path
def vectorDataType(obj):
types = ''
for t in obj.datatype:
if t == dataobjects.TYPE_VECTOR_POINT:
types += 'point, '
elif t == dataobjects.TYPE_VECTOR_LINE:
types += 'line, '
elif t == dataobjects.TYPE_VECTOR_POLYGON:
types += 'polygon, '
else:
types += 'any, '
return types[:-2]

View File

@ -26,10 +26,7 @@ __copyright__ = '(C) 2013, Victor Olaya'
__revision__ = '$Format:%H$'
import os
try:
import configparser
except ImportError:
import configparser as configparser
import configparser
from qgis.core import (QgsApplication,
QgsProcessingAlgorithm,
@ -40,7 +37,6 @@ from qgis.core import (QgsApplication,
QgsProcessingOutputLayerDefinition,
QgsProject)
from processing.core.Processing import Processing
from processing.core.parameters import ParameterSelection
from processing.gui.Postprocessing import handleAlgorithmResults

View File

@ -107,38 +107,3 @@ def checkMinDistance(point, index, distance, points):
return False
return True
NOGEOMETRY_EXTENSIONS = [
u'csv',
u'dbf',
u'ods',
u'xlsx',
]
class TableWriter(object):
def __init__(self, fileName, encoding, fields):
self.fileName = fileName
if not self.fileName.lower().endswith('csv'):
self.fileName += '.csv'
self.encoding = encoding
if self.encoding is None or encoding == 'System':
self.encoding = 'utf-8'
with open(self.fileName, 'w', newline='', encoding=self.encoding) as f:
self.writer = csv.writer(f)
if len(fields) != 0:
self.writer.writerow(fields)
def addRecord(self, values):
with open(self.fileName, 'a', newline='', encoding=self.encoding) as f:
self.writer = csv.writer(f)
self.writer.writerow(values)
def addRecords(self, records):
with open(self.fileName, 'a', newline='', encoding=self.encoding) as f:
self.writer = csv.writer(f)
self.writer.writerows(records)