예제 #1
0
def merge_items(source_item: pystac.Item,
                target_item: pystac.Item,
                move_assets: bool = False,
                ignore_conflicts: bool = False) -> None:
    """Merges the assets from source_item into target_item.

    The geometry and bounding box of the items will also be merged.

    Args:
        source_item (pystac.Item): The Item that will be merged into target_item.
            This item is not mutated in this operation.
        target_item (pystac.Item): The target item that will be merged into.
            This item will be mutated in this operation.
        move_assets (bool): If true, move the asset files alongside the target item.
        ignore_conflicts (bool): If True, assets with the same keys will not be merged,
            and asset files that would be moved to overwrite an existing file
            will not be moved. If False, either of these situations will throw an error.
    """
    target_item_href = target_item.get_self_href()
    if target_item_href is None:
        raise ValueError(
            f"Target Item {target_item.id} must have an HREF for merge")
    for key, asset in source_item.assets.items():
        if key in target_item.assets:
            if ignore_conflicts:
                continue
            else:
                raise Exception(
                    'Target item {} already has asset with key {}, '
                    'cannot merge asset in from {}'.format(
                        target_item, key, source_item))
        else:
            asset_href = asset.get_absolute_href()
            if asset_href is None:
                raise ValueError(
                    f"Asset {asset.title} must have an HREF for merge")
            if move_assets:
                new_asset_href = move_asset_file_to_item(
                    target_item, asset_href, ignore_conflicts=ignore_conflicts)
            else:
                if not is_absolute_href(asset.href):
                    asset_href = make_relative_href(asset_href,
                                                    target_item_href)
                new_asset_href = asset_href
            new_asset = asset.clone()
            new_asset.href = new_asset_href
            target_item.add_asset(key, new_asset)

    source_geom = shape(source_item.geometry)
    target_geom = shape(target_item.geometry)
    union_geom = source_geom.union(target_geom).buffer(0)
    target_item.geometry = mapping(union_geom)
    target_item.bbox = list(union_geom.bounds)
예제 #2
0
def move_assets(item: Item,
                asset_subdirectory: Optional[str] = None,
                make_hrefs_relative: bool = True,
                copy: bool = False,
                ignore_conflicts: bool = False) -> Item:
    """Moves assets for an item to be alongside that item.

    Args:
        item (Item): The PySTAC Item
            to perform the asset transformation on.
        asset_subdirectory (str or None): A subdirectory that will be used
            to store the assets. If not supplied, the assets will be moved
            or copied to the same directory as their item.
        make_assets_relative (bool): If True, will make the asset HREFs relative
            to the assets. If false, the asset will be an absolute href.
        copy (bool): If False this function will move the asset file; if True,
            the asset file will be copied.
        ignore_conflicts (bool): If the asset destination file already exists,
            this function will throw an error unless ignore_conflicts is True.

    Returns:
        Item: Returns an updated catalog or collection.
            This operation mutates the Item.
    """
    item_href = item.get_self_href()
    if item_href is None:
        raise ValueError(
            f"Self HREF is not available for item {item.id}. This operation "
            "requires that the Item HREFs are available.")

    for asset in item.assets.values():
        abs_asset_href = asset.get_absolute_href()
        if abs_asset_href is None:
            raise ValueError(
                f"Asset {asset.title} HREF is not available for item {item.id}. This operation "
                "requires that the Asset HREFs are available.")

        new_asset_href = move_asset_file_to_item(
            item,
            abs_asset_href,
            asset_subdirectory=asset_subdirectory,
            copy=copy,
            ignore_conflicts=ignore_conflicts)

        if make_hrefs_relative:
            asset.href = make_relative_href(new_asset_href, item_href)
        else:
            asset.href = new_asset_href

    return item
예제 #3
0
def add_raster_to_item(item: Item) -> Item:
    """Adds raster extension values to an item.

    Args:
        item (Item): The PySTAC Item to extend.

    Returns:
        Item: Returns an updated Item.
            This operation mutates the Item.
    """
    RasterExtension.add_to(item)
    for asset in item.assets.values():
        if asset.roles and "data" in asset.roles:
            raster = RasterExtension.ext(asset)
            href = make_absolute_href(asset.href, item.get_self_href())
            bands = _read_bands(href)
            if bands:
                raster.apply(bands)
    return item
예제 #4
0
def add_raster_to_item(item: Item) -> Item:
    """Adds raster extension values to an item.

    Args:
        item (Item): The PySTAC Item to extend.

    Returns:
        Item: Returns an updated Item.
            This operation mutates the Item.
    """
    RasterExtension.add_to(item)
    for asset in item.assets.values():
        if asset.roles and "data" in asset.roles:
            raster = RasterExtension.ext(asset)
            bands = []
            href = make_absolute_href(asset.href, item.get_self_href())
            dataset = gdal.Open(href, gdal.GA_ReadOnly)
            for nband in range(dataset.RasterCount):
                gdal_band = dataset.GetRasterBand(nband + 1)
                band = RasterBand.create()
                band.nodata = gdal_band.GetNoDataValue()
                band.spatial_resolution = dataset.GetGeoTransform()[1]
                band.data_type = DataType(
                    gdal.GetDataTypeName(gdal_band.DataType).lower())
                minimum = gdal_band.GetMinimum()
                maximum = gdal_band.GetMaximum()
                if not minimum or not max:
                    minimum, maximum = gdal_band.ComputeRasterMinMax(True)
                band.statistics = Statistics.create(minimum=minimum,
                                                    maximum=maximum)
                hist_data = gdal_band.GetHistogram(minimum, maximum,
                                                   NUM_BUCKETS)
                band.histogram = Histogram.create(NUM_BUCKETS, minimum,
                                                  maximum, hist_data)
                bands.append(band)
            if bands:
                raster.apply(bands)
    return item
예제 #5
0
파일: task.py 프로젝트: linz/geostore
 def get_item_href(self, item: Item, parent_dir: str) -> str:
     return str(item.get_self_href())
예제 #6
0
def move_asset_file_to_item(item: Item,
                            asset_href: str,
                            asset_subdirectory: Optional[str] = None,
                            copy: bool = False,
                            ignore_conflicts: bool = False) -> str:
    """Moves an asset file to be alongside that item.

    Args:
        item (Item): The PySTAC Item
            to perform the asset transformation on.
        asset_href (str): The absolute HREF to the asset file.
        asset_subdirectory (str or None): A subdirectory that will be used
            to store the assets. If not supplied, the assets will be moved
            or copied to the same directory as their item.
        copy (bool): If False this function will move the asset file; if True,
            the asset file will be copied.
        ignore_conflicts (bool): If the asset destination file already exists,
            this function will throw an error unless ignore_conflicts is True.

    Returns:
        str: The new absolute href for the asset file
    """
    item_href = item.get_self_href()
    if item_href is None:
        raise ValueError(
            f"Self HREF is not available for item {item.id}. This operation "
            "requires that the Item HREFs are available.")

    if not is_absolute_href(asset_href):
        raise ValueError('asset_href must be absolute.')

    item_dir = os.path.dirname(item_href)

    fname = os.path.basename(asset_href)
    if asset_subdirectory is None:
        target_dir = item_dir
    else:
        target_dir = os.path.join(item_dir, asset_subdirectory)
    new_asset_href = os.path.join(target_dir, fname)

    if asset_href != new_asset_href:
        dest_protocol = split_protocol(new_asset_href)[0]
        fs_dest = get_filesystem_class(dest_protocol)()
        op = None

        if fs_dest.exists(new_asset_href):
            if not ignore_conflicts:
                raise FileExistsError(
                    '{} already exists'.format(new_asset_href))
        else:
            if copy:

                def _op1(dry_run: bool = False) -> None:
                    logger.info("Copying {} to {}...".format(
                        asset_href, new_asset_href))
                    if not dry_run:
                        fs_dest.makedirs(os.path.dirname(new_asset_href),
                                         exist_ok=True)
                        with fsspec.open(asset_href, 'rb') as f_src:
                            with fsspec.open(new_asset_href, 'wb') as f_dst:
                                f_dst.write(f_src.read())

                op = _op1
            else:
                source_protocol = split_protocol(asset_href)[0]

                if source_protocol == dest_protocol:

                    def _op2(dry_run: bool = False) -> None:
                        logger.info("Moving {} to {}...".format(
                            asset_href, new_asset_href))
                        if not dry_run:
                            fs_dest.makedirs(os.path.dirname(new_asset_href),
                                             exist_ok=True)
                            fs_dest.move(asset_href, new_asset_href)

                    op = _op2
                else:

                    def _op3(dry_run: bool = False) -> None:
                        logger.info("Moving {} to {}...".format(
                            asset_href, new_asset_href))
                        if not dry_run:
                            fs_source = get_filesystem_class(source_protocol)()
                            fs_dest.makedirs(os.path.dirname(new_asset_href),
                                             exist_ok=True)
                            with fsspec.open(asset_href, 'rb') as f_src:
                                with fsspec.open(new_asset_href,
                                                 'wb') as f_dst:
                                    f_dst.write(f_src.read())
                            fs_source.delete(asset_href)

                    op = _op3

        if op is not None:
            op(dry_run=False)

    return new_asset_href