mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-14 23:32:20 +00:00
Compare commits
120
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d49d3d10cc | ||
|
|
6f830a2e70 | ||
|
|
e53cfef1d1 | ||
|
|
5d733eb07b | ||
|
|
7451c9b372 | ||
|
|
7578fcc9a1 | ||
|
|
1f20b609ee | ||
|
|
0cb8207285 | ||
|
|
c54ead9432 | ||
|
|
d0b614d88e | ||
|
|
9374e0228b | ||
|
|
235fe94a89 | ||
|
|
605bf5b564 | ||
|
|
85415bda97 | ||
|
|
8da632cc2d | ||
|
|
4debb49fe0 | ||
|
|
4568b9ff12 | ||
|
|
129b35e470 | ||
|
|
9261279639 | ||
|
|
81f3602134 | ||
|
|
422a11d9a4 | ||
|
|
9cc2a1811b | ||
|
|
b090937e5f | ||
|
|
59ffa87535 | ||
|
|
b080857c35 | ||
|
|
7ee047961b | ||
|
|
f0a8b1193a | ||
|
|
dd15223109 | ||
|
|
96cefa28b3 | ||
|
|
39c89d563b | ||
|
|
250f0e20c3 | ||
|
|
52507a0755 | ||
|
|
9ae121c7c0 | ||
|
|
6c7fe48f40 | ||
|
|
279aedb2f4 | ||
|
|
f24abfc88f | ||
|
|
58776a6976 | ||
|
|
391e33b0d5 | ||
|
|
deb42b38f7 | ||
|
|
fd06272e37 | ||
|
|
a3611caddb | ||
|
|
4d81d3be3a | ||
|
|
c2c196ab1e | ||
|
|
8cb096fc21 | ||
|
|
3934be9ff9 | ||
|
|
c73c5c4eb6 | ||
|
|
491c50ed18 | ||
|
|
c5cf579174 | ||
|
|
332551ec84 | ||
|
|
6e655b801d | ||
|
|
083da40d88 | ||
|
|
16d163a886 | ||
|
|
c653b3878d | ||
|
|
53cbd55181 | ||
|
|
a91a89ec1c | ||
|
|
c43bf103d6 | ||
|
|
6c55daf9ac | ||
|
|
9b46692c64 | ||
|
|
4bb7b411e9 | ||
|
|
9d01f8df77 | ||
|
|
f0ee1b95ca | ||
|
|
f29b0b2639 | ||
|
|
7f18943ec4 | ||
|
|
0325805eb0 | ||
|
|
73bd952736 | ||
|
|
7df581765d | ||
|
|
974023510f | ||
|
|
92d34bc4cc | ||
|
|
546ac22708 | ||
|
|
432a29ba59 | ||
|
|
a9d390c165 | ||
|
|
140f7ebd21 | ||
|
|
71bfc8aba0 | ||
|
|
df41c0affb | ||
|
|
f0b0378b11 | ||
|
|
0d1e3fb703 | ||
|
|
a44c42eb94 | ||
|
|
058ed0ffeb | ||
|
|
7b93045895 | ||
|
|
fcc44d0eaf | ||
|
|
f6760ad96c | ||
|
|
d42b6fe764 | ||
|
|
42540ad85e | ||
|
|
bc8aadf55f | ||
|
|
7314dac1ce | ||
|
|
fbc1a9a0ec | ||
|
|
22f43aab01 | ||
|
|
a7d722a1f4 | ||
|
|
0584292405 | ||
|
|
09f3380203 | ||
|
|
c24352ff5e | ||
|
|
feaf59776c | ||
|
|
4ae67fcb35 | ||
|
|
fe7590d66a | ||
|
|
557fe7169a | ||
|
|
a17346be6f | ||
|
|
294ccc0ee8 | ||
|
|
a4f321a9ef | ||
|
|
6fbc98952f | ||
|
|
4c33552105 | ||
|
|
1e4060f6ba | ||
|
|
57d87d2bbf | ||
|
|
01a74fceec | ||
|
|
f75179eea0 | ||
|
|
29cf9ff8f6 | ||
|
|
897a74ea27 | ||
|
|
bd1da596b8 | ||
|
|
6976cbc941 | ||
|
|
771ed98e3b | ||
|
|
282ad6c5f6 | ||
|
|
d1f4d1acdc | ||
|
|
ebaa439739 | ||
|
|
265074aa54 | ||
|
|
c763c38193 | ||
|
|
2448662574 | ||
|
|
d9e34f10c6 | ||
|
|
02a8442e6e | ||
|
|
628de8386d | ||
|
|
abfc85e03d | ||
|
|
fbec1488ac |
No files matched your search
+1
-1
@@ -176,7 +176,7 @@ VITE_AIS_LIVE_LABEL_MAX_ROWS=900
|
|||||||
AISSTREAM_API_KEY=
|
AISSTREAM_API_KEY=
|
||||||
# Optional AISStream subscription filters.
|
# Optional AISStream subscription filters.
|
||||||
# AISSTREAM_BOUNDING_BOXES=[[[-90,-180],[90,180]]]
|
# AISSTREAM_BOUNDING_BOXES=[[[-90,-180],[90,180]]]
|
||||||
# AISSTREAM_MESSAGE_TYPES=PositionReport,StandardClassBPositionReport,ExtendedClassBPositionReport,ShipStaticData,StaticDataReport
|
# AISSTREAM_MESSAGE_TYPES=PositionReport,StandardClassBPositionReport,ExtendedClassBPositionReport,ShipStaticData,StaticDataReport,AidsToNavigationReport
|
||||||
# Feed watchdog: silence (ms) after which the feed is REPORTED stale; the socket
|
# Feed watchdog: silence (ms) after which the feed is REPORTED stale; the socket
|
||||||
# is recycled at 2.5x that. Default 120000. The watchdog self-arms only for the
|
# is recycled at 2.5x that. Default 120000. The watchdog self-arms only for the
|
||||||
# default worldwide subscription — a narrow filter above can be legitimately
|
# default worldwide subscription — a narrow filter above can be legitimately
|
||||||
|
|||||||
+2
-2
@@ -1,13 +1,13 @@
|
|||||||
# Data Sources & Attribution
|
# Data Sources & Attribution
|
||||||
|
|
||||||
God's Eye View's **code** is [MIT](LICENSE)-licensed. **The MIT grant covers the source code only — it does NOT extend to third-party data or visual assets.** Every third-party source keeps its own license and terms. This file documents the live and bundled data sources; bundled 3D-model provenance is recorded in [`public/models/README.md`](public/models/README.md).
|
God's Eye View's **code** is [MIT](LICENSE)-licensed. **The MIT grant covers the source code only — it does NOT extend to third-party data or visual assets.** Every third-party source keeps its own license and terms. This file documents the live and bundled data sources. The bundled 3D models are the project's own procedural fleet models, MIT-licensed with the code ([`public/models/README.md`](public/models/README.md)).
|
||||||
|
|
||||||
How to read this:
|
How to read this:
|
||||||
|
|
||||||
- **The non-permissive datasets are carved out, not omitted.** Some bundled data (e.g. TeleGeography, CC BY-NC-SA) isn't MIT-compatible. Rather than hide it, we **bundle it with a clear license carve-out** so the app works out of the box — but it stays under the provider's terms.
|
- **The non-permissive datasets are carved out, not omitted.** Some bundled data (e.g. TeleGeography, CC BY-NC-SA) isn't MIT-compatible. Rather than hide it, we **bundle it with a clear license carve-out** so the app works out of the box — but it stays under the provider's terms.
|
||||||
- **If your use doesn't fit a dataset's license, remove that dataset.** Most importantly: TeleGeography is **NonCommercial** — commercial users must delete it (or license it from TeleGeography). It's one self-contained folder.
|
- **If your use doesn't fit a dataset's license, remove that dataset.** Most importantly: TeleGeography is **NonCommercial** — commercial users must delete it (or license it from TeleGeography). It's one self-contained folder.
|
||||||
- **Attribution is shown in-app** and listed here. Keep it intact. The required Google/Cesium credit renders on the on-globe credit line (bottom-left, `#cesium-credits`), and every per-layer credit below is registered into the expandable **"Data attribution"** lightbox on that line (`src/data/dataCredits.js` → `viewer.creditDisplay.addStaticCredit`). Both stay visible in clean-view and recording modes.
|
- **Attribution is shown in-app** and listed here. Keep it intact. The required Google/Cesium credit renders on the on-globe credit line (bottom-left, `#cesium-credits`), and every per-layer credit below is registered into the expandable **"Data attribution"** lightbox on that line (`src/data/dataCredits.js` → `viewer.creditDisplay.addStaticCredit`). Both stay visible in clean-view and recording modes.
|
||||||
- **Bundled model attribution lives beside the model files.** [`public/models/README.md`](public/models/README.md) records each shipped model's creator, source, license, and modification status.
|
- **The bundled 3D models are the project's own.** Every model under `public/models/` is a procedural fleet model generated by the project maintainers and covered by the repository's MIT license; [`public/models/README.md`](public/models/README.md) describes the set.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ In short: the MIT grant does not extend to any third-party data. See
|
|||||||
DATA_SOURCES.md for the full per-source license + attribution summary, and
|
DATA_SOURCES.md for the full per-source license + attribution summary, and
|
||||||
remove any dataset whose terms don't fit your use.
|
remove any dataset whose terms don't fit your use.
|
||||||
|
|
||||||
The 3D models under public/models/ are also third-party works and are NOT
|
The 3D models under public/models/ are the project's procedural fleet
|
||||||
licensed under MIT. They remain under their individual licenses. See
|
models, generated from code by the project maintainers, and are covered by
|
||||||
public/models/README.md for the author, source, license, modification notice,
|
the MIT license above like the source code. See public/models/README.md.
|
||||||
and attribution covering each model file.
|
|
||||||
@@ -60,7 +60,7 @@ Start with the included data sources, then add your own. Each layer is a separat
|
|||||||
- **📡 Contacts:** A 250 km roster of everything near your target — step through live aircraft and drop into any cockpit.
|
- **📡 Contacts:** A 250 km roster of everything near your target — step through live aircraft and drop into any cockpit.
|
||||||
- **🎯 Click-to-track anything:** Camera locks on, draws a fading trail, surfaces full metadata — and a tracked fire or vessel hands you off to the nearest live camera in one click.
|
- **🎯 Click-to-track anything:** Camera locks on, draws a fading trail, surfaces full metadata — and a tracked fire or vessel hands you off to the nearest live camera in one click.
|
||||||
- **🖊️ Voice whiteboard:** Speak annotations onto the world — real boundary polygons, marks, and routes.
|
- **🖊️ Voice whiteboard:** Speak annotations onto the world — real boundary polygons, marks, and routes.
|
||||||
- **🛫 3D hangar:** Real per-class aircraft models — 787, ATR-72, Citation, Bell 206, MQ-9 — and a tracked contact swaps from glyph to 3D model as you close in.
|
- **🛫 3D fleet:** 122 procedural models drawn life size by type — airliners, business jets, helicopters, drones, ships, buses, trams and trains — and every contact swaps from glyph to 3D model as you close in.
|
||||||
- **🎨 Reskin reality:** GLSL sensor looks over the normal globe — CRT, NVG, FLIR/thermal, Noir.
|
- **🎨 Reskin reality:** GLSL sensor looks over the normal globe — CRT, NVG, FLIR/thermal, Noir.
|
||||||
- **🟩 Detection overlay:** Screen-space bounding boxes and IDs on everything in view.
|
- **🟩 Detection overlay:** Screen-space bounding boxes and IDs on everything in view.
|
||||||
- **🎖️ Military HUD:** Tactical heads-up display with intelligence-style telemetry.
|
- **🎖️ Military HUD:** Tactical heads-up display with intelligence-style telemetry.
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
- When the globe stops drawing after a render error or a lost WebGL context,
|
||||||
|
an alert dialog says so instead of leaving a frozen or black globe behind
|
||||||
|
working controls. Retry restarts drawing (Reload after a lost context), and
|
||||||
|
Reset view reopens the app without the view restored from the address bar.
|
||||||
|
Cesium's "Rendering has stopped" panel no longer appears in the app
|
||||||
|
(German, @gekh, #1579).
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
- Let an application add its own Cockpit subjects through
|
||||||
|
`services.cockpitSubjects`. A provider supplies the subject's position,
|
||||||
|
heading and HUD (in the page's language, via `getLocale` and
|
||||||
|
`onLocaleChange` from `./i18n`); the camera can follow it without the
|
||||||
|
ground clamp, anchored exactly on it, and a generic HUD adds source rows, a
|
||||||
|
banner, a veil (off under reduced motion) and a bottom progress line. The
|
||||||
|
Rail and Transit layers expose read and hold APIs so a selected train or
|
||||||
|
vehicle can be ridden, and `./layers/rail/paths` is exported; that export
|
||||||
|
and the read APIs are experimental. `docs/APPLICATION.md` shows a minimal
|
||||||
|
provider. GEV itself registers none, and entry to the built-in aircraft,
|
||||||
|
satellite and vessel views is unchanged; a provider's subject takes entry
|
||||||
|
when it was selected after them (Denis Groshev, @ZloyS, #1686).
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
- Fix the translations of the strings added since the last review (News,
|
||||||
|
Data Library, Wildlife Sightings, Shipwrecks, Rail, the vessel and orbital
|
||||||
|
cockpits) in all twelve languages: neutral side labels and counts no longer
|
||||||
|
break the sentence, terms follow each glossary, and Traditional Chinese
|
||||||
|
follows Simplified Chinese again (German, @gekh, #1698).
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
- Draw every 3D model from the project's procedural fleet set: 121 models
|
||||||
|
(about 2 MB, MIT like the code) chosen per vehicle by type and drawn life
|
||||||
|
size, replacing the eight third-party aircraft models. Flights, Military
|
||||||
|
Flights and Local ADS-B pick a model by ICAO type, class and emitter
|
||||||
|
category; Vessels, Transit and Rail now draw models too, under the same 3D
|
||||||
|
toggle and distances, a ship at its AIS length and beam and a tram, bus or
|
||||||
|
train in its mode or category colour. The whole set loads once when a layer
|
||||||
|
starts (samehkhamis, #1714).
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
- Draw a vessel whose feed sends no length at its ship type's typical size, so
|
||||||
|
a cruise ship or container ship no longer shows as its type's smallest model
|
||||||
|
(samehkhamis, #1715).
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
- Collapse the CCTV panel when the layer is switched off. It stayed open with
|
||||||
|
an empty frame and a meta line that still described the last camera; the
|
||||||
|
meta line of a disabled layer now reads the catalog count. Contacts, Space
|
||||||
|
Missions and Clear selected data layers leave the panel as it is
|
||||||
|
(asturksever, #1723).
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
- Draw airport ground vehicles and ground stations as what they are instead of
|
||||||
|
the generic plane. An airport vehicle (type `ZVEH`) is a fire truck, pushback
|
||||||
|
tug, van or car by its callsign, a ground station (`GRND`) is a new 11.8 m
|
||||||
|
radio mast, and one with no altitude stands on the ground instead of at the
|
||||||
|
10 km airborne default (samehkhamis, #1729).
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
- Draw airport ground vehicles as real shapes instead of stacked boxes: the
|
||||||
|
car is an operations SUV, the van a high-roof panel van, the fire truck an
|
||||||
|
airport crash tender with turrets and the pushback a low tug with a glazed
|
||||||
|
cab, all on the ground at their built size (samehkhamis, #1730).
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
- Draw aircraft models in their own mesh colours instead of a 94% flat
|
||||||
|
white (amber for military) over the model; the tracked and emergency
|
||||||
|
colours now tint the mesh without hiding its paint (samehkhamis, #1731).
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
- An aircraft that reports no ground track (parked or taxiing, from adsb.lol
|
||||||
|
or a local receiver) now faces its reported true heading instead of north,
|
||||||
|
so one taxiing south no longer looks like it is moving backwards
|
||||||
|
(samehkhamis, #1732).
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
- Draw aids to navigation as buoys instead of ships: a buoy, beacon, RACON,
|
||||||
|
light or mark from the vessel feed (or any AIS station numbered 99MIDxxxx)
|
||||||
|
is now the fleet set's buoy of its IALA mark (cardinal, port or starboard
|
||||||
|
hand, safe water, isolated danger or special mark), standing still with no
|
||||||
|
heading, and its icon is a disc rather than a chevron. Its card and readout
|
||||||
|
show its kind of mark with no speed or heading. AISStream now subscribes to
|
||||||
|
aid-to-navigation reports and names each by its kind of mark and its full
|
||||||
|
name; the feed lists every ship ahead of any aid, and `vessels_in_area`
|
||||||
|
counts ships only. A virtual aid (a mark broadcast where nothing physical
|
||||||
|
stands) keeps its disc, is never drawn as a buoy, and its card says it is
|
||||||
|
virtual; vessel sources may mark any record `virtual` (samehkhamis, #1733).
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
- Draw transit vehicles as their kind, not one of five: trolleybuses, cable
|
||||||
|
cars, funiculars, gondolas and monorails are modes of their own, with their
|
||||||
|
own icon, colour, card word and fleet model. A vehicle record may carry its
|
||||||
|
route's GTFS `route_type` (`routeType`), which settles its mode before the
|
||||||
|
feed's route hints and picks the finer model (a coach for 200, a high-speed
|
||||||
|
set for 101). Prague's trolleybuses and Petřín funicular, and Bucharest,
|
||||||
|
Cluj and Turin's trams, trolleybuses and metro lines, now read as such from
|
||||||
|
the route ids in each operator's routes.txt. Le Havre's funicular, which its
|
||||||
|
routes.txt types as a bus, is a named correction that outranks the route
|
||||||
|
type (samehkhamis, #1734).
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
- Move Visual to the left rail, after Data Layers, Utilities and Authoring, and
|
||||||
|
lead the right column with Context; an open Context or CCTV panel takes the
|
||||||
|
column's full height. A switch in each panel header moves that side's panels
|
||||||
|
over their rail to the screen edge, and the scroll wheel at a screen edge
|
||||||
|
steps through that side's panels (manjunath22466, samehkhamis, #1735).
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
- Fix three time readings on the world timeline. A scrub near now goes live
|
||||||
|
only within two minutes of now, however long the track: with a layer whose
|
||||||
|
source covers years, any time in the last few weeks used to snap to live.
|
||||||
|
Fire cards and fire details count a detection's age from the end of the
|
||||||
|
24 hours shown, and from now only when live, so a window that ended months
|
||||||
|
ago reads "new 3h" rather than "new 105d". Weather and satellite cloud
|
||||||
|
frames stay shown, and the latest reads late, for at least one and a half
|
||||||
|
of the feed's own frame spacings, so a feed whose frames come an hour apart
|
||||||
|
no longer goes blank for half of every hour (samehkhamis, #1736).
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
- Let a host application decide where live contacts are drawn.
|
||||||
|
`createApplicationCatalog({ placement })` takes a placement provider whose
|
||||||
|
`layer(kind)` hands Flights, Military Flights, AIS Vessels, Transit and Rail
|
||||||
|
a `place(id, wallMs)` (and optionally `observe(id, fix)`, `forget(id)`):
|
||||||
|
each layer tells it every live fix it accepts and draws a contact where it
|
||||||
|
places it. Without one, or for a contact it does not place, every layer
|
||||||
|
moves as before (samehkhamis, #1737).
|
||||||
@@ -230,3 +230,125 @@ starts and switches the language with the `./i18n` entry (`startPageLocale`,
|
|||||||
`localePicker: false` to `createApplicationControls` instead of editing the
|
`localePicker: false` to `createApplicationControls` instead of editing the
|
||||||
markup. Node tests that import application modules register the component
|
markup. Node tests that import application modules register the component
|
||||||
loader with `node --import=<core package>/build/register-vue`.
|
loader with `node --import=<core package>/build/register-vue`.
|
||||||
|
|
||||||
|
### Cockpit subjects
|
||||||
|
|
||||||
|
Core's Cockpit rides a tracked aircraft, the tracked satellite and the
|
||||||
|
selected AIS vessel. An application adds kinds of its own with
|
||||||
|
`services.cockpitSubjects` on `createApplicationControls`: a list of
|
||||||
|
providers, checked once when the controls are built
|
||||||
|
(`src/cockpitSubjectProviders.js`). A malformed provider, or one with a member
|
||||||
|
that throws when read (a getter), is left out with a warning and the rest are
|
||||||
|
kept. A provider's subject takes entry when it was selected after every
|
||||||
|
built-in subject present (a tracked aircraft or satellite, a selected vessel),
|
||||||
|
whose own fixed order is unchanged, and needs the provider's `layerId` on; the
|
||||||
|
provider then holds its subject, hands the camera a frame and the generic HUD
|
||||||
|
a view model on every update, and releases it on exit. Provider methods are
|
||||||
|
synchronous and are called on the provider, so a class instance's methods keep
|
||||||
|
their `this`; one that throws or returns a promise is treated as having
|
||||||
|
failed. What a method returns may carry getters: one that throws when read
|
||||||
|
makes a candidate none, a frame malformed (the view ends) and a HUD view keep
|
||||||
|
the last; a worded member (labels, entry face, look) that throws keeps its
|
||||||
|
last good words.
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { getLocale, onLocaleChange } from 'gods-eye-view/i18n';
|
||||||
|
import { pointAtS } from 'gods-eye-view/layers/rail/paths';
|
||||||
|
|
||||||
|
const words = {
|
||||||
|
en: { view: 'Ride view', exit: 'Exit ride view', exitText: 'EXIT RIDE' },
|
||||||
|
de: {
|
||||||
|
view: 'Fahrtansicht',
|
||||||
|
exit: 'Fahrtansicht verlassen',
|
||||||
|
exitText: 'VERLASSEN',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Ride the Rail layer's selected train; `rail` is its layer instance. */
|
||||||
|
const ride = {
|
||||||
|
kind: 'example-ride',
|
||||||
|
layerId: 'rail',
|
||||||
|
entryFace: { icon: 'train', label: 'RIDE' },
|
||||||
|
// A function is read again when the page's language changes.
|
||||||
|
labels: () => words[getLocale()] ?? words.en,
|
||||||
|
candidate() {
|
||||||
|
const train = rail.getSelectedTrain();
|
||||||
|
return (
|
||||||
|
train && {
|
||||||
|
id: train.key,
|
||||||
|
name: train.label,
|
||||||
|
selectedAt: train.selectedAtMs,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
// Only a train bound to its line can be ridden: read() needs its path.
|
||||||
|
isEntryAllowed: () => Boolean(rail.getSelectedTrain()?.path),
|
||||||
|
hold: (id) => rail.setCockpitSubject(id),
|
||||||
|
read(nowMs, ctx) {
|
||||||
|
const train = rail.getCockpitSubject();
|
||||||
|
if (!train?.path) return null; // ends the view
|
||||||
|
const point = pointAtS(train.path.line, train.path.s);
|
||||||
|
return {
|
||||||
|
id: train.key,
|
||||||
|
latitude: point.lat,
|
||||||
|
longitude: point.lon,
|
||||||
|
heightM: train.position.railHeightM, // null stands it on the shared floor
|
||||||
|
name: train.label,
|
||||||
|
headingDeg:
|
||||||
|
train.path.direction < 0 ? point.bearingDeg + 180 : point.bearingDeg,
|
||||||
|
speedMps: train.motion.reportedSpeedMps ?? train.motion.derivedSpeedMps,
|
||||||
|
// The layer already moves the train smoothly: sit on it.
|
||||||
|
anchor: 'exact',
|
||||||
|
eye: { upM: 3.5 },
|
||||||
|
};
|
||||||
|
},
|
||||||
|
hud: (frame) => ({ title: frame.name }),
|
||||||
|
release(id, { restore }) {
|
||||||
|
rail.setCockpitSubject(null);
|
||||||
|
if (restore) rail.focusTrain(id);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
createApplicationControls({ /* ... */ services: { cockpitSubjects: [ride] } });
|
||||||
|
```
|
||||||
|
|
||||||
|
The `./i18n` entry gives `getLocale()` and `onLocaleChange()`:
|
||||||
|
Core translates only its own strings, so a provider words its labels, entry
|
||||||
|
face and HUD for the page's language (labels may be functions, as above; the
|
||||||
|
HUD is read again on a change). `gods-eye-view/layers/rail/paths` is the
|
||||||
|
Rail layer's pure path module (`createRailPath`, `pointAtS`, `projectOnPath`)
|
||||||
|
for a provider placing a train along its line. The frame, HUD view and
|
||||||
|
candidate fields are documented in `src/cockpitSubjectProviders.js`; the Rail
|
||||||
|
and Transit read APIs in `src/layers/rail/cockpitSubject.js` and
|
||||||
|
`src/layers/transit/cockpitSubject.js`. A snapshot read again while nothing in
|
||||||
|
it changed is the one read before, so `read` may take one on every update; a
|
||||||
|
train's `path.line` is a frozen copy of its line, for `pointAtS` and
|
||||||
|
`projectOnPath`. The `layers/rail/paths` export and the
|
||||||
|
Rail and Transit read APIs (`getSelectedTrain`, `getSelectedVehicle`,
|
||||||
|
`getCockpitSubject` and the snapshots they return, `path.line` among them)
|
||||||
|
are experimental and may change without notice.
|
||||||
|
|
||||||
|
A candidate's `selectedAt` is a token that changes each time the user selects
|
||||||
|
the subject, even the same one again, so entry counts it as selected then; a
|
||||||
|
new `id` under the same token is the same selection (a train's selection
|
||||||
|
moving to another feed's copy of it). The Rail and Transit snapshots give one,
|
||||||
|
`selectedAtMs`: when the user last selected the train or vehicle by a click or
|
||||||
|
`focusTrain`/`focusVehicle`. It is null after a deselection and for one
|
||||||
|
selected only by a hold, since a hold is not the user's selection.
|
||||||
|
|
||||||
|
A frame with `heightM: null` stands on the shared floor, or where it last
|
||||||
|
stood while that floor is cold. If no height has been known since entry, the
|
||||||
|
view waits, showing ACQUIRING SURFACE, for at most five seconds
|
||||||
|
(`COCKPIT_GROUND_WAIT_TIMEOUT_MS`), then ends and releases the subject.
|
||||||
|
|
||||||
|
`hold(id)` returns `true` once it holds the subject, or `false` to refuse
|
||||||
|
entry; any other answer, `undefined` included, refuses entry too, with one
|
||||||
|
warning. A refused hold, and one that throws or returns a promise, is followed
|
||||||
|
by `release(id, { restore: false })`, again once a returned promise settles,
|
||||||
|
so `release` must be harmless for a subject it does not hold and when called
|
||||||
|
more than once.
|
||||||
|
|
||||||
|
Leaving the view does not track again an aircraft that was tracked before
|
||||||
|
entry, as with the bridge and orbital views: when the user leaves by the exit
|
||||||
|
control, the map goes back to the ridden subject through
|
||||||
|
`release(id, { restore: true })`.
|
||||||
+236
-22
@@ -365,6 +365,25 @@ The source factories are exported at `layers/directions/source` and
|
|||||||
`layers/recent-imagery/source`. Configuration is applied at construction time;
|
`layers/recent-imagery/source`. Configuration is applied at construction time;
|
||||||
this does not introduce live source replacement.
|
this does not introduce live source replacement.
|
||||||
|
|
||||||
|
Application catalog composition also accepts an optional `placement`, a
|
||||||
|
host-supplied placement provider (`src/data/placementProvider.js`): an object
|
||||||
|
whose `layer(kind)` returns, for `aircraft`, `military`, `vessels`, `transit`
|
||||||
|
or `rail`, either null or `{ place(id, wallMs), observe?(id, fix),
|
||||||
|
forget?(id) }`. While live, each of those layers tells it every fix it accepts
|
||||||
|
(time, position, the height it draws the fix at, reported speed, course and
|
||||||
|
ground state) and draws a contact where `place` puts it: position, height
|
||||||
|
(the layer's own when none is given), course and speed. A null answer, a
|
||||||
|
provider that throws, a kind it leaves out, or no provider at all keeps the
|
||||||
|
layer's own motion, unchanged; following the world clock, the layers never
|
||||||
|
ask it. Transit and rail vehicles a provider places are advanced every frame
|
||||||
|
in view while their placed position changes; one it holds still lets the
|
||||||
|
render loop idle and is asked again each second, moving on once its placement
|
||||||
|
does. A placed transit vehicle is drawn at its placed point, and a placed
|
||||||
|
train where it is placed rather than on its bound railway line. Live vessels
|
||||||
|
a provider places move on between refreshes: redrawn in place at most every
|
||||||
|
250 ms, with a frame asked for each second while the provider places any
|
||||||
|
drawn vessel, and none once the layer is off.
|
||||||
|
|
||||||
Application catalog composition accepts an optional `streetLevelProviders` list.
|
Application catalog composition accepts an optional `streetLevelProviders` list.
|
||||||
An explicit list replaces the default Mapillary provider; an empty list removes
|
An explicit list replaces the default Mapillary provider; an empty list removes
|
||||||
all imagery providers. Without that option, Mapillary is registered only when
|
all imagery providers. Without that option, Mapillary is registered only when
|
||||||
@@ -627,6 +646,36 @@ panel that holds its row, and `set_panel_open` reaches it as
|
|||||||
`utilities-panel` or by "utilities", "draw", "drawing" or "import". On a phone
|
`utilities-panel` or by "utilities", "draw", "drawing" or "import". On a phone
|
||||||
it sits collapsed in the Layers sheet under Data Layers.
|
it sits collapsed in the Layers sheet under Data Layers.
|
||||||
|
|
||||||
|
## Side rails and the screen edge — November 14, 2026
|
||||||
|
|
||||||
|
Visual (`#pp-toggles`, the display settings, rail item `palette`) is the last
|
||||||
|
panel of the left column, after Data Layers, Utilities and Authoring, and
|
||||||
|
opens from the left rail like them (`PanelLayoutController`, falling back to
|
||||||
|
the right column in a host without a left stack). Context leads the right
|
||||||
|
column, followed by CCTV, Street Level and the other right panels. An open
|
||||||
|
Context or CCTV panel takes the column's full height; the other right panels
|
||||||
|
keep the content-sized layout and its hysteresis band. With nothing open, a
|
||||||
|
rail's icons and their names show as two glass pieces side by side; once a
|
||||||
|
panel opens, the icons stay in place and a highlight slides to the open one.
|
||||||
|
|
||||||
|
Each collapsible panel header has an edge switch (`UiPanelEdge.vue`,
|
||||||
|
`src/ui/panelEdge.js`): it moves that side's panels over their rail to the
|
||||||
|
screen edge, with the rail as a row of icons above the open panel, and back.
|
||||||
|
The choice is per side, kept in `localStorage` (`gev.panelEdge`), and applies
|
||||||
|
on the desktop shell only: phones and Cockpit keep their own layouts and do
|
||||||
|
not show the switch.
|
||||||
|
|
||||||
|
Scrolling the wheel at a screen edge (`src/ui/railEdgeScroll.js`, from the
|
||||||
|
edge to just past the rail, at most 84 px) steps that side's rail to its next
|
||||||
|
or previous panel instead of zooming the globe, wrapping round at either end.
|
||||||
|
One gesture is one step, trackpad coasting included, with at least half a
|
||||||
|
second between steps; a step that comes too soon is held until then and is
|
||||||
|
dropped if the pointer leaves the strip. Panels, controls, dialogs and the
|
||||||
|
world timeline in the strip keep their own wheel. The strip is off on phones
|
||||||
|
and touch screens, while the rails are hidden (clean view, recording), and it
|
||||||
|
follows the rails' sides in a right-to-left language. On a phone, Visual is in
|
||||||
|
the More sheet with the dock's Visual Presets, as before.
|
||||||
|
|
||||||
## God's Eye View in conversations — October 2, 2026
|
## God's Eye View in conversations — October 2, 2026
|
||||||
|
|
||||||
Tool answers that can be shown in God's Eye View include a view: camera, layers,
|
Tool answers that can be shown in God's Eye View include a view: camera, layers,
|
||||||
@@ -1706,7 +1755,7 @@ Applications supply the existing floor/snap, geoid, picking, sprite, camera,
|
|||||||
trail, focus, readout, context, aircraft presentation and render services.
|
trail, focus, readout, context, aircraft presentation and render services.
|
||||||
The factory never constructs a second application registry. Configure a source
|
The factory never constructs a second application registry. Configure a source
|
||||||
before initialization; replacing it while initialized is rejected. Model loads
|
before initialization; replacing it while initialized is rejected. Model loads
|
||||||
use the supplied asset resolver, including the preload path. Enrichment receives
|
use the supplied asset resolver, including the up-front fleet set load. Enrichment receives
|
||||||
an abort signal and cannot update a later lifecycle after destruction. Existing
|
an abort signal and cannot update a later lifecycle after destruction. Existing
|
||||||
camera, terrain floor, trail, selection and measured model-size policies remain.
|
camera, terrain floor, trail, selection and measured model-size policies remain.
|
||||||
|
|
||||||
@@ -2208,6 +2257,83 @@ the subject (tracking stopped, Satellites off) or tracking another target
|
|||||||
ends the view without refocusing. `src/ui/cockpitOrbitalView.test.mjs`
|
ends the view without refocusing. `src/ui/cockpitOrbitalView.test.mjs`
|
||||||
covers entry, camera, zoom, look, HUD and exit.
|
covers entry, camera, zoom, look, HUD and exit.
|
||||||
|
|
||||||
|
### Application subjects
|
||||||
|
|
||||||
|
An application can add its own first-person subjects beside the aircraft,
|
||||||
|
vessel and satellite: `services.cockpitSubjects` to `createApplicationControls`,
|
||||||
|
a list of subject providers (`src/cockpitSubjectProviders.js`, checked once by
|
||||||
|
the coordinator; a malformed one, or one with a member that throws when read,
|
||||||
|
is left out with a warning and the rest are kept). A provider names
|
||||||
|
its layer, an entry face and labels in the page's language, and supplies four
|
||||||
|
operations: `candidate()` (what entry would ride now), `hold(id)`,
|
||||||
|
`read(nowMs, ctx)` (a camera frame each update) and `hud(frame, ctx)` (a HUD
|
||||||
|
view model), with `release(id, {restore})` on exit. Entry needs the provider's
|
||||||
|
layer on, no Context change in flight and the provider's own
|
||||||
|
`isEntryAllowed(candidate)`; voice stays aircraft-only and is refused, with
|
||||||
|
the reason, while a provider's view is in use.
|
||||||
|
|
||||||
|
The built-in kinds keep their fixed entry order (a tracked aircraft, then the
|
||||||
|
tracked satellite, then the selected vessel), so without providers entry is
|
||||||
|
unchanged. A provider's candidate takes entry only when it was selected after
|
||||||
|
every built-in subject present, by when the Cockpit first saw it or saw it
|
||||||
|
selected again (its `selectedAt` changing): a train picked after an aircraft
|
||||||
|
was tracked takes entry, and an aircraft tracked after it takes it back.
|
||||||
|
Providers' candidates are ordered most recently selected first, then by
|
||||||
|
priority; one first seen together with a built-in subject comes after it. The
|
||||||
|
first in that order decides alone: when its gate is shut there is no entry
|
||||||
|
rather than the next subject's.
|
||||||
|
|
||||||
|
A frame places the eye `eye.upM` above `heightM` (the shared floor where the
|
||||||
|
frame gives none, or where it last stood while that floor is cold; with
|
||||||
|
neither, the camera stays where it is and the HUD reads ACQUIRING SURFACE for
|
||||||
|
at most `COCKPIT_GROUND_WAIT_TIMEOUT_MS`, after which the view ends and the
|
||||||
|
subject is released: no height stands in for a floor never read), slews toward `headingDeg` at the provider's rate, and may
|
||||||
|
turn off the floor clamps (`groundClamp: false`, for a subject inside a
|
||||||
|
structure) or keep the anchor exactly on the subject (`anchor: 'exact'`, for a
|
||||||
|
layer that already moves it smoothly; a frame with no `speedMps` is always
|
||||||
|
exact, since an inertial anchor runs on at the frame's speed); `cameraIntervalMs: 0` updates the
|
||||||
|
camera every rendered frame. A frame that is null, malformed or for another
|
||||||
|
subject ends the view (`restoreTracking: false`), as an aircraft tracked
|
||||||
|
meanwhile and the provider's layer turning off do; the exit control asks the
|
||||||
|
provider to restore its subject. The generic HUD shows the provider's kicker,
|
||||||
|
title, meta line, speed with its unit and tag, readout cards, always-visible
|
||||||
|
source rows, banner, route card and Live Signals rows, a veil that darkens the
|
||||||
|
picture under the HUD (with passing light streaks, which stop under reduced
|
||||||
|
motion), arrow-key look-around when the provider asks for it, and a progress
|
||||||
|
line along the bottom edge (`src/cockpitProgress.js`: close ticks merge,
|
||||||
|
labels never overlap). Core translates none of the provider's text: a host
|
||||||
|
words it for the page's language (`gods-eye-view/i18n`:
|
||||||
|
`getLocale`, `onLocaleChange`). Its entry face, labels and look may be
|
||||||
|
functions, read again when they are shown and on a change of language, as the
|
||||||
|
HUD view is.
|
||||||
|
|
||||||
|
The Rail layer offers a read API for such a view: `getSelectedTrain()` and
|
||||||
|
`getCockpitSubject()` (a snapshot of the train: where it is along its line,
|
||||||
|
which way it runs (`pathBinding.js` learns it), its rail height, speed as
|
||||||
|
reported or derived, position source, feed credit and stops, and
|
||||||
|
`selectedAtMs`, when the user last selected it by a click or `focusTrain`,
|
||||||
|
even again; null after a deselection and for a train only a hold selected),
|
||||||
|
`setCockpitSubject(key)` (its marker, 3D model and card hidden, the selection kept, its
|
||||||
|
feed held, clicks and Escape left to the view; the held copy stays the one
|
||||||
|
drawn of its train while held, another feed's copy hidden, and it keeps
|
||||||
|
moving, still selected, when its category is turned off) and
|
||||||
|
`focusTrain(key)` (false for a train the layer does not draw); its pure path
|
||||||
|
module is exported as `gods-eye-view/layers/rail/paths`. That export
|
||||||
|
and these read APIs are experimental and may change without notice. A snapshot read again while nothing in it changed is
|
||||||
|
the one read before, and its `path.line` is a frozen copy. Transit
|
||||||
|
offers the same for a vehicle (`getSelectedVehicle`, `getCockpitSubject`,
|
||||||
|
`setCockpitSubject`, `focusVehicle`): a held vehicle keeps playing when it is
|
||||||
|
out of the camera's view, and its sprite, 3D model, card, trail and detection
|
||||||
|
box are hidden; released, it is out of play until a visibility sweep finds it in
|
||||||
|
view. Its snapshot's `position.groundHeightM` is the floor where playback draws
|
||||||
|
it (the drawn marker's height while it is placed, else its segment's two
|
||||||
|
reports' floors at the playback fraction), not the newest report's, and null while that floor is unknown. Rail's `path.direction` is the
|
||||||
|
way the drawn train runs: once playback has placed it, a report that runs back
|
||||||
|
turns it only when playback reaches that report. `docs/APPLICATION.md` (Cockpit subjects) shows a minimal provider. `src/ui/cockpitSubjectView.test.mjs`,
|
||||||
|
`src/cockpitSubjectProviders.test.mjs`, `src/cockpitProgress.test.mjs`,
|
||||||
|
`src/layers/rail/cockpitSubject.test.mjs` and the Transit lifecycle tests
|
||||||
|
cover them.
|
||||||
|
|
||||||
## Context coordination
|
## Context coordination
|
||||||
|
|
||||||
Context controls own Contacts/Space Missions state, entry and exit transactions,
|
Context controls own Contacts/Space Missions state, entry and exit transactions,
|
||||||
@@ -2229,6 +2355,17 @@ shown without a fade once it is decoded (or after one second if its decode never
|
|||||||
settles), so a new camera's preview is blank only while its frame loads. Disposal
|
settles), so a new camera's preview is blank only while its frame loads. Disposal
|
||||||
releases listeners, subscriptions, image handlers, summary timers and chip-hide timers.
|
releases listeners, subscriptions, image handlers, summary timers and chip-hide timers.
|
||||||
|
|
||||||
|
The panel opens when a camera becomes active and collapses when the layer is
|
||||||
|
switched off, from its own switch or anywhere else. The panel chrome applies
|
||||||
|
the collapse, so a panel the desktop accordion only folded has its saved and
|
||||||
|
shared state closed too. Clear selected data layers and Context isolation
|
||||||
|
(Contacts, Space Missions) switch the layer off without the user asking: the
|
||||||
|
panel and its share preference stay as they are, and the layer comes back to an
|
||||||
|
open panel. Only the switch-off isolation makes counts (`suspendsLayer`, true
|
||||||
|
while `_clearLayersOutsideContextMode` switches the layer off): the user
|
||||||
|
switching CCTV off inside Contacts closes the panel as anywhere else. A panel opened by hand while the layer is off stays open, and its
|
||||||
|
meta line reads the catalog count, not the last active camera.
|
||||||
|
|
||||||
## UI disposal
|
## UI disposal
|
||||||
|
|
||||||
UI disposal releases the CCTV subscription, command-dock observer, legacy drag
|
UI disposal releases the CCTV subscription, command-dock observer, legacy drag
|
||||||
@@ -2420,8 +2557,9 @@ is validated against Cesium 1.138.0 and must be revalidated on upgrades.
|
|||||||
|
|
||||||
`scripts/qa-anime-sky.mjs` checks asset readiness, visible Normal sky and
|
`scripts/qa-anime-sky.mjs` checks asset readiness, visible Normal sky and
|
||||||
Anime band coverage against a Vite dev server.
|
Anime band coverage against a Vite dev server.
|
||||||
`scripts/qa-sky-model-lighting.mjs` compares a lit `airplane.glb` against
|
`scripts/qa-sky-model-lighting.mjs` compares a lit fleet airliner
|
||||||
black and white environment maps in isolated scenes.
|
(`public/models/fleet/aircraft/a320.glb`) against black and white environment
|
||||||
|
maps in isolated scenes.
|
||||||
|
|
||||||
## Model atmosphere on Apple Metal
|
## Model atmosphere on Apple Metal
|
||||||
|
|
||||||
@@ -2442,6 +2580,53 @@ future driver fix restores the effect with no code change; iOS/iPadOS platform
|
|||||||
detection is the backstop for when no probe context can be created. Applied
|
detection is the backstop for when no probe context can be created. Applied
|
||||||
during viewer construction, before any tile builds a draw command.
|
during viewer construction, before any tile builds a draw command.
|
||||||
|
|
||||||
|
## Render failure notice
|
||||||
|
|
||||||
|
When the globe stops drawing, the scene chrome says so instead of leaving a
|
||||||
|
black globe behind working controls. `installRenderFailureNotice()`
|
||||||
|
(`src/ui/renderFailure.js`) listens for Cesium's `renderError` and the canvas'
|
||||||
|
`webglcontextlost`, logs the error, and publishes a notice that
|
||||||
|
`RenderFailure.vue` shows as an alert dialog with focus on its first action.
|
||||||
|
The app's viewer uses `showRenderLoopErrors: false`, so Cesium's dead-end
|
||||||
|
"Rendering has stopped" panel no longer appears; `applicationViewerOptions()`
|
||||||
|
keeps it by default for other callers.
|
||||||
|
|
||||||
|
- **Retry** restarts the render loop. The notice stays until a frame starts
|
||||||
|
and ends without an error: Cesium raises `postRender` after a failed frame
|
||||||
|
too.
|
||||||
|
- **Reload**, after a lost context, reloads the page; the address keeps the
|
||||||
|
view.
|
||||||
|
- **Reset view** opens `appRootUrl()`, without the hash or `/share/<code>`
|
||||||
|
path; the query, such as `?lang=`, is kept.
|
||||||
|
|
||||||
|
Pitfalls:
|
||||||
|
|
||||||
|
- An error thrown outside Scene's error handling (a frame listener, `onTick`,
|
||||||
|
a resize) stops the loop without a `renderError`. The notice wraps the
|
||||||
|
widget's `render()` and `resize()` and raises it as one, once even with
|
||||||
|
`rethrowRenderErrors`.
|
||||||
|
- A throwing listener leaves its Cesium event mid-raise, with listener changes
|
||||||
|
only queued. The wrapper finishes those raises first (`finishRaise()` over
|
||||||
|
`frameEvents()`), so a layer turned off or on meanwhile behaves.
|
||||||
|
- A render error marks the loop stopped while its next frame is still queued.
|
||||||
|
The wrapper keeps the loop marked running, so a Retry or a shown tab
|
||||||
|
(`src/app/tools.js`) before that frame starts no second loop.
|
||||||
|
- After a lost context, later render errors are only logged, so the notice
|
||||||
|
keeps saying why. The listener neither prevents nor restores the loss.
|
||||||
|
- When the globe draws again, focus goes back where it was, or to the globe's
|
||||||
|
canvas, which the map's keys read as the map; the canvas is focusable only
|
||||||
|
until focus leaves or the globe is pressed. Focus the user moved stays put.
|
||||||
|
- The notice sits above floating panels such as the Québec camera viewer, and
|
||||||
|
its buttons are 44 px tall on touch screens.
|
||||||
|
|
||||||
|
An inline conversation panel never reloads or navigates its host's page: it
|
||||||
|
offers Retry after a render error only, and no notice after a lost context,
|
||||||
|
where the panel runtime's own notice applies (`src/app/globePanelRuntime.js`).
|
||||||
|
Its timer (`keepPanelRendering()`) draws only while the render loop is on and
|
||||||
|
logs nothing itself, so each render error is logged once, by the notice. An
|
||||||
|
error a timer frame throws is caught there: it has already been raised as a
|
||||||
|
render error.
|
||||||
|
|
||||||
## Map Source control ownership
|
## Map Source control ownership
|
||||||
|
|
||||||
Map Source controls own chip listeners, source-state subscriptions and selection
|
Map Source controls own chip listeners, source-state subscriptions and selection
|
||||||
@@ -3289,7 +3474,8 @@ reads `NASA FIRMS · LIVE · updated …`. A source may instead answer the 24 ho
|
|||||||
to a set time, naming its end as `at` (epoch ms): the row then reads
|
to a set time, naming its end as `at` (epoch ms): the row then reads
|
||||||
`NASA FIRMS · 24 h to MM-DD HH:MM UTC`, `getStats()` reports `at`, and
|
`NASA FIRMS · 24 h to MM-DD HH:MM UTC`, `getStats()` reports `at`, and
|
||||||
`get_active_fires` says "in the 24 hours to" that time and reports it as
|
`get_active_fires` says "in the 24 hours to" that time and reports it as
|
||||||
`window_end`. The dev proxy never sets `at`.
|
`window_end`, and card and detail ages count back from that time instead of
|
||||||
|
now. The dev proxy never sets `at`.
|
||||||
|
|
||||||
The FIRMS CSV parser rejects impossible acquisition calendar dates before the proxy filters records to the trailing 24 hours, while retaining valid UTC acquisition times.
|
The FIRMS CSV parser rejects impossible acquisition calendar dates before the proxy filters records to the trailing 24 hours, while retaining valid UTC acquisition times.
|
||||||
FIRMS ages round to whole hours before choosing a unit, so a 47.6-hour age reads "2d", not "48h"; with detections filtered to 24 hours, this shows mostly in the `STALE · cached {age}` stats line.
|
FIRMS ages round to whole hours before choosing a unit, so a 47.6-hour age reads "2d", not "48h"; with detections filtered to 24 hours, this shows mostly in the `STALE · cached {age}` stats line.
|
||||||
@@ -3606,20 +3792,22 @@ This is the current runtime/source-of-truth snapshot for the project.
|
|||||||
> 24.09 m aft (70 % of the model's rendered envelope, so inside it), 2.22 m
|
> 24.09 m aft (70 % of the model's rendered envelope, so inside it), 2.22 m
|
||||||
> below centre (6 %), and 2e-9 m off the centreline.
|
> below centre (6 %), and 2e-9 m off the centreline.
|
||||||
> - **The tracked trail attaches to REAL HULL, aft and below (2026-08-23):**
|
> - **The tracked trail attaches to REAL HULL, aft and below (2026-08-23):**
|
||||||
> `MODEL_TRAIL_ANCHOR_NATIVE` (`src/data/modelVisualAnchor.js`) holds, per GLB
|
> `FLEET_TRAIL_ANCHORS` (`src/data/fleetTrailAnchors.js`, generated by
|
||||||
> and in RAW glTF coordinates (see the transform-chain entry below), the point
|
> `scripts/measure-fleet-trail-anchors.mjs`) holds, per fleet aircraft and
|
||||||
> of the hull's CENTRELINE PROFILE (its y = 0 slice) closest to the aft-belly
|
> helicopter model and in RAW glTF coordinates (see the transform-chain entry
|
||||||
> AABB corner. It is NOT the corner: a bounding-box corner is empty
|
> below), the point of the hull's CENTRELINE PROFILE (its centreline slice)
|
||||||
> space, 4.80 m off the nearest triangle on `airplane.glb` and 6.14 m on
|
> closest to the aft-belly AABB corner. It is NOT the corner: a bounding-box
|
||||||
> `jet.glb`, so the trail ended in mid air beside the aircraft. The head segment
|
> corner is empty space (4.80 m off the nearest triangle on the airliner
|
||||||
|
> asset this was first measured on, 6.14 m on the jet), so the trail ended in
|
||||||
|
> mid air beside the aircraft. The head segment
|
||||||
> is drawn from a point behind the aircraft to this anchor, so the anchor must
|
> is drawn from a point behind the aircraft to this anchor, so the anchor must
|
||||||
> stay aft (83–96 % of each aft extreme) or the segment enters at the tail and
|
> stay aft (83–96 % of each aft extreme) or the segment enters at the tail and
|
||||||
> stops inside the fuselage. `modelScale.test.mjs` reads the POSITION BUFFERS —
|
> stops inside the fuselage. `fleetModels.test.mjs` reads the POSITION BUFFERS —
|
||||||
> real vertices and triangles, because accessor min/max cannot tell a corner
|
> real vertices and triangles, because accessor min/max cannot tell a corner
|
||||||
> from a surface — and re-derives on-hull, aft, lowest-at-its-station,
|
> from a surface — and re-derives on-hull, aft, lowest-at-its-station,
|
||||||
> on-centreline, and the construction itself. Re-measure, never re-guess.
|
> on-centreline, and the construction itself. Re-measure, never re-guess.
|
||||||
> - **The trail anchor rides CESIUM'S transform chain, not a hand-rolled one
|
> - **The trail anchor rides CESIUM'S transform chain, not a hand-rolled one
|
||||||
> (2026-08-23 regression fix):** `MODEL_TRAIL_ANCHOR_NATIVE` stores RAW
|
> (2026-08-23 regression fix):** `FLEET_TRAIL_ANCHORS` stores RAW
|
||||||
> glTF coordinates and `modelAnchorWorld()` assembles
|
> glTF coordinates and `modelAnchorWorld()` assembles
|
||||||
> `modelMatrix × components.transform × axisCorrection` — the same chain
|
> `modelMatrix × components.transform × axisCorrection` — the same chain
|
||||||
> `ModelSceneGraph` renders with, built from Cesium's own exported
|
> `ModelSceneGraph` renders with, built from Cesium's own exported
|
||||||
@@ -3654,7 +3842,7 @@ This is the current runtime/source-of-truth snapshot for the project.
|
|||||||
> ENVELOPE, and between them the drawn start slides along the segment so the
|
> ENVELOPE, and between them the drawn start slides along the segment so the
|
||||||
> visible length grows CONTINUOUSLY from zero. Three earlier cuts are recorded
|
> visible length grows CONTINUOUSLY from zero. Three earlier cuts are recorded
|
||||||
> because their shape matters: testing segment LENGTH against the radius HID
|
> because their shape matters: testing segment LENGTH against the radius HID
|
||||||
> real trail (58 m aft of `airplane.glb`'s 34.41 m envelope gives a 33.98 m
|
> real trail (58 m aft of an airliner's 34.41 m envelope gives a 33.98 m
|
||||||
> segment, suppressed, though ~23.6 m of it is open air); CLIPPING at the
|
> segment, suppressed, though ~23.6 m of it is open air); CLIPPING at the
|
||||||
> envelope and keeping only what lay outside stopped a moving trail visibly
|
> envelope and keeping only what lay outside stopped a moving trail visibly
|
||||||
> SHORT of the aircraft, since a bounding sphere encloses a lot of empty space
|
> SHORT of the aircraft, since a bounding sphere encloses a lot of empty space
|
||||||
@@ -4830,8 +5018,9 @@ activeCameraCardEnabled: true })` may publish it through the retained
|
|||||||
> - **Flights 3D/cockpit hardening:** the destination-direction cue is an
|
> - **Flights 3D/cockpit hardening:** the destination-direction cue is an
|
||||||
> inline SVG rather than a remotely loaded Material Icons ligature, so a
|
> inline SVG rather than a remotely loaded Material Icons ligature, so a
|
||||||
> blocked or late font can no longer expand the literal word `navigation`
|
> blocked or late font can no longer expand the literal word `navigation`
|
||||||
> across the cockpit. The grounded `airplane.glb` belly offset is calibrated
|
> across the cockpit. A grounded aircraft stands its fleet model's scaled
|
||||||
> to the current asset's measured Y-up bounds (`0.063` native units).
|
> clearance (the catalog's `clearance`, measured below the model's origin)
|
||||||
|
> above the ground.
|
||||||
> Contact Previous/Next and Live Signals aircraft handoffs now
|
> Contact Previous/Next and Live Signals aircraft handoffs now
|
||||||
> re-seed the first-person camera anchor at the selected flight immediately;
|
> re-seed the first-person camera anchor at the selected flight immediately;
|
||||||
> bounded feed-correction smoothing remains scoped to the same aircraft.
|
> bounded feed-correction smoothing remains scoped to the same aircraft.
|
||||||
@@ -5729,7 +5918,26 @@ Helsinki, the Netherlands, Norway, South East Queensland, Rio de Janeiro
|
|||||||
Ontario — Toronto (TTC surface vehicles; the subway publishes no
|
Ontario — Toronto (TTC surface vehicles; the subway publishes no
|
||||||
positions), MiWay, Hamilton HSR, Durham Region, YRT/Viva, Guelph,
|
positions), MiWay, Hamilton HSR, Durham Region, YRT/Viva, Guelph,
|
||||||
Burlington, Barrie and Kingston. Mode silhouettes
|
Burlington, Barrie and Kingston. Mode silhouettes
|
||||||
identify buses, trams, subways, trains, ferries and unclassified vehicles.
|
identify buses, trolleybuses, trams, cable cars, subways, monorails, trains,
|
||||||
|
funiculars, gondolas (aerial lifts), ferries and unclassified vehicles.
|
||||||
|
|
||||||
|
A vehicle's mode comes from, in order: the feed's fleet-number hint
|
||||||
|
(`vehicleMode`, which knows a bus standing in on a streetcar route); the feed's
|
||||||
|
correction for a route its own routes.txt mistypes (`routeCorrections`: Le
|
||||||
|
Havre's funicular `8-FUNI`, which LiA's routes.txt types as a bus); the GTFS
|
||||||
|
`route_type` of its route, when its record carries one as `routeType` (basic
|
||||||
|
0–12 or extended 100–1799, each extended type taken as the basic mode it is a
|
||||||
|
kind of: 200 coach is a bus, 101 high-speed is rail, 405 is a monorail); the
|
||||||
|
feed's route-id hint (`routeMode`); and the feed's default (`transitModeFor`,
|
||||||
|
`src/data/transitFeeds.js`). The GTFS-Realtime decoder carries no route type, so
|
||||||
|
a record from the bundled proxy is classified by the hints alone. Route hints
|
||||||
|
read from each operator's routes.txt cover Prague's trolleybus lines and Petřín
|
||||||
|
funicular, and Bucharest, Cluj-Napoca and Turin's trams, trolleybuses and metro
|
||||||
|
lines (and Turin's Sassi–Superga rack tramway, typed a funicular in its
|
||||||
|
routes.txt). Le Havre's funicular is a correction, not read from routes.txt: its
|
||||||
|
route hint and its correction both say funicular. Vilnius publishes no route ids in its positions, so
|
||||||
|
its trolleybuses read as buses. Retained history classifies its epochs the same
|
||||||
|
way, so a trail joins the live vehicle.
|
||||||
|
|
||||||
Retained transit history uses the same outlier quarantine as live observations and
|
Retained transit history uses the same outlier quarantine as live observations and
|
||||||
preserves the active live bracket. Rejected reports do not publish route or mode
|
preserves the active live bracket. Rejected reports do not publish route or mode
|
||||||
@@ -5795,9 +6003,10 @@ External halos are 1/1.5 px in normal, 1.25/1.25 px in CRT and 2/2 px in sensors
|
|||||||
final unpadded display size. Each mode has an outline with a front (a nose, a
|
final unpadded display size. Each mode has an outline with a front (a nose, a
|
||||||
bow or a chamfered cab) for a vehicle with a known course and a symmetric
|
bow or a chamfered cab) for a vehicle with a known course and a symmetric
|
||||||
outline for one without, which would otherwise sit at rotation 0 and point
|
outline for one without, which would otherwise sit at rotation 0 and point
|
||||||
north; a vehicle switches to the pointed glyph when a course arrives. Six modes, two sizes, three
|
north; a vehicle switches to the pointed glyph when a course arrives. Eleven modes, two sizes, three
|
||||||
profiles and the two outlines cap the raster cache at 72 variants. Normal mode colours are bus `#5EF08A`, tram
|
profiles and the two outlines cap the raster cache at 132 variants. Normal mode colours are bus `#5EF08A`,
|
||||||
`#FFC24A`, subway `#FF4538`, rail `#D9A6FF`, ferry `#5FD6FF`, and unknown
|
trolleybus `#B6F04A`, tram `#FFC24A`, cable car `#FF8F4A`, subway `#FF4538`, monorail `#FF6FB8`, rail
|
||||||
|
`#D9A6FF`, funicular `#E8C98A`, gondola `#7FA8FF`, ferry `#5FD6FF`, and unknown
|
||||||
`#D8DDE5`. Selection keeps the mode colour. Sensors reuse each normal silhouette's exact
|
`#D8DDE5`. Selection keeps the mode colour. Sensors reuse each normal silhouette's exact
|
||||||
outer path, filled opaque white without interior panel lines, with an opaque
|
outer path, filled opaque white without interior panel lines, with an opaque
|
||||||
`#05080C` halo. Only the external padding grows; the unpadded silhouette remains
|
`#05080C` halo. Only the external padding grows; the unpadded silhouette remains
|
||||||
@@ -7290,8 +7499,9 @@ pins and share links already supply complete boxes.
|
|||||||
normal four-samples-per-250-ms budget. Retry timestamps more than the maximum
|
normal four-samples-per-250-ms budget. Retry timestamps more than the maximum
|
||||||
30-second backoff ahead of the current clock are ignored. A smaller rollback
|
30-second backoff ahead of the current clock are ignored. A smaller rollback
|
||||||
can retain a bounded retry delay of up to 30 seconds.
|
can retain a bounded retry delay of up to 30 seconds.
|
||||||
- Commercial and military aircraft use the same high-level FLEET model regime: 2D billboards when zoomed out, optional glTF models when closer, controlled by the DISPLAY rail `3D` toggle and `Proximity` / `All` modes. Since 2026-08-16 (Hangar fleet) models are PER-CLASS: real CC-BY GLBs for light/bizjet/turboprop/widebody/helicopter/uav (`CLASS_MODEL_REAL` in `src/data/aircraftClass.js` — meters-baked, scale 1, per-model belly/radius; provenance in `public/models/README.md`), the shared `airplane.glb` for the remaining civilian classes, and the military layer maps weight classes (real GLBs / 747 heavies / `jet.glb` fastjets, per-model heading offsets, flat amber or emergency red). Textured civilians carry a HEAVY tint, not a light one: `MODEL_COLOR_BLEND_AMOUNT` is `0.94` in BOTH layers under Cesium's `ColorBlendMode.MIX`, so the class colour supplies 94% of the surface and the asset's own texture ~6%. The visual direction is clean light silhouettes with only a weak diffuse contribution from the approved textures, so liveries deliberately do NOT read. IR boost raises the blend to a full `1.0`. Under NVG/FLIR (map preset or Cockpit vision) models render unlit flat-white at full alpha and scene fog is disabled (fog otherwise blacks out distant models with the globe hidden); state restores on exit.
|
- Commercial and military aircraft use the same high-level FLEET model regime: 2D billboards when zoomed out, optional glTF models when closer, controlled by the DISPLAY rail `3D` toggle and `Proximity` / `All` modes. Every model is one of the project's procedural fleet models (`public/models/fleet/`, MIT, 122 GLBs, about 2 MB in all; `public/models/README.md`), chosen per aircraft by `aircraftModelSpec` (`src/data/fleetModels.js`): the first of its ICAO type's callsign rules in `types.json` (`aircraft_callsign`) its callsign matches, else its type's entry, else the model of its `classifyAircraft` class for a type the map lacks, else its ADS-B emitter category's, else the default airliner. It is drawn LIFE SIZE: the type's published length over the model's built length (`src/layers/flights/modelSpec.js`, shared by Flights, Military Flights and Local ADS-B), and a grounded aircraft stands the model's scaled clearance above the ground. An airport ground vehicle (feed type `ZVEH`) is a fire truck (`FIRE…`), pushback tug (`PUSH…`, `TUG…`), van (`DEICER…`, `SQUID…`, `SQB…`) or else a car by its callsign, and a ground station (`GRND`) is an 11.8 m radio mast; these models (catalog category `other`) are drawn at their built size, and such a contact with no altitude stands on the ground instead of at the airborne default (`src/layers/flights/records.js`). `classifyAircraft` still picks the 2D icons. The whole set loads once, up front, when a layer that draws it starts (`loadFleetModelSet`, which logs `[Fleet] N/122 models (X MB) loaded in N ms`); models are built from those bytes, never fetched mid-session, and an aircraft stays its billboard until the set has loaded. Every aircraft model draws its mesh's own colours (`aircraftModelBlend`, `src/data/aircraftModelLighting.js`): Cesium's `ColorBlendMode.HIGHLIGHT` with white, in Flights, Military Flights and Local ADS-B alike; the tracked colour (cyan, or amber in Military Flights) and the emergency red multiply into the mesh, so its paint still shows. IR boost draws them flat white (`MIX` at `1.0`). Under NVG/FLIR (map preset or Cockpit vision) models render unlit flat-white at full alpha and scene fog is disabled (fog otherwise blacks out distant models with the globe hidden); state restores on exit.
|
||||||
- **Aircraft models skip Cesium's dynamic environment map (2026-10-24).** Flights, Military Flights and Local ADS-B pass `environmentMapOptions: AIRCRAFT_ENVIRONMENT_MAP_OPTIONS` (`{ enabled: false }`, `src/data/aircraftModelLighting.js`) to every drawn model. Otherwise each `Model` renders the sky around it and reads it back from the GPU (`readPixels`) when it is first placed, and again whenever it moves more than 1 km, the scene's atmosphere settings change, or (under sunlight dynamic lighting) an hour of scene time passes (`DynamicEnvironmentMapManager`, Cesium 1.138). With the class colour supplying 94% of the surface, the models are lit from Cesium's default spherical harmonics instead, with no specular environment map, so the sky's model-lighting cube map no longer reaches aircraft. `src/data/aircraftModelLighting.test.mjs` pins the option at every drawn model call; the two preload calls only warm the glTF cache and are never drawn.
|
- Vessels, Transit and Rail draw fleet models under the same DISPLAY rail `3D` toggle, at the same altitude ceiling, caps and add/keep radii as the aircraft (`FLEET_MODEL_POLICY`, `src/layers/flights/policy.js`; `createFleetModelLayer`, `src/data/fleetModelInstances.js`). A vessel's model follows its AIS ship type and is drawn at its reported length and beam (AIS static dimensions A+B and C+D, now carried on vessel rows as `length` and `beam`), standing at the sea surface, heading by true heading then course. An aid to navigation is not a hull: a vessel record whose type names a buoy, beacon, mark, RACON or light, or whose MMSI is an aid-to-navigation station's (`99MIDxxxx`), is `isAidToNavigation` (`src/data/vesselTypes.js`) and is drawn as the set's `buoys` model of the IALA mark its type names (`aidToNavigationModel`, `src/data/fleetModels.js`: cardinal N/E/S/W, port or starboard hand, preferred channel by its side, safe water, isolated danger, special mark; a beacon, light, light vessel, RACON or reference point with no mark of its own is the special mark), else a red can (`DEFAULT_AID_MODEL`), at its built size and facing north whatever heading it reports. A type is an aid's when it is one of the 32 kinds an aid report names or uses a word for one (buoy, beacon, cardinal, safe water, RACON, lighthouse and so on); a vessel that works on aids (`Buoy Tender`, `Buoy Layer`) is not one. Its icon is a bone-white ringed disc (`AID_TO_NAVIGATION_STYLE`, `src/data/vesselLabels.js`) instead of a chevron, never rotated, and its card, selected card and HUD readout (`src/layers/vessels/cards.js`) show its kind alone, whole, in that colour: no speed or heading, since a fixed mark has neither. AISStream subscribes to `AidsToNavigationReport` (message 21) by default, and the server names each report's aid type code (0 to 31) as its kind (`aidToNavigationTypeName`: `20` is `Cardinal Mark N`) rather than reading it as a ship type, and its name runs on into the report's `NameExtension`. A virtual aid (the report's `VirtualAtoN` flag: a mark broadcast where nothing physical stands) carries `virtual: true` on its row, and on its vessel source record (the live-source contract's `virtual`, `src/sources/live/contract.js`, false unless a source says true; any source may set it). It keeps its disc but never gets a model (`vesselModelSpec` returns null for it, and the vessel layer gathers no model item for it), and its card and readout add `VIRTUAL` after its kind. `aisStreamRows` (`server/providers/vessels/ais-store.js`) puts every vessel ahead of every aid, so a capped request (the layer asks for 12,000 rows) never gives up a ship for a buoy. The `vessels_in_area` tool (and the brief built on it) counts ships only: it leaves aids out of its rows, counts, breakdowns and speed stats. A transit vehicle's model follows its route's GTFS `route_type` when its record carries one and that type is a kind of the vehicle's mode (`types.json` `transit.route_types`: 200 a coach, 101 a high-speed set, 106 a regional DMU, 710 a double-decker), else its layer mode (`transit.modes`: bus, trolleybus, tram, cable car, subway, monorail, rail, funicular, gondola or ferry; a vehicle of `unknown` mode keeps its icon); a fleet hint that overrules the route (a bus on a tram route) leaves the type unused. A monorail and a gondola are raised by their `transit.elevation` lifts. A train's model follows its rail category and mode (rail, metro or tram). The bundled GTFS-Realtime proxy carries no route type, so its vehicles draw their mode's model; a source that adds `routeType` reaches the finer ones. Both stand on the road or rail top they are drawn on, without the 1.5 m `GROUND_FLOOR_LIFT_M` their icons carry, and are painted in their mode or category colour where the model's `_TINT` attribute marks it. A vessel model is clipped at its waterline (one clipping plane per model, at the model origin's horizontal plane), so its hull below the water never shows through a plain globe, which Cesium does not depth-test models against. Under the NVG/FLIR styles (the Flights `irBoost` parameter) these models render unlit flat white, as aircraft models do. Each vehicle's icon stays the visual until its model is loaded, ready and placed; a model is picked as its icon is, and a vehicle drawn as its model keeps its selection card and its place in the detection overlay.
|
||||||
|
- **Aircraft models skip Cesium's dynamic environment map (2026-10-24).** Flights, Military Flights and Local ADS-B pass `environmentMapOptions: AIRCRAFT_ENVIRONMENT_MAP_OPTIONS` (`{ enabled: false }`, `src/data/aircraftModelLighting.js`) to every drawn model. Otherwise each `Model` renders the sky around it and reads it back from the GPU (`readPixels`) when it is first placed, and again whenever it moves more than 1 km, the scene's atmosphere settings change, or (under sunlight dynamic lighting) an hour of scene time passes (`DynamicEnvironmentMapManager`, Cesium 1.138). The models are lit from Cesium's default spherical harmonics instead, with no specular environment map, so the sky's model-lighting cube map no longer reaches aircraft. `src/data/aircraftModelLighting.test.mjs` pins the option at every drawn model call; every model is built from the fleet set loaded up front, so there is no separate preload.
|
||||||
- The DISPLAY-rail `3D` toggle is the user-facing activation path for both aircraft layers. Their small approved GLBs build their render resources without Cesium's frame-spread job queue, preventing continuous Photorealistic 3D Tiles streaming from starving model readiness; model caps, tracking, camera, and fallback billboards are unchanged.
|
- The DISPLAY-rail `3D` toggle is the user-facing activation path for both aircraft layers. Their small approved GLBs build their render resources without Cesium's frame-spread job queue, preventing continuous Photorealistic 3D Tiles streaming from starving model readiness; model caps, tracking, camera, and fallback billboards are unchanged.
|
||||||
- **The `3D` toggle DEFAULTS ON in `proximity` on a first run.** Proximity is itself the budget — models appear only below `MODEL_ALT_CEIL_M` and only for the nearest `MODEL_MAX` in view — so the default costs nothing at globe scale, and `all` remains a deliberate opt-in. A fresh boot runs NO layer-state restoration (`LayerStateCoordinator.start()` returns early with neither a share payload nor stored state), so four independent initializers decide what a first-run operator sees and must agree: `booleanOption('models3d', 'e', true)` in `src/data/layerState.js`, `_models3dEnabled = true` in BOTH flight layers, `this._models3dEnabled = true` in `src/ui/aircraftDisplay.js`, and the `active` / `visible` classes on `#models3d-toggle` / `#models3d-mode-row` in `index.html`. All four are pinned together in `src/data/layerState.test.mjs`. Explicit state still wins: because the codec omits default-valued options, `models3d: false` is now what travels in a link (`lo=…f.e.0`) and restores OFF at both aircraft layers. **Consequence for returning users:** a stored `gev:layer-state:v2` blob is a FULL options snapshot, so a session that wrote one before this change carries `models3d:false` and keeps 3D off until the operator flips it (or clears the key) — the durable snapshot is treated as the recipient's own state, by design.
|
- **The `3D` toggle DEFAULTS ON in `proximity` on a first run.** Proximity is itself the budget — models appear only below `MODEL_ALT_CEIL_M` and only for the nearest `MODEL_MAX` in view — so the default costs nothing at globe scale, and `all` remains a deliberate opt-in. A fresh boot runs NO layer-state restoration (`LayerStateCoordinator.start()` returns early with neither a share payload nor stored state), so four independent initializers decide what a first-run operator sees and must agree: `booleanOption('models3d', 'e', true)` in `src/data/layerState.js`, `_models3dEnabled = true` in BOTH flight layers, `this._models3dEnabled = true` in `src/ui/aircraftDisplay.js`, and the `active` / `visible` classes on `#models3d-toggle` / `#models3d-mode-row` in `index.html`. All four are pinned together in `src/data/layerState.test.mjs`. Explicit state still wins: because the codec omits default-valued options, `models3d: false` is now what travels in a link (`lo=…f.e.0`) and restores OFF at both aircraft layers. **Consequence for returning users:** a stored `gev:layer-state:v2` blob is a FULL options snapshot, so a session that wrote one before this change carries `models3d:false` and keeps 3D off until the operator flips it (or clears the key) — the durable snapshot is treated as the recipient's own state, by design.
|
||||||
- **Consequence of the flip on the recorded tracked/fleet inversion:** the 150–800 km band where surrounding contacts draw as models while the SELECTED one is still a glyph is now what an operator sees WITHOUT arming anything. The inversion itself is unchanged and still deliberate (see `src/data/trackedModelRegime.js`); only its reachability changed.
|
- **Consequence of the flip on the recorded tracked/fleet inversion:** the 150–800 km band where surrounding contacts draw as models while the SELECTED one is still a glyph is now what an operator sees WITHOUT arming anything. The inversion itself is unchanged and still deliberate (see `src/data/trackedModelRegime.js`); only its reachability changed.
|
||||||
@@ -8221,7 +8431,11 @@ clock drives all enabled observation rows. Earlier/Later use the sorted union of
|
|||||||
non-suspended products' advertised times; each product selects its nearest frame
|
non-suspended products' advertised times; each product selects its nearest frame
|
||||||
at or before the requested UTC time, never a future frame or an interpolation.
|
at or before the requested UTC time, never a future frame or an interpolation.
|
||||||
The maximum gap is 30 minutes for radar, regional infrared and lightning, and
|
The maximum gap is 30 minutes for radar, regional infrared and lightning, and
|
||||||
3 hours for hourly global infrared. A missing eligible frame hides that product
|
3 hours for hourly global infrared, but never less than one and a half of the
|
||||||
|
feed's median frame spacing over its latest frames, so a regional feed whose
|
||||||
|
frames come an hour apart holds each for 90 minutes; the latest frame reads late
|
||||||
|
after the same floor (20 minutes for radar and regional infrared, 45 for
|
||||||
|
lightning, 4 hours for global infrared). A missing eligible frame hides that product
|
||||||
and reports the gap; rows show actual displayed UTC time with synced/nearest labels.
|
and reports the gap; rows show actual displayed UTC time with synced/nearest labels.
|
||||||
Manifest rollover preserves the requested history time, even when frames expire.
|
Manifest rollover preserves the requested history time, even when frames expire.
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ Catalog: `src/i18n/locales/zh-Hant.json`. General rules: [TRANSLATORS.md](../TRA
|
|||||||
|
|
||||||
`zh-Hant` is the Simplified Chinese catalog (`zh-CN`, credited to abiyeenzo, #914, and EDIT-Aeterna, #979) written in Traditional characters with OpenCC character conversion. Wording and terminology are the same as in `zh-CN`: change a term in [zh-CN.md](./zh-CN.md) and the `zh-CN` catalog first, then convert. Only the script differs.
|
`zh-Hant` is the Simplified Chinese catalog (`zh-CN`, credited to abiyeenzo, #914, and EDIT-Aeterna, #979) written in Traditional characters with OpenCC character conversion. Wording and terminology are the same as in `zh-CN`: change a term in [zh-CN.md](./zh-CN.md) and the `zh-CN` catalog first, then convert. Only the script differs.
|
||||||
|
|
||||||
After `s2tw` conversion, fix the characters OpenCC picks wrongly: 年曆史 → 年歷史, 下遊 → 下游, 並道 → 併道, 發佈 → 發布, 公佈 → 公布.
|
After `s2tw` conversion, fix the characters OpenCC picks wrongly: 年曆史 → 年歷史, 下遊 → 下游, 並道 → 併道, 發佈 → 發布, 公佈 → 公布, 控制檯 → 控制台, and 周 → 週 where it means a week (1 週/秒).
|
||||||
|
|
||||||
## Style
|
## Style
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -26,7 +26,7 @@
|
|||||||
with the sources: src/materialSymbolsSubset.test.mjs fails when a source
|
with the sources: src/materialSymbolsSubset.test.mjs fails when a source
|
||||||
names a glyph this list is missing, because a missing glyph does not draw
|
names a glyph this list is missing, because a missing glyph does not draw
|
||||||
a box — the ligature never forms and the element renders the literal word. -->
|
a box — the ligature never forms and the element renders the literal word. -->
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20,400,0,0&icon_names=adjust,arrow_drop_down,arrow_forward,arrow_left,arrow_right,bolt,bug_report,category,chevron_left,chevron_right,close,close_fullscreen,dark_mode,delete,directions_boat,draw,east,eco,egg_alt,flare,flight,handyman,layers,layers_clear,light_mode,local_fire_department,location_on,more_horiz,movie,my_location,navigation,normal,on,open_in_full,partly_cloudy_day,pause,pentagon,pest_control,pets,play_arrow,public,question_mark,radar,radio,raven,right_panel_close,right_panel_open,rocket_launch,satellite_alt,search,set_meal,settings,skip_next,skip_previous,streetview,timeline,traffic,tune,umbrella,upload_file,videocam,view_in_ar,visibility,visibility_off,water_drop,zoom_in_map" rel="stylesheet" />
|
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20,400,0,0&icon_names=adjust,align_horizontal_left,align_horizontal_right,arrow_drop_down,arrow_forward,arrow_left,arrow_right,bolt,bug_report,category,chevron_left,chevron_right,close,close_fullscreen,dark_mode,delete,directions_boat,draw,east,eco,egg_alt,flare,flight,handyman,layers,layers_clear,light_mode,local_fire_department,location_on,more_horiz,movie,my_location,navigation,normal,on,open_in_full,palette,partly_cloudy_day,pause,pentagon,pest_control,pets,play_arrow,public,question_mark,radar,radio,raven,right_panel_close,right_panel_open,rocket_launch,satellite_alt,search,set_meal,settings,skip_next,skip_previous,streetview,timeline,traffic,tune,umbrella,upload_file,videocam,view_in_ar,visibility,visibility_off,water_drop,zoom_in_map" rel="stylesheet" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="gev-view" data-gev-view="scene-chrome"></div>
|
<div class="gev-view" data-gev-view="scene-chrome"></div>
|
||||||
|
|||||||
@@ -298,6 +298,7 @@
|
|||||||
},
|
},
|
||||||
"./sources/rail-service": "./src/sources/railService.js",
|
"./sources/rail-service": "./src/sources/railService.js",
|
||||||
"./layers/rail/source": "./src/layers/rail/source.js",
|
"./layers/rail/source": "./src/layers/rail/source.js",
|
||||||
|
"./layers/rail/paths": "./src/data/railPaths.js",
|
||||||
"./sources/map-features": "./src/sources/overpassFeatures.js",
|
"./sources/map-features": "./src/sources/overpassFeatures.js",
|
||||||
"./server/providers/mapillary": {
|
"./server/providers/mapillary": {
|
||||||
"node": "./server/providers/mapillary.js"
|
"node": "./server/providers/mapillary.js"
|
||||||
|
|||||||
+36
-17
@@ -1,20 +1,39 @@
|
|||||||
# Bundled 3D Model Attribution
|
# Bundled 3D Models
|
||||||
|
|
||||||
The model files in this directory are third-party visual assets. They are not
|
Every 3D model shipped in this directory is one of the project's procedural
|
||||||
covered by the repository's MIT source-code license; each remains available
|
fleet models under [`fleet/`](fleet/): aircraft, helicopters, ships, buoys,
|
||||||
under the license listed below.
|
transit and rail vehicles, and a few other airborne and ground objects. They
|
||||||
|
are generated from code by the project maintainers, contain no third-party
|
||||||
|
artwork, and are covered by the repository's [MIT license](../../LICENSE)
|
||||||
|
like the source code.
|
||||||
|
|
||||||
| File | Original work and creator | Source | License | Project modifications |
|
| Path | What it holds |
|
||||||
|---|---|---|---|---|
|
|---|---|
|
||||||
| `airplane.glb` | “boeing 747” by [zairiq-123](https://sketchfab.com/zairiq-123) | [Sketchfab model](https://sketchfab.com/3d-models/boeing-747-9b16672038ba48f98e6d80a159044ed9) | [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) | Substantially modified and optimized for God's Eye View, including geometry/material simplification and coordinate/orientation preparation. The former 24× runtime calibration is baked into the mesh; location, rotation, and scale are applied; the bounding-box centre is at the origin; and the model uses glTF +Y-up with its nose toward local −X. Geometry remains uncompressed so the aircraft asset does not compete with photogrammetry for Draco worker capacity. |
|
| `fleet/catalog.json` | Every model by name: its file, category, built length, beam and bounds (metres, in Cesium's Z-up model frame: x along the length with the nose toward −X, y across the beam, z up), the clearance below its origin, and its 2D icon class. |
|
||||||
| `jet.glb` | “Private Jet” by [Nick the Name](https://sketchfab.com/Nick_The_Name) | [Sketchfab model](https://sketchfab.com/3d-models/private-jet-cbdd1de6ced9461e950eafaa302cc82b) | [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) | Repackaged as a glTF binary for the project's military-flight visualization. Imported hierarchy transforms are baked into the meshes; location, rotation, and scale are applied; the bounding-box centre is at the origin; and the model uses meter scale, glTF +Y-up, and the shared nose −X convention. Existing materials are preserved. |
|
| `fleet/types.json` | Which model draws which vehicle, and at what length: ICAO aircraft and helicopter type codes, ADS-B emitter categories, AIS ship-type and length ranges, GTFS route types, transit modes and rail categories, with the defaults. |
|
||||||
| `bell206.glb` | “Bell 206 JetRanger” by [terran4627](https://sketchfab.com/terran4627) | [Sketchfab model](https://sketchfab.com/3d-models/bell-206-jetranger-d2f7ba1d671549d4b26aaf834139a1dd) | [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) | Optimized for God's Eye View: geometry/material simplification, textures resized to 256 px WebP, orientation/scale vertex-baked to real-world meters (Y-up, nose −X), origin centered. |
|
| `fleet/aircraft/`, `fleet/helicopters/`, `fleet/ships/`, `fleet/buoys/`, `fleet/transit/`, `fleet/other/` | The models, one GLB each (EXT_meshopt_compression and KHR_mesh_quantization, vertex colours, no textures). |
|
||||||
| `c172.glb` | “Cessna 172” by [e737](https://sketchfab.com/e0057537) | [Sketchfab model](https://sketchfab.com/3d-models/cessna-172-64cddaee5aff470682659a8c08525046) | [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) | Optimized for God's Eye View: geometry/material simplification, textures resized to 256 px WebP, orientation/scale vertex-baked to real-world meters (Y-up, nose −X), origin centered. |
|
|
||||||
| `citation2.glb` | “1990 Cessna Citation, Texture Detailed, Exterior” by [BlenderCommunityHead](https://sketchfab.com/aboodgoudagad) | [Sketchfab model](https://sketchfab.com/3d-models/1990-cessna-citation-texture-detailed-exterior-a78839624fe64900a8352cb23462350a) | [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) | Optimized for God's Eye View: geometry/material simplification, textures resized to 256 px WebP, orientation/scale vertex-baked to real-world meters (Y-up, nose −X), origin centered. |
|
|
||||||
| `mq9.glb` | “MQ-9” by [IProZenoN](https://sketchfab.com/IProZenoN) | [Sketchfab model](https://sketchfab.com/3d-models/mq-9-fabe963feb354c5584b51f9c470c3f7e) | [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) | Optimized for God's Eye View: geometry/material simplification, textures resized to 256 px WebP, orientation/scale vertex-baked to real-world meters (Y-up, nose −X), origin centered. |
|
|
||||||
| `b789.glb` | “Boeing 787-9” by [Nobilis 2](https://sketchfab.com/nobilishornet2) | [Sketchfab model](https://sketchfab.com/3d-models/boeing-787-9-b6711e2e698e4e469675c1154a50b7a3) | [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) | Optimized for God's Eye View: geometry/material simplification, textures resized to 256 px WebP, orientation/scale vertex-baked to real-world meters (Y-up, nose −X), origin centered. |
|
|
||||||
| `atr72.glb` | “ATR 72 - 600” by [Oyan3D](https://sketchfab.com/oyan3D) | [Sketchfab model](https://sketchfab.com/3d-models/atr-72-600-1e1a7186f7444d288675262fcee44744) | [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) | Optimized for God's Eye View: geometry/material simplification, textures removed with dominant material colors baked into PBR factors (flat “abstracted” style), orientation/scale vertex-baked to real-world meters (Y-up, nose −X), origin centered. |
|
|
||||||
|
|
||||||
CC BY 4.0 permits sharing and adaptation, including commercial use, provided
|
How the layers use them:
|
||||||
appropriate credit is retained, the license is linked, and modifications are
|
|
||||||
identified. These credits do not imply endorsement by the original creators.
|
- Each layer draws a vehicle with the model its type selects, scaled to the
|
||||||
|
type's published length (a vessel to its reported AIS length and beam), so
|
||||||
|
every model is drawn life size. Ground objects, balloons and obstacles in
|
||||||
|
the `other` category are drawn at the size they are built.
|
||||||
|
- An aid to navigation (a vessel record whose type names a buoy, beacon, IALA
|
||||||
|
mark, RACON or light, or whose MMSI is an aid station's `99MIDxxxx`) is
|
||||||
|
drawn as the `buoys` model of its mark (cardinal north, east, south or west,
|
||||||
|
port or starboard hand, safe water, isolated danger, special mark), a red
|
||||||
|
can when its type names no mark, at its built size and with no heading
|
||||||
|
(`vesselModelSpec`, `aidToNavigationModel`).
|
||||||
|
- An aircraft model's origin is its axis; it stands that model's scaled
|
||||||
|
clearance above the ground. A ship's origin is its waterline, and a transit
|
||||||
|
or rail vehicle's the road or rail top (a monorail or gondola is raised by
|
||||||
|
its `transit.elevation` entry, for a source that names those modes).
|
||||||
|
- Transit and rail models carry a `_TINT` vertex attribute that marks where
|
||||||
|
the route or category colour is painted.
|
||||||
|
- The whole set loads once, up front, when a layer that draws it starts; no
|
||||||
|
model is fetched while a session runs.
|
||||||
|
|
||||||
|
`src/data/fleetModels.js` reads the set and chooses each vehicle's model;
|
||||||
|
`src/data/fleetModels.test.mjs` checks that every model `types.json` names is
|
||||||
|
in the catalog and on disk, and that no GLB exceeds 3 MB.
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large.
Load diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loaded 100 of 393 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user