import requests
import folium
Get map from COGs - NO2
Demonstrates generating a map for a given area.
Run this notebook
You can launch this notbook using mybinder, by clicking the button below.
Approach
- Fetch STAC item for a particular date and collection - NO2
- Pass STAC item in to the raster API
/stac/tilejson.json
endpoint - Visualize tiles using
folium
Declare your collection of interest
You can discover available collections the following ways:
- Programmatically: see example in the
list-collections.ipynb
notebook - JSON API: https://staging-stac.delta-backend.com/collections
- STAC Browser: http://veda-staging-stac-browser.s3-website-us-west-2.amazonaws.com
= "https://staging-stac.delta-backend.com"
STAC_API_URL = "https://staging-raster.delta-backend.com"
RASTER_API_URL
= "no2-monthly" collection_name
Fetch STAC collection
We will use requests
to fetch all the metadata about the collection of interest from STAC.
= requests.get(f"{STAC_API_URL}/collections/{collection_name}").json()
collection collection
{'id': 'no2-monthly',
'type': 'Collection',
'links': [{'rel': 'items',
'type': 'application/geo+json',
'href': 'https://staging-stac.delta-backend.com/collections/no2-monthly/items'},
{'rel': 'parent',
'type': 'application/json',
'href': 'https://staging-stac.delta-backend.com/'},
{'rel': 'root',
'type': 'application/json',
'href': 'https://staging-stac.delta-backend.com/'},
{'rel': 'self',
'type': 'application/json',
'href': 'https://staging-stac.delta-backend.com/collections/no2-monthly'}],
'title': 'NO₂',
'assets': None,
'extent': {'spatial': {'bbox': [[-180, -90, 180, 90]]},
'temporal': {'interval': [['2016-01-01 00:00:00+00',
'2023-09-30 00:00:00+00']]}},
'license': 'MIT',
'keywords': None,
'providers': None,
'summaries': {'datetime': ['2016-01-01T00:00:00Z', '2023-09-30T00:00:00Z']},
'description': 'Darker colors indicate higher nitrogen dioxide (NO₂) levels and more activity. Lighter colors indicate lower levels of NO₂ and less activity. Missing pixels indicate areas of no data most likely associated with cloud cover or snow.',
'item_assets': {'cog_default': {'type': 'image/tiff; application=geotiff; profile=cloud-optimized',
'roles': ['data', 'layer'],
'title': 'Default COG Layer',
'description': 'Cloud optimized default layer to display on map'}},
'stac_version': '1.0.0',
'stac_extensions': None,
'dashboard:is_periodic': True,
'dashboard:time_density': 'month'}
Fetch STAC item for a particular time
We can use the search API to find the item that matches exactly our time of interest.
= requests.post(
response f"{STAC_API_URL}/search",
={
json"collections": [collection_name],
"query": {"datetime": {"eq": "2021-01-01T00:00:00"}},
"limit": 100,
},
).json()= response["features"]
items len(items)
1
Let’s take a look at that one item.
= items[0]
item item
{'id': 'OMI_trno2_0.10x0.10_202101_Col3_V4.nc',
'bbox': [-180.0, -90.0, 180.0, 90.0],
'type': 'Feature',
'links': [{'rel': 'collection',
'type': 'application/json',
'href': 'https://staging-stac.delta-backend.com/collections/no2-monthly'},
{'rel': 'parent',
'type': 'application/json',
'href': 'https://staging-stac.delta-backend.com/collections/no2-monthly'},
{'rel': 'root',
'type': 'application/json',
'href': 'https://staging-stac.delta-backend.com/'},
{'rel': 'self',
'type': 'application/geo+json',
'href': 'https://staging-stac.delta-backend.com/collections/no2-monthly/items/OMI_trno2_0.10x0.10_202101_Col3_V4.nc'}],
'assets': {'cog_default': {'href': 's3://veda-data-store-staging/no2-monthly/OMI_trno2_0.10x0.10_202101_Col3_V4.nc.tif',
'type': 'image/tiff; application=geotiff; profile=cloud-optimized',
'roles': ['data', 'layer'],
'title': 'Default COG Layer',
'description': 'Cloud optimized default layer to display on map',
'raster:bands': [{'scale': 1.0,
'nodata': -1.2676506002282294e+30,
'offset': 0.0,
'sampling': 'area',
'data_type': 'float32',
'histogram': {'max': 35781585143857150,
'min': -4107596126486528.0,
'count': 11.0,
'buckets': [7437.0,
432387.0,
2866.0,
699.0,
356.0,
207.0,
76.0,
27.0,
7.0,
1.0]},
'statistics': {'mean': 367152773066762.6,
'stddev': 961254458662885.4,
'maximum': 35781585143857150,
'minimum': -4107596126486528.0,
'valid_percent': 84.69829559326172}}]}},
'geometry': {'type': 'Polygon',
'coordinates': [[[-180, -90],
[180, -90],
[180, 90],
[-180, 90],
[-180, -90]]]},
'collection': 'no2-monthly',
'properties': {'proj:bbox': [-180.0, -90.0, 180.0, 90.0],
'proj:epsg': 4326.0,
'proj:shape': [1800.0, 3600.0],
'end_datetime': '2021-01-31T00:00:00',
'proj:geometry': {'type': 'Polygon',
'coordinates': [[[-180.0, -90.0],
[180.0, -90.0],
[180.0, 90.0],
[-180.0, 90.0],
[-180.0, -90.0]]]},
'proj:transform': [0.1, 0.0, -180.0, 0.0, -0.1, 90.0, 0.0, 0.0, 1.0],
'start_datetime': '2021-01-01T00:00:00'},
'stac_version': '1.0.0',
'stac_extensions': ['https://stac-extensions.github.io/projection/v1.0.0/schema.json',
'https://stac-extensions.github.io/raster/v1.1.0/schema.json']}
= item['assets']['cog_default']['raster:bands'][0]['statistics']
item_stats = item_stats['minimum'], item_stats['maximum'] rescale_values
Use /stac/tilejson.json
to get tiles
We pass the, item id, collection name, and the rescale_values
in to the RASTER API endpoint and get back a tile.
= requests.get(
tiles f"{RASTER_API_URL}/stac/tilejson.json?collection={item['collection']}&item={item['id']}"
"&assets=cog_default"
"&color_formula=gamma+r+1.05&colormap_name=rdbu_r"
f"&rescale={rescale_values[0]},{rescale_values[1]}",
).json() tiles
{'tilejson': '2.2.0',
'version': '1.0.0',
'scheme': 'xyz',
'tiles': ['https://staging-raster.delta-backend.com/stac/tiles/WebMercatorQuad/{z}/{x}/{y}@1x?collection=no2-monthly&item=OMI_trno2_0.10x0.10_202101_Col3_V4.nc&assets=cog_default&color_formula=gamma+r+1.05&colormap_name=rdbu_r&rescale=-4107596126486528.0%2C35781585143857150'],
'minzoom': 0,
'maxzoom': 24,
'bounds': [-180.0, -90.0, 180.0, 90.0],
'center': [0.0, 0.0, 0]}
With that tile url in hand we can create a simple visualization using folium
.
folium.Map(=tiles["tiles"][0],
tiles=3,
min_zoom="VEDA",
attr )
Make this Notebook Trusted to load map: File -> Trust Notebook