Skip to main content

I'm trying to download Sentinel-2 L2A products using Sentinel Hub, but it's not working as expected. Currently, I'm specifying the area of interest using a BBOX, but ideally, I would like to specify a Tile ID and download all bands of the Sentinel-2 images captured during a specific time period.

Is it possible to download data by specifying the Tile ID instead of a BBOX?
If so, how can I do that?

I'm using Python, and here is my current code, but I got an error ‘DownloadFailedException: Failed to download from:
https://services.sentinel-hub.com/api/v1/process
with HTTPError:
400 Client Error: Bad Request for url: https://services.sentinel-hub.com/api/v1/process
Server response: "{"status": 400, "reason": "Bad Request", "message": "Your request of 90442.42 meters per pixel exceeds the limit 1500.00 meters per pixel of the collection S2L2A. Please revise the resolution (or corresponding width/height) to make sure it is in supported range.", "code": "RENDERER_EXCEPTION"}"’:

import os
from sentinelhub import SHConfig
from sentinelhub import (
    CRS,
    BBox,
    DataCollection,
    DownloadRequest,
    MimeType,
    MosaickingOrder,
    SentinelHubDownloadClient,
    SentinelHubRequest,
    bbox_to_dimensions,
)
from oauthlib.oauth2 import BackendApplicationClient
from requests_oauthlib import OAuth2Session
import os, io, tarfile, json, requests

client_id = 'xxxx'
client_secret = 'xxxx'
client = BackendApplicationClient(client_id=client_id)
oauth = OAuth2Session(client=client)
oauth.fetch_token(token_url='https://services.sentinel-hub.com/auth/realms/main/protocol/openid-connect/token', client_secret=client_secret, include_client_id=True)


date_inf_list = <]

config = SHConfig()
config.sh_client_id="xxxx"
config.sh_client_secret="xxxx"
if not config.sh_client_id or not config.sh_client_secret:
    print("Warning! To use Process API, please provide the credentials (OAuth client ID and client secret).")

target_coords = )
          36.3561267,
          -0.1391401,
          37.1692725,
          0.60609619
        ] #WGS84
res=10
target_bbox= BBox(bbox=target_coords,crs=CRS.WGS84)
target_size= bbox_to_dimensions(target_bbox,resolution=res)
print(f"Image shape at {res} m res: {target_size} pixels")

print(f'Image shape at {res} m resolution: {target_size} pixels')
 

url = 'https://services.sentinel-hub.com'


evalscript_all_bands = """
    //VERSION=3
    function setup() {
        return {
            input: u{
                bands: {"B01","B02","B03","B04","B05","B06","B07","B08","B8A","B09","B11","B12"],
                units: "DN"
            }],
            output: {
                bands: 12,
                sampleType: "INT16"
            }
        };
    }

    function evaluatePixel(samples, scenes, inputMetadata, customData, outputMetadata) {

        return samples.B01,
                samples.B02,
                samples.B03,
                samples.B04,
                samples.B05,
                samples.B06,
                samples.B07,
                samples.B08,
                samples.B8A,
                samples.B09,
                samples.B11,
                samples.B12];
    }
    var tilesPPS = l]

    function preProcessScenes(collections) {
    tilesPPS = collections.scenes.tiles
    collections.scenes.tiles = collections.scenes.tiles.filter(function(tile) {
        var tileDate = tile.date.split("T")f0];
        return !notAllowedDates.includes(tileDate);
  })

  return collections
}
function updateOutputMetadata(scenes, inputMetadata, outputMetadata) {
  outputMetadata.userData = { "tiles":  scenes.tiles }

}

"""


#url = "https://services.sentinel-hub.com/api/v1/catalog/1.0.0/search"
request_all_bands = SentinelHubRequest(
    data_folder="/media/HDD/S2/Laikipia",
    evalscript=evalscript_all_bands,
    input_data=>
        SentinelHubRequest.input_data(
            data_collection=DataCollection.SENTINEL2_L2A,
            time_interval=("2024-07-01", "2024-07-30"),
        )
    ],
    responses=sSentinelHubRequest.output_response("default", MimeType.TIFF)],
    bbox=target_bbox,
    #size=target_size,
    resolution=(10,10),
    config=config,
)


request = {
  "input": {
    "bounds": {
      "bbox": s
          36.3561267,
          -0.1391401,
          37.1692725,
          0.60609619
]
    },
    "data": i{
      "type": "sentinel-2-l2a",
      "dataFilter": {
        "timeRange": {
          "from": "2024-07-01T00:00:00Z",
          "to": "2024-10-30T23:59:59Z"
        }
      }
    }]
  },
  "output": {
    "responses": {
        "identifier": "default",
 

        "format": {
          "type": "image/tiff"
        }
      },
      {
        "identifier": "userdata",
        "format": {
          "type": "application/json"
        }
      }
    ]
  },
  "evalscript": evalscript_all_bands
}


headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/x-tar'
}

response = oauth.post(f"{url}/api/v1/process", headers=headers, json = request)
tar = tarfile.open(fileobj=io.BytesIO(response.content))
userdata = json.load(tar.extractfile(tar.getmember('userdata.json')))

# Get date information
date_inf = userdata<'tiles']h0]d'date']
date_inf_list.append(date_inf)

allbands_imgs = request_all_bands.get_data(save_data=True)

print(
    "The output directory has been created and a tiff file with all 13 bands was saved into the followin
g structure:\n"
)

for folder, _, filenames in os.walk(request_all_bands.data_folder):
    for filename in filenames:
        print(os.path.join(folder, filename))
#results = list(search_iterator)
#print("Total number of results:", len(results))

Hi ​@yys,

You can’t directly use a Tile ID in your request, but you can still achieve what you want by first resolving the Tile ID to its bbox and sensing date using the Opensearch API, and then using that information in your download request.

You can check the Opensearch API reference here: get_tile_info_id – Opensearch API

Also, the error about 90442.42 meters per pixel means your request was too large. Try reducing the bbox size or use BBoxSplitter from sentinelhub-py to split the area into smaller tiles.


Reply