mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-18 00:03:05 -04:00
[processing] cleanup files from unused code and remove some files
This commit is contained in:
parent
ee8435a789
commit
3d4a59bb8b
@ -26,15 +26,10 @@ __copyright__ = '(C) 2015, Giovanni Manghi'
|
|||||||
__revision__ = '$Format:%H$'
|
__revision__ = '$Format:%H$'
|
||||||
|
|
||||||
from processing.algs.gdal.GdalAlgorithm import GdalAlgorithm
|
from processing.algs.gdal.GdalAlgorithm import GdalAlgorithm
|
||||||
from processing.core.parameters import ParameterString
|
from processing.algs.gdal.GdalUtils import GdalUtils
|
||||||
from processing.core.parameters import ParameterRaster
|
|
||||||
from processing.core.parameters import ParameterSelection
|
|
||||||
from processing.core.outputs import OutputRaster
|
|
||||||
|
|
||||||
from processing.tools.system import isWindows
|
from processing.tools.system import isWindows
|
||||||
|
|
||||||
from processing.algs.gdal.GdalUtils import GdalUtils
|
|
||||||
|
|
||||||
|
|
||||||
class gdalcalc(GdalAlgorithm):
|
class gdalcalc(GdalAlgorithm):
|
||||||
|
|
||||||
|
@ -27,12 +27,6 @@ __revision__ = '$Format:%H$'
|
|||||||
|
|
||||||
from qgis.core import QgsSettings
|
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.GdalAlgorithm import GdalAlgorithm
|
||||||
from processing.algs.gdal.GdalUtils import GdalUtils
|
from processing.algs.gdal.GdalUtils import GdalUtils
|
||||||
|
|
||||||
|
@ -25,15 +25,6 @@ __copyright__ = '(C) 2012, Victor Olaya'
|
|||||||
|
|
||||||
__revision__ = '$Format:%H$'
|
__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.GdalAlgorithm import GdalAlgorithm
|
||||||
from processing.algs.gdal.GdalUtils import GdalUtils
|
from processing.algs.gdal.GdalUtils import GdalUtils
|
||||||
|
|
||||||
|
@ -30,14 +30,6 @@ import os
|
|||||||
|
|
||||||
from qgis.PyQt.QtGui import QIcon
|
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.GdalAlgorithm import GdalAlgorithm
|
||||||
from processing.algs.gdal.GdalUtils import GdalUtils
|
from processing.algs.gdal.GdalUtils import GdalUtils
|
||||||
|
|
||||||
|
@ -31,10 +31,6 @@ from qgis.core import QgsProcessingUtils
|
|||||||
|
|
||||||
from qgis.PyQt.QtGui import QIcon
|
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.GdalAlgorithm import GdalAlgorithm
|
||||||
from processing.algs.gdal.GdalUtils import GdalUtils
|
from processing.algs.gdal.GdalUtils import GdalUtils
|
||||||
|
|
||||||
|
@ -36,7 +36,6 @@ from processing.core.ProcessingConfig import (ProcessingConfig, Setting)
|
|||||||
from .Grass7Utils import Grass7Utils
|
from .Grass7Utils import Grass7Utils
|
||||||
from .Grass7Algorithm import Grass7Algorithm
|
from .Grass7Algorithm import Grass7Algorithm
|
||||||
from processing.tools.system import isWindows, isMac
|
from processing.tools.system import isWindows, isMac
|
||||||
#from .nviz7 import nviz7
|
|
||||||
|
|
||||||
pluginPath = os.path.normpath(os.path.join(
|
pluginPath = os.path.normpath(os.path.join(
|
||||||
os.path.split(os.path.dirname(__file__))[0], os.pardir))
|
os.path.split(os.path.dirname(__file__))[0], os.pardir))
|
||||||
@ -109,7 +108,6 @@ class Grass7AlgorithmProvider(QgsProcessingProvider):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
QgsMessageLog.logMessage(
|
QgsMessageLog.logMessage(
|
||||||
self.tr('Could not open GRASS GIS 7 algorithm: {0}\n{1}').format(descriptionFile, str(e)), self.tr('Processing'), QgsMessageLog.CRITICAL)
|
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
|
return algs
|
||||||
|
|
||||||
def loadAlgorithms(self):
|
def loadAlgorithms(self):
|
||||||
|
@ -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
|
|
@ -35,7 +35,6 @@ from qgis.core import (QgsRasterFileWriter,
|
|||||||
QgsProcessingParameterNumber,
|
QgsProcessingParameterNumber,
|
||||||
QgsProcessingParameterRasterDestination)
|
QgsProcessingParameterRasterDestination)
|
||||||
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
|
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]
|
pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
|
||||||
|
|
||||||
@ -70,7 +69,7 @@ class Aspect(QgisAlgorithm):
|
|||||||
return self.tr('Aspect')
|
return self.tr('Aspect')
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
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)
|
zFactor = self.parameterAsDouble(parameters, self.Z_FACTOR, context)
|
||||||
|
|
||||||
outputFile = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)
|
outputFile = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)
|
||||||
|
@ -35,7 +35,6 @@ from qgis.core import (QgsRasterFileWriter,
|
|||||||
QgsProcessingParameterNumber,
|
QgsProcessingParameterNumber,
|
||||||
QgsProcessingParameterRasterDestination)
|
QgsProcessingParameterRasterDestination)
|
||||||
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
|
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]
|
pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
|
||||||
|
|
||||||
@ -78,7 +77,7 @@ class Hillshade(QgisAlgorithm):
|
|||||||
return self.tr('Hillshade')
|
return self.tr('Hillshade')
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
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)
|
zFactor = self.parameterAsDouble(parameters, self.Z_FACTOR, context)
|
||||||
azimuth = self.parameterAsDouble(parameters, self.AZIMUTH, context)
|
azimuth = self.parameterAsDouble(parameters, self.AZIMUTH, context)
|
||||||
vAngle = self.parameterAsDouble(parameters, self.V_ANGLE, context)
|
vAngle = self.parameterAsDouble(parameters, self.V_ANGLE, context)
|
||||||
|
@ -43,7 +43,6 @@ from qgis.core import (QgsRectangle,
|
|||||||
|
|
||||||
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
|
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
|
||||||
from processing.tools import raster
|
from processing.tools import raster
|
||||||
from processing.tools.dataobjects import exportRasterLayer
|
|
||||||
|
|
||||||
|
|
||||||
class HypsometricCurves(QgisAlgorithm):
|
class HypsometricCurves(QgisAlgorithm):
|
||||||
@ -82,7 +81,7 @@ class HypsometricCurves(QgisAlgorithm):
|
|||||||
def processAlgorithm(self, parameters, context, feedback):
|
def processAlgorithm(self, parameters, context, feedback):
|
||||||
raster_layer = self.parameterAsRasterLayer(parameters, self.INPUT_DEM, context)
|
raster_layer = self.parameterAsRasterLayer(parameters, self.INPUT_DEM, context)
|
||||||
target_crs = raster_layer.crs()
|
target_crs = raster_layer.crs()
|
||||||
rasterPath = exportRasterLayer(raster_layer)
|
rasterPath = raster_layer.source()
|
||||||
|
|
||||||
source = self.parameterAsSource(parameters, self.BOUNDARY_LAYER, context)
|
source = self.parameterAsSource(parameters, self.BOUNDARY_LAYER, context)
|
||||||
step = self.parameterAsDouble(parameters, self.STEP, context)
|
step = self.parameterAsDouble(parameters, self.STEP, context)
|
||||||
|
@ -41,7 +41,6 @@ from qgis.core import (QgsFeature,
|
|||||||
QgsProcessingParameterFeatureSink)
|
QgsProcessingParameterFeatureSink)
|
||||||
from processing.tools import raster
|
from processing.tools import raster
|
||||||
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
|
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
|
||||||
from processing.tools.dataobjects import exportRasterLayer
|
|
||||||
|
|
||||||
|
|
||||||
class PointsFromLines(QgisAlgorithm):
|
class PointsFromLines(QgisAlgorithm):
|
||||||
@ -74,7 +73,7 @@ class PointsFromLines(QgisAlgorithm):
|
|||||||
source = self.parameterAsSource(parameters, self.INPUT_VECTOR, context)
|
source = self.parameterAsSource(parameters, self.INPUT_VECTOR, context)
|
||||||
|
|
||||||
raster_layer = self.parameterAsRasterLayer(parameters, self.INPUT_RASTER, 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)
|
rasterDS = gdal.Open(rasterPath, gdal.GA_ReadOnly)
|
||||||
geoTransform = rasterDS.GetGeoTransform()
|
geoTransform = rasterDS.GetGeoTransform()
|
||||||
|
@ -42,7 +42,6 @@ from qgis.core import (QgsFeatureRequest,
|
|||||||
from qgis.PyQt.QtCore import QVariant
|
from qgis.PyQt.QtCore import QVariant
|
||||||
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
|
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
|
||||||
from processing.tools import raster
|
from processing.tools import raster
|
||||||
from processing.tools.dataobjects import exportRasterLayer
|
|
||||||
|
|
||||||
|
|
||||||
class PointsFromPolygons(QgisAlgorithm):
|
class PointsFromPolygons(QgisAlgorithm):
|
||||||
@ -74,7 +73,7 @@ class PointsFromPolygons(QgisAlgorithm):
|
|||||||
source = self.parameterAsSource(parameters, self.INPUT_VECTOR, context)
|
source = self.parameterAsSource(parameters, self.INPUT_VECTOR, context)
|
||||||
|
|
||||||
raster_layer = self.parameterAsRasterLayer(parameters, self.INPUT_RASTER, 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)
|
rasterDS = gdal.Open(rasterPath, gdal.GA_ReadOnly)
|
||||||
geoTransform = rasterDS.GetGeoTransform()
|
geoTransform = rasterDS.GetGeoTransform()
|
||||||
|
@ -39,7 +39,6 @@ from qgis.core import (QgsProcessingParameterDefinition,
|
|||||||
QgsRasterFileWriter,
|
QgsRasterFileWriter,
|
||||||
QgsProcessingException)
|
QgsProcessingException)
|
||||||
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
|
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]
|
pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
|
||||||
|
|
||||||
@ -126,7 +125,7 @@ class Relief(QgisAlgorithm):
|
|||||||
return self.tr('Relief')
|
return self.tr('Relief')
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
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)
|
zFactor = self.parameterAsDouble(parameters, self.Z_FACTOR, context)
|
||||||
automaticColors = self.parameterAsBool(parameters, self.AUTO_COLORS, context)
|
automaticColors = self.parameterAsBool(parameters, self.AUTO_COLORS, context)
|
||||||
outputFile = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)
|
outputFile = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)
|
||||||
|
@ -35,7 +35,6 @@ from qgis.core import (QgsRasterFileWriter,
|
|||||||
QgsProcessingParameterNumber,
|
QgsProcessingParameterNumber,
|
||||||
QgsProcessingParameterRasterDestination)
|
QgsProcessingParameterRasterDestination)
|
||||||
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
|
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]
|
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')
|
return self.tr('Ruggedness index')
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
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)
|
zFactor = self.parameterAsDouble(parameters, self.Z_FACTOR, context)
|
||||||
|
|
||||||
outputFile = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)
|
outputFile = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)
|
||||||
|
@ -35,8 +35,6 @@ from qgis.core import (QgsRasterFileWriter,
|
|||||||
QgsProcessingParameterNumber,
|
QgsProcessingParameterNumber,
|
||||||
QgsProcessingParameterRasterDestination)
|
QgsProcessingParameterRasterDestination)
|
||||||
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
|
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]
|
pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
|
||||||
|
|
||||||
@ -71,7 +69,7 @@ class Slope(QgisAlgorithm):
|
|||||||
return self.tr('Slope')
|
return self.tr('Slope')
|
||||||
|
|
||||||
def processAlgorithm(self, parameters, context, feedback):
|
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)
|
zFactor = self.parameterAsDouble(parameters, self.Z_FACTOR, context)
|
||||||
|
|
||||||
outputFile = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)
|
outputFile = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)
|
||||||
|
@ -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
|
import os
|
||||||
from qgis.PyQt import uic
|
|
||||||
from functools import partial
|
from functools import partial
|
||||||
import re
|
import re
|
||||||
import json
|
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__)
|
pluginPath = os.path.dirname(__file__)
|
||||||
WIDGET_ADD_NEW, BASE_ADD_NEW = uic.loadUiType(
|
WIDGET_ADD_NEW, BASE_ADD_NEW = uic.loadUiType(
|
||||||
os.path.join(pluginPath, 'AddNewExpressionDialog.ui'))
|
os.path.join(pluginPath, 'AddNewExpressionDialog.ui'))
|
||||||
@ -183,7 +186,7 @@ class ExpressionWidgetWrapper(WidgetWrapper):
|
|||||||
elif self.dialogType == DIALOG_BATCH:
|
elif self.dialogType == DIALOG_BATCH:
|
||||||
return QLineEdit()
|
return QLineEdit()
|
||||||
else:
|
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}
|
options = {self.dialog.resolveValueDescription(lyr): "{}@1".format(lyr) for lyr in layers}
|
||||||
return self._panel(options)
|
return self._panel(options)
|
||||||
|
|
||||||
|
@ -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)
|
|
@ -47,7 +47,6 @@ from qgis.core import (QgsMessageLog,
|
|||||||
import processing
|
import processing
|
||||||
from processing.script.ScriptUtils import ScriptUtils
|
from processing.script.ScriptUtils import ScriptUtils
|
||||||
from processing.core.ProcessingConfig import ProcessingConfig
|
from processing.core.ProcessingConfig import ProcessingConfig
|
||||||
from processing.core.GeoAlgorithm import GeoAlgorithm
|
|
||||||
from processing.gui.MessageBarProgress import MessageBarProgress
|
from processing.gui.MessageBarProgress import MessageBarProgress
|
||||||
from processing.gui.RenderingStyles import RenderingStyles
|
from processing.gui.RenderingStyles import RenderingStyles
|
||||||
from processing.gui.Postprocessing import handleAlgorithmResults
|
from processing.gui.Postprocessing import handleAlgorithmResults
|
||||||
|
@ -25,16 +25,8 @@ __copyright__ = '(C) 2012, Victor Olaya'
|
|||||||
|
|
||||||
__revision__ = '$Format:%H$'
|
__revision__ = '$Format:%H$'
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
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,
|
from qgis.core import (QgsExpressionContext,
|
||||||
QgsExpressionContextUtils,
|
QgsExpressionContextUtils,
|
||||||
QgsExpression,
|
QgsExpression,
|
||||||
@ -53,341 +45,6 @@ from qgis.core import (QgsExpressionContext,
|
|||||||
QgsProcessingOutputFolder)
|
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):
|
def getOutputFromString(s):
|
||||||
try:
|
try:
|
||||||
if "|" in s and s.startswith("Output"):
|
if "|" in s and s.startswith("Output"):
|
||||||
|
@ -26,21 +26,17 @@ __copyright__ = '(C) 2012, Victor Olaya'
|
|||||||
__revision__ = '$Format:%H$'
|
__revision__ = '$Format:%H$'
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
|
||||||
import math
|
|
||||||
from inspect import isclass
|
|
||||||
from copy import deepcopy
|
|
||||||
import numbers
|
|
||||||
|
|
||||||
from qgis.core import QgsProcessingUtils
|
from qgis.core import (QgsRasterLayer,
|
||||||
|
QgsVectorLayer,
|
||||||
from qgis.PyQt.QtCore import QCoreApplication
|
QgsMapLayer,
|
||||||
from qgis.core import (QgsRasterLayer, QgsVectorLayer, QgsMapLayer, QgsCoordinateReferenceSystem,
|
QgsCoordinateReferenceSystem,
|
||||||
QgsExpression,
|
QgsExpression,
|
||||||
QgsProject,
|
QgsProject,
|
||||||
QgsRectangle,
|
QgsRectangle,
|
||||||
QgsVectorFileWriter,
|
QgsVectorFileWriter,
|
||||||
QgsProcessing,
|
QgsProcessing,
|
||||||
|
QgsProcessingUtils,
|
||||||
QgsProcessingParameters,
|
QgsProcessingParameters,
|
||||||
QgsProcessingParameterDefinition,
|
QgsProcessingParameterDefinition,
|
||||||
QgsProcessingParameterRasterLayer,
|
QgsProcessingParameterRasterLayer,
|
||||||
@ -63,522 +59,6 @@ from qgis.core import (QgsRasterLayer, QgsVectorLayer, QgsMapLayer, QgsCoordinat
|
|||||||
QgsProcessingParameterFeatureSource,
|
QgsProcessingParameterFeatureSource,
|
||||||
QgsProcessingParameterNumber)
|
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):
|
def getParameterFromString(s):
|
||||||
# Try the parameter definitions used in description files
|
# Try the parameter definitions used in description files
|
||||||
@ -715,12 +195,3 @@ def getParameterFromString(s):
|
|||||||
param = QgsProcessingParameters.parameterFromScriptCode(s)
|
param = QgsProcessingParameters.parameterFromScriptCode(s)
|
||||||
if param:
|
if param:
|
||||||
return 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
|
|
||||||
|
@ -55,11 +55,6 @@ from processing.gui.AlgorithmDialogBase import AlgorithmDialogBase
|
|||||||
from processing.gui.AlgorithmExecutor import executeIterating
|
from processing.gui.AlgorithmExecutor import executeIterating
|
||||||
from processing.gui.Postprocessing import handleAlgorithmResults
|
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
|
from processing.tools import dataobjects
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,20 +35,10 @@ from qgis.core import (QgsApplication,
|
|||||||
QgsSettings,
|
QgsSettings,
|
||||||
QgsProcessingParameterDefinition)
|
QgsProcessingParameterDefinition)
|
||||||
from qgis.gui import QgsMessageBar
|
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.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
|
from processing.tools import dataobjects
|
||||||
|
|
||||||
pluginPath = os.path.split(os.path.dirname(__file__))[0]
|
pluginPath = os.path.split(os.path.dirname(__file__))[0]
|
||||||
|
@ -97,28 +97,13 @@ from qgis.gui import (
|
|||||||
from qgis.PyQt.QtCore import pyqtSignal, QObject, QVariant, Qt
|
from qgis.PyQt.QtCore import pyqtSignal, QObject, QVariant, Qt
|
||||||
from qgis.utils import iface
|
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.NumberInputPanel import NumberInputPanel, ModellerNumberInputPanel
|
||||||
from processing.gui.RangePanel import RangePanel
|
from processing.gui.RangePanel import RangePanel
|
||||||
from processing.modeler.MultilineTextPanel import MultilineTextPanel
|
|
||||||
from processing.gui.PointSelectionPanel import PointSelectionPanel
|
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.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.CheckboxesPanel import CheckboxesPanel
|
||||||
from processing.gui.MultipleInputPanel import MultipleInputPanel
|
from processing.gui.MultipleInputPanel import MultipleInputPanel
|
||||||
from processing.gui.BatchInputSelectionPanel import BatchInputSelectionPanel
|
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.ExtentSelectionPanel import ExtentSelectionPanel
|
||||||
from processing.gui.ParameterGuiUtils import getFileFilter
|
from processing.gui.ParameterGuiUtils import getFileFilter
|
||||||
|
|
||||||
|
from processing.tools import dataobjects
|
||||||
|
|
||||||
DIALOG_STANDARD = 'standard'
|
DIALOG_STANDARD = 'standard'
|
||||||
DIALOG_BATCH = 'batch'
|
DIALOG_BATCH = 'batch'
|
||||||
DIALOG_MODELER = 'modeler'
|
DIALOG_MODELER = 'modeler'
|
||||||
|
@ -68,7 +68,7 @@ class ModelerParametersDialog(QDialog):
|
|||||||
def __init__(self, alg, model, algName=None):
|
def __init__(self, alg, model, algName=None):
|
||||||
QDialog.__init__(self)
|
QDialog.__init__(self)
|
||||||
self.setModal(True)
|
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
|
self._alg = alg
|
||||||
# The model this algorithm is going to be added to
|
# The model this algorithm is going to be added to
|
||||||
self.model = model
|
self.model = model
|
||||||
|
@ -39,7 +39,6 @@ from qgis.core import (QgsExpressionContextUtils,
|
|||||||
|
|
||||||
from qgis.PyQt.QtCore import (QCoreApplication)
|
from qgis.PyQt.QtCore import (QCoreApplication)
|
||||||
|
|
||||||
from processing.core.GeoAlgorithm import GeoAlgorithm
|
|
||||||
from processing.gui.Help2Html import getHtmlFromHelpFile
|
from processing.gui.Help2Html import getHtmlFromHelpFile
|
||||||
from processing.core.parameters import getParameterFromString
|
from processing.core.parameters import getParameterFromString
|
||||||
from processing.core.outputs import getOutputFromString
|
from processing.core.outputs import getOutputFromString
|
||||||
|
@ -7,7 +7,6 @@ PLUGIN_INSTALL(processing tests/testdata ${TEST_DATA_FILES})
|
|||||||
IF(ENABLE_TESTS)
|
IF(ENABLE_TESTS)
|
||||||
INCLUDE(UsePythonTest)
|
INCLUDE(UsePythonTest)
|
||||||
ADD_PYTHON_TEST(ProcessingGuiTest GuiTest.py)
|
ADD_PYTHON_TEST(ProcessingGuiTest GuiTest.py)
|
||||||
ADD_PYTHON_TEST(ProcessingParametersTest ParametersTest.py)
|
|
||||||
ADD_PYTHON_TEST(ProcessingModelerTest ModelerTest.py)
|
ADD_PYTHON_TEST(ProcessingModelerTest ModelerTest.py)
|
||||||
ADD_PYTHON_TEST(ProcessingToolsTest ToolsTest.py)
|
ADD_PYTHON_TEST(ProcessingToolsTest ToolsTest.py)
|
||||||
ADD_PYTHON_TEST(ProcessingQgisAlgorithmsTest QgisAlgorithmsTest.py)
|
ADD_PYTHON_TEST(ProcessingQgisAlgorithmsTest QgisAlgorithmsTest.py)
|
||||||
|
@ -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()
|
|
@ -6,7 +6,7 @@
|
|||||||
##INPUT_LAYER=source
|
##INPUT_LAYER=source
|
||||||
##OUTPUT_LAYER=sink point
|
##OUTPUT_LAYER=sink point
|
||||||
|
|
||||||
from qgis.core import QgsWkbTypes, QgsProcessingUtils
|
from qgis.core import QgsWkbTypes, QgsProcessingUtils, QgsProcessingException
|
||||||
|
|
||||||
fields = INPUT_LAYER.fields()
|
fields = INPUT_LAYER.fields()
|
||||||
|
|
||||||
@ -16,7 +16,7 @@ fields = INPUT_LAYER.fields()
|
|||||||
features = INPUT_LAYER.getFeatures()
|
features = INPUT_LAYER.getFeatures()
|
||||||
count = INPUT_LAYER.featureCount()
|
count = INPUT_LAYER.featureCount()
|
||||||
if count == 0:
|
if count == 0:
|
||||||
raise GeoAlgorithmExecutionException('Input layer contains no features.')
|
raise QgsProcessingException('Input layer contains no features.')
|
||||||
|
|
||||||
total = 100.0 / count
|
total = 100.0 / count
|
||||||
|
|
||||||
|
@ -183,113 +183,6 @@ def load(fileName, name=None, crs=None, style=None, isRaster=False):
|
|||||||
return qgslayer
|
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):
|
def getRasterSublayer(path, param):
|
||||||
|
|
||||||
layer = QgsRasterLayer(path)
|
layer = QgsRasterLayer(path)
|
||||||
@ -342,18 +235,3 @@ def getRasterSublayer(path, param):
|
|||||||
except:
|
except:
|
||||||
# If the layer is not a raster layer, then just return the input path
|
# If the layer is not a raster layer, then just return the input path
|
||||||
return 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]
|
|
||||||
|
@ -26,10 +26,7 @@ __copyright__ = '(C) 2013, Victor Olaya'
|
|||||||
__revision__ = '$Format:%H$'
|
__revision__ = '$Format:%H$'
|
||||||
|
|
||||||
import os
|
import os
|
||||||
try:
|
import configparser
|
||||||
import configparser
|
|
||||||
except ImportError:
|
|
||||||
import configparser as configparser
|
|
||||||
|
|
||||||
from qgis.core import (QgsApplication,
|
from qgis.core import (QgsApplication,
|
||||||
QgsProcessingAlgorithm,
|
QgsProcessingAlgorithm,
|
||||||
@ -40,7 +37,6 @@ from qgis.core import (QgsApplication,
|
|||||||
QgsProcessingOutputLayerDefinition,
|
QgsProcessingOutputLayerDefinition,
|
||||||
QgsProject)
|
QgsProject)
|
||||||
from processing.core.Processing import Processing
|
from processing.core.Processing import Processing
|
||||||
from processing.core.parameters import ParameterSelection
|
|
||||||
from processing.gui.Postprocessing import handleAlgorithmResults
|
from processing.gui.Postprocessing import handleAlgorithmResults
|
||||||
|
|
||||||
|
|
||||||
|
@ -107,38 +107,3 @@ def checkMinDistance(point, index, distance, points):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
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)
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user