def item_mapper(item: pystac.Item) -> pystac.Item: new_assets = [ x for result in map(apply_asset_mapper, item.assets.items()) for x in result ] item.assets = dict(new_assets) return item
def transform_stac_to_stac(item: Item, enable_proj: bool = True, self_link: str = None, source_link: str = None) -> Item: """ Handle a 0.7.0 item and convert it to a 1.0.0.beta2 item. """ # Remove USGS extension and add back eo item.ext.enable("eo") # Add and update links item.links = [] if self_link: item.links.append(Link(rel="self", target=self_link)) if source_link: item.links.append( Link(rel="derived_from", target=source_link, media_type="application/json")) # Add some common fields item.common_metadata.constellation = "Landsat" item.common_metadata.instruments = [ i.lower() for i in item.properties["eo:instrument"].split("_") ] del item.properties["eo:instrument"] # Handle view extension item.ext.enable("view") item.ext.view.off_nadir = item.properties["eo:off_nadir"] del item.properties["eo:off_nadir"] if enable_proj: try: # If we can load the blue band, use it to add proj information blue_asset = item.assets["SR_B2.TIF"] blue = rasterio.open(blue_asset.href) shape = [blue.height, blue.width] transform = blue.transform crs = blue.crs.to_epsg() # Now we have the info, we can make the fields item.ext.enable("projection") item.ext.projection.epsg = crs new_assets = {} for name, asset in item.assets.items(): if asset.media_type == "image/vnd.stac.geotiff; cloud-optimized=true": item.ext.projection.set_transform(transform, asset=asset) item.ext.projection.set_shape(shape, asset=asset) asset.media_type = MediaType.COG except RasterioIOError: print("Failed to load blue band, so not handling proj fields") # Remove .TIF from asset names new_assets = {} for name, asset in item.assets.items(): new_name = name.replace(".TIF", "") new_assets[new_name] = asset item.assets = new_assets return item
def transform_stac_to_stac(item: Item, enable_proj: bool = True, self_link: str = None, source_link: str = None) -> Item: """ Handle a 0.7.0 item and convert it to a 1.0.0.beta2 item. If `enable_proj` is true, the assets' geotiff files must be accessible. """ # Clear hierarchical links item.set_parent(None) item.set_root(None) # Remove USGS extension and add back eo item.ext.enable("eo") # Add and update links if self_link: item.links.append(Link(rel="self", target=self_link)) if source_link: item.links.append( Link(rel="derived_from", target=source_link, media_type="application/json")) # Add some common fields item.common_metadata.constellation = "Landsat" if not item.properties.get("eo:instrument"): raise STACError("eo:instrument missing among the properties") # Test if eo:instrument come as str or list if isinstance(item.properties["eo:instrument"], str): item.common_metadata.instruments = [ i.lower() for i in item.properties.pop("eo:instrument").split("_") ] elif isinstance(item.properties["eo:instrument"], list): item.common_metadata.instruments = [ i.lower() for i in item.properties.pop("eo:instrument") ] else: raise STACError( f'eo:instrument type {type(item.properties["eo:instrument"])} not supported' ) # Handle view extension item.ext.enable("view") if (item.properties.get("eo:off_nadir") or item.properties.get("eo:off_nadir") == 0): item.ext.view.off_nadir = item.properties.pop("eo:off_nadir") elif (item.properties.get("view:off_nadir") or item.properties.get("view:off_nadir") == 0): item.ext.view.off_nadir = item.properties.pop("view:off_nadir") else: STACError("eo:off_nadir or view:off_nadir is a required property") if enable_proj: # Enabled projection item.ext.enable("projection") obtained_shape = None obtained_transform = None crs = None for asset in item.assets.values(): if "geotiff" in asset.media_type: # retrieve shape, transform and crs from the first geotiff file among the assets if not obtained_shape: try: with rasterio.open(asset.href) as opened_asset: obtained_shape = opened_asset.shape obtained_transform = opened_asset.transform crs = opened_asset.crs.to_epsg() # Check to ensure that all information is present if not obtained_shape or not obtained_transform or not crs: raise STACError( f"Failed setting shape, transform and csr from {asset.href}" ) except RasterioIOError as io_error: raise STACError( "Failed loading geotiff, so not handling proj fields" ) from io_error item.ext.projection.set_transform(obtained_transform, asset=asset) item.ext.projection.set_shape(obtained_shape, asset=asset) asset.media_type = MediaType.COG # Now we have the info, we can make the fields item.ext.projection.epsg = crs # Remove .TIF from asset names item.assets = { name.replace(".TIF", ""): asset for name, asset in item.assets.items() } return item