Skip to content

Commit 864e192

Browse files
committed
[processing] improved version detection mechanism for OTB
1 parent 7a87999 commit 864e192

File tree

243 files changed

+159
-127
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

243 files changed

+159
-127
lines changed

python/plugins/processing/algs/otb/OTBAlgorithm.py

+7-10
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
from processing.core.ProcessingLog import ProcessingLog
4444
from processing.core.parameters import getParameterFromString
4545
from processing.core.outputs import getOutputFromString
46-
from OTBUtils import OTBUtils
46+
import OTBUtils
4747
from processing.core.parameters import ParameterExtent
4848
from processing.tools.system import getTempFilename
4949
import xml.etree.ElementTree as ET
@@ -77,12 +77,16 @@ def getIcon(self):
7777
return QIcon(os.path.join(pluginPath, 'images', 'otb.png'))
7878

7979
def help(self):
80-
folder = os.path.join(OTBUtils.otbDescriptionPath(), 'doc')
80+
version = OTBUtils.getInstalledVersion()
81+
folder = OTBUtils.compatibleDescriptionPath(version)
82+
if folder is None:
83+
return False, None
84+
folder = os.path.join(folder, 'doc')
8185
helpfile = os.path.join(unicode(folder), self.appkey + ".html")
8286
if os.path.exists(helpfile):
8387
return False, helpfile
8488
else:
85-
raise False
89+
return False, None
8690

8791
def adapt_list_to_string(self, c_list):
8892
a_list = c_list[1:]
@@ -166,16 +170,9 @@ def defineCharacteristicsFromFile(self):
166170
self.tr('Could not open OTB algorithm: %s\n%s' % (self.descriptionFile, line)))
167171
raise e
168172

169-
def checkBeforeOpeningParametersDialog(self):
170-
return OTBUtils.checkOtbConfiguration()
171-
172173
def processAlgorithm(self, progress):
173174
currentOs = os.name
174175

175-
msg = OTBUtils.checkOtbConfiguration()
176-
if msg:
177-
raise GeoAlgorithmExecutionException(msg)
178-
179176
path = OTBUtils.otbPath()
180177

181178
commands = []

python/plugins/processing/algs/otb/OTBAlgorithmProvider.py

+17-9
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
from PyQt4.QtGui import QIcon
3333
from processing.core.AlgorithmProvider import AlgorithmProvider
3434
from processing.core.ProcessingConfig import ProcessingConfig, Setting
35-
from OTBUtils import OTBUtils
35+
import OTBUtils
3636
from OTBAlgorithm import OTBAlgorithm
3737
from processing.core.ProcessingLog import ProcessingLog
3838

@@ -45,7 +45,6 @@ class OTBAlgorithmProvider(AlgorithmProvider):
4545
def __init__(self):
4646
AlgorithmProvider.__init__(self)
4747
self.activate = True
48-
self.createAlgsList()
4948

5049
def getDescription(self):
5150
return self.tr("Orfeo Toolbox (Image analysis)")
@@ -57,18 +56,29 @@ def getIcon(self):
5756
return QIcon(os.path.join(pluginPath, 'images', 'otb.png'))
5857

5958
def _loadAlgorithms(self):
60-
self.algs = self.preloadedAlgs
59+
self.algs = []
60+
61+
version = OTBUtils.getInstalledVersion(True)
62+
if version is None:
63+
ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,
64+
self.tr('Problem with OTB installation: OTB was not found or is not correctly installed'))
65+
return
66+
67+
folder = OTBUtils.compatibleDescriptionPath(version)
68+
if folder is None:
69+
ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,
70+
self.tr('Problem with OTB installation: installed OTB version (%s) is not supported' % version))
71+
return
72+
73+
6174

62-
def createAlgsList(self):
63-
self.preloadedAlgs = []
64-
folder = OTBUtils.otbDescriptionPath()
6575
for descriptionFile in os.listdir(folder):
6676
if descriptionFile.endswith("xml"):
6777
try:
6878
alg = OTBAlgorithm(os.path.join(folder, descriptionFile))
6979

7080
if alg.name.strip() != "":
71-
self.preloadedAlgs.append(alg)
81+
self.algs.append(alg)
7282
else:
7383
ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,
7484
self.tr("Could not open OTB algorithm: %s" % descriptionFile))
@@ -102,5 +112,3 @@ def unload(self):
102112
ProcessingConfig.removeSetting(OTBUtils.OTB_FOLDER)
103113
ProcessingConfig.removeSetting(OTBUtils.OTB_LIB_FOLDER)
104114

105-
def canBeActivated(self):
106-
return not bool(OTBUtils.checkOtbConfiguration())

python/plugins/processing/algs/otb/OTBSpecific_XMLLoading.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444

4545
from processing.core.ProcessingConfig import ProcessingConfig
4646

47-
from OTBUtils import OTBUtils
47+
import OTBUtils
4848

4949

5050
def adaptBinaryMorphologicalOperation(commands_list):

python/plugins/processing/algs/otb/OTBUtils.py

+132-106
Original file line numberDiff line numberDiff line change
@@ -39,125 +39,151 @@
3939
import logging
4040
import xml.etree.ElementTree as ET
4141
import traceback
42+
from processing.gui.SilentProgress import SilentProgress
4243

4344

44-
class OTBUtils:
45+
OTB_FOLDER = "OTB_FOLDER"
46+
OTB_LIB_FOLDER = "OTB_LIB_FOLDER"
47+
OTB_SRTM_FOLDER = "OTB_SRTM_FOLDER"
48+
OTB_GEOID_FILE = "OTB_GEOID_FILE"
4549

46-
OTB_FOLDER = "OTB_FOLDER"
47-
OTB_LIB_FOLDER = "OTB_LIB_FOLDER"
48-
OTB_SRTM_FOLDER = "OTB_SRTM_FOLDER"
49-
OTB_GEOID_FILE = "OTB_GEOID_FILE"
5050

51-
@staticmethod
52-
def findOtbPath():
53-
folder = None
54-
#try to configure the path automatically
55-
if isMac():
56-
testfolder = os.path.join(unicode(QgsApplication.prefixPath()), "bin")
57-
if os.path.exists(os.path.join(testfolder, "otbcli")):
58-
folder = testfolder
59-
else:
60-
testfolder = "/usr/local/bin"
61-
if os.path.exists(os.path.join(testfolder, "otbcli")):
62-
folder = testfolder
63-
elif isWindows():
64-
testfolder = os.path.join(os.path.dirname(QgsApplication.prefixPath()),
65-
os.pardir, "bin")
66-
if os.path.exists(os.path.join(testfolder, "otbcli.bat")):
67-
folder = testfolder
51+
def findOtbPath():
52+
folder = None
53+
#try to configure the path automatically
54+
if isMac():
55+
testfolder = os.path.join(unicode(QgsApplication.prefixPath()), "bin")
56+
if os.path.exists(os.path.join(testfolder, "otbcli")):
57+
folder = testfolder
6858
else:
69-
testfolder = "/usr/bin"
59+
testfolder = "/usr/local/bin"
7060
if os.path.exists(os.path.join(testfolder, "otbcli")):
7161
folder = testfolder
72-
return folder
73-
74-
@staticmethod
75-
def otbPath():
76-
folder = OTBUtils.findOtbPath()
77-
if folder is None:
78-
folder = ProcessingConfig.getSetting(OTBUtils.OTB_FOLDER)
79-
return folder
80-
81-
@staticmethod
82-
def findOtbLibPath():
83-
folder = None
84-
#try to configure the path automatically
85-
if isMac():
86-
testfolder = os.path.join(unicode(QgsApplication.prefixPath()), "lib/otb/applications")
87-
if os.path.exists(testfolder):
88-
folder = testfolder
89-
else:
90-
testfolder = "/usr/local/lib/otb/applications"
91-
if os.path.exists(testfolder):
92-
folder = testfolder
93-
elif isWindows():
94-
testfolder = os.path.join(os.path.dirname(QgsApplication.prefixPath()), "orfeotoolbox", "applications")
95-
if os.path.exists(testfolder):
96-
folder = testfolder
62+
elif isWindows():
63+
testfolder = os.path.join(os.path.dirname(QgsApplication.prefixPath()),
64+
os.pardir, "bin")
65+
if os.path.exists(os.path.join(testfolder, "otbcli.bat")):
66+
folder = testfolder
67+
else:
68+
testfolder = "/usr/bin"
69+
if os.path.exists(os.path.join(testfolder, "otbcli")):
70+
folder = testfolder
71+
return folder
72+
73+
74+
def otbPath():
75+
folder = findOtbPath()
76+
if folder is None:
77+
folder = ProcessingConfig.getSetting(OTB_FOLDER)
78+
return folder
79+
80+
81+
def findOtbLibPath():
82+
folder = None
83+
#try to configure the path automatically
84+
if isMac():
85+
testfolder = os.path.join(unicode(QgsApplication.prefixPath()), "lib/otb/applications")
86+
if os.path.exists(testfolder):
87+
folder = testfolder
9788
else:
98-
testfolder = "/usr/lib/otb/applications"
89+
testfolder = "/usr/local/lib/otb/applications"
9990
if os.path.exists(testfolder):
10091
folder = testfolder
101-
return folder
102-
103-
@staticmethod
104-
def otbLibPath():
105-
folder = OTBUtils.findOtbLibPath()
106-
if folder is None:
107-
folder = ProcessingConfig.getSetting(OTBUtils.OTB_LIB_FOLDER)
108-
return folder
109-
110-
@staticmethod
111-
def otbSRTMPath():
112-
folder = ProcessingConfig.getSetting(OTBUtils.OTB_SRTM_FOLDER)
113-
if folder is None:
114-
folder = ""
115-
return folder
116-
117-
@staticmethod
118-
def otbGeoidPath():
119-
filepath = ProcessingConfig.getSetting(OTBUtils.OTB_GEOID_FILE)
120-
if filepath is None:
121-
filepath = ""
122-
return filepath
123-
124-
@staticmethod
125-
def otbDescriptionPath():
126-
return os.path.join(os.path.dirname(__file__), "description")
127-
128-
@staticmethod
129-
def executeOtb(commands, progress):
130-
loglines = []
131-
loglines.append(OTBUtils.tr("OTB execution console output"))
132-
os.putenv('ITK_AUTOLOAD_PATH', OTBUtils.otbLibPath())
133-
fused_command = ''.join(['"%s" ' % re.sub(r'^"|"$', '', c) for c in commands])
134-
proc = subprocess.Popen(fused_command, shell=True, stdout=subprocess.PIPE, stdin=open(os.devnull), stderr=subprocess.STDOUT, universal_newlines=True).stdout
135-
for line in iter(proc.readline, ""):
136-
if "[*" in line:
137-
idx = line.find("[*")
138-
perc = int(line[idx - 4:idx - 2].strip(" "))
139-
if perc != 0:
140-
progress.setPercentage(perc)
141-
else:
142-
loglines.append(line)
143-
progress.setConsoleInfo(line)
92+
elif isWindows():
93+
testfolder = os.path.join(os.path.dirname(QgsApplication.prefixPath()), "orfeotoolbox", "applications")
94+
if os.path.exists(testfolder):
95+
folder = testfolder
96+
else:
97+
testfolder = "/usr/lib/otb/applications"
98+
if os.path.exists(testfolder):
99+
folder = testfolder
100+
return folder
101+
102+
103+
def otbLibPath():
104+
folder = findOtbLibPath()
105+
if folder is None:
106+
folder = ProcessingConfig.getSetting(OTB_LIB_FOLDER)
107+
return folder
108+
109+
110+
def otbSRTMPath():
111+
folder = ProcessingConfig.getSetting(OTB_SRTM_FOLDER)
112+
if folder is None:
113+
folder = ""
114+
return folder
115+
116+
117+
def otbGeoidPath():
118+
filepath = ProcessingConfig.getSetting(OTB_GEOID_FILE)
119+
if filepath is None:
120+
filepath = ""
121+
return filepath
122+
123+
124+
def otbDescriptionPath():
125+
return os.path.join(os.path.dirname(__file__), "description")
126+
127+
_installedVersion = None
128+
_installedVersionFound = False
129+
130+
131+
def getInstalledVersion(runOtb=False):
132+
global _installedVersion
133+
global _installedVersionFound
134+
135+
if _installedVersionFound and not runOtb:
136+
return _installedVersion
137+
138+
commands =[os.path.join(otbPath(), "otbcli_Smoothing")]
139+
progress = SilentProgress()
140+
out = executeOtb(commands, progress, False)
141+
for line in out:
142+
if "version" in line:
143+
_installedVersionFound = True
144+
_installedVersion = line.split("version")[-1].strip()
145+
break
146+
return _installedVersion
147+
148+
def compatibleDescriptionPath(version):
149+
supportedVersions = {"5.0.0": "5.0.0"}
150+
if version is None:
151+
return None
152+
if version not in supportedVersions:
153+
lastVersion = sorted(supportedVersions.keys())[-1]
154+
if version > lastVersion:
155+
version = lastVersion
156+
else:
157+
return None
158+
159+
return os.path.join(otbDescriptionPath(), supportedVersions[version])
160+
161+
def executeOtb(commands, progress, addToLog = True):
162+
loglines = []
163+
loglines.append(tr("OTB execution console output"))
164+
os.putenv('ITK_AUTOLOAD_PATH', otbLibPath())
165+
fused_command = ''.join(['"%s" ' % re.sub(r'^"|"$', '', c) for c in commands])
166+
proc = subprocess.Popen(fused_command, shell=True, stdout=subprocess.PIPE, stdin=open(os.devnull), stderr=subprocess.STDOUT, universal_newlines=True).stdout
167+
for line in iter(proc.readline, ""):
168+
if "[*" in line:
169+
idx = line.find("[*")
170+
perc = int(line[idx - 4:idx - 2].strip(" "))
171+
if perc != 0:
172+
progress.setPercentage(perc)
173+
else:
174+
loglines.append(line)
175+
progress.setConsoleInfo(line)
144176

177+
if addToLog:
145178
ProcessingLog.addToLog(ProcessingLog.LOG_INFO, loglines)
146179

147-
@staticmethod
148-
def checkOtbConfiguration():
149-
path = OTBUtils.otbPath()
150-
libpath = OTBUtils.otbLibPath()
151-
configurationOk = bool(path) and bool(libpath)
152-
if not configurationOk:
153-
return OTBUtils.tr('OTB folder is not configured. Please configure it '
154-
'before running OTB algorithms.')
155-
156-
@staticmethod
157-
def tr(string, context=''):
158-
if context == '':
159-
context = 'OTBUtils'
160-
return QCoreApplication.translate(context, string)
180+
return loglines
181+
182+
183+
def tr(string, context=''):
184+
if context == '':
185+
context = 'OTBUtils'
186+
return QCoreApplication.translate(context, string)
161187

162188

163189
def get_choices_of(doc, parameter):

python/plugins/processing/tests/PackagingTests.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
***************************************************************************
1818
"""
1919

20+
2021
__author__ = 'Victor Olaya'
2122
__date__ = 'May 2015'
2223
__copyright__ = '(C) 2015, Victor Olaya'
@@ -35,7 +36,7 @@
3536
from processing.algs.saga.SagaUtils import *
3637
from processing.core.ProcessingConfig import ProcessingConfig
3738
from processing.algs.grass.GrassUtils import GrassUtils
38-
from processing.algs.otb.OTBUtils import OTBUtils
39+
from processing.algs.otb import OTBUtils
3940

4041

4142
class PackageTests(unittest.TestCase):

0 commit comments

Comments
 (0)