I have a labelling platform that is reading BYOC image tiles using WMS. Lately I have been getting a few reports from the team using it that some images are not showing up. I am checking on those using the python API to form a SentinelHubRequest to get the data and plot it to see what is going on. The message I get back is:
DownloadFailedException: Failed to download from:
https://services.sentinel-hub.com/api/v1/process
with HTTPError:
412 Client Error: Precondition Failed for url: https://services.sentinel-hub.com/api/v1/process
Server response: "{"status": 412, "reason": "Precondition Failed", "message": "Reingest tile 's3://<snip>cat2/911445_2017-08/(BAND).tif' (id = <snip>) because one of its files changed since ingestion. Reingest it using the endpoint https://docs.sentinel-hub.com/api/latest/reference/#operation/reingestByocCollectionTileById.", "code": "FILE_CHANGED"}"
So there seems to be some issue with the file having changed.
Is there an easy way to query the tiles in a collection to see which ones might be affected (having changed since ingestion)? Using the following:
collections_iterator = byoc.iter_collections()
collection_id = [collection["id"] for collection in collections_iterator
if "cat2" in collection["name"]]
collection = byoc.get_collection(collection_id[0])
tiles = list(byoc.iter_tiles(collection))
And then looping through tiles
to check for relevant messages doesn’t show any relevant information.
Since this is a collection with more than 30,000 tiles, I am hoping to be able to find tiles that might be affected so I can reingest them.
For completeness, here is the function I use to look for the individual image:
def request_from_sentinelhub(df, diam, collection, config, color="rgb",
plot=True):
"""Request tile from center point with specific diameter from Sentinel-Hub
collection and plot
"""
x, y, date = df.iloc[0][['x', 'y', "date"]]
tile_time = dateutil.parser.parse(date)
bbox = BBox((x-diam, y-diam, x+diam, y+diam), crs=CRS.WGS84)
if color == "ngb":
evalscript = """
//VERSION=3
function setup() {
return {
input: ["B2","B3","B4", "dataMask"],
output: { bands: 4 }
}
}
function evaluatePixel(sample) {
return [sample.B4/255, sample.B3/255,
sample.B2/255, sample.dataMask]
}
"""
elif color == "rgb":
evalscript = """
//VERSION=3
function setup() {
return {
input: ["B1","B2","B3", "dataMask"],
output: { bands: 4 }
}
}
function evaluatePixel(sample) {
return [sample.B3/255, sample.B2/255,
sample.B1/255, sample.dataMask]
}
"""
request = SentinelHubRequest(
evalscript = evalscript,
input_data=[SentinelHubRequest.input_data(
data_collection=collection, time_interval=tile_time
)],
responses=[
SentinelHubRequest.output_response("default", MimeType.PNG)
], bbox=bbox,
size=bbox_to_dimensions(bbox, 3),
config=config,
)
data = request.get_data()[0]# tiles = list(byoc.iter_tiles(created_collection))
if plot:
fig, ax = plt.subplots(figsize=(15, 10))
ax.imshow(data)
ax.set_title(tile_time.date().isoformat(), fontsize=10)
plt.tight_layout()
else:
return data
A DataFrame provides the dates and coordinates of the query:
my_byoc = DataCollection.define_byoc(collection['id'])
request_from_sentinelhub(catalog.iloc[0:1], 0.005, my_byoc, config)
Contents of catalog:
name tile x y date
0 SD1965429 335309 33.9015 18.2675 2018-02-15
Any pointers on how to find these problem tiles will be much appreciated!