Skip to main content

Geographic Neural Data Cube - Read and analyze .gndc compressed geospatial time-series data

Project description

pygndc

Geographic Neural Data Cube - A Python SDK for reading and analyzing .gndc compressed geospatial time-series data.

GeoNDC

What is GeoNDC?

GeoNDC is a continuous-time, AI-ready representation of Earth observation archives. Unlike traditional Analysis-Ready Data (cloud-corrected raster files) or geospatial foundation model embeddings (abstract feature vectors), GeoNDC preserves the original physical observables — surface reflectance, vegetation indices, biophysical variables — while enabling millisecond-level random-access queries at any (x, y, t) coordinate.

Each archive (MODIS, Sentinel-2, Landsat, HiGLASS, …) is encoded into a single self-contained .gndc file (typically 0.5–2 GB) that runs on a laptop, a server, or directly in a browser via WebGPU. Data providers train the model once and publish the file; users download it and run inference locally — the compressed form is the analysis-ready form. No hosted runtime, no API quota, no vendor lock-in.

Key capabilities:

  • Continuous-time reconstruction — query data at any moment, not just original observation times
  • Millisecond random access — point time series in ~7 ms, full-frame reconstruction in ~2 s on a consumer GPU
  • Analytic gradients — compute spatial/temporal derivatives directly from the neural network
  • Compact storage — typically ~100:1 versus Int16 raster baselines, up to ~400:1 versus raw float archives
  • Implicit gap-filling — cloud-occluded surfaces are reconstructed from the learned spatiotemporal field
  • Multi-sensor support — Sentinel-2, Landsat, MODIS, HiGLASS, and more

Online Viewer & Data

  • Web Viewer: Browse .gndc files directly in the browser via WebGPU at geondc.org/viewer — no installation required, GPU-accelerated, runs entirely client-side.
  • Sample Data: Download .gndc datasets from Hugging Face.

Installation

pip install pygndc

Or from source:

git clone https://github.com/jianboqi/pygndc.git
cd pygndc
pip install .

GPU support (recommended)

pip install pygndc installs CPU-only PyTorch by default. For GPU acceleration, install CUDA-enabled PyTorch first:

# Example for CUDA 12.1 (check https://pytorch.org for your CUDA version)
pip install torch --index-url https://download.pytorch.org/whl/cu121

# Then install pygndc
pip install pygndc

tiny-cuda-nn (fastest)

For best performance, install tiny-cuda-nn. This provides the optimized TCNN backend with significantly faster inference and lower memory usage.

pip install git+https://github.com/NVlabs/tiny-cuda-nn/#subdirectory=bindings/torch

Note: tiny-cuda-nn requires an NVIDIA GPU with CUDA support and a C++ compiler. If you cannot install it, pygndc will automatically fall back to pure PyTorch (torch_gpu or torch_cpu).

Optional dependencies

pip install pygndc[all]       # xarray + geopandas + scipy
pip install pygndc[xarray]    # xarray support
pip install pygndc[geo]       # geopandas + shapely

Inference modes

pygndc uses a single mode parameter to control both the backend and device:

Mode Backend Device Description
auto auto-detect auto-detect Default. Best available mode
tcnn_cuda tiny-cuda-nn GPU Fastest. Requires tinycudann + CUDA
torch_gpu PyTorch GPU No extra dependencies, requires CUDA
torch_cpu PyTorch CPU Works everywhere, slowest

Quick Start

import pygndc

# Open a .gndc file (auto-detects best mode)
with pygndc.open("samples/S2_sample_2022_to_2025.gndc") as ds:
    print(ds)                                          # Shows mode, shape, CRS, etc.

    # --- Read OBSERVED data: read(time, <spatial selector>, bands) ---
    frame  = ds.read(time=0)                               # full frame (H, W, C)
    frame  = ds.read(time="2024-06-15")                    # by stored date (exact match)
    sub    = ds.read(time=0, window=(col_off, row_off, w, h))      # pixel window
    region = ds.read(time=0, bbox=(116.3, 39.8, 116.5, 40.0))     # geographic bbox
    px     = ds.read(time=0, rowcol=(140, 140))            # pixel point -> (C,)
    px     = ds.read(time=0, latlng=(116.825, 40.486))     # geographic point -> (C,)
    rgb    = ds.read(time=0, bands=[0, 1, 2])              # select bands

    # Windowed reads build coords for just the window — memory scales with the
    # window, not the full frame, so huge images don't OOM.

    # --- SYNTHESIZE an unobserved time: interpolate(...) ---
    # read() raises on an unobserved date; interpolate() opts into synthesis.
    synth  = ds.interpolate("2024-06-15 12:00:00")         # continuous time interpolation
    synth  = ds.interpolate(0.5, bbox=(116.3, 39.8, 116.5, 40.0))  # 0.5 = normalized [0,1]

    # --- Point time series: series(point selector) -> (T, C) ---
    ts     = ds.series(latlng=(116.825, 40.486))           # (T, C) at a geo point
    ts     = ds.series(rowcol=(140, 140))                  # (T, C) at a pixel

    # Analysis
    ndvi = ds.ndvi(t=0, red_band=2, nir_band=3)            # (H, W)
    dx, dy = ds.gradient(t=0, mode="spatial")              # analytic gradients

    # Export
    arr = ds.to_numpy(t=0)                                 # (H, W, C) numpy array
    ds.to_tif("frame_0.tif", t=0)                         # single frame to GeoTIFF
    ds.to_tifs("output_dir/")                              # all frames
    xds = ds.to_xarray()                                   # xarray Dataset

# Specify mode explicitly
with pygndc.open("samples/S2_sample_2022_to_2025.gndc", mode="torch_cpu") as ds:
    frame = ds.read(time=0)

API note (v0.7): data access was unified into three verbs — read() (observed time), interpolate() (synthesized time), series() (point time series) — each taking exactly one spatial selector (window= / bbox= / rowcol= / latlng=). This replaces the previous read(t=...), read_at_time(), read_region(), sample() and pixel_series() methods.

CLI Commands

# Show model info
pygndc info model.gndc
pygndc info model.gndc --json

# Decompress to GeoTIFF files
pygndc decompress -i model.gndc -o ./output
pygndc decompress -i model.gndc -o ./output --timestamp 2024-06-15
pygndc decompress -i model.gndc -o ./output --start 2024-01-01 --end 2024-12-31 --interval 5

# Compute NDVI
pygndc ndvi -i model.gndc -o ndvi.tif --red-band 0 --nir-band 1

# Compute spatial gradient
pygndc derivative -i model.gndc -o gradient.tif --grad-mode mag

# Point query
pygndc sample -i model.gndc --lon 116.5 --lat 39.9

# Export pixel time series to CSV
pygndc timeseries -i model.gndc --row 100 --col 200 -o series.csv

# Launch interactive viewer
pygndc viewer -i model.gndc

# All commands support --mode (auto, tcnn_cuda, torch_gpu, torch_cpu)
pygndc decompress -i model.gndc -o ./output --mode torch_cpu

Interactive Viewer

A GUI tool for visualizing .gndc files with multiple display modes, time navigation, and pixel inspection.

from pygndc import start_viewer
start_viewer()

Features:

  • RGB, NDVI, temporal gradient, and spatial gradient display modes
  • Time slider with date navigation
  • Click-to-inspect pixel time series
  • Region selection and zoom
  • Export current frame or entire time series

File Format

A .gndc file is a zstandard-compressed archive containing:

Component Description
Header JSON metadata (dimensions, timestamps, CRS, band info)
Model Weights Compressed neural network parameters
Mask Data Optional validity mask (static or dynamic)
Residuals Optional correction data for higher accuracy

API Reference

See API_Reference.md for the full API documentation.

License

MIT License

Citation

@misc{qi2026geondcqueryableneuraldata,
  title={GeoNDC: A Queryable Neural Data Cube for Planetary-Scale Earth Observation},
  author={Jianbo Qi and Mengyao Li and Baogui Jiang and Yidan Chen and Qiao Wang},
  year={2026},
  eprint={2603.25037},
  archivePrefix={arXiv},
  primaryClass={cs.CV},
  url={https://arxiv.org/abs/2603.25037},
}

Contact

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pygndc-1.0.1.tar.gz (66.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pygndc-1.0.1-py3-none-any.whl (68.7 kB view details)

Uploaded Python 3

File details

Details for the file pygndc-1.0.1.tar.gz.

File metadata

  • Download URL: pygndc-1.0.1.tar.gz
  • Upload date:
  • Size: 66.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pygndc-1.0.1.tar.gz
Algorithm Hash digest
SHA256 068e9d4941896ef3ac4b73388cf5f23f8cc4749a351eb16d1a5a66821a0c5265
MD5 04eac1a79b7e2217f980a07bedc860fc
BLAKE2b-256 ee23d3958531b270cf24ce72b6d99bfa42bd9f1d69f099ca6f6878e7689da737

See more details on using hashes here.

Provenance

The following attestation bundles were made for pygndc-1.0.1.tar.gz:

Publisher: publish.yml on jianboqi/pygndc

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pygndc-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: pygndc-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 68.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pygndc-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 06ab3ec499a08c89eab5147f2b3da2d5098071dcb8e76074f5556e121e44cfaa
MD5 16c7f535ebaa408ad71110d4933fd83b
BLAKE2b-256 a2032cb86bbe43f738031056c23436778b04edde8245b256899c045e9c0182fb

See more details on using hashes here.

Provenance

The following attestation bundles were made for pygndc-1.0.1-py3-none-any.whl:

Publisher: publish.yml on jianboqi/pygndc

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page