""" *************************************************************************** GdalAlgorithmProvider.py --------------------- Date : August 2012 Copyright : (C) 2012 by Victor Olaya Email : volayaf at gmail dot com *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * *************************************************************************** """ __author__ = 'Victor Olaya' __date__ = 'August 2012' __copyright__ = '(C) 2012, Victor Olaya' import os import importlib from PyQt5.QtGui import QIcon from processing.core.ProcessingConfig import ProcessingConfig, Setting from qgis.PyQt.QtCore import QCoreApplication from qgis.core import (QgsApplication, QgsProcessingProvider, QgsRuntimeProfiler) pluginPath = os.path.normpath(os.path.join( os.path.split(os.path.dirname(__file__))[0], os.pardir)) class GdalAlgorithmProvider(QgsProcessingProvider): def __init__(self): super().__init__() self.algs = [] self._algorithm_definitions = None QgsApplication.processingRegistry().addAlgorithmAlias('qgis:buildvirtualvector', 'gdal:buildvirtualvector') def load(self): with QgsRuntimeProfiler.profile('GDAL Provider'): ProcessingConfig.settingIcons[self.name()] = self.icon() ProcessingConfig.addSetting(Setting(self.name(), 'ACTIVATE_GDAL', self.tr('Activate'), True)) ProcessingConfig.readSettings() self.refreshAlgorithms() return True def unload(self): ProcessingConfig.removeSetting('ACTIVATE_GDAL') def isActive(self): return ProcessingConfig.getSetting('ACTIVATE_GDAL') def setActive(self, active): ProcessingConfig.setSettingValue('ACTIVATE_GDAL', active) def name(self): return '数管工具集' def longName(self): # 延迟导入GdalUtils,只在需要时才加载 try: from .GdalUtils import GdalUtils version = GdalUtils.readableVersion() except ImportError: version = 'Unknown' return f'数管工具集 ({version})' def id(self): return 'gdal' def helpId(self): return 'gdal' def icon(self): return QIcon(os.path.join(pluginPath, 'images', 'dbms', 'tools.png')) def svgIconPath(self): return os.path.join(pluginPath, 'images', 'dbms', 'tools.png') def _get_algorithm_definitions(self): """获取算法定义列表,使用延迟加载""" if self._algorithm_definitions is None: self._algorithm_definitions = [ # GDAL Raster Tools ('AssignProjection', '.AssignProjection'), ('aspect', '.aspect'), ('buildvrt', '.buildvrt'), ('ClipRasterByExtent', '.ClipRasterByExtent'), ('ClipRasterByMask', '.ClipRasterByMask'), ('ColorRelief', '.ColorRelief'), ('contour', '.contour'), ('contour_polygon', '.contour'), ('Datasources2Vrt', '.Datasources2Vrt'), ('fillnodata', '.fillnodata'), ('gdalinfo', '.gdalinfo'), ('gdal2tiles', '.gdal2tiles'), ('gdal2xyz', '.gdal2xyz'), ('gdaladdo', '.gdaladdo'), ('gdalcalc', '.gdalcalc'), ('gdaltindex', '.gdaltindex'), ('GridAverage', '.GridAverage'), ('GridDataMetrics', '.GridDataMetrics'), ('GridInverseDistance', '.GridInverseDistance'), ('GridInverseDistanceNearestNeighbor', '.GridInverseDistanceNearestNeighbor'), ('GridLinear', '.GridLinear'), ('GridNearestNeighbor', '.GridNearestNeighbor'), ('hillshade', '.hillshade'), ('merge', '.merge'), ('nearblack', '.nearblack'), ('pct2rgb', '.pct2rgb'), ('polygonize', '.polygonize'), ('proximity', '.proximity'), ('rasterize', '.rasterize'), ('rearrange_bands', '.rearrange_bands'), ('retile', '.retile'), ('rgb2pct', '.rgb2pct'), ('roughness', '.roughness'), ('sieve', '.sieve'), ('slope', '.slope'), ('translate', '.translate'), ('tpi', '.tpi'), ('tri', '.tri'), ('warp', '.warp'), ('pansharp', '.pansharp'), ('ExtractProjection', '.extractprojection'), ('rasterize_over', '.rasterize_over'), ('rasterize_over_fixed_value', '.rasterize_over_fixed_value'), # OGR Vector Tools ('Buffer', '.Buffer'), ('ClipVectorByExtent', '.ClipVectorByExtent'), ('ClipVectorByMask', '.ClipVectorByMask'), ('Dissolve', '.Dissolve'), ('ExecuteSql', '.ExecuteSql'), ('OffsetCurve', '.OffsetCurve'), ('ogr2ogr', '.ogr2ogr'), ('ogrinfo', '.ogrinfo'), ('OneSideBuffer', '.OneSideBuffer'), ('PointsAlongLines', '.PointsAlongLines'), ('VectorProject', '.VectorProject'), # PostGIS Tools ('OgrToPostGis', '.OgrToPostGis'), ('Ogr2OgrToPostGisList', '.ogr2ogrtopostgislist'), ('Ogr2PostGisList', '.rastertopostgislist'), ('Postgisupdate', '.postgisupdate'), ('Postgisrestore', '.postgisrestore'), ('Postgistogeoserver', '.postgistogeoserver'), ('ImportOSGBToPostGIS', '.ImportOSGBToPostGIS'), ('ImportTableToPostGIS', '.ImportTableToPostGIS'), ('ImportSingleOSGBToPostGIS', '.ImportSingleOSGBToPostGIS'), ('DataStorageStatistics', '.DataStorageStatistics'), ('GdbToPostGisList', '.gdbtopostgislist'), # Export Tools ('ExportVectorByMask', '.ExportVectorByMask'), ('ExportRasterByMask', '.ExportRasterByMask'), # Other Tools ('LicenseMake', '.LicenseMake'), # Topology Tools ('A00', '.Topology.A00'), ('A01', '.Topology.A01'), ('A02', '.Topology.A02'), ('A03', '.Topology.A03'), ('A04', '.Topology.A04'), ('A05', '.Topology.A05'), ('P00', '.Topology.P00'), ('P01', '.Topology.P01'), ('L00', '.Topology.L00'), ('L01', '.Topology.L01'), ('L02', '.Topology.L02'), ('L03', '.Topology.L03'), ('L04', '.Topology.L04'), ('L05', '.Topology.L05'), ('L06', '.Topology.L06'), ('L07', '.Topology.L07'), ('L08', '.Topology.L08'), ('L09', '.Topology.L09'), ('L10', '.Topology.L10'), ('PP01', '.Topology.PP01'), ('PP02', '.Topology.PP02'), ('PL01', '.Topology.PL01'), ('PL02', '.Topology.PL02'), ('PA01', '.Topology.PA01'), ('PA02', '.Topology.PA02'), ('PA03', '.Topology.PA03'), ('LP01', '.Topology.LP01'), ('LL01', '.Topology.LL01'), ('LL02', '.Topology.LL02'), ('LL03', '.Topology.LL03'), ('LL04', '.Topology.LL04'), ('LA01', '.Topology.LA01'), ('LA02', '.Topology.LA02'), ('LA03', '.Topology.LA03'), ('AP01', '.Topology.AP01'), ('AP02', '.Topology.AP02'), ('AL01', '.Topology.AL01'), ('AA01', '.Topology.AA01'), ('AA02', '.Topology.AA02'), ('AA03', '.Topology.AA03'), ('AA04', '.Topology.AA04'), ('AA05', '.Topology.AA05'), ] return self._algorithm_definitions def _load_algorithm_class(self, class_name, module_path): """延迟加载算法类""" try: module = importlib.import_module(module_path, package=__package__) return getattr(module, class_name) except (ImportError, AttributeError) as e: print(f"Warning: Could not load algorithm {class_name} from {module_path}: {e}") return None def _load_viewshed_if_supported(self): """检查GDAL版本并加载viewshed算法""" try: from osgeo import gdal if int(gdal.VersionInfo()) > 3010000: viewshed_class = self._load_algorithm_class('viewshed', '.viewshed') if viewshed_class: return viewshed_class() except Exception as e: print(f"Warning: Could not check GDAL version or load viewshed: {e}") return None def loadAlgorithms(self): """使用延迟加载方式加载算法""" self.algs = [] # 获取算法定义 algorithm_definitions = self._get_algorithm_definitions() # 延迟加载每个算法 for class_name, module_path in algorithm_definitions: algorithm_class = self._load_algorithm_class(class_name, module_path) if algorithm_class: try: algorithm_instance = algorithm_class() self.algs.append(algorithm_instance) except Exception as e: print(f"Warning: Could not instantiate algorithm {class_name}: {e}") # 检查并加载viewshed算法(需要GDAL版本检查) viewshed_instance = self._load_viewshed_if_supported() if viewshed_instance: self.algs.append(viewshed_instance) # 将所有算法添加到提供者 for algorithm in self.algs: self.addAlgorithm(algorithm) def supportedOutputRasterLayerExtensions(self): """延迟加载GdalUtils""" try: from .GdalUtils import GdalUtils return GdalUtils.getSupportedOutputRasterExtensions() except ImportError: return [] def supportsNonFileBasedOutput(self): """ GDAL Provider doesn't support non file based outputs """ return False def tr(self, string, context=''): if context == '': context = 'GdalAlgorithmProvider' return QCoreApplication.translate(context, string)