Skip to content

Commit

Permalink
Merge pull request #2669 from volaya/otb_version
Browse files Browse the repository at this point in the history
[processing] improved version detection mechanism for OTB
  • Loading branch information
volaya committed Jan 15, 2016
2 parents df27c07 + b68ee3d commit 0b96621
Show file tree
Hide file tree
Showing 243 changed files with 158 additions and 127 deletions.
15 changes: 6 additions & 9 deletions python/plugins/processing/algs/otb/OTBAlgorithm.py
Expand Up @@ -43,7 +43,7 @@
from processing.core.ProcessingLog import ProcessingLog
from processing.core.parameters import getParameterFromString
from processing.core.outputs import getOutputFromString
from OTBUtils import OTBUtils
import OTBUtils
from processing.core.parameters import ParameterExtent
from processing.tools.system import getTempFilename
import xml.etree.ElementTree as ET
Expand Down Expand Up @@ -77,7 +77,11 @@ def getIcon(self):
return QIcon(os.path.join(pluginPath, 'images', 'otb.png'))

def help(self):
folder = os.path.join(OTBUtils.otbDescriptionPath(), 'doc')
version = OTBUtils.getInstalledVersion()
folder = OTBUtils.compatibleDescriptionPath(version)
if folder is None:
return False, None
folder = os.path.join(folder, 'doc')
helpfile = os.path.join(unicode(folder), self.appkey + ".html")
if os.path.exists(helpfile):
return False, helpfile
Expand Down Expand Up @@ -166,16 +170,9 @@ def defineCharacteristicsFromFile(self):
self.tr('Could not open OTB algorithm: %s\n%s' % (self.descriptionFile, line)))
raise e

def checkBeforeOpeningParametersDialog(self):
return OTBUtils.checkOtbConfiguration()

def processAlgorithm(self, progress):
currentOs = os.name

msg = OTBUtils.checkOtbConfiguration()
if msg:
raise GeoAlgorithmExecutionException(msg)

path = OTBUtils.otbPath()

commands = []
Expand Down
25 changes: 15 additions & 10 deletions python/plugins/processing/algs/otb/OTBAlgorithmProvider.py
Expand Up @@ -32,7 +32,7 @@
from PyQt4.QtGui import QIcon
from processing.core.AlgorithmProvider import AlgorithmProvider
from processing.core.ProcessingConfig import ProcessingConfig, Setting
from OTBUtils import OTBUtils
import OTBUtils
from OTBAlgorithm import OTBAlgorithm
from processing.core.ProcessingLog import ProcessingLog

Expand All @@ -45,7 +45,6 @@ class OTBAlgorithmProvider(AlgorithmProvider):
def __init__(self):
AlgorithmProvider.__init__(self)
self.activate = True
self.createAlgsList()

def getDescription(self):
return self.tr("Orfeo Toolbox (Image analysis)")
Expand All @@ -57,18 +56,27 @@ def getIcon(self):
return QIcon(os.path.join(pluginPath, 'images', 'otb.png'))

def _loadAlgorithms(self):
self.algs = self.preloadedAlgs
self.algs = []

version = OTBUtils.getInstalledVersion(True)
if version is None:
ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,
self.tr('Problem with OTB installation: OTB was not found or is not correctly installed'))
return

folder = OTBUtils.compatibleDescriptionPath(version)
if folder is None:
ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,
self.tr('Problem with OTB installation: installed OTB version (%s) is not supported' % version))
return

def createAlgsList(self):
self.preloadedAlgs = []
folder = OTBUtils.otbDescriptionPath()
for descriptionFile in os.listdir(folder):
if descriptionFile.endswith("xml"):
try:
alg = OTBAlgorithm(os.path.join(folder, descriptionFile))

if alg.name.strip() != "":
self.preloadedAlgs.append(alg)
self.algs.append(alg)
else:
ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,
self.tr("Could not open OTB algorithm: %s" % descriptionFile))
Expand Down Expand Up @@ -101,6 +109,3 @@ def unload(self):
AlgorithmProvider.unload(self)
ProcessingConfig.removeSetting(OTBUtils.OTB_FOLDER)
ProcessingConfig.removeSetting(OTBUtils.OTB_LIB_FOLDER)

def canBeActivated(self):
return not bool(OTBUtils.checkOtbConfiguration())
Expand Up @@ -44,7 +44,7 @@

from processing.core.ProcessingConfig import ProcessingConfig

from OTBUtils import OTBUtils
import OTBUtils


def adaptBinaryMorphologicalOperation(commands_list):
Expand Down
240 changes: 134 additions & 106 deletions python/plugins/processing/algs/otb/OTBUtils.py
Expand Up @@ -39,125 +39,153 @@
import logging
import xml.etree.ElementTree as ET
import traceback
from processing.gui.SilentProgress import SilentProgress


class OTBUtils:
OTB_FOLDER = "OTB_FOLDER"
OTB_LIB_FOLDER = "OTB_LIB_FOLDER"
OTB_SRTM_FOLDER = "OTB_SRTM_FOLDER"
OTB_GEOID_FILE = "OTB_GEOID_FILE"

OTB_FOLDER = "OTB_FOLDER"
OTB_LIB_FOLDER = "OTB_LIB_FOLDER"
OTB_SRTM_FOLDER = "OTB_SRTM_FOLDER"
OTB_GEOID_FILE = "OTB_GEOID_FILE"

@staticmethod
def findOtbPath():
folder = None
#try to configure the path automatically
if isMac():
testfolder = os.path.join(unicode(QgsApplication.prefixPath()), "bin")
if os.path.exists(os.path.join(testfolder, "otbcli")):
folder = testfolder
else:
testfolder = "/usr/local/bin"
if os.path.exists(os.path.join(testfolder, "otbcli")):
folder = testfolder
elif isWindows():
testfolder = os.path.join(os.path.dirname(QgsApplication.prefixPath()),
os.pardir, "bin")
if os.path.exists(os.path.join(testfolder, "otbcli.bat")):
folder = testfolder
def findOtbPath():
folder = None
#try to configure the path automatically
if isMac():
testfolder = os.path.join(unicode(QgsApplication.prefixPath()), "bin")
if os.path.exists(os.path.join(testfolder, "otbcli")):
folder = testfolder
else:
testfolder = "/usr/bin"
testfolder = "/usr/local/bin"
if os.path.exists(os.path.join(testfolder, "otbcli")):
folder = testfolder
return folder

@staticmethod
def otbPath():
folder = OTBUtils.findOtbPath()
if folder is None:
folder = ProcessingConfig.getSetting(OTBUtils.OTB_FOLDER)
return folder

@staticmethod
def findOtbLibPath():
folder = None
#try to configure the path automatically
if isMac():
testfolder = os.path.join(unicode(QgsApplication.prefixPath()), "lib/otb/applications")
if os.path.exists(testfolder):
folder = testfolder
else:
testfolder = "/usr/local/lib/otb/applications"
if os.path.exists(testfolder):
folder = testfolder
elif isWindows():
testfolder = os.path.join(os.path.dirname(QgsApplication.prefixPath()), "orfeotoolbox", "applications")
if os.path.exists(testfolder):
folder = testfolder
elif isWindows():
testfolder = os.path.join(os.path.dirname(QgsApplication.prefixPath()),
os.pardir, "bin")
if os.path.exists(os.path.join(testfolder, "otbcli.bat")):
folder = testfolder
else:
testfolder = "/usr/bin"
if os.path.exists(os.path.join(testfolder, "otbcli")):
folder = testfolder
return folder


def otbPath():
folder = findOtbPath()
if folder is None:
folder = ProcessingConfig.getSetting(OTB_FOLDER)
return folder


def findOtbLibPath():
folder = None
#try to configure the path automatically
if isMac():
testfolder = os.path.join(unicode(QgsApplication.prefixPath()), "lib/otb/applications")
if os.path.exists(testfolder):
folder = testfolder
else:
testfolder = "/usr/lib/otb/applications"
testfolder = "/usr/local/lib/otb/applications"
if os.path.exists(testfolder):
folder = testfolder
return folder

@staticmethod
def otbLibPath():
folder = OTBUtils.findOtbLibPath()
if folder is None:
folder = ProcessingConfig.getSetting(OTBUtils.OTB_LIB_FOLDER)
return folder

@staticmethod
def otbSRTMPath():
folder = ProcessingConfig.getSetting(OTBUtils.OTB_SRTM_FOLDER)
if folder is None:
folder = ""
return folder

@staticmethod
def otbGeoidPath():
filepath = ProcessingConfig.getSetting(OTBUtils.OTB_GEOID_FILE)
if filepath is None:
filepath = ""
return filepath

@staticmethod
def otbDescriptionPath():
return os.path.join(os.path.dirname(__file__), "description")

@staticmethod
def executeOtb(commands, progress):
loglines = []
loglines.append(OTBUtils.tr("OTB execution console output"))
os.putenv('ITK_AUTOLOAD_PATH', OTBUtils.otbLibPath())
fused_command = ''.join(['"%s" ' % re.sub(r'^"|"$', '', c) for c in commands])
proc = subprocess.Popen(fused_command, shell=True, stdout=subprocess.PIPE, stdin=open(os.devnull), stderr=subprocess.STDOUT, universal_newlines=True).stdout
for line in iter(proc.readline, ""):
if "[*" in line:
idx = line.find("[*")
perc = int(line[idx - 4:idx - 2].strip(" "))
if perc != 0:
progress.setPercentage(perc)
else:
loglines.append(line)
progress.setConsoleInfo(line)
elif isWindows():
testfolder = os.path.join(os.path.dirname(QgsApplication.prefixPath()), "orfeotoolbox", "applications")
if os.path.exists(testfolder):
folder = testfolder
else:
testfolder = "/usr/lib/otb/applications"
if os.path.exists(testfolder):
folder = testfolder
return folder


def otbLibPath():
folder = findOtbLibPath()
if folder is None:
folder = ProcessingConfig.getSetting(OTB_LIB_FOLDER)
return folder


def otbSRTMPath():
folder = ProcessingConfig.getSetting(OTB_SRTM_FOLDER)
if folder is None:
folder = ""
return folder


def otbGeoidPath():
filepath = ProcessingConfig.getSetting(OTB_GEOID_FILE)
if filepath is None:
filepath = ""
return filepath


def otbDescriptionPath():
return os.path.join(os.path.dirname(__file__), "description")

_installedVersion = None
_installedVersionFound = False


def getInstalledVersion(runOtb=False):
global _installedVersion
global _installedVersionFound

if _installedVersionFound and not runOtb:
return _installedVersion

commands = [os.path.join(otbPath(), "