# Imports
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import xarray as xr
# import s3fs
import re
from pelicanfs.core import PelicanFileSystem, PelicanMap,OSDFFileSystem
# import fsspec.implementations.http as fshttp
import geopandas as gpd
from pystac_client import Client
# from odc.stac import stac_load
from rasterio.mask import mask
import rasterio
from shapely.geometry import box
from urllib.parse import urlparseimport dask
from dask_jobqueue import PBSCluster
from dask.distributed import Client as dask_client
from dask.distributed import performance_reportUse the GeoJSON file to get the Area of Interest and query the STAC catalog for items¶
# Load the GeoJSON file
geojson_path = '3100180240.geojson'
gdf = gpd.read_file(geojson_path)
# Display the loaded GeoDataFrame
print(gdf) id SUB_AREA COAST PFAF_ID DIST_MAIN HYBAS_ID \
0 00140000000000002983 128.1 0 3512704524 784.3 3100180240
DIST_SINK NEXT_DOWN ORDER ENDO MAIN_BAS NEXT_SINK SORT UP_AREA \
0 784.3 3100180230 4 0 3100009670 3100009670 66318 128.1
geometry
0 POLYGON ((134.51667 66.87917, 134.51752 66.875...
# Extract AOI geometry
aoi_geometry = gdf.geometry.iloc[0]
aoi_bounds = aoi_geometry.bounds # (minx, miny, maxx, maxy)
# Get AOI centroid for visualization
centroid = aoi_geometry.centroid
long, lat = centroid.x, centroid.y
# Print the bounding box to verify
print("Bounding Box:", aoi_bounds)Bounding Box: (134.51666686838126, 66.7708333115583, 134.9046488751149, 66.97083294070578)
# Connect to the Earth Search STAC API (Sentinel-2 Level-2A COGs are available here)
catalog_url = "https://earth-search.aws.element84.com/v1"
catalog = Client.open(catalog_url)
# Define the date range as strings
start_date = "2019-01"
end_date = "2023-02"
# Define cloud cover threshold
cloud_cover_max = 0.05 # 5% cloud cover threshold
#cloud_cover_max = 0.20 # 20% cloud cover threshold
# Perform the search
search = catalog.search(
collections=["sentinel-2-l2a"],
bbox=aoi_bounds,
datetime=f"{start_date}/{end_date}",
#datetime="2022-06-01/2022-09-30",
query={"eo:cloud_cover": {"lt": cloud_cover_max * 100}}
)
# Get all matching items
items = list(search.items())
print(f"Found {len(items)} matching items.")Found 258 matching items.
# Confirm that the matching items are hosted in a aws-us-region by printing out the href links for the first n items
n=1
for i, item in enumerate(items[:n]):
print(f"\nItem {i+1}: {item.id}")
for asset_key, asset in item.assets.items():
print(f" {asset_key}: {asset.href}")
Item 1: S2B_53WMQ_20230222_0_L2A
aot: https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/53/W/MQ/2023/2/S2B_53WMQ_20230222_0_L2A/AOT.tif
blue: https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/53/W/MQ/2023/2/S2B_53WMQ_20230222_0_L2A/B02.tif
coastal: https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/53/W/MQ/2023/2/S2B_53WMQ_20230222_0_L2A/B01.tif
granule_metadata: https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/53/W/MQ/2023/2/S2B_53WMQ_20230222_0_L2A/granule_metadata.xml
green: https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/53/W/MQ/2023/2/S2B_53WMQ_20230222_0_L2A/B03.tif
nir: https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/53/W/MQ/2023/2/S2B_53WMQ_20230222_0_L2A/B08.tif
nir08: https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/53/W/MQ/2023/2/S2B_53WMQ_20230222_0_L2A/B8A.tif
nir09: https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/53/W/MQ/2023/2/S2B_53WMQ_20230222_0_L2A/B09.tif
red: https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/53/W/MQ/2023/2/S2B_53WMQ_20230222_0_L2A/B04.tif
rededge1: https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/53/W/MQ/2023/2/S2B_53WMQ_20230222_0_L2A/B05.tif
rededge2: https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/53/W/MQ/2023/2/S2B_53WMQ_20230222_0_L2A/B06.tif
rededge3: https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/53/W/MQ/2023/2/S2B_53WMQ_20230222_0_L2A/B07.tif
scl: https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/53/W/MQ/2023/2/S2B_53WMQ_20230222_0_L2A/SCL.tif
swir16: https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/53/W/MQ/2023/2/S2B_53WMQ_20230222_0_L2A/B11.tif
swir22: https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/53/W/MQ/2023/2/S2B_53WMQ_20230222_0_L2A/B12.tif
thumbnail: https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/53/W/MQ/2023/2/S2B_53WMQ_20230222_0_L2A/thumbnail.jpg
tileinfo_metadata: https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/53/W/MQ/2023/2/S2B_53WMQ_20230222_0_L2A/tileinfo_metadata.json
visual: https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/53/W/MQ/2023/2/S2B_53WMQ_20230222_0_L2A/TCI.tif
wvp: https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/53/W/MQ/2023/2/S2B_53WMQ_20230222_0_L2A/WVP.tif
aot-jp2: s3://sentinel-s2-l2a/tiles/53/W/MQ/2023/2/22/0/AOT.jp2
blue-jp2: s3://sentinel-s2-l2a/tiles/53/W/MQ/2023/2/22/0/B02.jp2
coastal-jp2: s3://sentinel-s2-l2a/tiles/53/W/MQ/2023/2/22/0/B01.jp2
green-jp2: s3://sentinel-s2-l2a/tiles/53/W/MQ/2023/2/22/0/B03.jp2
nir-jp2: s3://sentinel-s2-l2a/tiles/53/W/MQ/2023/2/22/0/B08.jp2
nir08-jp2: s3://sentinel-s2-l2a/tiles/53/W/MQ/2023/2/22/0/B8A.jp2
nir09-jp2: s3://sentinel-s2-l2a/tiles/53/W/MQ/2023/2/22/0/B09.jp2
red-jp2: s3://sentinel-s2-l2a/tiles/53/W/MQ/2023/2/22/0/B04.jp2
rededge1-jp2: s3://sentinel-s2-l2a/tiles/53/W/MQ/2023/2/22/0/B05.jp2
rededge2-jp2: s3://sentinel-s2-l2a/tiles/53/W/MQ/2023/2/22/0/B06.jp2
rededge3-jp2: s3://sentinel-s2-l2a/tiles/53/W/MQ/2023/2/22/0/B07.jp2
scl-jp2: s3://sentinel-s2-l2a/tiles/53/W/MQ/2023/2/22/0/SCL.jp2
swir16-jp2: s3://sentinel-s2-l2a/tiles/53/W/MQ/2023/2/22/0/B11.jp2
swir22-jp2: s3://sentinel-s2-l2a/tiles/53/W/MQ/2023/2/22/0/B12.jp2
visual-jp2: s3://sentinel-s2-l2a/tiles/53/W/MQ/2023/2/22/0/TCI.jp2
wvp-jp2: s3://sentinel-s2-l2a/tiles/53/W/MQ/2023/2/22/0/WVP.jp2
from shapely.geometry import mapping
# Reproject AOI to match raster CRS
from pyproj import CRS
from geopandas import GeoSeriesdef returnOSDFPath(url):
"""
Converts a URL to an OSDF path.
Parameters:
- url: URL to convert.
Returns:
- OSDF path.
"""
# Parse the URL
parsed_url = urlparse(url)
# Construct the OSDF path
osdf_path = f"/aws-opendata/us-west-2/sentinel-cogs{parsed_url.path}"
return osdf_path
Apply various masks and calculate NDVI¶
def clp(image_src, aoi_geometry):
"""
Clip a raster image to the Area of Interest (AOI).
Parameters:
- image_src: Open rasterio dataset.
- aoi_geometry: AOI geometry as a GeoJSON-like object.
Returns:
- Clipped image array and updated metadata.
"""
# out_image, out_transform = mask(image_src, [aoi_geometry], crop=True)
out_image, out_transform = mask(image_src, aoi_geometry, crop=True)
out_meta = image_src.meta.copy()
out_meta.update({
"driver": "GTiff",
"height": out_image.shape[1],
"width": out_image.shape[2],
"transform": out_transform
})
return out_image, out_meta
def maskWater(image, water_mask):
"""
Masks out water pixels using the MODIS water mask.
Parameters:
- image: Raster image to mask.
- water_mask: Water mask raster.
Returns:
- Water-masked image.
"""
water = water_mask.read(1) # Read the water mask
mask = water < 1 # Mask water pixels (water < 1)
image_masked = np.where(mask, image, np.nan)
return image_masked
def maskS2snow(image, snow_prob):
"""
Masks snow pixels using the MSK_SNWPRB (Snow Probability Mask).
Parameters:
- image: Raster image to mask.
- snow_prob: Snow probability raster.
Returns:
- Snow-masked image.
"""
snow = snow_prob.read(1) # Read the snow probability mask
mask = snow < 0.009 # Mask snow pixels (snow probability < 0.9%)
image_masked = np.where(mask, image, np.nan)
return image_masked
def maskWhite(image, b2, b3, b4):
"""
Masks white pixels by converting RGB to grayscale and applying a threshold.
Parameters:
- image: Raster image to mask.
- b2, b3, b4: Blue, Green, and Red bands respectively.
Returns:
- Grayscale-masked image.
"""
# Convert RGB to grayscale
grayscale = (0.3 * b4.read(1) + 0.59 * b3.read(1) + 0.11 * b2.read(1)) * 1e4
mask = grayscale <= 2000 # Mask white pixels (grayscale > 2000)
image_masked = np.where(mask, image, np.nan)
return image_masked%%time
# Loop through each item in the STAC query
for idx, item in enumerate(items, start=1):
print(f"Processing dataset #{idx}")
# Check required assets
required_assets = ["red", "green", "blue", "scl"]
if not all(asset in item.assets for asset in required_assets):
print(f"Skipping dataset #{idx}: Missing required assets.")
continue
# Get asset URLs
red_url = item.assets["red"].href
green_url = item.assets["green"].href
blue_url = item.assets["blue"].href
scl_url = item.assets["scl"].href
# Reproject AOI to match raster CRS
with rasterio.open(red_url) as src:
raster_crs = CRS(src.crs)
aoi_geometry_reprojected = GeoSeries(aoi_geometry).set_crs(gdf.crs).to_crs(raster_crs)
# Open and clip bands
with rasterio.open(red_url) as red_src, \
rasterio.open(green_url) as green_src, \
rasterio.open(blue_url) as blue_src, \
rasterio.open(scl_url) as scl_src:
aoi_geometry_reprojected = GeoSeries(aoi_geometry).set_crs(gdf.crs).to_crs(raster_crs)
raster_bounds = box(*red_src.bounds)
if not aoi_geometry_reprojected[0].intersects(raster_bounds):
print(f"Warning: AOI does not intersect the bounds of {red_url}. Skipping.")
continue
# Clip all RGB and SCL bands to AOI
red_clipped, red_meta = clp(red_src, aoi_geometry_reprojected)
green_clipped, _ = clp(green_src, aoi_geometry_reprojected)
blue_clipped, _ = clp(blue_src, aoi_geometry_reprojected)
scl_clipped, _ = clp(scl_src, aoi_geometry_reprojected)
# # Clip water_mask if available
# if water_mask_available:
# with rasterio.open(water_mask_url) as water_mask_src:
# water_mask_clipped, _ = clp(water_mask_src, aoi_geometry_reprojected)
# Apply maskS2clouds
# red_masked = maskS2clouds(red_clipped, scl_clipped)
# green_masked = maskS2clouds(green_clipped, scl_clipped)
# blue_masked = maskS2clouds(blue_clipped, scl_clipped)
# # Apply maskWater if available
# if water_mask_available:
# red_masked = maskWater(red_masked, water_mask_clipped)
# green_masked = maskWater(green_masked, water_mask_clipped)
# blue_masked = maskWater(blue_masked, water_mask_clipped)
# # Apply maskWhite
# red_final = maskWhite(red_clipped, blue_clipped, green_clipped, red_clipped)
# green_final = maskWhite(green_clipped, blue_clipped, green_clipped, red_clipped)
# blue_final = maskWhite(blue_clipped, blue_clipped, green_clipped, red_clipped)
print(f"Dataset #{idx} processed. Ready for visualization or further analysis.")Processing dataset #1
Dataset #1 processed. Ready for visualization or further analysis.
Processing dataset #2
Dataset #2 processed. Ready for visualization or further analysis.
Processing dataset #3
Dataset #3 processed. Ready for visualization or further analysis.
Processing dataset #4
Dataset #4 processed. Ready for visualization or further analysis.
Processing dataset #5
Dataset #5 processed. Ready for visualization or further analysis.
Processing dataset #6
Dataset #6 processed. Ready for visualization or further analysis.
Processing dataset #7
Dataset #7 processed. Ready for visualization or further analysis.
Processing dataset #8
Dataset #8 processed. Ready for visualization or further analysis.
Processing dataset #9
Dataset #9 processed. Ready for visualization or further analysis.
Processing dataset #10
Dataset #10 processed. Ready for visualization or further analysis.
Processing dataset #11
Dataset #11 processed. Ready for visualization or further analysis.
Processing dataset #12
Dataset #12 processed. Ready for visualization or further analysis.
Processing dataset #13
Dataset #13 processed. Ready for visualization or further analysis.
Processing dataset #14
Dataset #14 processed. Ready for visualization or further analysis.
Processing dataset #15
Dataset #15 processed. Ready for visualization or further analysis.
Processing dataset #16
Dataset #16 processed. Ready for visualization or further analysis.
Processing dataset #17
Dataset #17 processed. Ready for visualization or further analysis.
Processing dataset #18
Dataset #18 processed. Ready for visualization or further analysis.
Processing dataset #19
Dataset #19 processed. Ready for visualization or further analysis.
Processing dataset #20
Dataset #20 processed. Ready for visualization or further analysis.
Processing dataset #21
Dataset #21 processed. Ready for visualization or further analysis.
Processing dataset #22
Dataset #22 processed. Ready for visualization or further analysis.
Processing dataset #23
Dataset #23 processed. Ready for visualization or further analysis.
Processing dataset #24
Dataset #24 processed. Ready for visualization or further analysis.
Processing dataset #25
Dataset #25 processed. Ready for visualization or further analysis.
Processing dataset #26
Dataset #26 processed. Ready for visualization or further analysis.
Processing dataset #27
Dataset #27 processed. Ready for visualization or further analysis.
Processing dataset #28
Dataset #28 processed. Ready for visualization or further analysis.
Processing dataset #29
Dataset #29 processed. Ready for visualization or further analysis.
Processing dataset #30
Dataset #30 processed. Ready for visualization or further analysis.
Processing dataset #31
Dataset #31 processed. Ready for visualization or further analysis.
Processing dataset #32
Dataset #32 processed. Ready for visualization or further analysis.
Processing dataset #33
Dataset #33 processed. Ready for visualization or further analysis.
Processing dataset #34
Dataset #34 processed. Ready for visualization or further analysis.
Processing dataset #35
Dataset #35 processed. Ready for visualization or further analysis.
Processing dataset #36
Dataset #36 processed. Ready for visualization or further analysis.
Processing dataset #37
Dataset #37 processed. Ready for visualization or further analysis.
Processing dataset #38
Dataset #38 processed. Ready for visualization or further analysis.
Processing dataset #39
Dataset #39 processed. Ready for visualization or further analysis.
Processing dataset #40
Dataset #40 processed. Ready for visualization or further analysis.
Processing dataset #41
Dataset #41 processed. Ready for visualization or further analysis.
Processing dataset #42
Dataset #42 processed. Ready for visualization or further analysis.
Processing dataset #43
Dataset #43 processed. Ready for visualization or further analysis.
Processing dataset #44
Dataset #44 processed. Ready for visualization or further analysis.
Processing dataset #45
Dataset #45 processed. Ready for visualization or further analysis.
Processing dataset #46
Dataset #46 processed. Ready for visualization or further analysis.
Processing dataset #47
Dataset #47 processed. Ready for visualization or further analysis.
Processing dataset #48
Dataset #48 processed. Ready for visualization or further analysis.
Processing dataset #49
Dataset #49 processed. Ready for visualization or further analysis.
Processing dataset #50
Dataset #50 processed. Ready for visualization or further analysis.
Processing dataset #51
Dataset #51 processed. Ready for visualization or further analysis.
Processing dataset #52
Dataset #52 processed. Ready for visualization or further analysis.
Processing dataset #53
Dataset #53 processed. Ready for visualization or further analysis.
Processing dataset #54
Dataset #54 processed. Ready for visualization or further analysis.
Processing dataset #55
Dataset #55 processed. Ready for visualization or further analysis.
Processing dataset #56
Dataset #56 processed. Ready for visualization or further analysis.
Processing dataset #57
Dataset #57 processed. Ready for visualization or further analysis.
Processing dataset #58
Dataset #58 processed. Ready for visualization or further analysis.
Processing dataset #59
Dataset #59 processed. Ready for visualization or further analysis.
Processing dataset #60
Dataset #60 processed. Ready for visualization or further analysis.
Processing dataset #61
Dataset #61 processed. Ready for visualization or further analysis.
Processing dataset #62
Dataset #62 processed. Ready for visualization or further analysis.
Processing dataset #63
Dataset #63 processed. Ready for visualization or further analysis.
Processing dataset #64
Dataset #64 processed. Ready for visualization or further analysis.
Processing dataset #65
Dataset #65 processed. Ready for visualization or further analysis.
Processing dataset #66
Dataset #66 processed. Ready for visualization or further analysis.
Processing dataset #67
Dataset #67 processed. Ready for visualization or further analysis.
Processing dataset #68
Dataset #68 processed. Ready for visualization or further analysis.
Processing dataset #69
Dataset #69 processed. Ready for visualization or further analysis.
Processing dataset #70
Dataset #70 processed. Ready for visualization or further analysis.
Processing dataset #71
Dataset #71 processed. Ready for visualization or further analysis.
Processing dataset #72
Dataset #72 processed. Ready for visualization or further analysis.
Processing dataset #73
Dataset #73 processed. Ready for visualization or further analysis.
Processing dataset #74
Dataset #74 processed. Ready for visualization or further analysis.
Processing dataset #75
Dataset #75 processed. Ready for visualization or further analysis.
Processing dataset #76
Dataset #76 processed. Ready for visualization or further analysis.
Processing dataset #77
Dataset #77 processed. Ready for visualization or further analysis.
Processing dataset #78
Dataset #78 processed. Ready for visualization or further analysis.
Processing dataset #79
Dataset #79 processed. Ready for visualization or further analysis.
Processing dataset #80
Dataset #80 processed. Ready for visualization or further analysis.
Processing dataset #81
Dataset #81 processed. Ready for visualization or further analysis.
Processing dataset #82
Dataset #82 processed. Ready for visualization or further analysis.
Processing dataset #83
Dataset #83 processed. Ready for visualization or further analysis.
Processing dataset #84
Dataset #84 processed. Ready for visualization or further analysis.
Processing dataset #85
Dataset #85 processed. Ready for visualization or further analysis.
Processing dataset #86
Dataset #86 processed. Ready for visualization or further analysis.
Processing dataset #87
Dataset #87 processed. Ready for visualization or further analysis.
Processing dataset #88
Dataset #88 processed. Ready for visualization or further analysis.
Processing dataset #89
Dataset #89 processed. Ready for visualization or further analysis.
Processing dataset #90
Dataset #90 processed. Ready for visualization or further analysis.
Processing dataset #91
Dataset #91 processed. Ready for visualization or further analysis.
Processing dataset #92
Dataset #92 processed. Ready for visualization or further analysis.
Processing dataset #93
Dataset #93 processed. Ready for visualization or further analysis.
Processing dataset #94
Dataset #94 processed. Ready for visualization or further analysis.
Processing dataset #95
Dataset #95 processed. Ready for visualization or further analysis.
Processing dataset #96
Dataset #96 processed. Ready for visualization or further analysis.
Processing dataset #97
Dataset #97 processed. Ready for visualization or further analysis.
Processing dataset #98
Dataset #98 processed. Ready for visualization or further analysis.
Processing dataset #99
Dataset #99 processed. Ready for visualization or further analysis.
Processing dataset #100
Dataset #100 processed. Ready for visualization or further analysis.
Processing dataset #101
Dataset #101 processed. Ready for visualization or further analysis.
Processing dataset #102
Dataset #102 processed. Ready for visualization or further analysis.
Processing dataset #103
Dataset #103 processed. Ready for visualization or further analysis.
Processing dataset #104
Dataset #104 processed. Ready for visualization or further analysis.
Processing dataset #105
Dataset #105 processed. Ready for visualization or further analysis.
Processing dataset #106
Dataset #106 processed. Ready for visualization or further analysis.
Processing dataset #107
Dataset #107 processed. Ready for visualization or further analysis.
Processing dataset #108
Dataset #108 processed. Ready for visualization or further analysis.
Processing dataset #109
Dataset #109 processed. Ready for visualization or further analysis.
Processing dataset #110
Dataset #110 processed. Ready for visualization or further analysis.
Processing dataset #111
Dataset #111 processed. Ready for visualization or further analysis.
Processing dataset #112
Dataset #112 processed. Ready for visualization or further analysis.
Processing dataset #113
Dataset #113 processed. Ready for visualization or further analysis.
Processing dataset #114
Dataset #114 processed. Ready for visualization or further analysis.
Processing dataset #115
Dataset #115 processed. Ready for visualization or further analysis.
Processing dataset #116
Dataset #116 processed. Ready for visualization or further analysis.
Processing dataset #117
Dataset #117 processed. Ready for visualization or further analysis.
Processing dataset #118
Dataset #118 processed. Ready for visualization or further analysis.
Processing dataset #119
Dataset #119 processed. Ready for visualization or further analysis.
Processing dataset #120
Dataset #120 processed. Ready for visualization or further analysis.
Processing dataset #121
Dataset #121 processed. Ready for visualization or further analysis.
Processing dataset #122
Dataset #122 processed. Ready for visualization or further analysis.
Processing dataset #123
Dataset #123 processed. Ready for visualization or further analysis.
Processing dataset #124
Dataset #124 processed. Ready for visualization or further analysis.
Processing dataset #125
Dataset #125 processed. Ready for visualization or further analysis.
Processing dataset #126
Dataset #126 processed. Ready for visualization or further analysis.
Processing dataset #127
Dataset #127 processed. Ready for visualization or further analysis.
Processing dataset #128
Dataset #128 processed. Ready for visualization or further analysis.
Processing dataset #129
Dataset #129 processed. Ready for visualization or further analysis.
Processing dataset #130
Dataset #130 processed. Ready for visualization or further analysis.
Processing dataset #131
Dataset #131 processed. Ready for visualization or further analysis.
Processing dataset #132
Dataset #132 processed. Ready for visualization or further analysis.
Processing dataset #133
Dataset #133 processed. Ready for visualization or further analysis.
Processing dataset #134
Dataset #134 processed. Ready for visualization or further analysis.
Processing dataset #135
Dataset #135 processed. Ready for visualization or further analysis.
Processing dataset #136
Dataset #136 processed. Ready for visualization or further analysis.
Processing dataset #137
Dataset #137 processed. Ready for visualization or further analysis.
Processing dataset #138
Dataset #138 processed. Ready for visualization or further analysis.
Processing dataset #139
Dataset #139 processed. Ready for visualization or further analysis.
Processing dataset #140
Dataset #140 processed. Ready for visualization or further analysis.
Processing dataset #141
Dataset #141 processed. Ready for visualization or further analysis.
Processing dataset #142
Dataset #142 processed. Ready for visualization or further analysis.
Processing dataset #143
Dataset #143 processed. Ready for visualization or further analysis.
Processing dataset #144
Dataset #144 processed. Ready for visualization or further analysis.
Processing dataset #145
Dataset #145 processed. Ready for visualization or further analysis.
Processing dataset #146
Dataset #146 processed. Ready for visualization or further analysis.
Processing dataset #147
Dataset #147 processed. Ready for visualization or further analysis.
Processing dataset #148
Dataset #148 processed. Ready for visualization or further analysis.
Processing dataset #149
Dataset #149 processed. Ready for visualization or further analysis.
Processing dataset #150
Dataset #150 processed. Ready for visualization or further analysis.
Processing dataset #151
Dataset #151 processed. Ready for visualization or further analysis.
Processing dataset #152
Dataset #152 processed. Ready for visualization or further analysis.
Processing dataset #153
Dataset #153 processed. Ready for visualization or further analysis.
Processing dataset #154
Dataset #154 processed. Ready for visualization or further analysis.
Processing dataset #155
Dataset #155 processed. Ready for visualization or further analysis.
Processing dataset #156
Dataset #156 processed. Ready for visualization or further analysis.
Processing dataset #157
Dataset #157 processed. Ready for visualization or further analysis.
Processing dataset #158
Dataset #158 processed. Ready for visualization or further analysis.
Processing dataset #159
Dataset #159 processed. Ready for visualization or further analysis.
Processing dataset #160
Dataset #160 processed. Ready for visualization or further analysis.
Processing dataset #161
Dataset #161 processed. Ready for visualization or further analysis.
Processing dataset #162
Dataset #162 processed. Ready for visualization or further analysis.
Processing dataset #163
Dataset #163 processed. Ready for visualization or further analysis.
Processing dataset #164
Dataset #164 processed. Ready for visualization or further analysis.
Processing dataset #165
Dataset #165 processed. Ready for visualization or further analysis.
Processing dataset #166
Dataset #166 processed. Ready for visualization or further analysis.
Processing dataset #167
Dataset #167 processed. Ready for visualization or further analysis.
Processing dataset #168
Dataset #168 processed. Ready for visualization or further analysis.
Processing dataset #169
Dataset #169 processed. Ready for visualization or further analysis.
Processing dataset #170
Dataset #170 processed. Ready for visualization or further analysis.
Processing dataset #171
Dataset #171 processed. Ready for visualization or further analysis.
Processing dataset #172
Dataset #172 processed. Ready for visualization or further analysis.
Processing dataset #173
# %%time
# # Using pelicanfs
# # Loop through each item in the STAC query
# for idx, item in enumerate(items, start=1):
# print(f"Processing dataset #{idx}")
# # Check required assets
# required_assets = ["red", "green", "blue", "scl"]
# if not all(asset in item.assets for asset in required_assets):
# print(f"Skipping dataset #{idx}: Missing required assets.")
# continue
# # Get asset URLs
# red_url = item.assets["red"].href
# green_url = item.assets["green"].href
# blue_url = item.assets["blue"].href
# scl_url = item.assets["scl"].href
# pel_red_url = returnOSDFPath(red_url)
# pel_green_url = returnOSDFPath(green_url)
# pel_blue_url = returnOSDFPath(blue_url)
# pel_scl_url = returnOSDFPath(scl_url)
# pelfs = PelicanFileSystem("pelican://osg-htc.org")
# # Reproject AOI to match raster CRS
# with rasterio.open(pel_red_url,opener=pelfs) as src:
# with rasterio.open(red_url) as src:
# raster_crs = CRS(src.crs)
# aoi_geometry_reprojected = GeoSeries(aoi_geometry).set_crs(gdf.crs).to_crs(raster_crs)
# # Reproject AOI to match raster CRS
# with rasterio.open(pel_red_url, opener=pelfs) as red_src, \
# rasterio.open(pel_green_url, opener=pelfs) as green_src, \
# rasterio.open(pel_blue_url, opener=pelfs) as blue_src, \
# rasterio.open(pel_scl_url, opener=pelfs) as scl_src:
# aoi_geometry_reprojected = GeoSeries(aoi_geometry).set_crs(gdf.crs).to_crs(raster_crs)
# raster_bounds = box(*red_src.bounds)
# if not aoi_geometry_reprojected[0].intersects(raster_bounds):
# print(f"Warning: AOI does not intersect the bounds of {red_url}. Skipping.")
# continue
# # Clip all RGB and SCL bands to AOI
# red_clipped, red_meta = clp(red_src, aoi_geometry_reprojected)
# green_clipped, _ = clp(green_src, aoi_geometry_reprojected)
# blue_clipped, _ = clp(blue_src, aoi_geometry_reprojected)
# scl_clipped, _ = clp(scl_src, aoi_geometry_reprojected)
# print(f"Dataset #{idx} processed. Ready for visualization or further analysis.")from sklearn.preprocessing import MinMaxScaler
# Function to scale image bands properly
def scale_band(band):
scaler = MinMaxScaler(feature_range=(0, 1))
return scaler.fit_transform(band) # Normalize between 0-1
# Assuming red_clipped, green_clipped, and blue_clipped are 2D NumPy arrays
rgb = np.dstack((scale_band(red_clipped.squeeze()),
scale_band(green_clipped.squeeze()),
scale_band(blue_clipped.squeeze()),
))
# Plot
plt.figure(figsize=(10, 8))
plt.imshow(rgb)
plt.axis("off")
plt.show()# def visualize_rgb(red_band, green_band, blue_band, title="RGB Composite"):
# """
# Visualizes an RGB composite of raster bands using matplotlib.
# Parameters:
# - red_band, green_band, blue_band (numpy array): Red, Green, and Blue bands.
# - title (str): Title for the plot.
# """
# rgb = np.dstack((
# np.clip(red_band, 0, 1), # Normalize reflectance between 0-1
# np.clip(green_band, 0, 1),
# np.clip(blue_band, 0, 1)
# ))
# plt.figure(figsize=(10, 8))
# plt.imshow(rgb)
# plt.title(title)
# plt.axis("off")
# plt.show()
# # Example: Visualize RGB composite
# visualize_rgb(red_clipped, green_clipped, blue_clipped, title="Processed RGB Composite")