Skip to content

Commit 5dc8c3f

Browse files
authored
Merge pull request #6141 from alexbruy/processing-gdal
[processing] restore GDAL rasterize algorithm
2 parents 54f9846 + 77a6bbb commit 5dc8c3f

File tree

3 files changed

+170
-90
lines changed

3 files changed

+170
-90
lines changed

python/plugins/processing/algs/gdal/GdalAlgorithmProvider.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
from .pct2rgb import pct2rgb
5959
from .polygonize import polygonize
6060
from .proximity import proximity
61+
from .rasterize import rasterize
6162
from .retile import retile
6263
from .rgb2pct import rgb2pct
6364
from .roughness import roughness
@@ -68,7 +69,6 @@
6869
from .tri import tri
6970
from .warp import warp
7071

71-
# from .rasterize import rasterize
7272
# from .extractprojection import ExtractProjection
7373
# from .gdalcalc import gdalcalc
7474
# from .rasterize_over import rasterize_over
@@ -164,6 +164,7 @@ def loadAlgorithms(self):
164164
pct2rgb(),
165165
polygonize(),
166166
proximity(),
167+
rasterize(),
167168
retile(),
168169
rgb2pct(),
169170
roughness(),

python/plugins/processing/algs/gdal/rasterize.py

+144-87
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
***************************************************************************
1818
"""
1919

20-
2120
__author__ = 'Alexander Bruy'
2221
__date__ = 'September 2013'
2322
__copyright__ = '(C) 2013, Alexander Bruy'
@@ -30,6 +29,17 @@
3029

3130
from qgis.PyQt.QtGui import QIcon
3231

32+
from qgis.core import (QgsRasterFileWriter,
33+
QgsProcessingParameterDefinition,
34+
QgsProcessingParameterFeatureSource,
35+
QgsProcessingParameterField,
36+
QgsProcessingParameterRasterLayer,
37+
QgsProcessingParameterNumber,
38+
QgsProcessingParameterString,
39+
QgsProcessingParameterEnum,
40+
QgsProcessingParameterExtent,
41+
QgsProcessingParameterBoolean,
42+
QgsProcessingParameterRasterDestination)
3343
from processing.algs.gdal.GdalAlgorithm import GdalAlgorithm
3444
from processing.algs.gdal.GdalUtils import GdalUtils
3545

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

4151
INPUT = 'INPUT'
4252
FIELD = 'FIELD'
43-
DIMENSIONS = 'DIMENSIONS'
53+
BURN = 'BURN'
4454
WIDTH = 'WIDTH'
4555
HEIGHT = 'HEIGHT'
46-
NO_DATA = 'NO_DATA'
47-
RTYPE = 'RTYPE'
56+
UNITS = 'UNITS'
57+
NODATA = 'NODATA'
58+
EXTENT = 'EXTENT'
59+
INIT = 'INIT'
60+
INVERT = 'INVERT'
61+
ALL_TOUCH = 'ALL_TOUCH'
4862
OPTIONS = 'OPTIONS'
63+
DATA_TYPE = 'DATA_TYPE'
4964
OUTPUT = 'OUTPUT'
5065

51-
TYPE = ['Byte', 'Int16', 'UInt16', 'UInt32', 'Int32', 'Float32', 'Float64']
52-
53-
RAST_EXT = 'RAST_EXT'
54-
55-
def icon(self):
56-
return QIcon(os.path.join(pluginPath, 'images', 'gdaltools', 'rasterize.png'))
66+
TYPES = ['Byte', 'Int16', 'UInt16', 'UInt32', 'Int32', 'Float32', 'Float64', 'CInt16', 'CInt32', 'CFloat32', 'CFloat64']
5767

5868
def __init__(self):
5969
super().__init__()
6070

6171
def initAlgorithm(self, config=None):
62-
self.addParameter(ParameterVector(self.INPUT, self.tr('Input layer')))
63-
self.addParameter(ParameterTableField(self.FIELD,
64-
self.tr('Attribute field'), self.INPUT))
65-
self.addParameter(ParameterSelection(self.DIMENSIONS,
66-
self.tr('Set output raster size (ignored if above option is checked)'),
67-
['Output size in pixels', 'Output resolution in map units per pixel'], 1))
68-
self.addParameter(ParameterNumber(self.WIDTH,
69-
self.tr('Horizontal'), 0.0, 99999999.999999, 100.0))
70-
self.addParameter(ParameterNumber(self.HEIGHT,
71-
self.tr('Vertical'), 0.0, 99999999.999999, 100.0))
72-
self.addParameter(ParameterExtent(self.RAST_EXT, self.tr('Raster extent')))
73-
self.addParameter(ParameterString(self.NO_DATA,
74-
self.tr("Nodata value"),
75-
'', optional=True))
76-
77-
self.addParameter(ParameterString(self.OPTIONS,
78-
self.tr('Additional creation options'),
79-
optional=True,
80-
metadata={'widget_wrapper': 'processing.algs.gdal.ui.RasterOptionsWidget.RasterOptionsWidgetWrapper'}))
81-
self.addParameter(ParameterSelection(self.RTYPE,
82-
self.tr('Raster type'),
83-
self.TYPE, 5))
84-
85-
self.addOutput(OutputRaster(self.OUTPUT,
86-
self.tr('Rasterized')))
72+
self.units = [self.tr("Pixels"),
73+
self.tr("Georeferenced units")]
74+
75+
self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT,
76+
self.tr('Input layer')))
77+
self.addParameter(QgsProcessingParameterField(self.FIELD,
78+
self.tr('Field to use for a burn-in value'),
79+
None,
80+
self.INPUT,
81+
QgsProcessingParameterField.Numeric,
82+
optional=True))
83+
self.addParameter(QgsProcessingParameterNumber(self.BURN,
84+
self.tr('A fixed value to burn'),
85+
type=QgsProcessingParameterNumber.Double,
86+
defaultValue=0.0,
87+
optional=True))
88+
self.addParameter(QgsProcessingParameterEnum(self.UNITS,
89+
self.tr('Output raster size units'),
90+
self.units))
91+
self.addParameter(QgsProcessingParameterNumber(self.WIDTH,
92+
self.tr('Width/Horizontal resolution'),
93+
type=QgsProcessingParameterNumber.Double,
94+
minValue=0.0,
95+
defaultValue=0.0))
96+
self.addParameter(QgsProcessingParameterNumber(self.HEIGHT,
97+
self.tr('Height/Vertical resolution'),
98+
type=QgsProcessingParameterNumber.Double,
99+
minValue=0.0,
100+
defaultValue=0.0))
101+
self.addParameter(QgsProcessingParameterExtent(self.EXTENT,
102+
self.tr('Output extent')))
103+
self.addParameter(QgsProcessingParameterNumber(self.NODATA,
104+
self.tr('Assign a specified nodata value to output bands'),
105+
type=QgsProcessingParameterNumber.Double,
106+
defaultValue=0.0,
107+
optional=True))
108+
109+
options_param = QgsProcessingParameterString(self.OPTIONS,
110+
self.tr('Additional creation parameters'),
111+
defaultValue='',
112+
optional=True)
113+
options_param.setFlags(options_param.flags() | QgsProcessingParameterDefinition.FlagAdvanced)
114+
options_param.setMetadata({
115+
'widget_wrapper': {
116+
'class': 'processing.algs.gdal.ui.RasterOptionsWidget.RasterOptionsWidgetWrapper'}})
117+
self.addParameter(options_param)
118+
119+
dataType_param = QgsProcessingParameterEnum(self.DATA_TYPE,
120+
self.tr('Output data type'),
121+
self.TYPES,
122+
allowMultiple=False,
123+
defaultValue=5)
124+
dataType_param.setFlags(dataType_param.flags() | QgsProcessingParameterDefinition.FlagAdvanced)
125+
self.addParameter(dataType_param)
126+
127+
init_param = QgsProcessingParameterNumber(self.INIT,
128+
self.tr('Pre-initialize the output image with value'),
129+
type=QgsProcessingParameterNumber.Double,
130+
defaultValue=0.0,
131+
optional=True)
132+
init_param.setFlags(init_param.flags() | QgsProcessingParameterDefinition.FlagAdvanced)
133+
self.addParameter(init_param)
134+
135+
invert_param = QgsProcessingParameterBoolean(self.INVERT,
136+
self.tr('Invert rasterization'),
137+
defaultValue=False)
138+
invert_param.setFlags(invert_param.flags() | QgsProcessingParameterDefinition.FlagAdvanced)
139+
self.addParameter(invert_param)
140+
141+
self.addParameter(QgsProcessingParameterRasterDestination(self.OUTPUT,
142+
self.tr('Rasterized')))
87143

88144
def name(self):
89145
return 'rasterize'
@@ -97,70 +153,71 @@ def group(self):
97153
def groupId(self):
98154
return 'vectorconversion'
99155

100-
def getConsoleCommands(self, parameters, context, feedback, executing=True):
101-
inLayer = self.getParameterValue(self.INPUT)
102-
noData = self.getParameterValue(self.NO_DATA)
103-
rastext = str(self.getParameterValue(self.RAST_EXT))
104-
if not rastext:
105-
rastext = QgsProcessingUtils.combineLayerExtents([inLayer])
106-
opts = self.getParameterValue(self.OPTIONS)
107-
out = self.getOutputValue(self.OUTPUT)
156+
def icon(self):
157+
return QIcon(os.path.join(pluginPath, 'images', 'gdaltools', 'rasterize.png'))
108158

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

111-
if noData is not None:
112-
noData = str(noData)
162+
def getConsoleCommands(self, parameters, context, feedback, executing=True):
163+
ogrLayer, layerName = self.getOgrCompatibleSource(self.INPUT, parameters, context, feedback, executing)
113164

114-
arguments = []
115-
arguments.append('-a')
116-
arguments.append(str(self.getParameterValue(self.FIELD)))
165+
arguments = ['-l']
166+
arguments.append(layerName)
117167

118-
arguments.append('-ot')
119-
arguments.append(self.TYPE[self.getParameterValue(self.RTYPE)])
120-
dimType = self.getParameterValue(self.DIMENSIONS)
121-
arguments.append('-of')
122-
arguments.append(GdalUtils.getFormatShortNameFromFilename(out))
123-
124-
regionCoords = rastext.split(',')
125-
try:
126-
rastext = []
127-
rastext.append('-te')
128-
rastext.append(regionCoords[0])
129-
rastext.append(regionCoords[2])
130-
rastext.append(regionCoords[1])
131-
rastext.append(regionCoords[3])
132-
except IndexError:
133-
rastext = []
134-
if rastext:
135-
arguments.extend(rastext)
136-
137-
if dimType == 0:
138-
# size in pixels
168+
fieldName = self.parameterAsString(parameters, self.FIELD, context)
169+
if fieldName:
170+
arguments.append('-a')
171+
arguments.append(fieldName)
172+
else:
173+
arguments.append('-burn')
174+
arguments.append(self.parameterAsDouble(parameters, self.BURN, context))
175+
176+
units = self.parameterAsEnum(parameters, self.UNITS, context)
177+
if units == 0:
139178
arguments.append('-ts')
140-
arguments.append(str(self.getParameterValue(self.WIDTH)))
141-
arguments.append(str(self.getParameterValue(self.HEIGHT)))
142179
else:
143-
# resolution in map units per pixel
144180
arguments.append('-tr')
145-
arguments.append(str(self.getParameterValue(self.WIDTH)))
146-
arguments.append(str(self.getParameterValue(self.HEIGHT)))
181+
arguments.append(self.parameterAsDouble(parameters, self.WIDTH, context))
182+
arguments.append(self.parameterAsDouble(parameters, self.HEIGHT, context))
147183

148-
if noData and len(noData) > 0:
184+
initValue = self.parameterAsDouble(parameters, self.INIT, context)
185+
if initValue:
186+
arguments.append('-init')
187+
arguments.append(initValue)
188+
189+
if self.parameterAsBool(parameters, self.INVERT, context):
190+
arguments.append('-i')
191+
192+
if self.parameterAsBool(parameters, self.ALL_TOUCH, context):
193+
arguments.append('-at')
194+
195+
nodata = self.parameterAsDouble(parameters, self.NODATA, context)
196+
if nodata:
149197
arguments.append('-a_nodata')
150-
arguments.append(noData)
198+
arguments.append(nodata)
151199

152-
if opts:
153-
arguments.append('-co')
154-
arguments.append(opts)
200+
extent = self.parameterAsExtent(parameters, self.EXTENT, context)
201+
if not extent.isNull():
202+
arguments.append('-te')
203+
arguments.append(extent.xMinimum())
204+
arguments.append(extent.yMinimum())
205+
arguments.append(extent.xMaximum())
206+
arguments.append(extent.yMaximum())
155207

156-
arguments.append('-l')
208+
arguments.append('-ot')
209+
arguments.append(self.TYPES[self.parameterAsEnum(parameters, self.DATA_TYPE, context)])
157210

158-
print(GdalUtils.ogrLayerName(inLayer))
159-
arguments.append(GdalUtils.ogrLayerName(inLayer))
160-
arguments.append(ogrLayer)
211+
out = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)
212+
arguments.append('-of')
213+
arguments.append(QgsRasterFileWriter.driverForExtension(os.path.splitext(out)[1]))
214+
options = self.parameterAsString(parameters, self.OPTIONS, context)
161215

216+
if options:
217+
arguments.append('-co')
218+
arguments.append(options)
219+
220+
arguments.append(ogrLayer)
162221
arguments.append(out)
163-
return ['gdal_rasterize', GdalUtils.escapeAndJoin(arguments)]
164222

165-
def commandName(self):
166-
return "gdal_rasterize"
223+
return ['gdal_rasterize', GdalUtils.escapeAndJoin(arguments)]

python/plugins/processing/tests/testdata/gdal_algorithm_tests.yaml

+24-2
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ tests:
303303
hash: fff4a08498e93494f3f2cf1a9074451e6fd68341849aedc9e2c45e6a
304304
type: rasterhash
305305

306-
# Disabled as gdal2_poligonize.py is not available on Travis
306+
# Disabled as gdal_poligonize.py is not available on Travis
307307
# - algorithm: gdal:polygonize
308308
# name: Polygonize
309309
# params:
@@ -318,7 +318,7 @@ tests:
318318
# name: expected/gdal/polygonize.gml
319319
# type: vector
320320

321-
# Disabled as gdal2_proximity.py is not available on Travis
321+
# Disabled as gdal_proximity.py is not available on Travis
322322
# - algorithm: gdal:proximity
323323
# name: Proximity
324324
# params:
@@ -338,6 +338,28 @@ tests:
338338
# hash: 32802271d1ce083ca14078bfefaef6300ae8809af11f6a4270583d0c
339339
# type: rasterhash
340340

341+
- algorithm: gdal:rasterize
342+
name: Test (gdal:rasterize)
343+
params:
344+
BURN: 0.0
345+
DATA_TYPE: 5
346+
EXTENT: -1.0,10.0,-3.0,6.0 [EPSG:4326]
347+
FIELD: intval
348+
HEIGHT: 10.0
349+
INIT: 0.0
350+
INPUT:
351+
name: polys.gml
352+
type: vector
353+
INVERT: false
354+
NODATA: 0.0
355+
OPTIONS: ''
356+
UNITS: 0
357+
WIDTH: 10.0
358+
results:
359+
OUTPUT:
360+
hash: 30409eb496900df4ceeab37200a91552c350dbc7761eb089dd75a329
361+
type: rasterhash
362+
341363
- algorithm: gdal:roughness
342364
name: Roughness
343365
params:

0 commit comments

Comments
 (0)