Commit 11d76d0f authored by Daniel Scheffler's avatar Daniel Scheffler
Browse files

Merge branch 'bugfix/fix_no_dem_exception' into 'master'

Bugfix/fix no dem exception

Closes #37

See merge request !47
parents 130ed224 12a82dce
Pipeline #11331 passed with stages
in 11 minutes and 24 seconds
......@@ -2,6 +2,18 @@
History
=======
0.13.2 (2020-08-11)
-------------------
* Fixed issue #37 (Empty FileNotFoundError in case no DEM is provided by the user). If no DEM is provided by the user,
an average elevation (default=0) is used instead. Added corresponding warning and log messages.
* Fixed exception in case an average elevation is passed.
* Fixed a bug that caused 0 or 1 integers provided in the config parameters to be converted to booleans.
* User-provided file paths are now validated directly on startup.
* DEM_Processor instance can now be created from an average elevation (returns a flat DEM).
* RPC geolayer generators are now also compatible with an integer as input elevation.
0.13.1 (2020-08-07)
-------------------
......
......@@ -255,7 +255,7 @@ class _EnMAP_Image(object):
:return: geoarray.GeoArray
"""
if self._dem is None:
raise NotImplementedError('An automatic DEM getter is not yet implemented.')
raise NotImplementedError('DEM is missing. An automatic DEM getter is currently not implemented.')
return self._dem
@dem.setter
......
......@@ -129,7 +129,8 @@ class EnMAP_Detector_SensorGeo(_EnMAP_Image):
logger=self.logger)\
.correct(self.data, self.deadpixelmap)
def get_preprocessed_dem(self):
def get_preprocessed_dem(self) -> GeoArray:
"""Get a digital elevation model in EnMAP sensor geometry of the current detector."""
if self.cfg.path_dem:
self.logger.info('Pre-processing DEM for %s...' % self.detector_name)
DP = DEM_Processor(self.cfg.path_dem, enmapIm_cornerCoords=tuple(zip(self.detector_meta.lon_UL_UR_LL_LR,
......@@ -164,6 +165,11 @@ class EnMAP_Detector_SensorGeo(_EnMAP_Image):
else:
self.dem = DP.dem
else:
self.logger.info('No DEM for the %s detector provided. Falling back to an average elevation of %d meters.'
% (self.detector_name, self.cfg.average_elevation))
self.dem = GeoArray(np.full(self.data.shape[:2], self.cfg.average_elevation).astype(np.int16))
return self.dem
def append_new_image(self, img2: 'EnMAP_Detector_SensorGeo', n_lines: int = None) -> None:
......@@ -224,13 +230,15 @@ class EnMAP_Detector_SensorGeo(_EnMAP_Image):
if not self.cfg.is_dummy_dataformat:
img2_cornerCoords = tuple(zip(img2.detector_meta.lon_UL_UR_LL_LR,
img2.detector_meta.lat_UL_UR_LL_LR))
dem_validated = DEM_Processor(img2.cfg.path_dem,
enmapIm_cornerCoords=img2_cornerCoords).dem
elevation = DEM_Processor(img2.cfg.path_dem,
enmapIm_cornerCoords=img2_cornerCoords).dem \
if img2.cfg.path_dem else self.cfg.average_elevation
LL, LR = compute_mapCoords_within_sensorGeoDims(
sensorgeoCoords_YX=[(n_lines - 1, 0), # LL
(n_lines - 1, img2.detector_meta.ncols - 1)], # LR
rpc_coeffs=list(img2.detector_meta.rpc_coeffs.values())[0], # RPC coeffs of first band of the detector
dem=dem_validated,
elevation=elevation,
enmapIm_cornerCoords=img2_cornerCoords,
enmapIm_dims_sensorgeo=(img2.detector_meta.nrows, img2.detector_meta.ncols)
)
......
......@@ -386,13 +386,12 @@ class EnMAP_Metadata_L1B_Detector_SensorGeo(object):
def compute_geolayer_for_cube(self):
self.logger.info('Computing %s geolayer...' % self.detector_name)
lons, lats = RPC_3D_Geolayer_Generator(rpc_coeffs_per_band=self.rpc_coeffs,
dem=self.cfg.path_dem,
enmapIm_cornerCoords=tuple(zip(self.lon_UL_UR_LL_LR,
self.lat_UL_UR_LL_LR)),
enmapIm_dims_sensorgeo=(self.nrows, self.ncols),
CPUs=self.cfg.CPUs)\
lons, lats = \
RPC_3D_Geolayer_Generator(rpc_coeffs_per_band=self.rpc_coeffs,
elevation=self.cfg.path_dem if self.cfg.path_dem else self.cfg.average_elevation,
enmapIm_cornerCoords=tuple(zip(self.lon_UL_UR_LL_LR, self.lat_UL_UR_LL_LR)),
enmapIm_dims_sensorgeo=(self.nrows, self.ncols),
CPUs=self.cfg.CPUs)\
.compute_geolayer()
return lons, lats
......
......@@ -87,10 +87,10 @@ config_for_testing_dlr = dict(
# 'ENMAP01-____L1B-DT000000987_20130205T105307Z_001_V000101_20190426T143700Z__rows0-99.zip'
# Alps full
'ENMAP01-____L1B-DT000000987_20130205T105307Z_001_V000101_20190426T143700Z.zip'
# 'ENMAP01-____L1B-DT000000987_20130205T105307Z_001_V000101_20190426T143700Z.zip'
# Arcachon
# 'ENMAP01-____L1B-DT000400126_20170218T110115Z_002_V000204_20200206T182719Z__rows700-799.zip'
'ENMAP01-____L1B-DT000400126_20170218T110115Z_002_V000204_20200206T182719Z__rows700-799.zip'
# Arcachon 1000x30
# 'ENMAP01-____L1B-DT000400126_20170218T110115Z_002_V000204_20200206T182719Z__rows700-730.zip'
......@@ -101,21 +101,21 @@ config_for_testing_dlr = dict(
# Arcachon full tile 3, reprocessed 05/2020
# 'ENMAP01-____L1B-DT000400126_20170218T110119Z_003_V000204_20200508T124425Z.zip'
)),
# path_l1b_enmap_image_gapfill=os.path.abspath(
# os.path.join(path_enptlib, '..', 'tests', 'data', 'EnMAP_Level_1B',
# # Alps
# # 'ENMAP01-____L1B-DT000000987_20130205T105307Z_001_V000101_20190426T143700Z__rows100-199.zip'
#
# # Arcachon
# 'ENMAP01-____L1B-DT000400126_20170218T110115Z_002_V000204_20200206T182719Z__rows800-899.zip'
# )),
path_l1b_enmap_image_gapfill=os.path.abspath(
os.path.join(path_enptlib, '..', 'tests', 'data', 'EnMAP_Level_1B',
# Alps
# 'ENMAP01-____L1B-DT000000987_20130205T105307Z_001_V000101_20190426T143700Z__rows100-199.zip'
# Arcachon
'ENMAP01-____L1B-DT000400126_20170218T110115Z_002_V000204_20200206T182719Z__rows800-899.zip'
)),
path_dem=os.path.abspath(
os.path.join(path_enptlib, '..', 'tests', 'data',
# Alps
'DLR_L2A_DEM_UTM32.bsq'
# 'DLR_L2A_DEM_UTM32.bsq'
# Arcachon tile 2 ASTER DEM (02/2020)
# 'ENMAP01-____L1B-DT000400126_20170218T110115Z_002_V000204_20200206T182719Z__tile2__DEM_ASTER.bsq'
'ENMAP01-____L1B-DT000400126_20170218T110115Z_002_V000204_20200206T182719Z__tile2__DEM_ASTER.bsq'
# Arcachon tile 3 ASTER DEM (05/2020)
# 'ENMAP01-____L1B-DT000400126_20170218T110119Z_003_V000204_20200508T124425Z__tile3__DEM_ASTER.bsq'
......@@ -287,7 +287,7 @@ class EnPTConfig(object):
self.path_l1b_enmap_image = self.absPath(gp('path_l1b_enmap_image'))
self.path_l1b_enmap_image_gapfill = self.absPath(gp('path_l1b_enmap_image_gapfill'))
self.path_dem = self.absPath(gp('path_dem'))
self.average_elevation = self.absPath(gp('average_elevation'))
self.average_elevation = gp('average_elevation')
self.path_l1b_snr_model = self.absPath(gp('path_l1b_snr_model'))
self.working_dir = self.absPath(gp('working_dir')) or None
self.n_lines_to_append = gp('n_lines_to_append')
......@@ -345,6 +345,16 @@ class EnPTConfig(object):
EnPTValidator(allow_unknown=True, schema=enpt_schema_config_output).validate(self.to_dict())
# check if given paths point to existing files
paths = {k: v for k, v in self.__dict__.items() if k.startswith('path_')}
for k, fp in paths.items():
if fp and not os.path.exists(fp):
raise FileNotFoundError("The file path provided at the '%s' parameter does not exist (%s)." % (k, fp))
if not self.path_dem:
warnings.warn('No digital elevation model provided. Note that this may cause uncertainties, e.g., '
'in the atmospheric correction and the orthorectification.', RuntimeWarning, stacklevel=2)
# check invalid interleave
if self.output_interleave == 'line' and self.output_format == 'GTiff':
warnings.warn("The interleaving type 'line' is not supported by the GTiff output format. Using 'pixel'.",
......@@ -484,9 +494,9 @@ def json_to_python(value):
return None
if value == "slice(None, None, None)":
return slice(None)
if value in [True, "true"]:
if value is True or value == "true":
return True
if value in [False, "false"]:
if value is False or value == "false":
return False
if is_number(value):
try:
......
......@@ -34,11 +34,11 @@ from multiprocessing import cpu_count
import numpy as np
from geoarray import GeoArray
from py_tools_ds.geo.projection import get_proj4info, proj4_to_dict
from py_tools_ds.geo.projection import get_proj4info, proj4_to_dict, EPSG2WKT
from py_tools_ds.geo.coord_trafo import reproject_shapelyGeometry, transform_any_prj
from py_tools_ds.geo.vector.topology import get_footprint_polygon, get_overlap_polygon
from ..spatial_transform import Geometry_Transformer
from ..spatial_transform import Geometry_Transformer, get_UTMEPSG_from_LonLat, get_center_coord
__author__ = 'Daniel Scheffler'
......@@ -78,8 +78,8 @@ class DEM_Processor(object):
xmin, xmax = cornersXY[:, 0].min(), cornersXY[:, 0].max()
ymin, ymax = cornersXY[:, 1].min(), cornersXY[:, 1].max()
raise ValueError('The provided digital elevation model covers %.1f percent of the EnMAP image. It must '
'cover it completely. The minimal needed extent in the provided projection is: \n'
raise ValueError('The provided digital elevation model does not cover the EnMAP image completely '
'(only around %.1f percent). The minimal needed extent in the provided projection is: \n'
'xmin: %s, xmax: %s, ymin: %s, ymax: %s.' % (overlap_perc, xmin, xmax, ymin, ymax))
def _set_nodata_if_not_provided(self):
......@@ -87,6 +87,33 @@ class DEM_Processor(object):
if self.dem._nodata is None:
self.dem.nodata = -9999
@classmethod
def get_flat_dem_from_average_elevation(cls, corner_coords_lonlat, average_elevation, xres=30, yres=30):
"""Return a 'flat DEM' instance of DEM_Processor.
(a GeoArray fully covering the given coorner coordinates with the average elevation as pixel values)
:param corner_coords_lonlat: corner coordinates to be covered by the output DEM
:param average_elevation: average elevation in meters
:param xres: x-resolution in meters
:param yres: y-resolution in meters
:return:
"""
# compute the dimensions of the flat output DEM
tgt_utm_epsg = get_UTMEPSG_from_LonLat(*get_center_coord(corner_coords_lonlat))
corner_coords_utm = [transform_any_prj(prj_src=4326, prj_tgt=tgt_utm_epsg, x=x, y=y)
for x, y in corner_coords_lonlat]
x_all, y_all = list(zip(*corner_coords_utm))
cols = int(np.ceil((max(x_all) - min(x_all)) / xres)) + 2
rows = int(np.ceil((max(y_all) - min(y_all)) / yres)) + 2
# get a GeoArray instance
dem_gA = GeoArray(np.full((rows, cols), fill_value=average_elevation),
geotransform=(np.floor(min(x_all)) - xres, xres, 0, np.ceil(max(y_all)) + yres, 0, -yres),
projection=EPSG2WKT(tgt_utm_epsg))
return cls(dem_gA, corner_coords_lonlat)
def fill_gaps(self):
pass
......
......@@ -251,13 +251,14 @@ class RPC_Geolayer_Generator(object):
"""
def __init__(self,
rpc_coeffs: dict,
dem: Union[str, GeoArray],
elevation: Union[str, GeoArray, int, float],
enmapIm_cornerCoords: Tuple[Tuple[float, float]],
enmapIm_dims_sensorgeo: Tuple[int, int]):
"""Get an instance of RPC_Geolayer_Generator.
:param rpc_coeffs: RPC coefficients for a single EnMAP band
:param dem: digital elevation model in map geometry (file path or instance of GeoArray)
:param elevation: digital elevation model in map geometry (file path or instance of GeoArray) OR
average elevation as integer or float
:param enmapIm_cornerCoords: corner coordinates as tuple of lon/lat pairs
:param enmapIm_dims_sensorgeo: dimensions of the EnMAP image in sensor geometry (rows, colunms)
"""
......@@ -276,7 +277,7 @@ class RPC_Geolayer_Generator(object):
self.col_num_coeffs = rpc_coeffs['col_num_coeffs']
self.col_den_coeffs = rpc_coeffs['col_den_coeffs']
self.dem = GeoArray(dem)
self.elevation = elevation if isinstance(elevation, (int, float)) else GeoArray(elevation)
self.enmapIm_cornerCoords = enmapIm_cornerCoords
self.enmapIm_dims_sensorgeo = enmapIm_dims_sensorgeo
......@@ -315,7 +316,7 @@ class RPC_Geolayer_Generator(object):
:param lon_norm: normalized longitudes
:param lat_norm: normalized latitudes
:param height_norm: normalized elevations
:param height_norm: normalized elevation
:return:
"""
P = lat_norm.flatten()
......@@ -448,17 +449,20 @@ class RPC_Geolayer_Generator(object):
np.arange(xmin, xmax + meshwidth, meshwidth),
indexing='ij')
# transform UTM grid to DEM projection
x_grid_demPrj, y_grid_demPrj = \
(x_grid_utm, y_grid_utm) if prj_equal(grid_utm_epsg, self.dem.epsg) else \
transform_coordArray(EPSG2WKT(grid_utm_epsg),
EPSG2WKT(self.dem.epsg),
x_grid_utm, y_grid_utm)
# retrieve corresponding heights from DEM
# -> resample DEM to EnMAP grid?
xy_pairs_demPrj = np.vstack([x_grid_demPrj.flatten(), y_grid_demPrj.flatten()]).T
heights = self.dem.read_pointData(xy_pairs_demPrj).flatten()
if not isinstance(self.elevation, (int, float)):
# transform UTM grid to DEM projection
x_grid_demPrj, y_grid_demPrj = \
(x_grid_utm, y_grid_utm) if prj_equal(grid_utm_epsg, self.elevation.epsg) else \
transform_coordArray(EPSG2WKT(grid_utm_epsg),
EPSG2WKT(self.elevation.epsg),
x_grid_utm, y_grid_utm)
# retrieve corresponding heights from DEM
# -> resample DEM to EnMAP grid?
xy_pairs_demPrj = np.vstack([x_grid_demPrj.flatten(), y_grid_demPrj.flatten()]).T
heights = self.elevation.read_pointData(xy_pairs_demPrj).flatten()
else:
heights = np.full_like(x_grid_utm.flatten(), self.elevation)
# transform UTM points to lon/lat
lon_grid, lat_grid = transform_coordArray(EPSG2WKT(grid_utm_epsg), EPSG2WKT(4326), x_grid_utm, y_grid_utm)
......@@ -504,7 +508,7 @@ class RPC_3D_Geolayer_Generator(object):
"""
def __init__(self,
rpc_coeffs_per_band: dict,
dem: Union[str, GeoArray],
elevation: Union[str, GeoArray, int, float],
enmapIm_cornerCoords: Tuple[Tuple[float, float]],
enmapIm_dims_sensorgeo: Tuple[int, int],
CPUs: int = None):
......@@ -514,24 +518,27 @@ class RPC_3D_Geolayer_Generator(object):
({'band_1': <rpc_coeffs_dict>,
'band_2': <rpc_coeffs_dict>,
...})
:param dem: digital elevation model in map geometry (file path or instance of GeoArray)
:param elevation: digital elevation model in MAP geometry (file path or instance of GeoArray) OR
average elevation as integer or float
:param enmapIm_cornerCoords: corner coordinates as tuple of lon/lat pairs
:param enmapIm_dims_sensorgeo: dimensions of the EnMAP image in sensor geometry (rows, colunms)
:param CPUs: number of CPUs to use
"""
self.rpc_coeffs_per_band = OrderedDict(natsorted(rpc_coeffs_per_band.items()))
self.dem = dem
self.elevation = elevation
self.enmapIm_cornerCoords = enmapIm_cornerCoords
self.enmapIm_dims_sensorgeo = enmapIm_dims_sensorgeo
self.CPUs = CPUs or cpu_count()
# get validated DEM in map geometry
# self.logger.debug('Verifying DEM...') # TODO
from ..dem_preprocessing import DEM_Processor
self.dem = DEM_Processor(dem_path_geoarray=dem,
enmapIm_cornerCoords=enmapIm_cornerCoords).dem
# TODO clip DEM to needed area
self.dem.to_mem()
if not isinstance(elevation, (int, float)):
# get validated DEM in map geometry
# self.logger.debug('Verifying DEM...') # TODO
from ..dem_preprocessing import DEM_Processor
self.elevation = DEM_Processor(dem_path_geoarray=elevation,
enmapIm_cornerCoords=enmapIm_cornerCoords).dem
# TODO clip DEM to needed area
self.elevation.to_mem()
# self.elevation.reproject_to_new_grid()
self.bandgroups_with_unique_rpc_coeffs = self._get_bandgroups_with_unique_rpc_coeffs()
......@@ -566,7 +573,7 @@ class RPC_3D_Geolayer_Generator(object):
def _compute_geolayer_for_unique_coeffgroup(kwargs):
lons, lats = \
RPC_Geolayer_Generator(rpc_coeffs=kwargs['rpc_coeffs'],
dem=global_dem_sensorgeo,
elevation=global_dem_sensorgeo,
enmapIm_cornerCoords=kwargs['enmapIm_cornerCoords'],
enmapIm_dims_sensorgeo=kwargs['enmapIm_dims_sensorgeo']
).compute_geolayer()
......@@ -590,7 +597,7 @@ class RPC_3D_Geolayer_Generator(object):
# compute the geolayer ONLY FOR ONE BAND per group with unique RPC coefficients
global global_dem_sensorgeo
global_dem_sensorgeo = self.dem
global_dem_sensorgeo = self.elevation
if len(self.bandgroups_with_unique_rpc_coeffs) == 1:
lons_oneband, lats_oneband = self._compute_geolayer_for_unique_coeffgroup(kwargs_list[0])[:2]
......@@ -626,7 +633,7 @@ class RPC_3D_Geolayer_Generator(object):
def compute_mapCoords_within_sensorGeoDims(sensorgeoCoords_YX: List[Tuple[float, float]],
rpc_coeffs: dict,
dem: Union[str, GeoArray],
elevation: Union[str, GeoArray, int, float],
enmapIm_cornerCoords: Tuple[Tuple[float, float]],
enmapIm_dims_sensorgeo: Tuple[int, int],
) -> List[Tuple[float, float]]:
......@@ -634,14 +641,15 @@ def compute_mapCoords_within_sensorGeoDims(sensorgeoCoords_YX: List[Tuple[float,
:param sensorgeoCoords_YX: list of requested sensor geometry positions [(row, column), (row, column), ...]
:param rpc_coeffs: RPC coefficients describing the relation between sensor and map geometry
:param dem: digital elevation model in MAP geometry
:param elevation: digital elevation model in MAP geometry (file path or instance of GeoArray) OR
average elevation as integer or float
:param enmapIm_cornerCoords: MAP coordinates of the EnMAP image
:param enmapIm_dims_sensorgeo: dimensions of the sensor geometry EnMAP image (rows, columns)
:return:
"""
# compute coordinate array
RPCGG = RPC_Geolayer_Generator(rpc_coeffs=rpc_coeffs,
dem=dem,
elevation=elevation,
enmapIm_cornerCoords=enmapIm_cornerCoords, # order does not matter
enmapIm_dims_sensorgeo=enmapIm_dims_sensorgeo)
lons, lats = RPCGG.compute_geolayer()
......
......@@ -27,6 +27,6 @@
# You should have received a copy of the GNU Lesser General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
__version__ = '0.13.1'
__versionalias__ = '20200807.01'
__version__ = '0.13.2'
__versionalias__ = '20200811.01'
__author__ = 'Daniel Scheffler'
......@@ -118,6 +118,10 @@ class Test_EnPTConfig(TestCase):
# check validity
EnPTValidator(allow_unknown=True, schema=enpt_schema_config_output).validate(params)
def test_invalid_filepath(self):
with self.assertRaises(FileNotFoundError):
EnPTConfig(path_l1b_enmap_image='/path/to/not/existing/image.tif')
if __name__ == '__main__':
main()
......@@ -90,6 +90,12 @@ class Test_DEM_Processor(TestCase):
with self.assertRaises(ValueError):
DEM_Processor(dem, enmapIm_cornerCoords=self.ll_cornerCoords)
def test_get_flat_dem(self):
DP = DEM_Processor.get_flat_dem_from_average_elevation(corner_coords_lonlat=self.ll_cornerCoords,
average_elevation=50)
self.assertIsInstance(DP.dem, GeoArray)
self.assertEqual(np.mean(DP.dem), 50)
def test_fill_gaps(self):
pass
......
......@@ -181,7 +181,7 @@ class Test_RPC_Geolayer_Generator(TestCase):
# bounding polygon DLR test data
self.lats = np.array([47.7872236, 47.7232358, 47.5195676, 47.4557831])
self.lons = np.array([10.7966311, 11.1693436, 10.7111131, 11.0815993])
corner_coords = np.vstack([self.lons, self.lats]).T.tolist()
self._corner_coords = np.vstack([self.lons, self.lats]).T.tolist()
# spatial coverage of datatake DLR test data
# self.lats = np.array([47.7870358956, 47.723060779, 46.9808418244, 46.9174014681])
......@@ -193,8 +193,8 @@ class Test_RPC_Geolayer_Generator(TestCase):
self.dims_sensorgeo = (1024, 1000)
self.RPCGG = RPC_Geolayer_Generator(self.rpc_coeffs,
dem=self.dem,
enmapIm_cornerCoords=corner_coords,
elevation=self.dem,
enmapIm_cornerCoords=self._corner_coords,
enmapIm_dims_sensorgeo=self.dims_sensorgeo)
def test_normalize_coordinates(self):
......@@ -227,6 +227,18 @@ class Test_RPC_Geolayer_Generator(TestCase):
self.assertFalse(np.isnan(lons_interp).any())
self.assertFalse(np.isnan(lats_interp).any())
def test_compute_geolayer_average_elevation(self):
RPCGG = RPC_Geolayer_Generator(self.rpc_coeffs,
elevation=50.6,
enmapIm_cornerCoords=self._corner_coords,
enmapIm_dims_sensorgeo=self.dims_sensorgeo)
lons_interp, lats_interp = RPCGG.compute_geolayer()
self.assertEqual(lons_interp.shape, lats_interp.shape)
self.assertEqual(lons_interp.shape, self.dims_sensorgeo)
self.assertFalse(np.isnan(lons_interp).any())
self.assertFalse(np.isnan(lats_interp).any())
class Test_RPC_3D_Geolayer_Generator(TestCase):
def setUp(self):
......@@ -266,7 +278,7 @@ class Test_RPC_3D_Geolayer_Generator(TestCase):
def test_compute_geolayer_one_unique_coeff_set(self):
lons, lats = RPC_3D_Geolayer_Generator(self.rpc_coeffs_per_band,
dem=self.dem,
elevation=self.dem,
enmapIm_cornerCoords=self.corner_coords,
enmapIm_dims_sensorgeo=self.dims_sensorgeo
).compute_geolayer()
......@@ -282,7 +294,7 @@ class Test_RPC_3D_Geolayer_Generator(TestCase):
NOTE: NaNs should be filled automatically.
"""
lons, lats = RPC_3D_Geolayer_Generator(self._get__faulty_rpc_coeffs(),
dem=self.dem,
elevation=self.dem,
enmapIm_cornerCoords=self.corner_coords,
enmapIm_dims_sensorgeo=self.dims_sensorgeo
).compute_geolayer()
......@@ -293,7 +305,7 @@ class Test_RPC_3D_Geolayer_Generator(TestCase):
def test_compute_geolayer_multiple_coeff_sets_singleprocessing(self):
lons, lats = RPC_3D_Geolayer_Generator(self._get_rpc_coeffs_with_multiple_coeff_sets(),
dem=self.dem,
elevation=self.dem,
enmapIm_cornerCoords=self.corner_coords,
enmapIm_dims_sensorgeo=self.dims_sensorgeo,
CPUs=1
......@@ -305,7 +317,19 @@ class Test_RPC_3D_Geolayer_Generator(TestCase):
def test_compute_geolayer_multiple_coeff_sets_multiprocessing(self):
lons, lats = RPC_3D_Geolayer_Generator(self._get_rpc_coeffs_with_multiple_coeff_sets(),
dem=self.dem,
elevation=self.dem,
enmapIm_cornerCoords=self.corner_coords,
enmapIm_dims_sensorgeo=self.dims_sensorgeo,
CPUs=6
).compute_geolayer()
self.assertEqual(lons.shape, lats.shape)
self.assertEqual(lons.shape, (1024, 1000, 6))
self.assertFalse(np.array_equal(lons[:, :, 0], lons[:, :, 2]))
self.assertFalse(np.array_equal(lats[:, :, 0], lats[:, :, 2]))
def test_compute_geolayer_average_elevation(self):
lons, lats = RPC_3D_Geolayer_Generator(self._get_rpc_coeffs_with_multiple_coeff_sets(),
elevation=50.6,
enmapIm_cornerCoords=self.corner_coords,
enmapIm_dims_sensorgeo=self.dims_sensorgeo,
CPUs=6
......
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