mirror of
https://github.com/zvx-echo6/recon.git
synced 2026-05-21 23:24:47 +02:00
Switch /api/reverse/<lat>/<lon> elevation source from Valhalla to planet-DEM
Per OFFROUTE-ARCHITECTURE.md §9 ("planet-dem.pmtiles as single elevation
source"). The bundle endpoint previously called Valhalla /height, which only
has 48 Idaho HGT tiles; it now reads the planet-scale Terrarium PMTiles that
already back the frontend hillshade and contours.
- dem.py: add DEMReader.sample_point(lat, lon) — one z12 tile (LRU-cached),
Web-Mercator pixel index, None outside the +/-85.05 pole cap or when untiled.
- netsyms_api.py: module-level DEMReader singleton (lazy mmap, None if init
fails); _reverse_elevation now calls _DEM.sample_point; drop the Valhalla
HTTP call and _VALHALLA_HEIGHT_URL.
- tests: DEM-mock and DEM-unavailable cases; EXPECTED_KEYS derives from
_BUNDLE_KEYS. All 9 tests pass.
Verified live: Boise 824m, London 8m, Tokyo 35m, Yosemite 2804m, pole -> None.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
a80bb6e848
commit
3d2d69cd56
3 changed files with 77 additions and 17 deletions
|
|
@ -158,7 +158,28 @@ class DEMReader:
|
|||
}
|
||||
|
||||
return elevation, metadata
|
||||
|
||||
|
||||
def sample_point(self, lat: float, lon: float) -> Optional[float]:
|
||||
"""Return elevation in meters at a single point, or None if untiled.
|
||||
|
||||
Reads one z12 Terrarium tile (LRU-cached) and indexes the matching
|
||||
pixel. Sub-ms warm, ~15 ms cold per tile via NFS. Returns None when the
|
||||
tile is absent (e.g. true ocean nodata) or lat is outside the
|
||||
Web-Mercator pole cap (~+/-85.05 deg).
|
||||
"""
|
||||
if not -85.05112878 <= lat <= 85.05112878:
|
||||
return None
|
||||
n = 2 ** ZOOM_LEVEL
|
||||
fx = (lon + 180.0) / 360.0 * n
|
||||
fy = (1.0 - math.asinh(math.tan(math.radians(lat))) / math.pi) / 2.0 * n
|
||||
tx, ty = int(fx), int(fy)
|
||||
tile = self._decode_tile(ZOOM_LEVEL, tx, ty)
|
||||
if tile is None:
|
||||
return None
|
||||
row = min(TILE_SIZE - 1, int((fy - ty) * TILE_SIZE))
|
||||
col = min(TILE_SIZE - 1, int((fx - tx) * TILE_SIZE))
|
||||
return float(tile[row, col])
|
||||
|
||||
def pixel_to_latlon(self, row: int, col: int, metadata: dict) -> Tuple[float, float]:
|
||||
"""Convert pixel coordinates to lat/lon."""
|
||||
lat = metadata["origin_lat"] + row * metadata["pixel_size_lat"]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue