From 3d4a59bb8bc4130ca9a78a9aea2be2cebf21d000 Mon Sep 17 00:00:00 2001 From: Alexander Bruy Date: Mon, 27 Nov 2017 16:03:14 +0200 Subject: [PATCH] [processing] cleanup files from unused code and remove some files --- .../plugins/processing/algs/gdal/gdalcalc.py | 7 +- .../algs/gdal/ogr2ogrtabletopostgislist.py | 6 - .../algs/gdal/ogr2ogrtopostgislist.py | 9 - .../plugins/processing/algs/gdal/rasterize.py | 8 - .../processing/algs/gdal/rasterize_over.py | 4 - .../algs/grass7/Grass7AlgorithmProvider.py | 2 - .../plugins/processing/algs/grass7/nviz7.py | 196 ------- python/plugins/processing/algs/qgis/Aspect.py | 3 +- .../plugins/processing/algs/qgis/Hillshade.py | 3 +- .../processing/algs/qgis/HypsometricCurves.py | 3 +- .../processing/algs/qgis/PointsFromLines.py | 3 +- .../algs/qgis/PointsFromPolygons.py | 3 +- python/plugins/processing/algs/qgis/Relief.py | 3 +- .../processing/algs/qgis/Ruggedness.py | 3 +- python/plugins/processing/algs/qgis/Slope.py | 4 +- .../algs/qgis/ui/RasterCalculatorWidgets.py | 33 +- .../plugins/processing/core/GeoAlgorithm.py | 340 ----------- python/plugins/processing/core/Processing.py | 1 - python/plugins/processing/core/outputs.py | 343 ----------- python/plugins/processing/core/parameters.py | 539 +----------------- .../plugins/processing/gui/AlgorithmDialog.py | 5 - python/plugins/processing/gui/BatchPanel.py | 12 +- python/plugins/processing/gui/wrappers.py | 23 +- .../modeler/ModelerParametersDialog.py | 2 +- .../processing/script/ScriptAlgorithm.py | 1 - .../plugins/processing/tests/CMakeLists.txt | 1 - .../processing/tests/ParametersTest.py | 124 ---- .../tests/testdata/scripts/centroids.py | 4 +- .../plugins/processing/tools/dataobjects.py | 122 ---- python/plugins/processing/tools/general.py | 6 +- python/plugins/processing/tools/vector.py | 35 -- 31 files changed, 42 insertions(+), 1806 deletions(-) delete mode 100644 python/plugins/processing/algs/grass7/nviz7.py delete mode 100644 python/plugins/processing/core/GeoAlgorithm.py delete mode 100644 python/plugins/processing/tests/ParametersTest.py diff --git a/python/plugins/processing/algs/gdal/gdalcalc.py b/python/plugins/processing/algs/gdal/gdalcalc.py index cdbd8be2e33..55814fb78a0 100644 --- a/python/plugins/processing/algs/gdal/gdalcalc.py +++ b/python/plugins/processing/algs/gdal/gdalcalc.py @@ -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): diff --git a/python/plugins/processing/algs/gdal/ogr2ogrtabletopostgislist.py b/python/plugins/processing/algs/gdal/ogr2ogrtabletopostgislist.py index 33350ddcefe..54ff8c59461 100644 --- a/python/plugins/processing/algs/gdal/ogr2ogrtabletopostgislist.py +++ b/python/plugins/processing/algs/gdal/ogr2ogrtabletopostgislist.py @@ -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 diff --git a/python/plugins/processing/algs/gdal/ogr2ogrtopostgislist.py b/python/plugins/processing/algs/gdal/ogr2ogrtopostgislist.py index 5c53ab7275e..75c2524f729 100644 --- a/python/plugins/processing/algs/gdal/ogr2ogrtopostgislist.py +++ b/python/plugins/processing/algs/gdal/ogr2ogrtopostgislist.py @@ -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 diff --git a/python/plugins/processing/algs/gdal/rasterize.py b/python/plugins/processing/algs/gdal/rasterize.py index 3a1a3381c13..18c4d4cce2a 100644 --- a/python/plugins/processing/algs/gdal/rasterize.py +++ b/python/plugins/processing/algs/gdal/rasterize.py @@ -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 diff --git a/python/plugins/processing/algs/gdal/rasterize_over.py b/python/plugins/processing/algs/gdal/rasterize_over.py index f671004b8c9..63698a8a081 100644 --- a/python/plugins/processing/algs/gdal/rasterize_over.py +++ b/python/plugins/processing/algs/gdal/rasterize_over.py @@ -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 diff --git a/python/plugins/processing/algs/grass7/Grass7AlgorithmProvider.py b/python/plugins/processing/algs/grass7/Grass7AlgorithmProvider.py index e5c94ac8433..335288ecc4a 100644 --- a/python/plugins/processing/algs/grass7/Grass7AlgorithmProvider.py +++ b/python/plugins/processing/algs/grass7/Grass7AlgorithmProvider.py @@ -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): diff --git a/python/plugins/processing/algs/grass7/nviz7.py b/python/plugins/processing/algs/grass7/nviz7.py deleted file mode 100644 index ef35f406289..00000000000 --- a/python/plugins/processing/algs/grass7/nviz7.py +++ /dev/null @@ -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 diff --git a/python/plugins/processing/algs/qgis/Aspect.py b/python/plugins/processing/algs/qgis/Aspect.py index 613c4e09c9b..70c08b4ffc3 100644 --- a/python/plugins/processing/algs/qgis/Aspect.py +++ b/python/plugins/processing/algs/qgis/Aspect.py @@ -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) diff --git a/python/plugins/processing/algs/qgis/Hillshade.py b/python/plugins/processing/algs/qgis/Hillshade.py index 52b6d3153be..7875408696d 100644 --- a/python/plugins/processing/algs/qgis/Hillshade.py +++ b/python/plugins/processing/algs/qgis/Hillshade.py @@ -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) diff --git a/python/plugins/processing/algs/qgis/HypsometricCurves.py b/python/plugins/processing/algs/qgis/HypsometricCurves.py index 6f429b04ff5..69de9d49415 100644 --- a/python/plugins/processing/algs/qgis/HypsometricCurves.py +++ b/python/plugins/processing/algs/qgis/HypsometricCurves.py @@ -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) diff --git a/python/plugins/processing/algs/qgis/PointsFromLines.py b/python/plugins/processing/algs/qgis/PointsFromLines.py index e76a5e1f5c0..b2c855529df 100644 --- a/python/plugins/processing/algs/qgis/PointsFromLines.py +++ b/python/plugins/processing/algs/qgis/PointsFromLines.py @@ -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() diff --git a/python/plugins/processing/algs/qgis/PointsFromPolygons.py b/python/plugins/processing/algs/qgis/PointsFromPolygons.py index 9496559c09d..2983c77af4e 100644 --- a/python/plugins/processing/algs/qgis/PointsFromPolygons.py +++ b/python/plugins/processing/algs/qgis/PointsFromPolygons.py @@ -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() diff --git a/python/plugins/processing/algs/qgis/Relief.py b/python/plugins/processing/algs/qgis/Relief.py index bdf48f42388..6140ddba8be 100644 --- a/python/plugins/processing/algs/qgis/Relief.py +++ b/python/plugins/processing/algs/qgis/Relief.py @@ -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) diff --git a/python/plugins/processing/algs/qgis/Ruggedness.py b/python/plugins/processing/algs/qgis/Ruggedness.py index 5351d3b6bc2..d179a526230 100644 --- a/python/plugins/processing/algs/qgis/Ruggedness.py +++ b/python/plugins/processing/algs/qgis/Ruggedness.py @@ -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) diff --git a/python/plugins/processing/algs/qgis/Slope.py b/python/plugins/processing/algs/qgis/Slope.py index 6606d219f2c..b7d765dabc3 100644 --- a/python/plugins/processing/algs/qgis/Slope.py +++ b/python/plugins/processing/algs/qgis/Slope.py @@ -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) diff --git a/python/plugins/processing/algs/qgis/ui/RasterCalculatorWidgets.py b/python/plugins/processing/algs/qgis/ui/RasterCalculatorWidgets.py index 0d8d0e64151..8d96c5c237d 100644 --- a/python/plugins/processing/algs/qgis/ui/RasterCalculatorWidgets.py +++ b/python/plugins/processing/algs/qgis/ui/RasterCalculatorWidgets.py @@ -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) diff --git a/python/plugins/processing/core/GeoAlgorithm.py b/python/plugins/processing/core/GeoAlgorithm.py deleted file mode 100644 index e5c2bc746a4..00000000000 --- a/python/plugins/processing/core/GeoAlgorithm.py +++ /dev/null @@ -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) diff --git a/python/plugins/processing/core/Processing.py b/python/plugins/processing/core/Processing.py index 3190fa12625..25afe6d7b17 100644 --- a/python/plugins/processing/core/Processing.py +++ b/python/plugins/processing/core/Processing.py @@ -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 diff --git a/python/plugins/processing/core/outputs.py b/python/plugins/processing/core/outputs.py index d2de220731d..29e8e587e8b 100644 --- a/python/plugins/processing/core/outputs.py +++ b/python/plugins/processing/core/outputs.py @@ -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"): diff --git a/python/plugins/processing/core/parameters.py b/python/plugins/processing/core/parameters.py index ac316f655d0..55da7c82c06 100644 --- a/python/plugins/processing/core/parameters.py +++ b/python/plugins/processing/core/parameters.py @@ -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 diff --git a/python/plugins/processing/gui/AlgorithmDialog.py b/python/plugins/processing/gui/AlgorithmDialog.py index a0342a351aa..be22387569f 100644 --- a/python/plugins/processing/gui/AlgorithmDialog.py +++ b/python/plugins/processing/gui/AlgorithmDialog.py @@ -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 diff --git a/python/plugins/processing/gui/BatchPanel.py b/python/plugins/processing/gui/BatchPanel.py index 5cd469a85bb..98e5a1475c2 100644 --- a/python/plugins/processing/gui/BatchPanel.py +++ b/python/plugins/processing/gui/BatchPanel.py @@ -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] diff --git a/python/plugins/processing/gui/wrappers.py b/python/plugins/processing/gui/wrappers.py index 2eb47277413..e3aa8b07129 100755 --- a/python/plugins/processing/gui/wrappers.py +++ b/python/plugins/processing/gui/wrappers.py @@ -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' diff --git a/python/plugins/processing/modeler/ModelerParametersDialog.py b/python/plugins/processing/modeler/ModelerParametersDialog.py index 205214634b2..0195c7b8ffe 100755 --- a/python/plugins/processing/modeler/ModelerParametersDialog.py +++ b/python/plugins/processing/modeler/ModelerParametersDialog.py @@ -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 diff --git a/python/plugins/processing/script/ScriptAlgorithm.py b/python/plugins/processing/script/ScriptAlgorithm.py index 195974679f5..d184d92c60e 100644 --- a/python/plugins/processing/script/ScriptAlgorithm.py +++ b/python/plugins/processing/script/ScriptAlgorithm.py @@ -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 diff --git a/python/plugins/processing/tests/CMakeLists.txt b/python/plugins/processing/tests/CMakeLists.txt index 3340ae9da73..54f091ed541 100644 --- a/python/plugins/processing/tests/CMakeLists.txt +++ b/python/plugins/processing/tests/CMakeLists.txt @@ -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) diff --git a/python/plugins/processing/tests/ParametersTest.py b/python/plugins/processing/tests/ParametersTest.py deleted file mode 100644 index 06bdbadc98d..00000000000 --- a/python/plugins/processing/tests/ParametersTest.py +++ /dev/null @@ -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() diff --git a/python/plugins/processing/tests/testdata/scripts/centroids.py b/python/plugins/processing/tests/testdata/scripts/centroids.py index d4b102f761f..0548e8fb0b7 100644 --- a/python/plugins/processing/tests/testdata/scripts/centroids.py +++ b/python/plugins/processing/tests/testdata/scripts/centroids.py @@ -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 diff --git a/python/plugins/processing/tools/dataobjects.py b/python/plugins/processing/tools/dataobjects.py index 977690c7f03..6c0fe427379 100644 --- a/python/plugins/processing/tools/dataobjects.py +++ b/python/plugins/processing/tools/dataobjects.py @@ -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] diff --git a/python/plugins/processing/tools/general.py b/python/plugins/processing/tools/general.py index 1ffa7cf60a6..7ff4388b9b4 100644 --- a/python/plugins/processing/tools/general.py +++ b/python/plugins/processing/tools/general.py @@ -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 diff --git a/python/plugins/processing/tools/vector.py b/python/plugins/processing/tools/vector.py index aeb00cd6d2f..e4ea970181a 100755 --- a/python/plugins/processing/tools/vector.py +++ b/python/plugins/processing/tools/vector.py @@ -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)