ClipRasterByMask.py

Pedro Venâncio, 2019-02-13 11:57 AM

Download (10.5 KB)

 
1
# -*- coding: utf-8 -*-
2

    
3
"""
4
***************************************************************************
5
    ClipRasterByMask.py
6
    ---------------------
7
    Date                 : September 2013
8
    Copyright            : (C) 2013 by Alexander Bruy
9
    Email                : alexander bruy at gmail dot com
10
***************************************************************************
11
*                                                                         *
12
*   This program is free software; you can redistribute it and/or modify  *
13
*   it under the terms of the GNU General Public License as published by  *
14
*   the Free Software Foundation; either version 2 of the License, or     *
15
*   (at your option) any later version.                                   *
16
*                                                                         *
17
***************************************************************************
18
"""
19

    
20
__author__ = 'Alexander Bruy'
21
__date__ = 'September 2013'
22
__copyright__ = '(C) 2013, Alexander Bruy'
23

    
24
# This will get replaced with a git SHA1 when you do a git archive
25

    
26
__revision__ = '$Format:%H$'
27

    
28
import os
29

    
30
from qgis.PyQt.QtGui import QIcon
31

    
32
from qgis.core import (QgsRasterFileWriter,
33
                       QgsProcessing,
34
                       QgsProcessingException,
35
                       QgsProcessingParameterDefinition,
36
                       QgsProcessingParameterFeatureSource,
37
                       QgsProcessingParameterRasterLayer,
38
                       QgsProcessingParameterCrs,
39
                       QgsProcessingParameterEnum,
40
                       QgsProcessingParameterString,
41
                       QgsProcessingParameterNumber,
42
                       QgsProcessingParameterBoolean,
43
                       QgsProcessingParameterRasterDestination)
44
from processing.algs.gdal.GdalAlgorithm import GdalAlgorithm
45
from processing.algs.gdal.GdalUtils import GdalUtils
46

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

    
49

    
50
class ClipRasterByMask(GdalAlgorithm):
51

    
52
    INPUT = 'INPUT'
53
    MASK = 'MASK'
54
    SOURCE_CRS = 'SOURCE_CRS'
55
    TARGET_CRS = 'TARGET_CRS'
56
    NODATA = 'NODATA'
57
    ALPHA_BAND = 'ALPHA_BAND'
58
    CROP_TO_CUTLINE = 'CROP_TO_CUTLINE'
59
    KEEP_RESOLUTION = 'KEEP_RESOLUTION'
60
    SET_RESOLUTION = 'SET_RESOLUTION'
61
    X_RESOLUTION = 'X_RESOLUTION'
62
    Y_RESOLUTION = 'Y_RESOLUTION'
63
    OPTIONS = 'OPTIONS'
64
    DATA_TYPE = 'DATA_TYPE'
65
    OUTPUT = 'OUTPUT'
66

    
67
    TYPES = ['Use input layer data type', 'Byte', 'Int16', 'UInt16', 'UInt32', 'Int32', 'Float32', 'Float64', 'CInt16', 'CInt32', 'CFloat32', 'CFloat64']
68

    
69
    def __init__(self):
70
        super().__init__()
71

    
72
    def initAlgorithm(self, config=None):
73
        self.addParameter(QgsProcessingParameterRasterLayer(self.INPUT,
74
                                                            self.tr('Input layer')))
75
        self.addParameter(QgsProcessingParameterFeatureSource(self.MASK,
76
                                                              self.tr('Mask layer'),
77
                                                              [QgsProcessing.TypeVectorPolygon]))
78
        self.addParameter(QgsProcessingParameterCrs(self.SOURCE_CRS,
79
                                                    self.tr('Source CRS'),
80
                                                    optional=True))
81
        self.addParameter(QgsProcessingParameterCrs(self.TARGET_CRS,
82
                                                    self.tr('Target CRS'),
83
                                                    optional=True))
84
        self.addParameter(QgsProcessingParameterNumber(self.NODATA,
85
                                                       self.tr('Assign a specified nodata value to output bands'),
86
                                                       type=QgsProcessingParameterNumber.Double,
87
                                                       defaultValue=None,
88
                                                       optional=True))
89
        self.addParameter(QgsProcessingParameterBoolean(self.ALPHA_BAND,
90
                                                        self.tr('Create an output alpha band'),
91
                                                        defaultValue=False))
92
        self.addParameter(QgsProcessingParameterBoolean(self.CROP_TO_CUTLINE,
93
                                                        self.tr('Match the extent of the clipped raster to the extent of the mask layer'),
94
                                                        defaultValue=True))
95
        self.addParameter(QgsProcessingParameterBoolean(self.KEEP_RESOLUTION,
96
                                                        self.tr('Keep resolution of input raster'),
97
                                                        defaultValue=False))
98
        self.addParameter(QgsProcessingParameterBoolean(self.SET_RESOLUTION,
99
                                                        self.tr('Set output file resolution'),
100
                                                        defaultValue=False))
101
        self.addParameter(QgsProcessingParameterNumber(self.X_RESOLUTION,
102
                                                       self.tr('X Resolution to output bands'),
103
                                                       type=QgsProcessingParameterNumber.Double,
104
                                                       defaultValue=None,
105
                                                       optional=True))
106
        self.addParameter(QgsProcessingParameterNumber(self.Y_RESOLUTION,
107
                                                       self.tr('Y Resolution to output bands'),
108
                                                       type=QgsProcessingParameterNumber.Double,
109
                                                       defaultValue=None,
110
                                                       optional=True))
111
        options_param = QgsProcessingParameterString(self.OPTIONS,
112
                                                     self.tr('Additional creation options'),
113
                                                     defaultValue='',
114
                                                     optional=True)
115
        options_param.setFlags(options_param.flags() | QgsProcessingParameterDefinition.FlagAdvanced)
116
        options_param.setMetadata({
117
            'widget_wrapper': {
118
                'class': 'processing.algs.gdal.ui.RasterOptionsWidget.RasterOptionsWidgetWrapper'}})
119
        self.addParameter(options_param)
120

    
121
        dataType_param = QgsProcessingParameterEnum(self.DATA_TYPE,
122
                                                    self.tr('Output data type'),
123
                                                    self.TYPES,
124
                                                    allowMultiple=False,
125
                                                    defaultValue=0)
126
        dataType_param.setFlags(dataType_param.flags() | QgsProcessingParameterDefinition.FlagAdvanced)
127
        self.addParameter(dataType_param)
128

    
129
        self.addParameter(QgsProcessingParameterRasterDestination(self.OUTPUT,
130
                                                                  self.tr('Clipped (mask)')))
131

    
132
    def name(self):
133
        return 'cliprasterbymasklayer'
134

    
135
    def displayName(self):
136
        return self.tr('Clip raster by mask layer')
137

    
138
    def icon(self):
139
        return QIcon(os.path.join(pluginPath, 'images', 'gdaltools', 'raster-clip.png'))
140

    
141
    def group(self):
142
        return self.tr('Raster extraction')
143

    
144
    def groupId(self):
145
        return 'rasterextraction'
146

    
147
    def commandName(self):
148
        return 'gdalwarp'
149

    
150
    def getConsoleCommands(self, parameters, context, feedback, executing=True):
151
        inLayer = self.parameterAsRasterLayer(parameters, self.INPUT, context)
152
        if inLayer is None:
153
            raise QgsProcessingException(self.invalidRasterError(parameters, self.INPUT))
154

    
155
        maskLayer, maskLayerName = self.getOgrCompatibleSource(self.MASK, parameters, context, feedback, executing)
156

    
157
        sourceCrs = self.parameterAsCrs(parameters, self.SOURCE_CRS, context)
158
        targetCrs = self.parameterAsCrs(parameters, self.TARGET_CRS, context)
159

    
160
        if self.NODATA in parameters and parameters[self.NODATA] is not None:
161
            nodata = self.parameterAsDouble(parameters, self.NODATA, context)
162
        else:
163
            nodata = None
164
        options = self.parameterAsString(parameters, self.OPTIONS, context)
165
        out = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)
166
        self.setOutputValue(self.OUTPUT, out)
167

    
168
        arguments = []
169

    
170
        if sourceCrs.isValid():
171
            arguments.append('-s_srs')
172
            arguments.append(GdalUtils.gdal_crs_string(sourceCrs))
173

    
174
        if targetCrs.isValid():
175
            arguments.append('-t_srs')
176
            arguments.append(GdalUtils.gdal_crs_string(targetCrs))
177

    
178
        data_type = self.parameterAsEnum(parameters, self.DATA_TYPE, context)
179
        if data_type:
180
            arguments.append('-ot ' + self.TYPES[data_type])
181

    
182
        arguments.append('-of')
183
        arguments.append(QgsRasterFileWriter.driverForExtension(os.path.splitext(out)[1]))
184

    
185
        if self.parameterAsBool(parameters, self.KEEP_RESOLUTION, context):
186
            arguments.append('-tr')
187
            arguments.append(str(inLayer.rasterUnitsPerPixelX()))
188
            arguments.append(str(-inLayer.rasterUnitsPerPixelY()))
189
            arguments.append('-tap')
190

    
191
        if self.parameterAsBool(parameters, self.SET_RESOLUTION, context):
192
            arguments.append('-tr')
193
            if self.X_RESOLUTION in parameters and parameters[self.X_RESOLUTION] is not None:
194
                xres = self.parameterAsDouble(parameters, self.X_RESOLUTION, context)
195
                arguments.append('{}'.format(xres))
196
            else:
197
                arguments.append(str(inLayer.rasterUnitsPerPixelX()))
198
            if self.Y_RESOLUTION in parameters and parameters[self.Y_RESOLUTION] is not None:
199
                yres = self.parameterAsDouble(parameters, self.Y_RESOLUTION, context)
200
                arguments.append('{}'.format(yres))
201
            else:
202
                arguments.append(str(-inLayer.rasterUnitsPerPixelY()))
203
            arguments.append('-tap')
204

    
205
        arguments.append('-cutline')
206
        arguments.append(maskLayer)
207

    
208
        if self.parameterAsBool(parameters, self.CROP_TO_CUTLINE, context):
209
            arguments.append('-crop_to_cutline')
210

    
211
        if self.parameterAsBool(parameters, self.ALPHA_BAND, context):
212
            arguments.append('-dstalpha')
213

    
214
        if nodata is not None:
215
            arguments.append('-dstnodata {}'.format(nodata))
216

    
217
        if options:
218
            arguments.extend(GdalUtils.parseCreationOptions(options))
219

    
220
        arguments.append(inLayer.source())
221
        arguments.append(out)
222

    
223
        return [self.commandName(), GdalUtils.escapeAndJoin(arguments)]