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