With no aircraft tracked, Cockpit can ride the selected AIS vessel. Entry
needs only Live AIS Vessels and a selected vessel; C, double-click and the
entry buttons (reading BRIDGE with a ship icon) enter it, while voice stays
aircraft-only.
The eye sits on the AIS position at a representative bridge height for the
vessel's type family, looks along true heading and moves along course over
ground. The last fix is dead-reckoned for up to 180 s between the layer's
refreshes, and on rivers and lakes the waterline is read from the rendered
surface around the ship rather than the geoid.
The bridge HUD shows speed and course over ground, a straight heading
tape, window mullions, the AIS destination as a reported voyage and a
heading-up radar of nearby ships (3 to 24 NM). The arrow keys look around,
Home or 0 looks ahead again. The vessel layer hides the ridden ship's
sprite and card, ignores scene clicks while held, and returns the camera
to the vessel's map view on exit.
Main now ships an Iceland pack that loads the full live Vegagerðin list
(about 500 views) with its CC BY 4.0 credit. The World catalog's 166
Vegagerðin rows point at the same frames under different ids, so every one
of those cameras would be drawn twice. Drop them from the World export and
its loader policy; World is now 2,230 rows and the default catalog limit
7,350 (4,000 shared slots plus 3,350 reserved).
Register Data attribution entries for Ottawa, Québec, TripCheck and MLIT,
as every other CCTV pack has. MLIT's terms ask for the source in the form
"出典:国土交通省 川の防災情報" with the page link, and ODOT asks for
"Camera courtesy of ODOT"; TripCheck partner cameras keep their owner's
name in the label.
The Houston guard test from main checked the old 4,000 default ceiling;
check the 4,000 shared slots instead, like the other pack tests.
One JSON list from gagnaveita.vegagerdin.is (about 500 camera views at roughly
170 road stations). Frames are JPEG stills in a single directory on
www.vegagerdin.is; only links inside that directory are registered, and the
media proxy pins the same directory.
The list decides ids, coordinates and which frame path is proxied, so it is
fetched over https with redirects refused and the body read capped at 2 MiB;
every rejection path releases the response body. Camera ids come from the frame
file name, which is unique per view in the live feed, and repeated frames
collapse before the cap.
The feed's view description (`Skyring`) is the label. An explicit Icelandic
facing ("til vesturs", "í suður", "séð austur") sets a high-confidence heading
(264 of 499 views); a view that states none, or two different ones, keeps the
id-hash low-confidence pose. A bare road direction ("Miklabraut austur") is not
read as a facing.
IRCA publishes road camera images under CC BY 4.0 and asks that the licensor is
acknowledged without implying endorsement; the attribution is in the Data
attribution popover and DATA_SOURCES.md, and every camera carries the licence
string. Default cap is 250 with anchors at Reykjavík and four regional centres so
a cap keeps every region. CCTV_ICELAND_ENABLED=0 turns the pack off.
Verified against the live feed through fetchCctvImageFromUpstream: 499 of 499
frames returned a JPEG, all distinct, all under 20 minutes old.
createTrafficSource({ roadModes }) lets a host offer a subset of the TomTom,
OSM and Hybrid road modes (all three by default). Without OSM the layer never
draws simulated roads, and a single mode shows no road chip.
While flow is live the Street Traffic row offers Lines (every road with flow
as a steady green/amber/red line, from the heat-line renderer) and Dots (the
moving dots), saved in layer state and share links. Defaults: Lines off,
Dots on.
A throw from the crop capture now has a test that it closes its decision with an error outcome. Direct calls to the crop and image senders pin the channel-closed and pointer-scale-not-useful skips. The docs say a send decision requests an image, and when a pointer snapshot counts as already requested.
Review fixes on top of #1578:
- Exiting Space Missions cancels the layer's own camera flights again (entry,
roster preview, mission focus); only a flight navigation started after
releaseCameraOwnership() runs on.
- A failed first index load says so: "Space Missions unavailable: the
mission index could not load. Try again later." on both the Context and
Data Layers routes, instead of a generic transition toast. Translated.
- Regression tests for both; docs and changelog describe the real feedback.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Third review pass on #835. No runtime change.
- Controller test: viewport decisions reach the controller's debug log.
- Policy test: a second request for a snapshot still being captured is
logged pointer-already-requested and is not captured twice.
- CURRENT-STATE: pointer-not-fresh also covers a missing snapshot,
already-requested covers an earlier attempt that threw, and the image
step runs when any tool output of the response was sent.
- Changelog: describe what is recorded rather than a fixed miscount.
Second review pass on #835's diagnostics. Behaviour is unchanged.
- Report viewport_context.result as soon as the send returns, so a throw
in the retained-frame bookkeeping cannot log a real send as "error".
- List the decision reasons and when each field is present in
CURRENT-STATE, note that the rate limit can split a pair, and say which
codes are defensive.
- Changelog: the decision is logged when an entity-context answer reaches
the image step, not for every answer.
Review fixes on top of #1601:
- Only redirect a provider the params switch on to a keyless source, so a
filter-only setParams (360°, SINCE) no longer moves an explicitly chosen
keyless Mapillary to KartaView.
- Keyless QA gate: assert the new KartaView default and that the Mapillary
chip explains its key instead of switching (it used to expect KEY REQUIRED).
- Tests: Graph-proxy keyReady, filter-only updates; shared test helper.
- README and CURRENT-STATE describe the keyless default.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Review follow-up for #835. What is captured, sent and kept is unchanged.
- Log nothing for tool results other than get_entity_context, so other
tools stop spending the shared debug-log budget.
- Give every decision and outcome the same contextId and image kind, so
overlapping requests pair up.
- Log why a crop decision did not send (stale, off ground, off screen,
expired, pose changed, already requested) instead of leaving a lone
"pointer-ground-crop" that reads as sent.
- Split capture-invalidated into session-reset, superseded, channel-lost
and frame-stale.
- Close the pair with "error" when a step throws, then rethrow.
- Document the events in CURRENT-STATE and reword the changelog fragment.
- Keep the open card across a widened reload only when its index still
holds the same report; the server may answer a pinned version with newer
bytes.
- Narrowing to a window the loaded data already covers clears a failed
wider reload, so the row no longer stays in error.
- Label the every-age option "All" (contextual) so the six-option switch
fits the row in every locale; tooltip and info line keep "All markers".
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Review fixes on top of #1528:
- Narrowing the age window only removes markers; a product loaded with a
narrower window is reloaded when the window widens again. Fixes markers
missing after 7d -> 1d -> 7d and avoids reparsing every KMZ on narrowing.
- A wider window over the same edition keeps the open report card.
- Date-only event dates cover their whole UTC day, so 1d still shows
yesterday's reports.
- The age options are one labelled "Event age" radio switch (row
`segmented` control, as FIRMS confidence) instead of toggle chips mixed
with the product chips.
- Un-nest the per-product age test; QA compares data-source counts with the
live defaults instead of a hard-coded 2.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
- Publish classificationName next to the raw NHC code; unknown codes stay
unexpanded.
- Publish staleCacheFetchedAt only while the proxy serves its cache.
- Touch the shared store on clear only after this layer published, so a
feed failure no longer evicts another layer's dangling selection.
- Drop the unreachable no-storm branch and the unused return value.
- Tests: split the heading fixture into due north and stationary, cover
the unavailable and failure paths with the real store, and check that
clear/disable leave another layer's selection alone; fold the fake-store
test into the real-store one.
Wildlife Sightings (#1591) published share token 9, so News takes the
next free token, 00. The token tests read the ledger before both where
they were written against it, and the README counts both layers.
A slow re-read of a refused key read as unavailable until it landed; it
now stays refused. The first-read wait is 10 s, for a margin under the
browser's 15 s. A failed Conflicts read no longer stops Local's refresh,
which the server reads on its own. Tests cover GDELT's wait, the refused
key and a caller abort past the timeout, and fail rather than hang; the
docs say what a section serves meanwhile.
A country's first World News API read, or Liveuamap's, could take up to
20 s while the browser waits 15, so the panel showed the browser's own
"signal timed out". A read with nothing to serve yet is now waited for
at most 12 s, as GDELT's already was: past that the section answers
unavailable while the read goes on, and the next refresh is served from
it. A client timeout reads "News feed unavailable".
Main's wildlife-sightings layer took share-link token 9, so shipwrecks
takes the next free token, 00. Locale, docs, format-scope and voice
manifest conflicts keep both sides. Ledger and registry tests now model
the ledger before shipwrecks took 00, and layer counts include both
new layers.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Keyless GTFS-Realtime feed published by ZDiTM Szczecin under CC0 1.0.
Speeds are m/s (checked against vehicle movement), the file refreshes about
every 20 s, and the feed carries no route ids, so vehicles take the default
bus mode.
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
From 400 km, a tilt to -5° that a zoom out x2.5 caught 70 frames in eased down from the camera's old pitch at the new range. That put the camera below the place's horizon: the first frame's crosshair hit the ground 186 km from London, and London stayed hidden for about 11 frames. The re-solve also left the pivot pitch at 0°, so a zoom in before the next frame computed an infinite clearance floor, was refused, and stayed at 1,000 km.
The re-solved pivot pitch now stops at the place's horizon limit, or where the pivot already was. A camera that the zoom leaves past that limit steps down to it with the zoom and holds it, and the zoom still reports that angle. A zoom in straight after brings the range back to 400 km.