From 79a4c99672127e753615b059401454982a239b75 Mon Sep 17 00:00:00 2001 From: hawc2 Date: Thu, 2 Jul 2026 10:39:18 -0400 Subject: [PATCH] lift the network lines off the ground --- js/layers/network-layers.js | 24 ++++++++++++++++++++++++ js/map-init.js | 6 ++++++ 2 files changed, 30 insertions(+) diff --git a/js/layers/network-layers.js b/js/layers/network-layers.js index 61a6402..d0f4ab8 100644 --- a/js/layers/network-layers.js +++ b/js/layers/network-layers.js @@ -64,6 +64,18 @@ export const loadNetworkPoints = async () => { }; export const loadNetworkLayers = () => { + // Lift the connection lines off the ground so they read as 3D alongside the + // building-elevated point icons (which use `symbol-z-elevate`). Mapbox has no + // line equivalent that auto-snaps to building height, so this is a single + // constant offset (meters) rather than a per-endpoint match — good enough to + // stop the lines lying flat on the street. Requires `line-elevation-reference` + // to be set; both props need mapbox-gl >= 3.8 (we're on 3.17). Tune per level + // if high-site links want more lift than rooftop/mesh links. The paint + // blocks below set `line-emissive-strength` so the lifted lines stay bright + // above the shaded 3D buildings instead of going dim. + // NOTE: requires the mercator projection (set in map-init.js) — `line-z-offset` + // is silently ignored under Mapbox's default globe projection. + const LINE_Z_OFFSET_M = 35; // Level 1 loadNetworkLayer('/get_level1', 'line').then(() => { const animationLineId = 'highsite-line'; @@ -73,12 +85,15 @@ export const loadNetworkLayers = () => { id: animationLineId, layout: { visibility: 'none', + 'line-elevation-reference': 'ground', + 'line-z-offset': LINE_Z_OFFSET_M, }, minzoom: 13, paint: { 'line-color': 'lime', 'line-width': 2, 'line-opacity': 0.65, + 'line-emissive-strength': 1, }, }); const cb = bindCheckboxAnimation(animationLineId, 'toggleNetworkLinks'); @@ -94,12 +109,15 @@ export const loadNetworkLayers = () => { id: animationLineId, layout: { visibility: 'none', + 'line-elevation-reference': 'ground', + 'line-z-offset': LINE_Z_OFFSET_M, }, minzoom: 13, paint: { 'line-color': 'magenta', 'line-width': 4, 'line-opacity': 0.65, + 'line-emissive-strength': 1, }, }); const cb = bindCheckboxAnimation(animationLineId, 'toggleNetworkLinks2'); @@ -115,12 +133,15 @@ export const loadNetworkLayers = () => { id: animationLineId, layout: { visibility: 'none', + 'line-elevation-reference': 'ground', + 'line-z-offset': LINE_Z_OFFSET_M, }, minzoom: 13, paint: { 'line-color': 'yellow', 'line-width': 4, 'line-opacity': 0.65, + 'line-emissive-strength': 1, }, }); const cb = bindCheckboxAnimation(animationLineId, 'toggleNetworkLinks3'); @@ -136,12 +157,15 @@ export const loadNetworkLayers = () => { id: animationLineId, layout: { visibility: 'none', + 'line-elevation-reference': 'ground', + 'line-z-offset': LINE_Z_OFFSET_M, }, minzoom: 13, paint: { 'line-color': '#0800ff', 'line-width': 4, 'line-opacity': 0.65, + 'line-emissive-strength': 1, }, }); const cb = bindCheckboxAnimation(animationLineId, 'toggleNetworkLinks4'); diff --git a/js/map-init.js b/js/map-init.js index c330174..4e8178b 100644 --- a/js/map-init.js +++ b/js/map-init.js @@ -43,6 +43,12 @@ export default () => { window.map = new mapboxgl.Map({ container: 'map', style: 'mapbox://styles/mapbox/streets-v12', + // Mapbox GL JS v3 defaults to the globe projection, and `line-z-offset` + // (used to elevate the connection lines in network-layers.js) is "not + // supported for globe projection" — it is silently ignored there. Mercator + // is required for the elevated lines to render. The map is always viewed at + // city zoom levels, where globe and mercator look identical anyway. + projection: 'mercator', zoom: map_zoom, center: map_center, pitch: 0,