Skip to content

Add 3DEP_1M data source for native 1-meter DEMs#25

Open
scottstanie wants to merge 4 commits intomasterfrom
fix-3dep
Open

Add 3DEP_1M data source for native 1-meter DEMs#25
scottstanie wants to merge 4 commits intomasterfrom
fix-3dep

Conversation

@scottstanie
Copy link
Copy Markdown
Owner

Summary

  • Adds --data-source 3DEP_1M for accessing native 1-meter resolution lidar DEMs from the USGS 3DEP program
  • Queries the TNM Access API to discover which tiles cover the requested bbox, then fetches them as Cloud Optimized GeoTIFFs from S3 via /vsicurl/
  • Uses a two-step GDAL warp: first reproject from source UTM (various zones) to EPSG:4326, then convert NAVD88 heights to WGS84 ellipsoidal

Why a separate source from 3DEP?

The existing 3DEP source uses the ImageServer exportImage endpoint, which dynamically resamples all 3DEP data at the requested resolution (hardcoded to ~30m via DEFAULT_RES). While the ImageServer can serve 1m data at fine pixel sizes, it has practical limitations:

  • 2000-pixel export limit per chunk (would need thousands of requests for large areas at 1m)
  • Silently falls back to coarser data where 1m coverage doesn't exist
  • Dynamic resampling vs. native source tiles

The 3DEP_1M approach:

  • Explicitly discovers 1m tiles and fails clearly when coverage doesn't exist
  • Direct COG access from S3 (efficient partial reads, no chunk limits)
  • Outputs at native ~1m resolution

Key fix during review

The original implementation set srcSRS = "EPSG:4269+5703" (NAD83 geographic + NAVD88), but 1m tiles are in NAD83/UTM (meters). This would cause GDAL to misinterpret UTM meter coordinates as geographic degrees. Fixed with a two-step warp:

  1. Reproject UTM → EPSG:4326 (let GDAL read source CRS from file metadata)
  2. Convert NAVD88 → WGS84 ellipsoidal (now that coords are geographic, compound CRS is correct)

Test plan

  • Unit tests for TNM API tile discovery (mock-based, 3 tests)
  • All 16 existing tests pass
  • Integration test with real download: sardem --bbox -118.4 33.7 -118.3 33.8 --data-source 3DEP_1M -o test_3dep_1m.tif

🤖 Generated with Claude Code

scottstanie and others added 4 commits February 21, 2026 17:45
The existing 3DEP source uses the ImageServer which resamples to ~30m.
3DEP_1M queries the TNM Access API for 1m tiles and fetches them as
COGs from S3 via /vsicurl/. Uses a two-step GDAL warp: first reproject
from source UTM to EPSG:4326, then convert NAVD88 to WGS84 ellipsoidal.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The dateline bbox splitting used shapely to split polygons at 180 degrees,
but this is unnecessary for axis-aligned bounding boxes — simple arithmetic
suffices. This also fixes CI failures where shapely was not installed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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