mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-27 00:33:48 -05:00
Prevent changes to files that weren't changed between releases. This eases review of the changes between releases significantly.
254 lines
11 KiB
Python
254 lines
11 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
"""
|
|
***************************************************************************
|
|
OtbAlgorithmsTest.py
|
|
---------------------
|
|
Date : January 2019
|
|
Copyright : (C) 2019 by CNES
|
|
Author : otb att cnes dot fr
|
|
***************************************************************************
|
|
* *
|
|
* 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__ = 'Rashad Kanavath'
|
|
__date__ = 'Janauary 2019'
|
|
__copyright__ = '(C) 2019, CNES'
|
|
|
|
import os
|
|
import sys
|
|
import unittest
|
|
import hashlib
|
|
import shutil
|
|
import nose2
|
|
import tempfile
|
|
from qgis.core import (QgsProcessingParameterNumber,
|
|
QgsApplication,
|
|
QgsRasterLayer,
|
|
QgsMapLayer,
|
|
QgsProject,
|
|
QgsProcessingContext,
|
|
QgsProcessingUtils,
|
|
QgsProcessingFeedback,
|
|
QgsProcessingParameterDefinition)
|
|
from qgis.testing import start_app, unittest
|
|
from processing.core.ProcessingConfig import ProcessingConfig, Setting
|
|
from processing.gui.AlgorithmDialog import AlgorithmDialog
|
|
from processing.gui.BatchAlgorithmDialog import BatchAlgorithmDialog
|
|
from processing.gui.wrappers import *
|
|
from processing.modeler.ModelerParametersDialog import ModelerParametersDialog
|
|
from processing.algs.otb.OtbAlgorithm import OtbAlgorithm
|
|
from processing.algs.otb.OtbAlgorithmProvider import OtbAlgorithmProvider
|
|
from processing.algs.otb.OtbUtils import OtbUtils
|
|
from processing.algs.otb.OtbChoiceWidget import OtbParameterChoice, OtbChoiceWidgetWrapper
|
|
import AlgorithmsTestBase
|
|
|
|
import processing
|
|
OTB_INSTALL_DIR = os.environ.get('OTB_INSTALL_DIR')
|
|
|
|
|
|
class TestOtbAlgorithms(unittest.TestCase, AlgorithmsTestBase.AlgorithmsTest):
|
|
|
|
@staticmethod
|
|
def __input_raster_layer():
|
|
options = QgsRasterLayer.LayerOptions()
|
|
options.loadDefaultStyle = False
|
|
return QgsRasterLayer(os.path.join(AlgorithmsTestBase.processingTestDataPath(), 'raster.tif'),
|
|
"raster_input",
|
|
'gdal',
|
|
options)
|
|
|
|
def test_bug21373_mode_vector(self):
|
|
"""
|
|
This issue is reported on qgis bug tracker: #21373
|
|
This issue is reported on qgis-otb-plugin tracker: #30
|
|
"""
|
|
context = QgsProcessingContext()
|
|
context.setProject(QgsProject.instance())
|
|
feedback = QgsProcessingFeedback()
|
|
parameters = {
|
|
'in': TestOtbAlgorithms.__input_raster_layer(),
|
|
'filter': 'meanshift',
|
|
'mode.vector.out': 'vector.shp'
|
|
}
|
|
alg = OtbAlgorithm('Segmentation', 'Segmentation', os.path.join(self.descrFolder, 'Segmentation.txt'))
|
|
results = alg.processAlgorithm(parameters, context, feedback)
|
|
self.assertDictEqual(results, {'mode.vector.out': 'vector.shp'})
|
|
|
|
def test_bug21373_mode_raster(self):
|
|
"""
|
|
This issue is reported on qgis bug tracker: #21373
|
|
"""
|
|
context = QgsProcessingContext()
|
|
context.setProject(QgsProject.instance())
|
|
feedback = QgsProcessingFeedback()
|
|
parameters = {
|
|
'in': TestOtbAlgorithms.__input_raster_layer(),
|
|
'filter': 'meanshift',
|
|
'mode': 'raster',
|
|
'mode.raster.out': 'raster.tif'
|
|
}
|
|
alg = OtbAlgorithm('Segmentation', 'Segmentation', os.path.join(self.descrFolder, 'Segmentation.txt'))
|
|
results = alg.processAlgorithm(parameters, context, feedback)
|
|
self.assertDictEqual(results, {'mode.raster.out': 'raster.tif'})
|
|
|
|
def test_bug21374_Fail(self):
|
|
"""
|
|
This issue is reported on qgis bug tracker: #21374
|
|
"""
|
|
outdir = tempfile.mkdtemp()
|
|
self.cleanup_paths.append(outdir)
|
|
context = QgsProcessingContext()
|
|
context.setProject(QgsProject.instance())
|
|
feedback = QgsProcessingFeedback()
|
|
parameters = {
|
|
'in': TestOtbAlgorithms.__input_raster_layer(),
|
|
'filter': 'cc',
|
|
'mode.vector.out': os.path.join(outdir, 'vector.shp')
|
|
}
|
|
|
|
alg = OtbAlgorithm('Segmentation', 'Segmentation', os.path.join(self.descrFolder, 'Segmentation.txt'))
|
|
ok, msg = alg.checkParameterValues(parameters, context)
|
|
self.assertFalse(ok, 'Algorithm failed checkParameterValues with result {}'.format(msg))
|
|
|
|
def test_init_algorithms(self):
|
|
"""
|
|
This test will read each otb algorithm in 'algs.txt'
|
|
and creates an instance of OtbAlgorithm and check if it can be executed
|
|
This is done in :class: `OtbAlgorithmProvider` load() method
|
|
"""
|
|
algs_txt = os.path.join(self.descrFolder, 'algs.txt')
|
|
with open(algs_txt) as lines:
|
|
line = lines.readline().strip('\n').strip()
|
|
if line != '' and line.startswith('#'):
|
|
version = line[1:]
|
|
print('version =', version)
|
|
line = lines.readline().strip('\n').strip()
|
|
while line != '' and not line.startswith('#'):
|
|
data = line.split('|')
|
|
descriptionFile = os.path.join(self.descrFolder, str(data[1]) + '.txt')
|
|
alg = OtbAlgorithm(data[0], data[1], descriptionFile)
|
|
self.assertIsInstance(alg, OtbAlgorithm)
|
|
ret, msg = alg.canExecute()
|
|
print("canExecute '{}' - {}".format(alg.id(), ret))
|
|
self.assertEqual(ret, True)
|
|
line = lines.readline().strip('\n').strip()
|
|
|
|
def test_parameterAs_ScriptMode(self):
|
|
"""
|
|
This test will pass an instance of QgsCoordinateReferenceSystem for 'epsg' parameter
|
|
of otb::Rasterization. There is same test in otb_algorithm_tests.yaml which passes
|
|
an instance of str for epsg parameter.
|
|
"""
|
|
outdir = tempfile.mkdtemp()
|
|
self.cleanup_paths.append(outdir)
|
|
|
|
context = QgsProcessingContext()
|
|
context.setProject(QgsProject.instance())
|
|
feedback = QgsProcessingFeedback()
|
|
|
|
vectorFile = os.path.join(AlgorithmsTestBase.processingTestDataPath(), 'polys.gml')
|
|
vectorLayer = QgsProcessingUtils.mapLayerFromString(vectorFile, context)
|
|
parameters = {
|
|
'in': vectorLayer,
|
|
'epsg': QgsCoordinateReferenceSystem('EPSG:4326'),
|
|
'spx': 1.0,
|
|
'spy': 1.0,
|
|
'outputpixeltype': 1,
|
|
'out': os.path.join(outdir, 'raster.tif')
|
|
}
|
|
results = processing.run('otb:Rasterization', parameters, None, feedback)
|
|
result_lyr = QgsProcessingUtils.mapLayerFromString(results['out'], context)
|
|
self.assertTrue(result_lyr.isValid())
|
|
|
|
def test_OTBParameterChoiceExists(self):
|
|
"""
|
|
This test is here to know if we have change `type()` method of :class: `OtbParameterChoice`
|
|
That value is used by Otb when it creates descriptor files. So changes to this string must be test
|
|
in a unit-test.
|
|
"""
|
|
alg_smoothing = OtbAlgorithm('Image Filtering', 'Smoothing', os.path.join(self.descrFolder, 'Smoothing.txt'))
|
|
found = False
|
|
for param in alg_smoothing.parameterDefinitions():
|
|
## print (param.name(), param.type())
|
|
if param.type() == 'OTBParameterChoice':
|
|
found = True
|
|
break
|
|
self.assertEqual(found, True)
|
|
|
|
def test_OTBParameterChoice_Gui(self):
|
|
"""
|
|
This test is similar to GuiTests in processing that is done on other parameter widget in processing
|
|
Main difference is this test uses create_wrapper_from_metadata() rather than create_wrapper_from_class()
|
|
like rest of processing widgets.
|
|
"""
|
|
param = OtbParameterChoice('test')
|
|
|
|
alg = QgsApplication.processingRegistry().createAlgorithmById('otb:Smoothing')
|
|
# algorithm dialog
|
|
dlg = AlgorithmDialog(alg)
|
|
wrapper = WidgetWrapperFactory.create_wrapper_from_metadata(param, dlg)
|
|
self.assertIsNotNone(wrapper)
|
|
self.assertIsInstance(wrapper, OtbChoiceWidgetWrapper)
|
|
self.assertEqual(wrapper.dialog, dlg)
|
|
self.assertIsNotNone(wrapper.widget)
|
|
|
|
alg = QgsApplication.processingRegistry().createAlgorithmById('otb:Smoothing')
|
|
# batch dialog
|
|
dlg = BatchAlgorithmDialog(alg)
|
|
wrapper = WidgetWrapperFactory.create_wrapper_from_metadata(param, dlg)
|
|
self.assertIsNotNone(wrapper)
|
|
self.assertIsInstance(wrapper, OtbChoiceWidgetWrapper)
|
|
self.assertEqual(wrapper.dialog, dlg)
|
|
self.assertIsNotNone(wrapper.widget)
|
|
|
|
alg = QgsApplication.processingRegistry().createAlgorithmById('otb:Smoothing')
|
|
# modeler dialog
|
|
model = QgsProcessingModelAlgorithm()
|
|
dlg = ModelerParametersDialog(alg, model)
|
|
wrapper = WidgetWrapperFactory.create_wrapper_from_metadata(param, dlg)
|
|
self.assertIsNotNone(wrapper)
|
|
self.assertIsInstance(wrapper, OtbChoiceWidgetWrapper)
|
|
self.assertEqual(wrapper.dialog, dlg)
|
|
self.assertIsNotNone(wrapper.widget)
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
start_app()
|
|
from processing.core.Processing import Processing
|
|
Processing.initialize()
|
|
ProcessingConfig.setSettingValue("OTB_ACTIVATE", True)
|
|
ProcessingConfig.setSettingValue(OtbUtils.FOLDER, OTB_INSTALL_DIR)
|
|
ProcessingConfig.setSettingValue(OtbUtils.APP_FOLDER, os.path.join(OTB_INSTALL_DIR, 'lib', 'otb', 'applications'))
|
|
ProcessingConfig.readSettings()
|
|
# Refresh OTB Algorithms after settings are changed.
|
|
for p in QgsApplication.processingRegistry().providers():
|
|
if p.id() == "otb":
|
|
p.refreshAlgorithms()
|
|
cls.descrFolder = os.path.join(OTB_INSTALL_DIR, 'share', 'otb', 'description')
|
|
cls.cleanup_paths = []
|
|
|
|
@classmethod
|
|
def tearDownClass(cls):
|
|
from processing.core.Processing import Processing
|
|
Processing.deinitialize()
|
|
for path in cls.cleanup_paths:
|
|
shutil.rmtree(path)
|
|
|
|
def test_definition_file(self):
|
|
"""
|
|
return name of yaml file containing test definitions
|
|
"""
|
|
print("OTB_INSTALL_DIR = '{}'".format(OTB_INSTALL_DIR))
|
|
return 'otb_algorithm_tests.yaml'
|
|
|
|
|
|
if __name__ == '__main__':
|
|
nose2.main()
|