Grass7AlgorithmProvider.py 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. """
  2. ***************************************************************************
  3. Grass7AlgorithmProvider.py
  4. ---------------------
  5. Date : April 2014
  6. Copyright : (C) 2014 by Victor Olaya
  7. Email : volayaf at gmail 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__ = 'Victor Olaya'
  18. __date__ = 'April 2014'
  19. __copyright__ = '(C) 2014, Victor Olaya'
  20. import os
  21. from pathlib import Path
  22. from qgis.PyQt.QtCore import QCoreApplication
  23. from qgis.core import (Qgis,
  24. QgsApplication,
  25. QgsProcessingProvider,
  26. QgsVectorFileWriter,
  27. QgsMessageLog,
  28. QgsProcessingUtils,
  29. QgsRuntimeProfiler)
  30. from processing.core.ProcessingConfig import (ProcessingConfig, Setting)
  31. from grassprovider.Grass7Utils import Grass7Utils
  32. from grassprovider.Grass7Algorithm import Grass7Algorithm
  33. from processing.tools.system import isWindows, isMac
  34. class Grass7AlgorithmProvider(QgsProcessingProvider):
  35. descriptionFolders = Grass7Utils.grassDescriptionFolders()
  36. def __init__(self):
  37. super().__init__()
  38. self.algs = []
  39. def load(self):
  40. with QgsRuntimeProfiler.profile('Grass Provider'):
  41. ProcessingConfig.settingIcons[self.name()] = self.icon()
  42. ProcessingConfig.addSetting(Setting(
  43. self.name(),
  44. Grass7Utils.GRASS_LOG_COMMANDS,
  45. self.tr('Log execution commands'), False))
  46. ProcessingConfig.addSetting(Setting(
  47. self.name(),
  48. Grass7Utils.GRASS_LOG_CONSOLE,
  49. self.tr('Log console output'), False))
  50. ProcessingConfig.addSetting(Setting(
  51. self.name(),
  52. Grass7Utils.GRASS_HELP_URL,
  53. self.tr('Location of GRASS docs'), ''))
  54. # Add settings for using r.external/v.external instead of r.in.gdal/v.in.ogr
  55. # but set them to False by default because the {r,v}.external implementations
  56. # have some bugs on windows + there are algorithms that can't be used with
  57. # external data (need a solid r.in.gdal/v.in.ogr).
  58. # For more info have a look at e.g. https://trac.osgeo.org/grass/ticket/3927
  59. ProcessingConfig.addSetting(Setting(
  60. self.name(),
  61. Grass7Utils.GRASS_USE_REXTERNAL,
  62. self.tr('For raster layers, use r.external (faster) instead of r.in.gdal'),
  63. False))
  64. ProcessingConfig.addSetting(Setting(
  65. self.name(),
  66. Grass7Utils.GRASS_USE_VEXTERNAL,
  67. self.tr('For vector layers, use v.external (faster) instead of v.in.ogr'),
  68. False))
  69. ProcessingConfig.readSettings()
  70. self.refreshAlgorithms()
  71. return True
  72. def unload(self):
  73. ProcessingConfig.removeSetting(Grass7Utils.GRASS_LOG_COMMANDS)
  74. ProcessingConfig.removeSetting(Grass7Utils.GRASS_LOG_CONSOLE)
  75. ProcessingConfig.removeSetting(Grass7Utils.GRASS_HELP_URL)
  76. ProcessingConfig.removeSetting(Grass7Utils.GRASS_USE_REXTERNAL)
  77. ProcessingConfig.removeSetting(Grass7Utils.GRASS_USE_VEXTERNAL)
  78. def createAlgsList(self):
  79. algs = []
  80. folders = self.descriptionFolders
  81. for folder in folders:
  82. for descriptionFile in folder.glob('*.txt'):
  83. try:
  84. alg = Grass7Algorithm(descriptionFile)
  85. if alg.name().strip() != '':
  86. algs.append(alg)
  87. else:
  88. QgsMessageLog.logMessage(self.tr('Could not open GRASS GIS 7 algorithm: {0}').format(descriptionFile), self.tr('Processing'), Qgis.Critical)
  89. except Exception as e:
  90. QgsMessageLog.logMessage(
  91. self.tr('Could not open GRASS GIS 7 algorithm: {0}\n{1}').format(descriptionFile, e), self.tr('Processing'), Qgis.Critical)
  92. return algs
  93. def loadAlgorithms(self):
  94. version = Grass7Utils.installedVersion(True)
  95. if version is None:
  96. QgsMessageLog.logMessage(self.tr('Problem with GRASS installation: GRASS was not found or is not correctly installed'),
  97. self.tr('Processing'), Qgis.Critical)
  98. return
  99. self.algs = self.createAlgsList()
  100. for a in self.algs:
  101. self.addAlgorithm(a)
  102. def name(self):
  103. return 'GRASS'
  104. def longName(self):
  105. version = Grass7Utils.installedVersion()
  106. return 'GRASS GIS ({})'.format(version) if version is not None else "GRASS GIS"
  107. def id(self):
  108. return 'grass7'
  109. def helpId(self):
  110. return 'grass7'
  111. def icon(self):
  112. return QgsApplication.getThemeIcon("/providerGrass.svg")
  113. def svgIconPath(self):
  114. return QgsApplication.iconPath("/providerGrass.svg")
  115. def defaultVectorFileExtension(self, hasGeometry=True):
  116. # By default,'gpkg', but if OGR has not been compiled with sqlite3, then
  117. # we take "SHP"
  118. if 'GPKG' in [o.driverName for o in
  119. QgsVectorFileWriter.ogrDriverList()]:
  120. return 'gpkg'
  121. else:
  122. return 'shp' if hasGeometry else 'dbf'
  123. def supportsNonFileBasedOutput(self):
  124. """
  125. GRASS7 Provider doesn't support non file based outputs
  126. """
  127. return False
  128. def supportedOutputVectorLayerExtensions(self):
  129. # We use the same extensions than QGIS because:
  130. # - QGIS is using OGR like GRASS
  131. # - There are very chances than OGR version used in GRASS is
  132. # different from QGIS OGR version.
  133. return QgsVectorFileWriter.supportedFormatExtensions()
  134. def supportedOutputRasterLayerExtensions(self):
  135. return Grass7Utils.getSupportedOutputRasterExtensions()
  136. def canBeActivated(self):
  137. return not bool(Grass7Utils.checkGrassIsInstalled())
  138. def tr(self, string, context=''):
  139. if context == '':
  140. context = 'Grass7AlgorithmProvider'
  141. return QCoreApplication.translate(context, string)