toolsrtm.satellite
Satellite image retrieval via STAC (SpatioTemporal Asset Catalog). Port of
ToolsRTM::get.satellite_collection/get.sentinel2_cube, scoped to
Sentinel-2 L2A on Microsoft Planetary Computer / AWS Earth Search – see the
module docstring for exactly what’s in and out of scope versus the R source.
Note
Needs the optional stac extra: pip install "toolsrtm[stac]"
(pystac-client, planetary-computer, odc-stac, rioxarray, rasterio) and a
live network connection to the chosen STAC API.
Satellite image retrieval via STAC (SpatioTemporal Asset Catalog).
Python port of ToolsRTM::get.satellite_collection/get.sentinel2_cube
(R, built on rstac/gdalcubes). Needs the optional stac extra
(pip install toolsrtm[stac]: pystac-client, planetary-computer,
odc-stac, rioxarray, rasterio) and a live network connection to the chosen
STAC API – neither is imported by toolsrtm/__init__.py, so a plain
import toolsrtm never requires them.
Covers the same 9 collections R’s own per-collection switch() does –
Sentinel-2 L2A, Landsat Collection 2 L2, and 6 MODIS products – via
COLLECTION_ASSETS (default asset/band names looked up automatically
from collection, same as R’s switch(); pass asset_names
yourself to override or point this at any other STAC collection). Verified
live against Microsoft Planetary Computer for Sentinel-2 L2A and Landsat
C2 L2 (see tests/test_satellite.py); the MODIS collections use the same
query/asset-selection code path but weren’t each individually re-verified
live (no eo:cloud_cover property on MODIS items, so cloud filtering is
skipped for those collections, matching R).
Uses a plain (minx, miny, maxx, maxy) WGS84 bounding box rather than R’s
sf polygon + centroid-buffer workflow (get_bounding_box) – pass your
own already-buffered box (e.g. from shapely/geopandas).
- toolsrtm.satellite.COLLECTION_ASSETS = {'landsat-c2-l2': ['blue', 'green', 'red', 'nir08', 'swir16', 'swir22'], 'modis-09A1-061': ['sur_refl_b01', 'sur_refl_b02', 'sur_refl_b03', 'sur_refl_b04', 'sur_refl_b05', 'sur_refl_b06', 'sur_refl_b07'], 'modis-09Q1-061': ['sur_refl_b01', 'sur_refl_b02', 'sur_refl_qc_250m', 'sur_refl_state_250m'], 'modis-11A2-061': ['LST_Day_1km'], 'modis-15A2H-061': ['Lai_500m', 'Fpar_500m', 'LaiStdDev_500m', 'FparStdDev_500m', 'FparLai_QC'], 'modis-15A3H-061': ['Lai_500m', 'Fpar_500m', 'LaiStdDev_500m', 'FparStdDev_500m', 'FparLai_QC'], 'modis-17A2HGF-061': ['Gpp_500m', 'PsnNet_500m'], 'sentinel-2-l2a': ['B02', 'B03', 'B04', 'B05', 'B06', 'B07', 'B08', 'B8A', 'B11', 'B12', 'SCL'], 'sentinel-s2-l2a': ['B02', 'B03', 'B04', 'B05', 'B06', 'B07', 'B08', 'B8A', 'B11', 'B12', 'SCL'], 'sentinel-s2-l2a-cogs': ['B02', 'B03', 'B04', 'B05', 'B06', 'B07', 'B08', 'B8A', 'B11', 'B12', 'SCL']}
Default asset/band names per STAC collection, matching R’s own
get.satellite_collection’s per-collectionswitch().
- class toolsrtm.satellite.SatelliteCollection(items: 'list', metadata: "'pd.DataFrame'", cloud_server: 'str', collection: 'str', asset_names: 'list[str]')[source]
Bases:
object- Parameters:
items (list)
metadata (pd.DataFrame)
cloud_server (str)
collection (str)
asset_names (list[str])
- items: list
signed pystac.Item objects matching the search
- metadata: pd.DataFrame
id, datetime, platform, cloud_cover (where available)
- Type:
one row per item
- cloud_server: str
- collection: str
- asset_names: list[str]
- toolsrtm.satellite.get_satellite_collection(bbox, collection='sentinel-2-l2a', date_range=('2023-06-01', '2023-09-30'), cloud_server='microsoft', n_limit=500, cloud_threshold=20.0, asset_names=None)[source]
Search a STAC API for satellite scenes over a bounding box/date range.
Python port of
get.satellite_collection(R). Filters by cloud cover when the collection has aneo:cloud_coverproperty (true for Sentinel-2/Landsat; skipped otherwise). Items are signed (planetary_computer.sign) whencloud_server="microsoft"so their asset URLs are directly readable.- Parameters:
bbox (Sequence[float]) –
(minx, miny, maxx, maxy)in WGS84 (EPSG:4326).collection (str) – STAC collection id (e.g.
"sentinel-2-l2a").date_range (Sequence[str]) –
(start, end)ISO dates, e.g.("2023-06-01", "2023-09-30").cloud_server (str) –
"microsoft"(Planetary Computer) or"amazon"(Earth Search v1).n_limit (int) – maximum number of items to return.
cloud_threshold (float) – maximum allowed
eo:cloud_coverpercentage.asset_names (Sequence[str] | None) – band/asset names to keep; defaults to the entry for
collectioninCOLLECTION_ASSETS(falling back toDEFAULT_ASSETS, Sentinel-2 L2A’s bands, for an unlisted collection).
- Returns:
- Return type:
- toolsrtm.satellite.get_sentinel2_cube(satellite_collection, bbox, resolution=10.0, crs='EPSG:32632', aggregation_method=None, resampling_method='cubic')[source]
Build a Sentinel-2 (or any STAC collection’s) data cube from a
get_satellite_collection()result, clipped to a bounding box.Python port of
get.sentinel2_cube(R,gdalcubes-based) using odc.stac.load instead – a different resampling/mosaicking engine than R’sgdalcubes, so pixel values won’t match R exactly even for the same scenes/bbox/resolution; both are standard, correct STAC-cube builders, not a numerical port.- Parameters:
satellite_collection (SatelliteCollection) – result of
get_satellite_collection().bbox (Sequence[float]) –
(minx, miny, maxx, maxy)in WGS84 (EPSG:4326) – the crop extent.resolution (float) – output pixel size in
crsunits (metres, for a UTMcrs).crs (str) – output CRS (a projected CRS – pick the correct UTM zone for your area).
aggregation_method (str | None) – if given, one of
"mean","median","min","max","first"– collapses the time dimension (matching R’s ownaggregation_method). IfNone, every scene’s own timestamp is kept.resampling_method (str) – reprojection resampling:
"nearest","bilinear", or"cubic"(matchesodc.stac.load’sresampling).
- Returns:
an xarray.Dataset with one data variable per asset in
satellite_collection.asset_names.- Return type:
xr.Dataset