Skip to content

Commit

Permalink
Restore TIN interpolation algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Aug 18, 2017
1 parent 4bba95f commit 000c86e
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 152 deletions.
4 changes: 2 additions & 2 deletions python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py
Expand Up @@ -151,6 +151,7 @@
from .SumLines import SumLines
from .SymmetricalDifference import SymmetricalDifference
from .TextToFloat import TextToFloat
from .TinInterpolation import TinInterpolation
from .TopoColors import TopoColor
from .Translate import Translate
from .TruncateTable import TruncateTable
Expand All @@ -169,7 +170,6 @@
# from .FieldPyculator import FieldsPyculator
# from .SelectByAttributeSum import SelectByAttributeSum
# from .DefineProjection import DefineProjection
# from .TinInterpolation import TinInterpolation
# from .RasterCalculator import RasterCalculator
# from .ExecuteSQL import ExecuteSQL
# from .FindProjection import FindProjection
Expand All @@ -194,7 +194,6 @@ def getAlgs(self):
# FieldsPyculator(),
# FieldsMapper(), SelectByAttributeSum()
# DefineProjection(),
# TinInterpolation(),
# RasterCalculator(),
# ExecuteSQL(), FindProjection(),
# ]
Expand Down Expand Up @@ -309,6 +308,7 @@ def getAlgs(self):
SumLines(),
SymmetricalDifference(),
TextToFloat(),
TinInterpolation(),
TopoColor(),
Translate(),
TruncateTable(),
Expand Down
202 changes: 91 additions & 111 deletions python/plugins/processing/algs/qgis/TinInterpolation.py
Expand Up @@ -29,29 +29,61 @@

from qgis.PyQt.QtGui import QIcon

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

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

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 'tin_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 TinInterpolation(QgisAlgorithm):

INTERPOLATION_DATA = 'INTERPOLATION_DATA'
Expand All @@ -61,8 +93,8 @@ class TinInterpolation(QgisAlgorithm):
CELLSIZE_X = 'CELLSIZE_X'
CELLSIZE_Y = 'CELLSIZE_Y'
EXTENT = 'EXTENT'
OUTPUT_LAYER = 'OUTPUT_LAYER'
TRIANULATION_FILE = 'TRIANULATION_FILE'
OUTPUT = 'OUTPUT'
TRIANGULATION_FILE = 'TRIANGULATION_FILE'

def icon(self):
return QIcon(os.path.join(pluginPath, 'images', 'interpolation.png'))
Expand All @@ -78,82 +110,34 @@ def initAlgorithm(self, config=None):
self.tr('Clough-Toucher (cubic)')
]

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(ParameterSelection(self.METHOD,
self.tr('Interpolation method'),
self.METHODS,
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.addOutput(OutputVector(self.TRIANULATION_FILE,
self.tr('Triangulation'),
)) # datatype=dataobjects.TYPE_VECTOR_LINE))
self.addParameter(QgsProcessingParameterEnum(self.METHOD,
self.tr('Interpolation method'),
options=self.METHODS,
defaultValue=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')))

self.addParameter(QgsProcessingParameterFileDestination(self.TRIANGULATION_FILE,
self.tr('Triangulation'),
self.tr('SHP files (*.shp)'),
optional=True))

def name(self):
return 'tininterpolation'
Expand All @@ -162,30 +146,24 @@ def displayName(self):
return self.tr('TIN interpolation')

def processAlgorithm(self, parameters, context, feedback):
interpolationData = self.getParameterValue(self.INTERPOLATION_DATA)
method = self.getParameterValue(self.METHOD)
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)
triangulation = self.getOutputValue(self.TRIANULATION_FILE)
interpolationData = ParameterInterpolationData.parseValue(parameters[self.INTERPOLATION_DATA])
method = self.parameterAsEnum(parameters, self.METHOD, 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)
triangulation = self.parameterAsFileOutput(parameters, self.TRIANGULATION_FILE, context)

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

if cellsizeX == 0.0 or cellsizeY == 0.0:
raise GeoAlgorithmExecutionException(
raise QgsProcessingException(
self.tr('Cellsize should be greater than 0.'))

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(';'):
Expand Down Expand Up @@ -213,8 +191,9 @@ def processAlgorithm(self, parameters, context, feedback):
interpolationMethod = QgsTINInterpolator.CloughTocher

interpolator = QgsTINInterpolator(layerData, interpolationMethod)
interpolator.setExportTriangulationToFile(True)
interpolator.setTriangulationFilePath(triangulation)
if triangulation is not None and triangulation != '':
interpolator.setExportTriangulationToFile(True)
interpolator.setTriangulationFilePath(triangulation)

writer = QgsGridFileWriter(interpolator,
output,
Expand All @@ -224,4 +203,5 @@ def processAlgorithm(self, parameters, context, feedback):
cellsizeX,
cellsizeY)

writer.writeFile()
writer.writeFile(feedback)
return {self.OUTPUT: output}
78 changes: 39 additions & 39 deletions python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml
Expand Up @@ -1528,45 +1528,45 @@ tests:
hash: 56d2671d50444f8571affba3f9e585830b82af5e380394178f521065
type: rasterhash

# - algorithm: qgis:tininterpolation
# name: TIN interpolation using attribute
# params:
# CELLSIZE_X: 0.02667
# CELLSIZE_Y: 0.02667
# COLUMNS: 300
# EXTENT: 0, 8, -5, 3
# INTERPOLATION_DATA:
# name: pointsz.gml,False,1,0
# type: interpolation
# METHOD: '0'
# ROWS: 300
# results:
# OUTPUT_LAYER:
# hash: 87f40be6ec08f3fcbb5707762de71f6be35bb265c61f594335562a26
# type: rasterhash
# #TRIANULATION_FILE:
# # name: expected/triangulation.gml
# # type: vector
#
# - algorithm: qgis:tininterpolation
# name: TIN interpolation using Z value
# params:
# CELLSIZE_X: 0.02667
# CELLSIZE_Y: 0.02667
# COLUMNS: 300
# EXTENT: 0, 8, -5, 3
# INTERPOLATION_DATA:
# name: pointsz.gml,True,-1,0
# type: interpolation
# METHOD: '1'
# ROWS: 300
# results:
# OUTPUT_LAYER:
# hash: 5e14dd0b879884b8b8da56c082947dad681feb4e9f1137f5cda126f8
# type: rasterhash
# #TRIANULATION_FILE:
# # name: expected/triangulation.gml
# # type: vector
- algorithm: qgis:tininterpolation
name: TIN interpolation using attribute
params:
CELLSIZE_X: 0.02667
CELLSIZE_Y: 0.02667
COLUMNS: 300
EXTENT: 0, 8, -5, 3
INTERPOLATION_DATA:
name: pointsz.gml,False,1,0
type: interpolation
METHOD: '0'
ROWS: 300
results:
OUTPUT:
hash: 87f40be6ec08f3fcbb5707762de71f6be35bb265c61f594335562a26
type: rasterhash
#TRIANGULATION_FILE:
# name: expected/triangulation.gml
# type: vector

- algorithm: qgis:tininterpolation
name: TIN interpolation using Z value
params:
CELLSIZE_X: 0.02667
CELLSIZE_Y: 0.02667
COLUMNS: 300
EXTENT: 0, 8, -5, 3
INTERPOLATION_DATA:
name: pointsz.gml,True,-1,0
type: interpolation
METHOD: '1'
ROWS: 300
results:
OUTPUT:
hash: 5e14dd0b879884b8b8da56c082947dad681feb4e9f1137f5cda126f8
type: rasterhash
#TRIANULATION_FILE:
# name: expected/triangulation.gml
# type: vector

- algorithm: native:removenullgeometries
name: Remove null geometries
Expand Down

0 comments on commit 000c86e

Please sign in to comment.