Skip to content

Commit

Permalink
Merge pull request #6141 from alexbruy/processing-gdal
Browse files Browse the repository at this point in the history
[processing] restore GDAL rasterize algorithm
  • Loading branch information
alexbruy committed Jan 24, 2018
2 parents 54f9846 + 77a6bbb commit 5dc8c3f
Show file tree
Hide file tree
Showing 3 changed files with 170 additions and 90 deletions.
3 changes: 2 additions & 1 deletion python/plugins/processing/algs/gdal/GdalAlgorithmProvider.py
Expand Up @@ -58,6 +58,7 @@
from .pct2rgb import pct2rgb
from .polygonize import polygonize
from .proximity import proximity
from .rasterize import rasterize
from .retile import retile
from .rgb2pct import rgb2pct
from .roughness import roughness
Expand All @@ -68,7 +69,6 @@
from .tri import tri
from .warp import warp

# from .rasterize import rasterize
# from .extractprojection import ExtractProjection
# from .gdalcalc import gdalcalc
# from .rasterize_over import rasterize_over
Expand Down Expand Up @@ -164,6 +164,7 @@ def loadAlgorithms(self):
pct2rgb(),
polygonize(),
proximity(),
rasterize(),
retile(),
rgb2pct(),
roughness(),
Expand Down
231 changes: 144 additions & 87 deletions python/plugins/processing/algs/gdal/rasterize.py
Expand Up @@ -17,7 +17,6 @@
***************************************************************************
"""


__author__ = 'Alexander Bruy'
__date__ = 'September 2013'
__copyright__ = '(C) 2013, Alexander Bruy'
Expand All @@ -30,6 +29,17 @@

from qgis.PyQt.QtGui import QIcon

from qgis.core import (QgsRasterFileWriter,
QgsProcessingParameterDefinition,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterField,
QgsProcessingParameterRasterLayer,
QgsProcessingParameterNumber,
QgsProcessingParameterString,
QgsProcessingParameterEnum,
QgsProcessingParameterExtent,
QgsProcessingParameterBoolean,
QgsProcessingParameterRasterDestination)
from processing.algs.gdal.GdalAlgorithm import GdalAlgorithm
from processing.algs.gdal.GdalUtils import GdalUtils

Expand All @@ -40,50 +50,96 @@ class rasterize(GdalAlgorithm):

INPUT = 'INPUT'
FIELD = 'FIELD'
DIMENSIONS = 'DIMENSIONS'
BURN = 'BURN'
WIDTH = 'WIDTH'
HEIGHT = 'HEIGHT'
NO_DATA = 'NO_DATA'
RTYPE = 'RTYPE'
UNITS = 'UNITS'
NODATA = 'NODATA'
EXTENT = 'EXTENT'
INIT = 'INIT'
INVERT = 'INVERT'
ALL_TOUCH = 'ALL_TOUCH'
OPTIONS = 'OPTIONS'
DATA_TYPE = 'DATA_TYPE'
OUTPUT = 'OUTPUT'

TYPE = ['Byte', 'Int16', 'UInt16', 'UInt32', 'Int32', 'Float32', 'Float64']

RAST_EXT = 'RAST_EXT'

def icon(self):
return QIcon(os.path.join(pluginPath, 'images', 'gdaltools', 'rasterize.png'))
TYPES = ['Byte', 'Int16', 'UInt16', 'UInt32', 'Int32', 'Float32', 'Float64', 'CInt16', 'CInt32', 'CFloat32', 'CFloat64']

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

def initAlgorithm(self, config=None):
self.addParameter(ParameterVector(self.INPUT, self.tr('Input layer')))
self.addParameter(ParameterTableField(self.FIELD,
self.tr('Attribute field'), self.INPUT))
self.addParameter(ParameterSelection(self.DIMENSIONS,
self.tr('Set output raster size (ignored if above option is checked)'),
['Output size in pixels', 'Output resolution in map units per pixel'], 1))
self.addParameter(ParameterNumber(self.WIDTH,
self.tr('Horizontal'), 0.0, 99999999.999999, 100.0))
self.addParameter(ParameterNumber(self.HEIGHT,
self.tr('Vertical'), 0.0, 99999999.999999, 100.0))
self.addParameter(ParameterExtent(self.RAST_EXT, self.tr('Raster extent')))
self.addParameter(ParameterString(self.NO_DATA,
self.tr("Nodata value"),
'', optional=True))

self.addParameter(ParameterString(self.OPTIONS,
self.tr('Additional creation options'),
optional=True,
metadata={'widget_wrapper': 'processing.algs.gdal.ui.RasterOptionsWidget.RasterOptionsWidgetWrapper'}))
self.addParameter(ParameterSelection(self.RTYPE,
self.tr('Raster type'),
self.TYPE, 5))

self.addOutput(OutputRaster(self.OUTPUT,
self.tr('Rasterized')))
self.units = [self.tr("Pixels"),
self.tr("Georeferenced units")]

self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT,
self.tr('Input layer')))
self.addParameter(QgsProcessingParameterField(self.FIELD,
self.tr('Field to use for a burn-in value'),
None,
self.INPUT,
QgsProcessingParameterField.Numeric,
optional=True))
self.addParameter(QgsProcessingParameterNumber(self.BURN,
self.tr('A fixed value to burn'),
type=QgsProcessingParameterNumber.Double,
defaultValue=0.0,
optional=True))
self.addParameter(QgsProcessingParameterEnum(self.UNITS,
self.tr('Output raster size units'),
self.units))
self.addParameter(QgsProcessingParameterNumber(self.WIDTH,
self.tr('Width/Horizontal resolution'),
type=QgsProcessingParameterNumber.Double,
minValue=0.0,
defaultValue=0.0))
self.addParameter(QgsProcessingParameterNumber(self.HEIGHT,
self.tr('Height/Vertical resolution'),
type=QgsProcessingParameterNumber.Double,
minValue=0.0,
defaultValue=0.0))
self.addParameter(QgsProcessingParameterExtent(self.EXTENT,
self.tr('Output extent')))
self.addParameter(QgsProcessingParameterNumber(self.NODATA,
self.tr('Assign a specified nodata value to output bands'),
type=QgsProcessingParameterNumber.Double,
defaultValue=0.0,
optional=True))

options_param = QgsProcessingParameterString(self.OPTIONS,
self.tr('Additional creation parameters'),
defaultValue='',
optional=True)
options_param.setFlags(options_param.flags() | QgsProcessingParameterDefinition.FlagAdvanced)
options_param.setMetadata({
'widget_wrapper': {
'class': 'processing.algs.gdal.ui.RasterOptionsWidget.RasterOptionsWidgetWrapper'}})
self.addParameter(options_param)

dataType_param = QgsProcessingParameterEnum(self.DATA_TYPE,
self.tr('Output data type'),
self.TYPES,
allowMultiple=False,
defaultValue=5)
dataType_param.setFlags(dataType_param.flags() | QgsProcessingParameterDefinition.FlagAdvanced)
self.addParameter(dataType_param)

init_param = QgsProcessingParameterNumber(self.INIT,
self.tr('Pre-initialize the output image with value'),
type=QgsProcessingParameterNumber.Double,
defaultValue=0.0,
optional=True)
init_param.setFlags(init_param.flags() | QgsProcessingParameterDefinition.FlagAdvanced)
self.addParameter(init_param)

invert_param = QgsProcessingParameterBoolean(self.INVERT,
self.tr('Invert rasterization'),
defaultValue=False)
invert_param.setFlags(invert_param.flags() | QgsProcessingParameterDefinition.FlagAdvanced)
self.addParameter(invert_param)

self.addParameter(QgsProcessingParameterRasterDestination(self.OUTPUT,
self.tr('Rasterized')))

def name(self):
return 'rasterize'
Expand All @@ -97,70 +153,71 @@ def group(self):
def groupId(self):
return 'vectorconversion'

def getConsoleCommands(self, parameters, context, feedback, executing=True):
inLayer = self.getParameterValue(self.INPUT)
noData = self.getParameterValue(self.NO_DATA)
rastext = str(self.getParameterValue(self.RAST_EXT))
if not rastext:
rastext = QgsProcessingUtils.combineLayerExtents([inLayer])
opts = self.getParameterValue(self.OPTIONS)
out = self.getOutputValue(self.OUTPUT)
def icon(self):
return QIcon(os.path.join(pluginPath, 'images', 'gdaltools', 'rasterize.png'))

ogrLayer = GdalUtils.ogrConnectionString(inLayer, context)[1:-1]
def commandName(self):
return 'gdal_rasterize'

if noData is not None:
noData = str(noData)
def getConsoleCommands(self, parameters, context, feedback, executing=True):
ogrLayer, layerName = self.getOgrCompatibleSource(self.INPUT, parameters, context, feedback, executing)

arguments = []
arguments.append('-a')
arguments.append(str(self.getParameterValue(self.FIELD)))
arguments = ['-l']
arguments.append(layerName)

arguments.append('-ot')
arguments.append(self.TYPE[self.getParameterValue(self.RTYPE)])
dimType = self.getParameterValue(self.DIMENSIONS)
arguments.append('-of')
arguments.append(GdalUtils.getFormatShortNameFromFilename(out))

regionCoords = rastext.split(',')
try:
rastext = []
rastext.append('-te')
rastext.append(regionCoords[0])
rastext.append(regionCoords[2])
rastext.append(regionCoords[1])
rastext.append(regionCoords[3])
except IndexError:
rastext = []
if rastext:
arguments.extend(rastext)

if dimType == 0:
# size in pixels
fieldName = self.parameterAsString(parameters, self.FIELD, context)
if fieldName:
arguments.append('-a')
arguments.append(fieldName)
else:
arguments.append('-burn')
arguments.append(self.parameterAsDouble(parameters, self.BURN, context))

units = self.parameterAsEnum(parameters, self.UNITS, context)
if units == 0:
arguments.append('-ts')
arguments.append(str(self.getParameterValue(self.WIDTH)))
arguments.append(str(self.getParameterValue(self.HEIGHT)))
else:
# resolution in map units per pixel
arguments.append('-tr')
arguments.append(str(self.getParameterValue(self.WIDTH)))
arguments.append(str(self.getParameterValue(self.HEIGHT)))
arguments.append(self.parameterAsDouble(parameters, self.WIDTH, context))
arguments.append(self.parameterAsDouble(parameters, self.HEIGHT, context))

if noData and len(noData) > 0:
initValue = self.parameterAsDouble(parameters, self.INIT, context)
if initValue:
arguments.append('-init')
arguments.append(initValue)

if self.parameterAsBool(parameters, self.INVERT, context):
arguments.append('-i')

if self.parameterAsBool(parameters, self.ALL_TOUCH, context):
arguments.append('-at')

nodata = self.parameterAsDouble(parameters, self.NODATA, context)
if nodata:
arguments.append('-a_nodata')
arguments.append(noData)
arguments.append(nodata)

if opts:
arguments.append('-co')
arguments.append(opts)
extent = self.parameterAsExtent(parameters, self.EXTENT, context)
if not extent.isNull():
arguments.append('-te')
arguments.append(extent.xMinimum())
arguments.append(extent.yMinimum())
arguments.append(extent.xMaximum())
arguments.append(extent.yMaximum())

arguments.append('-l')
arguments.append('-ot')
arguments.append(self.TYPES[self.parameterAsEnum(parameters, self.DATA_TYPE, context)])

print(GdalUtils.ogrLayerName(inLayer))
arguments.append(GdalUtils.ogrLayerName(inLayer))
arguments.append(ogrLayer)
out = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)
arguments.append('-of')
arguments.append(QgsRasterFileWriter.driverForExtension(os.path.splitext(out)[1]))
options = self.parameterAsString(parameters, self.OPTIONS, context)

if options:
arguments.append('-co')
arguments.append(options)

arguments.append(ogrLayer)
arguments.append(out)
return ['gdal_rasterize', GdalUtils.escapeAndJoin(arguments)]

def commandName(self):
return "gdal_rasterize"
return ['gdal_rasterize', GdalUtils.escapeAndJoin(arguments)]
26 changes: 24 additions & 2 deletions python/plugins/processing/tests/testdata/gdal_algorithm_tests.yaml
Expand Up @@ -303,7 +303,7 @@ tests:
hash: fff4a08498e93494f3f2cf1a9074451e6fd68341849aedc9e2c45e6a
type: rasterhash

# Disabled as gdal2_poligonize.py is not available on Travis
# Disabled as gdal_poligonize.py is not available on Travis
# - algorithm: gdal:polygonize
# name: Polygonize
# params:
Expand All @@ -318,7 +318,7 @@ tests:
# name: expected/gdal/polygonize.gml
# type: vector

# Disabled as gdal2_proximity.py is not available on Travis
# Disabled as gdal_proximity.py is not available on Travis
# - algorithm: gdal:proximity
# name: Proximity
# params:
Expand All @@ -338,6 +338,28 @@ tests:
# hash: 32802271d1ce083ca14078bfefaef6300ae8809af11f6a4270583d0c
# type: rasterhash

- algorithm: gdal:rasterize
name: Test (gdal:rasterize)
params:
BURN: 0.0
DATA_TYPE: 5
EXTENT: -1.0,10.0,-3.0,6.0 [EPSG:4326]
FIELD: intval
HEIGHT: 10.0
INIT: 0.0
INPUT:
name: polys.gml
type: vector
INVERT: false
NODATA: 0.0
OPTIONS: ''
UNITS: 0
WIDTH: 10.0
results:
OUTPUT:
hash: 30409eb496900df4ceeab37200a91552c350dbc7761eb089dd75a329
type: rasterhash

- algorithm: gdal:roughness
name: Roughness
params:
Expand Down

0 comments on commit 5dc8c3f

Please sign in to comment.