sentinel-hub / sentinelhub-py

Download and process satellite imagery in Python using Sentinel Hub services.
http://sentinelhub-py.readthedocs.io/en/latest/
MIT License
798 stars 243 forks source link

[HELP] #526

Open stamatisvas opened 3 months ago

stamatisvas commented 3 months ago

Hi, I am using the following code to download CO data from sentinel5p:

evalscript_co = """
//VERSION=3
function setup() {
   return {
    input: ["CO"], 
    output: { 
      bands: 1,
      sampleType: "FLOAT32"
    },
  };
}

function evaluatePixel(samples) {
   return [samples.CO] 
}
"""

def download_co_imgs(start_date, end_date, path_to_save_data):

    current_date = start_date
    while current_date <= end_date:

        request_co_data = SentinelHubRequest(
        evalscript=evalscript_co,
        input_data=[
            SentinelHubRequest.input_data(

                DataCollection.SENTINEL5P.define_from("sentinel-5p-l2", service_url=config.sh_base_url),
            )
        ],
        responses=[SentinelHubRequest.output_response("default", MimeType.TIFF)],
        data_folder=path_to_save_data,
        bbox=betsiboka_bbox,
        size=betsiboka_size,
        config=config,
    )
        current_date += timedelta(days=1)
        request_co_data.get_data(save_data=True)

When I use the function to download data it downloads a folder for each day with the files [response.tiff, request.json]. The problem is that I cannot find the acquisition time for the images, i..e the sentinel5p acquisition time for every image. The request.json contains this:

{
    "timeRange": 
    {
        "from": "2020-11-11T00:00:00Z",
        "to": "2020-11-11T23:59:59Z"
    }
}

and not the specific time of the acquisition. Any help with that?

mlubej commented 3 months ago

Hi @stamatisvas!

Thank you for posting this question. I tried running your example but noticed that you don't use the time interval in your request anywhere. Your SentinelHubRequest.input_data dictionary should contain the time_interval parameter like so:

SentinelHubRequest.input_data(
    data_collection=DataCollection.SENTINEL5P,
    time_interval=(current_date, end_date)
)

I also updated the DataCollection part, since there was no need to update the data collection. Unless you are using some other sh_base_url? I didn't see it defined anywhere.

Now, to get to the issue. The reason that the time range is returned is that the SH in the background creates a mosaic of all observations during the timedelta which you specify (1 day). If you want finer temporal resolution I suggest that you decrease the timedelta to 1 hour, that should give you better precision, but will still not give you the exact timestamp.

If you're interested in the exact timestamps, you have to save the information from the scenes and save it explicitly in the evalscript using the updateOutputMetadata function.

Another option is to query the timestamps via the SH Catalog, like so:

from sentinelhub import SHConfig, SentinelHubCatalog

creodias_config = SHConfig()
creodias_config.sh_base_url = "https://creodias.sentinel-hub.com/"

catalog = SentinelHubCatalog(creodias_config)
search_iterator = catalog.search(collection="sentinel-5p-l2", bbox=betsiboka_bbox, time=("2020-11-01", "2020-11-30"))

timestamps = [ts.isoformat() for ts in search_iterator.get_timestamps()]

The service URL needed to be updated, because the 5P collection lives on creodias

You can then use the specific timestamps to make specific requests by providing the exact timestamp in the request.

Hope that helps!