Commit 0531f649 authored by Daniel Scheffler's avatar Daniel Scheffler
Browse files

Band names and nodata values are now correctly read in case of data formats...


Band names and nodata values are now correctly read in case of data formats other than ENVI. Improved saved metadata for all formats (mainly applies to band names and nodata values). Fixed nodata value not passed through when reading a data format other than ENVI and saving in ENVI format. Updated HISTORY.rst.
Signed-off-by: Daniel Scheffler's avatarDaniel Scheffler <danschef@gfz-potsdam.de>
parent be93ae33
Pipeline #21613 passed with stage
in 2 minutes and 32 seconds
......@@ -2,10 +2,17 @@
History
=======
0.10.11 (coming soon)
---------------------
0.10.11 (2021-04-08)
--------------------
* Fixed another numpy data type DeprecationWarning.
* Added 'make docs' artifacts to .gitignore.
* Fixed undeleted output of Test_GeoArray.test_save().
* Added .gitkeep to tests/output/ folder.
* 'make lint' now directly prints the log outputs.
* Band names and nodata values are now correctly read in case of data formats other than ENVI.
* Improved saved metadata for all formats (mainly applies to band names and nodata values).
* Fixed nodata value not passed through when reading a data format other than ENVI and saving in ENVI format.
0.10.10 (2021-02-19)
......
......@@ -818,7 +818,6 @@ class GeoArray(object):
:param getitem_params: <list> a list of slices in the form [row_slice, col_slice, band_slice]
:return out_arr: <np.ndarray> the output array
"""
ds = gdal.Open(path)
if not ds:
raise Exception('Error reading file: ' + gdal.GetLastErrorMsg())
......@@ -1022,16 +1021,34 @@ class GeoArray(object):
# ENVI #
########
if fmt == 'ENVI':
ds_out.SetMetadata(envi_metadict, 'ENVI')
for bidx in range(self.bands):
band = ds_out.GetRasterBand(bidx + 1)
if 'band_names' in envi_metadict:
for bidx in range(self.bands):
band = ds_out.GetRasterBand(bidx + 1)
if 'band_names' in envi_metadict:
bandname = self.metadata.band_meta['band_names'][bidx].strip()
band.SetDescription(bandname)
assert band.GetDescription() == bandname
del band
# NOTE: band-specific nodata values are not supported by the ENVI header format
if 'nodata' in envi_metadict:
nodataVal = self.metadata.band_meta['nodata'][bidx]
band.SetNoDataValue(nodataVal)
assert band.GetNoDataValue() == nodataVal
del band
# avoid that band names are written to global meta
if 'band_names' in envi_metadict:
del envi_metadict['band_names']
if 'nodata' in envi_metadict:
del envi_metadict['nodata']
# set data ignore value in case self.metadata.band_meta contains a unique nodata value
if 'nodata' in self.metadata.band_meta and len(set(self.metadata.band_meta['nodata'])) == 1:
envi_metadict['data ignore value'] = str(self.metadata.band_meta['nodata'][0])
ds_out.SetMetadata(envi_metadict, 'ENVI')
if 'description' in envi_metadict:
ds_out.SetDescription(envi_metadict['description'])
......@@ -1052,12 +1069,22 @@ class GeoArray(object):
for bidx in range(self.bands):
band = ds_out.GetRasterBand(bidx + 1)
bandmeta = bandmeta_dict[bidx]
bandmeta = bandmeta_dict[bidx].copy()
# filter global metadata out
bandmeta = {k: v for k, v in bandmeta.items() if k not in self.metadata.global_meta}
# meta2write = dict((k, repr(v)) for k, v in self.metadata.band_meta.items() if v is not np.nan)
band.SetMetadata(bandmeta)
if 'band_names' in envi_metadict:
if 'band_names' in bandmeta:
band.SetDescription(self.metadata.band_meta['band_names'][bidx].strip())
del bandmeta['band_names']
if 'nodata' in bandmeta:
band.SetNoDataValue(self.metadata.band_meta['nodata'][bidx])
del bandmeta['nodata']
if bandmeta:
band.SetMetadata(bandmeta)
band.FlushCache()
del band
......
......@@ -196,6 +196,17 @@ class GDAL_Metadata(object):
# meta_gs = GeoSeries(band.GetMetadata())
bandmeta_dict = band.GetMetadata()
# read bandname
bandname = band.GetDescription()
if bandname:
bandmeta_dict['band_names'] = bandname
# read nodata value
nodataVal = band.GetNoDataValue()
if nodataVal is not None:
bandmeta_dict['nodata'] = nodataVal
# read remaining meta
for k, v in bandmeta_dict.items():
if k not in self.band_meta:
self.band_meta[k] = []
......
......@@ -424,14 +424,16 @@ class Test_GeoArray(TestCase):
with tempfile.NamedTemporaryFile(dir=os.path.join(tests_path, "tests", "data", "output"),
prefix="L8_BadDataMask10x11_copy_",
suffix=".tif") as tf:
# Save as temporary GTiff
L8_2bands_extract10x11_copy = tf.name
gA.save(L8_2bands_extract10x11_copy, fmt="GTiff")
gA_copy = GeoArray(L8_2bands_extract10x11_copy)
self.assertTrue(os.path.exists(L8_2bands_extract10x11_copy))
self.assertIsInstance(gA_copy, GeoArray)
self.assertTrue(np.array_equal(gA[:], gA_copy[:]))
# save GeoArray and validate output
for fmt in ['ENVI', 'GTiff']:
gA.save(tf.name, fmt=fmt)
gA_copy = GeoArray(tf.name)
self.assertTrue(os.path.exists(tf.name))
self.assertIsInstance(gA_copy, GeoArray)
self.assertTrue(np.array_equal(gA[:], gA_copy[:]))
self.assertEqual(gA._nodata, gA_copy._nodata)
def test_show(self):
# test 3D case
......
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