# Contour Tile Rebuild — Terrarium DEM Alignment Fix ## Problem Contour lines are misaligned from hillshade terrain. Root cause: - Contours: built from SRTM HGT (EPSG:4326, ~30m resolution) - Hillshade: built from Mapzen Terrarium (EPSG:3857, ~10m at z12) Different DEMs = different elevation values at same coordinates = visible offset. ## Solution Regenerate contours from the same Terrarium DEM tiles used for hillshade. The `hillshade-na.pmtiles` file contains 93GB of Terrarium-encoded RGB PNGs. Decode elevation from those tiles, generate contours. Same pixels = guaranteed alignment. ## Infrastructure | Resource | Location | Specs | |----------|----------|-------| | Compute | cortex (192.168.1.150) | i9-10900X, 16 cores, 22GB RAM | | Storage | pi-nas NFS `/mnt/pi-nas` | 16TB free on /export/data | | Source DEM | hillshade-na.pmtiles | 93GB, z0-12, Terrarium encoding | | Tools | cortex | GDAL 3.8.4, tippecanoe, pmtiles | ## Terrarium Encoding ``` elevation_meters = (R * 256 + G + B / 256) - 32768 ``` Source tiles are EPSG:3857 (Web Mercator), 256x256 PNG, z0-12. ## Output Specification Must match existing `contours-na.pmtiles` structure for frontend compatibility: ```json { "layer": "contours", "attributes": { "elevation_ft": "Number", "elevation_m": "Number", "tier": "String" // "minor" | "intermediate" | "index" }, "zoom": "4-14", "format": "MVT" } ``` Tier mapping: - 40ft interval → tier: "minor" - 200ft interval → tier: "intermediate" - 1000ft interval → tier: "index" ## Regions Process in chunks to fit RAM: | Region | Bounds (W,S,E,N) | |--------|------------------| | alaska | -168,51,-130,72 | | canada-west | -141,48,-90,72 | | canada-east | -90,42,-52,72 | | conus-west | -125,31,-104,49 | | conus-central | -104,25,-84,49 | | conus-east | -84,24,-66,48 | | mexico | -118,14,-86,33 | | caribbean | -86,14,-59,28 | ## Pipeline Phases ### Phase 1: Extract DEM from Terrarium PMTiles 1. Read z12 tiles from hillshade-na.pmtiles 2. Decode Terrarium RGB → elevation (meters) 3. Mosaic into regional GeoTIFFs (EPSG:3857) 4. Reproject to EPSG:4326 for gdal_contour ### Phase 2: Generate Contours For each region: ```bash # Convert meters to feet gdal_calc.py -A region.tif --outfile=region_ft.tif --calc="A*3.28084" # Generate contours at all intervals gdal_contour -a elevation -i 40 -f FlatGeoBuf region_ft.tif region_40ft.fgb gdal_contour -a elevation -i 200 -f FlatGeoBuf region_ft.tif region_200ft.fgb gdal_contour -a elevation -i 1000 -f FlatGeoBuf region_ft.tif region_1000ft.fgb ``` ### Phase 3: Build Vector Tiles 1. Add tier attribute and merge intervals into single FGB per region 2. Generate mbtiles with tippecanoe: ```bash tippecanoe -o region.mbtiles -l contours -Z4 -z14 --no-feature-limit --no-tile-size-limit --simplification=10 region_merged.fgb ``` 3. Join all regions: `tile-join -o contours-na.mbtiles *.mbtiles` 4. Convert: `pmtiles convert contours-na.mbtiles contours-na.pmtiles` ### Phase 4: Deploy 1. Copy to VM 130: `/mnt/nav/tiles/contours-na.pmtiles` 2. Verify with `pmtiles show` 3. Browser test at navi.echo6.co ## Workspace ``` /mnt/pi-nas/nav/contour-rebuild/ ├── dem/ # Regional GeoTIFFs (keep for future rebuilds) ├── contours/ # Intermediate FlatGeoBuf files (delete after) ├── tiles/ # Output mbtiles and pmtiles ├── logs/ # Timestamped logs per phase ├── scripts/ # Pipeline scripts └── backup/ # Original contours-na.pmtiles backup ``` ## Verification After deploy, manual browser test: 1. Hard refresh navi.echo6.co 2. Toggle contours on 3. Zoom to Twin Falls / Snake River Canyon 4. Contour lines should align precisely with hillshade canyon walls ## Constraints - All operations as zvx (pi-nas root_squash) - Do not modify hillshade-na.pmtiles (read only) - Do not touch frontend code - Keep intermediate GeoTIFFs for future interval changes - Delete .fgb and .mbtiles after final pmtiles verified ## Created 2026-04-27 — Alignment fix rebuild