Commit 6fafc203 authored by Eva Schiffer's avatar Eva Schiffer
Browse files

better info message for GeoTIFF files

parent e1d6cf41
......@@ -1071,12 +1071,14 @@ class aeri(object):
returns a string, describing the file in a user readable format.
"""
# TODO, this is a temporary implementation to be replaced with more details soon
# TODO, this is a temporary implementation to be replaced with more details later
to_return = "File path: " + self._path + "\n"
to_return += "\tvariables:\n"
temp_vars = self()
for var_name in temp_vars :
to_return += "\t" + var_name + "\n"
to_return += "\t\t" + var_name + "\n"
return to_return
......@@ -1087,10 +1089,14 @@ class tiff (object):
"""wrapper for to open GeoTIFF data sets for comparison
__call__ yields sequence of variable names
__getitem__ returns individual variables ready for slicing to numpy arrays
Note: In the past I've had difficulty finding gdal documentation. Here's what I've been looking at:
https://gdal.org/doxygen/classGDALDataset.html
"""
_tiff = None
_path = None
_metadata = { }
GRAY_NAME = "grayscale value"
RED_NAME = "red"
......@@ -1141,7 +1147,43 @@ class tiff (object):
},
}
@staticmethod
def _get_tiff_datatypes_map ( ) :
"""
gdal currently has some attributes that tell about data types, but does not
have an enum, so roll our own using a dictionary
returns a dictionary maping the type numerical value to a string name based on the gdal attr name
"""
datatype_keys = [x for x in dir(gdal) if x.startswith("GDT_")]
datatype_map = { }
for key_value in datatype_keys :
datatype_map[getattr(gdal, key_value)] = key_value
return datatype_map
@staticmethod
def _get_all_metadata(file_obj, ):
"""
Given a gdal file object, get all the global metadata we can find in it.
returns a dictionary with hierarchical metadata info stored with string path keys
so it is no longer hierarchical, but rather a regular dictionary
"""
all_data = file_obj.GetMetadata().copy()
# now look to see if there are any other domains
all_domains = file_obj.GetMetadataDomainList()
for domain_name in all_domains:
temp_metadata = file_obj.GetMetadata(domain_name).copy()
for metadata_key in temp_metadata:
full_key = domain_name + '/' + metadata_key if len(domain_name) >= 1 else metadata_key
all_data[full_key] = temp_metadata[metadata_key]
return all_data
def _get_generic_band_name (self, number) :
"""get a generic band name for this number"""
......@@ -1173,9 +1215,11 @@ class tiff (object):
assert(gdal is not None)
if allowWrite:
LOG.warning("Write access requested, but is not currently supported for GeoTIFF files. File will be opened read-only.")
LOG.warning("Write access requested, but is not currently supported for GeoTIFF files. "
"File will be opened read-only.")
self._tiff = gdal.Open(filename)
self._metadata = tiff._get_all_metadata(self._tiff)
self.niceNames = useMeaningfulNames
self.revIndex = self.REV_INFO[self._tiff.RasterCount] if self._tiff.RasterCount in self.REV_INFO else { }
......@@ -1203,26 +1247,30 @@ class tiff (object):
def __getitem__(self, name):
LOG.debug("opening variable: " + name)
# first figure out the index for this variable
var_index = self._get_band_index_from_name(name)
# get the data out of the file
temp_band = self._tiff.GetRasterBand(var_index)
temp_band = self.get_variable_object(name)
temp_data = temp_band.ReadAsArray()
# there is no standard scaling procedure for GeoTIFFs, so skip that!
return temp_data
# TODO, this hasn't been supported in other file types
def close (self) :
# Dave couldn't find any explicit way to close it other
# than let the garbage collector take care of it
self._tiff = None
# Note: in future I may be able to use self._tiff.GDALClose()?
def get_variable_object(self, name):
return None
def get_variable_object(self, name) :
# first figure out the index for this variable
var_index = self._get_band_index_from_name(name)
# get the band object
temp_band = self._tiff.GetRasterBand(var_index)
return temp_band
def missing_value(self, name):
return None
......@@ -1238,7 +1286,8 @@ class tiff (object):
be created
"""
LOG.warning ("GeoTIFF io class does not yet support writing. Unable to create new variable in GeoTIFF file.")
LOG.warning ("GeoTIFF io class does not yet support writing. "
"Unable to create new variable in GeoTIFF file.")
return None
......@@ -1250,7 +1299,8 @@ class tiff (object):
if the attribute does not exist for the given variable, create it and set it to the new value
"""
LOG.warning ("GeoTIFF io class does not yet support writing. Unable to add attribute information to GeoTIFF file.")
LOG.warning ("GeoTIFF io class does not yet support writing. "
"Unable to add attribute information to GeoTIFF file.")
return
......@@ -1259,36 +1309,43 @@ class tiff (object):
returns all the attributes associated with a variable name
"""
# FUTURE, GeoTIFF files do have attributes, but this isn't hooked up yet
# this is not a perfect mapping, but for now, get the metadata for the variable
var_obj = self.get_variable_object(variableName,)
return { }
return var_obj.GetMetadata().copy()
def get_attribute(self, variableName, attributeName, caseInsensitive=True) :
"""
returns the value of the attribute if it is available for this variable, or None
"""
# FUTURE, GeoTIFF files do have attributes, but this isn't hooked up yet
return None
# this is not a perfect mapping, but for now, use the metadata for the variable
temp_attrs = self.get_variable_attributes(variableName)
to_return = temp_attrs[attributeName] if attributeName in temp_attrs else None
return to_return
def get_global_attributes(self, caseInsensitive=True) :
"""
get a list of all the global attributes for this file or None
"""
# FUTURE, GeoTIFF files do have attributes, but this isn't hooked up yet
# FUTURE, this is not a perfect mapping, there are other attributes
# like the projection we could get separtely
temp_metadata = tiff._get_all_metadata(self._tiff)
return { }
return temp_metadata
def get_global_attribute(self, attributeName, caseInsensitive=True) :
"""
returns the value of a global attribute if it is available or None
"""
# FUTURE, GeoTIFF files do have attributes, but this isn't hooked up yet
# check to see if our attributeName is available
temp_attrs = self.get_global_attributes()
to_return = temp_attrs[attributeName] if attributeName in temp_attrs else None
return None
return to_return
def is_loadable_type (self, name) :
"""
......@@ -1309,12 +1366,35 @@ class tiff (object):
returns a string, describing the file in a user readable format.
"""
# TODO, this is a temporary implementation to be replaced with more details soon
# identify the specific file with it's path
to_return = "File path: " + self._path + "\n"
# give some basic information about the file
to_return += "\tNumber of available bands: " + str(self._tiff.RasterCount) + "\n"
to_return += "\tData shape: (" + str(self._tiff.RasterYSize) + ", " \
+ str(self._tiff.RasterXSize) + ")" + "\n"
to_return += "\tProjection: " + str(self._tiff.GetProjection()) + "\n"
# add detailed variables info
to_return += "\tvariables:\n"
temp_vars = self()
for var_name in temp_vars :
to_return += "\t" + var_name + "\n"
v_object = self.get_variable_object(var_name)
temp_dtype = v_object.DataType
text_dtype = tiff._get_tiff_datatypes_map()[temp_dtype]
simple_name = self._get_generic_band_name(self._get_band_index_from_name(var_name))
to_return += "\t\t" + text_dtype + " " + var_name + " (" + simple_name + ")\n"
if show_attrs :
temp_attrs = self.get_variable_attributes(var_name, caseInsensitive=False, )
for attr_name in temp_attrs:
to_return += "\t\t\t" + attr_name + " = " + str(temp_attrs[attr_name]) + "\n"
# if we're showing attributes, show the global ones
if show_attrs :
to_return += "\tfile metadata: \n"
temp_g_attrs = self.get_global_attributes(caseInsensitive=False, )
for g_attr_name in temp_g_attrs:
to_return += "\t\t" + g_attr_name + " = " + str(temp_g_attrs[g_attr_name]) + "\n"
return to_return
......
Supports Markdown
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