@mytec: iter10.3.1 ready for testing
This commit is contained in:
@@ -380,6 +380,7 @@ export default function App() {
|
||||
visible={heatmapVisible}
|
||||
opacity={settings.heatmapOpacity}
|
||||
radiusMeters={settings.heatmapRadius}
|
||||
rsrpThreshold={settings.rsrpThreshold}
|
||||
/>
|
||||
<CoverageBoundary
|
||||
points={coverageResult.points}
|
||||
|
||||
@@ -24,6 +24,7 @@ interface GeographicHeatmapProps {
|
||||
visible: boolean;
|
||||
opacity?: number;
|
||||
radiusMeters?: number;
|
||||
rsrpThreshold?: number;
|
||||
}
|
||||
|
||||
export default function GeographicHeatmap({
|
||||
@@ -31,6 +32,7 @@ export default function GeographicHeatmap({
|
||||
visible,
|
||||
opacity = 0.7,
|
||||
radiusMeters = 400,
|
||||
rsrpThreshold = -100,
|
||||
}: GeographicHeatmapProps) {
|
||||
const map = useMap();
|
||||
const layerRef = useRef<L.GridLayer | null>(null);
|
||||
@@ -53,7 +55,12 @@ export default function GeographicHeatmap({
|
||||
rendererRef.current.setRadiusMeters(radiusMeters);
|
||||
}, [radiusMeters]);
|
||||
|
||||
// Invalidate cache when points change (use length + first/last coords as fingerprint)
|
||||
// Update renderer threshold when prop changes
|
||||
useEffect(() => {
|
||||
rendererRef.current.setRsrpThreshold(rsrpThreshold);
|
||||
}, [rsrpThreshold]);
|
||||
|
||||
// Invalidate cache when points or threshold change
|
||||
useEffect(() => {
|
||||
if (points.length === 0) {
|
||||
rendererRef.current.setPointsHash('empty');
|
||||
@@ -61,9 +68,9 @@ export default function GeographicHeatmap({
|
||||
}
|
||||
const first = points[0];
|
||||
const last = points[points.length - 1];
|
||||
const hash = `${points.length}:${first.lat.toFixed(4)},${first.lon.toFixed(4)}:${last.rsrp}`;
|
||||
const hash = `${points.length}:${first.lat.toFixed(4)},${first.lon.toFixed(4)}:${last.rsrp}:t${rsrpThreshold}`;
|
||||
rendererRef.current.setPointsHash(hash);
|
||||
}, [points]);
|
||||
}, [points, rsrpThreshold]);
|
||||
|
||||
// Create / destroy GridLayer
|
||||
const createLayer = useCallback(() => {
|
||||
|
||||
@@ -34,6 +34,7 @@ export interface HeatmapPoint {
|
||||
export class HeatmapTileRenderer {
|
||||
private tileSize = 256;
|
||||
private radiusMeters: number;
|
||||
private rsrpThreshold: number;
|
||||
|
||||
// LRU cache: key → canvas
|
||||
private cache = new Map<string, ImageData>();
|
||||
@@ -42,9 +43,10 @@ export class HeatmapTileRenderer {
|
||||
// Points fingerprint for cache invalidation
|
||||
private pointsHash = '';
|
||||
|
||||
constructor(radiusMeters = 400, maxCacheSize = 150) {
|
||||
constructor(radiusMeters = 400, maxCacheSize = 150, rsrpThreshold = -100) {
|
||||
this.radiusMeters = radiusMeters;
|
||||
this.maxCacheSize = maxCacheSize;
|
||||
this.rsrpThreshold = rsrpThreshold;
|
||||
}
|
||||
|
||||
/** Update the geographic radius of each coverage point. */
|
||||
@@ -55,6 +57,14 @@ export class HeatmapTileRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
/** Update the RSRP threshold — points below this are not rendered. */
|
||||
setRsrpThreshold(threshold: number): void {
|
||||
if (threshold !== this.rsrpThreshold) {
|
||||
this.rsrpThreshold = threshold;
|
||||
this.clearCache();
|
||||
}
|
||||
}
|
||||
|
||||
/** Call when points change to invalidate cache. */
|
||||
setPointsHash(hash: string): void {
|
||||
if (hash !== this.pointsHash) {
|
||||
@@ -105,9 +115,10 @@ export class HeatmapTileRenderer {
|
||||
// still contribute their gaussian tail inside the tile
|
||||
const bufferDeg = (this.radiusMeters / 111_000) * 2;
|
||||
|
||||
// Filter relevant points
|
||||
// Filter relevant points — geographic bounds AND RSRP threshold
|
||||
const relevant = points.filter(
|
||||
(p) =>
|
||||
p.rsrp >= this.rsrpThreshold &&
|
||||
p.lat >= latMin - bufferDeg &&
|
||||
p.lat <= latMax + bufferDeg &&
|
||||
p.lon >= lonMin - bufferDeg &&
|
||||
|
||||
Reference in New Issue
Block a user