mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 10:53:59 +00:00
fix(fires): paint aggregated heat cells warm by density, not by strongest FRP
Coloring each far-zoom cell with the ramp stop of its strongest detection turned a burning region into a blue / teal / lime mosaic: neighbouring cells flipped hue on one outlier and the cold stops did not read as fire. Cells say where it burns, so they go back to the heat-normalized score (density, night share, max FRP) on the warm end of the ramp — lime, amber, red — with the cell card accent matching. Single detections keep the full six-stop FRP ramp. Co-Authored-By: Claude Fable 5.1 <[email protected]>
This commit is contained in:
1 parent
1dad6b658a
commit
887b261195
4 files changed
+39
-15
No files matched your search
@@ -137,15 +137,33 @@ export function createModel({
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill color for an aggregated heat cell: the ramp color of its strongest
|
||||
* detection, so cells, markers and the slider legend read on one scale.
|
||||
* @param {number} maxFrp - Strongest FRP in the cell, megawatts.
|
||||
* Severity stop for an aggregated heat cell from its heat-normalized score
|
||||
* (density, night share and strongest FRP together). Cells say *where* it
|
||||
* burns, so they stay on the warm end of the ramp — lime, amber, red — and
|
||||
* read as one field instead of a per-cell mosaic; the cold stops belong to
|
||||
* single detections, which say *how hard* each one burns.
|
||||
* @param {number} normalized - 0..1 heat score (sqrt-normalized to the view).
|
||||
* @returns {{name: string, minFrp: number, color: Cesium.Color}}
|
||||
*/
|
||||
|
||||
function cellColorStop(normalized) {
|
||||
const name =
|
||||
normalized > 0.72 ? 'red' : normalized > 0.42 ? 'amber' : 'lime';
|
||||
return (
|
||||
DETECTION_COLOR_STOPS.find((stop) => stop.name === name) ||
|
||||
DETECTION_COLOR_STOPS[0]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill color for an aggregated heat cell.
|
||||
* @param {number} normalized - 0..1 heat score (see {@link cellColorStop}).
|
||||
* @param {number} alpha - Fill alpha (heat-normalized by the caller).
|
||||
* @returns {Cesium.Color}
|
||||
*/
|
||||
|
||||
function heatColor(maxFrp, alpha) {
|
||||
return frpColorStop(maxFrp).color.withAlpha(alpha);
|
||||
function heatColor(normalized, alpha) {
|
||||
return cellColorStop(normalized).color.withAlpha(alpha);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -476,14 +494,14 @@ export function createModel({
|
||||
}
|
||||
|
||||
/**
|
||||
* Cell card accent: the ramp stop of the cell's strongest detection,
|
||||
* Cell card accent: the warm severity stop of the cell's heat score,
|
||||
* mirroring heatColor.
|
||||
* @param {number} maxFrp - Strongest FRP in the cell, megawatts.
|
||||
* @param {number} normalized - 0..1 heat score.
|
||||
* @returns {string} "r, g, b" accent string.
|
||||
*/
|
||||
|
||||
function cellAccent(maxFrp) {
|
||||
return accentForSeverity(frpColorStop(maxFrp).name);
|
||||
function cellAccent(normalized) {
|
||||
return accentForSeverity(cellColorStop(normalized).name);
|
||||
}
|
||||
|
||||
/** Coordinate line like "30.512°N 75.831°E". */
|
||||
@@ -590,6 +608,7 @@ export function createModel({
|
||||
cellIntersectsBounds,
|
||||
heatScore,
|
||||
heatColor,
|
||||
cellColorStop,
|
||||
frpColorStop,
|
||||
detectionColorStop,
|
||||
frpPixelSize,
|
||||
|
||||
@@ -144,7 +144,7 @@ export function createRendering({
|
||||
const score = components.model.heatScore(cell);
|
||||
const normalized = Math.min(1, Math.sqrt(score / maxScore));
|
||||
const alpha = 0.16 + normalized * 0.5;
|
||||
const color = components.model.heatColor(cell.maxFrp, alpha);
|
||||
const color = components.model.heatColor(normalized, alpha);
|
||||
const centerLon = cell.lonCell + lod.gridDegrees / 2;
|
||||
const centerLat = cell.latCell + lod.gridDegrees / 2;
|
||||
const position = Cesium.Cartesian3.fromDegrees(centerLon, centerLat, 0);
|
||||
@@ -170,12 +170,13 @@ export function createRendering({
|
||||
});
|
||||
|
||||
// Cells arrive heat-sorted, so candidate order doubles as label priority.
|
||||
// Accent is resolved here because `normalized` only exists in this walk.
|
||||
layerState._labelCandidates.push({
|
||||
position,
|
||||
cullPosition: components.model.cellCullPosition(centerLon, centerLat),
|
||||
fire: null,
|
||||
cell,
|
||||
accent: components.model.cellAccent(cell.maxFrp),
|
||||
accent: components.model.cellAccent(normalized),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user