Skip to content
Permalink
Browse files
Port IDW Interpolation alg to new API
  • Loading branch information
nyalldawson committed Aug 18, 2017
1 parent 355cff1 commit a07ea33
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 130 deletions.
@@ -31,23 +31,58 @@

from qgis.core import (QgsRectangle,
QgsProcessingUtils,
QgsProcessingParameterDefinition)
QgsProcessingParameterDefinition,
QgsProcessingParameterNumber,
QgsProcessingParameterExtent,
QgsProcessingParameterRasterDestination,
QgsProcessingException)
from qgis.analysis import (QgsInterpolator,
QgsIDWInterpolator,
QgsGridFileWriter
)
QgsGridFileWriter)

from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
from processing.core.parameters import (Parameter,
ParameterNumber,
ParameterExtent,
_splitParameterOptions)
from processing.core.outputs import OutputRaster

pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]


class ParameterInterpolationData(QgsProcessingParameterDefinition):

def __init__(self, name='', description=''):
super().__init__(name, description)
self.setMetadata({
'widget_wrapper': 'processing.algs.qgis.ui.InterpolationDataWidget.InterpolationDataWidgetWrapper'
})

def type(self):
return 'idw_interpolation_data'

def clone(self):
return ParameterInterpolationData(self.name(), self.description())

@staticmethod
def parseValue(value):
if value is None:
return None

if value == '':
return None

if isinstance(value, str):
return value if value != '' else None
else:
return ParameterInterpolationData.dataToString(value)

@staticmethod
def dataToString(data):
s = ''
for c in data:
s += '{}, {}, {:d}, {:d};'.format(c[0],
c[1],
c[2],
c[3])
return s[:-1]


class IdwInterpolation(QgisAlgorithm):

INTERPOLATION_DATA = 'INTERPOLATION_DATA'
@@ -57,7 +92,7 @@ class IdwInterpolation(QgisAlgorithm):
CELLSIZE_X = 'CELLSIZE_X'
CELLSIZE_Y = 'CELLSIZE_Y'
EXTENT = 'EXTENT'
OUTPUT_LAYER = 'OUTPUT_LAYER'
OUTPUT = 'OUTPUT'

def icon(self):
return QIcon(os.path.join(pluginPath, 'images', 'interpolation.png'))
@@ -69,78 +104,29 @@ def __init__(self):
super().__init__()

def initAlgorithm(self, config=None):
class ParameterInterpolationData(Parameter):
default_metadata = {
'widget_wrapper': 'processing.algs.qgis.ui.InterpolationDataWidget.InterpolationDataWidgetWrapper'
}

def __init__(self, name='', description=''):
Parameter.__init__(self, name, description)

def setValue(self, value):
if value is None:
if not self.flags() & QgsProcessingParameterDefinition.FlagOptional:
return False
self.value = None
return True

if value == '':
if not self.flags() & QgsProcessingParameterDefinition.FlagOptional:
return False

if isinstance(value, str):
self.value = value if value != '' else None
else:
self.value = ParameterInterpolationData.dataToString(value)
return True

def getValueAsCommandLineParameter(self):
return '"{}"'.format(self.value)

def getAsScriptCode(self):
param_type = ''
param_type += 'interpolation data '
return '##' + self.name + '=' + param_type

@classmethod
def fromScriptCode(self, line):
isOptional, name, definition = _splitParameterOptions(line)
descName = QgsProcessingParameters.descriptionFromName(name)
parent = definition.lower().strip()[len('interpolation data') + 1:]
return ParameterInterpolationData(name, descName, parent)

@staticmethod
def dataToString(data):
s = ''
for c in data:
s += '{}, {}, {:d}, {:d};'.format(c[0],
c[1],
c[2],
c[3])
return s[:-1]

self.addParameter(ParameterInterpolationData(self.INTERPOLATION_DATA,
self.tr('Input layer(s)')))
self.addParameter(ParameterNumber(self.DISTANCE_COEFFICIENT,
self.tr('Distance coefficient P'),
0.0, 99.99, 2.0))
self.addParameter(ParameterNumber(self.COLUMNS,
self.tr('Number of columns'),
0, 10000000, 300))
self.addParameter(ParameterNumber(self.ROWS,
self.tr('Number of rows'),
0, 10000000, 300))
self.addParameter(ParameterNumber(self.CELLSIZE_X,
self.tr('Cell Size X'),
0.0, 999999.000000, 0.0))
self.addParameter(ParameterNumber(self.CELLSIZE_Y,
self.tr('Cell Size Y'),
0.0, 999999.000000, 0.0))
self.addParameter(ParameterExtent(self.EXTENT,
self.tr('Extent'),
optional=False))
self.addOutput(OutputRaster(self.OUTPUT_LAYER,
self.tr('Interpolated')))
self.addParameter(QgsProcessingParameterNumber(self.DISTANCE_COEFFICIENT,
self.tr('Distance coefficient P'), type=QgsProcessingParameterNumber.Double,
minValue=0.0, maxValue=99.99, defaultValue=2.0))
self.addParameter(QgsProcessingParameterNumber(self.COLUMNS,
self.tr('Number of columns'),
minValue=0, maxValue=10000000, defaultValue=300))
self.addParameter(QgsProcessingParameterNumber(self.ROWS,
self.tr('Number of rows'),
minValue=0, maxValue=10000000, defaultValue=300))
self.addParameter(QgsProcessingParameterNumber(self.CELLSIZE_X,
self.tr('Cell Size X'), type=QgsProcessingParameterNumber.Double,
minValue=0.0, maxValue=999999.000000, defaultValue=0.0))
self.addParameter(QgsProcessingParameterNumber(self.CELLSIZE_Y,
self.tr('Cell Size Y'), type=QgsProcessingParameterNumber.Double,
minValue=0.0, maxValue=999999.000000, defaultValue=0.0))
self.addParameter(QgsProcessingParameterExtent(self.EXTENT,
self.tr('Extent'),
optional=False))
self.addParameter(QgsProcessingParameterRasterDestination(self.OUTPUT,
self.tr('Interpolated')))

def name(self):
return 'idwinterpolation'
@@ -149,25 +135,19 @@ def displayName(self):
return self.tr('IDW interpolation')

def processAlgorithm(self, parameters, context, feedback):
interpolationData = self.getParameterValue(self.INTERPOLATION_DATA)
coefficient = self.getParameterValue(self.DISTANCE_COEFFICIENT)
columns = self.getParameterValue(self.COLUMNS)
rows = self.getParameterValue(self.ROWS)
cellsizeX = self.getParameterValue(self.CELLSIZE_X)
cellsizeY = self.getParameterValue(self.CELLSIZE_Y)
extent = self.getParameterValue(self.EXTENT).split(',')
output = self.getOutputValue(self.OUTPUT_LAYER)
interpolationData = ParameterInterpolationData.parseValue(parameters[self.INTERPOLATION_DATA])
coefficient = self.parameterAsDouble(parameters, self.DISTANCE_COEFFICIENT, context)
columns = self.parameterAsInt(parameters, self.COLUMNS, context)
rows = self.parameterAsInt(parameters, self.ROWS, context)
cellsizeX = self.parameterAsDouble(parameters, self.CELLSIZE_X, context)
cellsizeY = self.parameterAsDouble(parameters, self.CELLSIZE_Y, context)
bbox = self.parameterAsExtent(parameters, self.EXTENT, context)
output = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)

if interpolationData is None:
raise GeoAlgorithmExecutionException(
raise QgsProcessingException(
self.tr('You need to specify at least one input layer.'))

xMin = float(extent[0])
xMax = float(extent[1])
yMin = float(extent[2])
yMax = float(extent[3])
bbox = QgsRectangle(xMin, yMin, xMax, yMax)

layerData = []
layers = []
for row in interpolationData.split(';'):
@@ -201,3 +181,4 @@ def processAlgorithm(self, parameters, context, feedback):
cellsizeY)

writer.writeFile()
return {self.OUTPUT: output}
@@ -83,6 +83,7 @@
from .HubDistancePoints import HubDistancePoints
from .HubLines import HubLines
from .HypsometricCurves import HypsometricCurves
from .IdwInterpolation import IdwInterpolation
from .ImportIntoPostGIS import ImportIntoPostGIS
from .ImportIntoSpatialite import ImportIntoSpatialite
from .Intersection import Intersection
@@ -168,7 +169,6 @@
# from .FieldPyculator import FieldsPyculator
# from .SelectByAttributeSum import SelectByAttributeSum
# from .DefineProjection import DefineProjection
# from .IdwInterpolation import IdwInterpolation
# from .TinInterpolation import TinInterpolation
# from .RasterCalculator import RasterCalculator
# from .ExecuteSQL import ExecuteSQL
@@ -194,7 +194,7 @@ def getAlgs(self):
# FieldsPyculator(),
# FieldsMapper(), SelectByAttributeSum()
# DefineProjection(),
# IdwInterpolation(), TinInterpolation(),
# TinInterpolation(),
# RasterCalculator(),
# ExecuteSQL(), FindProjection(),
# ]
@@ -241,6 +241,7 @@ def getAlgs(self):
HubDistancePoints(),
HubLines(),
HypsometricCurves(),
IdwInterpolation(),
ImportIntoPostGIS(),
ImportIntoSpatialite(),
Intersection(),
@@ -1494,40 +1494,40 @@ tests:
name: expected/multipoint_delaunay.gml
type: vector

# - algorithm: qgis:idwinterpolation
# name: IDW interpolation using attribute
# params:
# CELLSIZE_X: 0.02667
# CELLSIZE_Y: 0.02667
# COLUMNS: 300
# DISTANCE_COEFFICIENT: 2.0
# EXTENT: 0, 8, -5, 3
# INTERPOLATION_DATA:
# name: pointsz.gml,False,1,0
# type: interpolation
# ROWS: 300
# results:
# OUTPUT_LAYER:
# hash: 56d2671d50444f8571affba3f9e585830b82af5e380394178f521065
# type: rasterhash
#
# - algorithm: qgis:idwinterpolation
# name: IDW interpolation using Z value
# params:
# CELLSIZE_X: 0.02667
# CELLSIZE_Y: 0.02667
# COLUMNS: 300
# DISTANCE_COEFFICIENT: 2.0
# EXTENT: 0, 8, -5, 3
# INTERPOLATION_DATA:
# name: pointsz.gml,True,-1,0
# type: interpolation
# ROWS: 300
# results:
# OUTPUT_LAYER:
# hash: 56d2671d50444f8571affba3f9e585830b82af5e380394178f521065
# type: rasterhash
#
- algorithm: qgis:idwinterpolation
name: IDW interpolation using attribute
params:
CELLSIZE_X: 0.02667
CELLSIZE_Y: 0.02667
COLUMNS: 300
DISTANCE_COEFFICIENT: 2.0
EXTENT: 0, 8, -5, 3
INTERPOLATION_DATA:
name: pointsz.gml,False,1,0
type: interpolation
ROWS: 300
results:
OUTPUT:
hash: 56d2671d50444f8571affba3f9e585830b82af5e380394178f521065
type: rasterhash

- algorithm: qgis:idwinterpolation
name: IDW interpolation using Z value
params:
CELLSIZE_X: 0.02667
CELLSIZE_Y: 0.02667
COLUMNS: 300
DISTANCE_COEFFICIENT: 2.0
EXTENT: 0, 8, -5, 3
INTERPOLATION_DATA:
name: pointsz.gml,True,-1,0
type: interpolation
ROWS: 300
results:
OUTPUT:
hash: 56d2671d50444f8571affba3f9e585830b82af5e380394178f521065
type: rasterhash

# - algorithm: qgis:tininterpolation
# name: TIN interpolation using attribute
# params:

0 comments on commit a07ea33

Please sign in to comment.