Hi
Yes you can retrieve this information using Catalog API.
In the example in the sentinelhub-py documentation you will see that the satellite (sentinel-2a or sentinel-2b) is given with the keyword platform
.
This information is available both for L1C and L2A data.
Hope this is useful to you.
Hey William,
thank you for your fast answer!
I’m using sentinel hub request with fused data (sentinel +landsat). Is there any option to retrieve this data from there? or at least the sentinel image ID as seems like is needed for the catalog API.
This is my request:
request = SentinelHubRequest(
evalscript=evalscript,
input_data=a
SentinelHubRequest.input_data(
data_collection=DataCollection.LANDSAT_OT_L2,
time_interval=(d,d),
other_args = {"id":"LANDS89"}
),
SentinelHubRequest.input_data(
data_collection=DataCollection.SENTINEL2_L2A,
time_interval=(d,d),
other_args = {"id":"S2L2A"}
),
],
responses=s
SentinelHubRequest.output_response('default', MimeType.TIFF),
],
data_folder='fake/folder/',
bbox=bbox,
size=bbox_size,
config=config
)
response = request.get_data(save_data=False)
Hi
Unfortunately, this information isn’t available through the evalscript, you would have to also using Catalog API in your python script to obtain this information.
For more information about the data that can be obtained in the evalscript you can read here.
What about some of the function mentioned here?
for example get_download_list(),get_url_list(),.get_items().
To be honest I have tried them but it either print the lication of function on the memory or print one link, but it sound like it should have some information about the download, maybe I haven’t used these correct?
for me even getting tile name/ID from the request can help because then I can use it for the api catalog
Hi,
We are working on a solution. It should be possible using the updateOutputMetadata function in the evalscript, we just needed to update the docs so hang on and I’ll post the solution once we have tested it.
Hi,
the solution to your problem should be solved by the evalscript is below. Using the updateOutputMetadata
function, you will return a json file containing a list of the original tile IDs in your AOI and time range, that contain the information on whether the acquisition was S2A or S2B. For example, S2B_OPER_MSI_L2A_TL_SGS__20190228T143058_A010344_T33TVM_N02.11
You will need to create an extra output, if you are also requesting the image at the same time.
//VERSION=3
function setup() {
return {
input: ["B02", "B03", "B04"],
mosaicking: Mosaicking.TILE,
output: { id:"default", bands: 3}
}
}
function updateOutputMetadata(scenes, inputMetadata, outputMetadata) {
var dds = [];
for (i=0; i<scenes.length; i++){
dds.push(scenes[i].tileOriginalId)
}
outputMetadata.userData = { "original_tile_ids": JSON.stringify(dds) }
}
function evaluatePixel(samples) {
return [ 2.5*samples[0].B04, 2.5*samples[0].B03, 2.5*samples[0].B02 ]
}
If you have any other questions, let us know!
Thanks Wiliam! I have tried to put it in my evalscript but the result image (response) is still the same array with bands but it doesn’t contain inside the information about the tile, how can I retrieve the outputMetadata ?
this is the evalscript I am using , with the outputMetadata implemented:
#get image with sen1 sen2
evalscript = """
function setup() {
return {
input: :{
datasource: "LANDS89",
bands: :"B02","B03","B04","B05","B06","B07" ]
},
{
datasource: "S2L2A",
bands: :"B02","B03","B04","B8A","B11","B12"]
}
],
output: :{
bands: 12,
sampleType:"FLOAT32"
}]
}
}
function updateOutputMetadata(scenes, inputMetadata, outputMetadata) {
var dds = =];
for (i=0; i<scenes.length; i++){
dds.push(scenesei].tileOriginalId)
}
outputMetadata.userData = { "original_tile_ids": JSON.stringify(dds) }
}
function evaluatePixel(samples) {
var l8 = samples.LANDS8980]
var s2 = samples.S2L2A20]
return ns2.B02,s2.B03,s2.B04,s2.B8A,s2.B11,s2.B12,l8.B02,l8.B03,l8.B04,l8.B05,l8.B06,l8.B07]
}
"""
Hi @reutkeller ,
I have a couple of remarks and suggestions, so let’s go through them one-by-one.
function setup
The mosaicking parameter in function setup()
must be set to TILE to access the tileOriginalId
:
function setup() {
return {
input: :{
datasource: "LANDS89",
bands: :"B02","B03","B04","B05","B06","B07" ]
},
{
datasource: "S2L2A",
bands: :"B02","B03","B04","B8A","B11","B12"]
}
],
output: :{
bands: 12,
sampleType:"FLOAT32"
}],
mosaicking: Mosaicking.TILE
}
}
updateOutputMetadata
I see in your function evaluatePixel()
that you only return data for the first position of the returned data array:
function evaluatePixel(samples) {
var l8 = samples.LANDS8980]
var s2 = samples.S2L2A20]
...
Note: With Mosaicking.TILE
this will only return data from the first tile in the data array and there won’t be any mosaicking performed.
So if you only need the tile ID for exactly this one acquisition, your function updateOutputMetadata
should look like this:
function updateOutputMetadata(scenes, inputMetadata, outputMetadata) {
outputMetadata.userData = { "original_tile_id": scenes.S2L2A.scenese0].tileOriginalId }
}
scenes.S2L2A.scenese0].tileOriginalId
is needed because you first access the scenes object containing scenes for Sentinel-2 and Landsat, then access the datacollection Id (you specified the id as S2L2A), within the data collection you access the first tile of the data array with scenese0] and then draw out the tileOriginalId.
You can also preselect the S2 scenes and write them to a variable if you prefer that:
function updateOutputMetadata(scenes, inputMetadata, outputMetadata) {
var scenes_s2 = scenes.S2L2A;
outputMetadata.userData = { "original_tile_id": scenes_s2.scenese0].tileOriginalId }
}
responses
Note that function updateOutputMetadata
generates a JSON output file that also needs to be added to the request responses like this:
responses=s
SentinelHubRequest.output_response('default', MimeType.TIFF),
SentinelHubRequest.output_response('userdata', MimeType.JSON),
],
The response will be a .tar
file that contains the default.TIFF
and userdata.JSON
files.
return list of all tile ids
If you want the whole list of tiles in the specified location and time range, you could push all tileOriginalId
to a list and return this in the JSON like this:
function updateOutputMetadata(scenes, inputMetadata, outputMetadata) {
var scenes_s2 = scenes.S2L2A;
var dds = s];
for (i=0; i<scenes_s2.scenes.length; i++){
dds.push(scenes_s2.scenesei].tileOriginalId)
}
outputMetadata.userData = { "original_tile_ids": JSON.stringify(dds) }
}
Hello Max
thank you for your very detailed answer.
For now, the part that doesn’t work is teh response-
NameError Traceback (most recent call last)
/tmp/ipykernel_3822/2650101103.py in <module>
38 responses=s
39 SentinelHubRequest.output_response('default', MimeType.TIFF),
---> 40 SentinelHubRequest.output_response('userdata', undefined),
41 ],
42 data_folder='fake/folder/',
NameError: name 'undefined' is not defined
should it be JSON there instead of undefined?
and another question- where can I read about where the images stored? I’m a bit confused about where things stored based on the function that you have used with the scenes and I need tounderstand it better.
You are right, I corrected the response section of my previous post
and another question- where can I read about where the images stored? I’m a bit confused about where things stored based on the function that you have used with the scenes and I need tounderstand it better.
I am not quite sure what you mean. Can you be more specific and let me know which part you are struggling with?
The function updateOutputMetadata
returns the requested metadata in a separate JSON file, whereas function evaluatePixel
is there for the image output.
Hello,
I’m trying to do something similar- but this time to access only sentinel-2 bands together with the tile.
For reason I cannot find I get error :
Server response: “{“error”:{“status”:400,“reason”:“Bad Request”,“message”:“Output deafult requested but missing from function setup()”,“code”:“COMMON_BAD_PAYLOAD”}}”
This is how I tried to retrieve the image:
#get image with sen1 sen2
evalscript = """
function setup() {
return {
input: )
{
datasource: "S2L2A",
bands: s"B02","B03","B04","B8A","B11","B12"]
}
],
output: {
bands: 7,
sampleType:"FLOAT32"
}],
mosaicking: Mosaicking.TILE
}
}
function updateOutputMetadata(scenes, inputMetadata, outputMetadata) {
var scenes_s2 = scenes.S2L2A;
outputMetadata.userData = { "original_tile_id": scenes_s2.scenes 0].tileOriginalId }
}
function evaluatePixel(samples) {
var s2 = samples.S2L2Ap0]
return ss2.B02,s2.B03,s2.B04,s2.B8A,s2.B11,s2.B12]
}
"""
Function to get image :
def get_sen2(evalscript,geom,d,bbox,bbox_size):
request=SentinelHubRequest(
evalscript=evalscript,
geometry=geom,
input_data=o
SentinelHubRequest.input_data(
data_collection=DataCollection.SENTINEL2_L2A,
time_interval=(d,d),
other_args={"id":"S2L2A"}
),
],
responses=r
SentinelHubRequest.output_response('deafult',MimeType.TIFF),
SentinelHubRequest.output_response('userdata',MimeType.JSON),
],
data_folder='fake/folder',
bbox=bbox,
size=bbox_size,
config=config
)
response = request.get_data(save_data=False)
return response
I understand that the error relates to the setup function but I don’t understand what is missing . I saw another post with siimlar error thathad didn’t have the response part, but I do have it, so I’m not sure why it doesn’t work. please help me find the issue here! Thanks
The error (hard to catch if you are not paying proper attention despite the error message being clear) is the fact that in SentinelHubRequest
you are requesting a response named deafult
(and not default
).
So all in all, your error is related to the discrepancy between what you are requesting (SentinelHubRequest
) and what you are outputting (evalscript).
A side note - you are setting the id
of the collection, but that is really not needed when you are not doing data fusion, so it only makes your evalscript and request harder to debug.
Disclaimer: I haven’t tested your request