The transit layer knew five modes, so a trolleybus drew as a bus, a
funicular as a train and a coach as a city bus. The GTFS basic route types
are now modes of their own (trolleybus, cable_tram, monorail, funicular,
aerial_lift), each with an icon, colour, detection tier, card word, voice
name, speed ceiling and fleet model.
A vehicle record may carry its route's GTFS route_type as routeType. It
settles the mode after the feed's fleet hint and before its route hint, and
picks the finer model (a coach for 200, a high-speed set for 101) when the
type is a kind of the vehicle's mode. Retained history classifies epochs
through transitModeFor too, so trails join the live vehicle.
Route hints from each operator's routes.txt: Prague's trolleybus lines
(51-59, 232, 275) and Petrin funicular, and the trams, trolleybuses and
metro lines of Bucharest, Cluj-Napoca and Turin. A feed may also name
route corrections that outrank the route type: Le Havre's routes.txt types
its funicular (8-FUNI) as a bus, so it is corrected to a funicular.
A virtual aid (AIS message 21's VirtualAtoN flag) is a mark broadcast
where nothing physical stands, so drawing it as a buoy showed a mark
that is not there. The vessel source record now carries `virtual`
(false unless a source says true; any source may set it), AISStream
sets it from VirtualAtoN, and the vessel layer keeps such an aid's
disc: vesselModelSpec returns null for it and the layer gathers no
model item for it. Its card, selected card and readout add VIRTUAL
after its kind.
A buoy's card, selected card and HUD readout showed "0.0KT · 135°" from
whatever its source reported. A fixed mark has neither, so they now show
its kind alone, whole ("CARDINAL MARK N", which the 14-character type cut
read as "CARDINAL MARK "), in the bone white of its disc.
isAidToNavigation now knows every kind an aid report names ("Light, with
sectors", "Fixed structure off shore" had no aid word), leaves out a
"Buoy Layer" as it does a tender, and matches each type text once: the
vessel layer asks per vessel on its rotation pass, which now skips the
aid discs it never turns.
Aid rows no longer cost ships their place: aisStreamRows lists every
vessel ahead of every aid, so the layer's 12,000-row request never drops
a ship for a buoy, and vessels_in_area (and the brief built on it)
counts ships only. An aid's name runs on into its NameExtension.
A buoy, beacon, RACON, light or IALA mark in the vessel feed was drawn
as a ship. A vessel record whose type names one, or whose MMSI is an
aid-to-navigation station's (99MIDxxxx), is now isAidToNavigation and
vesselModelSpec draws it as the fleet set's buoy of its mark (cardinal
N/E/S/W, port or starboard hand, safe water, isolated danger, special
mark; a red can when the type names no mark), at its built size and
flagged fixed so its model does not turn to a heading. Its icon is a
disc instead of a chevron.
AISStream now subscribes to AidsToNavigationReport by default, and the
server names each report's aid type code (0 to 31) as its kind instead
of reading it as a ship type.
Contacts and Space Missions switch CCTV off to isolate themselves and restore
it on the way out: the panel and its share preference now stay as they are for
that round trip, as they do for Clear selected data layers. The controls no
longer read the collapsed class before asking: the panel chrome tells a panel
the accordion folded from one whose saved state is closed.
The camera controls gate asserts the collapse, reopens CCTV from the right
rail before switching it back on, and runs a Contacts entry and exit with the
panel open.
The points-of-interest keys (Q/W/E/R/T while a city is expanded) are a
second bare-key document listener, and it did not look at modifiers
either: Alt+R or a delivered Ctrl+R picked the fourth POI and flew the
camera there. It now leaves Cmd, Ctrl and Alt chords to the browser like
the application shortcuts; Shift still counts as the key. The docs and
the changelog entry say so.
A link check of every manifest found 404 licence or provider pages for
OpenSeaMap seamarks, EMODnet bathymetry and the PDOK, basemap.at, Geneva
SITG, ICGC Catalunya, Luxembourg and Vlaanderen aerial photos, and no
answer from the SEDAC GPW, Minnesota and Bangor hosts. Drop those 11
entries, renumber the unpublished share-token ledger, point the tests at
remaining entries and regenerate DATA_SOURCES.md.
The City of Amsterdam's verkeersinformatiesystemen register lists where
its ~500 traffic and ANPR cameras stand, with type and asset number, but
publishes no pictures. That fits a Data Library dataset better than a
CCTV pack: the register answers GeoJSON in WGS84 with CORS headers, so
the entry fetches it browser-direct with no proxy code.
The register names no licence ("public unless stated otherwise"), so the
entry stays operator opt-in, as #251 had it. The dataset and the
position-only camera idea come from @Maher-Reven's #251, which this
replaces; the entry lists them as maintainer and in its attribution.
Co-authored-by: Maher Kurdi <[email protected]>
DATA LAYERS keeps its curated core layers; regional and niche sources
live in the Data Library, opened from Browse data library at the foot
of the panel. Each entry is a JSON manifest in src/library/entries/
pointing at a live upstream (query API, provider-hosted file or tile
endpoint), so nothing is bundled and a self-hosted instance hosts no
data. Sources without CORS go through one allowlisted /api/library
route. Kinds: dataset (GeoJSON, CSV, JSON records, ArcGIS, partitioned
GeoParquet), tiles (XYZ, WMS/ArcGIS bbox export, terrarium relief) and
pack. Selections persist and travel in share links as lib=, separate
from the core layer tokens. Library rows get Zoom and Remove icon
chips that work while the layer is off, rendered through RailChips.
Strings are translated in every locale.
Shorter comments, changelog and CURRENT-STATE text for the 502 outage
path; the CURRENT-STATE paragraph now also names the 429 exception and
which budget expiry answers busy and which answers 502. Text only.
Core's catalog passes worldClock.timeFor('news') as the layer's now, so a host that follows the clock for News can show a past time's reports with their ages, window and counts as they were then. Core does not follow the clock for the layer, so it keeps reading the wall clock.