@mytec: iter2 tested, added heatmapfix task

This commit is contained in:
2026-01-30 09:11:15 +02:00
parent d7f1204e35
commit 3f86210706

151
RFCP-Heatmap-Fix.md Normal file
View File

@@ -0,0 +1,151 @@
# RFCP Heatmap Fix - Zoom-Dependent Intensity
## Problem
At close zoom (12-15), heatmap becomes solid yellow/orange with no gradient visible.
## Root Cause
The `intensity` values and `max` parameter aren't scaling properly with zoom level, causing saturation.
## Solution
### File: `frontend/src/components/map/Heatmap.tsx`
Replace the current implementation with this improved version:
```typescript
import { useEffect, useState } from 'react';
import { useMap } from 'react-leaflet';
import { HeatmapLayerFactory } from '@vgrid/react-leaflet-heatmap-layer';
const HeatmapLayer = HeatmapLayerFactory<[number, number, number]>();
interface HeatmapProps {
points: Array<{
lat: number;
lon: number;
rsrp: number;
siteId: string;
}>;
visible: boolean;
}
export function Heatmap({ points, visible }: HeatmapProps) {
const map = useMap();
const [mapZoom, setMapZoom] = useState(map.getZoom());
useEffect(() => {
const handleZoomEnd = () => {
setMapZoom(map.getZoom());
};
map.on('zoomend', handleZoomEnd);
return () => {
map.off('zoomend', handleZoomEnd);
};
}, [map]);
if (!visible || points.length === 0) {
return null;
}
// Zoom-dependent heatmap parameters
const getHeatmapParams = (zoom: number) => {
// Radius scales inversely with zoom
// zoom 6 (country): radius=40, blur=20
// zoom 10 (region): radius=28, blur=14
// zoom 14 (city): radius=16, blur=10
// zoom 18 (street): radius=8, blur=6
const radius = Math.max(8, Math.min(40, 50 - zoom * 2.5));
const blur = Math.max(6, Math.min(20, 30 - zoom * 1.5));
// Max intensity also scales with zoom
// Lower zoom (zoomed out) = higher max (more spread)
// Higher zoom (zoomed in) = lower max (more detail)
const maxIntensity = Math.max(0.3, Math.min(1.0, 1.2 - zoom * 0.05));
return { radius, blur, maxIntensity };
};
const { radius, blur, maxIntensity } = getHeatmapParams(mapZoom);
// Normalize RSRP to 0-1 intensity
// RSRP ranges: -120 (very weak) to -70 (excellent)
const normalizeRSRP = (rsrp: number): number => {
const minRSRP = -120;
const maxRSRP = -70;
const normalized = (rsrp - minRSRP) / (maxRSRP - minRSRP);
return Math.max(0, Math.min(1, normalized));
};
// Convert points to heatmap format: [lat, lon, intensity]
const heatmapPoints = points.map(point => [
point.lat,
point.lon,
normalizeRSRP(point.rsrp)
] as [number, number, number]);
return (
<HeatmapLayer
points={heatmapPoints}
longitudeExtractor={(p) => p[1]}
latitudeExtractor={(p) => p[0]}
intensityExtractor={(p) => p[2]}
gradient={{
0.0: '#0d47a1', // Dark Blue (very weak)
0.2: '#00bcd4', // Cyan (weak)
0.4: '#4caf50', // Green (fair)
0.6: '#ffeb3b', // Yellow (good)
0.8: '#ff9800', // Orange (strong)
1.0: '#f44336', // Red (excellent)
}}
radius={radius}
blur={blur}
max={maxIntensity} // ← KEY FIX: dynamic max
minOpacity={0.3}
/>
);
}
```
## Key Changes
1. **Dynamic `max` parameter**:
```typescript
const maxIntensity = Math.max(0.3, Math.min(1.0, 1.2 - zoom * 0.05));
```
- Zoom 6: max = 0.9 (spread out, needs higher threshold)
- Zoom 12: max = 0.6 (medium detail)
- Zoom 18: max = 0.3 (tight detail, lower threshold)
2. **Better RSRP normalization**:
```typescript
const normalized = (rsrp - minRSRP) / (maxRSRP - minRSRP);
```
- Ensures full 0-1 range is used
- Maps -120 dBm → 0.0 (blue)
- Maps -70 dBm → 1.0 (red)
3. **Clearer variable names** and comments
## Testing
After applying this fix:
1. **Zoom out (level 6-8)**: Should see smooth gradient, larger blob
2. **Zoom medium (level 10-12)**: Clear color transitions
3. **Zoom close (level 14-16)**: Should still show gradient, not solid color
4. **Very close (level 18+)**: Small detailed dots with gradient
## If Still Solid at Close Zoom
Try adjusting the `maxIntensity` formula:
```typescript
// More aggressive scaling (lower max at high zoom)
const maxIntensity = Math.max(0.2, Math.min(1.0, 1.5 - zoom * 0.08));
// Or even more aggressive
const maxIntensity = Math.max(0.15, Math.min(1.0, 2.0 - zoom * 0.1));
```
This will make the gradient more visible at close zoom levels.