Bases: DataObjectSupportingAggregation
Represents a Geo Raster Aggregation in HydroShare
Source code in hsclient\hydroshare.py
class GeoRasterAggregation(DataObjectSupportingAggregation):
"""Represents a Geo Raster Aggregation in HydroShare"""
@classmethod
def create(cls, base_aggr):
return super().create(aggr_cls=cls, base_aggr=base_aggr)
def _compute_updated_aggregation_path(self, temp_folder, *files) -> str:
file_path = ""
for _file in files:
filename = os.path.basename(_file)
if filename.endswith(".vrt"):
file_path = urljoin(temp_folder, filename)
break
else:
filename = pathlib.Path(filename).stem + ".vrt"
file_path = urljoin(temp_folder, filename)
break
return file_path
def _validate_aggregation_path(self, agg_path: str, for_save_data: bool = False) -> str:
if for_save_data:
tif_file_count = 0
vrt_file_count = 0
tif_file_path = ""
vrt_file_path = ""
for item in os.listdir(agg_path):
item_full_path = os.path.join(agg_path, item)
if os.path.isfile(item_full_path):
file_ext = pathlib.Path(item_full_path).suffix.lower()
if file_ext in (".tif", ".tiff"):
tif_file_count += 1
tif_file_path = item_full_path
elif file_ext == '.vrt':
vrt_file_path = item_full_path
vrt_file_count += 1
if vrt_file_count > 1:
raise Exception(f"Aggregation path '{agg_path}' is not a valid path. "
f"More than one vrt was file found")
else:
raise Exception(f"Aggregation path '{agg_path}' is not a valid path. "
f"There are files that are not of raster file types")
if tif_file_count == 0:
raise Exception(f"Aggregation path '{agg_path}' is not a valid path. "
f"No tif file was found")
if tif_file_count > 1 and vrt_file_count == 0:
raise Exception(f"Aggregation path '{agg_path}' is not a valid path. "
f"Missing a vrt file")
if vrt_file_path:
file_path = vrt_file_path
else:
file_path = tif_file_path
else:
file_path = self._get_file_path(agg_path)
return file_path
def as_data_object(self, agg_path: str) -> 'rasterio.DatasetReader':
"""
Loads the Geo Raster aggregation to a rasterio DatasetReader object
:param agg_path: the path to the Geo Raster aggregation
:return: the Geo Raster aggregation as a rasterio DatasetReader object
"""
if rasterio is None:
raise Exception("rasterio package was not found")
return self._get_data_object(agg_path=agg_path, func=rasterio.open)
def save_data_object(self, resource: 'Resource', agg_path: str, as_new_aggr: bool = False,
destination_path: str = "") -> 'Aggregation':
"""
Saves the rasterio DatasetReader object to the Geo Raster aggregation
:param resource: the resource containing the aggregation
:param agg_path: the path to the Geo Raster aggregation
:param as_new_aggr: Defaults False, set to True to create a new Geo Raster aggregation
:param destination_path: the destination path in Hydroshare to save the new aggregation
:return: the updated or new Geo Raster aggregation
"""
def upload_raster_files(dst_path=""):
raster_files = []
for item in os.listdir(agg_path):
item_full_path = os.path.join(agg_path, item)
if os.path.isfile(item_full_path):
raster_files.append(item_full_path)
if not dst_path:
self._update_aggregation(resource, *raster_files)
else:
resource.file_upload(*raster_files, destination_path=dst_path)
def get_main_file_path():
main_file_name = os.path.basename(file_path)
if not main_file_name.lower().endswith('.vrt'):
main_file_name = pathlib.Path(main_file_name).stem + ".vrt"
if destination_path:
aggr_main_file_path = os.path.join(destination_path, main_file_name)
else:
aggr_main_file_path = main_file_name
return aggr_main_file_path
self._validate_aggregation_for_update(resource, AggregationType.GeographicRasterAggregation)
file_path = self._validate_aggregation_path(agg_path, for_save_data=True)
if not as_new_aggr:
destination_path = dirname(self.main_file_path)
# cache some of the metadata fields of the original aggregation to update the metadata of the
# updated aggregation
keywords = self.metadata.subjects
additional_meta = self.metadata.additional_metadata
upload_raster_files(dst_path=destination_path)
aggr_main_file_path = get_main_file_path()
# retrieve the updated aggregation
aggr = resource.aggregation(file__path=aggr_main_file_path)
# update metadata
for kw in keywords:
if kw not in aggr.metadata.subjects:
aggr.metadata.subjects.append(kw)
aggr.metadata.additional_metadata = additional_meta
aggr.save()
else:
# creating a new aggregation by uploading the updated data files
upload_raster_files(dst_path=destination_path)
# retrieve the new aggregation
aggr_main_file_path = get_main_file_path()
agg_path = urljoin(destination_path, os.path.basename(aggr_main_file_path))
aggr = resource.aggregation(file__path=agg_path)
aggr._data_object = None
return aggr
as_data_object(agg_path)
Loads the Geo Raster aggregation to a rasterio DatasetReader object :param agg_path: the path to the Geo Raster aggregation :return: the Geo Raster aggregation as a rasterio DatasetReader object
Source code in hsclient\hydroshare.py
def as_data_object(self, agg_path: str) -> 'rasterio.DatasetReader':
"""
Loads the Geo Raster aggregation to a rasterio DatasetReader object
:param agg_path: the path to the Geo Raster aggregation
:return: the Geo Raster aggregation as a rasterio DatasetReader object
"""
if rasterio is None:
raise Exception("rasterio package was not found")
return self._get_data_object(agg_path=agg_path, func=rasterio.open)
save_data_object(resource, agg_path, as_new_aggr=False, destination_path='')
Saves the rasterio DatasetReader object to the Geo Raster aggregation :param resource: the resource containing the aggregation :param agg_path: the path to the Geo Raster aggregation :param as_new_aggr: Defaults False, set to True to create a new Geo Raster aggregation :param destination_path: the destination path in Hydroshare to save the new aggregation :return: the updated or new Geo Raster aggregation
Source code in hsclient\hydroshare.py
def save_data_object(self, resource: 'Resource', agg_path: str, as_new_aggr: bool = False,
destination_path: str = "") -> 'Aggregation':
"""
Saves the rasterio DatasetReader object to the Geo Raster aggregation
:param resource: the resource containing the aggregation
:param agg_path: the path to the Geo Raster aggregation
:param as_new_aggr: Defaults False, set to True to create a new Geo Raster aggregation
:param destination_path: the destination path in Hydroshare to save the new aggregation
:return: the updated or new Geo Raster aggregation
"""
def upload_raster_files(dst_path=""):
raster_files = []
for item in os.listdir(agg_path):
item_full_path = os.path.join(agg_path, item)
if os.path.isfile(item_full_path):
raster_files.append(item_full_path)
if not dst_path:
self._update_aggregation(resource, *raster_files)
else:
resource.file_upload(*raster_files, destination_path=dst_path)
def get_main_file_path():
main_file_name = os.path.basename(file_path)
if not main_file_name.lower().endswith('.vrt'):
main_file_name = pathlib.Path(main_file_name).stem + ".vrt"
if destination_path:
aggr_main_file_path = os.path.join(destination_path, main_file_name)
else:
aggr_main_file_path = main_file_name
return aggr_main_file_path
self._validate_aggregation_for_update(resource, AggregationType.GeographicRasterAggregation)
file_path = self._validate_aggregation_path(agg_path, for_save_data=True)
if not as_new_aggr:
destination_path = dirname(self.main_file_path)
# cache some of the metadata fields of the original aggregation to update the metadata of the
# updated aggregation
keywords = self.metadata.subjects
additional_meta = self.metadata.additional_metadata
upload_raster_files(dst_path=destination_path)
aggr_main_file_path = get_main_file_path()
# retrieve the updated aggregation
aggr = resource.aggregation(file__path=aggr_main_file_path)
# update metadata
for kw in keywords:
if kw not in aggr.metadata.subjects:
aggr.metadata.subjects.append(kw)
aggr.metadata.additional_metadata = additional_meta
aggr.save()
else:
# creating a new aggregation by uploading the updated data files
upload_raster_files(dst_path=destination_path)
# retrieve the new aggregation
aggr_main_file_path = get_main_file_path()
agg_path = urljoin(destination_path, os.path.basename(aggr_main_file_path))
aggr = resource.aggregation(file__path=agg_path)
aggr._data_object = None
return aggr