mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 10:53:59 +00:00
Merge upstream/main: air-quality layer (AQHI) meets i18n
Upstream's #568 adds the Air quality layer to the Weather group (ECCC AQHI, Canada only) with a band legend, worst-first list and voice support. - package-boundaries: both sides' entries unioned. - layerPanel/weatherPanel tests: both sides' new tests kept; the weatherPanel fixture follows upstream (legendCategorical: true, the 'list' block id) while our localized-history (K-6) test stays. - air-quality strings marked: band labels and the provider label as msg() data, the readings-list aria-label through t(); es/ru entries added (+6 keys each). - The synthetic air-quality allocation-benchmark titles follow the file's own convention (// i18n-ignore) like TRK/VESSEL/CAMERA. Also verified the auto-merged weatherPanel.js against upstream: ORDER gains 'air-quality', OBSERVED stays slice(2, 5), and the data-driven legendCategorical path is upstream's. npm run i18n: complete (2559), no unmarked strings. npm test: only the pre-existing environmental OPENAI_API_KEY leak fails. Build passes.
This commit is contained in:
commit
f3da0916d9
38 files changed
+2061
-62
No files matched your search
@@ -26,6 +26,12 @@ import {
|
||||
TRACKED_OVERLAY_SOURCE_OPTIONS,
|
||||
} from '../data/trackedReadout.js';
|
||||
import { CCTV_AMBIENT_CARD_MAX } from '../data/cctvLod.js';
|
||||
import {
|
||||
AIR_QUALITY_OVERLAY_COHORT_LIMIT,
|
||||
AIR_QUALITY_OVERLAY_COLLISION_CAPACITY,
|
||||
AIR_QUALITY_OVERLAY_SOURCE_ID,
|
||||
createAirQualityOverlayEntry,
|
||||
} from '../layers/airQuality/model.js';
|
||||
import {
|
||||
CCTV_OVERLAY_SOURCE_ID,
|
||||
createCctvThumbnailOverlayEntry,
|
||||
@@ -1110,6 +1116,69 @@ function buildSubmarineCablesWorkload(count) {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The air-quality station cohort at full size.
|
||||
*
|
||||
* Measured standalone (the submarine-cable precedent) rather than stacked on
|
||||
* the Phase-5 host: air-quality stations are sparse and, with the single
|
||||
* currently-registered provider, continental — so the question a budget has to
|
||||
* answer is what its own cohort costs, not what it adds to a worldwide worst
|
||||
* case it never shares a viewport with. The entry shape is the same static
|
||||
* `ambient-label` the earthquake layer publishes, so the per-candidate ceiling
|
||||
* is the meaningful gate.
|
||||
*/
|
||||
function buildAirQualityWorkload(count) {
|
||||
if (count !== AIR_QUALITY_OVERLAY_COHORT_LIMIT) {
|
||||
throw new Error(
|
||||
`air-quality requires ${AIR_QUALITY_OVERLAY_COHORT_LIMIT} entries`,
|
||||
);
|
||||
}
|
||||
const workload = {
|
||||
entries: [],
|
||||
positions: [],
|
||||
drifts: [],
|
||||
registrations: [],
|
||||
};
|
||||
const columns = Math.max(1, Math.ceil(Math.sqrt((count * 16) / 9)));
|
||||
const rows = Math.max(1, Math.ceil(count / columns));
|
||||
const spanX = columns > 1 ? 1.68 / (columns - 1) : 0;
|
||||
const spanY = rows > 1 ? 1.56 / (rows - 1) : 0;
|
||||
const stations = [];
|
||||
for (let index = 0; index < count; index++) {
|
||||
const column = index % columns;
|
||||
const row = Math.floor(index / columns);
|
||||
const baseX = -0.84 + column * spanX;
|
||||
const baseY = -0.78 + row * spanY;
|
||||
const position = new Cesium.Cartesian3(baseX, baseY, 0);
|
||||
workload.positions.push(position);
|
||||
workload.drifts.push({
|
||||
baseX,
|
||||
baseY,
|
||||
phase: index * 0.27,
|
||||
rate: 0.32 + (index % 6) * 0.04,
|
||||
});
|
||||
const entry = createAirQualityOverlayEntry({
|
||||
id: `air-${index}`,
|
||||
position,
|
||||
// i18n-ignore: synthetic allocation-benchmark fixture, not shown as UI
|
||||
title: `Station ${index} ${1 + (index % 10)}`,
|
||||
accent: '#4cc9f0',
|
||||
value: 1 + (index % 10),
|
||||
});
|
||||
entry.horizonCull = false;
|
||||
stations.push(entry);
|
||||
}
|
||||
workload.registrations.push({
|
||||
sourceId: AIR_QUALITY_OVERLAY_SOURCE_ID,
|
||||
entries: stations,
|
||||
options: {
|
||||
cohortLimit: AIR_QUALITY_OVERLAY_COHORT_LIMIT,
|
||||
collisionCapacity: AIR_QUALITY_OVERLAY_COLLISION_CAPACITY,
|
||||
},
|
||||
});
|
||||
return workload;
|
||||
}
|
||||
|
||||
function buildPhase6DetectionWorkload(count) {
|
||||
const random = makeRandom(0xd37ec710);
|
||||
const positions = [];
|
||||
@@ -1215,9 +1284,13 @@ function main() {
|
||||
? buildPhase5RocketMissionWorkload(ENTRY_COUNT)
|
||||
: PROFILE === 'all-live-radio'
|
||||
? buildAllLiveRadioWorkload(ENTRY_COUNT)
|
||||
: PROFILE === 'submarine-cables'
|
||||
? buildSubmarineCablesWorkload(ENTRY_COUNT)
|
||||
: buildWorkload(ENTRY_COUNT);
|
||||
: PROFILE === 'air-quality'
|
||||
? buildAirQualityWorkload(ENTRY_COUNT)
|
||||
: PROFILE === 'submarine-cables'
|
||||
? buildSubmarineCablesWorkload(
|
||||
ENTRY_COUNT,
|
||||
)
|
||||
: buildWorkload(ENTRY_COUNT);
|
||||
const { entries, positions, drifts } = workload;
|
||||
const solveIntervalMs = Number(process.env.GEV_ALLOC_SOLVE_MS) || 125;
|
||||
const detectionActive = !!workload.detectionLayer;
|
||||
|
||||
Reference in new issue
Block a user