GeoEmbed
netcl-based visual feature encoders for aerial and satellite imagery.
What It Can Do
- 256d L2-Normalized Vectors: Encodes aerial and satellite imagery into compact 256-dimensional unit vectors ($|z|_2 = 1.0$).
- Direct Similarity Measurement: Vector dot product directly yields cosine similarity in $[-1.0, 1.0]$:
$$S(z_1, z_2) = z_1 \cdot z_2$$
- Environmental Invariance: Stable across multi-year temporal drift, seasons, foliage changes, sun angles, and illumination conditions.
- Topological & Semantic Structure: Captures road networks, parcel boundaries, forested areas, water bodies, and built-up patterns.
- Unsupervised Clustering: Latent vectors organically group semantic landscape and terrain types without manual labels:
| Reference Orthophoto | Continuous Latent Field (PCA) | Low Cluster ($k=2$) |
|---|---|---|
| Low Cluster ($k=3$) | Low Cluster ($k=4$) | Cluster Map ($k=6$) |
|---|---|---|
| Cluster Map ($k=8$) | Cluster Map ($k=10$) | Cluster Map ($k=20$) |
|---|---|---|
The cluster maps and continuous latent field above visualize the representations produced by the V3 encoder across an aerial orthophoto grid. At low cluster counts ($k=2, 3, 4$), the latent space cleanly partitions macroscopic landscape classes (dense forest vs. open agricultural land). As $k$ increases ($k=6, 8, 10, 20$), subtle sub-structures such as access roads, parcel boundaries, and individual built structures emerge purely unsupervised.
Data source of sample orthophotos: © LGL Baden-Württemberg (www.lgl-bw.de), licensed under dl-de/by-2-0. See ATTRIBUTION.md for details.
- Downstream Applications:
- Unsupervised land-cover segmentation and zone maps
- Parcel and boundary structure delineation
- Temporal change detection across multi-year captures
- Visual localization and map matching against orthophoto databases
What It Expects as Input
- Image Type: Nadir aerial and satellite imagery (orthophotos, top-down perspective).
- Format: File path (
str/Path), PILImage, or NumPy array. - Color Channels: 3-channel RGB (automatically converted and normalized to $[-1.0, 1.0]$).
- Geometry: Square image tiles.
- Preferred Ground Scale / Zoom Level:
z=18Web-Mercator ($\approx 0.5\text{ m/pixel}$ GSD). The encoders are natively calibrated for $z=18$ aerial tiles. Any single, consistent scale works as long as queries and reference index match, but $z=18$ provides optimal feature separation.
Model Variations & Input Resolution
| Model | Native Tile Size | Architecture | Checkpoint Source | Description |
|---|---|---|---|---|
V3 (Model()) |
$128 \times 128$ px | ResNet-18 baseline | Bundled in package (offline) |
Compact, fast baseline visual encoder. Used to generate the cluster visualizations above. |
V11 (Model.v11()) |
$256 \times 256$ px | Dual-Tower (ResNet-18 + Vision Transformer) | Auto-downloaded on demand | Factorized structure + fine detail towers with relational attention head. |
V12 (Model.v12()) |
$256 \times 256$ px | Dual-Tower (Refined topology) | Auto-downloaded on demand | Enhanced topological boundary resolution and boundary contrast. |
Limitations
- No Scale Invariance: The models deliberately do not enforce cross-scale invariance to preserve fine discriminative details. All tiles in an index and query set must share the same ground scale (preferably $z=18$). Mixing different zoom levels (e.g. $z=16$ and $z=18$) leads to scale aliasing and false matches.
- Nadir Perspective Only: Strictly top-down orthophotos. Oblique aerial imagery, perspective drone shots, or street-level photos are not supported.
- RGB Only: Standard 3-channel RGB. Multispectral, near-infrared (NIR), or synthetic-aperture radar (SAR) imagery are not supported without prior conversion.
Code
from geoembed import Model
# Default model: V3 (native 128x128 tile input, bundled offline)
model = Model()
# Factorized dual-tower models (native 256x256 tile input, auto-downloaded)
model = Model.v11(device="gpu")
model = Model.v12(device="cpu")
# Encode a single image -> (256,) L2-normalized vector
vector = model.encode("tile.png")
# Encode a batch of images -> (N, 256) NumPy array
vectors = model.encode(["tile_a.png", "tile_b.png"])
# Cosine similarity between two images -> float in [-1.0, 1.0]
sim = model.similarity("tile_a.png", "tile_b.png")
print(f"Similarity: {sim:.4f}")
Metadata
Release files for geoembed 1.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| geoembed-1.0.1.tar.gz | 41.9 MB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| geoembed-1.0.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 83.7 MB
Release files / geoembed-1.0.1.tar.gz
| Download URL | geoembed-1.0.1.tar.gz |
|---|---|
| Size | 41.9 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6427f702d07242adc354dd8529d6ef92322d7c4906681e7f8f83d505c9d2bcf0
|
|
BLAKE2b-256 checksum How to use checksums |
ae2603ed2ce0308897d751bec92084f576c06a54bad4f8a8d39af77c86da8be1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.0
|
Release files / geoembed-1.0.1-py3-none-any.whl
| Download URL | geoembed-1.0.1-py3-none-any.whl |
|---|---|
| Size | 41.9 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ab0c9b0fb3b3339a99027dce605c59490535c82986b9c8168a428be7ef26682e
|
|
BLAKE2b-256 checksum How to use checksums |
8b83c8cf8661607f4d522759aee47b43e6a90ef310ae495473d94243321130be
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.0
|
Security for geoembed 1.0.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.