Commit 7bc08f6d authored by Daniel Scheffler's avatar Daniel Scheffler

Added a first prototype of a metadata class.

parent 85db94cb
# -*- coding: utf-8 -*-
import os
from pprint import pformat
from geopandas import GeoDataFrame, GeoSeries
try:
from osgeo import gdal
except ImportError:
import gdal
autohandled_meta = [
'bands',
'byte_order',
'coordinate_system_string',
'data_type',
'file_type',
'header_offset',
'interleave',
'lines',
'samples',
]
class GDAL_Metadata(object):
def __init__(self, filePath='', nbands=1):
# privates
self._global_meta = dict()
self._band_meta = dict()
self.bands = nbands
self.filePath = filePath
self.format = ''
if filePath:
self.read_from_file(filePath)
@classmethod
def from_file(cls, filePath):
return GDAL_Metadata(filePath=filePath)
@classmethod
def from_DataFrame(cls, dataframe):
# type: (GeoDataFrame) -> 'GDAL_Metadata'
if dataframe.empty:
raise ValueError('DataFame must not be empty.')
GDMD = GDAL_Metadata(nbands=dataframe.shape[1])
GDMD.df = dataframe
return GDMD
def to_DataFrame(self):
df = GeoDataFrame(columns=range(self.bands))
# add global meta
for k, v in self.global_meta.items():
df.loc[k] = GeoSeries(dict(zip(df.columns, [v] * len(df.columns))))
# add band meta
for k, v in self.band_meta.items():
df.loc[k] = GeoSeries(dict(zip(df.columns, v)))
return df
@property
def global_meta(self):
if not self._global_meta:
pass
return self._global_meta
@global_meta.setter
def global_meta(self, meta_dict):
if not isinstance(meta_dict, dict):
raise TypeError("Expected type 'dict', received '%s'." % type(meta_dict))
self._global_meta = meta_dict
@property
def band_meta(self):
if not self._band_meta:
pass
return self._band_meta
@band_meta.setter
def band_meta(self, value):
pass
@property
def all_meta(self):
all_meta = self.global_meta.copy()
all_meta.update(self.band_meta)
return all_meta
@staticmethod
def _convert_str_parameter(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:
return param_value
def read_from_file(self, filePath):
assert ' ' not in filePath, "The given path contains whitespaces. This is not supported by GDAL."
if not os.path.exists(filePath):
raise FileNotFoundError(filePath)
ds = gdal.Open(filePath)
try:
if not ds:
raise Exception('Error reading file: ' + gdal.GetLastErrorMsg())
self.bands = ds.RasterCount
self.format = ds.GetDriver().GetDescription()
###############
# ENVI format #
###############
if self.format == 'ENVI':
metadict = ds.GetMetadata('ENVI')
for k, v in metadict.items():
if k not in autohandled_meta:
if len(v.split(',')) == self.bands:
# band meta parameter
item_list = [
item_str.split('{')[1].strip() if item_str.strip().startswith('{') else
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_parameter(item_str) for item_str in item_list]
else:
# global meta parameter
self.global_meta[k] = self._convert_str_parameter(v)
#####################
# remaining formats #
#####################
else:
# read global domain metadata
self.global_meta = ds.GetMetadata()
# read band domain metadata
for b in range(self.bands):
band = ds.GetRasterBand(b + 1)
# meta_gs = GeoSeries(band.GetMetadata())
bandmeta_dict = band.GetMetadata()
for k, v in bandmeta_dict.items():
if k not in self.band_meta:
self.band_meta[k] = []
self.band_meta[k].append(self._convert_str_parameter(v))
# # fill metadata
# self.df[b] = meta_gs
del band
finally:
del ds
return self.all_meta
def __repr__(self):
return pformat(self.all_meta)
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from unittest import TestCase
from geoarray.metadata import GDAL_Metadata
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
def test_init(self):
GDAL_Metadata(self.test_filePath)
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