Getting Started
Quick guide to using SAND for satellite data download
Installation
Install SAND from the GitHub repository:
pip install https://github.com/hygeos/SAND.gitAuthentication
SAND uses the ~/.netrc file for authentication. Create or edit this file with your provider credentials:
machine dataspace.copernicus.eu
login your@email.com
password your_password
machine geodes.cnes.fr
login your@email.com
password your_token_secret
machine data.eumetsat.int
login your_api_key
password your_api_secret
machine urs.earthdata.nasa.gov
login your_username
password your_password
machine m2m.cr.usgs.gov
login your@email.com
password your_api_token
Tip
Ensure the file has restricted permissions: chmod 600 ~/.netrc
Basic workflow
The typical SAND workflow has three steps :
- Initialize a provider
- Query for products matching your constraints
- Download the selected products
Step 1: Initialize a provider
from sand.usgs import DownloadUSGS
# Create a downloader instance
dl = DownloadUSGS()Available providers :
DownloadCDSE— Copernicus Data SpaceDownloadCNES— CNES GeodesDownloadEumDAC— EUMETSAT Data StoreDownloadNASA— NASA CMRDownloadUSGS— USGS M2M API
Step 2: Query products
Use the query() method with temporal, spatial, and naming constraints :
from sand.constraint import Time, Geo
from datetime import datetime
results = dl.query(
collection_sand="LANDSAT-8-OLI",
level=1,
time=Time(
start=datetime(2020, 1, 1),
end=datetime(2020, 12, 31)
),
geo=Geo.Point(lat=48.8566, lon=2.3522), # Paris
cloudcover_thres=20,
)
# Print results
results.print()
# Access individual products
for product in results:
print(product.product_id, product.date)Step 3: Download
from pathlib import Path
# Download a single product
path = dl.download(results[0], dir="./data")
print(f"Downloaded to: {path}")
# Download all products
paths = dl.download_all(results, dir="./data", if_exists="skip")Constraints
Temporal constraints
from sand.constraint import Time
from datetime import datetime
# Full datetime
t = Time(start="2024-01-01", end="2024-06-30")
# Date only (end of day is applied automatically)
from datetime import date
t = Time(start=date(2024, 1, 1), end=date(2024, 6, 30))Spatial constraints
from sand.constraint import Geo
# Point with buffer (~11km at equator)
point = Geo.Point(lat=48.8566, lon=2.3522, extend_factor=0.1)
# Bounding box
polygon = Geo.Polygon(lat_min=48.8, lat_max=48.9, lon_min=2.3, lon_max=2.4)
# MGRS/VENUS tile
tile = Geo.Tile("31TUU")Naming constraints
from sand.constraint import Name
# Name contains all of these strings
name = Name(contains=["T31", "S2A"])
# Name starts with prefix
name = Name(startswith="S2A_MSIL2A")
# Name matches glob pattern
name = Name(glob="*T31TUU*")Caching query results
Use the cache_sandquery decorator to cache query results to JSON :
from sand.results import cache_sandquery
@cache_sandquery("./cache.json")
def my_query():
return dl.query(
collection_sand="SENTINEL-2-MSI",
time=Time(start="2024-01-01", end="2024-01-31"),
geo=Geo.Point(lat=48.8566, lon=2.3522),
)
# First call executes the query and caches results
results = my_query()
# Subsequent calls load from cache
results = my_query()Next steps
- See the Providers guide for provider-specific configuration
- Browse the API Reference for detailed class and method documentation