GdalAlgorithmProvider.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. """
  2. ***************************************************************************
  3. GdalAlgorithmProvider.py
  4. ---------------------
  5. Date : August 2012
  6. Copyright : (C) 2012 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__ = 'August 2012'
  19. __copyright__ = '(C) 2012, Victor Olaya'
  20. import os
  21. import importlib
  22. from PyQt5.QtGui import QIcon
  23. from processing.core.ProcessingConfig import ProcessingConfig, Setting
  24. from qgis.PyQt.QtCore import QCoreApplication
  25. from qgis.core import (QgsApplication,
  26. QgsProcessingProvider,
  27. QgsRuntimeProfiler)
  28. pluginPath = os.path.normpath(os.path.join(
  29. os.path.split(os.path.dirname(__file__))[0], os.pardir))
  30. class GdalAlgorithmProvider(QgsProcessingProvider):
  31. def __init__(self):
  32. super().__init__()
  33. self.algs = []
  34. self._algorithm_definitions = None
  35. QgsApplication.processingRegistry().addAlgorithmAlias('qgis:buildvirtualvector', 'gdal:buildvirtualvector')
  36. def load(self):
  37. with QgsRuntimeProfiler.profile('GDAL Provider'):
  38. ProcessingConfig.settingIcons[self.name()] = self.icon()
  39. ProcessingConfig.addSetting(Setting(self.name(), 'ACTIVATE_GDAL',
  40. self.tr('Activate'), True))
  41. ProcessingConfig.readSettings()
  42. self.refreshAlgorithms()
  43. return True
  44. def unload(self):
  45. ProcessingConfig.removeSetting('ACTIVATE_GDAL')
  46. def isActive(self):
  47. return ProcessingConfig.getSetting('ACTIVATE_GDAL')
  48. def setActive(self, active):
  49. ProcessingConfig.setSettingValue('ACTIVATE_GDAL', active)
  50. def name(self):
  51. return '数管工具集'
  52. def longName(self):
  53. # 延迟导入GdalUtils,只在需要时才加载
  54. try:
  55. from .GdalUtils import GdalUtils
  56. version = GdalUtils.readableVersion()
  57. except ImportError:
  58. version = 'Unknown'
  59. return f'数管工具集 ({version})'
  60. def id(self):
  61. return 'gdal'
  62. def helpId(self):
  63. return 'gdal'
  64. def icon(self):
  65. return QIcon(os.path.join(pluginPath, 'images', 'dbms', 'tools.png'))
  66. def svgIconPath(self):
  67. return os.path.join(pluginPath, 'images', 'dbms', 'tools.png')
  68. def _get_algorithm_definitions(self):
  69. """获取算法定义列表,使用延迟加载"""
  70. if self._algorithm_definitions is None:
  71. self._algorithm_definitions = [
  72. # GDAL Raster Tools
  73. ('AssignProjection', '.AssignProjection'),
  74. ('aspect', '.aspect'),
  75. ('buildvrt', '.buildvrt'),
  76. ('ClipRasterByExtent', '.ClipRasterByExtent'),
  77. ('ClipRasterByMask', '.ClipRasterByMask'),
  78. ('ColorRelief', '.ColorRelief'),
  79. ('contour', '.contour'),
  80. ('contour_polygon', '.contour'),
  81. ('Datasources2Vrt', '.Datasources2Vrt'),
  82. ('fillnodata', '.fillnodata'),
  83. ('gdalinfo', '.gdalinfo'),
  84. ('gdal2tiles', '.gdal2tiles'),
  85. ('gdal2xyz', '.gdal2xyz'),
  86. ('gdaladdo', '.gdaladdo'),
  87. ('gdalcalc', '.gdalcalc'),
  88. ('gdaltindex', '.gdaltindex'),
  89. ('GridAverage', '.GridAverage'),
  90. ('GridDataMetrics', '.GridDataMetrics'),
  91. ('GridInverseDistance', '.GridInverseDistance'),
  92. ('GridInverseDistanceNearestNeighbor', '.GridInverseDistanceNearestNeighbor'),
  93. ('GridLinear', '.GridLinear'),
  94. ('GridNearestNeighbor', '.GridNearestNeighbor'),
  95. ('hillshade', '.hillshade'),
  96. ('merge', '.merge'),
  97. ('nearblack', '.nearblack'),
  98. ('pct2rgb', '.pct2rgb'),
  99. ('polygonize', '.polygonize'),
  100. ('proximity', '.proximity'),
  101. ('rasterize', '.rasterize'),
  102. ('rearrange_bands', '.rearrange_bands'),
  103. ('retile', '.retile'),
  104. ('rgb2pct', '.rgb2pct'),
  105. ('roughness', '.roughness'),
  106. ('sieve', '.sieve'),
  107. ('slope', '.slope'),
  108. ('translate', '.translate'),
  109. ('tpi', '.tpi'),
  110. ('tri', '.tri'),
  111. ('warp', '.warp'),
  112. ('pansharp', '.pansharp'),
  113. ('ExtractProjection', '.extractprojection'),
  114. ('rasterize_over', '.rasterize_over'),
  115. ('rasterize_over_fixed_value', '.rasterize_over_fixed_value'),
  116. # OGR Vector Tools
  117. ('Buffer', '.Buffer'),
  118. ('ClipVectorByExtent', '.ClipVectorByExtent'),
  119. ('ClipVectorByMask', '.ClipVectorByMask'),
  120. ('Dissolve', '.Dissolve'),
  121. ('ExecuteSql', '.ExecuteSql'),
  122. ('OffsetCurve', '.OffsetCurve'),
  123. ('ogr2ogr', '.ogr2ogr'),
  124. ('ogrinfo', '.ogrinfo'),
  125. ('OneSideBuffer', '.OneSideBuffer'),
  126. ('PointsAlongLines', '.PointsAlongLines'),
  127. ('VectorProject', '.VectorProject'),
  128. # PostGIS Tools
  129. ('OgrToPostGis', '.OgrToPostGis'),
  130. ('Ogr2OgrToPostGisList', '.ogr2ogrtopostgislist'),
  131. ('Ogr2PostGisList', '.rastertopostgislist'),
  132. ('Postgisupdate', '.postgisupdate'),
  133. ('Postgisrestore', '.postgisrestore'),
  134. ('Postgistogeoserver', '.postgistogeoserver'),
  135. ('ImportOSGBToPostGIS', '.ImportOSGBToPostGIS'),
  136. ('ImportTableToPostGIS', '.ImportTableToPostGIS'),
  137. ('ImportSingleOSGBToPostGIS', '.ImportSingleOSGBToPostGIS'),
  138. ('DataStorageStatistics', '.DataStorageStatistics'),
  139. ('GdbToPostGisList', '.gdbtopostgislist'),
  140. # Export Tools
  141. ('ExportVectorByMask', '.ExportVectorByMask'),
  142. ('ExportRasterByMask', '.ExportRasterByMask'),
  143. # Other Tools
  144. ('LicenseMake', '.LicenseMake'),
  145. # Topology Tools
  146. ('A00', '.Topology.A00'),
  147. ('A01', '.Topology.A01'),
  148. ('A02', '.Topology.A02'),
  149. ('A03', '.Topology.A03'),
  150. ('A04', '.Topology.A04'),
  151. ('A05', '.Topology.A05'),
  152. ('P00', '.Topology.P00'),
  153. ('P01', '.Topology.P01'),
  154. ('L00', '.Topology.L00'),
  155. ('L01', '.Topology.L01'),
  156. ('L02', '.Topology.L02'),
  157. ('L03', '.Topology.L03'),
  158. ('L04', '.Topology.L04'),
  159. ('L05', '.Topology.L05'),
  160. ('L06', '.Topology.L06'),
  161. ('L07', '.Topology.L07'),
  162. ('L08', '.Topology.L08'),
  163. ('L09', '.Topology.L09'),
  164. ('L10', '.Topology.L10'),
  165. ('PP01', '.Topology.PP01'),
  166. ('PP02', '.Topology.PP02'),
  167. ('PL01', '.Topology.PL01'),
  168. ('PL02', '.Topology.PL02'),
  169. ('PA01', '.Topology.PA01'),
  170. ('PA02', '.Topology.PA02'),
  171. ('PA03', '.Topology.PA03'),
  172. ('LP01', '.Topology.LP01'),
  173. ('LL01', '.Topology.LL01'),
  174. ('LL02', '.Topology.LL02'),
  175. ('LL03', '.Topology.LL03'),
  176. ('LL04', '.Topology.LL04'),
  177. ('LA01', '.Topology.LA01'),
  178. ('LA02', '.Topology.LA02'),
  179. ('LA03', '.Topology.LA03'),
  180. ('AP01', '.Topology.AP01'),
  181. ('AP02', '.Topology.AP02'),
  182. ('AL01', '.Topology.AL01'),
  183. ('AA01', '.Topology.AA01'),
  184. ('AA02', '.Topology.AA02'),
  185. ('AA03', '.Topology.AA03'),
  186. ('AA04', '.Topology.AA04'),
  187. ('AA05', '.Topology.AA05'),
  188. ]
  189. return self._algorithm_definitions
  190. def _load_algorithm_class(self, class_name, module_path):
  191. """延迟加载算法类"""
  192. try:
  193. module = importlib.import_module(module_path, package=__package__)
  194. return getattr(module, class_name)
  195. except (ImportError, AttributeError) as e:
  196. print(f"Warning: Could not load algorithm {class_name} from {module_path}: {e}")
  197. return None
  198. def _load_viewshed_if_supported(self):
  199. """检查GDAL版本并加载viewshed算法"""
  200. try:
  201. from osgeo import gdal
  202. if int(gdal.VersionInfo()) > 3010000:
  203. viewshed_class = self._load_algorithm_class('viewshed', '.viewshed')
  204. if viewshed_class:
  205. return viewshed_class()
  206. except Exception as e:
  207. print(f"Warning: Could not check GDAL version or load viewshed: {e}")
  208. return None
  209. def loadAlgorithms(self):
  210. """使用延迟加载方式加载算法"""
  211. self.algs = []
  212. # 获取算法定义
  213. algorithm_definitions = self._get_algorithm_definitions()
  214. # 延迟加载每个算法
  215. for class_name, module_path in algorithm_definitions:
  216. algorithm_class = self._load_algorithm_class(class_name, module_path)
  217. if algorithm_class:
  218. try:
  219. algorithm_instance = algorithm_class()
  220. self.algs.append(algorithm_instance)
  221. except Exception as e:
  222. print(f"Warning: Could not instantiate algorithm {class_name}: {e}")
  223. # 检查并加载viewshed算法(需要GDAL版本检查)
  224. viewshed_instance = self._load_viewshed_if_supported()
  225. if viewshed_instance:
  226. self.algs.append(viewshed_instance)
  227. # 将所有算法添加到提供者
  228. for algorithm in self.algs:
  229. self.addAlgorithm(algorithm)
  230. def supportedOutputRasterLayerExtensions(self):
  231. """延迟加载GdalUtils"""
  232. try:
  233. from .GdalUtils import GdalUtils
  234. return GdalUtils.getSupportedOutputRasterExtensions()
  235. except ImportError:
  236. return []
  237. def supportsNonFileBasedOutput(self):
  238. """
  239. GDAL Provider doesn't support non file based outputs
  240. """
  241. return False
  242. def tr(self, string, context=''):
  243. if context == '':
  244. context = 'GdalAlgorithmProvider'
  245. return QCoreApplication.translate(context, string)