Skip to content

feat: grad_meh import pipeline with ZIP upload and MapLibre styles#136

Merged
fank merged 12 commits into
mainfrom
feat/gradmeh-import
Feb 6, 2026
Merged

feat: grad_meh import pipeline with ZIP upload and MapLibre styles#136
fank merged 12 commits into
mainfrom
feat/gradmeh-import

Conversation

@fank
Copy link
Copy Markdown
Member

@fank fank commented Feb 6, 2026

Summary

  • Replaces the legacy PBO/WRP pipeline with a grad_meh-based import pipeline using GDAL for satellite tiles, DEM processing (hillshade, heightmap, color-relief, contours), and tippecanoe for vector features
  • Adds a ZIP upload endpoint (POST /api/maps/import) to the maptool web server, replacing the removed PBO upload and local-path-only import-dir endpoints
  • Generates full MapLibre style documents (standard/satellite/hybrid) with vector feature layers sorted to match Arma 3's map render order
  • Improves label readability with text halos and fixes runway rendering (fill instead of line)

Test plan

  • Build: go build ./cmd/ocap-maptool && go test ./internal/maptool/...
  • Upload a grad_meh ZIP export via the web UI and verify job completes
  • Verify generated style.json has correct layer ordering (labels above roads)
  • Verify label readability (namelocal, citycenter, namemarine, hill all have halos)
  • Verify runways render as filled polygons, not outlines
  • Test CLI import: ocap-maptool import -maps maps altis/

fank added 12 commits February 6, 2026 14:52
…ation

Add a 12-stage pipeline for importing grad_meh map exports, producing
5 PMTiles (satellite, features, heightmap, hillshade, color-relief),
3 MapLibre style variants (standard, satellite, hybrid), and rich
metadata — matching the Python arma3-maptiler output.

New stages: prepare_dem, generate_satellite_tiles, generate_heightmap,
generate_hillshade, generate_colorrelief, generate_contours (4 intervals
via gdal_contour), process_geojson, generate_vector_tiles (per-layer
tippecanoe with tile-join fallback), generate_styles, generate_metadata.

Includes all Python parity fixes: satellite z8 min zoom, DEM nodata
fill, sea level mask (A>=0), contour underwater colors, house extrusion
zoom, hillshade LZW compression, hidden satellite toggle in standard
style, label colors with halos, correct icon sizes, full color relief
guide, and bush layer skip.

Renames PBO-specific files to *_pbo/*_legacy suffixes for clarity.
gdal_fillnodata.py requires both src and dst arguments. Write to a
temp file and rename back to the original DEM path.
Prevents "attempt to write a readonly database" errors when re-running
the pipeline with leftover MBTiles files from a previous run.
The PBO import pipeline (WRP parsing, PAA decoding, shapefile reading,
gdal2tiles tiling) is superseded by the grad_meh pipeline. This removes
all PBO-specific code, the PAA decoder package, and unused dependencies
(go-lzo, gdal2tiles.py, depbo) — net deletion of ~3,700 lines.
Replace the local-path-only importDir endpoint with importZip that
accepts multipart ZIP uploads via POST /api/maps/import. Extracts
the ZIP with zip-slip protection, locates the grad_meh directory
(at root or one level deep), and submits the import job. Also sets
SubDirs=true in processJob so web uploads use organized output layout.
Sort vector feature layers by cartographic render order matching the
Arma 3 engine: sea → contours → forest → rocks → buildings → roads
(trail/track/road/main_road/runway sub-ordered) → railway → powerline
→ bridges → vegetation → icons → labels. Previously layer order
depended on directory listing order, causing labels to render below
roads.
Add semi-transparent white text halos to hill, namemarine, namelocal,
and citycenter labels so they remain readable over varied terrain.
Change runway from line to fill type so it renders as solid grey
tarmac instead of just an outline.
…gradmeh

53 new tests covering pure logic functions:
- styles: categorizeLayer, isLayerVisible, buildVectorFeatureLayers
  (sort order, road sub-order, filtering), GenerateStyleDocument
- vector: colorArrayToHex, clamp255, toFloat64, transformCoords
- geojson: armaToGeoJSON coordinate conversion
- metadata: assetPath, computeElevationStats
- gradmeh: WorldNameFromDir, ValidateGradMehDir, ReadGradMehMeta
grad_meh is the only import pipeline now, so the qualifier is
redundant. Renames:
- gradmeh.go → worldmeta.go
- satellite_gradmeh.go → satellite.go
- vector_gradmeh.go → vector.go
- cmd/ocap-maptool/gradmeh.go → pipeline.go
(plus corresponding test files)
…st logging

Scanner now reports a single status (none/incomplete/complete) based
on whether all required files exist (satellite.pmtiles, features.pmtiles,
standard.json, map.json). Checks tiles/ and styles/ subdirs with root
fallback. Frontend shows colored status badge instead of individual
checkmarks. Removes request logging middleware.
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Feb 6, 2026

Merging this branch changes the coverage (1 decrease, 1 increase)

Impacted Packages Coverage Δ 🤖
github.com/OCAP2/web/cmd/ocap-maptool 0.00% (ø)
github.com/OCAP2/web/internal/maptool 12.95% (+3.18%) 👍
github.com/OCAP2/web/internal/maptool/paa 0.00% (-22.81%) 💀 💀

Coverage by file

Changed files (no unit tests)

Changed File Coverage Δ Total Covered Missed 🤖
github.com/OCAP2/web/cmd/ocap-maptool/handler.go 0.00% (ø) 652 (+129) 0 652 (+129)
github.com/OCAP2/web/cmd/ocap-maptool/import.go 0.00% (ø) 259 (-163) 0 259 (-163)
github.com/OCAP2/web/cmd/ocap-maptool/main.go 0.00% (ø) 271 (-64) 0 271 (-64)
github.com/OCAP2/web/cmd/ocap-maptool/pipeline.go 0.00% (ø) 12 (+12) 0 12 (+12)
github.com/OCAP2/web/internal/maptool/colorrelief.go 0.00% (ø) 195 (+195) 0 195 (+195)
github.com/OCAP2/web/internal/maptool/contours_gdal.go 0.00% (ø) 136 (+136) 0 136 (+136)
github.com/OCAP2/web/internal/maptool/dem.go 0.00% (ø) 355 (+355) 0 355 (+355)
github.com/OCAP2/web/internal/maptool/dem_pipeline.go 0.00% (ø) 286 (+286) 0 286 (+286)
github.com/OCAP2/web/internal/maptool/heightmap.go 0.00% (ø) 400 (+400) 0 400 (+400)
github.com/OCAP2/web/internal/maptool/hillshade.go 0.00% (ø) 416 (+416) 0 416 (+416)
github.com/OCAP2/web/internal/maptool/jobmanager.go 29.58% (+4.20%) 284 (-43) 84 (+1) 200 (-44) 👍
github.com/OCAP2/web/internal/maptool/mbtiles.go 0.00% (ø) 0 (-305) 0 0 (-305)
github.com/OCAP2/web/internal/maptool/metadata.go 10.89% (-10.43%) 358 (+161) 39 (-3) 319 (+164) 💀
github.com/OCAP2/web/internal/maptool/paa/decode.go 0.00% (-19.72%) 0 (-492) 0 (-97) 0 (-395) 💀
github.com/OCAP2/web/internal/maptool/paa/dxt1.go 0.00% (-29.52%) 0 (-227) 0 (-67) 0 (-160) 💀 💀
github.com/OCAP2/web/internal/maptool/pbo.go 0.00% (-8.89%) 0 (-270) 0 (-24) 0 (-246) 👎
github.com/OCAP2/web/internal/maptool/pipeline.go 30.70% (-0.69%) 215 (+27) 66 (+7) 149 (+20) 👎
github.com/OCAP2/web/internal/maptool/raster_tiles.go 0.00% (ø) 111 (+111) 0 111 (+111)
github.com/OCAP2/web/internal/maptool/satellite.go 0.00% (-7.37%) 580 (-465) 0 (-77) 580 (-388) 👎
github.com/OCAP2/web/internal/maptool/scanner.go 32.81% (+6.32%) 192 (+41) 63 (+23) 129 (+18) 👍
github.com/OCAP2/web/internal/maptool/shapefile.go 0.00% (ø) 0 (-974) 0 0 (-974)
github.com/OCAP2/web/internal/maptool/styles.go 34.05% (+34.05%) 605 (+605) 206 (+206) 399 (+399) 🌟
github.com/OCAP2/web/internal/maptool/tiles.go 40.00% (+37.98%) 20 (-277) 8 (+2) 12 (-279) 🌟
github.com/OCAP2/web/internal/maptool/tools.go 29.00% (+5.40%) 100 (+11) 29 (+8) 71 (+3) 👍
github.com/OCAP2/web/internal/maptool/vector.go 6.89% (+4.77%) 958 (-176) 66 (+42) 892 (-218) 👍
github.com/OCAP2/web/internal/maptool/worldmeta.go 23.08% (+23.08%) 169 (+169) 39 (+39) 130 (+130) 🌟
github.com/OCAP2/web/internal/maptool/wrp.go 0.00% (-9.78%) 0 (-1923) 0 (-188) 0 (-1735) 👎

Please note that the "Total", "Covered", and "Missed" counts above refer to code statements instead of lines of code. The value in brackets refers to the test coverage of that file in the old version of the code.

Changed unit test files

  • github.com/OCAP2/web/internal/maptool/geojson_test.go
  • github.com/OCAP2/web/internal/maptool/jobmanager_test.go
  • github.com/OCAP2/web/internal/maptool/metadata_test.go
  • github.com/OCAP2/web/internal/maptool/paa/decode_test.go
  • github.com/OCAP2/web/internal/maptool/paa/dxt1_test.go
  • github.com/OCAP2/web/internal/maptool/pbo_test.go
  • github.com/OCAP2/web/internal/maptool/pipeline_test.go
  • github.com/OCAP2/web/internal/maptool/satellite_test.go
  • github.com/OCAP2/web/internal/maptool/scanner_test.go
  • github.com/OCAP2/web/internal/maptool/styles_test.go
  • github.com/OCAP2/web/internal/maptool/tiles_test.go
  • github.com/OCAP2/web/internal/maptool/tools_test.go
  • github.com/OCAP2/web/internal/maptool/vector_test.go
  • github.com/OCAP2/web/internal/maptool/worldmeta_test.go
  • github.com/OCAP2/web/internal/maptool/wrp_data_test.go
  • github.com/OCAP2/web/internal/maptool/wrp_test.go

@fank fank merged commit f324664 into main Feb 6, 2026
2 checks passed
@fank fank deleted the feat/gradmeh-import branch February 6, 2026 16:10
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