Skip to content

feat: Globe view, antimeridian, and polar projection support#266

Closed
espg wants to merge 9 commits intodevelopmentseed:mainfrom
englacial:globe-view-support
Closed

feat: Globe view, antimeridian, and polar projection support#266
espg wants to merge 9 commits intodevelopmentseed:mainfrom
englacial:globe-view-support

Conversation

@espg
Copy link

@espg espg commented Feb 25, 2026

This is in response to the discussion in this issue , about the possibility of defaulting to a global viewer in the source.coop stac-map viewer.

Summary

  • Implement globe view tile traversal by threading projectTo4326 through the tileset and computing bounding volumes in 3D globe common space via viewport.projectPosition
  • Add antimeridian crossing detection in RasterReprojector — when a tile's WGS84 longitudes span >180°, normalize them to a continuous range (e.g. [170, 190] instead of [170, -170]) so mesh triangles don't wrap the wrong way around the globe
  • Add polar projection support with pole detection and a maxTriangles safety cap on run() to prevent infinite refinement near poles
  • Add 37 new tests across tile traversal, antimeridian handling, and polar projections (up from 1 placeholder test)
  • Add a globe-view example using GlobeView + COGLayer

Closes #82, closes #171, closes #172

Commits

  1. Baseline tests — 21 tests for tile traversal code (bounds, LOD, child ranges, OBB) establishing a regression baseline before changes
  2. Globe view traversal_getGlobeBoundingVolume(), sampleReferencePointsInWgs84(), globe-mode bounds conversion in getTileIndices(), LOD fix using centerLatitude instead of Mercator-specific worldToLngLat()
  3. Antimeridian — detect ±180° crossing from initial corner vertices, shift negative longitudes by +360, apply offset to subsequent vertices during mesh refinement
  4. Polar projections — detect tiles near poles (|lat| > 75° + antimeridian crossing), maxTriangles parameter on run() to cap refinement
  5. Globe example — minimal GlobeView + COGLayer example with debug controls

Test plan

  • All 42 unit tests pass (pnpm test in deck.gl-raster and raster-reproject)
  • Run globe-view example with NZ imagery URL — verify tiles render on the globe
  • Run cog-basic example — verify no regression in Mercator rendering

espg added 5 commits February 25, 2026 09:55
Expand __TEST_EXPORTS to expose helper functions (getOverlappingChildRange,
getMetersPerPixel, rescaleEPSG3857ToCommonSpace, sampleReferencePointsInEPSG3857)
and add 21 tests covering:

- computeProjectedTileBounds for WebMercatorQuad and UTM31
- rescaleEPSG3857ToCommonSpace coordinate mapping and clamping
- sampleReferencePointsInEPSG3857 interpolation
- getOverlappingChildRange parent-child tile relationships
- getMetersPerPixel zoom/latitude behavior
- RasterTileNode.insideBounds AABB overlap logic
- RasterTileNode.getBoundingVolume OBB computation (Mercator path)
- RasterTileNode.children quadtree traversal

Establishes regression baseline before globe view changes.
Remove the assert(false, "TODO") blocker in getBoundingVolume() and implement
full globe view support in the tile traversal code:

- Thread projectTo4326 through TileMatrixSetTileset → getTileIndices() →
  RasterTileNode (alongside existing projectTo3857)
- Add _getGlobeBoundingVolume() which samples reference points in WGS84 and
  projects them into globe common space via viewport.projectPosition
- Add sampleReferencePointsInWgs84() helper (parallel to the existing
  sampleReferencePointsInEPSG3857)
- Return centerLatitude from getBoundingVolume() so LOD computation works in
  both Mercator and Globe views without calling worldToLngLat()
- Handle globe-mode bounds conversion in getTileIndices() by projecting WGS84
  bounds corners through the globe project function instead of lngLatToWorld()
- Remove unused assert import

Closes developmentseed#82
Detect when a tile's output positions span the ±180° meridian and
normalize longitudes to a continuous range (e.g., [170, 190] instead
of [170, -170]). This prevents mesh triangles from spanning 340° of
longitude and ensures correct GPU-side interpolation for tiles near
the date line.
Detect tiles containing or near a geographic pole (|lat| > 75° with
antimeridian crossing). Add a maxTriangles safety cap to run() to
prevent infinite refinement near poles, where the extreme longitude
variation can require many more triangles to converge.

The existing antimeridian normalization handles the longitude wrapping
for polar tiles — the mesh refines around the remaining discontinuity.
deck.gl's GlobeView renders the resulting mesh correctly since
projectPosition handles arbitrary (lng, lat) values.
Provides a minimal example using deck.gl's GlobeView with COGLayer
for visualizing COG imagery on a 3D globe. Includes a dark background
sphere, debug mesh controls, and commented URLs for both mid-latitude
and polar datasets.
@espg espg changed the title Globe view, antimeridian, and polar projection support feat: Globe view, antimeridian, and polar projection support Feb 25, 2026
@github-actions github-actions bot added the feat label Feb 25, 2026
@kylebarron
Copy link
Member

kylebarron commented Feb 26, 2026

Thanks for the PR! It's really exciting!

Each of these issues is an important thing to resolve and fix.

But given the architectural importance of these three features, I think we really need this as three separate PRs to be able to adequately review it. Seems like Globe view, antimeridian, and polar projection support should be quite separable features?

Copy link
Member

@kylebarron kylebarron left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one comment from an initial read through here.

Let's tackle just the globe view first in a new PR. I think globe view should be easier and more straightforward than the others.

Comment on lines +9 to +11
// Register WebGL adapter — required when DeckGL creates its own context
// (unlike MapboxOverlay which reuses MaplibreGL's existing context)
luma.registerAdapters([webgl2Adapter]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've never seen this before; this isn't required for a standard DeckGL app

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, thought this was needed to get a proper context map background (i.e., coastlines, country borders)-- looks like another change in the same commit fixed that issue and we can excise this.

@espg
Copy link
Author

espg commented Feb 26, 2026

closing in favor of #268 , #269 , and #270

@espg espg closed this Feb 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support images over the North/South poles Support images spanning the antimeridian Support for rendering in globe view

2 participants