-
Notifications
You must be signed in to change notification settings - Fork 252
Open
Labels
Description
Hi Sentinel Hub Team,
I’m currently using the SentinelHub Python package to pull NDWI values for a specific for a golf club in Butner, NC area — bounding box: [-78.7936, 36.0958, -78.7780, 36.1088], CRS: WGS84). My data source is Sentinel-2 L2A.
My workflow:
- Request Sentinel-2 L2A imagery with a custom evalscript to calculate NDWI
- Convert the raster response into a tabular CSV format (longitude, latitude, NDWI)
The part I’m struggling with is:
- I want to automatically extract the acquisition date of each image and add it as a column in the tabular output.
- Right now I can only insert a static date manually.
Could you advise how to:
- Extract the acquisition timestamp for Sentinel-2 L2A data directly from the API response.
- Append it automatically to each row in the CSV.
Any guidance or example code on how to include the acquisition date in addition to the NDWI values would be really helpful.
Thank you for your support!
heres my code
# NDWI SENTINEL HUB
from sentinelhub import SHConfig, SentinelHubRequest, DataCollection, MimeType, CRS, BBox, bbox_to_dimensions, SentinelHubDownloadClient, DownloadFailedException
import numpy as np
import pandas as pd
from datetime import datetime
import json
# ---------------------------
# STEP 1: SentinelHub credentials
# ---------------------------
config = SHConfig()
config.sh_client_id =
config.sh_client_secret =
print("Step 1: Credentials loaded.")
# ---------------------------
# STEP 2: Define Area of Interest (Butner Clover Club Country, NC)
# ---------------------------
try:
# 'crs' stands for Coordinate Reference System. It tells the program how to interpret the latitude and longitude values in the bounding box.
# In this case, CRS.WGS84 means we are using the standard GPS coordinate system for these coordinates.
bbox = BBox([-78.7936, 36.0958, -78.7780, 36.1088], crs=CRS.WGS84)
resolution = 10
size = bbox_to_dimensions(bbox, resolution=resolution) #?????
print("Step 2: Area of interest defined successfully.")
except Exception as e:
print(f"ERROR at Step 2: Failed to define BBox or dimensions. Error: {e}")
exit()
# ---------------------------
# STEP 3: CALCUALTING NDWI
# ---------------------------
try:
ndwi_script = """
//VERSION=3
function setup() {
return {
input: ["B03", "B08"],
output: { bands: 1, sampleType: "FLOAT32" } #
};
}
function evaluatePixel(sample) {
let ndwi = (sample.B03 - sample.B08) / (sample.B03 + sample.B08);
return [ndwi];
}
"""
print("Step 3: Evalscript defined.")
except Exception as e:
print(f"ERROR at Step 3: Failed to define evalscript. Error: {e}")
exit()
# ---------------------------
# STEP 4: Make request - Use Sentinel‑2 L2A images in this date range, filter out cloudy scenes (>20%), and if combining scenes, pick the least cloudy pixels
# ---------------------------
try:
request = SentinelHubRequest(
evalscript=ndwi_script,
input_data=[SentinelHubRequest.input_data(
DataCollection.SENTINEL2_L2A,
# We add a max_cc of 20% to avoid cloudy images.
time_interval=("2024-01-01", "2024-06-30"),
maxcc=0.20,
# This is crucial. It tells the API to return all available scenes in the time interval.
mosaicking_order='leastCC'
)],
responses=[
SentinelHubRequest.output_response("default", MimeType.TIFF)
],
bbox=bbox,
size=size,
config=config
)
print("Step 4: Request object created.")
except Exception as e:
print(f"ERROR at Step 4: Failed to create SentinelHubRequest. Error: {e}")
exit()
# ---------------------------
# STEP 5: Get data and process
# ---------------------------
try:
# Get the NDWI data
ndwi_img = request.get_data()[0].squeeze() #runs the request data and turns to 2D array
print("Step 5: Data retrieved successfully.")
# For now, let's add a placeholder date that we can verify manually
# TODO: Implement proper date extraction from Sentinel Hub metadata
acquisition_date = "2024-01-01" # Placeholder - needs proper implementation
# Convert to tabular format
rows, cols = ndwi_img.shape
x_coords = np.linspace(bbox.min_x, bbox.max_x, cols)
y_coords = np.linspace(bbox.min_y, bbox.max_y, rows)
lon, lat = np.meshgrid(x_coords, y_coords)
df = pd.DataFrame({
"longitude": lon.flatten(),
"latitude": lat.flatten(),
"NDWI": ndwi_img.flatten(),
"date": acquisition_date
})
print("Step 5: Data processed and converted to DataFrame.")
except Exception as e:
print(f"ERROR at Step 5: Failed during data retrieval or processing. Error: {e}")
exit()
# ---------------------------
# STEP 6: Save or return DataFrame
# ---------------------------
try:
df.to_csv("butner_clover_club_ndwi_" + datetime.now().strftime("%Y%m%d_%H%M%S") + ".csv", index=False)
print("Step 6: Data successfully saved to CSV.")
dataset = df
except Exception as e:
print(f"ERROR at Step 6: Failed to save to CSV. Error: {e}")
exit()
print("\nScript finished. Check the CSV file for results with multiple acquisition dates.")```Reactions are currently unavailable