예제 #1
0
    def validateAppFolders(self, v):
        if not self.isActive():
            return
        if not v:
            self.setActive(False)
            raise ValueError(self.tr('Cannot activate OTB provider'))

        folder = OtbUtils.otbFolder()
        otb_app_dirs = self.appDirs(v)
        if len(otb_app_dirs) < 1:
            self.setActive(False)
            raise ValueError(
                self.tr("'{}' does not exist. OTB provider will be disabled".
                        format(v)))

        #isValid is True if there is atleast one valid otb application is given path
        isValid = False
        descr_folder = self.descrFolder(folder)
        for app_dir in otb_app_dirs:
            if not os.path.exists(app_dir):
                continue
            for otb_app in os.listdir(app_dir):
                if not otb_app.startswith('otbapp_') or \
                    'TestApplication' in otb_app or \
                        'ApplicationExample' in otb_app:
                    continue
                app_name = os.path.basename(otb_app).split('.')[0][7:]
                dfile = os.path.join(descr_folder, app_name + '.txt')
                isValid = True
                if not os.path.exists(dfile):
                    cmdlist = [
                        os.path.join(folder, 'bin',
                                     otb_exe_file('otbQgisDescriptor')),
                        app_name, app_dir, descr_folder + '/'
                    ]
                    commands = ' '.join(cmdlist)
                    QgsMessageLog.logMessage(self.tr(commands),
                                             self.tr('Processing'),
                                             Qgis.Critical)
                    OtbUtils.executeOtb(commands, feedback=None)

        if isValid:
            # if check needed for testsing
            if utils.iface is not None:
                utils.iface.messageBar().pushInfo(
                    "OTB",
                    "OTB provider is activated from '{}'.".format(folder))
        else:
            self.setActive(False)
            raise ValueError(
                self.tr(
                    "No OTB algorithms found in '{}'. OTB will be disabled".
                    format(','.join(otb_app_dirs))))
예제 #2
0
 def createAlgsList(self):
     algs = []
     try:
         folder = OtbUtils.otbFolder()
         alg_names = []
         algs_txt = self.algsFile(folder)
         with open(algs_txt) as lines:
             line = lines.readline().strip('\n').strip()
             if line != '' and line.startswith('#'):
                 line = lines.readline().strip('\n').strip()
             while line != '' and not line.startswith('#'):
                 data = line.split('|')
                 descriptionFile = self.descrFile(folder,
                                                  str(data[1]) + '.txt')
                 group, name = str(data[0]), str(data[1])
                 if name not in alg_names:
                     algs.append(OtbAlgorithm(group, name, descriptionFile))
                     #avoid duplicate algorithms from algs.txt file (possible but rare)
                     alg_names.append(name)
                 line = lines.readline().strip('\n').strip()
     except Exception as e:
         import traceback
         errmsg = "Could not open OTB algorithm from file: \n" + descriptionFile + "\nError:\n" + traceback.format_exc(
         )
         QgsMessageLog.logMessage(self.tr(errmsg), self.tr('Processing'),
                                  Qgis.Critical)
     return algs
예제 #3
0
    def validateAppFolders(self, v):
        if not self.isActive():
            return
        if not v:
            self.setActive(False)
            raise ValueError(self.tr('Cannot activate OTB provider'))

        folder = OtbUtils.otbFolder()
        otb_app_dirs = self.appDirs(v)
        if len(otb_app_dirs) < 1:
            self.setActive(False)
            raise ValueError(self.tr("'{}' does not exist. OTB provider will be disabled".format(v)))

        #isValid is True if there is atleast one valid otb application is given path
        isValid = False
        descr_folder = self.descrFolder(folder)
        for app_dir in otb_app_dirs:
            if not os.path.exists(app_dir):
                continue
            for otb_app in os.listdir(app_dir):
                if not otb_app.startswith('otbapp_') or \
                    'TestApplication' in otb_app or \
                        'ApplicationExample' in otb_app:
                    continue
                app_name = os.path.basename(otb_app).split('.')[0][7:]
                dfile = os.path.join(descr_folder, app_name + '.txt')
                isValid = True
                if not os.path.exists(dfile):
                    cmdlist = [os.path.join(
                        folder, 'bin',
                        otb_exe_file('otbQgisDescriptor')),
                        app_name, app_dir, descr_folder + '/']
                    commands = ' '.join(cmdlist)
                    QgsMessageLog.logMessage(self.tr(commands), self.tr('Processing'), Qgis.Critical)
                    OtbUtils.executeOtb(commands, feedback=None)

        if isValid:
            # if check needed for testsing
            if utils.iface is not None:
                utils.iface.messageBar().pushInfo("OTB", "OTB provider is activated from '{}'.".format(folder))
        else:
            self.setActive(False)
            raise ValueError(self.tr("No OTB algorithms found in '{}'. OTB will be disabled".format(','.join(otb_app_dirs))))
예제 #4
0
 def canBeActivated(self):
     if not self.isActive():
         return False
     folder = OtbUtils.otbFolder()
     if folder and os.path.exists(folder):
         if os.path.isfile(self.algsFile(folder)):
             return True
         utils.iface.messageBar().pushWarning("OTB", "Cannot find '{}'. OTB provider will be disabled".format(self.algsFile(folder)))
     self.setActive(False)
     return False
예제 #5
0
 def canBeActivated(self):
     if not self.isActive():
         return False
     folder = OtbUtils.otbFolder()
     if folder and os.path.exists(folder):
         if os.path.isfile(self.algsFile(folder)):
             return True
         utils.iface.messageBar().pushWarning("OTB", "Cannot find '{}'. OTB provider will be disabled".format(self.algsFile(folder)))
     self.setActive(False)
     return False
예제 #6
0
 def load(self):
     group = self.name()
     ProcessingConfig.settingIcons[group] = self.icon()
     ProcessingConfig.addSetting(
         Setting(group, OtbSettings.ACTIVATE, self.tr('Activate'), True))
     ProcessingConfig.addSetting(
         Setting(group,
                 OtbSettings.FOLDER,
                 self.tr("OTB folder"),
                 OtbUtils.otbFolder(),
                 valuetype=Setting.FOLDER,
                 validator=self.validateOtbFolder))
     ProcessingConfig.addSetting(
         Setting(group,
                 OtbSettings.APP_FOLDER,
                 self.tr("OTB application folder"),
                 OtbUtils.appFolder(),
                 valuetype=Setting.MULTIPLE_FOLDERS,
                 validator=self.validateAppFolders))
     ProcessingConfig.addSetting(
         Setting(group,
                 OtbSettings.SRTM_FOLDER,
                 self.tr("SRTM tiles folder"),
                 OtbUtils.srtmFolder(),
                 valuetype=Setting.FOLDER))
     ProcessingConfig.addSetting(
         Setting(group,
                 OtbSettings.GEOID_FILE,
                 self.tr("Geoid file"),
                 OtbUtils.geoidFile(),
                 valuetype=Setting.FOLDER))
     ProcessingConfig.addSetting(
         Setting(group,
                 OtbSettings.MAX_RAM_HINT,
                 self.tr("Maximum RAM to use"),
                 OtbUtils.maxRAMHint(),
                 valuetype=Setting.STRING))
     ProcessingConfig.addSetting(
         Setting(group,
                 OtbSettings.LOGGER_LEVEL,
                 self.tr("Logger level"),
                 OtbUtils.loggerLevel(),
                 valuetype=Setting.STRING,
                 validator=self.validateLoggerLevel))
     ProcessingConfig.readSettings()
     self.refreshAlgorithms()
     return True
예제 #7
0
 def createAlgsList(self):
     algs = []
     try:
         folder = OtbUtils.otbFolder()
         alg_names = []
         algs_txt = self.algsFile(folder)
         with open(algs_txt) as lines:
             line = lines.readline().strip('\n').strip()
             if line != '' and line.startswith('#'):
                 line = lines.readline().strip('\n').strip()
             while line != '' and not line.startswith('#'):
                 data = line.split('|')
                 descriptionFile = self.descrFile(folder, str(data[1]) + '.txt')
                 group, name = str(data[0]), str(data[1])
                 if name not in alg_names:
                     algs.append(OtbAlgorithm(group, name, descriptionFile))
                     #avoid duplicate algorithms from algs.txt file (possible but rare)
                     alg_names.append(name)
                 line = lines.readline().strip('\n').strip()
     except Exception as e:
         import traceback
         errmsg = "Could not open OTB algorithm from file: \n" + descriptionFile + "\nError:\n" + traceback.format_exc()
         QgsMessageLog.logMessage(self.tr(errmsg), self.tr('Processing'), Qgis.Critical)
     return algs
예제 #8
0
 def load(self):
     group = self.name()
     ProcessingConfig.settingIcons[group] = self.icon()
     ProcessingConfig.addSetting(Setting(group, OtbSettings.ACTIVATE, self.tr('Activate'), True))
     ProcessingConfig.addSetting(Setting(group, OtbSettings.FOLDER,
                                         self.tr("OTB folder"),
                                         OtbUtils.otbFolder(),
                                         valuetype=Setting.FOLDER,
                                         validator=self.validateOtbFolder
                                         ))
     ProcessingConfig.addSetting(Setting(group, OtbSettings.APP_FOLDER,
                                         self.tr("OTB application folder"),
                                         OtbUtils.appFolder(),
                                         valuetype=Setting.MULTIPLE_FOLDERS,
                                         validator=self.validateAppFolders
                                         ))
     ProcessingConfig.addSetting(Setting(group, OtbSettings.SRTM_FOLDER,
                                         self.tr("SRTM tiles folder"),
                                         OtbUtils.srtmFolder(),
                                         valuetype=Setting.FOLDER
                                         ))
     ProcessingConfig.addSetting(Setting(group, OtbSettings.GEOID_FILE,
                                         self.tr("Geoid file"),
                                         OtbUtils.geoidFile(),
                                         valuetype=Setting.FOLDER
                                         ))
     ProcessingConfig.addSetting(Setting(group, OtbSettings.MAX_RAM_HINT,
                                         self.tr("Maximum RAM to use"),
                                         OtbUtils.maxRAMHint(),
                                         valuetype=Setting.STRING
                                         ))
     ProcessingConfig.addSetting(Setting(group, OtbSettings.LOGGER_LEVEL,
                                         self.tr("Logger level"),
                                         OtbUtils.loggerLevel(),
                                         valuetype=Setting.STRING,
                                         validator=self.validateLoggerLevel
                                         ))
     ProcessingConfig.readSettings()
     self.refreshAlgorithms()
     return True
예제 #9
0
    def loadAlgorithms(self):
        if not self.canBeActivated():
            return

        version_file = os.path.join(OtbUtils.otbFolder(), 'share', 'doc', 'otb', 'VERSION')
        if not os.path.isfile(version_file):
            version_file = os.path.join(OtbUtils.otbFolder(), 'VERSION')

        if os.path.isfile(version_file):
            with open(version_file) as vf:
                vlines = vf.readlines()
                vlines = [l.strip() for l in vlines]
                vline = vlines[0]
                if 'OTB Version:' in vline:
                    self.version = vline.split(':')[1].strip()

        QgsMessageLog.logMessage(self.tr("Loading OTB '{}'.".format(self.version)), self.tr('Processing'), Qgis.Info)
        self.algs = self.createAlgsList()
        for a in self.algs:
            self.addAlgorithm(a)
        self.algs = []

        otb_folder = self.normalize_path(OtbUtils.otbFolder())
        otb_app_path_env = os.pathsep.join(self.appDirs(OtbUtils.appFolder()))
        gdal_data_dir = None
        geotiff_csv_dir = None
        otbcli_path = OtbUtils.cliPath()
        try:
            if os.name == 'nt':
                app_vargs = " %*"
                export_cmd = 'SET '
                first_line = ':: Setup environment for OTB package. Generated by QGIS plugin'
                otb_app_launcher = os.path.join(otb_folder, 'bin', 'otbApplicationLauncherCommandLine.exe')
                gdal_data_dir = os.path.join(otb_folder, 'share', 'data')
                geotiff_csv_dir = os.path.join(otb_folder, 'share', 'epsg_csv')
            else:
                app_vargs = " \"$@\""
                export_cmd = 'export '
                first_line = '#!/bin/sh'
                otb_app_launcher = os.path.join(otb_folder, 'bin', 'otbApplicationLauncherCommandLine')
                lines = None
                env_profile = os.path.join(otb_folder, 'otbenv.profile')
                if os.path.exists(env_profile):
                    with open(env_profile) as f:
                        lines = f.readlines()
                        lines = [x.strip() for x in lines]
                        for line in lines:
                            if not line or line.startswith('#'):
                                continue
                            if 'GDAL_DATA=' in line:
                                gdal_data_dir = line.split("GDAL_DATA=")[1]
                            if 'GEOTIFF_CSV='in line:
                                geotiff_csv_dir = line.split("GEOTIFF_CSV=")[1]
            with open(otbcli_path, 'w') as otb_cli_file:
                otb_cli_file.write(first_line + os.linesep)
                otb_cli_file.write(export_cmd + "LC_NUMERIC=C" + os.linesep)
                otb_cli_file.write(export_cmd + "GDAL_DRIVER_PATH=disable" + os.linesep)
                if gdal_data_dir:
                    otb_cli_file.write(export_cmd + "GDAL_DATA=" + "\"" + gdal_data_dir + "\"" + os.linesep)
                if geotiff_csv_dir:
                    otb_cli_file.write(export_cmd + "GEOTIFF_CSV=" + "\"" + geotiff_csv_dir + "\"" + os.linesep)
                if OtbUtils.loggerLevel():
                    otb_cli_file.write(export_cmd + "OTB_LOGGER_LEVEL=" + OtbUtils.loggerLevel() + os.linesep)
                max_ram_hint = OtbUtils.maxRAMHint()
                if max_ram_hint and not int(max_ram_hint) == 128:
                    otb_cli_file.write(export_cmd + "OTB_MAX_RAM_HINT=" + max_ram_hint + os.linesep)
                otb_cli_file.write(export_cmd + "OTB_APPLICATION_PATH=" + "\"" + otb_app_path_env + "\"" + os.linesep)
                otb_cli_file.write("\"" + otb_app_launcher + "\"" + app_vargs + os.linesep)

            if not os.name == 'nt':
                os.chmod(otbcli_path, 0o744)
        except BaseException as e:
            import traceback
            os.remove(otbcli_path)
            errmsg = "Cannot write:" + otbcli_path + "\nError:\n" + traceback.format_exc()
            QgsMessageLog.logMessage(self.tr(errmsg), self.tr('Processing'), Qgis.Critical)
            raise e
        QgsMessageLog.logMessage(self.tr("Using otbcli: '{}'.".format(otbcli_path)), self.tr('Processing'), Qgis.Info)
예제 #10
0
    def processAlgorithm(self, parameters, context, feedback):
        otb_cli_file = OtbUtils.cliPath()
        command = '"{}" {} {}'.format(otb_cli_file, self.name(),
                                      OtbUtils.appFolder())
        outputPixelType = None
        for k, v in parameters.items():
            # if value is None for a parameter we don't have any businees with this key
            if v is None:
                continue
            # for 'outputpixeltype' parameter we find the pixeltype string from self.pixelTypes
            if k == 'outputpixeltype':
                pixel_type = self.pixelTypes[int(
                    parameters['outputpixeltype'])]
                outputPixelType = None if pixel_type == 'float' else pixel_type
                continue

            param = self.parameterDefinition(k)
            if param.isDestination():
                continue
            if isinstance(param, QgsProcessingParameterEnum):
                value = self.parameterAsEnum(parameters, param.name(), context)
            elif isinstance(param, QgsProcessingParameterBoolean):
                value = self.parameterAsBool(parameters, param.name(), context)
            elif isinstance(param, QgsProcessingParameterCrs):
                crsValue = self.parameterAsCrs(parameters, param.name(),
                                               context)
                authid = crsValue.authid()
                if authid.startswith('EPSG:'):
                    value = authid.split('EPSG:')[1]
                else:
                    raise QgsProcessingException(
                        self.
                        tr("Incorrect value for parameter '{}'. No EPSG code found in '{}'"
                           .format(param.name(), authid)))
            elif isinstance(param, QgsProcessingParameterFile):
                value = self.parameterAsFile(parameters, param.name(), context)
            elif isinstance(param, QgsProcessingParameterMultipleLayers):
                layers = self.parameterAsLayerList(parameters, param.name(),
                                                   context)
                if layers is None or len(layers) == 0:
                    continue
                value = ' '.join([
                    '"{}"'.format(self.getLayerSource(param.name(), layer))
                    for layer in layers
                ])
            elif isinstance(param, QgsProcessingParameterNumber):
                if param.dataType() == QgsProcessingParameterNumber.Integer:
                    value = self.parameterAsInt(parameters, param.name(),
                                                context)
                else:
                    value = self.parameterAsDouble(parameters, param.name(),
                                                   context)
            elif isinstance(param, (QgsProcessingParameterRasterLayer,
                                    QgsProcessingParameterVectorLayer)):
                value = '"{}"'.format(
                    self.getLayerSource(
                        param.name(),
                        self.parameterAsLayer(parameters, param.name(),
                                              context)))
            elif isinstance(param, QgsProcessingParameterString):
                value = '"{}"'.format(
                    self.parameterAsString(parameters, param.name(), context))
            else:
                # Use whatever is given
                value = '"{}"'.format(parameters[param.name()])

            # Check if value is set in above if elif ladder and update command string
            if value and value is not None:
                command += ' -{} {}'.format(k, value)

        output_files = {}

        for out in self.destinationParameterDefinitions():
            filePath = self.parameterAsOutputLayer(parameters, out.name(),
                                                   context)
            output_files[out.name()] = filePath
            if outputPixelType is not None:
                command += ' -{} "{}" "{}"'.format(out.name(), filePath,
                                                   outputPixelType)
            else:
                command += ' -{} "{}"'.format(out.name(), filePath)

        QgsMessageLog.logMessage(self.tr('cmd={}'.format(command)),
                                 self.tr('Processing'), Qgis.Info)
        if not os.path.exists(otb_cli_file) or not os.path.isfile(
                otb_cli_file):
            import errno
            raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT),
                                    otb_cli_file)

        OtbUtils.executeOtb(command, feedback)

        result = {}
        for o in self.outputDefinitions():
            if o.name() in output_files:
                result[o.name()] = output_files[o.name()]
        return result
예제 #11
0
    def defineCharacteristicsFromFile(self):
        line = None
        try:
            with open(self._descriptionfile) as lines:
                line = lines.readline().strip('\n').strip()
                self._name = line.split('|')[0]
                self.appkey = self._name
                line = lines.readline().strip('\n').strip()
                self.doc = line
                self.i18n_doc = QCoreApplication.translate(
                    "OtbAlgorithm", self.doc)
                #self._name = self._name #+ " - " + self.doc
                self._display_name = self.tr(self._name)
                self.i18n_name = QCoreApplication.translate(
                    "OtbAlgorithm", self._name)

                line = lines.readline().strip('\n').strip()
                self._group = line
                self.i18n_group = QCoreApplication.translate(
                    "OtbAlgorithm", self._group)
                line = lines.readline().strip('\n').strip()
                while line != '':
                    line = line.strip('\n').strip()
                    if line.startswith('#'):
                        line = lines.readline().strip('\n').strip()
                        continue
                    param = None
                    if 'OTBParameterChoice' in line:
                        tokens = line.split("|")
                        params = [
                            t if str(t) != str(None) else None
                            for t in tokens[1:]
                        ]
                        options = params[2].split(';')
                        param = OtbParameterChoice(params[0], params[1],
                                                   options, params[3],
                                                   params[4])
                    else:
                        param = getParameterFromString(line)

                    #if parameter is None, then move to next line and continue
                    if param is None:
                        line = lines.readline().strip('\n').strip()
                        continue

                    name = param.name()
                    if '.' in name and len(name.split('.')) > 2:
                        p = name.split('.')[:-2]
                        group_key = '.'.join(p)
                        group_value = name.split('.')[-2]
                        metadata = param.metadata()
                        metadata['group_key'] = group_key
                        metadata['group_value'] = group_value
                        param.setMetadata(metadata)

                    #'elev.dem.path', 'elev.dem', 'elev.dem.geoid', 'elev.geoid' are special!
                    #Even though it is not typical for OTB to fix on parameter keys,
                    #we current use below !hack! to set SRTM path and GEOID files
                    #Future releases of OTB must follow this rule keep
                    #compatibility or update this checklist.
                    if name in ["elev.dem.path", "elev.dem"]:
                        param.setDefaultValue(OtbUtils.srtmFolder())
                    if name in ["elev.dem.geoid", "elev.geoid"]:
                        param.setDefaultValue(OtbUtils.geoidFile())

                    # outputpixeltype is a special parameter associated with raster output
                    # reset list of options to 'self.pixelTypes'.
                    if name == 'outputpixeltype':
                        param.setOptions(self.pixelTypes)
                        param.setDefaultValue(self.pixelTypes.index('float'))

                    self.addParameter(param)
                    #parameter is added now and we must move to next line
                    line = lines.readline().strip('\n').strip()

        except BaseException as e:
            import traceback
            errmsg = "Could not open OTB algorithm from file: \n" + self._descriptionfile + "\nline=" + line + "\nError:\n" + traceback.format_exc(
            )
            QgsMessageLog.logMessage(self.tr(errmsg), self.tr('Processing'),
                                     Qgis.Critical)
            raise e
예제 #12
0
    def loadAlgorithms(self):
        if not self.canBeActivated():
            return

        version_file = os.path.join(OtbUtils.otbFolder(), 'share', 'doc',
                                    'otb', 'VERSION')
        if not os.path.isfile(version_file):
            version_file = os.path.join(OtbUtils.otbFolder(), 'VERSION')

        if os.path.isfile(version_file):
            with open(version_file) as vf:
                vlines = vf.readlines()
                vlines = [l.strip() for l in vlines]
                vline = vlines[0]
                if 'OTB Version:' in vline:
                    self.version = vline.split(':')[1].strip()

        QgsMessageLog.logMessage(
            self.tr("Loading OTB '{}'.".format(self.version)),
            self.tr('Processing'), Qgis.Info)
        self.algs = self.createAlgsList()
        for a in self.algs:
            self.addAlgorithm(a)
        self.algs = []

        otb_folder = self.normalize_path(OtbUtils.otbFolder())
        otb_app_path_env = os.pathsep.join(self.appDirs(OtbUtils.appFolder()))
        gdal_data_dir = None
        geotiff_csv_dir = None
        otbcli_path = OtbUtils.cliPath()
        try:
            if os.name == 'nt':
                app_vargs = " %*"
                export_cmd = 'SET '
                first_line = ':: Setup environment for OTB package. Generated by QGIS plugin'
                otb_app_launcher = os.path.join(
                    otb_folder, 'bin', 'otbApplicationLauncherCommandLine.exe')
                gdal_data_dir = os.path.join(otb_folder, 'share', 'data')
                geotiff_csv_dir = os.path.join(otb_folder, 'share', 'epsg_csv')
            else:
                app_vargs = " \"$@\""
                export_cmd = 'export '
                first_line = '#!/bin/sh'
                otb_app_launcher = os.path.join(
                    otb_folder, 'bin', 'otbApplicationLauncherCommandLine')
                lines = None
                env_profile = os.path.join(otb_folder, 'otbenv.profile')
                if os.path.exists(env_profile):
                    with open(env_profile) as f:
                        lines = f.readlines()
                        lines = [x.strip() for x in lines]
                        for line in lines:
                            if not line or line.startswith('#'):
                                continue
                            if 'GDAL_DATA=' in line:
                                gdal_data_dir = line.split("GDAL_DATA=")[1]
                            if 'GEOTIFF_CSV=' in line:
                                geotiff_csv_dir = line.split("GEOTIFF_CSV=")[1]
            with open(otbcli_path, 'w') as otb_cli_file:
                otb_cli_file.write(first_line + os.linesep)
                otb_cli_file.write(export_cmd + "LC_NUMERIC=C" + os.linesep)
                otb_cli_file.write(export_cmd + "GDAL_DRIVER_PATH=disable" +
                                   os.linesep)
                if gdal_data_dir:
                    otb_cli_file.write(export_cmd + "GDAL_DATA=" + "\"" +
                                       gdal_data_dir + "\"" + os.linesep)
                if geotiff_csv_dir:
                    otb_cli_file.write(export_cmd + "GEOTIFF_CSV=" + "\"" +
                                       geotiff_csv_dir + "\"" + os.linesep)
                if OtbUtils.loggerLevel():
                    otb_cli_file.write(export_cmd + "OTB_LOGGER_LEVEL=" +
                                       OtbUtils.loggerLevel() + os.linesep)
                max_ram_hint = OtbUtils.maxRAMHint()
                if max_ram_hint and not int(max_ram_hint) == 128:
                    otb_cli_file.write(export_cmd + "OTB_MAX_RAM_HINT=" +
                                       max_ram_hint + os.linesep)
                otb_cli_file.write(export_cmd + "OTB_APPLICATION_PATH=" +
                                   "\"" + otb_app_path_env + "\"" + os.linesep)
                otb_cli_file.write("\"" + otb_app_launcher + "\"" + app_vargs +
                                   os.linesep)

            if not os.name == 'nt':
                os.chmod(otbcli_path, 0o744)
        except BaseException as e:
            import traceback
            os.remove(otbcli_path)
            errmsg = "Cannot write:" + otbcli_path + "\nError:\n" + traceback.format_exc(
            )
            QgsMessageLog.logMessage(self.tr(errmsg), self.tr('Processing'),
                                     Qgis.Critical)
            raise e
        QgsMessageLog.logMessage(
            self.tr("Using otbcli: '{}'.".format(otbcli_path)),
            self.tr('Processing'), Qgis.Info)
예제 #13
0
    def processAlgorithm(self, parameters, context, feedback):
        otb_cli_file = OtbUtils.cliPath()
        command = '"{}" {} {}'.format(otb_cli_file, self.name(), OtbUtils.appFolder())
        outputPixelType = None
        for k, v in parameters.items():
            # if value is None for a parameter we don't have any businees with this key
            if v is None:
                continue
            # for 'outputpixeltype' parameter we find the pixeltype string from self.pixelTypes
            if k == 'outputpixeltype':
                pixel_type = self.pixelTypes[int(parameters['outputpixeltype'])]
                outputPixelType = None if pixel_type == 'float' else pixel_type
                continue

            param = self.parameterDefinition(k)
            if param.isDestination():
                continue
            if isinstance(param, QgsProcessingParameterEnum):
                value = self.parameterAsEnum(parameters, param.name(), context)
            elif isinstance(param, QgsProcessingParameterBoolean):
                value = self.parameterAsBool(parameters, param.name(), context)
            elif isinstance(param, QgsProcessingParameterCrs):
                crsValue = self.parameterAsCrs(parameters, param.name(), context)
                authid = crsValue.authid()
                if authid.startswith('EPSG:'):
                    value = authid.split('EPSG:')[1]
                else:
                    raise QgsProcessingException(
                        self.tr("Incorrect value for parameter '{}'. No EPSG code found in '{}'".format(
                            param.name(),
                            authid)))
            elif isinstance(param, QgsProcessingParameterFile):
                value = self.parameterAsFile(parameters, param.name(), context)
            elif isinstance(param, QgsProcessingParameterMultipleLayers):
                layers = self.parameterAsLayerList(parameters, param.name(), context)
                if layers is None or len(layers) == 0:
                    continue
                value = ' '.join(['"{}"'.format(self.getLayerSource(param.name(), layer)) for layer in layers])
            elif isinstance(param, QgsProcessingParameterNumber):
                if param.dataType() == QgsProcessingParameterNumber.Integer:
                    value = self.parameterAsInt(parameters, param.name(), context)
                else:
                    value = self.parameterAsDouble(parameters, param.name(), context)
            elif isinstance(param, (QgsProcessingParameterRasterLayer, QgsProcessingParameterVectorLayer)):
                value = '"{}"'.format(self.getLayerSource(param.name(), self.parameterAsLayer(parameters, param.name(), context)))
            elif isinstance(param, QgsProcessingParameterString):
                value = '"{}"'.format(self.parameterAsString(parameters, param.name(), context))
            else:
                # Use whatever is given
                value = '"{}"'.format(parameters[param.name()])

            # Check if value is set in above if elif ladder and update command string
            if value and value is not None:
                command += ' -{} {}'.format(k, value)

        output_files = {}

        for out in self.destinationParameterDefinitions():
            filePath = self.parameterAsOutputLayer(parameters, out.name(), context)
            output_files[out.name()] = filePath
            if outputPixelType is not None:
                command += ' -{} "{}" "{}"'.format(out.name(), filePath, outputPixelType)
            else:
                command += ' -{} "{}"'.format(out.name(), filePath)

        QgsMessageLog.logMessage(self.tr('cmd={}'.format(command)), self.tr('Processing'), Qgis.Info)
        if not os.path.exists(otb_cli_file) or not os.path.isfile(otb_cli_file):
            import errno
            raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT), otb_cli_file)

        OtbUtils.executeOtb(command, feedback)

        result = {}
        for o in self.outputDefinitions():
            if o.name() in output_files:
                result[o.name()] = output_files[o.name()]
        return result
예제 #14
0
    def defineCharacteristicsFromFile(self):
        line = None
        try:
            with open(self._descriptionfile) as lines:
                line = lines.readline().strip('\n').strip()
                self._name = line.split('|')[0]
                self.appkey = self._name
                line = lines.readline().strip('\n').strip()
                self.doc = line
                self.i18n_doc = QCoreApplication.translate("OtbAlgorithm", self.doc)
                #self._name = self._name #+ " - " + self.doc
                self._display_name = self.tr(self._name)
                self.i18n_name = QCoreApplication.translate("OtbAlgorithm", self._name)

                line = lines.readline().strip('\n').strip()
                self._group = line
                self.i18n_group = QCoreApplication.translate("OtbAlgorithm", self._group)
                line = lines.readline().strip('\n').strip()
                while line != '':
                    line = line.strip('\n').strip()
                    if line.startswith('#'):
                        line = lines.readline().strip('\n').strip()
                        continue
                    param = None
                    if 'OTBParameterChoice' in line:
                        tokens = line.split("|")
                        params = [t if str(t) != str(None) else None for t in tokens[1:]]
                        options = params[2].split(';')
                        param = OtbParameterChoice(params[0], params[1], options, params[3], params[4])
                    else:
                        param = getParameterFromString(line)

                    #if parameter is None, then move to next line and continue
                    if param is None:
                        line = lines.readline().strip('\n').strip()
                        continue

                    name = param.name()
                    if '.' in name and len(name.split('.')) > 2:
                        p = name.split('.')[:-2]
                        group_key = '.'.join(p)
                        group_value = name.split('.')[-2]
                        metadata = param.metadata()
                        metadata['group_key'] = group_key
                        metadata['group_value'] = group_value
                        param.setMetadata(metadata)

                    #'elev.dem.path', 'elev.dem', 'elev.dem.geoid', 'elev.geoid' are special!
                    #Even though it is not typical for OTB to fix on parameter keys,
                    #we current use below !hack! to set SRTM path and GEOID files
                    #Future releases of OTB must follow this rule keep
                    #compatibility or update this checklist.
                    if name in ["elev.dem.path", "elev.dem"]:
                        param.setDefaultValue(OtbUtils.srtmFolder())
                    if name in ["elev.dem.geoid", "elev.geoid"]:
                        param.setDefaultValue(OtbUtils.geoidFile())

                    # outputpixeltype is a special parameter associated with raster output
                    # reset list of options to 'self.pixelTypes'.
                    if name == 'outputpixeltype':
                        param.setOptions(self.pixelTypes)
                        param.setDefaultValue(self.pixelTypes.index('float'))

                    self.addParameter(param)
                    #parameter is added now and we must move to next line
                    line = lines.readline().strip('\n').strip()

        except BaseException as e:
            import traceback
            errmsg = "Could not open OTB algorithm from file: \n" + self._descriptionfile + "\nline=" + line + "\nError:\n" + traceback.format_exc()
            QgsMessageLog.logMessage(self.tr(errmsg), self.tr('Processing'), Qgis.Critical)
            raise e