Unverified Commit 72702615 authored by Daniel Scheffler's avatar Daniel Scheffler
Browse files

Revised GUI parameters, added dropdown menus.

parent 4b0ad30f
...@@ -33,16 +33,17 @@ from threading import Thread ...@@ -33,16 +33,17 @@ from threading import Thread
from queue import Queue from queue import Queue
from subprocess import Popen, PIPE from subprocess import Popen, PIPE
from qgis.core import \ from qgis.core import (
(QgsProcessingAlgorithm, QgsProcessingAlgorithm,
QgsProcessingParameterFile, QgsProcessingParameterFile,
QgsProcessingParameterNumber, QgsProcessingParameterNumber,
QgsProcessingParameterFolderDestination, QgsProcessingParameterFolderDestination,
QgsProcessingParameterBoolean, QgsProcessingParameterBoolean,
QgsProcessingParameterString, QgsProcessingParameterString,
QgsProcessingParameterDefinition, QgsProcessingParameterDefinition,
QgsProcessingParameterRasterLayer QgsProcessingParameterRasterLayer,
) QgsProcessingParameterEnum
)
from .version import __version__ from .version import __version__
...@@ -60,7 +61,9 @@ class _EnPTBaseAlgorithm(QgsProcessingAlgorithm): ...@@ -60,7 +61,9 @@ class _EnPTBaseAlgorithm(QgsProcessingAlgorithm):
P_output_dir = 'output_dir' P_output_dir = 'output_dir'
P_working_dir = 'working_dir' P_working_dir = 'working_dir'
P_n_lines_to_append = 'n_lines_to_append' P_n_lines_to_append = 'n_lines_to_append'
P_drop_bad_bands = 'drop_bad_bands'
P_disable_progress_bars = 'disable_progress_bars' P_disable_progress_bars = 'disable_progress_bars'
P_output_format = 'output_format'
P_path_earthSunDist = 'path_earthSunDist' P_path_earthSunDist = 'path_earthSunDist'
P_path_solar_irr = 'path_solar_irr' P_path_solar_irr = 'path_solar_irr'
P_scale_factor_toa_ref = 'scale_factor_toa_ref' P_scale_factor_toa_ref = 'scale_factor_toa_ref'
...@@ -68,9 +71,6 @@ class _EnPTBaseAlgorithm(QgsProcessingAlgorithm): ...@@ -68,9 +71,6 @@ class _EnPTBaseAlgorithm(QgsProcessingAlgorithm):
P_enable_vnir_swir_coreg = 'enable_vnir_swir_coreg' P_enable_vnir_swir_coreg = 'enable_vnir_swir_coreg'
P_path_reference_image = 'path_reference_image' P_path_reference_image = 'path_reference_image'
P_enable_ac = 'enable_ac' P_enable_ac = 'enable_ac'
P_auto_download_ecmwf = 'auto_download_ecmwf'
P_enable_ice_retrieval = 'enable_ice_retrieval'
P_enable_cloud_screening = 'enable_cloud_screening'
P_scale_factor_boa_ref = 'scale_factor_boa_ref' P_scale_factor_boa_ref = 'scale_factor_boa_ref'
P_run_smile_P = 'run_smile_P' P_run_smile_P = 'run_smile_P'
P_run_deadpix_P = 'run_deadpix_P' P_run_deadpix_P = 'run_deadpix_P'
...@@ -79,6 +79,8 @@ class _EnPTBaseAlgorithm(QgsProcessingAlgorithm): ...@@ -79,6 +79,8 @@ class _EnPTBaseAlgorithm(QgsProcessingAlgorithm):
P_deadpix_P_interp_spatial = 'deadpix_P_interp_spatial' P_deadpix_P_interp_spatial = 'deadpix_P_interp_spatial'
P_ortho_resampAlg = 'ortho_resampAlg' P_ortho_resampAlg = 'ortho_resampAlg'
P_vswir_overlap_algorithm = 'vswir_overlap_algorithm' P_vswir_overlap_algorithm = 'vswir_overlap_algorithm'
P_target_projection_type = 'target_projection_type'
P_target_epsg = 'target_epsg'
# # Output parameters # # Output parameters
P_OUTPUT_RASTER = 'outraster' P_OUTPUT_RASTER = 'outraster'
...@@ -133,141 +135,152 @@ class _EnPTBaseAlgorithm(QgsProcessingAlgorithm): ...@@ -133,141 +135,152 @@ class _EnPTBaseAlgorithm(QgsProcessingAlgorithm):
super(_EnPTBaseAlgorithm, self).addParameter(param, *args, **kwargs) super(_EnPTBaseAlgorithm, self).addParameter(param, *args, **kwargs)
def initAlgorithm(self, configuration=None): def initAlgorithm(self, configuration=None):
self.addParameter(QgsProcessingParameterFile( self.addParameter(
name=self.P_json_config, description='Configuration JSON template file', QgsProcessingParameterFile(
behavior=QgsProcessingParameterFile.File, extension='json', name=self.P_json_config,
defaultValue=None, description='Configuration JSON template file',
behavior=QgsProcessingParameterFile.File,
extension='json',
defaultValue=None,
optional=True)) optional=True))
self.addParameter(QgsProcessingParameterNumber( self.addParameter(
name=self.P_CPUs, QgsProcessingParameterNumber(
description='Number of CPU cores to be used for processing', name=self.P_CPUs,
type=QgsProcessingParameterNumber.Integer, description='Number of CPU cores to be used for processing',
defaultValue=cpu_count(), minValue=0, maxValue=cpu_count(), type=QgsProcessingParameterNumber.Integer,
optional=True), defaultValue=cpu_count(), minValue=0, maxValue=cpu_count(),
optional=True),
advanced=True) advanced=True)
self.addParameter(QgsProcessingParameterFile( self.addParameter(
name=self.P_path_l1b_enmap_image, QgsProcessingParameterFile(
description='EnMAP Level-1B image (zip-archive or root directory)')) name=self.P_path_l1b_enmap_image,
description='EnMAP Level-1B image (zip-archive or root directory)'))
self.addParameter(QgsProcessingParameterFile( self.addParameter(
name=self.P_path_l1b_enmap_image_gapfill, QgsProcessingParameterFile(
description='Adjacent EnMAP Level-1B image to be used for gap-filling (zip-archive or root directory)', name=self.P_path_l1b_enmap_image_gapfill,
optional=True), description='Adjacent EnMAP Level-1B image to be used for gap-filling (zip-archive or root directory)',
optional=True),
advanced=True) advanced=True)
self.addParameter(QgsProcessingParameterRasterLayer( self.addParameter(
name=self.P_path_dem, QgsProcessingParameterRasterLayer(
description='Input path of digital elevation model in map or sensor geometry; GDAL compatible file ' name=self.P_path_dem,
'format \n(must cover the EnMAP L1B data completely if given in map geometry or must have the ' description='Input path of digital elevation model in map or sensor geometry; GDAL compatible file '
'same \npixel dimensions like the EnMAP L1B data if given in sensor geometry)', 'format \n(must cover the EnMAP L1B data completely if given in map geometry or must have '
optional=True)) 'the same \npixel dimensions like the EnMAP L1B data if given in sensor geometry)',
optional=True))
self.addParameter(QgsProcessingParameterNumber(
name=self.P_average_elevation, self.addParameter(
description='Average elevation in meters above sea level \n' QgsProcessingParameterNumber(
'(may be provided if no DEM is available and ignored if DEM is given)', name=self.P_average_elevation,
type=QgsProcessingParameterNumber.Integer, description='Average elevation in meters above sea level \n'
defaultValue=0, '(may be provided if no DEM is available and ignored if DEM is given)',
optional=True), type=QgsProcessingParameterNumber.Integer,
defaultValue=0,
optional=True),
advanced=True) advanced=True)
self.addParameter(QgsProcessingParameterFolderDestination( self.addParameter(
name=self.P_output_dir, QgsProcessingParameterFolderDestination(
description='Output directory where processed data and log files are saved', name=self.P_output_dir,
defaultValue=self._get_default_output_dir(), description='Output directory where processed data and log files are saved',
optional=True)) defaultValue=self._get_default_output_dir(),
optional=True))
self.addParameter(QgsProcessingParameterFile(
name=self.P_working_dir, self.addParameter(
description='Directory to be used for temporary files', QgsProcessingParameterFile(
behavior=QgsProcessingParameterFile.Folder, name=self.P_working_dir,
defaultValue=None, description='Directory to be used for temporary files',
optional=True)) behavior=QgsProcessingParameterFile.Folder,
defaultValue=None,
self.addParameter(QgsProcessingParameterNumber( optional=True))
name=self.P_n_lines_to_append,
description='Number of lines to be added to the main image [if not given, use the whole imgap]', self.addParameter(
type=QgsProcessingParameterNumber.Integer, QgsProcessingParameterNumber(
defaultValue=None, name=self.P_n_lines_to_append,
optional=True), description='Number of lines to be added to the main image [if not given, use the whole imgap]',
type=QgsProcessingParameterNumber.Integer,
defaultValue=None,
optional=True),
advanced=True) advanced=True)
self.addParameter(QgsProcessingParameterBoolean( self.addParameter(
name=self.P_disable_progress_bars, QgsProcessingParameterBoolean(
description='Disable all progress bars during processing', name=self.P_drop_bad_bands,
defaultValue=True, description='Do not include bad bands (water absorption bands 1358-1453 nm / 1814-1961 nm) '
optional=True), 'in the L2A product',
defaultValue=True),
advanced=True) advanced=True)
self.addParameter(QgsProcessingParameterFile( self.addParameter(
name=self.P_path_earthSunDist, QgsProcessingParameterBoolean(
description='Input path of the earth sun distance model', name=self.P_disable_progress_bars,
defaultValue=None, description='Disable all progress bars during processing',
optional=True), defaultValue=True),
advanced=True) advanced=True)
self.addParameter(QgsProcessingParameterFile( self.addParameter(
name=self.P_path_solar_irr, QgsProcessingParameterEnum(
description='Input path of the solar irradiance model', name=self.P_output_format,
defaultValue=None, description="Output format (file format of all raster output files).",
optional=True), options=['GTiff', 'ENVI'],
defaultValue=0),
advanced=True) advanced=True)
self.addParameter(QgsProcessingParameterNumber( # output_interleave?
name=self.P_scale_factor_toa_ref,
description='Scale factor to be applied to TOA reflectance result',
type=QgsProcessingParameterNumber.Integer,
defaultValue=10000,
optional=True),
advanced=True)
self.addParameter(QgsProcessingParameterBoolean( self.addParameter(
name=self.P_enable_keystone_correction, QgsProcessingParameterFile(
description='Keystone correction', name=self.P_path_earthSunDist,
defaultValue=False, description='Input path of the earth sun distance model',
optional=True)) defaultValue=None,
optional=True),
self.addParameter(QgsProcessingParameterBoolean(
name=self.P_enable_vnir_swir_coreg,
description='VNIR/SWIR co-registration',
defaultValue=False,
optional=True))
self.addParameter(QgsProcessingParameterRasterLayer(
name=self.P_path_reference_image,
description='Reference image for co-registration.',
defaultValue=None,
optional=True))
self.addParameter(QgsProcessingParameterBoolean(
name=self.P_enable_ac,
description='Enable atmospheric correction using SICOR algorithm',
defaultValue=True,
optional=True))
self.addParameter(QgsProcessingParameterBoolean(
name=self.P_auto_download_ecmwf,
description='Automatically download ECMWF data for atmospheric correction',
defaultValue=False,
optional=True),
advanced=True) advanced=True)
self.addParameter(QgsProcessingParameterBoolean( self.addParameter(
name=self.P_enable_ice_retrieval, QgsProcessingParameterFile(
description='Enable ice retrieval (increases accuracy of water vapour retrieval)', name=self.P_path_solar_irr,
defaultValue=True, description='Input path of the solar irradiance model',
optional=True), defaultValue=None,
optional=True),
advanced=True) advanced=True)
self.addParameter(QgsProcessingParameterBoolean( self.addParameter(
name=self.P_enable_cloud_screening, QgsProcessingParameterNumber(
description='Cloud screening during atmospheric correction', name=self.P_scale_factor_toa_ref,
defaultValue=False, description='Scale factor to be applied to TOA reflectance result',
optional=True), type=QgsProcessingParameterNumber.Integer,
defaultValue=10000),
advanced=True) advanced=True)
self.addParameter(
QgsProcessingParameterBoolean(
name=self.P_enable_keystone_correction,
description='Keystone correction',
defaultValue=False))
self.addParameter(
QgsProcessingParameterBoolean(
name=self.P_enable_vnir_swir_coreg,
description='VNIR/SWIR co-registration',
defaultValue=False))
self.addParameter(
QgsProcessingParameterRasterLayer(
name=self.P_path_reference_image,
description='Reference image for co-registration.',
defaultValue=None,
optional=True))
self.addParameter(
QgsProcessingParameterBoolean(
name=self.P_enable_ac,
description='Enable atmospheric correction using SICOR algorithm',
defaultValue=True))
self.addParameter(QgsProcessingParameterNumber( self.addParameter(QgsProcessingParameterNumber(
name=self.P_scale_factor_boa_ref, name=self.P_scale_factor_boa_ref,
description='Scale factor to be applied to BOA reflectance result', description='Scale factor to be applied to BOA reflectance result',
...@@ -276,61 +289,81 @@ class _EnPTBaseAlgorithm(QgsProcessingAlgorithm): ...@@ -276,61 +289,81 @@ class _EnPTBaseAlgorithm(QgsProcessingAlgorithm):
optional=True), optional=True),
advanced=True) advanced=True)
self.addParameter(QgsProcessingParameterBoolean( self.addParameter(
name=self.P_run_smile_P, QgsProcessingParameterBoolean(
description='Smile detection and correction (provider smile coefficients are ignored)', name=self.P_run_smile_P,
defaultValue=False, description='Smile detection and correction (provider smile coefficients are ignored)',
optional=True)) defaultValue=False))
self.addParameter(
QgsProcessingParameterBoolean(
name=self.P_run_deadpix_P,
description='Dead pixel correction',
defaultValue=True))
self.addParameter(
QgsProcessingParameterEnum(
name=self.P_deadpix_P_algorithm,
description="Algorithm for dead pixel correction",
options=['spectral', 'spatial'],
defaultValue=0),
advanced=True)
self.addParameter(QgsProcessingParameterBoolean( self.addParameter(
name=self.P_run_deadpix_P, QgsProcessingParameterEnum(
description='Dead pixel correction', name=self.P_deadpix_P_interp_spectral,
defaultValue=True, description="Spectral interpolation algorithm to be used during dead pixel correction ",
optional=True)) options=['linear', 'bilinear', 'cubic', 'spline'],
defaultValue=0),
advanced=True)
self.addParameter(QgsProcessingParameterString( self.addParameter(
name=self.P_deadpix_P_algorithm, QgsProcessingParameterEnum(
description="Algorithm for dead pixel correction ('spectral' or 'spatial')", name=self.P_deadpix_P_interp_spatial,
defaultValue='spectral', description="Spatial interpolation algorithm to be used during dead pixel correction",
multiLine=False, options=['linear', 'bilinear', 'cubic', 'spline'],
optional=True), defaultValue=0),
advanced=True) advanced=True)
self.addParameter(QgsProcessingParameterString( self.addParameter(
name=self.P_deadpix_P_interp_spectral, QgsProcessingParameterEnum(
description="Spectral interpolation algorithm to be used during dead pixel correction " name=self.P_ortho_resampAlg,
"('linear', 'bilinear', 'cubic', 'spline')", description="Ortho-rectification resampling algorithm",
defaultValue='linear', options=['nearest', 'bilinear', 'gauss'],
multiLine=False, defaultValue=2),
optional=True),
advanced=True) advanced=True)
self.addParameter(QgsProcessingParameterString( self.addParameter(
name=self.P_deadpix_P_interp_spatial, QgsProcessingParameterEnum(
description="Spatial interpolation algorithm to be used during dead pixel correction " name=self.P_vswir_overlap_algorithm,
"('linear', 'bilinear', 'cubic', 'spline')", description="Algorithm specifying how to deal with the spectral bands "
defaultValue='linear', "in the VNIR/SWIR spectral overlap region",
multiLine=False, options=['VNIR and SWIR bands, order by wavelength', 'average VNIR and SWIR bands',
optional=True), 'VNIR bands only', 'SWIR bands only'],
defaultValue=3),
advanced=True) advanced=True)
self.addParameter(QgsProcessingParameterString( self.addParameter(
name=self.P_ortho_resampAlg, QgsProcessingParameterEnum(
description="Ortho-rectification resampling algorithm ('nearest', 'bilinear', 'gauss')", self.P_target_projection_type,
defaultValue='bilinear', description='Projection type of the raster output files',
multiLine=False, options=['UTM', 'Geographic'],
optional=True), defaultValue=0),
advanced=True) advanced=True)
self.addParameter(QgsProcessingParameterString( self.addParameter(
name=self.P_vswir_overlap_algorithm, QgsProcessingParameterNumber(
description="Algorithm specifying how to deal with the spectral bands in the VNIR/SWIR spectral overlap " name=self.P_target_epsg,
"region ('order_by_wvl', 'average', 'vnir_only', 'swir_only')", description='Custom EPSG code of the target projection (overrides target_projection_type)',
defaultValue='swir_only', type=QgsProcessingParameterNumber.Integer,
multiLine=False, defaultValue=None,
optional=True), optional=True),
advanced=True) advanced=True)
# TODO:
# "target_coord_grid": "None" /*custom target coordinate grid to which the output is resampled
# ([x0, x1, y0, y1], e.g., [0, 30, 0, 30])*/
@staticmethod @staticmethod
def shortHelpString(*args, **kwargs): def shortHelpString(*args, **kwargs):
"""Example: """Example:
...@@ -367,7 +400,6 @@ class _EnPTBaseAlgorithm(QgsProcessingAlgorithm): ...@@ -367,7 +400,6 @@ class _EnPTBaseAlgorithm(QgsProcessingAlgorithm):
:param cmd: a normal shell command including parameters :param cmd: a normal shell command including parameters
""" """
def reader(pipe, queue): def reader(pipe, queue):
try: try:
with pipe: with pipe:
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
import os import os
from pkgutil import find_loader from pkgutil import find_loader
from glob import glob from glob import glob
from pprint import pprint
from qgis.core import \ from qgis.core import \
(QgsProcessingContext, (QgsProcessingContext,
...@@ -75,6 +76,18 @@ class EnPTAlgorithm(_EnPTBaseAlgorithm): ...@@ -75,6 +76,18 @@ class EnPTAlgorithm(_EnPTBaseAlgorithm):
raise ImportError("enpt", "EnPT must be installed into the QGIS Python environment " raise ImportError("enpt", "EnPT must be installed into the QGIS Python environment "
"when calling 'EnPTAlgorithm'.") "when calling 'EnPTAlgorithm'.")
# replace Enum parameters with corresponding strings
for n, opts in [
('output_format', {0: 'GTiff', 1: 'ENVI'}),
('deadpix_P_algorithm', {0: 'spectral', 1: 'spatial'}),
('deadpix_P_interp_spectral', {0: 'linear', 1: 'bilinear', 2: 'cubic', 3: 'spline'}),
('deadpix_P_interp_spatial', {0: 'linear', 1: 'bilinear', 2: 'cubic', 3: 'spline'}),
('ortho_resampAlg', {0: 'nearest', 1: 'bilinear', 2: 'gauss'}),
('vswir_overlap_algorithm', {0: 'order_by_wvl', 1: 'average', 2: 'vnir_only', 3: 'swir_only'}),
('target_projection_type', {0: 'UTM', 1: 'Geographic'}),
]:
parameters[n] = opts[parameters[n]]
feedback.pushInfo("The log messages of the EnMAP processing tool are written to the *.log file " feedback.pushInfo("The log messages of the EnMAP processing tool are written to the *.log file "
"in the specified output folder.") "in the specified output folder.")
...@@ -83,13 +96,14 @@ class EnPTAlgorithm(_EnPTBaseAlgorithm): ...@@ -83,13 +96,14 @@ class EnPTAlgorithm(_EnPTBaseAlgorithm):
if k not in ['anaconda_root'] if k not in ['anaconda_root']
and v not in [None, NULL, 'NULL', '']} and v not in [None, NULL, 'NULL', '']}
# print parameters and console call to log # print parameters and console call to log
# for key in sorted(parameters): # for key in sorted(parameters):
# feedback.pushInfo('{} = {}'.format(key, repr(parameters[key]))) # feedback.pushInfo('{} = {}'.format(key, repr(parameters[key])))
keyval_str = ' '.join(['--{} {}'.format(key, parameters[key]) keyval_str = ' '.join(['--{} {}'.format(key, parameters[key])
for key in sorted(parameters) for key in sorted(parameters)
if parameters[key] not in [None, NULL, 'NULL', '']]) if parameters[key] not in [None, NULL, 'NULL', '']])
print(parameters) pprint(parameters)
print(keyval_str + '\n\n') print(keyval_str + '\n\n')
feedback.pushInfo("\nCalling EnPT with the following command:\n" feedback.pushInfo("\nCalling EnPT with the following command:\n"
"enpt %s\n\n" % keyval_str) "enpt %s\n\n" % keyval_str)
......
...@@ -170,6 +170,18 @@ class ExternalEnPTAlgorithm(_EnPTBaseAlgorithm): ...@@ -170,6 +170,18 @@ class ExternalEnPTAlgorithm(_EnPTBaseAlgorithm):
parameters = {k: v for k, v in parameters.items() parameters = {k: v for k, v in parameters.items()
if k not in ['anaconda_root']} if k not in ['anaconda_root']}
# replace Enum parameters with corresponding strings
for n, opts in [
('output_format', {0: 'GTiff', 1: 'ENVI'}),
('deadpix_P_algorithm', {0: 'spectral', 1: 'spatial'}),
('deadpix_P_interp_spectral', {0: 'linear', 1: 'bilinear', 2: 'cubic', 3: 'spline'}),
('deadpix_P_interp_spatial', {0: 'linear', 1: 'bilinear', 2: 'cubic', 3: 'spline'}),
('ortho_resampAlg', {0: 'nearest', 1: 'bilinear', 2: 'gauss'}),
('vswir_overlap_algorithm', {0: 'order_by_wvl', 1: 'average', 2: 'vnir_only', 3: 'swir_only'}),
('target_projection_type', {0: 'UTM', 1: 'Geographic'}),
]:
parameters[n] = opts[parameters[n]]
# print parameters and console call to log # print parameters and console call to log
# for key in sorted(parameters): # for key in sorted(parameters):
# feedback.pushInfo('{} = {}'.format(key, repr(parameters[key]))) # feedback.pushInfo('{} = {}'.format(key, repr(parameters[key])))
......
...@@ -54,8 +54,9 @@ enpt_test_parameters = dict( ...@@ -54,8 +54,9 @@ enpt_test_parameters = dict(
deadpix_P_algorithm='spectral', deadpix_P_algorithm='spectral',
deadpix_P_interp_spectral='linear', deadpix_P_interp_spectral='linear',
deadpix_P_interp_spatial='linear', deadpix_P_interp_spatial='linear',
drop_bad_bands=True,
disable_progress_bars=False, disable_progress_bars=False,
enable_cloud_screening=False, output_format='GTiff',
enable_keystone_correction=False, enable_keystone_correction=False,
enable_vnir_swir_coreg=False, enable_vnir_swir_coreg=False,
json_config=None, json_config=None,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment