buildvrt.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. """
  2. ***************************************************************************
  3. merge.py
  4. ---------------------
  5. Date : October 2014
  6. Copyright : (C) 2014 by Radoslaw Guzinski
  7. Email : rmgu at dhi-gras dot com
  8. ***************************************************************************
  9. * *
  10. * This program is free software; you can redistribute it and/or modify *
  11. * it under the terms of the GNU General Public License as published by *
  12. * the Free Software Foundation; either version 2 of the License, or *
  13. * (at your option) any later version. *
  14. * *
  15. ***************************************************************************
  16. """
  17. __author__ = 'Radoslaw Guzinski'
  18. __date__ = 'October 2014'
  19. __copyright__ = '(C) 2014, Radoslaw Guzinski'
  20. import os
  21. import pathlib
  22. from qgis.PyQt.QtCore import QCoreApplication
  23. from qgis.PyQt.QtGui import QIcon
  24. from qgis.core import (QgsProcessingAlgorithm,
  25. QgsProcessing,
  26. QgsProcessingParameterDefinition,
  27. QgsProperty,
  28. QgsProcessingParameters,
  29. QgsProcessingParameterMultipleLayers,
  30. QgsProcessingParameterEnum,
  31. QgsProcessingParameterBoolean,
  32. QgsProcessingParameterRasterDestination,
  33. QgsProcessingParameterCrs,
  34. QgsProcessingParameterString,
  35. QgsProcessingOutputLayerDefinition,
  36. QgsProcessingUtils)
  37. from processing.algs.gdal.GdalAlgorithm import GdalAlgorithm
  38. from processing.algs.gdal.GdalUtils import GdalUtils
  39. pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
  40. class buildvrt(GdalAlgorithm):
  41. INPUT = 'INPUT'
  42. OUTPUT = 'OUTPUT'
  43. RESOLUTION = 'RESOLUTION'
  44. SEPARATE = 'SEPARATE'
  45. PROJ_DIFFERENCE = 'PROJ_DIFFERENCE'
  46. ADD_ALPHA = 'ADD_ALPHA'
  47. ASSIGN_CRS = 'ASSIGN_CRS'
  48. RESAMPLING = 'RESAMPLING'
  49. SRC_NODATA = 'SRC_NODATA'
  50. EXTRA = 'EXTRA'
  51. def __init__(self):
  52. super().__init__()
  53. def initAlgorithm(self, config=None):
  54. class ParameterVrtDestination(QgsProcessingParameterRasterDestination):
  55. def __init__(self, name, description):
  56. super().__init__(name, description)
  57. def clone(self):
  58. copy = ParameterVrtDestination(self.name(), self.description())
  59. return copy
  60. def defaultFileExtension(self):
  61. return 'vrt'
  62. def createFileFilter(self):
  63. return '{} (*.vrt *.VRT)'.format(QCoreApplication.translate("GdalAlgorithm", 'VRT files'))
  64. def supportedOutputRasterLayerExtensions(self):
  65. return ['vrt']
  66. def parameterAsOutputLayer(self, definition, value, context):
  67. return super(QgsProcessingParameterRasterDestination, self).parameterAsOutputLayer(definition, value, context)
  68. def isSupportedOutputValue(self, value, context):
  69. output_path = QgsProcessingParameters.parameterAsOutputLayer(self, value, context)
  70. if pathlib.Path(output_path).suffix.lower() != '.vrt':
  71. return False, QCoreApplication.translate("GdalAlgorithm", 'Output filename must use a .vrt extension')
  72. return True, ''
  73. self.RESAMPLING_OPTIONS = ((self.tr('Nearest Neighbour'), 'nearest'),
  74. (self.tr('Bilinear (2x2 Kernel)'), 'bilinear'),
  75. (self.tr('Cubic (4x4 Kernel)'), 'cubic'),
  76. (self.tr('Cubic B-Spline (4x4 Kernel)'), 'cubicspline'),
  77. (self.tr('Lanczos (6x6 Kernel)'), 'lanczos'),
  78. (self.tr('Average'), 'average'),
  79. (self.tr('Mode'), 'mode'))
  80. self.RESOLUTION_OPTIONS = ((self.tr('Average'), 'average'),
  81. (self.tr('Highest'), 'highest'),
  82. (self.tr('Lowest'), 'lowest'))
  83. self.addParameter(QgsProcessingParameterMultipleLayers(self.INPUT,
  84. self.tr('Input layers'),
  85. QgsProcessing.TypeRaster))
  86. self.addParameter(QgsProcessingParameterEnum(self.RESOLUTION,
  87. self.tr('Resolution'),
  88. options=[i[0] for i in self.RESOLUTION_OPTIONS],
  89. defaultValue=0))
  90. separate_param = QgsProcessingParameterBoolean(self.SEPARATE,
  91. self.tr('Place each input file into a separate band'),
  92. defaultValue=True)
  93. # default to not using separate bands is a friendlier option, but we can't change the parameter's actual
  94. # defaultValue without breaking API!
  95. separate_param.setGuiDefaultValueOverride(False)
  96. self.addParameter(separate_param)
  97. self.addParameter(QgsProcessingParameterBoolean(self.PROJ_DIFFERENCE,
  98. self.tr('Allow projection difference'),
  99. defaultValue=False))
  100. add_alpha_param = QgsProcessingParameterBoolean(self.ADD_ALPHA,
  101. self.tr('Add alpha mask band to VRT when source raster has none'),
  102. defaultValue=False)
  103. add_alpha_param.setFlags(add_alpha_param.flags() | QgsProcessingParameterDefinition.FlagAdvanced)
  104. self.addParameter(add_alpha_param)
  105. assign_crs = QgsProcessingParameterCrs(self.ASSIGN_CRS,
  106. self.tr('Override projection for the output file'),
  107. defaultValue=None, optional=True)
  108. assign_crs.setFlags(assign_crs.flags() | QgsProcessingParameterDefinition.FlagAdvanced)
  109. self.addParameter(assign_crs)
  110. resampling = QgsProcessingParameterEnum(self.RESAMPLING,
  111. self.tr('Resampling algorithm'),
  112. options=[i[0] for i in self.RESAMPLING_OPTIONS],
  113. defaultValue=0)
  114. resampling.setFlags(resampling.flags() | QgsProcessingParameterDefinition.FlagAdvanced)
  115. self.addParameter(resampling)
  116. src_nodata_param = QgsProcessingParameterString(self.SRC_NODATA,
  117. self.tr('Nodata value(s) for input bands (space separated)'),
  118. defaultValue=None,
  119. optional=True)
  120. src_nodata_param.setFlags(src_nodata_param.flags() | QgsProcessingParameterDefinition.FlagAdvanced)
  121. self.addParameter(src_nodata_param)
  122. extra_param = QgsProcessingParameterString(self.EXTRA,
  123. self.tr('Additional command-line parameters'),
  124. defaultValue=None,
  125. optional=True)
  126. extra_param.setFlags(extra_param.flags() | QgsProcessingParameterDefinition.FlagAdvanced)
  127. self.addParameter(extra_param)
  128. self.addParameter(ParameterVrtDestination(self.OUTPUT, QCoreApplication.translate("ParameterVrtDestination", 'Virtual')))
  129. def name(self):
  130. return 'buildvirtualraster'
  131. def displayName(self):
  132. return QCoreApplication.translate("buildvrt", 'Build virtual raster')
  133. def icon(self):
  134. return QIcon(os.path.join(pluginPath, 'images', 'gdaltools', 'vrt.png'))
  135. def group(self):
  136. return QCoreApplication.translate("buildvrt", 'Raster miscellaneous')
  137. def groupId(self):
  138. return 'rastermiscellaneous'
  139. def commandName(self):
  140. return "gdalbuildvrt"
  141. def getConsoleCommands(self, parameters, context, feedback, executing=True):
  142. arguments = [
  143. '-overwrite',
  144. '-resolution',
  145. self.RESOLUTION_OPTIONS[self.parameterAsEnum(parameters, self.RESOLUTION, context)][1]
  146. ]
  147. if self.parameterAsBoolean(parameters, buildvrt.SEPARATE, context):
  148. arguments.append('-separate')
  149. if self.parameterAsBoolean(parameters, buildvrt.PROJ_DIFFERENCE, context):
  150. arguments.append('-allow_projection_difference')
  151. if self.parameterAsBoolean(parameters, buildvrt.ADD_ALPHA, context):
  152. arguments.append('-addalpha')
  153. crs = self.parameterAsCrs(parameters, self.ASSIGN_CRS, context)
  154. if crs.isValid():
  155. arguments.append('-a_srs')
  156. arguments.append(GdalUtils.gdal_crs_string(crs))
  157. arguments.append('-r')
  158. arguments.append(self.RESAMPLING_OPTIONS[self.parameterAsEnum(parameters, self.RESAMPLING, context)][1])
  159. if self.SRC_NODATA in parameters and parameters[self.SRC_NODATA] not in (None, ''):
  160. nodata = self.parameterAsString(parameters, self.SRC_NODATA, context)
  161. arguments.append('-srcnodata')
  162. arguments.append(nodata)
  163. if self.EXTRA in parameters and parameters[self.EXTRA] not in (None, ''):
  164. extra = self.parameterAsString(parameters, self.EXTRA, context)
  165. arguments.append(extra)
  166. # Always write input files to a text file in case there are many of them and the
  167. # length of the command will be longer then allowed in command prompt
  168. list_file = GdalUtils.writeLayerParameterToTextFile(filename='buildvrtInputFiles.txt', alg=self, parameters=parameters, parameter_name=self.INPUT, context=context, executing=executing, quote=False)
  169. arguments.append('-input_file_list')
  170. arguments.append(list_file)
  171. out = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)
  172. self.setOutputValue(self.OUTPUT, out)
  173. arguments.append(out)
  174. return [self.commandName(), GdalUtils.escapeAndJoin(arguments)]