mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-15 07:42:23 +00:00
Draw nine layers' fills through engine.ground, one display each
Earthquakes, air quality, GNSS Integrity, fire perimeters, Prohibited & Restricted Airspace, Active Fires, S2 GhostMaps, cyclone advisories and submarine cables each have one render/display.js on the globe contract; their render/cesium* and render/navara* files go. Their discs, cells, polygons and corridors are engine.ground sets, so on Navara they come from the one ground screen pass with exact colours instead of nine hand-written classification passes and lit SDK vector layers. Cesium's look stays the reference: - Earthquake and air-quality discs have no outline (Cesium drew none on clamped ellipses); earthquake discs can now be picked on Navara too. - Perimeters, drone zones and GhostMaps polygons outline their outer ring only, as Cesium did. - GNSS cells stay out of the pick pass; cyclone cones, tracks and centres are culled by a port of Cesium's horizon occluder. - Submarine cables are one ground corridor set, as Cesium batched them; landing points, tips and stems are movers and lines. - FIRMS glows are a sprite set and its cells a ground set. The far-zoom heat raster, which no primitive draws yet, sits behind one seam, render/heatField.js, with a Cesium and a Navara backend. The shared Navara ground helpers that only these layers used go (navaraGroundCells, the cell and ground geometry, the zone renderers), as does the ground prototype script. Coupling: layer renderer lines fall from 1636/6953 to 1011/4832 (Cesium/Navara), Navara ground passes from 7 to 5, Cesium-importing files from 65 to 53, engine.extensions reads from 26 to 19.
This commit is contained in:
1 parent
974a0b6361
commit
54fe0aea40
124 files changed
+8407
-9576
No files matched your search
@@ -34,6 +34,10 @@ const navaraPackage = /^(?:(?:three|postprocessing)(?:\/|$)|@navaramap\/)/;
|
||||
// cesium only in render/cesium*.js, three and Navara only in
|
||||
// render/navara*.js. The list grows with each layer moved onto renderers.
|
||||
const RENDERED_LAYER_DIRS = [
|
||||
'src/layers/droneAirspace/',
|
||||
'src/layers/cyclones/',
|
||||
'src/layers/ghostMaps/',
|
||||
'src/layers/submarineCables/',
|
||||
'src/layers/alpr/',
|
||||
'src/layers/cctv/',
|
||||
'src/layers/transit/',
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
{
|
||||
"metrics": {
|
||||
"cesiumLayerRendererLines": 1636,
|
||||
"navaraLayerRendererLines": 6953,
|
||||
"cesiumImportFiles": 65,
|
||||
"viewerLines": 1901,
|
||||
"navaraKindChecks": 12,
|
||||
"cesiumLayerRendererLines": 1011,
|
||||
"navaraLayerRendererLines": 4832,
|
||||
"cesiumImportFiles": 53,
|
||||
"viewerLines": 1745,
|
||||
"navaraKindChecks": 9,
|
||||
"engineSniffCalls": 14,
|
||||
"engineExtensionReads": 26,
|
||||
"groundEffectPasses": 7,
|
||||
"engineExtensionReads": 19,
|
||||
"groundEffectPasses": 5,
|
||||
"cesiumSdkLoads": 6,
|
||||
"screenSpaceHandlerFiles": 10,
|
||||
"engineNameLines": 133
|
||||
"screenSpaceHandlerFiles": 8,
|
||||
"engineNameLines": 108
|
||||
},
|
||||
"measuredAt": "after the radio, transit and CCTV displays; one engine.extensions read is CCTV's meshes seam, 2026-11-07"
|
||||
"measuredAt": "after the ground layers (earthquakes, air quality, GNSS, perimeters, drone airspace, FIRMS, GhostMaps, cyclones, cables), 2026-11-07"
|
||||
}
|
||||
+23
-23
@@ -625,13 +625,8 @@
|
||||
"src/layers/submarineCables/bundledSource.js",
|
||||
"src/layers/submarineCables/geometry.js",
|
||||
"src/layers/submarineCables/index.js",
|
||||
"src/layers/submarineCables/ingestion.js",
|
||||
"src/layers/submarineCables/interaction.js",
|
||||
"src/layers/submarineCables/lifecycle.js",
|
||||
"src/layers/submarineCables/overlay.js",
|
||||
"src/layers/submarineCables/policy.js",
|
||||
"src/layers/submarineCables/rendering.js",
|
||||
"src/layers/submarineCables/state.js",
|
||||
"src/layers/submarineCables/surface.js",
|
||||
"src/data/telegeographySubmarineCables.js",
|
||||
"src/data/telegeographySubmarineCables.test.mjs",
|
||||
@@ -908,7 +903,6 @@
|
||||
"src/layers/cyclones/rendering.js",
|
||||
"src/layers/cyclones/labels.js",
|
||||
"src/layers/cyclones/source.js",
|
||||
"src/layers/cyclones/rendering.test.mjs",
|
||||
"src/layers/cyclones/labels.test.mjs",
|
||||
"src/layers/cyclones/index.test.mjs",
|
||||
"src/layers/cyclones/source.test.mjs",
|
||||
@@ -1403,23 +1397,10 @@
|
||||
"src/layers/localAdsb/qaDrawn.test.mjs",
|
||||
"src/tooling/w1RuntimeEvidence.test.mjs",
|
||||
"scripts/fixtures/w2/earthquakes.mjs",
|
||||
"src/layers/earthquakes/render/cesium.js",
|
||||
"src/layers/earthquakes/render/cesium.test.mjs",
|
||||
"src/layers/earthquakes/render/navara.js",
|
||||
"src/layers/earthquakes/render/navaraGeometry.js",
|
||||
"src/layers/earthquakes/render/navaraGeometry.test.mjs",
|
||||
"src/layers/earthquakes/render/navaraGrid.js",
|
||||
"src/layers/earthquakes/render/navaraGrid.test.mjs",
|
||||
"src/layers/earthquakes/render/navara.test.mjs",
|
||||
"src/layers/firms/render/cesium.js",
|
||||
"src/layers/firms/render/cesium.test.mjs",
|
||||
"src/layers/firms/rectangle.js",
|
||||
"src/layers/firms/rectangle.test.mjs",
|
||||
"src/layers/firms/viewport.test.mjs",
|
||||
"scripts/fixtures/w2/firms.mjs",
|
||||
"src/layers/firms/render/navara.test.mjs",
|
||||
"src/layers/firms/render/navaraGeometry.test.mjs",
|
||||
"src/layers/firms/render/navaraSprites.test.mjs",
|
||||
"src/layers/firms/lifecycle.test.mjs",
|
||||
"scripts/fixtures/w2/radio.mjs",
|
||||
"scripts/qa-map-policy.mjs",
|
||||
@@ -1620,11 +1601,30 @@
|
||||
"src/globe/navara/ground/pack.test.mjs",
|
||||
"src/globe/navara/ground/pass.js",
|
||||
"src/globe/navara/ground/vector.js",
|
||||
"src/layers/earthquakes/render/ground.js",
|
||||
"src/layers/perimeters/render/ground.js",
|
||||
"scripts/qa-ground-suite.mjs",
|
||||
"scripts/qa-ground-bench.mjs",
|
||||
"scripts/qa-ground-prototypes.mjs",
|
||||
"scripts/qa-ground-switch.mjs",
|
||||
"docs/GLOBE-PRIMITIVES.md"
|
||||
"docs/GLOBE-PRIMITIVES.md",
|
||||
"src/layers/airQuality/render/display.js",
|
||||
"src/layers/airQuality/render/display.test.mjs",
|
||||
"src/layers/cyclones/render/display.js",
|
||||
"src/layers/cyclones/render/display.test.mjs",
|
||||
"src/layers/droneAirspace/render/display.js",
|
||||
"src/layers/droneAirspace/render/display.test.mjs",
|
||||
"src/layers/earthquakes/render/display.js",
|
||||
"src/layers/earthquakes/render/display.test.mjs",
|
||||
"src/layers/firms/render/cesiumHeat.js",
|
||||
"src/layers/firms/render/display.js",
|
||||
"src/layers/firms/render/display.test.mjs",
|
||||
"src/layers/firms/render/heatField.js",
|
||||
"src/layers/firms/render/sprites.js",
|
||||
"src/layers/ghostMaps/render/display.js",
|
||||
"src/layers/ghostMaps/render/display.test.mjs",
|
||||
"src/layers/gnss/render/display.js",
|
||||
"src/layers/gnss/render/display.test.mjs",
|
||||
"src/layers/perimeters/render/display.js",
|
||||
"src/layers/perimeters/render/display.test.mjs",
|
||||
"src/layers/submarineCables/render/display.js",
|
||||
"src/layers/submarineCables/render/display.test.mjs",
|
||||
"src/testSupport/groundDisplayEngines.mjs"
|
||||
]
|
||||
@@ -1583,7 +1583,8 @@
|
||||
"src/layers/earthquakes/source.js",
|
||||
"src/layers/earthquakes/records.js",
|
||||
"src/geo/",
|
||||
"src/layers/shared/color.js"
|
||||
"src/layers/shared/color.js",
|
||||
"src/layers/earthquakes/render/display.js"
|
||||
],
|
||||
"external": []
|
||||
},
|
||||
@@ -2180,13 +2181,8 @@
|
||||
"src/layers/submarineCables/geometry.js",
|
||||
"src/layers/submarineCables/index.js",
|
||||
"src/layers/submarineCables/session.js",
|
||||
"src/layers/submarineCables/ingestion.js",
|
||||
"src/layers/submarineCables/interaction.js",
|
||||
"src/layers/submarineCables/lifecycle.js",
|
||||
"src/layers/submarineCables/overlay.js",
|
||||
"src/layers/submarineCables/policy.js",
|
||||
"src/layers/submarineCables/rendering.js",
|
||||
"src/layers/submarineCables/state.js",
|
||||
"src/layers/submarineCables/surface.js",
|
||||
"src/data/inputOwnership.js",
|
||||
"src/i18n/index.js",
|
||||
@@ -2202,7 +2198,10 @@
|
||||
"src/i18n/locales/uk.json",
|
||||
"src/i18n/locales/zh-CN.json",
|
||||
"src/i18n/locales/zh-Hant.json",
|
||||
"src/geo/"
|
||||
"src/geo/",
|
||||
"src/sources/requestDeadline.js",
|
||||
"src/layers/shared/color.js",
|
||||
"src/layers/submarineCables/render/display.js"
|
||||
],
|
||||
"external": ["cesium"]
|
||||
},
|
||||
@@ -2779,13 +2778,8 @@
|
||||
"src/layers/submarineCables/geometry.js",
|
||||
"src/layers/submarineCables/index.js",
|
||||
"src/layers/submarineCables/session.js",
|
||||
"src/layers/submarineCables/ingestion.js",
|
||||
"src/layers/submarineCables/interaction.js",
|
||||
"src/layers/submarineCables/lifecycle.js",
|
||||
"src/layers/submarineCables/overlay.js",
|
||||
"src/layers/submarineCables/policy.js",
|
||||
"src/layers/submarineCables/rendering.js",
|
||||
"src/layers/submarineCables/state.js",
|
||||
"src/layers/submarineCables/surface.js",
|
||||
"src/layers/traffic/animation.js",
|
||||
"src/layers/traffic/controls.js",
|
||||
@@ -3058,20 +3052,16 @@
|
||||
"src/layers/earthquakes/records.js",
|
||||
"src/app/layers/perimeters.js",
|
||||
"src/layers/perimeters/index.js",
|
||||
"src/layers/perimeters/render/cesium.js",
|
||||
"src/layers/shared/render/cesiumZones.js",
|
||||
"src/layers/perimeters/source.js",
|
||||
"src/layers/perimeters/records.js",
|
||||
"src/layers/perimeters/cards.js",
|
||||
"src/layers/perimeters/inciweb.js",
|
||||
"src/app/layers/gnss.js",
|
||||
"src/layers/gnss/index.js",
|
||||
"src/layers/gnss/render/cesium.js",
|
||||
"src/layers/gnss/source.js",
|
||||
"src/layers/gnss/records.js",
|
||||
"src/app/layers/ghostMaps.js",
|
||||
"src/layers/ghostMaps/index.js",
|
||||
"src/layers/ghostMaps/render/cesium.js",
|
||||
"src/layers/ghostMaps/catalog.js",
|
||||
"src/layers/ghostMaps/records.js",
|
||||
"src/layers/ghostMaps/kml.js",
|
||||
@@ -3299,7 +3289,6 @@
|
||||
"src/data/geoImportImages.js",
|
||||
"src/app/layers/airQuality.js",
|
||||
"src/layers/airQuality/index.js",
|
||||
"src/layers/airQuality/render/cesium.js",
|
||||
"src/layers/airQuality/model.js",
|
||||
"src/layers/airQuality/source.js",
|
||||
"src/ui/statusText.js",
|
||||
@@ -3477,23 +3466,13 @@
|
||||
"src/layers/shared/render/engineView.js",
|
||||
"src/celestialRing/render/cesium.js",
|
||||
"src/celestialRing/view.js",
|
||||
"src/layers/earthquakes/render/cesium.js",
|
||||
"src/layers/earthquakes/render/navara.js",
|
||||
"src/layers/airQuality/render/navara.js",
|
||||
"src/layers/gnss/render/navara.js",
|
||||
"src/layers/perimeters/render/navara.js",
|
||||
"src/layers/shared/render/navaraPolygons.js",
|
||||
"src/layers/shared/render/navaraZones.js",
|
||||
"src/layers/droneAirspace/render/navara.js",
|
||||
"src/layers/earthquakes/render/navaraGeometry.js",
|
||||
"src/layers/earthquakes/render/navaraGrid.js",
|
||||
"src/layers/installations/render/navara.js",
|
||||
"src/layers/awareness/render/navara.js",
|
||||
"src/layers/awareness/render/navaraPulses.js",
|
||||
"src/layers/infrastructure/render/navara.js",
|
||||
"src/layers/shared/render/navaraStems.js",
|
||||
"src/layers/shared/render/navaraSceneDepth.js",
|
||||
"src/layers/submarineCables/render/navara.js",
|
||||
"src/layers/directions/render/navara.js",
|
||||
"src/layers/traffic/render/navara.js",
|
||||
"src/layers/streetLevel/render/navara.js",
|
||||
@@ -3505,9 +3484,7 @@
|
||||
"src/layers/weather/render/navaraSurface.js",
|
||||
"src/layers/wind/render/navara.js",
|
||||
"src/layers/wind/render/flowMesh.js",
|
||||
"src/layers/ghostMaps/render/navara.js",
|
||||
"src/layers/shared/render/navaraGroundPicks.js",
|
||||
"src/layers/cyclones/render/navara.js",
|
||||
"src/layers/shared/render/groundRing.js",
|
||||
"src/layers/bikeshare/stationPoints.js",
|
||||
"src/layers/shared/viewRectangle.js",
|
||||
@@ -3515,8 +3492,6 @@
|
||||
"src/layers/installations/render/navaraOutlineBatch.js",
|
||||
"src/layers/installations/render/navaraStencilBatch.js",
|
||||
"src/layers/firms/rectangle.js",
|
||||
"src/layers/firms/render/cesium.js",
|
||||
"src/layers/firms/render/navara.js",
|
||||
"src/layers/shared/render/navaraMoverBank.js",
|
||||
"src/layers/shared/render/moverBank.js",
|
||||
"src/layers/recentImagery/render/navara.js",
|
||||
@@ -3526,13 +3501,8 @@
|
||||
"src/layers/alpr/overlay.js",
|
||||
"src/layers/alpr/presentation.js",
|
||||
"src/layers/radio/screenClusters.js",
|
||||
"src/layers/shared/render/navaraCellGeometry.js",
|
||||
"src/layers/shared/render/navaraGroundCells.js",
|
||||
"src/layers/firms/render/navaraSprites.js",
|
||||
"src/layers/shared/render/imageAtlas.js",
|
||||
"src/layers/firms/render/navaraHeat.js",
|
||||
"src/layers/shared/render/navaraGroundGeometry.js",
|
||||
"src/layers/shared/render/navaraGroundGrid.js",
|
||||
"src/layers/shared/render/navaraGroundSurface.js",
|
||||
"src/layers/shared/render/navaraGroundEffect.js",
|
||||
"src/annotations/outlineRungs.js",
|
||||
@@ -3602,7 +3572,19 @@
|
||||
"src/layers/cctv/render/cesiumMeshes.js",
|
||||
"src/layers/cctv/render/meshes.js",
|
||||
"src/layers/cctv/render/display.js",
|
||||
"src/layers/transit/render/display.js"
|
||||
"src/layers/transit/render/display.js",
|
||||
"src/layers/earthquakes/render/display.js",
|
||||
"src/layers/airQuality/render/display.js",
|
||||
"src/layers/submarineCables/render/display.js",
|
||||
"src/layers/firms/render/sprites.js",
|
||||
"src/layers/cyclones/render/display.js",
|
||||
"src/layers/droneAirspace/render/display.js",
|
||||
"src/layers/ghostMaps/render/display.js",
|
||||
"src/layers/perimeters/render/display.js",
|
||||
"src/layers/gnss/render/display.js",
|
||||
"src/layers/firms/render/cesiumHeat.js",
|
||||
"src/layers/firms/render/heatField.js",
|
||||
"src/layers/firms/render/display.js"
|
||||
],
|
||||
"external": [
|
||||
"hls.js",
|
||||
@@ -3935,13 +3917,8 @@
|
||||
"src/layers/submarineCables/geometry.js",
|
||||
"src/layers/submarineCables/index.js",
|
||||
"src/layers/submarineCables/session.js",
|
||||
"src/layers/submarineCables/ingestion.js",
|
||||
"src/layers/submarineCables/interaction.js",
|
||||
"src/layers/submarineCables/lifecycle.js",
|
||||
"src/layers/submarineCables/overlay.js",
|
||||
"src/layers/submarineCables/policy.js",
|
||||
"src/layers/submarineCables/rendering.js",
|
||||
"src/layers/submarineCables/state.js",
|
||||
"src/layers/submarineCables/surface.js",
|
||||
"src/layers/traffic/animation.js",
|
||||
"src/layers/traffic/controls.js",
|
||||
@@ -4031,20 +4008,16 @@
|
||||
"src/layers/earthquakes/records.js",
|
||||
"src/app/layers/perimeters.js",
|
||||
"src/layers/perimeters/index.js",
|
||||
"src/layers/perimeters/render/cesium.js",
|
||||
"src/layers/shared/render/cesiumZones.js",
|
||||
"src/layers/perimeters/source.js",
|
||||
"src/layers/perimeters/records.js",
|
||||
"src/layers/perimeters/cards.js",
|
||||
"src/layers/perimeters/inciweb.js",
|
||||
"src/app/layers/gnss.js",
|
||||
"src/layers/gnss/index.js",
|
||||
"src/layers/gnss/render/cesium.js",
|
||||
"src/layers/gnss/source.js",
|
||||
"src/layers/gnss/records.js",
|
||||
"src/app/layers/ghostMaps.js",
|
||||
"src/layers/ghostMaps/index.js",
|
||||
"src/layers/ghostMaps/render/cesium.js",
|
||||
"src/layers/ghostMaps/catalog.js",
|
||||
"src/layers/ghostMaps/records.js",
|
||||
"src/layers/ghostMaps/kml.js",
|
||||
@@ -4211,7 +4184,6 @@
|
||||
"src/data/cameraFraming.js",
|
||||
"src/app/layers/airQuality.js",
|
||||
"src/layers/airQuality/index.js",
|
||||
"src/layers/airQuality/render/cesium.js",
|
||||
"src/layers/airQuality/model.js",
|
||||
"src/layers/airQuality/source.js",
|
||||
"src/ui/statusText.js",
|
||||
@@ -4282,9 +4254,7 @@
|
||||
"src/celestialRing/render/cesium.js",
|
||||
"src/celestialRing/view.js",
|
||||
"src/layers/shared/render/engineView.js",
|
||||
"src/layers/earthquakes/render/cesium.js",
|
||||
"src/layers/firms/rectangle.js",
|
||||
"src/layers/firms/render/cesium.js",
|
||||
"src/annotations/outlineRungs.js",
|
||||
"src/sources/openFreeMapOutlines.js",
|
||||
"src/sources/nominatimOutlines.js",
|
||||
@@ -4337,7 +4307,20 @@
|
||||
"src/layers/cctv/render/cesiumMeshes.js",
|
||||
"src/layers/cctv/render/meshes.js",
|
||||
"src/layers/cctv/render/display.js",
|
||||
"src/layers/transit/render/display.js"
|
||||
"src/layers/transit/render/display.js",
|
||||
"src/layers/earthquakes/render/display.js",
|
||||
"src/layers/airQuality/render/display.js",
|
||||
"src/layers/cyclones/render/display.js",
|
||||
"src/layers/gnss/render/display.js",
|
||||
"src/layers/firms/render/sprites.js",
|
||||
"src/layers/submarineCables/render/display.js",
|
||||
"src/layers/perimeters/render/display.js",
|
||||
"src/layers/droneAirspace/render/display.js",
|
||||
"src/globe/ground.js",
|
||||
"src/layers/ghostMaps/render/display.js",
|
||||
"src/layers/firms/render/cesiumHeat.js",
|
||||
"src/layers/firms/render/heatField.js",
|
||||
"src/layers/firms/render/display.js"
|
||||
],
|
||||
"external": [
|
||||
"hls.js",
|
||||
@@ -5185,8 +5168,6 @@
|
||||
"src/geo/cartesian3.js",
|
||||
"src/geo/math.js",
|
||||
"src/layers/perimeters/index.js",
|
||||
"src/layers/perimeters/render/cesium.js",
|
||||
"src/layers/shared/render/cesiumZones.js",
|
||||
"src/sources/httpBody.js",
|
||||
"src/i18n/marker.js",
|
||||
"src/layers/perimeters/source.js",
|
||||
@@ -5205,7 +5186,9 @@
|
||||
"src/i18n/locales/ru.json",
|
||||
"src/i18n/locales/uk.json",
|
||||
"src/i18n/locales/zh-CN.json",
|
||||
"src/i18n/locales/zh-Hant.json"
|
||||
"src/i18n/locales/zh-Hant.json",
|
||||
"src/layers/shared/color.js",
|
||||
"src/layers/perimeters/render/display.js"
|
||||
],
|
||||
"external": ["cesium"]
|
||||
},
|
||||
@@ -5213,7 +5196,6 @@
|
||||
"exports": ["./layers/gnss"],
|
||||
"modules": [
|
||||
"src/layers/gnss/index.js",
|
||||
"src/layers/gnss/render/cesium.js",
|
||||
"src/sources/httpBody.js",
|
||||
"src/i18n/marker.js",
|
||||
"src/layers/gnss/source.js",
|
||||
@@ -5232,7 +5214,18 @@
|
||||
"src/i18n/locales/zh-CN.json",
|
||||
"src/i18n/locales/zh-Hant.json",
|
||||
"src/ui/statusText.js",
|
||||
"src/ui/layerNames.js"
|
||||
"src/ui/layerNames.js",
|
||||
"src/layers/shared/viewRectangle.js",
|
||||
"src/layers/shared/color.js",
|
||||
"src/geo/math.js",
|
||||
"src/geo/cartesian2.js",
|
||||
"src/geo/matrix3.js",
|
||||
"src/geo/cartesian3.js",
|
||||
"src/geo/matrix4.js",
|
||||
"src/geo/quaternion.js",
|
||||
"src/geo/boundingSphere.js",
|
||||
"src/geo/",
|
||||
"src/layers/gnss/render/display.js"
|
||||
],
|
||||
"external": ["cesium"]
|
||||
},
|
||||
@@ -5279,7 +5272,6 @@
|
||||
"exports": ["./layers/ghostmaps"],
|
||||
"modules": [
|
||||
"src/layers/ghostMaps/index.js",
|
||||
"src/layers/ghostMaps/render/cesium.js",
|
||||
"src/layers/ghostMaps/catalog.js",
|
||||
"src/layers/ghostMaps/records.js",
|
||||
"src/layers/ghostMaps/kml.js",
|
||||
@@ -5335,7 +5327,6 @@
|
||||
"modules": [
|
||||
"src/layers/droneAirspace/index.js",
|
||||
"src/geo/",
|
||||
"src/layers/shared/render/cesiumZones.js",
|
||||
"src/sources/httpBody.js",
|
||||
"src/layers/droneAirspace/source.js",
|
||||
"src/layers/droneAirspace/records.js",
|
||||
@@ -5353,7 +5344,9 @@
|
||||
"src/i18n/locales/ru.json",
|
||||
"src/i18n/locales/uk.json",
|
||||
"src/i18n/locales/zh-CN.json",
|
||||
"src/i18n/locales/zh-Hant.json"
|
||||
"src/i18n/locales/zh-Hant.json",
|
||||
"src/layers/shared/color.js",
|
||||
"src/layers/droneAirspace/render/display.js"
|
||||
],
|
||||
"external": ["cesium"]
|
||||
},
|
||||
@@ -5538,7 +5531,6 @@
|
||||
"src/geo/cartesian3.js",
|
||||
"src/geo/math.js",
|
||||
"src/layers/airQuality/index.js",
|
||||
"src/layers/airQuality/render/cesium.js",
|
||||
"src/layers/airQuality/model.js",
|
||||
"src/layers/airQuality/source.js",
|
||||
"src/sources/httpBody.js",
|
||||
@@ -5557,7 +5549,9 @@
|
||||
"src/i18n/locales/zh-CN.json",
|
||||
"src/i18n/locales/zh-Hant.json",
|
||||
"src/ui/statusText.js",
|
||||
"src/ui/layerNames.js"
|
||||
"src/ui/layerNames.js",
|
||||
"src/layers/shared/color.js",
|
||||
"src/layers/airQuality/render/display.js"
|
||||
],
|
||||
"external": ["cesium"]
|
||||
},
|
||||
|
||||
@@ -1,313 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* The engine.ground prototypes of earthquakes and fire perimeters
|
||||
* (src/layers/earthquakes/render/ground.js,
|
||||
* src/layers/perimeters/render/ground.js) against what each engine draws
|
||||
* today, on fixed data over California in daylight. Per engine: the canvas
|
||||
* without the layers, with today's renderers, with the ground prototypes;
|
||||
* the pixels each drawing changed (a channel off by more than 24), and
|
||||
* their overlap (intersection over union) with today's Cesium drawing; a
|
||||
* pick of a quake and of a perimeter through engine.picker. Writes the
|
||||
* images and a side-by-side to --out.
|
||||
*
|
||||
* GOOGLE_MAPS_API_KEY= CESIUM_ION_TOKEN= npm run dev -- --port 4271
|
||||
* node scripts/qa-ground-prototypes.mjs http://localhost:4271 --out=DIR
|
||||
*/
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import puppeteer from 'puppeteer';
|
||||
import sharp from 'sharp';
|
||||
|
||||
const BLOCKED_HOSTS =
|
||||
/(^|\.)(googleapis\.com|google\.com|gstatic\.com|cesium\.com)$/;
|
||||
const args = process.argv.slice(2);
|
||||
const origin = args.find((arg) => !arg.startsWith('--'));
|
||||
const option = (name) =>
|
||||
args.find((arg) => arg.startsWith(`--${name}=`))?.slice(name.length + 3);
|
||||
const out = option('out') ?? 'qa-ground-prototypes';
|
||||
if (!origin) {
|
||||
console.error(
|
||||
'Usage: node scripts/qa-ground-prototypes.mjs <origin> --out=DIR',
|
||||
);
|
||||
process.exit(2);
|
||||
}
|
||||
fs.mkdirSync(out, { recursive: true });
|
||||
const VIEW = { lon: -119.6, lat: 37.2, alt: 700000 };
|
||||
|
||||
async function capture(page, kind) {
|
||||
const ui = await page.evaluate(
|
||||
async (kind, view) => {
|
||||
const { engine } = window.__godsEyeView;
|
||||
const frame = () =>
|
||||
new Promise((resolve) => {
|
||||
const remove = engine.frames.postRender.addEventListener(() => {
|
||||
remove();
|
||||
resolve();
|
||||
});
|
||||
engine.render.request('ground-prototypes');
|
||||
});
|
||||
const settle = async () => {
|
||||
let loaded = 0;
|
||||
const started = performance.now();
|
||||
while (loaded < 20 && performance.now() - started < 60000) {
|
||||
await frame();
|
||||
loaded = engine.surface.tilesLoaded() ? loaded + 1 : 0;
|
||||
}
|
||||
};
|
||||
const shot = async () => {
|
||||
await settle();
|
||||
const canvas = engine.host.canvas;
|
||||
const copy = document.createElement('canvas');
|
||||
copy.width = canvas.clientWidth;
|
||||
copy.height = canvas.clientHeight;
|
||||
copy.getContext('2d').drawImage(canvas, 0, 0, copy.width, copy.height);
|
||||
return copy.toDataURL('image/png');
|
||||
};
|
||||
const geo = await import('/src/geo/index.js');
|
||||
const { depthColor } = await import('/src/layers/earthquakes/model.js');
|
||||
// Fixed quakes and perimeters (one with a hole) in the view.
|
||||
const quakes = [
|
||||
[-121.8, 36.6, 3.1, 8],
|
||||
[-120.6, 35.9, 4.6, 12],
|
||||
[-118.4, 37.6, 5.4, 9],
|
||||
[-117.6, 36.2, 2.8, 120],
|
||||
[-121.0, 38.4, 3.9, 400],
|
||||
[-119.0, 38.9, 6.0, 15],
|
||||
].map(([lon, lat, mag, depthKm], index) => ({
|
||||
stableId: `q${index}`,
|
||||
usgsId: `q${index}`,
|
||||
position: geo.cartesian3.fromDegrees(lon, lat),
|
||||
baseRadius: 2 ** mag * 1000,
|
||||
color: depthColor(depthKm),
|
||||
isSignificant: mag >= 5,
|
||||
fillAlpha: mag >= 5 ? 0.4 : 0.3,
|
||||
outlineAlpha: mag >= 5 ? 1 : 0.8,
|
||||
mag,
|
||||
place: `fixture ${index}`,
|
||||
time: 0,
|
||||
depthKm,
|
||||
}));
|
||||
const blob = (lon, lat, rx, ry, count = 40) => {
|
||||
const ring = [];
|
||||
for (let k = 0; k < count; k++) {
|
||||
const angle = (k / count) * 2 * Math.PI;
|
||||
const wobble = 1 + 0.18 * Math.sin(angle * 5);
|
||||
ring.push([
|
||||
lon + rx * wobble * Math.cos(angle),
|
||||
lat + ry * wobble * Math.sin(angle),
|
||||
]);
|
||||
}
|
||||
ring.push(ring[0]);
|
||||
return ring;
|
||||
};
|
||||
const perimeters = [
|
||||
{
|
||||
stableId: 'p0',
|
||||
containedPct: 10,
|
||||
polygons: [
|
||||
[blob(-120.2, 37.9, 0.35, 0.25), blob(-120.2, 37.9, 0.12, 0.08)],
|
||||
],
|
||||
},
|
||||
{
|
||||
stableId: 'p1',
|
||||
containedPct: 60,
|
||||
polygons: [[blob(-118.9, 36.6, 0.25, 0.3)]],
|
||||
},
|
||||
{
|
||||
stableId: 'p2',
|
||||
containedPct: 100,
|
||||
polygons: [
|
||||
[blob(-121.4, 37.4, 0.15, 0.12)],
|
||||
[blob(-121.1, 37.1, 0.1, 0.1)],
|
||||
],
|
||||
},
|
||||
];
|
||||
// A restored view settles after the loading screen: take the camera.
|
||||
await new Promise((resolve) => setTimeout(resolve, 3000));
|
||||
engine.camera.setView({
|
||||
destination: geo.cartesian3.fromDegrees(view.lon, view.lat, view.alt),
|
||||
});
|
||||
const images = { base: await shot() };
|
||||
// Today's renderers on this engine.
|
||||
let quakeRenderer;
|
||||
let perimeterRenderer;
|
||||
if (kind === 'cesium') {
|
||||
const { viewer } = engine.extensions.cesium;
|
||||
const { createEarthquakesCesiumRenderer } =
|
||||
await import('/src/layers/earthquakes/render/cesium.js');
|
||||
const { createPerimetersCesiumRenderer } =
|
||||
await import('/src/layers/perimeters/render/cesium.js');
|
||||
quakeRenderer = createEarthquakesCesiumRenderer(engine, { viewer });
|
||||
perimeterRenderer = createPerimetersCesiumRenderer({
|
||||
viewer,
|
||||
screenSpaceEventHandlerFactory: () => ({
|
||||
setInputAction() {},
|
||||
destroy() {},
|
||||
}),
|
||||
});
|
||||
} else {
|
||||
const navara = engine.extensions.navara;
|
||||
const { createEarthquakesNavaraRenderer } =
|
||||
await import('/src/layers/earthquakes/render/navara.js');
|
||||
const { createPerimetersNavaraRenderer } =
|
||||
await import('/src/layers/perimeters/render/navara.js');
|
||||
quakeRenderer = createEarthquakesNavaraRenderer(engine, navara);
|
||||
perimeterRenderer = createPerimetersNavaraRenderer(engine, navara);
|
||||
}
|
||||
quakeRenderer.replace(quakes);
|
||||
quakeRenderer.setVisible(true);
|
||||
perimeterRenderer.replace(perimeters);
|
||||
perimeterRenderer.setVisible(true);
|
||||
for (let index = 0; index < 60; index++) await frame();
|
||||
images.today = await shot();
|
||||
quakeRenderer.destroy();
|
||||
perimeterRenderer.destroy();
|
||||
// The prototypes on engine.ground.
|
||||
const { createEarthquakesGroundRenderer } =
|
||||
await import('/src/layers/earthquakes/render/ground.js');
|
||||
const { createPerimetersGroundRenderer } =
|
||||
await import('/src/layers/perimeters/render/ground.js');
|
||||
const quakesOnGround = createEarthquakesGroundRenderer(engine);
|
||||
const perimetersOnGround = createPerimetersGroundRenderer(engine);
|
||||
quakesOnGround.replace(quakes);
|
||||
quakesOnGround.setVisible(true);
|
||||
perimetersOnGround.replace(perimeters);
|
||||
perimetersOnGround.setVisible(true);
|
||||
const ready = () =>
|
||||
engine.ground.list().every(({ id }) => id) &&
|
||||
['earthquakes', 'fire-perimeters'].every((id) =>
|
||||
engine.ground.list().some((entry) => entry.id === id),
|
||||
);
|
||||
while (!ready()) await frame();
|
||||
for (let index = 0; index < 60; index++) await frame();
|
||||
images.ground = await shot();
|
||||
const screen = (lon, lat) =>
|
||||
engine.projector.worldToWindow(geo.cartesian3.fromDegrees(lon, lat));
|
||||
const picks = {
|
||||
quake: engine.picker.pick(screen(-118.4, 37.6))?.id ?? null,
|
||||
perimeter: engine.picker.pick(screen(-118.9, 36.6))?.id ?? null,
|
||||
hole: engine.picker.pick(screen(-120.2, 37.9))?.id ?? null,
|
||||
records: quakesOnGround.records(10).length,
|
||||
};
|
||||
quakesOnGround.destroy();
|
||||
perimetersOnGround.destroy();
|
||||
return { images, picks };
|
||||
},
|
||||
kind,
|
||||
VIEW,
|
||||
);
|
||||
return ui;
|
||||
}
|
||||
|
||||
async function openEngine(browser, kind) {
|
||||
const page = await browser.newPage();
|
||||
await page.setViewport({ width: 1280, height: 800 });
|
||||
page.on('pageerror', (error) => console.log(' page error:', error.message));
|
||||
await page.setRequestInterception(true);
|
||||
page.on('request', (request) => {
|
||||
if (BLOCKED_HOSTS.test(new URL(request.url()).hostname)) request.abort();
|
||||
else request.continue();
|
||||
});
|
||||
await page.goto(
|
||||
`${origin}/?welcome=0&engine=${kind}#v=2&lat=${VIEW.lat}&lon=${VIEW.lon}&alt=${VIEW.alt}&heading=0&pitch=-90&map=osm&l=`,
|
||||
);
|
||||
await page.waitForFunction(
|
||||
(expected) =>
|
||||
window.__godsEyeView?.engine?.kind === expected &&
|
||||
document.getElementById('loading-screen')?.classList.contains('hidden'),
|
||||
{ timeout: 300_000, polling: 250 },
|
||||
kind,
|
||||
);
|
||||
// Daylight over California (Navara lights the scene by the app clock).
|
||||
await page.evaluate(async () => {
|
||||
const { appClock } = await import('/src/time/clock.js');
|
||||
appClock.freeze(Date.UTC(2026, 10, 7, 20, 0));
|
||||
});
|
||||
return page;
|
||||
}
|
||||
|
||||
const decode = async (dataUrl) => {
|
||||
const { data, info } = await sharp(
|
||||
Buffer.from(dataUrl.split(',')[1], 'base64'),
|
||||
)
|
||||
.raw()
|
||||
.ensureAlpha()
|
||||
.toBuffer({ resolveWithObject: true });
|
||||
return { data, width: info.width, height: info.height };
|
||||
};
|
||||
// Pixels where `image` differs from `base` by more than 24 on a channel.
|
||||
const changed = (base, image) => {
|
||||
const mask = new Uint8Array(base.width * base.height);
|
||||
for (let i = 0; i < mask.length; i++)
|
||||
for (let c = 0; c < 3; c++)
|
||||
if (Math.abs(base.data[i * 4 + c] - image.data[i * 4 + c]) > 24) {
|
||||
mask[i] = 1;
|
||||
break;
|
||||
}
|
||||
return mask;
|
||||
};
|
||||
const iou = (a, b) => {
|
||||
let both = 0;
|
||||
let either = 0;
|
||||
for (let i = 0; i < a.length; i++) {
|
||||
both += a[i] & b[i];
|
||||
either += a[i] | b[i];
|
||||
}
|
||||
return either ? both / either : 1;
|
||||
};
|
||||
const count = (mask) => mask.reduce((total, value) => total + value, 0);
|
||||
|
||||
const browser = await puppeteer.launch({ headless: true });
|
||||
const results = {};
|
||||
try {
|
||||
for (const kind of ['cesium', 'navara']) {
|
||||
const page = await openEngine(browser, kind);
|
||||
results[kind] = await capture(page, kind);
|
||||
await page.close();
|
||||
}
|
||||
} finally {
|
||||
await browser.close();
|
||||
}
|
||||
const masks = {};
|
||||
for (const kind of ['cesium', 'navara']) {
|
||||
const { images, picks } = results[kind];
|
||||
const base = await decode(images.base);
|
||||
masks[kind] = {
|
||||
today: changed(base, await decode(images.today)),
|
||||
ground: changed(base, await decode(images.ground)),
|
||||
};
|
||||
for (const name of ['base', 'today', 'ground'])
|
||||
fs.writeFileSync(
|
||||
path.join(out, `${kind}-${name}.png`),
|
||||
Buffer.from(images[name].split(',')[1], 'base64'),
|
||||
);
|
||||
console.log(
|
||||
`${kind}: today changed ${count(masks[kind].today)} px, ground ${count(masks[kind].ground)} px; picks ${JSON.stringify(picks)}`,
|
||||
);
|
||||
}
|
||||
const reference = masks.cesium.today;
|
||||
console.log(
|
||||
`overlap with today's Cesium drawing (IoU of changed pixels): Cesium ground ${iou(reference, masks.cesium.ground).toFixed(3)}, Navara ground ${iou(reference, masks.navara.ground).toFixed(3)}, Navara today ${iou(reference, masks.navara.today).toFixed(3)}`,
|
||||
);
|
||||
// Side by side: Cesium today, Cesium ground, Navara today, Navara ground.
|
||||
const tiles = await Promise.all(
|
||||
['cesium-today', 'cesium-ground', 'navara-today', 'navara-ground'].map(
|
||||
(name) =>
|
||||
sharp(path.join(out, `${name}.png`))
|
||||
.resize(640, 400)
|
||||
.png()
|
||||
.toBuffer(),
|
||||
),
|
||||
);
|
||||
await sharp({
|
||||
create: { width: 1280, height: 800, channels: 3, background: '#000' },
|
||||
})
|
||||
.composite(
|
||||
tiles.map((input, index) => ({
|
||||
input,
|
||||
left: (index % 2) * 640,
|
||||
top: Math.floor(index / 2) * 400,
|
||||
})),
|
||||
)
|
||||
.png()
|
||||
.toFile(path.join(out, 'side-by-side.png'));
|
||||
Reference in new issue
Block a user