1# -*- coding: utf-8 -*- 2 3""" 4*************************************************************************** 5 SagaAlgorithmProvider.py 6 --------------------- 7 Date : August 2012 8 Copyright : (C) 2012 by Victor Olaya 9 Email : volayaf 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__ = 'Victor Olaya' 21__date__ = 'August 2012' 22__copyright__ = '(C) 2012, Victor Olaya' 23 24import os 25from qgis.PyQt.QtGui import QIcon 26from qgis.PyQt.QtCore import QCoreApplication 27from qgis.core import (Qgis, 28 QgsProcessingProvider, 29 QgsProcessingUtils, 30 QgsApplication, 31 QgsMessageLog, 32 QgsRuntimeProfiler) 33from processing.core.ProcessingConfig import ProcessingConfig, Setting 34from processing.tools.system import isWindows, isMac 35 36from .SagaAlgorithm import SagaAlgorithm 37from .SplitRGBBands import SplitRGBBands 38from . import SagaUtils 39 40pluginPath = os.path.normpath(os.path.join( 41 os.path.split(os.path.dirname(__file__))[0], os.pardir)) 42 43REQUIRED_VERSION = '2.3.' 44BETA_SUPPORT_VERSION = '7.' 45 46 47class SagaAlgorithmProvider(QgsProcessingProvider): 48 49 def __init__(self): 50 super().__init__() 51 self.algs = [] 52 53 def load(self): 54 with QgsRuntimeProfiler.profile('SAGA Provider'): 55 ProcessingConfig.settingIcons[self.name()] = self.icon() 56 ProcessingConfig.addSetting(Setting("SAGA", 'ACTIVATE_SAGA', 57 self.tr('Activate'), True)) 58 ProcessingConfig.addSetting(Setting("SAGA", 59 SagaUtils.SAGA_IMPORT_EXPORT_OPTIMIZATION, 60 self.tr('Enable SAGA Import/Export optimizations'), False)) 61 ProcessingConfig.addSetting(Setting("SAGA", 62 SagaUtils.SAGA_LOG_COMMANDS, 63 self.tr('Log execution commands'), True)) 64 ProcessingConfig.addSetting(Setting("SAGA", 65 SagaUtils.SAGA_LOG_CONSOLE, 66 self.tr('Log console output'), True)) 67 ProcessingConfig.readSettings() 68 self.refreshAlgorithms() 69 70 return True 71 72 def unload(self): 73 ProcessingConfig.removeSetting('ACTIVATE_SAGA') 74 ProcessingConfig.removeSetting(SagaUtils.SAGA_LOG_CONSOLE) 75 ProcessingConfig.removeSetting(SagaUtils.SAGA_LOG_COMMANDS) 76 77 def isActive(self): 78 return ProcessingConfig.getSetting('ACTIVATE_SAGA') 79 80 def setActive(self, active): 81 ProcessingConfig.setSettingValue('ACTIVATE_SAGA', active) 82 83 def canBeActivated(self): 84 version = SagaUtils.getInstalledVersion(True) 85 if version is not None and (version.startswith(REQUIRED_VERSION) or version >= BETA_SUPPORT_VERSION): 86 return True 87 return False 88 89 def warningMessage(self): 90 version = SagaUtils.getInstalledVersion(True) 91 if version is not None and version >= BETA_SUPPORT_VERSION: 92 return self.tr('SAGA version {} is not officially supported - algorithms may encounter issues').format(version) 93 return '' 94 95 def loadAlgorithms(self): 96 version = SagaUtils.getInstalledVersion(True) 97 if version is None: 98 QgsMessageLog.logMessage(self.tr('Problem with SAGA installation: SAGA was not found or is not correctly installed'), 99 self.tr('Processing'), Qgis.Critical) 100 return 101 102 if not version.startswith(REQUIRED_VERSION) and not version >= BETA_SUPPORT_VERSION: 103 QgsMessageLog.logMessage(self.tr('Problem with SAGA installation: unsupported SAGA version (found: {}, required: {}).').format(version, REQUIRED_VERSION), 104 self.tr('Processing'), 105 Qgis.Critical) 106 return 107 108 self.algs = [] 109 folder = SagaUtils.sagaDescriptionPath() 110 for descriptionFile in os.listdir(folder): 111 if descriptionFile.endswith('txt'): 112 try: 113 alg = SagaAlgorithm(os.path.join(folder, descriptionFile)) 114 if alg.name().strip() != '': 115 self.algs.append(alg) 116 else: 117 QgsMessageLog.logMessage(self.tr('Could not open SAGA algorithm: {}'.format(descriptionFile)), 118 self.tr('Processing'), Qgis.Critical) 119 except Exception as e: 120 QgsMessageLog.logMessage(self.tr('Could not open SAGA algorithm: {}\n{}'.format(descriptionFile, str(e))), 121 self.tr('Processing'), Qgis.Critical) 122 123 self.algs.append(SplitRGBBands()) 124 for a in self.algs: 125 self.addAlgorithm(a) 126 127 def name(self): 128 return 'SAGA' 129 130 def longName(self): 131 version = SagaUtils.getInstalledVersion() 132 return 'SAGA ({})'.format(version) if version is not None else 'SAGA' 133 134 def id(self): 135 return 'saga' 136 137 def defaultVectorFileExtension(self, hasGeometry=True): 138 return 'shp' if hasGeometry else 'dbf' 139 140 def defaultRasterFileExtension(self): 141 return 'sdat' 142 143 def supportedOutputRasterLayerExtensions(self): 144 return ['sdat'] 145 146 def supportedOutputVectorLayerExtensions(self): 147 return ['shp', 'dbf'] 148 149 def supportedOutputTableExtensions(self): 150 return ['dbf'] 151 152 def flags(self): 153 # push users towards alternative algorithms instead, SAGA algorithms should only be used by experienced 154 # users who understand and can workaround the frequent issues encountered here 155 return QgsProcessingProvider.FlagDeemphasiseSearchResults 156 157 def supportsNonFileBasedOutput(self): 158 """ 159 SAGA Provider doesn't support non file based outputs 160 """ 161 return False 162 163 def icon(self): 164 return QgsApplication.getThemeIcon("/providerSaga.svg") 165 166 def tr(self, string, context=''): 167 if context == '': 168 context = 'SagaAlgorithmProvider' 169 return QCoreApplication.translate(context, string) 170