# Open the Zarr store from S3
fs = s3fs.S3FileSystem(profile="default", asynchronous=True)
zstore = zarr.storage.FsspecStore(fs, path=mosaic_output.removeprefix('s3://')) # FsspecStore expects a path without the 's3://' scheme prefix
ds = xr.open_zarr(zstore)
# Create a transformer to convert from lat/lon to meters
transformer = Transformer.from_crs("EPSG:4326", "EPSG:3857", always_xy=True)
# Transform bounding box coordinates from lat/lon to meters
(min_x, max_x), (min_y, max_y) = transformer.transform(
[min_lon, max_lon],
[min_lat, max_lat]
)
# Subset the data to our AOI bounds
# Determine y-coordinate order (ascending vs descending) to slice correctly
if ds.y[0] < ds.y[-1]:
ds_subset = ds.sel(x=slice(min_x, max_x), y=slice(min_y, max_y))
else:
ds_subset = ds.sel(x=slice(min_x, max_x), y=slice(max_y, min_y))
# Select RGB bands and access the variables array
# Band names are prefixed with the dataset name (e.g., s2med_harvest:B04)
rgb = ds_subset.sel(band=["s2med_harvest:B04", "s2med_harvest:B03", "s2med_harvest:B02"])["variables"]
# Handle time dimension if present
if "time" in rgb.dims:
rgb = rgb.isel(time=0)
# Normalize values for display (Sentinel-2 reflectance * 10000)
rgb_normalized = rgb / 3000
rgb_normalized = rgb_normalized.clip(0, 1)
# Visualize as RGB composite
rgb_normalized.hvplot.rgb(
x="x",
y="y",
bands="band",
data_aspect=1,
xaxis=False,
yaxis=False,
title="Harvest Season Mosaic - Haskell County, KS (2024)",
frame_width=600,
)