We propose to showcase the capabilities of the recently created data catalog at the Computer Science department, West University of Timișoara. The catalog exposes Sentinel-2 imagery (currently) using STAC Catalogs.
We store Sentinel-2 L1C products from 2017-01-01 till present, covering the whole territory of Romania. This post will illustrate the usage of stackstac in order to turn a STAC Collection into an xarray dataframe that is later processed using dask showing a timelapse of some big cities in Romania throughout the years. The work presented is based on the stackstac example.
The approach for generating the timelapse GIF’s is rather simple:
- Generate a bounding box from national codes (aka. SIRUTA in Romania) using an OWS feature containing Romania’s administrative territorial bounds from geo-spatial.org.
- Query the data intersecting with said bounding box using stackstac, selecting the RGB bands for Sentinel-2 (B02, B03 and B04) and convert the data to an xarray array.
- Filter scenes based on cloud coverage (this metadata is available in the STAC catalog). For the examples listed here, I filtered the images so that all of them have less than 1% cloud coverage.
- Resample the xarray array on the time dimension at each 10 days.
- Crop the array at a given buffer (in meters) from the centroid of the bounding box.
- Apply gamma correction in order to create True Color Image (TCI) composites with a gamma value of 2.2 (Results shown in a paper published by Sinergise show that this is a value that works well with Sentinel-2 data).
- Use dask and geogif to render the timelapse GIF.
So, how do we do this with Python?
Simply start off by interrogating the STAC catalog:
|
|
Then, we ask stackstac.stack() to create our array:
|
|
This is what our datacube looks like so far:
We can then start filtering scenes based on cloud cover and resample the data
|
|
Afterwards, convert the centroid lat-lon coordinates to UTM using proj and crop the array to our desired Area of Interest:
|
|
We can use dask.array.power() to apply gamma correction to the cube:
|
|
And finally, use dask and geogif to produce our GIF’s
|
|
These are the results:
Special thanks to my colleague, Marian Neagul for the support and guidance, to geo-spatial.org for providing the territorial administrative bounds, and to the Romanian Space Agency for supplying Jupyter Hub environments.