fix: use coverage circles instead of heatmap layer

Replace heatmap layer with concentric circle layers around scanner
positions. This avoids the z-index issue where heatmap appeared at
floor 0 below all markers.

Shows three coverage rings:
- Green inner (good signal ~5m)
- Yellow middle (fair signal ~10m)
- Red outer (weak signal ~15m)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
User
2026-02-01 10:39:20 +01:00
parent 24de6c7f06
commit 4b4cc47e67

View File

@@ -2556,6 +2556,7 @@ function toggleHeatMap() {
}
// Render heat map layer on 3D map
// Uses circle layers for scanner coverage visualization
async function renderHeatMap() {
if (!map3d || !map3dLoaded) {
console.log('[HeatMap] 3D map not ready');
@@ -2572,12 +2573,15 @@ async function renderHeatMap() {
// Remove existing heat map if present
removeHeatMap();
// Add heat map source
// Filter to scanner positions only (weight=1.0 indicates scanners)
const scannerPoints = data.points.filter(p => p.weight >= 0.9);
// Add coverage circles source
map3d.addSource('signal-heatmap', {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: data.points.map(p => ({
features: scannerPoints.map(p => ({
type: 'Feature',
geometry: { type: 'Point', coordinates: [p.lon, p.lat] },
properties: { weight: p.weight }
@@ -2585,24 +2589,42 @@ async function renderHeatMap() {
}
});
// Add heat map layer
// Add outer coverage ring (weak signal ~15m)
map3d.addLayer({
id: 'signal-heatmap-layer',
type: 'heatmap',
id: 'signal-heatmap-outer',
type: 'circle',
source: 'signal-heatmap',
paint: {
'heatmap-weight': ['get', 'weight'],
'heatmap-intensity': 0.6,
'heatmap-radius': 40,
'heatmap-opacity': 0.6,
'heatmap-color': [
'interpolate', ['linear'], ['heatmap-density'],
0, 'rgba(0,0,255,0)',
0.3, 'rgba(0,255,255,0.5)',
0.5, 'rgba(0,255,0,0.6)',
0.7, 'rgba(255,255,0,0.7)',
1, 'rgba(255,0,0,0.8)'
]
'circle-radius': 80,
'circle-color': 'rgba(255, 100, 100, 0.15)',
'circle-stroke-width': 1,
'circle-stroke-color': 'rgba(255, 100, 100, 0.3)'
}
});
// Add middle coverage ring (fair signal ~10m)
map3d.addLayer({
id: 'signal-heatmap-middle',
type: 'circle',
source: 'signal-heatmap',
paint: {
'circle-radius': 50,
'circle-color': 'rgba(255, 255, 100, 0.2)',
'circle-stroke-width': 1,
'circle-stroke-color': 'rgba(255, 255, 100, 0.4)'
}
});
// Add inner coverage ring (good signal ~5m)
map3d.addLayer({
id: 'signal-heatmap-inner',
type: 'circle',
source: 'signal-heatmap',
paint: {
'circle-radius': 25,
'circle-color': 'rgba(100, 255, 100, 0.25)',
'circle-stroke-width': 1,
'circle-stroke-color': 'rgba(100, 255, 100, 0.5)'
}
});
} catch (e) {
@@ -2614,9 +2636,13 @@ async function renderHeatMap() {
function removeHeatMap() {
if (!map3d) return;
if (map3d.getLayer('signal-heatmap-layer')) {
map3d.removeLayer('signal-heatmap-layer');
}
// Remove all heatmap layers
['signal-heatmap-inner', 'signal-heatmap-middle', 'signal-heatmap-outer', 'signal-heatmap-layer'].forEach(layerId => {
if (map3d.getLayer(layerId)) {
map3d.removeLayer(layerId);
}
});
if (map3d.getSource('signal-heatmap')) {
map3d.removeSource('signal-heatmap');
}