Skip to content
This repository has been archived by the owner on Sep 23, 2024. It is now read-only.

proj:transform and proj:shape in assets #11

Open
rmg55 opened this issue Mar 5, 2021 · 10 comments
Open

proj:transform and proj:shape in assets #11

rmg55 opened this issue Mar 5, 2021 · 10 comments

Comments

@rmg55
Copy link

rmg55 commented Mar 5, 2021

It looks like some catalogs have the transform and shape in the assets (I think that is the correct term) rather than the properties. Probably due to the bands/assets have different resolutions. For instance:

import satsearch
URL='https://earth-search.aws.element84.com/v0'
results = satsearch.Search.search(url=URL,
                                  collections=['sentinel-s2-l2a-cogs'],
                                  bbox=[-105.791,39.783,-103.677,41.870],
                                  datetime='2021-02-27/2021-02-27')
stac_catalog = results.query()
#Just use the cogs
stac_items = [f for f in stac_catalog['features'] if f['collection']=='sentinel-s2-l2a-cogs']
stac_items[0]
output
{'type': 'Feature',
 'stac_version': '1.0.0-beta.2',
 'stac_extensions': ['eo', 'view', 'proj'],
 'id': 'S2A_30VXK_20210305_0_L2A',
 'bbox': [-0.29262403233012585,
  58.46076357917498,
  0.6099851126869734,
  58.612152234653784],
 'geometry': {'type': 'Polygon',
  'coordinates': [[[0.5967195657827756, 58.46076357917498],
    [-0.2908733182739893, 58.61116185262608],
    [-0.29262403233012585, 58.612152234653784],
    [0.6099851126869734, 58.58996039069121],
    [0.5967195657827756, 58.46076357917498]]]},
 'properties': {'datetime': '2021-03-05T11:24:56Z',
  'platform': 'sentinel-2a',
  'constellation': 'sentinel-2',
  'instruments': ['msi'],
  'gsd': 10,
  'view:off_nadir': 0,
  'proj:epsg': 32630,
  'sentinel:utm_zone': 30,
  'sentinel:latitude_band': 'V',
  'sentinel:grid_square': 'XK',
  'sentinel:sequence': '0',
  'sentinel:product_id': 'S2A_MSIL2A_20210305T112111_N0214_R037_T30VXK_20210305T121545',
  'sentinel:data_coverage': 3.1,
  'eo:cloud_cover': 4.65,
  'sentinel:valid_cloud_cover': True,
  'created': '2021-03-05T18:17:22.360Z',
  'updated': '2021-03-05T18:17:22.360Z'},
 'collection': 'sentinel-s2-l2a-cogs',
 'assets': {'thumbnail': {'title': 'Thumbnail',
   'type': 'image/png',
   'roles': ['thumbnail'],
   'href': 'https://roda.sentinel-hub.com/sentinel-s2-l1c/tiles/30/V/XK/2021/3/5/0/preview.jpg'},
  'overview': {'title': 'True color image',
   'type': 'image/tiff; application=geotiff; profile=cloud-optimized',
   'roles': ['overview'],
   'gsd': 10,
   'eo:bands': [{'name': 'B04',
     'common_name': 'red',
     'center_wavelength': 0.6645,
     'full_width_half_max': 0.038},
    {'name': 'B03',
     'common_name': 'green',
     'center_wavelength': 0.56,
     'full_width_half_max': 0.045},
    {'name': 'B02',
     'common_name': 'blue',
     'center_wavelength': 0.4966,
     'full_width_half_max': 0.098}],
   'href': 'https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/XK/2021/3/S2A_30VXK_20210305_0_L2A/L2A_PVI.tif',
   'proj:shape': [343, 343],
   'proj:transform': [320, 0, 600000, 0, -320, 6500040, 0, 0, 1]},
  'info': {'title': 'Original JSON metadata',
   'type': 'application/json',
   'roles': ['metadata'],
   'href': 'https://roda.sentinel-hub.com/sentinel-s2-l2a/tiles/30/V/XK/2021/3/5/0/tileInfo.json'},
  'metadata': {'title': 'Original XML metadata',
   'type': 'application/xml',
   'roles': ['metadata'],
   'href': 'https://roda.sentinel-hub.com/sentinel-s2-l2a/tiles/30/V/XK/2021/3/5/0/metadata.xml'},
  'visual': {'title': 'True color image',
   'type': 'image/tiff; application=geotiff; profile=cloud-optimized',
   'roles': ['overview'],
   'gsd': 10,
   'eo:bands': [{'name': 'B04',
     'common_name': 'red',
     'center_wavelength': 0.6645,
     'full_width_half_max': 0.038},
    {'name': 'B03',
     'common_name': 'green',
     'center_wavelength': 0.56,
     'full_width_half_max': 0.045},
    {'name': 'B02',
     'common_name': 'blue',
     'center_wavelength': 0.4966,
     'full_width_half_max': 0.098}],
   'href': 'https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/XK/2021/3/S2A_30VXK_20210305_0_L2A/TCI.tif',
   'proj:shape': [10980, 10980],
   'proj:transform': [10, 0, 600000, 0, -10, 6500040, 0, 0, 1]},
  'B01': {'title': 'Band 1 (coastal)',
   'type': 'image/tiff; application=geotiff; profile=cloud-optimized',
   'roles': ['data'],
   'gsd': 60,
   'eo:bands': [{'name': 'B01',
     'common_name': 'coastal',
     'center_wavelength': 0.4439,
     'full_width_half_max': 0.027}],
   'href': 'https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/XK/2021/3/S2A_30VXK_20210305_0_L2A/B01.tif',
   'proj:shape': [1830, 1830],
   'proj:transform': [60, 0, 600000, 0, -60, 6500040, 0, 0, 1]},
  'B02': {'title': 'Band 2 (blue)',
   'type': 'image/tiff; application=geotiff; profile=cloud-optimized',
   'roles': ['data'],
   'gsd': 10,
   'eo:bands': [{'name': 'B02',
     'common_name': 'blue',
     'center_wavelength': 0.4966,
     'full_width_half_max': 0.098}],
   'href': 'https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/XK/2021/3/S2A_30VXK_20210305_0_L2A/B02.tif',
   'proj:shape': [10980, 10980],
   'proj:transform': [10, 0, 600000, 0, -10, 6500040, 0, 0, 1]},
  'B03': {'title': 'Band 3 (green)',
   'type': 'image/tiff; application=geotiff; profile=cloud-optimized',
   'roles': ['data'],
   'gsd': 10,
   'eo:bands': [{'name': 'B03',
     'common_name': 'green',
     'center_wavelength': 0.56,
     'full_width_half_max': 0.045}],
   'href': 'https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/XK/2021/3/S2A_30VXK_20210305_0_L2A/B03.tif',
   'proj:shape': [10980, 10980],
   'proj:transform': [10, 0, 600000, 0, -10, 6500040, 0, 0, 1]},
  'B04': {'title': 'Band 4 (red)',
   'type': 'image/tiff; application=geotiff; profile=cloud-optimized',
   'roles': ['data'],
   'gsd': 10,
   'eo:bands': [{'name': 'B04',
     'common_name': 'red',
     'center_wavelength': 0.6645,
     'full_width_half_max': 0.038}],
   'href': 'https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/XK/2021/3/S2A_30VXK_20210305_0_L2A/B04.tif',
   'proj:shape': [10980, 10980],
   'proj:transform': [10, 0, 600000, 0, -10, 6500040, 0, 0, 1]},
  'B05': {'title': 'Band 5',
   'type': 'image/tiff; application=geotiff; profile=cloud-optimized',
   'roles': ['data'],
   'gsd': 20,
   'eo:bands': [{'name': 'B05',
     'center_wavelength': 0.7039,
     'full_width_half_max': 0.019}],
   'href': 'https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/XK/2021/3/S2A_30VXK_20210305_0_L2A/B05.tif',
   'proj:shape': [5490, 5490],
   'proj:transform': [20, 0, 600000, 0, -20, 6500040, 0, 0, 1]},
  'B06': {'title': 'Band 6',
   'type': 'image/tiff; application=geotiff; profile=cloud-optimized',
   'roles': ['data'],
   'gsd': 20,
   'eo:bands': [{'name': 'B06',
     'center_wavelength': 0.7402,
     'full_width_half_max': 0.018}],
   'href': 'https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/XK/2021/3/S2A_30VXK_20210305_0_L2A/B06.tif',
   'proj:shape': [5490, 5490],
   'proj:transform': [20, 0, 600000, 0, -20, 6500040, 0, 0, 1]},
  'B07': {'title': 'Band 7',
   'type': 'image/tiff; application=geotiff; profile=cloud-optimized',
   'roles': ['data'],
   'gsd': 20,
   'eo:bands': [{'name': 'B07',
     'center_wavelength': 0.7825,
     'full_width_half_max': 0.028}],
   'href': 'https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/XK/2021/3/S2A_30VXK_20210305_0_L2A/B07.tif',
   'proj:shape': [5490, 5490],
   'proj:transform': [20, 0, 600000, 0, -20, 6500040, 0, 0, 1]},
  'B08': {'title': 'Band 8 (nir)',
   'type': 'image/tiff; application=geotiff; profile=cloud-optimized',
   'roles': ['data'],
   'gsd': 10,
   'eo:bands': [{'name': 'B08',
     'common_name': 'nir',
     'center_wavelength': 0.8351,
     'full_width_half_max': 0.145}],
   'href': 'https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/XK/2021/3/S2A_30VXK_20210305_0_L2A/B08.tif',
   'proj:shape': [10980, 10980],
   'proj:transform': [10, 0, 600000, 0, -10, 6500040, 0, 0, 1]},
  'B8A': {'title': 'Band 8A',
   'type': 'image/tiff; application=geotiff; profile=cloud-optimized',
   'roles': ['data'],
   'gsd': 20,
   'eo:bands': [{'name': 'B8A',
     'center_wavelength': 0.8648,
     'full_width_half_max': 0.033}],
   'href': 'https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/XK/2021/3/S2A_30VXK_20210305_0_L2A/B8A.tif',
   'proj:shape': [5490, 5490],
   'proj:transform': [20, 0, 600000, 0, -20, 6500040, 0, 0, 1]},
  'B09': {'title': 'Band 9',
   'type': 'image/tiff; application=geotiff; profile=cloud-optimized',
   'roles': ['data'],
   'gsd': 60,
   'eo:bands': [{'name': 'B09',
     'center_wavelength': 0.945,
     'full_width_half_max': 0.026}],
   'href': 'https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/XK/2021/3/S2A_30VXK_20210305_0_L2A/B09.tif',
   'proj:shape': [1830, 1830],
   'proj:transform': [60, 0, 600000, 0, -60, 6500040, 0, 0, 1]},
  'B11': {'title': 'Band 11 (swir16)',
   'type': 'image/tiff; application=geotiff; profile=cloud-optimized',
   'roles': ['data'],
   'gsd': 20,
   'eo:bands': [{'name': 'B11',
     'common_name': 'swir16',
     'center_wavelength': 1.6137,
     'full_width_half_max': 0.143}],
   'href': 'https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/XK/2021/3/S2A_30VXK_20210305_0_L2A/B11.tif',
   'proj:shape': [5490, 5490],
   'proj:transform': [20, 0, 600000, 0, -20, 6500040, 0, 0, 1]},
  'B12': {'title': 'Band 12 (swir22)',
   'type': 'image/tiff; application=geotiff; profile=cloud-optimized',
   'roles': ['data'],
   'gsd': 20,
   'eo:bands': [{'name': 'B12',
     'common_name': 'swir22',
     'center_wavelength': 2.22024,
     'full_width_half_max': 0.242}],
   'href': 'https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/XK/2021/3/S2A_30VXK_20210305_0_L2A/B12.tif',
   'proj:shape': [5490, 5490],
   'proj:transform': [20, 0, 600000, 0, -20, 6500040, 0, 0, 1]},
  'AOT': {'title': 'Aerosol Optical Thickness (AOT)',
   'type': 'image/tiff; application=geotiff; profile=cloud-optimized',
   'roles': ['data'],
   'href': 'https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/XK/2021/3/S2A_30VXK_20210305_0_L2A/AOT.tif',
   'proj:shape': [1830, 1830],
   'proj:transform': [60, 0, 600000, 0, -60, 6500040, 0, 0, 1]},
  'WVP': {'title': 'Water Vapour (WVP)',
   'type': 'image/tiff; application=geotiff; profile=cloud-optimized',
   'roles': ['data'],
   'href': 'https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/XK/2021/3/S2A_30VXK_20210305_0_L2A/WVP.tif',
   'proj:shape': [10980, 10980],
   'proj:transform': [10, 0, 600000, 0, -10, 6500040, 0, 0, 1]},
  'SCL': {'title': 'Scene Classification Map (SCL)',
   'type': 'image/tiff; application=geotiff; profile=cloud-optimized',
   'roles': ['data'],
   'href': 'https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/XK/2021/3/S2A_30VXK_20210305_0_L2A/SCL.tif',
   'proj:shape': [5490, 5490],
   'proj:transform': [20, 0, 600000, 0, -20, 6500040, 0, 0, 1]}},
 'links': [{'rel': 'self',
   'href': 'https://earth-search.aws.element84.com/v0/collections/sentinel-s2-l2a-cogs/items/S2A_30VXK_20210305_0_L2A'},
  {'rel': 'canonical',
   'href': 'https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/30/V/XK/2021/3/S2A_30VXK_20210305_0_L2A/S2A_30VXK_20210305_0_L2A.json',
   'type': 'application/json'},
  {'title': 'sentinel-s2-l2a-aws/workflow-publish-sentinel/tiles-30-V-XK-2021-3-5-0',
   'rel': 'via-cirrus',
   'href': 'https://cirrus-earth-search.aws.element84.com/v0/catid/sentinel-s2-l2a-aws/workflow-publish-sentinel/tiles-30-V-XK-2021-3-5-0'},
  {'title': 'Source STAC Item',
   'rel': 'derived_from',
   'href': 'https://cirrus-v0-data-1qm7gekzjucbq.s3.us-west-2.amazonaws.com/sentinel-s2-l2a/30/V/XK/2021/3/S2A_30VXK_20210305_0_L2A/S2A_30VXK_20210305_0_L2A.json',
   'type': 'application/json'},
  {'title': 'sentinel-s2-l2a/workflow-cog-archive/S2A_30VXK_20210305_0_L2A',
   'rel': 'via-cirrus',
   'href': 'https://cirrus-earth-search.aws.element84.com/v0/catid/sentinel-s2-l2a/workflow-cog-archive/S2A_30VXK_20210305_0_L2A'},
  {'rel': 'parent',
   'href': 'https://earth-search.aws.element84.com/v0/collections/sentinel-s2-l2a-cogs'},
  {'rel': 'collection',
   'href': 'https://earth-search.aws.element84.com/v0/collections/sentinel-s2-l2a-cogs'},
  {'rel': 'root', 'href': 'https://earth-search.aws.element84.com/v0/'}]}

Perhaps adding a "target_asset" keyword to build_vrt, then update the logic on shapes/transform to somthing like:

if shapes is None:
    if Band==None
        shapes = [stac_item["properties"]["proj:shape"] for stac_item in stac_items]
    else:
        try:
            shapes = [stac_item["properties"]['assets']["proj:shape"] for stac_item in stac_items]
        except KeyError:
            shapes = [stac_item["properties"]['assets'][Band]["proj:shape"] for stac_item in stac_items]

elif len(shapes) != len(stac_items):
    raise ValueError(
            "Number of user-provided 'shapes' does not match the number of "
            "'stac_items' ({} != {})".format(len(shapes), len(stac_items))
        )

Happy to work up a PR if this seems like a good route.

@TomAugspurger
Copy link
Collaborator

Yeah, I recall something in the proj extension about "default" assets. Right now the type on shapes is List[Tuple], specifying the shape of each asset. I wonder if it should be a List[Dict[Tuple]], specifying the shape of each band for each asset... I'll need to play with this a bit.

Anyway, agreed that we should have some way to handle this case.

@rmg55 rmg55 closed this as completed Mar 5, 2021
@rmg55 rmg55 reopened this Mar 5, 2021
@rmg55
Copy link
Author

rmg55 commented Mar 5, 2021

Sounds good @TomAugspurger

I updated the original post to change "target_band" to "target_asset". Quickly glancing at build_vrt, is it currently hardcoded to stac_item["assets"]["image"] (line 225)?

In the Sentinel Catalog the assets look like:

stac_items[0]['assets'].keys()
dict_keys(['thumbnail', 'overview', 'info', 'metadata', 'visual', 'B01', 'B02', 'B03', 'B04', 'B05', 'B06', 'B07', 'B08', 'B8A', 'B09', 'B11', 'B12', 'AOT', 'WVP', 'SCL'])

Cheers

@TomAugspurger
Copy link
Collaborator

Thanks. Just a general comment that right now stac-vrt bakes in many assumptions about the dataset I tested it on (NAIP on Azure: https://github.com/microsoft/AIforEarthDataSets/blob/main/data/naip.md). So we'll need to generalize things to handle that.

The NAIP dataset stores the four bands in a single COG. The AWS Sentinel data looks to have multiple assets (COGs) per STAC item. So we'll need some way of indicating which assets will be put into the VRT.

Right now we have something like

build_vrt(naip_data, asset_key="image")

which returns a VRT that has multiple bands since the COGs have multiple bands. Would a user ever do something like

build_vrt(sentinel_data, asset_key=["B01", "B02"])

which would return a similar VRT (multiple bands) that have been stacked together?

@TomAugspurger
Copy link
Collaborator

which would return a similar VRT (multiple bands) that have been stacked together?

Looking at gdalbuildvrt, the -separate parameter controls this. By default, they're considered tiles in a larger mosaic, but -separate says to treat them as separate bands.

Now, my imagined use case for stac-vrt is for creating a large mosaic from many items. But we can apply the same idea here... I guess we would want some kind of VRT of VRTs, where the "inner" VRTs use a -separate-like behavior to stack the multiple files into separate bands of a single array. Then the outer VRT would mosaic those many VRTs into a single mosaic.

If you have API suggestions it'd be great to hear them. I think my initial preference is to preserve a single build_vrt function, but expand it to handle the case where bands are split across multiple files. Something like concat_assets=["B02", "B03"] would build up the inner VRTs? Or maybe even just assets=["B02", "B03"]. In which case our "current default" would be the hardcoded assets="image".

cc @scottyhq, if you have thoughts on the API design as well. Anything we should consider from xarray?

@rmg55
Copy link
Author

rmg55 commented Mar 8, 2021

My 2cents would be to use assets=["B02","B03"] and have a concat=BOOL. If concat=False, then return a list of vrt files, if True, then return the single multiband file (gdal -separate version).

Not sure if this is the correct place to put these ideas, but I wanted to mention a few other functionalities that I think would be useful to think about including:

  1. Mosaicing - stitching together a bunch of asset(s)

    • Base Case: STAC items are in the same CRS. Overlap regions determined by the order of the files in the VRT (current implementation)
    • Variable CRS: When stac items have different CRS (aka Sentinel, Landsat), I assume we would need to implement the warping parameters within vrt file to get them into the same geographic projection. Good discussion in the Pangeo Discourse page about why this would be great to have - https://discourse.pangeo.io/t/copernicus-sentiel-2-overlapping-coordinates-between-tiles/1280/10. If keeping rasterio as a dependency, the WarpedVRT function would probably be really useful for this.
    • Overlap Regions: Ability to provide (or have pre-built) pixel functions that can be applied to overlap regions in the mosaic (e.g. mean, max, min, best).
  2. Stacking Items: Stack single band asset from a STAC item and place it into a band in a vrt file (gdal -seperate). This would replace the "band" dimension, with "time". This would not involve any spatial mosaicing. This would need to be a single file per band, because COGs are limited to 3 dimensions (unless there is some way to use the (Multidimensional VRT)[https://gdal.org/drivers/raster/vrt_multidimensional.html#vrt-multidimensional] and have x,y,band,time dimensions).

@scottyhq
Copy link

scottyhq commented Mar 9, 2021

Hi @rmg55 and @TomAugspurger . Very excited about the potential for stac-vrt for both mosaicing and stacking! These ideas are all great. A lot of this discussion has come up over in intake/intake-stac#65, and I'm thinking I'll open a draft PR over there to more easily comment on API ideas. I've found working with several available catalogs has been key given how relevant info can be stored in different places via extensions, there is some churn in itemcollections returned by stac-search results (stac-utils/pystac#256 (comment)) versus static catalogs, and not everything is implemented yet in pystac (e.g. stac-utils/pystac#132)

cc @scottyhq, if you have thoughts on the API design as well. Anything we should consider from xarray?

In brief, my recommendation would be to keep the keyword arguments in build_vrt() as close as possible to gdal's buildvrt. for example separate=False by default. I think it's best for starters to focus on the case for data like NAIP, S2, HLS, that is already on a common grid (at least same CRS) to avoid reprojection/WarpedVRT/resampling complications. I've found -resolution='highest' is also handy for the S2 case where different assets can have different ground-sample-distance. I think that is more natural than the default -resolution=average...

As for 'asset' or 'asset_key'... 'asset_key' can be anything for better or worse ('B04', 'visual', 'random-name'). One of my favorite features of intake-stac is the mapping between eo:bands common names to assets though. For example it's really nice as a user to say assets=["red","nir"] and let the code find the matching key.

@rmg55
Copy link
Author

rmg55 commented Mar 10, 2021

Thanks @scottyhq great points (especially the -resolution arg). Will switch over to the other thread, but just wanted to clarify one point:

focus on the case for data like NAIP, S2, HLS, that is already on a common grid (at least same CRS) to avoid reprojection/WarpedVRT/resampling complications

If working in the same tile (and temporally stacking assets), then yes, we should have a consistent CRS. However, if mosaicing, I don't think this is the case . For instance here is an example with the Sentinel STAC where we would probably want to reproject into a geographic projection (e.g. epsg:4326). Perhaps I am missing something her though?

import satsearch
URL='https://earth-search.aws.element84.com/v0'
results = satsearch.Search.search(url=URL,
                                  collections=['sentinel-s2-l2a-cogs'],
                                  bbox=[-110.791,39.783,-50.677,41.870],
                                  datetime='2021-02-27/2021-02-27')
stac_catalog = results.items().geojson()
for assets in stac_items:
    print('Projection:',
          'epsg:'+str(assets['properties']['proj:epsg']),
          'UTM Zone:',
          assets['properties']['sentinel:utm_zone'],
          'Lat. Band:',
          assets['properties']['sentinel:latitude_band'],
          'Grid Square:',
          assets['properties']['sentinel:grid_square'])
Projection: epsg:32613 UTM Zone: 13 Lat. Band: T Grid Square: DE
Projection: epsg:32613 UTM Zone: 13 Lat. Band: T Grid Square: EE
Projection: epsg:32613 UTM Zone: 13 Lat. Band: T Grid Square: FE
Projection: epsg:32613 UTM Zone: 13 Lat. Band: T Grid Square: GE
Projection: epsg:32614 UTM Zone: 14 Lat. Band: T Grid Square: KK
Projection: epsg:32613 UTM Zone: 13 Lat. Band: T Grid Square: DF
Projection: epsg:32613 UTM Zone: 13 Lat. Band: T Grid Square: EF
Projection: epsg:32613 UTM Zone: 13 Lat. Band: T Grid Square: FF
Projection: epsg:32614 UTM Zone: 14 Lat. Band: T Grid Square: KL
Projection: epsg:32613 UTM Zone: 13 Lat. Band: T Grid Square: GF
Projection: epsg:32613 UTM Zone: 13 Lat. Band: T Grid Square: EG
Projection: epsg:32614 UTM Zone: 14 Lat. Band: T Grid Square: LL
Projection: epsg:32613 UTM Zone: 13 Lat. Band: T Grid Square: FG
Projection: epsg:32614 UTM Zone: 14 Lat. Band: T Grid Square: KM
Projection: epsg:32613 UTM Zone: 13 Lat. Band: T Grid Square: GG
Projection: epsg:32614 UTM Zone: 14 Lat. Band: T Grid Square: LM
Projection: epsg:32615 UTM Zone: 15 Lat. Band: T Grid Square: WE
Projection: epsg:32615 UTM Zone: 15 Lat. Band: T Grid Square: XE
Projection: epsg:32615 UTM Zone: 15 Lat. Band: T Grid Square: YE
Projection: epsg:32616 UTM Zone: 16 Lat. Band: T Grid Square: BK
Projection: epsg:32616 UTM Zone: 16 Lat. Band: T Grid Square: CK
Projection: epsg:32615 UTM Zone: 15 Lat. Band: T Grid Square: WF
Projection: epsg:32615 UTM Zone: 15 Lat. Band: T Grid Square: XF
Projection: epsg:32615 UTM Zone: 15 Lat. Band: T Grid Square: YF
Projection: epsg:32616 UTM Zone: 16 Lat. Band: T Grid Square: BL
Projection: epsg:32616 UTM Zone: 16 Lat. Band: T Grid Square: CL
Projection: epsg:32615 UTM Zone: 15 Lat. Band: T Grid Square: WG
Projection: epsg:32615 UTM Zone: 15 Lat. Band: T Grid Square: XG
Projection: epsg:32615 UTM Zone: 15 Lat. Band: T Grid Square: YG
Projection: epsg:32616 UTM Zone: 16 Lat. Band: T Grid Square: BM
Projection: epsg:32616 UTM Zone: 16 Lat. Band: T Grid Square: CM
Projection: epsg:32617 UTM Zone: 17 Lat. Band: T Grid Square: NE
Projection: epsg:32617 UTM Zone: 17 Lat. Band: T Grid Square: PE
Projection: epsg:32617 UTM Zone: 17 Lat. Band: T Grid Square: QE
Projection: epsg:32618 UTM Zone: 18 Lat. Band: T Grid Square: TK
Projection: epsg:32618 UTM Zone: 18 Lat. Band: T Grid Square: UK
Projection: epsg:32617 UTM Zone: 17 Lat. Band: T Grid Square: NF
Projection: epsg:32617 UTM Zone: 17 Lat. Band: T Grid Square: PF
Projection: epsg:32618 UTM Zone: 18 Lat. Band: T Grid Square: TL
Projection: epsg:32617 UTM Zone: 17 Lat. Band: T Grid Square: QF
Projection: epsg:32618 UTM Zone: 18 Lat. Band: T Grid Square: UL
Projection: epsg:32617 UTM Zone: 17 Lat. Band: T Grid Square: PG
Projection: epsg:32618 UTM Zone: 18 Lat. Band: T Grid Square: VL
Projection: epsg:32617 UTM Zone: 17 Lat. Band: T Grid Square: QG
Projection: epsg:32618 UTM Zone: 18 Lat. Band: T Grid Square: TM
Projection: epsg:32618 UTM Zone: 18 Lat. Band: T Grid Square: UM
Projection: epsg:32618 UTM Zone: 18 Lat. Band: T Grid Square: VM

@matthewhanson
Copy link
Member

These are some great features, some random thoughts:

  • For referencing assets by spectral band "common_name" I filed Referencing assets by eo:bands common_name pystac#275
  • being able to include multiple files with different CRS's would be great, for either mosaicking or stacking (granted, different CRS's when stacking is probably unlikely)
  • You should be able to specify any band (or multiple bands) from any asset to include
  • You should be able to mosaic together multiple bands, as different bands...i.e., I want to mosaic together all red bands together from a series of files, green, blue...and have a 3-band VRT mosaic
  • When specifying multiple bands from multiple files a user likely wants to create a mosaic as above. But maybe they want to create a stack of multiple bands from multiple files? An exploded stack of multiple bands from multiple files (e.g., 2 bands from 5 files = 10-band file) seems like a rare use case, IMO, is it something that should be supported?

@lossyrob
Copy link
Member

Noting here that I'm creating Items where proj:epsg, proj:bbox live at the Item level as a default for any asset, while proj:shape and proj:transform may be Item specific.

PySTAC allows you to pull a property from an asset if available, and if not checks the properties of the Item. e.g. in

asset_key: str = ...
item: pystac.Item = ...
bbox: Optional[List[float]] = item.ext.projection.get_bbox(item.assets[asset_key])

bbox will be pulled from the asset; if the asset doesn't have that property, it's pulled from the item; if the item doesn't have it, it's None.

@RichardScottOZ
Copy link

I don't think resolution : average makes sense, either @scottyhq - not for multispectral satellite data, anyway. Landsat 8 - 30s, 15s and 100s for example.

Reprojection - not necessarily geographic @rmg55 - you could have say Australian or European or South American projected coordinate systems for larger scale areas you may want to use - so possibly an option?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants