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:
@@ -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');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user