From cee716c0d24506e904ec2bc686f4f35a6ece5502 Mon Sep 17 00:00:00 2001 From: Robert Chacon Date: Mon, 16 Mar 2026 03:42:57 -0600 Subject: [PATCH] changes --- docs-es/v2.0/node-manager-ui-es.md | 2 +- docs/v2.0/node-manager-ui.md | 2 +- .../src/node_manager/js_build/src/flow_map.js | 14 +- .../src/node_manager/js_build/src/site_map.js | 637 +++++++++--------- .../src/node_manager/static2/node_manager.css | 4 +- 5 files changed, 335 insertions(+), 324 deletions(-) diff --git a/docs-es/v2.0/node-manager-ui-es.md b/docs-es/v2.0/node-manager-ui-es.md index 7c4c9844..e117e8ac 100644 --- a/docs-es/v2.0/node-manager-ui-es.md +++ b/docs-es/v2.0/node-manager-ui-es.md @@ -18,7 +18,7 @@ Esta página documenta las vistas clave de la WebUI (Node Manager) y su comporta - Usa un promedio del lado cliente de 30 segundos a partir de `NetworkTree`, sin agregar trabajo de rollup en el backend. - Los APs pueden heredar coordenadas del sitio padre solo para visualización cuando faltan coordenadas explícitas. - Usa un mapa base local con estilo LibreQoS con bordes de país/estado, costas, lagos principales, ríos principales, áreas marinas, superposiciones sutiles de regiones físicas y contexto de autopistas principales a mayor zoom para orientación geográfica. -- Site Map ahora distribuye localmente una superposición GRIP filtrada a mayor zoom para mejorar la orientación, mientras que las carreteras integradas de Natural Earth siguen funcionando como respaldo/contexto a menor zoom. La capa GRIP incluida se adelgaza a corredores más largos para añadir estructura reconocible sin convertir el mapa en un callejero completo. +- Site Map utiliza una capa local de carreteras derivada de Natural Earth para ayudar con la orientación, manteniendo el resto del mapa base discreto y operativo. ### Flow Globe - Visualización geográfica de flujos basada en la geolocalización de endpoints. diff --git a/docs/v2.0/node-manager-ui.md b/docs/v2.0/node-manager-ui.md index 13374c30..a35b63bf 100644 --- a/docs/v2.0/node-manager-ui.md +++ b/docs/v2.0/node-manager-ui.md @@ -18,7 +18,7 @@ This page documents key WebUI (Node Manager) views and operational behavior in t - Uses a 30-second client-side average from `NetworkTree` data rather than adding backend rollup work. - APs can inherit parent site coordinates for display when explicit AP coordinates are missing. - Uses a local LibreQoS-themed basemap with country/state borders, coastlines, major lakes, major rivers, marine areas, subtle physical-region overlays, and higher-zoom major-highway context for geographic orientation. -- Site Map now ships a locally filtered GRIP roads overlay at higher zoom for added orientation, while the built-in Natural Earth roads remain as low-zoom fallback/context. The shipped GRIP layer is thinned to longer corridor segments so the map gains recognizable structure without turning into a full street map. +- Site Map uses a local Natural Earth-derived roads layer for orientation while keeping the rest of the basemap quiet and operational. ### Flow Globe - Geographic flow visualization based on endpoint geolocation. diff --git a/src/rust/lqosd/src/node_manager/js_build/src/flow_map.js b/src/rust/lqosd/src/node_manager/js_build/src/flow_map.js index 2d1fc25f..bdf3d2f4 100644 --- a/src/rust/lqosd/src/node_manager/js_build/src/flow_map.js +++ b/src/rust/lqosd/src/node_manager/js_build/src/flow_map.js @@ -17,6 +17,8 @@ const DEFAULT_POINT_OF_VIEW = { lng: -32, altitude: 2.15, }; +const MIN_ZOOM_SPEED = 1.8; +const MAX_ZOOM_SPEED = 3.4; const FLOW_MAP_DEBUG = (() => { const params = new URLSearchParams(window.location.search); const disabled = new Set( @@ -421,7 +423,6 @@ class FlowMapGlobe { this.controls.enablePan = false; this.controls.enableDamping = false; this.controls.rotateSpeed = 0.75; - this.controls.zoomSpeed = 1.5; this.controls.minDistance = 120; this.controls.maxDistance = 420; this.controls.autoRotate = this.autoRotate; @@ -429,6 +430,7 @@ class FlowMapGlobe { this.globe.pointOfView(DEFAULT_POINT_OF_VIEW, 0); this.captureViewState(); + this.syncControlSpeeds(); this.applyTheme(); this.attachControlListeners(); } @@ -471,11 +473,13 @@ class FlowMapGlobe { } this.controls.addEventListener("start", () => { this.userInteracting = true; + this.syncControlSpeeds(); clearScheduledRefresh(); this.scheduleInteractionRelease(); }); this.controls.addEventListener("change", () => { this.captureViewState(); + this.syncControlSpeeds(); if (this.rawPayload.length > 0 && this.updateClusterRadius()) { this.scheduleRecluster(); } @@ -512,6 +516,14 @@ class FlowMapGlobe { } } + syncControlSpeeds() { + if (!this.controls) { + return; + } + const altitude = Number.isFinite(this.lastKnownAltitude) ? this.lastKnownAltitude : DEFAULT_POINT_OF_VIEW.altitude; + this.controls.zoomSpeed = Math.max(MIN_ZOOM_SPEED, Math.min(MAX_ZOOM_SPEED, 0.95 + (altitude * 0.75))); + } + currentClusterSize() { return this.activeClusterRadius; } diff --git a/src/rust/lqosd/src/node_manager/js_build/src/site_map.js b/src/rust/lqosd/src/node_manager/js_build/src/site_map.js index 5cf97e12..59a4f182 100644 --- a/src/rust/lqosd/src/node_manager/js_build/src/site_map.js +++ b/src/rust/lqosd/src/node_manager/js_build/src/site_map.js @@ -17,7 +17,6 @@ const PHYSICAL_REGIONS_GEOJSON_PATH = "vendor/site_map_physical_regions.geojson" const PHYSICAL_REGIONS_10M_GEOJSON_PATH = "vendor/site_map_physical_regions_10m.geojson"; const MARINE_AREAS_GEOJSON_PATH = "vendor/site_map_marine_areas.geojson"; const MAJOR_ROADS_10M_GEOJSON_PATH = "vendor/site_map_major_roads_10m.geojson"; -const GRIP_ROADS_GEOJSON_PATH = "vendor/site_map_grip_roads.geojson"; const INITIAL_CENTER = [-101.5, 39.8]; const INITIAL_ZOOM = 3.15; const SITE_SOURCE_ID = "site-map-sites"; @@ -31,7 +30,6 @@ const PHYSICAL_REGIONS_SOURCE_ID = "site-map-physical-regions"; const PHYSICAL_REGIONS_10M_SOURCE_ID = "site-map-physical-regions-10m"; const MARINE_AREAS_SOURCE_ID = "site-map-marine-areas"; const MAJOR_ROADS_10M_SOURCE_ID = "site-map-major-roads-10m"; -const GRIP_ROADS_SOURCE_ID = "site-map-grip-roads"; const SITE_CLUSTER_LAYER_ID = "site-map-site-clusters"; const SITE_POINTS_LAYER_ID = "site-map-site-points"; const AP_CLUSTER_LAYER_ID = "site-map-ap-clusters"; @@ -48,7 +46,6 @@ const PHYSICAL_REGIONS_10M_FILL_LAYER_ID = "site-map-physical-regions-10m-fill"; const PHYSICAL_REGIONS_10M_LINE_LAYER_ID = "site-map-physical-regions-10m-line"; const MARINE_AREAS_FILL_LAYER_ID = "site-map-marine-areas-fill"; const MAJOR_ROADS_10M_LAYER_ID = "site-map-major-roads-10m-line"; -const GRIP_ROADS_LAYER_ID = "site-map-grip-roads-line"; function listenOnceWithTimeout(eventName, timeoutMs, handler, onTimeout) { let done = false; @@ -248,6 +245,8 @@ class SiteMapPage { this.lastUpdateAt = 0; this.latestRender = null; this.unmappedOpen = false; + this.heavyLayersInstalled = false; + this.heavyLayersInstallQueued = false; this.canvas = document.getElementById("siteMapCanvas"); this.statusChip = document.getElementById("siteMapStatusChip"); @@ -311,7 +310,7 @@ class SiteMapPage { center: INITIAL_CENTER, zoom: INITIAL_ZOOM, attributionControl: false, - customAttribution: "Natural Earth, GRIP / GLOBIO (CC0)", + customAttribution: "Natural Earth", }); this.map.addControl(new window.maplibregl.NavigationControl({ visualizePitch: false }), "bottom-left"); this.map.addControl(new window.maplibregl.AttributionControl({ compact: true }), "bottom-left"); @@ -325,10 +324,11 @@ class SiteMapPage { }); this.map.on("load", () => { - this.installSourcesAndLayers(); + this.installPointSourcesAndLayers(); this.installInteractions(); this.applyTheme(); this.renderFromHistory(); + this.queueHeavyLayersInstall(); }); } @@ -370,9 +370,6 @@ class SiteMapPage { if (this.map.getLayer(MAJOR_ROADS_10M_LAYER_ID)) { this.map.setPaintProperty(MAJOR_ROADS_10M_LAYER_ID, "line-color", palette.roads); } - if (this.map.getLayer(GRIP_ROADS_LAYER_ID)) { - this.map.setPaintProperty(GRIP_ROADS_LAYER_ID, "line-color", palette.roads); - } if (this.map.getLayer(LAKES_FILL_LAYER_ID)) { this.map.setPaintProperty(LAKES_FILL_LAYER_ID, "fill-color", palette.water); } @@ -396,310 +393,7 @@ class SiteMapPage { } } - installSourcesAndLayers() { - this.map.addSource(COUNTRIES_SOURCE_ID, { - type: "geojson", - data: COUNTRIES_GEOJSON_PATH, - }); - this.map.addSource(MARINE_AREAS_SOURCE_ID, { - type: "geojson", - data: MARINE_AREAS_GEOJSON_PATH, - }); - this.map.addSource(PHYSICAL_REGIONS_SOURCE_ID, { - type: "geojson", - data: PHYSICAL_REGIONS_GEOJSON_PATH, - }); - this.map.addSource(PHYSICAL_REGIONS_10M_SOURCE_ID, { - type: "geojson", - data: PHYSICAL_REGIONS_10M_GEOJSON_PATH, - }); - this.map.addSource(MAJOR_ROADS_10M_SOURCE_ID, { - type: "geojson", - data: MAJOR_ROADS_10M_GEOJSON_PATH, - }); - this.map.addSource(GRIP_ROADS_SOURCE_ID, { - type: "geojson", - data: GRIP_ROADS_GEOJSON_PATH, - }); - this.map.addSource(LAKES_SOURCE_ID, { - type: "geojson", - data: LAKES_GEOJSON_PATH, - }); - this.map.addSource(RIVERS_SOURCE_ID, { - type: "geojson", - data: RIVERS_GEOJSON_PATH, - }); - this.map.addSource(ADMIN1_SOURCE_ID, { - type: "geojson", - data: ADMIN1_BOUNDARIES_GEOJSON_PATH, - }); - this.map.addSource(COASTLINE_SOURCE_ID, { - type: "geojson", - data: COASTLINES_GEOJSON_PATH, - }); - this.map.addLayer({ - id: MARINE_AREAS_FILL_LAYER_ID, - type: "fill", - source: MARINE_AREAS_SOURCE_ID, - paint: { - "fill-color": countryPalette().marine, - "fill-opacity": 0.9, - }, - }); - this.map.addLayer({ - id: COUNTRY_FILL_LAYER_ID, - type: "fill", - source: COUNTRIES_SOURCE_ID, - paint: { - "fill-color": countryPalette().land, - "fill-opacity": isDarkMode() ? 0.8 : 0.76, - }, - }); - this.map.addLayer({ - id: PHYSICAL_REGIONS_FILL_LAYER_ID, - type: "fill", - source: PHYSICAL_REGIONS_SOURCE_ID, - paint: { - "fill-color": countryPalette().terrain, - "fill-opacity": [ - "interpolate", ["linear"], ["zoom"], - 0, - [ - "match", ["get", "featurecla"], - "mountain range", isDarkMode() ? 0.22 : 0.15, - "mountain", isDarkMode() ? 0.18 : 0.12, - "plateau", isDarkMode() ? 0.12 : 0.08, - "basin", isDarkMode() ? 0.09 : 0.06, - "plain", isDarkMode() ? 0.06 : 0.04, - "desert", isDarkMode() ? 0.08 : 0.05, - isDarkMode() ? 0.08 : 0.05, - ], - 4.5, - [ - "match", ["get", "featurecla"], - "mountain range", isDarkMode() ? 0.18 : 0.11, - "mountain", isDarkMode() ? 0.15 : 0.09, - "plateau", isDarkMode() ? 0.08 : 0.05, - "basin", isDarkMode() ? 0.06 : 0.04, - "plain", isDarkMode() ? 0.04 : 0.02, - "desert", isDarkMode() ? 0.05 : 0.03, - isDarkMode() ? 0.05 : 0.03, - ], - 6, - 0, - ], - }, - }); - this.map.addLayer({ - id: PHYSICAL_REGIONS_LINE_LAYER_ID, - type: "line", - source: PHYSICAL_REGIONS_SOURCE_ID, - paint: { - "line-color": countryPalette().terrain, - "line-width": [ - "interpolate", ["linear"], ["zoom"], - 2, 0.18, - 5, 0.3, - 8, 0.46, - ], - "line-opacity": [ - "interpolate", ["linear"], ["zoom"], - 0, 0.05, - 4.5, 0.08, - 6, 0.03, - 7, 0, - ], - }, - }); - this.map.addLayer({ - id: PHYSICAL_REGIONS_10M_FILL_LAYER_ID, - type: "fill", - source: PHYSICAL_REGIONS_10M_SOURCE_ID, - minzoom: 4.5, - paint: { - "fill-color": countryPalette().terrain, - "fill-opacity": [ - "interpolate", ["linear"], ["zoom"], - 4.5, - 0, - 5.5, - [ - "match", ["get", "featurecla"], - "mountain range", isDarkMode() ? 0.24 : 0.16, - "mountain", isDarkMode() ? 0.2 : 0.13, - "plateau", isDarkMode() ? 0.12 : 0.08, - "basin", isDarkMode() ? 0.09 : 0.06, - "plain", isDarkMode() ? 0.05 : 0.03, - "desert", isDarkMode() ? 0.07 : 0.05, - isDarkMode() ? 0.07 : 0.05, - ], - 8, - [ - "match", ["get", "featurecla"], - "mountain range", isDarkMode() ? 0.28 : 0.19, - "mountain", isDarkMode() ? 0.24 : 0.16, - "plateau", isDarkMode() ? 0.15 : 0.1, - "basin", isDarkMode() ? 0.11 : 0.08, - "plain", isDarkMode() ? 0.07 : 0.05, - "desert", isDarkMode() ? 0.09 : 0.06, - isDarkMode() ? 0.09 : 0.06, - ], - ], - }, - }); - this.map.addLayer({ - id: PHYSICAL_REGIONS_10M_LINE_LAYER_ID, - type: "line", - source: PHYSICAL_REGIONS_10M_SOURCE_ID, - minzoom: 4.5, - paint: { - "line-color": countryPalette().terrain, - "line-width": [ - "interpolate", ["linear"], ["zoom"], - 4.5, 0.18, - 6, 0.34, - 8, 0.5, - ], - "line-opacity": [ - "interpolate", ["linear"], ["zoom"], - 4.5, 0, - 5.5, 0.05, - 8, 0.1, - ], - }, - }); - this.map.addLayer({ - id: MAJOR_ROADS_10M_LAYER_ID, - type: "line", - source: MAJOR_ROADS_10M_SOURCE_ID, - minzoom: 5.5, - paint: { - "line-color": countryPalette().roads, - "line-width": [ - "interpolate", ["linear"], ["zoom"], - 5.5, 0.3, - 7, 0.55, - 9, 0.95, - ], - "line-opacity": [ - "interpolate", ["linear"], ["zoom"], - 5.5, 0, - 6.5, isDarkMode() ? 0.18 : 0.14, - 9, isDarkMode() ? 0.28 : 0.22, - ], - }, - }); - this.map.addLayer({ - id: GRIP_ROADS_LAYER_ID, - type: "line", - source: GRIP_ROADS_SOURCE_ID, - minzoom: 5.5, - paint: { - "line-color": countryPalette().roads, - "line-width": [ - "interpolate", ["linear"], ["zoom"], - 5.5, 0.4, - 7.5, 0.8, - 10, 1.35, - ], - "line-opacity": [ - "interpolate", ["linear"], ["zoom"], - 5.5, 0, - 6.25, isDarkMode() ? 0.18 : 0.14, - 8, isDarkMode() ? 0.3 : 0.24, - 10, isDarkMode() ? 0.42 : 0.34, - ], - }, - }); - this.map.setPaintProperty(MAJOR_ROADS_10M_LAYER_ID, "line-opacity", [ - "interpolate", ["linear"], ["zoom"], - 0, 0, - 4.5, isDarkMode() ? 0.1 : 0.08, - 5.5, isDarkMode() ? 0.14 : 0.1, - 6.25, 0, - ]); - this.map.addLayer({ - id: LAKES_FILL_LAYER_ID, - type: "fill", - source: LAKES_SOURCE_ID, - paint: { - "fill-color": countryPalette().water, - "fill-opacity": 0.92, - }, - }); - this.map.addLayer({ - id: RIVERS_LINE_LAYER_ID, - type: "line", - source: RIVERS_SOURCE_ID, - paint: { - "line-color": countryPalette().rivers, - "line-width": [ - "interpolate", ["linear"], ["zoom"], - 2, 0.22, - 5, 0.4, - 8, 0.62, - ], - "line-opacity": [ - "interpolate", ["linear"], ["zoom"], - 2, 0.42, - 5, 0.34, - 8, 0.28, - ], - }, - }); - this.map.addLayer({ - id: ADMIN1_LINE_LAYER_ID, - type: "line", - source: ADMIN1_SOURCE_ID, - paint: { - "line-color": countryPalette().admin1, - "line-width": [ - "interpolate", ["linear"], ["zoom"], - 2, 0.34, - 5, 0.58, - 8, 0.95, - ], - "line-opacity": [ - "interpolate", ["linear"], ["zoom"], - 0, 0.3, - 3, 0.46, - 5.5, 0.6, - 7, 0.52, - 9, 0.42, - ], - }, - }); - this.map.addLayer({ - id: COUNTRY_LINE_LAYER_ID, - type: "line", - source: COUNTRIES_SOURCE_ID, - paint: { - "line-color": countryPalette().borders, - "line-width": [ - "interpolate", ["linear"], ["zoom"], - 2, 0.5, - 5, 0.8, - 8, 1.2, - ], - "line-opacity": 0.9, - }, - }); - this.map.addLayer({ - id: COASTLINE_LAYER_ID, - type: "line", - source: COASTLINE_SOURCE_ID, - paint: { - "line-color": countryPalette().coast, - "line-width": [ - "interpolate", ["linear"], ["zoom"], - 2, 0.45, - 5, 0.8, - 8, 1.25, - ], - "line-opacity": 0.82, - }, - }); - + installPointSourcesAndLayers() { this.map.addSource(SITE_SOURCE_ID, { type: "geojson", data: { type: "FeatureCollection", features: [] }, @@ -803,6 +497,311 @@ class SiteMapPage { }); } + installHeavyGeographyLayers() { + if (this.heavyLayersInstalled || !this.map?.isStyleLoaded()) { + return; + } + + const addLayerBelowPoints = (layer) => this.map.addLayer(layer, SITE_CLUSTER_LAYER_ID); + + this.map.addSource(COUNTRIES_SOURCE_ID, { + type: "geojson", + data: COUNTRIES_GEOJSON_PATH, + }); + this.map.addSource(MARINE_AREAS_SOURCE_ID, { + type: "geojson", + data: MARINE_AREAS_GEOJSON_PATH, + }); + this.map.addSource(PHYSICAL_REGIONS_SOURCE_ID, { + type: "geojson", + data: PHYSICAL_REGIONS_GEOJSON_PATH, + }); + this.map.addSource(PHYSICAL_REGIONS_10M_SOURCE_ID, { + type: "geojson", + data: PHYSICAL_REGIONS_10M_GEOJSON_PATH, + }); + this.map.addSource(MAJOR_ROADS_10M_SOURCE_ID, { + type: "geojson", + data: MAJOR_ROADS_10M_GEOJSON_PATH, + }); + this.map.addSource(LAKES_SOURCE_ID, { + type: "geojson", + data: LAKES_GEOJSON_PATH, + }); + this.map.addSource(RIVERS_SOURCE_ID, { + type: "geojson", + data: RIVERS_GEOJSON_PATH, + }); + this.map.addSource(ADMIN1_SOURCE_ID, { + type: "geojson", + data: ADMIN1_BOUNDARIES_GEOJSON_PATH, + }); + this.map.addSource(COASTLINE_SOURCE_ID, { + type: "geojson", + data: COASTLINES_GEOJSON_PATH, + }); + + addLayerBelowPoints({ + id: MARINE_AREAS_FILL_LAYER_ID, + type: "fill", + source: MARINE_AREAS_SOURCE_ID, + paint: { + "fill-color": countryPalette().marine, + "fill-opacity": 0.9, + }, + }); + addLayerBelowPoints({ + id: COUNTRY_FILL_LAYER_ID, + type: "fill", + source: COUNTRIES_SOURCE_ID, + paint: { + "fill-color": countryPalette().land, + "fill-opacity": isDarkMode() ? 0.8 : 0.76, + }, + }); + addLayerBelowPoints({ + id: PHYSICAL_REGIONS_FILL_LAYER_ID, + type: "fill", + source: PHYSICAL_REGIONS_SOURCE_ID, + paint: { + "fill-color": countryPalette().terrain, + "fill-opacity": [ + "interpolate", ["linear"], ["zoom"], + 0, + [ + "match", ["get", "featurecla"], + "mountain range", isDarkMode() ? 0.22 : 0.15, + "mountain", isDarkMode() ? 0.18 : 0.12, + "plateau", isDarkMode() ? 0.12 : 0.08, + "basin", isDarkMode() ? 0.09 : 0.06, + "plain", isDarkMode() ? 0.06 : 0.04, + "desert", isDarkMode() ? 0.08 : 0.05, + isDarkMode() ? 0.08 : 0.05, + ], + 4.5, + [ + "match", ["get", "featurecla"], + "mountain range", isDarkMode() ? 0.18 : 0.11, + "mountain", isDarkMode() ? 0.15 : 0.09, + "plateau", isDarkMode() ? 0.08 : 0.05, + "basin", isDarkMode() ? 0.06 : 0.04, + "plain", isDarkMode() ? 0.04 : 0.02, + "desert", isDarkMode() ? 0.05 : 0.03, + isDarkMode() ? 0.05 : 0.03, + ], + 6, + 0, + ], + }, + }); + addLayerBelowPoints({ + id: PHYSICAL_REGIONS_LINE_LAYER_ID, + type: "line", + source: PHYSICAL_REGIONS_SOURCE_ID, + paint: { + "line-color": countryPalette().terrain, + "line-width": [ + "interpolate", ["linear"], ["zoom"], + 2, 0.18, + 5, 0.3, + 8, 0.46, + ], + "line-opacity": [ + "interpolate", ["linear"], ["zoom"], + 0, 0.05, + 4.5, 0.08, + 6, 0.03, + 7, 0, + ], + }, + }); + addLayerBelowPoints({ + id: PHYSICAL_REGIONS_10M_FILL_LAYER_ID, + type: "fill", + source: PHYSICAL_REGIONS_10M_SOURCE_ID, + minzoom: 4.5, + paint: { + "fill-color": countryPalette().terrain, + "fill-opacity": [ + "interpolate", ["linear"], ["zoom"], + 4.5, + 0, + 5.5, + [ + "match", ["get", "featurecla"], + "mountain range", isDarkMode() ? 0.24 : 0.16, + "mountain", isDarkMode() ? 0.2 : 0.13, + "plateau", isDarkMode() ? 0.12 : 0.08, + "basin", isDarkMode() ? 0.09 : 0.06, + "plain", isDarkMode() ? 0.05 : 0.03, + "desert", isDarkMode() ? 0.07 : 0.05, + isDarkMode() ? 0.07 : 0.05, + ], + 8, + [ + "match", ["get", "featurecla"], + "mountain range", isDarkMode() ? 0.28 : 0.19, + "mountain", isDarkMode() ? 0.24 : 0.16, + "plateau", isDarkMode() ? 0.15 : 0.1, + "basin", isDarkMode() ? 0.11 : 0.08, + "plain", isDarkMode() ? 0.07 : 0.05, + "desert", isDarkMode() ? 0.09 : 0.06, + isDarkMode() ? 0.09 : 0.06, + ], + ], + }, + }); + addLayerBelowPoints({ + id: PHYSICAL_REGIONS_10M_LINE_LAYER_ID, + type: "line", + source: PHYSICAL_REGIONS_10M_SOURCE_ID, + minzoom: 4.5, + paint: { + "line-color": countryPalette().terrain, + "line-width": [ + "interpolate", ["linear"], ["zoom"], + 4.5, 0.18, + 6, 0.34, + 8, 0.5, + ], + "line-opacity": [ + "interpolate", ["linear"], ["zoom"], + 4.5, 0, + 5.5, 0.05, + 8, 0.1, + ], + }, + }); + addLayerBelowPoints({ + id: MAJOR_ROADS_10M_LAYER_ID, + type: "line", + source: MAJOR_ROADS_10M_SOURCE_ID, + minzoom: 5.5, + paint: { + "line-color": countryPalette().roads, + "line-width": [ + "interpolate", ["linear"], ["zoom"], + 5.5, 0.3, + 7, 0.55, + 9, 0.95, + ], + "line-opacity": [ + "interpolate", ["linear"], ["zoom"], + 5.5, 0, + 6.5, isDarkMode() ? 0.18 : 0.14, + 9, isDarkMode() ? 0.28 : 0.22, + ], + }, + }); + this.map.setPaintProperty(MAJOR_ROADS_10M_LAYER_ID, "line-opacity", [ + "interpolate", ["linear"], ["zoom"], + 0, 0, + 4.5, isDarkMode() ? 0.1 : 0.08, + 5.5, isDarkMode() ? 0.14 : 0.1, + 6.25, 0, + ]); + addLayerBelowPoints({ + id: LAKES_FILL_LAYER_ID, + type: "fill", + source: LAKES_SOURCE_ID, + paint: { + "fill-color": countryPalette().water, + "fill-opacity": 0.92, + }, + }); + addLayerBelowPoints({ + id: RIVERS_LINE_LAYER_ID, + type: "line", + source: RIVERS_SOURCE_ID, + paint: { + "line-color": countryPalette().rivers, + "line-width": [ + "interpolate", ["linear"], ["zoom"], + 2, 0.22, + 5, 0.4, + 8, 0.62, + ], + "line-opacity": [ + "interpolate", ["linear"], ["zoom"], + 2, 0.42, + 5, 0.34, + 8, 0.28, + ], + }, + }); + addLayerBelowPoints({ + id: ADMIN1_LINE_LAYER_ID, + type: "line", + source: ADMIN1_SOURCE_ID, + paint: { + "line-color": countryPalette().admin1, + "line-width": [ + "interpolate", ["linear"], ["zoom"], + 2, 0.34, + 5, 0.58, + 8, 0.95, + ], + "line-opacity": [ + "interpolate", ["linear"], ["zoom"], + 0, 0.3, + 3, 0.46, + 5.5, 0.6, + 7, 0.52, + 9, 0.42, + ], + }, + }); + addLayerBelowPoints({ + id: COUNTRY_LINE_LAYER_ID, + type: "line", + source: COUNTRIES_SOURCE_ID, + paint: { + "line-color": countryPalette().borders, + "line-width": [ + "interpolate", ["linear"], ["zoom"], + 2, 0.5, + 5, 0.8, + 8, 1.2, + ], + "line-opacity": 0.9, + }, + }); + addLayerBelowPoints({ + id: COASTLINE_LAYER_ID, + type: "line", + source: COASTLINE_SOURCE_ID, + paint: { + "line-color": countryPalette().coast, + "line-width": [ + "interpolate", ["linear"], ["zoom"], + 2, 0.45, + 5, 0.8, + 8, 1.25, + ], + "line-opacity": 0.82, + }, + }); + + this.heavyLayersInstalled = true; + this.applyTheme(); + } + + queueHeavyLayersInstall() { + if (this.heavyLayersInstalled || this.heavyLayersInstallQueued) { + return; + } + this.heavyLayersInstallQueued = true; + const install = () => { + this.heavyLayersInstallQueued = false; + this.installHeavyGeographyLayers(); + }; + if (typeof window.requestIdleCallback === "function") { + window.requestIdleCallback(install, { timeout: 1200 }); + return; + } + window.setTimeout(install, 0); + } + installInteractions() { const pointLayers = [SITE_POINTS_LAYER_ID, AP_POINTS_LAYER_ID]; const clusterLayers = [SITE_CLUSTER_LAYER_ID, AP_CLUSTER_LAYER_ID]; @@ -875,15 +874,15 @@ class SiteMapPage { requestInitialTree() { this.setStatus("Waiting for data", "spinner"); + if (!this.subscription) { + this.subscription = subscribeWS(["NetworkTree"], (liveMsg) => { + if (liveMsg.event === "NetworkTree") { + this.processTreeMessage(liveMsg); + } + }); + } listenOnceWithTimeout("NetworkTree", INITIAL_REQUEST_TIMEOUT_MS, (msg) => { this.processTreeMessage(msg); - if (!this.subscription) { - this.subscription = subscribeWS(["NetworkTree"], (liveMsg) => { - if (liveMsg.event === "NetworkTree") { - this.processTreeMessage(liveMsg); - } - }); - } }, () => { this.setStatus("No data received yet", "warning"); }); diff --git a/src/rust/lqosd/src/node_manager/static2/node_manager.css b/src/rust/lqosd/src/node_manager/static2/node_manager.css index 5bb3100c..31d5a0b5 100644 --- a/src/rust/lqosd/src/node_manager/static2/node_manager.css +++ b/src/rust/lqosd/src/node_manager/static2/node_manager.css @@ -91,10 +91,10 @@ body::before { padding: 12px; } } -.lqos_logo { +html[data-bs-theme="light"] .lqos_logo { filter: invert(100%); } -.dark-mode .lqos_logo { +html[data-bs-theme="dark"] .lqos_logo { filter: none; } .sidebar {