Skill Tracer
Skills › Scientific Agent Skills › geomaster › data-sources.md

data-sources.md

161 lines · skills/geomaster/references/data-sources.md at 5f2bc03

Open on GitHub
1# Geospatial data sources and API contracts
2
3Reviewed 2026-10-01. Public STAC metadata searches were exercised; authenticated
4pixel downloads, commercial APIs, CDS jobs and Earth Engine exports were not.
5

Geospatial data sources and API contracts

Reviewed 2026-10-01. Public STAC metadata searches were exercised; authenticated pixel downloads, commercial APIs, CDS jobs and Earth Engine exports were not.

Raw lines 1 to 5
6## Satellite, elevation and thematic catalogs
7
8| Data | Official discovery entry point | Selection checks |
9|---|---|---|
10| Sentinel-1/2/3/5P | [Copernicus Data Space](https://dataspace.copernicus.eu/) | Mission, processing level, mode, polarization, baseline and QA |
11| Landsat archive | [USGS EarthExplorer](https://earthexplorer.usgs.gov/) | Collection 2, L1 versus L2, optical versus thermal availability |
12| PlanetScope/SkySat | [Planet](https://docs.planet.com/) | Licensed product and asset type; resolution varies by product |
13| Maxar, Airbus, Capella | Provider catalogs | Confirm current license, acquisition and processing contract before ordering |
14| SRTM, ASTER GDEM, Copernicus DEM | [CDSE DEM](https://documentation.dataspace.copernicus.eu/Data/Additional.html) and producer catalogs | DSM versus bare-earth DEM, void masks, vertical datum and angular pixel spacing |
15| AW3D30 | [JAXA](https://www.eorc.jaxa.jp/ALOS/en/aw3d30/) | Product version, DSM interpretation, masks |
16| ArcticDEM | [Polar Geospatial Center](https://www.pgc.umn.edu/data/arcticdem/) | Strip versus mosaic, reference frame and acquisition dates |
17| WorldCover, MODIS land cover, NLCD | [ESA WorldCover](https://esa-worldcover.org/), [LP DAAC](https://lpdaac.usgs.gov/), [MRLC](https://www.mrlc.gov/) | Legend and year, not a universal class count |
18| ERA5, MERRA-2, JRA | [CDS](https://cds.climate.copernicus.eu/), [NASA GMAO](https://gmao.gsfc.nasa.gov/), [JMA](https://jra.kishou.go.jp/) | Dataset-specific temporal coverage, grid, units and accumulation intervals |
19| Admin/hydrology/population | [Natural Earth](https://www.naturalearthdata.com/), [GADM](https://gadm.org/), [HydroSHEDS](https://www.hydrosheds.org/), [WorldPop](https://www.worldpop.org/), [HDX](https://data.humdata.org/) | Boundary vintage, population counts versus densities, attribution/license |
21Do not use the retired SciHub DHuS endpoint or `SentinelAPI(...scihub...)` for new
22workflows. CDSE is a different service; STAC metadata discovery does not imply
23unauthenticated access to every linked product. Follow the selected asset's CDSE
24S3/OData access instructions rather than inventing a download URL.

Satellite, elevation and thematic catalogs

DataOfficial discovery entry pointSelection checks
Sentinel-1/2/3/5PCopernicus Data SpaceMission, processing level, mode, polarization, baseline and QA
Landsat archiveUSGS EarthExplorerCollection 2, L1 versus L2, optical versus thermal availability
PlanetScope/SkySatPlanetLicensed product and asset type; resolution varies by product
Maxar, Airbus, CapellaProvider catalogsConfirm current license, acquisition and processing contract before ordering
SRTM, ASTER GDEM, Copernicus DEMCDSE DEM and producer catalogsDSM versus bare-earth DEM, void masks, vertical datum and angular pixel spacing
AW3D30JAXAProduct version, DSM interpretation, masks
ArcticDEMPolar Geospatial CenterStrip versus mosaic, reference frame and acquisition dates
WorldCover, MODIS land cover, NLCDESA WorldCover, LP DAAC, MRLCLegend and year, not a universal class count
ERA5, MERRA-2, JRACDS, NASA GMAO, JMADataset-specific temporal coverage, grid, units and accumulation intervals
Admin/hydrology/populationNatural Earth, GADM, HydroSHEDS, WorldPop, HDXBoundary vintage, population counts versus densities, attribution/license

Do not use the retired SciHub DHuS endpoint or SentinelAPI(...scihub...) for new workflows. CDSE is a different service; STAC metadata discovery does not imply unauthenticated access to every linked product. Follow the selected asset's CDSE S3/OData access instructions rather than inventing a download URL.

Raw lines 6 to 25
26## STAC search
28| Catalog root | Contract |
29|---|---|
30| `https://stac.dataspace.copernicus.eu/v1` | CDSE public STAC discovery; inspect collection/queryables and asset access requirements |
31| `https://earth-search.aws.element84.com/v1` | Element 84 Earth Search; Sentinel asset keys use names such as `red`, `nir`, `scl` |
32| `https://planetarycomputer.microsoft.com/api/stac/v1` | Microsoft Planetary Computer; Sentinel keys include `B04`, `B08`, `SCL`; sign protected Azure assets |
34Each supports Item Search under `/search` and returns GeoJSON `FeatureCollection`
35with `features` and pagination links. Follow `rel=next` including its method/body;
36do not construct page numbers. GeoJSON bbox is west,south,east,north in degrees.
37Collection IDs and asset keys are provider-specific even for the same mission.
39```python
40from pystac_client import Client
42catalog = Client.open('https://earth-search.aws.element84.com/v1')
43search = catalog.search(collections=['sentinel-2-l2a'],
44 bbox=[-122.5, 37.7, -122.3, 37.9],
45 datetime='2023-06-01/2023-06-30',
46 query={'eo:cloud_cover': {'lt': 20}},
47 limit=2, max_items=5)
48items = list(search.items())
49if not items:
50 raise ValueError('No matching items')
51asset_metadata = {k: a.to_dict() for k, a in items[0].assets.items()}
52```
54`items()` is an iterator that fetches further pages; `item_collection()` materializes
55the bounded result. `limit` is per-page, `max_items` is the client total.
56Scene cloud percentage is only a coarse filter. Record item IDs, acquisition times,
57asset checksums where available, scale/offset and the QA mask rule.
59For Planetary Computer pass `modifier=planetary_computer.sign_inplace` to
60`Client.open`. `ItemSearch` itself is not iterable; use `search.items()`.
61The SDK's SAS token service is `GET /api/sas/v1/token/{account}/{container}`;
62it returns `token` and `msft:expiry`. SDK signing appends the expiring SAS query to
63Azure asset URLs. Do not log signed URLs or treat them as permanent identifiers.
64Public metadata access was tested without a subscription key; access policies and
65limits can differ for protected assets.
67Sources: [CDSE STAC](https://documentation.dataspace.copernicus.eu/APIs/STAC.html),
68[Earth Search](https://element84.com/earth-search/),
69[PySTAC Client](https://pystac-client.readthedocs.io/en/latest/api.html),
70[Planetary Computer SDK](https://github.com/microsoft/planetary-computer-sdk-for-python/blob/main/planetary_computer/sas.py).

STAC search

Catalog rootContract
https://stac.dataspace.copernicus.eu/v1CDSE public STAC discovery; inspect collection/queryables and asset access requirements
https://earth-search.aws.element84.com/v1Element 84 Earth Search; Sentinel asset keys use names such as red, nir, scl
https://planetarycomputer.microsoft.com/api/stac/v1Microsoft Planetary Computer; Sentinel keys include B04, B08, SCL; sign protected Azure assets

Each supports Item Search under /search and returns GeoJSON FeatureCollection with features and pagination links. Follow rel=next including its method/body; do not construct page numbers. GeoJSON bbox is west,south,east,north in degrees. Collection IDs and asset keys are provider-specific even for the same mission.

from pystac_client import Client

catalog = Client.open('https://earth-search.aws.element84.com/v1')
search = catalog.search(collections=['sentinel-2-l2a'],
                        bbox=[-122.5, 37.7, -122.3, 37.9],
                        datetime='2023-06-01/2023-06-30',
                        query={'eo:cloud_cover': {'lt': 20}},
                        limit=2, max_items=5)
items = list(search.items())
if not items:
    raise ValueError('No matching items')
asset_metadata = {k: a.to_dict() for k, a in items[0].assets.items()}

items() is an iterator that fetches further pages; item_collection() materializes the bounded result. limit is per-page, max_items is the client total. Scene cloud percentage is only a coarse filter. Record item IDs, acquisition times, asset checksums where available, scale/offset and the QA mask rule.

For Planetary Computer pass modifier=planetary_computer.sign_inplace to Client.open. ItemSearch itself is not iterable; use search.items(). The SDK's SAS token service is GET /api/sas/v1/token/{account}/{container}; it returns token and msft:expiry. SDK signing appends the expiring SAS query to Azure asset URLs. Do not log signed URLs or treat them as permanent identifiers. Public metadata access was tested without a subscription key; access policies and limits can differ for protected assets.

Sources: CDSE STAC, Earth Search, PySTAC Client, Planetary Computer SDK.

Raw lines 26 to 71
72## ERA5 through CDS
74Configure CDS using its current personal-access-token setup and accept the chosen
75dataset terms. The URL is `https://cds.climate.copernicus.eu/api`;
76the old UID:key credential format and `/api/v2` configuration are not the current recipe.
77Use the dataset download form's generated request for the exact variables/product.
78This illustrative request creates a remote retrieval job:
80```python
81import cdsapi
82client = cdsapi.Client()
83client.retrieve('reanalysis-era5-single-levels', {
84 'product_type': ['reanalysis'], 'variable': ['2m_temperature'],
85 'year': ['2023'], 'month': ['01'], 'day': ['01'], 'time': ['12:00'],
86 'area': [37.9, -122.5, 37.7, -122.3], # north, west, south, east
87 'data_format': 'netcdf', 'download_format': 'unarchived',
88}, 'era5_temp.nc')
89```
91`retrieve` handles asynchronous processing and download, not pagination. Inspect
92actual NetCDF dimensions (`valid_time` versus `time`) and units before aggregation.
93[CDS setup](https://cds.climate.copernicus.eu/how-to-api) recommends current cdsapi;
94credentialed retrieval was not run.

ERA5 through CDS

Configure CDS using its current personal-access-token setup and accept the chosen dataset terms. The URL is https://cds.climate.copernicus.eu/api; the old UID:key credential format and /api/v2 configuration are not the current recipe. Use the dataset download form's generated request for the exact variables/product. This illustrative request creates a remote retrieval job:

import cdsapi
client = cdsapi.Client()
client.retrieve('reanalysis-era5-single-levels', {
    'product_type': ['reanalysis'], 'variable': ['2m_temperature'],
    'year': ['2023'], 'month': ['01'], 'day': ['01'], 'time': ['12:00'],
    'area': [37.9, -122.5, 37.7, -122.3],  # north, west, south, east
    'data_format': 'netcdf', 'download_format': 'unarchived',
}, 'era5_temp.nc')

retrieve handles asynchronous processing and download, not pagination. Inspect actual NetCDF dimensions (valid_time versus time) and units before aggregation. CDS setup recommends current cdsapi; credentialed retrieval was not run.

Raw lines 72 to 95
96## OpenStreetMap, Overpass and Nominatim
98OSMnx 2.1.1 uses `ox.features_from_place(place, tags={'building': True})`,
99`ox.graph_from_place(place, network_type='drive')` and `ox.geocode_to_gdf(place)`.
100These call external services. Cache permitted results, bound areas and obey service
101policies. The public Nominatim service requires a meaningful identifying user-agent
102and at most one request per second; it is not a bulk or autocomplete endpoint.
104```python
105import requests
106query = '[out:json][timeout:25];way["highway"](37.700,-122.401,37.701,-122.400);out geom;'
107response = requests.post('https://overpass-api.de/api/interpreter',
108 data={'data': query}, timeout=40)
109response.raise_for_status()
110data = response.json()
111if data.get('remark'):
112 raise RuntimeError(data['remark']) # A timeout/error can accompany HTTP 200.
113elements = data['elements']
114```
116Overpass bbox is south,west,north,east. It has no generic page parameter; subdivide
117large AOIs and reconcile OSM type/ID duplicates. This query is an illustrative public
118request, not executed in this refresh. See [OSMnx](https://osmnx.readthedocs.io/en/stable/user-reference.html),
119[Overpass](https://wiki.openstreetmap.org/wiki/Overpass_API),
120[Nominatim policy](https://operations.osmfoundation.org/policies/nominatim/).

OpenStreetMap, Overpass and Nominatim

OSMnx 2.1.1 uses ox.features_from_place(place, tags={'building': True}), ox.graph_from_place(place, network_type='drive') and ox.geocode_to_gdf(place). These call external services. Cache permitted results, bound areas and obey service policies. The public Nominatim service requires a meaningful identifying user-agent and at most one request per second; it is not a bulk or autocomplete endpoint.

import requests
query = '[out:json][timeout:25];way["highway"](37.700,-122.401,37.701,-122.400);out geom;'
response = requests.post('https://overpass-api.de/api/interpreter',
                         data={'data': query}, timeout=40)
response.raise_for_status()
data = response.json()
if data.get('remark'):
    raise RuntimeError(data['remark'])  # A timeout/error can accompany HTTP 200.
elements = data['elements']

Overpass bbox is south,west,north,east. It has no generic page parameter; subdivide large AOIs and reconcile OSM type/ID duplicates. This query is an illustrative public request, not executed in this refresh. See OSMnx, Overpass, Nominatim policy.

Raw lines 96 to 121
122## Geocoding and current weather
124These are credentialed illustrative request contracts, not live test results.
125Read tokens from an environment variable or credential store; never embed them in a
126notebook, output URL or exception log. Use request timeouts and HTTP checks, then
127validate the provider's response status before selecting a location.
129| API | Method/path and required parameters | Response/limits |
130|---|---|---|
131| Google Geocoding v3 | GET `https://maps.googleapis.com/maps/api/geocode/json`; `address`, `key` | JSON `status` must be `OK`, nonempty `results`; `geometry.location` is `{lat,lng}`. `ZERO_RESULTS` is distinct from denial/quota errors. No pagination. |
132| Mapbox Geocoding v6 | GET `https://api.mapbox.com/search/geocode/v6/forward`; `q`, `access_token`; use `autocomplete=false` for a completed query | GeoJSON `features`, coordinates lon/lat. `limit` is 1..10; no page traversal. v6 does not return POIs; use an address/place, not an assumed landmark lookup. Temporary results cannot be stored; request permitted permanent usage explicitly. |
133| OpenWeather current | GET `https://api.openweathermap.org/data/2.5/weather`; `lat`, `lon`, `appid`, optionally `units=metric` | `main.temp`, `dt` (Unix seconds), `timezone` (seconds), `weather`; standard temperature defaults to Kelvin. A current snapshot is not a historical time series. No pagination. |
135Sources: [Google request/response](https://developers.google.com/maps/documentation/geocoding/guides-v3/requests-geocoding),
136[Mapbox v6](https://docs.mapbox.com/api/search/geocoding/),
137[OpenWeather](https://openweathermap.org/api/current).

Geocoding and current weather

These are credentialed illustrative request contracts, not live test results. Read tokens from an environment variable or credential store; never embed them in a notebook, output URL or exception log. Use request timeouts and HTTP checks, then validate the provider's response status before selecting a location.

APIMethod/path and required parametersResponse/limits
Google Geocoding v3GET https://maps.googleapis.com/maps/api/geocode/json; address, keyJSON status must be OK, nonempty results; geometry.location is {lat,lng}. ZERO_RESULTS is distinct from denial/quota errors. No pagination.
Mapbox Geocoding v6GET https://api.mapbox.com/search/geocode/v6/forward; q, access_token; use autocomplete=false for a completed queryGeoJSON features, coordinates lon/lat. limit is 1..10; no page traversal. v6 does not return POIs; use an address/place, not an assumed landmark lookup. Temporary results cannot be stored; request permitted permanent usage explicitly.
OpenWeather currentGET https://api.openweathermap.org/data/2.5/weather; lat, lon, appid, optionally units=metricmain.temp, dt (Unix seconds), timezone (seconds), weather; standard temperature defaults to Kelvin. A current snapshot is not a historical time series. No pagination.

Sources: Google request/response, Mapbox v6, OpenWeather.

Raw lines 122 to 138
139## Raster quality and elevation downloads
141The `elevation` package wraps SRTM acquisition and native GDAL/Make tooling.
142`elevation.clip(bounds=..., output=...)` downloads/crops; `elevation.clean()` cleans
143temporary cache products, not raster voids. Void filling needs a separately chosen
144method and QA. Never call `clean(input, output)` expecting a repaired DEM.
146```python
147import numpy as np
148import rasterio
150def assess_data_quality(path):
151 with rasterio.open(path) as src:
152 data = src.read(masked=True).astype('float64')
153 valid = data.compressed()
154 valid = valid[np.isfinite(valid)]
155 return {'valid_fraction': valid.size / data.size,
156 'range': (float(valid.min()), float(valid.max())) if valid.size else None,
157 'crs': str(src.crs), 'resolution': src.res}
158```
160This checks numeric support, not acquisition quality or product correctness.
161[Elevation source](https://github.com/bopen/elevation) documents its native dependencies.

Raster quality and elevation downloads

The elevation package wraps SRTM acquisition and native GDAL/Make tooling. elevation.clip(bounds=..., output=...) downloads/crops; elevation.clean() cleans temporary cache products, not raster voids. Void filling needs a separately chosen method and QA. Never call clean(input, output) expecting a repaired DEM.

import numpy as np
import rasterio

def assess_data_quality(path):
    with rasterio.open(path) as src:
        data = src.read(masked=True).astype('float64')
        valid = data.compressed()
        valid = valid[np.isfinite(valid)]
        return {'valid_fraction': valid.size / data.size,
                'range': (float(valid.min()), float(valid.max())) if valid.size else None,
                'crs': str(src.crs), 'resolution': src.res}

This checks numeric support, not acquisition quality or product correctness. Elevation source documents its native dependencies.

Raw lines 139 to 161