Skip to content

fix(hex): render GeoJSON hex tilesets instead of 404ing on .pbf (#252) - #253

Merged
cboettig merged 1 commit into
mainfrom
fix/hex-geojson-render
Jun 17, 2026
Merged

fix(hex): render GeoJSON hex tilesets instead of 404ing on .pbf (#252)#253
cboettig merged 1 commit into
mainfrom
fix/hex-geojson-render

Conversation

@cboettig

Copy link
Copy Markdown
Member

Fixes #252.

Problem

add_hex_tile_layer only ever built a {type:'vector'} source pointed at the .pbf tile endpoint. Since mcp-data-server#181, register_hex_tiles auto-selects GeoJSON for small/single-resolution tilesets, whose .pbf endpoint deliberately 404s — so every GeoJSON hex render came up blank.

A subtlety beyond "just add a geojson source"

Branching the source type alone isn't enough. Hex fill is painted by buildFillColorExpression, which does ['match', ['get','res'], …] because the vector pyramid packs multiple H3 resolutions per tile. The GeoJSON export carries only the value columns as feature properties — no res — so reusing that paint would send every feature to the match fallback (rgba(0,0,0,0)), still blank.

So the GeoJSON branch needs a flat ramp over the finest-res stats.

Changes

  • addHexTileLayer branches on format:
    • geojsonaddSource({type:'geojson', data: geojson_url}) + fill layer with no source-layer and a flat ramp from new buildFlatFillColorExpression (built over value_stats.by_res[finest_res] + the chosen palette, so existing palette/opacity/legend wiring still applies).
    • vector → existing path, unchanged.
  • Hash still derives from tile_url_template (returned for both formats); geojson_url's shape (…/hex/<hash>/data.geojson) isn't parseable by extractHashFromUrl.
  • Tool schema gains format + geojson_url; description/prompt updated to pass them through and stop steering toward tile_url-only.

No conflict with existing GeoJSON rendering

The three other GeoJSON pipelines are isolated from the hex path and unchanged: curated catalog layers (dataset-catalog.js → generic addLayer, ids <ds>/<asset>), the h3geo.js cell overlay (fixed source id, interactive cell drawing), and animation-manager.js tracks. The hex path keeps its own hex-<hash> ids and shares no styling code, so there's no id collision or shared-state confusion.

Tests

npm test → 303 passing. Added coverage in test/hex-layer-helpers.test.js (flat ramp: structure, min==max collapse, validation) and test/map-manager.hex.test.js (geojson source shape, no source-layer, flat non-res paint, hash from tile_url, finest-res selection, missing-geojson_url error).

Browser render verification (MapLibre) is manual per the coverage policy — recommend a quick check on the padus dev app against the Yolo County hash from the issue.

🤖 Generated with Claude Code

add_hex_tile_layer only ever built a {type:'vector'} source pointed at the
.pbf tile endpoint. When register_hex_tiles auto-selects GeoJSON, that
endpoint 404s and the layer renders blank.

Branch addHexTileLayer on format:
- geojson -> {type:'geojson', data: geojson_url}, fill layer with no
  source-layer, and a *flat* fill-color ramp over the finest-res stats.
  GeoJSON features carry only value columns (no `res`), so the per-res
  `match` expression would render everything transparent — add
  buildFlatFillColorExpression for the single-resolution case.
- vector -> existing path, unchanged.

The hash still derives from tile_url_template (returned for both formats);
geojson_url's shape isn't parseable by extractHashFromUrl. Extend the tool
schema with format + geojson_url and update the prompt to pass them through.

No conflict with the other GeoJSON pipelines (curated catalog layers,
h3geo overlay, animation tracks): the hex path keeps its own hex-<hash>
ids and shares no styling code.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 49.43% 3501 / 7082
🔵 Statements 49.41% 3501 / 7085
🔵 Functions 57.4% 124 / 216
🔵 Branches 81.72% 671 / 821
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
app/hex-layer-helpers.js 100% 100% 100% 100%
app/map-manager.js 46.4% 85.71% 36.58% 46.43% 56-145, 152-156, 162-379, 388-432, 442-454, 462-474, 538-539, 556-557, 675-684, 712-713, 719-722, 731-741, 747-754, 795-798, 806-810, 813-826, 832-833, 839-842, 911-912, 932-934, 956-961, 967-970, 980-998, 1005-1009, 1017-1110, 1117-1195, 1202-1207, 1219-1265, 1289-1308, 1311-1326, 1336-1338, 1383-1390, 1424-1425, 1458-1462, 415
app/map-tools.js 96.3% 88.88% 56% 96.3% 90-92, 110-112, 447-461
Generated in workflow #100 for commit afed4a9 by the Vitest Coverage Report Action

@cboettig
cboettig merged commit 949e1c9 into main Jun 17, 2026
1 check passed
@cboettig
cboettig deleted the fix/hex-geojson-render branch June 17, 2026 05:40
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.

add_hex_tile_layer ignores format=geojson → GeoJSON hex tilesets render blank (vector source 404s)

1 participant