Skip to content

Add SPZ_NIANTIC_georeference extension - #103

Closed
diegomazala wants to merge 1 commit into
nianticlabs:mainfrom
diegomazala:feat/niantic-georeference-extension
Closed

diegomazala wants to merge 1 commit into
nianticlabs:mainfrom
diegomazala:feat/niantic-georeference-extension

Conversation

@diegomazala

@diegomazala diegomazala commented Aug 4, 2026 •

Copy link
Copy Markdown

Summary

Adds SPZ_NIANTIC_georeference (type 0x4E530001), an extension that records a similarity transform placing an SPZ asset's local frame into an Earth-centered geocentric CRS (e.g. EPSG:4978, WGS84 ECEF):

p_crs = scale * (q * p_local * q⁻¹) + origin
  • origin (double[3], meters), rotation (double[4], unit quaternion), and scale (double, dimensionless uniform factor) carry the transform at full precision — independent of the 24-bit fixed-point quantization used for Gaussian positions themselves.
  • scale is uniform (isotropic) only, matching the classic 7-parameter Helmert/similarity transform used for local-to-global CRS registration. It corrects for the scale ambiguity inherent to unreferenced reconstruction (e.g. monocular SfM), which is always isotropic under a calibrated-camera model — there is deliberately no anisotropic scale or shear field, since that would describe a different problem (a deformed local frame) than this extension addresses.
  • crs_epsg names the target geocentric CRS; epoch (decimal year) and an optional WKT2 wkt string are provenance fields.
  • This is a descriptor only — the library never applies the transform to Gaussian data. Readers that don't care about georeferencing can ignore it entirely; readers that do can apply the transform themselves in double precision at load time.
  • Post-transform heights are ellipsoidal by construction. wkt records the source compound CRS (including vertical datum) as provenance — it is never authoritative for transforming data, since orthometric-vs-ellipsoidal height mixups silently shift world position by tens of meters.

Design notes / prior art

The split between a numeric transform (authoritative) and CRS metadata (descriptive) mirrors patterns in two existing geospatial formats:

  • 3D Tiles (OGC standard) roots its scene graph with a transform — a 4×4 matrix mapping a tile's local frame into the tileset's global frame, commonly EPSG:4978 (ECEF). That matrix already supports scale as a first-class citizen (as does glTF's TRS node convention); this extension's scale field brings the same capability without requiring a full affine matrix.
  • COPC (spec PDF, built on LAZ 1.4) carries CRS as a WKT string in a VLR/EVLR. This extension borrows the "optional WKT2 string" shape, but deliberately weakens it to provenance-only: COPC's WKT is the authoritative CRS, while here the numeric transform is authoritative and wkt is metadata about where it came from (compound CRS incl. vertical datum), since a reader must not re-derive a transform from it.

Testing

  • extensions/cc/georeference-niantic.{h,cc} — payload struct, serialization, and load-time validation (ext_version, reserved crs_epsg=0, quaternion normalization, non-finite/non-positive scale, wkt_length bounds, oversized-wkt-on-write guard).
  • tests/python/test_extensions.py — round-trips (with/without epoch and wkt), coexistence with SPZ_ADOBE_safe_orbit_camera, malformed-payload skip paths (including invalid scale: zero, negative, NaN, Inf), and Earth-radius origin precision.
  • Bindings for Python (nanobind) and WASM (Emscripten/embind + TypeScript declarations) mirror the existing Adobe extension pattern.
  • extensions/README.md documents the payload layout and validation rules; top-level README.md gets a georeferencing section; vendor ID 0x4E53 ("NS") is allocated in the vendor table.

Ran python -m pytest tests/python/ with SPZ_BUILD_EXTENSIONS=ON — 120 passed, 0 skipped, 0 failed.

@diegomazala
diegomazala force-pushed the feat/niantic-georeference-extension branch 2 times, most recently from 4325d7c to 870886f Compare August 4, 2026 18:47
Defines SpzExtensionGeoreferenceNiantic (type 0x4E530001) carrying a
similarity transform from the local frame to a geocentric CRS (origin,
unit quaternion, uniform scale, EPSG code) with optional epoch and WKT2
provenance:

  p_crs = scale * (q * p_local * q^-1) + origin

scale is uniform (isotropic) only, matching the classic 7-parameter
Helmert/similarity transform used for local-to-global CRS registration:
it corrects for the scale ambiguity inherent to unreferenced
reconstruction (e.g. monocular SfM), which is always isotropic under a
calibrated-camera model. There is deliberately no anisotropic scale or
shear field.

The extension is a descriptor only: origin/rotation/scale are
full-precision doubles, independent of the 24-bit fixed-point
quantization used for Gaussian positions, and the library never applies
the transform to the Gaussian data itself. Post-transform heights are
ellipsoidal by construction; wkt records the source compound CRS
(including vertical datum) as provenance only, never as a target
definition.

Wires the extension into the record parser, rejects reserved crs_epsg 0,
unsupported ext_version, and non-finite/non-positive scale on load,
normalizes non-unit quaternions within tolerance, and caps wkt size on
write to guard the u32 record length against overflow (oversized wkt is
omitted, never truncated).

Exposes the extension in Python (nanobind) and WASM (embind + TypeScript
declarations), mirroring the existing Adobe extension bindings. Adds
round-trip and malformed-payload tests, allocates vendor ID 0x4E53 ("NS"),
and documents the payload layout and validation rules in
extensions/README.md and the top-level README.
@diegomazala
diegomazala force-pushed the feat/niantic-georeference-extension branch from 870886f to 58b7df9 Compare August 4, 2026 19:14
@diegomazala diegomazala closed this Aug 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant