Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
Daniel Scheffler
geoarray
Commits
e04db20b
Commit
e04db20b
authored
Aug 07, 2018
by
Daniel Scheffler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
First implementation of metadata class in GeoArray.
parent
7bc08f6d
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
65 additions
and
52 deletions
+65
-52
geoarray/baseclasses.py
geoarray/baseclasses.py
+29
-46
geoarray/metadata.py
geoarray/metadata.py
+26
-5
tests/test_metadata.py
tests/test_metadata.py
+10
-1
No files found.
geoarray/baseclasses.py
View file @
e04db20b
...
...
@@ -40,6 +40,7 @@ from py_tools_ds.numeric.array import get_array_tilebounds
# internal imports
from
.subsetting
import
get_array_at_mapPos
from
.metadata
import
GDAL_Metadata
if
PY3
:
# noinspection PyCompatibility
...
...
@@ -171,7 +172,7 @@ class GeoArray(object):
# update bandnames in metadata
if
self
.
_metadata
is
not
None
:
self
.
metadata
.
loc
[
'band_name'
,
:
]
=
list_bandnames
self
.
metadata
.
band_meta
[
'band_name
s
'
]
=
list_bandnames
else
:
del
self
.
bandnames
...
...
@@ -499,9 +500,8 @@ class GeoArray(object):
if
self
.
_metadata
is
not
None
:
return
self
.
_metadata
else
:
default
=
GeoDataFrame
(
columns
=
range
(
self
.
bands
))
# for bn,idx in self.bandnames.items():
# default.loc['band_index',bn] = idx
default
=
GDAL_Metadata
(
nbands
=
self
.
bands
)
self
.
_metadata
=
default
if
not
self
.
is_inmem
:
self
.
set_gdalDataset_meta
()
...
...
@@ -717,28 +717,13 @@ class GeoArray(object):
# FIXME this does not support different nodata values within the same file
self
.
_nodata
=
band
.
GetNoDataValue
()
# read global domain metadata
# TODO check to specifically use the 'ENVI' metadata domain ds.GetMetadata('ENVI')
global_meta
=
ds
.
GetMetadata
()
# read band domain metadata
for
b
in
range
(
self
.
bands
):
band
=
ds
.
GetRasterBand
(
b
+
1
)
meta_gs
=
GeoSeries
(
band
.
GetMetadata
())
# add band names if available
if
'Band_%s'
%
str
(
b
+
1
)
in
global_meta
.
keys
():
meta_gs
[
'band_name'
]
=
global_meta
[
'Band_%s'
%
str
(
b
+
1
)]
# TODO add the remaining global metadata
# set metadata attribute
if
self
.
is_inmem
or
not
self
.
filePath
:
# metadata cannot be read from disk -> set it to the default
self
.
_metadata
=
GDAL_Metadata
(
nbands
=
self
.
bands
)
# avoid double-call of set_gdalDataset_meta by setting self._metadata to default value
self
.
_metadata
=
\
self
.
_metadata
if
self
.
_metadata
is
not
None
else
GeoDataFrame
(
columns
=
range
(
self
.
bands
))
# fill metadata
self
.
metadata
[
b
]
=
meta_gs
del
band
else
:
self
.
_metadata
=
GDAL_Metadata
(
filePath
=
self
.
filePath
)
del
ds
...
...
@@ -909,32 +894,30 @@ class GeoArray(object):
# set metadata
# NOTE: The dataset has to be written BEFORE metadata are added. Otherwise, metadata are not written.
if
not
self
.
metadata
.
empty
:
global_meta
=
{}
if
fmt
==
'ENVI'
:
envi_metadict
=
self
.
metadata
.
to_ENVI_metadict
()
ds_out
.
SetMetadata
(
envi_metadict
,
'ENVI'
)
# set band domain metadata
for
bidx
in
range
(
self
.
bands
):
band
=
ds_out
.
GetRasterBand
(
bidx
+
1
)
meta2write
=
self
.
metadata
[
bidx
].
to_dict
()
meta2write
=
dict
((
k
,
repr
(
v
))
for
k
,
v
in
meta2write
.
items
()
if
v
is
not
np
.
nan
)
if
'band_names'
in
envi_metadict
:
ds_out
.
SetMetadata
({
'Band_%s'
%
str
(
bidx
+
1
):
self
.
metadata
.
band_meta
[
'band_names'
][
bidx
]
for
bidx
in
range
(
self
.
bands
)})
if
'band_name'
in
meta2write
:
global_meta
[
'Band_%s'
%
str
(
bidx
+
1
)]
=
str
(
meta2write
[
'band_name'
])
del
meta2write
[
'band_name'
]
ds_out
.
FlushCache
()
gdal
.
Unlink
(
out_path
+
'.aux.xml'
)
band
.
SetMetadata
(
meta2write
)
band
.
FlushCache
()
del
band
elif
self
.
metadata
.
all_meta
:
# set global domain metadata
if
self
.
metadata
.
global_meta
:
ds_out
.
SetMetadata
(
self
.
metadata
.
global_meta
)
# set global domain metadata
if
global_meta
:
ds_out
.
SetMetadata
(
global_meta
)
# set band domain metadata
for
bidx
in
range
(
self
.
bands
):
band
=
ds_out
.
GetRasterBand
(
bidx
+
1
)
meta2write
=
dict
((
k
,
repr
(
v
))
for
k
,
v
in
self
.
metadata
.
band_meta
.
items
()
if
v
is
not
np
.
nan
)
# get ENVI metadata domain
# ds_orig = gdal.Open(self.filePath)
# envi_meta_domain = ds_orig.GetMetadata('ENVI')
# ds.SetMetadata(envi_meta_domain, 'ENVI')
# ds_orig = None
band
.
SetMetadata
(
meta2write
)
band
.
FlushCache
()
del
band
ds_out
.
FlushCache
()
...
...
geoarray/metadata.py
View file @
e04db20b
...
...
@@ -97,13 +97,30 @@ class GDAL_Metadata(object):
return
all_meta
@
staticmethod
def
_convert_
str_
param
ete
r
(
param_value
):
def
_convert_param
_from_st
r
(
param_value
):
try
:
try
:
return
int
(
param_value
)
# NOTE: float('0.34') causes ValueError: invalid literal for int() with base 10
except
ValueError
:
return
float
(
param_value
)
except
ValueError
:
if
param_value
.
startswith
(
'{'
):
param_value
=
param_value
.
split
(
'{'
)[
1
]
if
param_value
.
endswith
(
'}'
):
param_value
=
param_value
.
split
(
'}'
)[
0
]
return
param_value
.
strip
()
def
_convert_param_to_ENVI_str
(
self
,
param_value
):
if
isinstance
(
param_value
,
int
):
return
str
(
param_value
)
elif
isinstance
(
param_value
,
float
):
return
'%f'
%
param_value
elif
isinstance
(
param_value
,
list
):
return
'{ '
+
', '
.
join
([
self
.
_convert_param_to_ENVI_str
(
i
)
for
i
in
param_value
])
+
' }'
else
:
return
param_value
def
read_from_file
(
self
,
filePath
):
...
...
@@ -139,11 +156,11 @@ class GDAL_Metadata(object):
item_str
.
split
(
'}'
)[
0
].
strip
()
if
item_str
.
strip
().
endswith
(
'}'
)
else
item_str
.
strip
()
for
item_str
in
v
.
split
(
','
)]
self
.
band_meta
[
k
]
=
[
self
.
_convert_
str_
param
ete
r
(
item_str
)
for
item_str
in
item_list
]
self
.
band_meta
[
k
]
=
[
self
.
_convert_param
_from_st
r
(
item_str
)
for
item_str
in
item_list
]
else
:
# global meta parameter
self
.
global_meta
[
k
]
=
self
.
_convert_
str_
param
ete
r
(
v
)
self
.
global_meta
[
k
]
=
self
.
_convert_param
_from_st
r
(
v
)
#####################
# remaining formats #
...
...
@@ -163,7 +180,7 @@ class GDAL_Metadata(object):
if
k
not
in
self
.
band_meta
:
self
.
band_meta
[
k
]
=
[]
self
.
band_meta
[
k
].
append
(
self
.
_convert_
str_
param
ete
r
(
v
))
self
.
band_meta
[
k
].
append
(
self
.
_convert_param
_from_st
r
(
v
))
# # fill metadata
# self.df[b] = meta_gs
...
...
@@ -175,4 +192,8 @@ class GDAL_Metadata(object):
return
self
.
all_meta
def
__repr__
(
self
):
return
pformat
(
self
.
all_meta
)
return
'Metadata:
\n\n
'
+
pformat
(
self
.
all_meta
)
def
to_ENVI_metadict
(
self
):
return
dict
(
zip
(
self
.
all_meta
.
keys
(),
[
self
.
_convert_param_to_ENVI_str
(
i
)
for
i
in
self
.
all_meta
.
values
()]))
tests/test_metadata.py
View file @
e04db20b
...
...
@@ -4,12 +4,21 @@
from
unittest
import
TestCase
from
geoarray.metadata
import
GDAL_Metadata
from
geoarray
import
GeoArray
class
Test_GDAL_Metadata
(
TestCase
):
def
setUp
(
self
):
self
.
test_filePath
=
'/home/gfz-fe/scheffler/temp/SPECHOM/ORIG_DATA/'
\
'f130502t01p00r09_refl_master_calibration_Aviris.bsq'
# FIXME
self
.
test_outfilePath
=
'/home/gfz-fe/scheffler/temp/SPECHOM_py/debugging/'
\
'f130502t01p00r09_refl_master_calibration_Aviris_out.bsq'
# FIXME
def
test_init
(
self
):
GDAL_Metadata
(
self
.
test_filePath
)
meta
=
GDAL_Metadata
(
self
.
test_filePath
)
self
.
assertIsInstance
(
meta
,
GDAL_Metadata
)
def
test_save
(
self
):
gA
=
GeoArray
(
self
.
test_filePath
)
gA
.
to_mem
()
gA
.
save
(
self
.
test_outfilePath
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment