Skip to content

Commit

Permalink
[FEATURE][processing] New algorithm "Contour Polygons"
Browse files Browse the repository at this point in the history
With similar functionality to the existing GDAL contour algorithm, but exporting polygon representations of the contours
  • Loading branch information
pwicks86 committed Apr 7, 2020
1 parent 0f1f43f commit b73bd58
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 3 deletions.
3 changes: 2 additions & 1 deletion python/plugins/processing/algs/gdal/GdalAlgorithmProvider.py
Expand Up @@ -37,7 +37,7 @@
from .ClipRasterByExtent import ClipRasterByExtent
from .ClipRasterByMask import ClipRasterByMask
from .ColorRelief import ColorRelief
from .contour import contour
from .contour import contour, contour_polygon
from .Datasources2Vrt import Datasources2Vrt
from .fillnodata import fillnodata
from .gdalinfo import gdalinfo
Expand Down Expand Up @@ -147,6 +147,7 @@ def loadAlgorithms(self):
ClipRasterByMask(),
ColorRelief(),
contour(),
contour_polygon(),
Datasources2Vrt(),
fillnodata(),
gdalinfo(),
Expand Down
58 changes: 57 additions & 1 deletion python/plugins/processing/algs/gdal/contour.py
Expand Up @@ -139,7 +139,7 @@ def groupId(self):
def commandName(self):
return 'gdal_contour'

def getConsoleCommands(self, parameters, context, feedback, executing=True):
def _buildArgsList(self, parameters, context, feedback, executing):
inLayer = self.parameterAsRasterLayer(parameters, self.INPUT, context)
if inLayer is None:
raise QgsProcessingException(self.invalidRasterError(parameters, self.INPUT))
Expand Down Expand Up @@ -192,5 +192,61 @@ def getConsoleCommands(self, parameters, context, feedback, executing=True):

arguments.append(inLayer.source())
arguments.append(output)
return arguments

def getConsoleCommands(self, parameters, context, feedback, executing=True):
arguments = self._buildArgsList(parameters, context, feedback, executing)
return [self.commandName(), GdalUtils.escapeAndJoin(arguments)]


class contour_polygon(contour):

FIELD_NAME_MIN = 'FIELD_NAME_MIN'
FIELD_NAME_MAX = 'FIELD_NAME_MAX'

def __init__(self):
super().__init__()

def initAlgorithm(self, config=None):
super().initAlgorithm(config)
# FIELD_NAME isn't used in polygon mode
self.removeParameter(contour.FIELD_NAME)

self.addParameter(QgsProcessingParameterString(self.FIELD_NAME_MIN,
self.tr('Attribute name for minimum elevation of contour polygon'),
defaultValue='ELEV_MIN',
optional=True))

self.addParameter(QgsProcessingParameterString(self.FIELD_NAME_MAX,
self.tr('Attribute name for maximum elevation of contour polygon'),
defaultValue='ELEV_MAX',
optional=True))

# Need to replace the output parameter, as we are producing a different type of output
self.removeParameter(contour.OUTPUT)
self.addParameter(QgsProcessingParameterVectorDestination(
contour.OUTPUT, self.tr('Contours'), QgsProcessing.TypeVectorPolygon))

def name(self):
return 'contour_polygon'

def displayName(self):
return self.tr('Contour Polygons')

def getConsoleCommands(self, parameters, context, feedback, executing=True):
arguments = self._buildArgsList(parameters, context, feedback, executing)

fieldNameMin = self.parameterAsString(parameters, self.FIELD_NAME_MIN, context)
fieldNameMax = self.parameterAsString(parameters, self.FIELD_NAME_MAX, context)

if fieldNameMin:
arguments.insert(0, fieldNameMin)
arguments.insert(0, '-amin')

if fieldNameMax:
arguments.insert(0, fieldNameMax)
arguments.insert(0, '-amax')

arguments.insert(0, "-p")

return [self.commandName(), GdalUtils.escapeAndJoin(arguments)]
21 changes: 20 additions & 1 deletion python/plugins/processing/tests/GdalAlgorithmsRasterTest.py
Expand Up @@ -47,7 +47,7 @@
from processing.algs.gdal.gdal2tiles import gdal2tiles
from processing.algs.gdal.gdalcalc import gdalcalc
from processing.algs.gdal.gdaltindex import gdaltindex
from processing.algs.gdal.contour import contour
from processing.algs.gdal.contour import contour, contour_polygon
from processing.algs.gdal.gdalinfo import gdalinfo
from processing.algs.gdal.hillshade import hillshade
from processing.algs.gdal.aspect import aspect
Expand Down Expand Up @@ -404,6 +404,25 @@ def testClipRasterByMask(self):
source + ' ' +
outdir + '/check.jpg'])

def testContourPolygon(self):
context = QgsProcessingContext()
feedback = QgsProcessingFeedback()
source = os.path.join(testDataPath, 'dem.tif')
alg = contour_polygon()
alg.initAlgorithm()
with tempfile.TemporaryDirectory() as outdir:
self.assertEqual(
alg.getConsoleCommands({'INPUT': source,
'BAND': 1,
'FIELD_NAME_MIN': 'min',
'FIELD_NAME_MAX': 'max',
'INTERVAL': 5,
'OUTPUT': outdir + '/check.shp'}, context, feedback),
['gdal_contour',
'-p -amax max -amin min -b 1 -i 5.0 -f "ESRI Shapefile" ' +
source + ' ' +
outdir + '/check.shp'])

def testContour(self):
context = QgsProcessingContext()
feedback = QgsProcessingFeedback()
Expand Down

0 comments on commit b73bd58

Please sign in to comment.