Which Sentinel-2 tiles cover my area of interest?

Sentinel-2 products include several tiles and it is not straightforward to identify which of those tiles cover an given area of interest.

This entry is about showing how to identify the Sentinel-2 tiles covering an area of interest expressed as a bounding box as lower left corner, upper right corner (lon min, lat min, lon max, lat max).
Once identified, the other tiles can be removed from the Sentinel-2 product and be processed with tools like GDAL or SNAP.

There are two steps in the process:

Query the catalogue with a time and an area of interest.

Let’s say we are working with the Doñana protected area with the bounding box -6.93,36.64,-6.03,37.47 and the time of interest March 2016.

We use the opensearch-client to do so:

opensearch-client -p start='2016-03-01' -p end='2016-03-31' -p bbox='-6.93,36.64,-6.03,37.47' https://data2.terradue.com/eop/cache/series/S2A/description

This will return the 14 products below:

https://data2.terradue.com/eop/cache/series/S2A/search?format=atom&uid=S2A_OPER_PRD_MSIL1C_PDMC_20160504T235051_R094_V20160504T111111_20160504T111111 https://data2.terradue.com/eop/cache/series/S2A/search?format=atom&uid=S2A_OPER_PRD_MSIL1C_PDMC_20160504T232702_R094_V20160504T105917_20160504T105917 https://data2.terradue.com/eop/cache/series/S2A/search?format=atom&uid=S2A_OPER_PRD_MSIL1C_PDMC_20160501T145527_R037_V20160430T112639_20160430T112639 https://data2.terradue.com/eop/cache/series/S2A/search?format=atom&uid=S2A_OPER_PRD_MSIL1C_PDMC_20160427T220610_R137_V20160427T111524_20160427T111524 https://data2.terradue.com/eop/cache/series/S2A/search?format=atom&uid=S2A_OPER_PRD_MSIL1C_PDMC_20160424T190559_R094_V20160424T110939_20160424T110939 https://data2.terradue.com/eop/cache/series/S2A/search?format=atom&uid=S2A_OPER_PRD_MSIL1C_PDMC_20160420T202128_R037_V20160420T112242_20160420T112242 https://data2.terradue.com/eop/cache/series/S2A/search?format=atom&uid=S2A_OPER_PRD_MSIL1C_PDMC_20160417T202220_R137_V20160417T111159_20160417T111159 https://data2.terradue.com/eop/cache/series/S2A/search?format=atom&uid=S2A_OPER_PRD_MSIL1C_PDMC_20160414T200539_R094_V20160414T110907_20160414T110907 https://data2.terradue.com/eop/cache/series/S2A/search?format=atom&uid=S2A_OPER_PRD_MSIL1C_PDMC_20160412T182040_R037_V20160410T112358_20160410T112358 https://data2.terradue.com/eop/cache/series/S2A/search?format=atom&uid=S2A_OPER_PRD_MSIL1C_PDMC_20160408T074353_R137_V20160407T111223_20160407T111223 https://data2.terradue.com/eop/cache/series/S2A/search?format=atom&uid=S2A_OPER_PRD_MSIL1C_PDMC_20160406T170650_R094_V20160404T110311_20160404T110311 https://data2.terradue.com/eop/cache/series/S2A/search?format=atom&uid=S2A_OPER_PRD_MSIL1C_PDMC_20160322T063320_R037_V20160321T112950_20160321T112950 https://data2.terradue.com/eop/cache/series/S2A/search?format=atom&uid=S2A_OPER_PRD_MSIL1C_PDMC_20160316T022911_R094_V20160315T110157_20160315T110157 https://data2.terradue.com/eop/cache/series/S2A/search?format=atom&uid=S2A_OPER_PRD_MSIL1C_PDMC_20160309T104243_R137_V20160308T112023_20160308T112023

Not that we have all the references of the Sentinel-2 products over the Doñana area of interest and covering the time of interest, let’s proceed to the next step.

Identify the tiles of interest

We will focus on the first result of the list to better explain this step. Extending it to the remaining items of the Sentinel-2 list is only a matter of iterating all items.

Let’s define a variable ref with the first Sentinel-2 product reference:

ref="https://data2.terradue.com/eop/cache/series/S2A/search?format=atom&uid=S2A_OPER_PRD_MSIL1C_PDMC_20160504T235051_R094_V20160504T111111_20160504T111111"

Let’s also define a variable bbox with the area of interest:

bbox="-6.93,36.64,-6.03,37.47"

Then let’s retrieve a few metadata elements:

read identifier self startdate enddate < <( opensearch-client ${ref} identifier,self,startdate,enddate | tr "," " " )

This single line of bash code provides the Sentinel-2 product identifier, its catalogue reference and its acquisition time span. We will use this information to identify the tiles.

We can now query the catalogue for the tiles over our area of interest:

tiles="$( opensearch-client \ -p "pt=S2MSI1CT" \ -p "bbox=${bbox}" \ -p "start=${startdate}" \ -p "stop=${enddate}" \ https://data2.terradue.com/eop/sentinel2/dataset/search identifier | tr "\n" "," | rev | cut -c 2- | rev )"

where startdate and enddate were retrieved in the previous step.

Finally, print the Sentinel-2 product reference and the list of tiles:

echo "${self},${tiles}"

This will return:

https://data2.terradue.com/eop/cache/series/S2A/search?format=atom&uid=S2A_OPER_PRD_MSIL1C_PDMC_20160504T235051_R094_V20160504T111111_20160504T111111,S2A_OPER_MSI_L1C_TL_SGS__20160504T182153_A004524_T29SQA_N02.02,S2A_OPER_MSI_L1C_TL_SGS__20160504T182153_A004524_T30STF_N02.02

Putting all the pieces together

Let’s create a function that for a given Sentinel-2 product and bounding box, prints the Sentinel-2 product reference and the list of tiles covering the bounding box:

function product2tiles () { local ref=$1 local bbox="$2" read identifier self startdate enddate < <( opensearch-client ${ref} identifier,self,startdate,enddate | tr "," " " ) [ -z ${self} ] || [ -z ${startdate} ] || [ -z ${enddate} ] && return 2 tiles="$( opensearch-client \ -p "pt=S2MSI1CT" \ -p "bbox=${bbox}" \ -p "start=${startdate}" \ -p "stop=${enddate}" \ https://data2.terradue.com/eop/sentinel2/dataset/search identifier | tr "\n" "," | rev | cut -c 2- | rev )" [ -z ${tiles} ] && return 3 echo "${self},${tiles}" }

Now let’s run it:

bbox='-6.93,36.64,-6.03,37.47' opensearch-client -p start='2016-03-01' -p end='2016-03-31' -p bbox="${bbox}" https://data2.terradue.com/eop/cache/series/S2A/description | while read ref do product2tiles ${ref} "${bbox}" done

That’s it!