A unified Python interface to Earth embeddings: image encoders, location encoders, and precomputed geospatial products.
See the codeA shared Python interface for Earth observation images, locations, and embedding products.
Quickstart · Compare 22 models · Hugging Face & resources · Notebooks · Docs · Contribute
emb = get_embedding("prithvi", spatial=spatial, temporal=temporal, output=output)
Choose a place, a time window, and an output. Swap the model name to explore 16 image configurations, 3 location encoders, and 3 precomputed products. The familiar rs-embed geographic API is preserved; Earth Embedding adds location models, direct product access, and multi-model comparison.
git clone https://github.com/GISWLH/earth-embedding.git
cd earth-embedding
python -m pip install -e ".[plot,location]"
# For image/product routes that use Earth Engine:
earthengine authenticate
from earth_embedding import PointBuffer, TemporalSpec, OutputSpec, get_embedding
spatial = PointBuffer(lon=114.41, lat=30.52, buffer_m=640)
temporal = TemporalSpec.range("2021-05-01", "2021-10-31")
output = OutputSpec.grid() # Or OutputSpec.pooled() for a feature vector.
emb = get_embedding("prithvi", spatial=spatial, temporal=temporal, output=output)
# The same geographic interface also works for Esri's location encoder.
gle = get_embedding("esri_gle", spatial=spatial, output=output, grid_step_m=80)
Use Python 3.12+. First use downloads the selected weights. Image routes need
their model dependencies and imagery access; Esri GLE runs
directly in PyTorch without Earth Engine or ArcGIS. Annual products use
TemporalSpec.year(2021); location encoders need no date.

One region, 22 real outputs. Image encoders, location encoders (including Esri GLE), and precomputed products appear together. This is a qualitative gallery: each panel uses its own PCA colors and retains its own spatial support. Equal colors across panels do not indicate equal features or classes. The gallery reuses verified historical Wuhan image/product outputs and adds real location inference. Inputs, provenance, and reproduction. Dates differ across these archived runs; SatVision's historical proxy input and Copernicus's coarse product window are labeled in the figure and provenance.
from earth_embedding import compare_embeddings, plot_embedding_comparison
comparison = compare_embeddings(
["prithvi", "dofa", "remoteclip", "satclip", "geoclip", "esri_gle"],
spatial=spatial,
temporal=temporal,
output=output,
model_options={name: {"grid_step_m": 80}
for name in ("satclip", "geoclip", "esri_gle")},
on_error="record", # Keep successful panels; show each failure explicitly.
)
fig = plot_embedding_comparison(comparison, columns=3)
fig.savefig("comparison.png", dpi=180, bbox_inches="tight")
Set models=None to select the entire 22-entry catalog. Give annual
products a year through model_options; the complete example
does this for you and saves the figure, feature arrays, and a run report:
# All catalog models, one PNG. Requires their runtimes, weights and data access.
python examples/compare_models.py --models all --out outputs/comparison
# A smaller CPU run with no imagery download or Earth Engine authentication.
python examples/compare_models.py --models satclip geoclip esri_gle --device cpu
Results are available as comparison.embeddings["prithvi"]; failures are
reported in comparison.errors. Models run sequentially and release their
cached runtimes between requests by default. Comparison notebook.

These encoders use longitude and latitude, with no satellite observation
date. Their spatial patterns show learned geographic priors. Adjust the region
and sampling spacing with the same spatial and grid_step_m arguments.
Origin and attribution. Earth Embedding is an independently maintained extension of CyberGIS rs-embed, created by Dingqi Ye and contributors. We retain its Apache-2.0 license and acknowledge its APIs, adapters, and engineering foundation. The upstream paper describes rs-embed; our manuscript and extensions are separate work. See provenance.
Python 3.12+, CPU. Install from this Git repository; no PyPI release is assumed. The small real samples are bundled and SHA-256 verified. No Earth Engine login or private paths are needed.
git clone https://github.com/GISWLH/earth-embedding.git
cd earth-embedding
python -m pip install -e ".[demo,aef]"
from earth_embedding.demo import load_demo, pca_colors, plot_map
data = load_demo("aef")
colors = pca_colors(data.features)
fig = plot_map(data.samples, colors, title="San Francisco Bay Area | AEF 2021 | PCA RGB")
fig.savefig("aef-pca.png", dpi=160)

San Francisco Bay Area and surroundings, 122.6–121.6° W / 37.3–38.3° N, about 88 × 111 km. 5,933 real Google / Google DeepMind AEF 2021 overview cells at 1,280 m support; the checked bundle is 2.1 MB. RGB shows descriptive principal components, not land-cover classes. Sampling and licenses: full tutorial. To repeat official GCS reads use fetch_aef_demo() from earth_embedding.demo; the first map above works offline.
from earth_embedding import get_location_embeddings
from earth_embedding.demo import load_demo, pca_colors, plot_map
data = load_demo("bayarea")
points = data.samples[["center_lon", "center_lat"]].to_numpy()
gle = get_location_embeddings("esri_gle", points, device="cpu", batch_size=128)
fig = plot_map(data.samples, pca_colors(gle.data), title="San Francisco Bay Area | Esri GLE | PCA RGB")
fig.savefig("esri-gle-pca.png", dpi=160)

5,933 San Francisco Bay Area locations; official ~3.7 MB weights download once and run directly in PyTorch. No ArcGIS/ArcPy. GLE has no observation year; colors show a geographic prior, not a dated land-cover map.
from earth_embedding.demo import classify_demo, plot_classification
result = classify_demo()
print({k: result["metrics"][k] for k in ("oa", "macro_f1", "balanced_accuracy")})
fig = plot_classification(result)
fig.savefig("bayarea-classification.png", dpi=160)

| OA | Macro-F1 | Balanced Accuracy | Train / test / buffer / excluded |
|---|---|---|---|
| 91.39% | 87.49% | 85.65% | 3383 / 2173 / 375 / 2 |
Newly computed regional software demo, not current global paper results. Four classes: built, vegetation, cropland, water. South trains, north tests, with a ≥5.5 km geographic gap; two bare cells are excluded. There are only 9 cropland training cells, so class imbalance limits this fixed holdout. Scaler and Logistic Regression fit training rows only (seed 42). Gray cells are unscored. Class counts, source/license, split, metrics and limits.
01 · AEF · 02 · Esri GLE · 03 · Classification · 04 · Export / reuse
Notebooks 01–04 contain real execution outputs and maps. Execution receipt · Complete tutorial · Editable Excalidraw. Notebook 04 exports and safely reloads batches; it does not rank products with unequal spatial support. 05 · Compare models includes executed three-model CPU comparison outputs and an optional full-catalog cell; see its execution receipt.
Remote sensing models expose different inputs, preprocessing rules, spatial supports, and access methods. Earth Embedding makes those differences explicit while providing reusable interfaces for obtaining features. Start with satellite imagery, a list of locations, or an existing embedding product; receive embedding values and provenance metadata for your own analysis.
[longitude, latitude] interface. Esri's lightweight weights run directly in PyTorch.The earth_embedding import and earth-embedding command are the new entry points. Existing rs_embed imports and rs-embed commands remain available for compatibility.
Use Python 3.12 or later. Install this project from its Git repository; the instructions below do not assume an earth-embedding release on PyPI.
python -m pip install "earth-embedding @ git+https://github.com/GISWLH/earth-embedding.git"
For optional features or development:
git clone https://github.com/GISWLH/earth-embedding.git
cd earth-embedding
python -m pip install -e ".[location,aef]"
| Extra / environment | When you need it |
|---|---|
| Base installation | Core APIs and the dependencies declared in pyproject.toml |
.[location] | GeoCLIP's official Python package; SatCLIP and Esri GLE use bundled runtimes |
.[aef] | Rasterio and PyArrow for direct AlphaEarth COG sampling and Parquet indexes |
.[benchmark] | Scikit-learn for the spatial-holdout evaluation example |
.[terratorch] | TerraMind's TerraTorch runtime; Prithvi uses a bundled runtime |
.[dev,full,location,aef,benchmark] | Development checks and these optional integrations |
PyTorch must match your hardware. Model weights may download on first use; image encoders can require substantial memory. Neither the catalog command nor the describe command performs model inference:
earth-embedding models --json
earth-embedding describe satclip
For Earth Engine imagery/product routes, authorize your account with earthengine authenticate and configure an eligible Cloud project (EE_PROJECT when required). The direct location and GCS examples below do not initialize Earth Engine.
No image acquisition or date selection is needed. Inputs are WGS84 degrees in longitude, latitude order; even a single point is a two-dimensional array.
from earth_embedding import get_location_embeddings
locations = [[-122.42, 37.77], [139.76, 35.68], [-0.12, 51.51]]
result = get_location_embeddings("satclip", locations, device="cpu")
print(result.data.shape) # (3, 256)
print(result.meta)
# Esri's official ~3.7 MB model package downloads and caches on first use.
esri = get_location_embeddings("esri_gle", locations, device="cpu")
print(esri.data.shape) # (3, 256)
# Install .[location] first; GeoCLIP returns 512 features per location.
geoclip = get_location_embeddings("geoclip", locations, device="cpu")
Esri GLE uses its official pretrained weights with direct PyTorch inference; ArcGIS and ArcPy are not required. Downloads are pinned by SHA-256, and a local .dlpk or satclip.pth can be supplied for offline use. Esri's model terms apply separately. See Esri GLE setup and the validation report.
Location embeddings describe a learned geographic prior. Querying the same location with a different year does not produce an observation of land-cover change.
Use the geographic API to fetch the configured imagery and run an image encoder. This example needs authorized Earth Engine access, model weights, and the model's runtime dependencies.
from earth_embedding import PointBuffer, TemporalSpec, OutputSpec, get_embedding
result = get_embedding(
"remoteclip",
spatial=PointBuffer(lon=-122.42, lat=37.77, buffer_m=320),
temporal=TemporalSpec.range("2021-05-01", "2021-10-31"),
output=OutputSpec.pooled(),
device="cpu",
)
print(result.data.shape)
print(result.meta)
Already have imagery? get_image_embedding(model, pixels, spatial=..., temporal=..., sensor=..., device=...) accepts local CHW or TCHW arrays without fetching imagery. Supply the adapter's exact band order, sensor units, and time contract; an arbitrary RGB array is not valid input for every model. See API reference and model documentation.
Download the official footprint index once, then select a year and area. The index is global; check its size before downloading.
curl -L -o aef_index.parquet https://storage.googleapis.com/alphaearth_foundations/satellite_embedding/v1/annual/aef_index.parquet
from earth_embedding import BBox, find_aef_tiles, sample_aef
tiles = find_aef_tiles(
"aef_index.parquet",
spatial=BBox(-122.43, 37.76, -122.41, 37.78),
year=2021,
)
result = sample_aef([[-122.42, 37.77]], tiles=tiles)
print(result.data.shape) # (1, 64)
print(result.meta["source_for_point"])
The sampler performs CRS transformation, byte-range COG reads, signed-int8 dequantization, and nodata handling. Keep candidate tiles within one year. Missing coverage raises by default; strict=False preserves those rows as NaN. Network errors remain explicit errors.
Google's official GCS guide documents provider-paid access as of July 2026 and annual coverage from 2017 through 2025. See data access for the CSV/GeoParquet/GeoPackage indexes, object manifest, Earth Engine alternative, and required attribution. AEF model weights are not distributed by this project.
Classification follows the delivered object and evaluated input contract. Architecture, resolution, learning signal, and evaluation eligibility are separate properties. An adapter's presence is an integration statement; it is not a guarantee of current data access, checkpoint availability, or successful execution on your machine.
| Model ID / guide | Class | Current adapter input | Upstream source | Weights or product |
|---|---|---|---|---|
remoteclip | A · image | Sentinel-2 RGB | Source | Hugging Face model |
satmae | A · image | Sentinel-2 RGB | Source | Hugging Face model |
satmaepp | A · image | Sentinel-2 RGB | Source | Hugging Face model |
satmaepp_s2_10b | A · image | Sentinel-2 10 bands | Source | Hugging Face model |
scalemae | A · image | Sentinel-2 RGB + ground resolution | Source | Hugging Face model |
wildsat | A · image | Sentinel-2 RGB | Source | official download |
prithvi | A · image | Sentinel-2 6 bands + time/location | Source | Hugging Face model |
terrafm | A · image | Sentinel-2 12 bands or Sentinel-1 VV/VH | Source | Hugging Face model |
terramind | A · image | Sentinel-2 12 bands | Source | Hugging Face model |
dofa | A · image | Multispectral imagery + wavelengths | Source | Hugging Face model |
fomo | A · image | Sentinel-2 12 bands | Source | official download |
thor | A · image | Sentinel-2 10 bands | Source | Hugging Face model |
satvision | A · image | 14 calibrated TOA channels | Source | Hugging Face model |
anysat | A · image | Sentinel-2 10-band time series | Source | Hugging Face model |
galileo | A · image | Sentinel-2 10-band time series | Source | Hugging Face model |
agrifm | A · image | Sentinel-2 10-band time series | Source | official download |
satclip | B · location | Longitude/latitude only | Source | Hugging Face model |
geoclip | B · location | Longitude/latitude only | Source | official download |
esri_gle | B · location | Longitude/latitude only | Source | official download |
tessera | C · product | Published GeoTessera embedding tiles | Source | official product |
gse | C · product | Annual Google Satellite Embedding product | Source | official product |
copernicus | C · product | 0.25-degree embedding product | Source | Hugging Face dataset |
Checkpoint packaging, default variants and model terms. These are upstream resources, not weights republished by this project.
The taxonomy also includes C2 sampled embedding collections. No C2 adapter is claimed in this 22-entry catalog. Model-lineage names alone do not determine a class: published weights and a precomputed product can be separate releases.
| Stage | Interface | What to check |
|---|---|---|
| Discover | earth-embedding models --json, describe MODEL | Input requirements, supported output, optional dependencies |
| Inspect imagery | inspect_provider_patch(...) | Coverage, bands, pixel values, shape, acquisition window |
| Encode images | get_embedding(...), get_image_embedding(...) | Provider or local input; correct preprocessing |
| Encode locations | get_location_embeddings(...) | WGS84 [lon, lat], model/checkpoint, device |
| Read AEF data | find_aef_tiles(...), sample_aef(...) | Year, coverage, CRS, nodata, source URL |
| Scale extraction | get_embeddings_batch(...), export_batch(...) | Consistent configuration, cache, metadata, error handling |
| Analyze | Your downstream estimator and spatial splits | Task labels, leakage, matched support, uncertainty |
Results expose .data and .meta. Persist both: a feature matrix without its model revision, coordinates, dates, and preprocessing choices is difficult to reproduce. Feature dimensions and spatial grid support vary across models; the library does not make vectors from different encoders interchangeable.
These are downstream workflows you can implement with the features; they are not universal pretrained prediction heads supplied by every adapter.
The evaluation example consumes saved features without fetching imagery. Supply a metadata CSV with sample_id,target,split,spatial_group, and one NPZ per model containing X and sample_id. Use train / test splits whose spatial groups are disjoint.
python -m pip install -e ".[benchmark]"
python examples/evaluate_embeddings.py --metadata metadata.csv --features satclip=satclip.npz geoclip=geoclip.npz --task classification --out evaluation.json
The script aligns all models to the same finite cohort, fits scaling and linear estimators on training rows only, and records cohort/input hashes. For regression use --task regression. Define a meaningful spatial split before running it; this example does not reproduce final manuscript scores.
Our manuscript work motivates three additions to the software: an explicit release taxonomy, comparable input/output contracts, and evaluation provenance. The frozen manuscript benchmark contains 20 systems: A16 + B1 (SatCLIP) + C3. The software catalog now has 22 adapters because GeoCLIP and Esri GLE are additional integrations; this does not expand the paper's evaluated set automatically.
The revised main evaluation uses a globally distributed 640 m design. Wuhan 567/2,173-tile materials provide local and historical diagnostics and retain their own scope. Evaluation covers classification, fraction regression, and supported dense-output tasks; matched spatial support and spatial holdouts matter more than a single aggregate ranking. SatVision and Copernicus-Embed retain their taxonomy classes even where their spatial support makes them ineligible for a controlled comparison.
See research scope and evidence boundaries. The manuscript is under development; this repository does not claim an accepted RSE paper, a final leaderboard, or that a smoke test establishes scientific superiority.
The validation report separates unit tests, real model inference, and live data access. The Bay Area integration receipt verifies the regional AEF sample and all three README examples. Notebook execution and held-out classification metrics are recorded separately.
Data providers can require authentication, quotas, or terms acceptance. Some models need specialized packages or large checkpoints. Esri GLE's weights retain Esri's model terms. A location encoder has no temporal observations. Coarse products cannot be made equivalent to a 10 m field by resampling. Read limitations before designing a comparison.
The hero and logo are editable hand-drawn Excalidraw assets. See the artwork source and rendering instructions.
Useful contributions include adapters with explicit input contracts, reproducible failure reports, small executable examples, provider-access fixes, and improvements to English, Chinese, or Japanese documentation. Start with CONTRIBUTING.md and open an issue with a model's official source, license, checkpoint, and a concrete use case.
Priorities include broader environment validation, reproducible user-supplied imagery examples, more precomputed-product access routes, and carefully documented C2 integrations. These are development directions, not promises of currently implemented functionality.
For this extension, cite the software repository and the commit or release you used; machine-readable metadata is in CITATION.cff. Cite the original rs-embed paper when using its framework, and the original model/data publications for the artifacts used in your analysis. Our research manuscript will receive its own citation when a public bibliographic record is available.
@article{ye2026modelplacetimeremote,
title={Any Model, Any Place, Any Time: Get Remote Sensing Foundation Model Embeddings On Demand},
author={Ye, Dingqi and Kiv, Daniel and Hu, Wei and Shi, Jimeng and Wang, Shaowen},
year={2026},
eprint={2602.23678},
archivePrefix={arXiv},
url={https://arxiv.org/abs/2602.23678}
}
We thank the rs-embed contributors, model authors, Google Earth Engine, Google and Google DeepMind, TorchGeo, GeoTessera, TerraTorch, rshf, Microsoft SatCLIP, GeoCLIP, Esri, and the wider Earth observation community. Integration does not imply endorsement.
Library code is distributed under Apache-2.0, with inherited attribution retained in NOTICE. Vendored components, model weights, data, and fonts retain their respective licenses. AlphaEarth data is CC-BY-4.0; Esri's software/model terms apply separately. See provenance and licensing.
A unified Python interface to Earth embeddings: image encoders, location encoders, and precomputed geospatial products.
See the codeA shared Python interface for Earth observation images, locations, and embedding products.
Quickstart · Compare 22 models · Hugging Face & resources · Notebooks · Docs · Contribute
emb = get_embedding("prithvi", spatial=spatial, temporal=temporal, output=output)
Choose a place, a time window, and an output. Swap the model name to explore 16 image configurations, 3 location encoders, and 3 precomputed products. The familiar rs-embed geographic API is preserved; Earth Embedding adds location models, direct product access, and multi-model comparison.
git clone https://github.com/GISWLH/earth-embedding.git
cd earth-embedding
python -m pip install -e ".[plot,location]"
# For image/product routes that use Earth Engine:
earthengine authenticate
from earth_embedding import PointBuffer, TemporalSpec, OutputSpec, get_embedding
spatial = PointBuffer(lon=114.41, lat=30.52, buffer_m=640)
temporal = TemporalSpec.range("2021-05-01", "2021-10-31")
output = OutputSpec.grid() # Or OutputSpec.pooled() for a feature vector.
emb = get_embedding("prithvi", spatial=spatial, temporal=temporal, output=output)
# The same geographic interface also works for Esri's location encoder.
gle = get_embedding("esri_gle", spatial=spatial, output=output, grid_step_m=80)
Use Python 3.12+. First use downloads the selected weights. Image routes need
their model dependencies and imagery access; Esri GLE runs
directly in PyTorch without Earth Engine or ArcGIS. Annual products use
TemporalSpec.year(2021); location encoders need no date.

One region, 22 real outputs. Image encoders, location encoders (including Esri GLE), and precomputed products appear together. This is a qualitative gallery: each panel uses its own PCA colors and retains its own spatial support. Equal colors across panels do not indicate equal features or classes. The gallery reuses verified historical Wuhan image/product outputs and adds real location inference. Inputs, provenance, and reproduction. Dates differ across these archived runs; SatVision's historical proxy input and Copernicus's coarse product window are labeled in the figure and provenance.
from earth_embedding import compare_embeddings, plot_embedding_comparison
comparison = compare_embeddings(
["prithvi", "dofa", "remoteclip", "satclip", "geoclip", "esri_gle"],
spatial=spatial,
temporal=temporal,
output=output,
model_options={name: {"grid_step_m": 80}
for name in ("satclip", "geoclip", "esri_gle")},
on_error="record", # Keep successful panels; show each failure explicitly.
)
fig = plot_embedding_comparison(comparison, columns=3)
fig.savefig("comparison.png", dpi=180, bbox_inches="tight")
Set models=None to select the entire 22-entry catalog. Give annual
products a year through model_options; the complete example
does this for you and saves the figure, feature arrays, and a run report:
# All catalog models, one PNG. Requires their runtimes, weights and data access.
python examples/compare_models.py --models all --out outputs/comparison
# A smaller CPU run with no imagery download or Earth Engine authentication.
python examples/compare_models.py --models satclip geoclip esri_gle --device cpu
Results are available as comparison.embeddings["prithvi"]; failures are
reported in comparison.errors. Models run sequentially and release their
cached runtimes between requests by default. Comparison notebook.

These encoders use longitude and latitude, with no satellite observation
date. Their spatial patterns show learned geographic priors. Adjust the region
and sampling spacing with the same spatial and grid_step_m arguments.
Origin and attribution. Earth Embedding is an independently maintained extension of CyberGIS rs-embed, created by Dingqi Ye and contributors. We retain its Apache-2.0 license and acknowledge its APIs, adapters, and engineering foundation. The upstream paper describes rs-embed; our manuscript and extensions are separate work. See provenance.
Python 3.12+, CPU. Install from this Git repository; no PyPI release is assumed. The small real samples are bundled and SHA-256 verified. No Earth Engine login or private paths are needed.
git clone https://github.com/GISWLH/earth-embedding.git
cd earth-embedding
python -m pip install -e ".[demo,aef]"
from earth_embedding.demo import load_demo, pca_colors, plot_map
data = load_demo("aef")
colors = pca_colors(data.features)
fig = plot_map(data.samples, colors, title="San Francisco Bay Area | AEF 2021 | PCA RGB")
fig.savefig("aef-pca.png", dpi=160)

San Francisco Bay Area and surroundings, 122.6–121.6° W / 37.3–38.3° N, about 88 × 111 km. 5,933 real Google / Google DeepMind AEF 2021 overview cells at 1,280 m support; the checked bundle is 2.1 MB. RGB shows descriptive principal components, not land-cover classes. Sampling and licenses: full tutorial. To repeat official GCS reads use fetch_aef_demo() from earth_embedding.demo; the first map above works offline.
from earth_embedding import get_location_embeddings
from earth_embedding.demo import load_demo, pca_colors, plot_map
data = load_demo("bayarea")
points = data.samples[["center_lon", "center_lat"]].to_numpy()
gle = get_location_embeddings("esri_gle", points, device="cpu", batch_size=128)
fig = plot_map(data.samples, pca_colors(gle.data), title="San Francisco Bay Area | Esri GLE | PCA RGB")
fig.savefig("esri-gle-pca.png", dpi=160)

5,933 San Francisco Bay Area locations; official ~3.7 MB weights download once and run directly in PyTorch. No ArcGIS/ArcPy. GLE has no observation year; colors show a geographic prior, not a dated land-cover map.
from earth_embedding.demo import classify_demo, plot_classification
result = classify_demo()
print({k: result["metrics"][k] for k in ("oa", "macro_f1", "balanced_accuracy")})
fig = plot_classification(result)
fig.savefig("bayarea-classification.png", dpi=160)

| OA | Macro-F1 | Balanced Accuracy | Train / test / buffer / excluded |
|---|---|---|---|
| 91.39% | 87.49% | 85.65% | 3383 / 2173 / 375 / 2 |
Newly computed regional software demo, not current global paper results. Four classes: built, vegetation, cropland, water. South trains, north tests, with a ≥5.5 km geographic gap; two bare cells are excluded. There are only 9 cropland training cells, so class imbalance limits this fixed holdout. Scaler and Logistic Regression fit training rows only (seed 42). Gray cells are unscored. Class counts, source/license, split, metrics and limits.
01 · AEF · 02 · Esri GLE · 03 · Classification · 04 · Export / reuse
Notebooks 01–04 contain real execution outputs and maps. Execution receipt · Complete tutorial · Editable Excalidraw. Notebook 04 exports and safely reloads batches; it does not rank products with unequal spatial support. 05 · Compare models includes executed three-model CPU comparison outputs and an optional full-catalog cell; see its execution receipt.
Remote sensing models expose different inputs, preprocessing rules, spatial supports, and access methods. Earth Embedding makes those differences explicit while providing reusable interfaces for obtaining features. Start with satellite imagery, a list of locations, or an existing embedding product; receive embedding values and provenance metadata for your own analysis.
[longitude, latitude] interface. Esri's lightweight weights run directly in PyTorch.The earth_embedding import and earth-embedding command are the new entry points. Existing rs_embed imports and rs-embed commands remain available for compatibility.
Use Python 3.12 or later. Install this project from its Git repository; the instructions below do not assume an earth-embedding release on PyPI.
python -m pip install "earth-embedding @ git+https://github.com/GISWLH/earth-embedding.git"
For optional features or development:
git clone https://github.com/GISWLH/earth-embedding.git
cd earth-embedding
python -m pip install -e ".[location,aef]"
| Extra / environment | When you need it |
|---|---|
| Base installation | Core APIs and the dependencies declared in pyproject.toml |
.[location] | GeoCLIP's official Python package; SatCLIP and Esri GLE use bundled runtimes |
.[aef] | Rasterio and PyArrow for direct AlphaEarth COG sampling and Parquet indexes |
.[benchmark] | Scikit-learn for the spatial-holdout evaluation example |
.[terratorch] | TerraMind's TerraTorch runtime; Prithvi uses a bundled runtime |
.[dev,full,location,aef,benchmark] | Development checks and these optional integrations |
PyTorch must match your hardware. Model weights may download on first use; image encoders can require substantial memory. Neither the catalog command nor the describe command performs model inference:
earth-embedding models --json
earth-embedding describe satclip
For Earth Engine imagery/product routes, authorize your account with earthengine authenticate and configure an eligible Cloud project (EE_PROJECT when required). The direct location and GCS examples below do not initialize Earth Engine.
No image acquisition or date selection is needed. Inputs are WGS84 degrees in longitude, latitude order; even a single point is a two-dimensional array.
from earth_embedding import get_location_embeddings
locations = [[-122.42, 37.77], [139.76, 35.68], [-0.12, 51.51]]
result = get_location_embeddings("satclip", locations, device="cpu")
print(result.data.shape) # (3, 256)
print(result.meta)
# Esri's official ~3.7 MB model package downloads and caches on first use.
esri = get_location_embeddings("esri_gle", locations, device="cpu")
print(esri.data.shape) # (3, 256)
# Install .[location] first; GeoCLIP returns 512 features per location.
geoclip = get_location_embeddings("geoclip", locations, device="cpu")
Esri GLE uses its official pretrained weights with direct PyTorch inference; ArcGIS and ArcPy are not required. Downloads are pinned by SHA-256, and a local .dlpk or satclip.pth can be supplied for offline use. Esri's model terms apply separately. See Esri GLE setup and the validation report.
Location embeddings describe a learned geographic prior. Querying the same location with a different year does not produce an observation of land-cover change.
Use the geographic API to fetch the configured imagery and run an image encoder. This example needs authorized Earth Engine access, model weights, and the model's runtime dependencies.
from earth_embedding import PointBuffer, TemporalSpec, OutputSpec, get_embedding
result = get_embedding(
"remoteclip",
spatial=PointBuffer(lon=-122.42, lat=37.77, buffer_m=320),
temporal=TemporalSpec.range("2021-05-01", "2021-10-31"),
output=OutputSpec.pooled(),
device="cpu",
)
print(result.data.shape)
print(result.meta)
Already have imagery? get_image_embedding(model, pixels, spatial=..., temporal=..., sensor=..., device=...) accepts local CHW or TCHW arrays without fetching imagery. Supply the adapter's exact band order, sensor units, and time contract; an arbitrary RGB array is not valid input for every model. See API reference and model documentation.
Download the official footprint index once, then select a year and area. The index is global; check its size before downloading.
curl -L -o aef_index.parquet https://storage.googleapis.com/alphaearth_foundations/satellite_embedding/v1/annual/aef_index.parquet
from earth_embedding import BBox, find_aef_tiles, sample_aef
tiles = find_aef_tiles(
"aef_index.parquet",
spatial=BBox(-122.43, 37.76, -122.41, 37.78),
year=2021,
)
result = sample_aef([[-122.42, 37.77]], tiles=tiles)
print(result.data.shape) # (1, 64)
print(result.meta["source_for_point"])
The sampler performs CRS transformation, byte-range COG reads, signed-int8 dequantization, and nodata handling. Keep candidate tiles within one year. Missing coverage raises by default; strict=False preserves those rows as NaN. Network errors remain explicit errors.
Google's official GCS guide documents provider-paid access as of July 2026 and annual coverage from 2017 through 2025. See data access for the CSV/GeoParquet/GeoPackage indexes, object manifest, Earth Engine alternative, and required attribution. AEF model weights are not distributed by this project.
Classification follows the delivered object and evaluated input contract. Architecture, resolution, learning signal, and evaluation eligibility are separate properties. An adapter's presence is an integration statement; it is not a guarantee of current data access, checkpoint availability, or successful execution on your machine.
| Model ID / guide | Class | Current adapter input | Upstream source | Weights or product |
|---|---|---|---|---|
remoteclip | A · image | Sentinel-2 RGB | Source | Hugging Face model |
satmae | A · image | Sentinel-2 RGB | Source | Hugging Face model |
satmaepp | A · image | Sentinel-2 RGB | Source | Hugging Face model |
satmaepp_s2_10b | A · image | Sentinel-2 10 bands | Source | Hugging Face model |
scalemae | A · image | Sentinel-2 RGB + ground resolution | Source | Hugging Face model |
wildsat | A · image | Sentinel-2 RGB | Source | official download |
prithvi | A · image | Sentinel-2 6 bands + time/location | Source | Hugging Face model |
terrafm | A · image | Sentinel-2 12 bands or Sentinel-1 VV/VH | Source | Hugging Face model |
terramind | A · image | Sentinel-2 12 bands | Source | Hugging Face model |
dofa | A · image | Multispectral imagery + wavelengths | Source | Hugging Face model |
fomo | A · image | Sentinel-2 12 bands | Source | official download |
thor | A · image | Sentinel-2 10 bands | Source | Hugging Face model |
satvision | A · image | 14 calibrated TOA channels | Source | Hugging Face model |
anysat | A · image | Sentinel-2 10-band time series | Source | Hugging Face model |
galileo | A · image | Sentinel-2 10-band time series | Source | Hugging Face model |
agrifm | A · image | Sentinel-2 10-band time series | Source | official download |
satclip | B · location | Longitude/latitude only | Source | Hugging Face model |
geoclip | B · location | Longitude/latitude only | Source | official download |
esri_gle | B · location | Longitude/latitude only | Source | official download |
tessera | C · product | Published GeoTessera embedding tiles | Source | official product |
gse | C · product | Annual Google Satellite Embedding product | Source | official product |
copernicus | C · product | 0.25-degree embedding product | Source | Hugging Face dataset |
Checkpoint packaging, default variants and model terms. These are upstream resources, not weights republished by this project.
The taxonomy also includes C2 sampled embedding collections. No C2 adapter is claimed in this 22-entry catalog. Model-lineage names alone do not determine a class: published weights and a precomputed product can be separate releases.
| Stage | Interface | What to check |
|---|---|---|
| Discover | earth-embedding models --json, describe MODEL | Input requirements, supported output, optional dependencies |
| Inspect imagery | inspect_provider_patch(...) | Coverage, bands, pixel values, shape, acquisition window |
| Encode images | get_embedding(...), get_image_embedding(...) | Provider or local input; correct preprocessing |
| Encode locations | get_location_embeddings(...) | WGS84 [lon, lat], model/checkpoint, device |
| Read AEF data | find_aef_tiles(...), sample_aef(...) | Year, coverage, CRS, nodata, source URL |
| Scale extraction | get_embeddings_batch(...), export_batch(...) | Consistent configuration, cache, metadata, error handling |
| Analyze | Your downstream estimator and spatial splits | Task labels, leakage, matched support, uncertainty |
Results expose .data and .meta. Persist both: a feature matrix without its model revision, coordinates, dates, and preprocessing choices is difficult to reproduce. Feature dimensions and spatial grid support vary across models; the library does not make vectors from different encoders interchangeable.
These are downstream workflows you can implement with the features; they are not universal pretrained prediction heads supplied by every adapter.
The evaluation example consumes saved features without fetching imagery. Supply a metadata CSV with sample_id,target,split,spatial_group, and one NPZ per model containing X and sample_id. Use train / test splits whose spatial groups are disjoint.
python -m pip install -e ".[benchmark]"
python examples/evaluate_embeddings.py --metadata metadata.csv --features satclip=satclip.npz geoclip=geoclip.npz --task classification --out evaluation.json
The script aligns all models to the same finite cohort, fits scaling and linear estimators on training rows only, and records cohort/input hashes. For regression use --task regression. Define a meaningful spatial split before running it; this example does not reproduce final manuscript scores.
Our manuscript work motivates three additions to the software: an explicit release taxonomy, comparable input/output contracts, and evaluation provenance. The frozen manuscript benchmark contains 20 systems: A16 + B1 (SatCLIP) + C3. The software catalog now has 22 adapters because GeoCLIP and Esri GLE are additional integrations; this does not expand the paper's evaluated set automatically.
The revised main evaluation uses a globally distributed 640 m design. Wuhan 567/2,173-tile materials provide local and historical diagnostics and retain their own scope. Evaluation covers classification, fraction regression, and supported dense-output tasks; matched spatial support and spatial holdouts matter more than a single aggregate ranking. SatVision and Copernicus-Embed retain their taxonomy classes even where their spatial support makes them ineligible for a controlled comparison.
See research scope and evidence boundaries. The manuscript is under development; this repository does not claim an accepted RSE paper, a final leaderboard, or that a smoke test establishes scientific superiority.
The validation report separates unit tests, real model inference, and live data access. The Bay Area integration receipt verifies the regional AEF sample and all three README examples. Notebook execution and held-out classification metrics are recorded separately.
Data providers can require authentication, quotas, or terms acceptance. Some models need specialized packages or large checkpoints. Esri GLE's weights retain Esri's model terms. A location encoder has no temporal observations. Coarse products cannot be made equivalent to a 10 m field by resampling. Read limitations before designing a comparison.
The hero and logo are editable hand-drawn Excalidraw assets. See the artwork source and rendering instructions.
Useful contributions include adapters with explicit input contracts, reproducible failure reports, small executable examples, provider-access fixes, and improvements to English, Chinese, or Japanese documentation. Start with CONTRIBUTING.md and open an issue with a model's official source, license, checkpoint, and a concrete use case.
Priorities include broader environment validation, reproducible user-supplied imagery examples, more precomputed-product access routes, and carefully documented C2 integrations. These are development directions, not promises of currently implemented functionality.
For this extension, cite the software repository and the commit or release you used; machine-readable metadata is in CITATION.cff. Cite the original rs-embed paper when using its framework, and the original model/data publications for the artifacts used in your analysis. Our research manuscript will receive its own citation when a public bibliographic record is available.
@article{ye2026modelplacetimeremote,
title={Any Model, Any Place, Any Time: Get Remote Sensing Foundation Model Embeddings On Demand},
author={Ye, Dingqi and Kiv, Daniel and Hu, Wei and Shi, Jimeng and Wang, Shaowen},
year={2026},
eprint={2602.23678},
archivePrefix={arXiv},
url={https://arxiv.org/abs/2602.23678}
}
We thank the rs-embed contributors, model authors, Google Earth Engine, Google and Google DeepMind, TorchGeo, GeoTessera, TerraTorch, rshf, Microsoft SatCLIP, GeoCLIP, Esri, and the wider Earth observation community. Integration does not imply endorsement.
Library code is distributed under Apache-2.0, with inherited attribution retained in NOTICE. Vendored components, model weights, data, and fonts retain their respective licenses. AlphaEarth data is CC-BY-4.0; Esri's software/model terms apply separately. See provenance and licensing.