Compare commits

..
Author SHA1 Message Date
Said Turksever a3d17669f3 feat(transit): confirm 33 Japanese feeds live and centre them on their vehicles
A probe at 08:00 Japan time on 2026-11-14 saw vehicle positions on 33 of
the Japanese feeds. Those rows lose liveSeen: false, so they join the
coverage heat-map; the ones seen with five or more vehicles are centred
on them with a radius that covers the farthest one. The 21 feeds that
were empty overnight and in the morning stay registered and flagged.
2026-11-13 23:06:34 +00:00
Said Turksever b17bfa690f feat(transit): smooth coverage heat-map at every zoom, live feeds only
Draw coverage as Gaussian discs blended in the opaque pass: wide spots
from orbit cross-fading into service-area patches at regional zoom.
Translucent billboards darkened into rimmed discs under Cesium's OIT at
orbital distances. Feeds not yet seen live get no spot.
2026-11-13 17:55:06 +00:00
Said Turksever 7082a02057 feat(transit): show feed coverage as a glow at globe view
Above the altitude gate the layer draws no vehicles, so nothing showed
where Transit has data. One soft spot per enabled feed, hotter where
networks cluster, fading in across the gate. Built from the registry;
no feed is polled for it.
2026-11-13 17:14:33 +00:00
Said Turksever d4e308d905 feat(transit): add 55 Japanese bus networks
Keyless VehiclePositions feeds the Mobility Database records under
CC0 1.0 or CC BY 4.0. Added overnight in Japan: 50 answered with an
empty message, and each row says whether positions have been seen.
2026-11-13 16:44:34 +00:00
Said Turksever eed1f42779 refactor(transit): label catalogue feeds as public realtime vehicle feeds 2026-11-13 16:37:12 +00:00
Said Turksever 310e741700 docs(changelog): reword catalogue feeds entry (#1716) 2026-11-13 16:34:03 +00:00
Said Turksever 0ba90fbf61 feat(transit): add 139 feeds from the open GTFS-Realtime catalogues
Ten operators whose published terms were read and permit display, and
129 keyless feeds with no stated licence, marked as such. Feeds whose
terms need a key, registration or permission are left out and a test
keeps their hosts unregistered.
2026-11-13 16:12:36 +00:00
Said Turksever 7b2e8729fe docs(changelog): French transit networks (#1716) 2026-11-13 15:39:16 +00:00
Said Turksever b3ffe9beb2 feat(transit): add 112 French networks from transport.data.gouv.fr
Each row is the keyless GTFS-RT vehicle feed of a national access point
record whose licence field is Licence Ouverte 2.0 or ODbL, seen live on
2026-11-13. Rows live in transitFeedsFrance.js; line names for feeds
that publish internal route keys come from each record's routes.txt.
Networks already registered through the operator's own endpoint are not
added again.
2026-11-13 15:38:18 +00:00
60 changed files with 8754 additions and 1132 deletions

No files matched your search

+307 -1
View File
@@ -175,6 +175,312 @@ How to read this:
| **Toulon Mistral** (feed-rdtpm-toulon.ratpdev.com) | Transit layer live vehicles, Toulon, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/reseau-de-transport-urbain-de-la-metropole-toulon-provence-mediterranee). Dataset record’s licence field quoted. Speeds are km/h: readings ran 3.5 times the measured movement on 2026-11-07, so the proxy converts them. Route ids are zero-padded. | Métropole Toulon Provence Méditerranée (Mistral) |
| **Le Havre LiA** (opendata.transports-lia.fr) | Transit layer live vehicles, Le Havre, France | ODbL (https://transport.data.gouv.fr/datasets/reseau-de-transport-en-commun-lia-gtfs-siri). The network publishes under ODbL (dataset record quoted); and this is its own GTFS-RT vehicle feed from that record; route ids carry the network prefix `8-`. The layer draws positions and redistributes no database. Lines A and B are the tramway. | Le Havre Seine Métropole (LiA) |
| **Tours Fil Bleu** (data.filbleu.fr) | Transit layer live vehicles, Tours, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/fil-bleu-syndicat-des-mobilites-gtfs-gtfs-rt). Dataset record’s licence field quoted. | Fil Bleu – Syndicat des Mobilités de Touraine |
| **Agde Cap’Bus** (zenbus.net) | Transit layer live vehicles, Agde, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/gtfs-capbus). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (6 vehicles on 2026-11-13). Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Cap’Bus – Communauté d’agglomération Hérault-Méditerranée |
| **Agen Tempo** (api.pysae.com) | Transit layer live vehicles, Agen, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/agen-gtfs-urbain). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (33 vehicles on 2026-11-13). | Tempo Bus – Agglomération d’Agen |
| **Alès Alesy** (alesy.plateforme-2cloud.com) | Transit layer live vehicles, Alès, France | ODbL (https://transport.data.gouv.fr/datasets/horaires-theoriques-des-lignes-urbaines-et-interurbaines-sur-le-reseau-alesy-gtfs). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (62 vehicles on 2026-11-13). ODbL asks for credit and share-alike on a derived database; the layer draws positions and redistributes no database. | Alesy – Syndicat mixte transports publics du bassin d’Alès |
| **Aléop coaches** (proxy.transport.data.gouv.fr) | Transit layer live vehicles, Pays de la Loire, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/arrets-horaires-et-circuits-des-lignes-de-transports-aleop-1). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (103 vehicles on 2026-11-13). Served by the national access point’s own proxy of the operator feed. Route `YEU` is the Île d’Yeu boat. Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Aléop - Pays de la Loire – Pays de la Loire |
| **Amiens Ametis** (proxy.transport.data.gouv.fr) | Transit layer live vehicles, Amiens, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/ametis). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (95 vehicles on 2026-11-13). Served by the national access point’s own proxy of the operator feed. | Ametis – Communauté d’agglomération Amiens Métropole |
| **Angers Irigo** (ara-api.enroute.mobi) | Transit layer live vehicles, Angers, France | ODbL (https://transport.data.gouv.fr/datasets/angers-loire-metropole-reseau-irigo-gtfs-gtfs-rt-siri). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (214 vehicles on 2026-11-13). ODbL asks for credit and share-alike on a derived database; the layer draws positions and redistributes no database. Lines A, B and C are the tramway. Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Irigo – Communauté urbaine Angers Loire Métropole |
| **Arles Envia** (accm.plateforme-2cloud.com) | Transit layer live vehicles, Arles, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/donnees-statiques-et-temps-reels-reseau-envia). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (33 vehicles on 2026-11-13). Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Envia – Communauté d’agglomération d’Arles-Crau-Camargue-Montagnette |
| **Arras Artis** (api.pysae.com) | Transit layer live vehicles, Arras, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/reseau-de-transport-artis). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (5 vehicles on 2026-11-13). Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Artis – Communauté urbaine d’Arras |
| **Aubenas Tout’enbus** (gtfs-rt.infra-hubup.fr) | Transit layer live vehicles, Aubenas, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/donnees-theoriques-et-temps-reel). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (5 vehicles on 2026-11-13). Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Tout’enbus – Région Auvergne-Rhône-Alpes (CC du Bassin d’Aubenas) |
| **Auch Alliance** (zenbus.net) | Transit layer live vehicles, Auch, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/gtfs-reseau-alliance-bus-grand-auch). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (7 vehicles on 2026-11-13). Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Alliance – Communauté d’agglomération Grand Auch Coeur de Gascogne |
| **Auray Glazgo** (api.pysae.com) | Transit layer live vehicles, Auray, France | ODbL (https://transport.data.gouv.fr/datasets/reseau-urbain-glazgo). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (4 vehicles on 2026-11-13). ODbL asks for credit and share-alike on a derived database; the layer draws positions and redistributes no database. Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Glazgo – Communauté de communes Auray Quiberon Terre Atlantique |
| **Avignon Orizo** (api.maas-fr.cityway.fr) | Transit layer live vehicles, Avignon, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/reseau-orizo-grand-avignon). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (90 vehicles on 2026-11-13). Line T1 is the tramway. | Orizo – Communauté d’agglomération du Grand Avignon (COGA) |
| **Barentin MOCA** (proxy.transport.data.gouv.fr) | Transit layer live vehicles, Barentin, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/moca-communaute-de-communes-caux-austreberthe). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (2 vehicles on 2026-11-13). Served by the national access point’s own proxy of the operator feed. Published through the Atoumod (Normandy) hub; its positions stalled for about ten minutes once on 2026-11-13. | MOCA – Communauté de communes Caux - Austreberthe |
| **Beaune Côte&Bus** (proxy.transport.data.gouv.fr) | Transit layer live vehicles, Beaune, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/offre-de-transport-de-la-c-a-beaune-cote-sud-gtfs). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (5 vehicles on 2026-11-13). Served by the national access point’s own proxy of the operator feed. | Côte&Bus – Communauté d’agglomération Beaune, Côte et Sud - Communauté Beaune-Chagny-Nolay |
| **Beauvais Corolis** (api.oisemob.cityway.fr) | Transit layer live vehicles, Beauvais, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/donnees-theoriques-et-temps-reel-du-reseau-corolis-urbain-communaute-dagglomeration-du-beauvaisis). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (23 vehicles on 2026-11-13). | Corolis – Communauté d’agglomération du Beauvaisis |
| **Beauvaisis Corolis interurbain** (api.oisemob.cityway.fr) | Transit layer live vehicles, Beauvais, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/donnees-theoriques-et-temps-reel-du-reseau-corolis-interurbain-communaute-dagglomeration-du-beauvaisis). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (13 vehicles on 2026-11-13). | Corolis – Communauté d’agglomération du Beauvaisis |
| **Bernay l’Bus** (zenbus.net) | Transit layer live vehicles, Bernay, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/reseau-transport-urbain-de-bernay). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (1 vehicles on 2026-11-13). Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | l’Bus – Communauté de communes Intercom Bernay Terres de Normandie |
| **Blois Azalys** (app.mecatran.com) | Transit layer live vehicles, Blois, France | ODbL (https://transport.data.gouv.fr/datasets/agglopolys-offre-theorique-mobilite-reseau-urbain-azalys-de-blois). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (55 vehicles on 2026-11-13). ODbL asks for credit and share-alike on a derived database; the layer draws positions and redistributes no database. Speeds are km/h: readings ran 6.63 times the measured movement on 2026-11-13, so the proxy converts them. Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Azalys – Communauté d’agglomération de Blois "Agglopolys" |
| **Bourg-en-Bresse Rubis** (proxy.transport.data.gouv.fr) | Transit layer live vehicles, Bourg-en-Bresse, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/rubis-grand-bourg-mobilites-offre-de-transport-theorique-et-temps-reel). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (34 vehicles on 2026-11-13). Served by the national access point’s own proxy of the operator feed. Speeds are km/h: readings ran 4.99 times the measured movement on 2026-11-13, so the proxy converts them. The feed carries no route ids. | Rubis – Communauté d’agglomération du Bassin de Bourg-en-Bresse |
| **Bourgoin-Jallieu Ruban** (app.pysae.com) | Transit layer live vehicles, Bourgoin-Jallieu, France | ODbL (https://transport.data.gouv.fr/datasets/reseau-ruban). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (28 vehicles on 2026-11-13). ODbL asks for credit and share-alike on a derived database; the layer draws positions and redistributes no database. | Ruban – Communauté d’agglomération Porte de l’Isère (CAPI) |
| **Brest Bibus** (proxy.transport.data.gouv.fr) | Transit layer live vehicles, Brest, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/horaires-theoriques-et-temps-reel-des-bus-et-tramways-circulant-sur-le-territoire-de-brest-metropole). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (113 vehicles on 2026-11-13). Served by the national access point’s own proxy of the operator feed. Lines A and B are the tramway; line C is the cable car, which has no mode of its own here and draws as a bus. Vehicles carry no timestamp of their own, so the feed header’s is used. | Bibus – Brest Métropole |
| **Béziers beeMob** (feed-beemob-beziers.ratpdev.com) | Transit layer live vehicles, Béziers, France | ODbL (https://transport.data.gouv.fr/datasets/horaires-theoriques-et-temps-reel-du-reseau-de-transports-beemob-beziers-mediterranee). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (40 vehicles on 2026-11-13). ODbL asks for credit and share-alike on a derived database; the layer draws positions and redistributes no database. | beeMob – Communauté d’agglomération de Béziers-Méditerranée |
| **Cannes Palm Bus** (proxy.transport.data.gouv.fr) | Transit layer live vehicles, Cannes, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/horaires-theoriques-et-temps-reel-gtfs-gtfs-rt-du-reseau-palmbus-cannes-pays-de-lerins). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (86 vehicles on 2026-11-13). Served by the national access point’s own proxy of the operator feed. Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Palmbus – Communauté d’agglomération Cannes Pays de Lérins |
| **Carcassonne RTCA** (proxy.transport.data.gouv.fr) | Transit layer live vehicles, Carcassonne, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/reseau-rtca). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (23 vehicles on 2026-11-13). Served by the national access point’s own proxy of the operator feed. | RTCA – Communauté d’agglomération Carcassonne Agglo |
| **Caux Seine Rezo’Bus** (app.pysae.com) | Transit layer live vehicles, Lillebonne, France | ODbL (https://transport.data.gouv.fr/datasets/reseau-urbain-caux-seine-mobilite-rezobus). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (2 vehicles on 2026-11-13). ODbL asks for credit and share-alike on a derived database; the layer draws positions and redistributes no database. | REZO’BUS – Communauté d’agglomération Caux Seine Agglo |
| **Cavaillon C’mon bus** (app.pysae.com) | Transit layer live vehicles, Cavaillon, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/gtfs-reseau-cmonbus). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (11 vehicles on 2026-11-13). Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Cmonbus – Communauté d’agglomération Luberon Monts de Vaucluse |
| **Cayenne Agglo’bus** (cacl.plateforme-2cloud.com) | Transit layer live vehicles, Cayenne, French Guiana | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/agence-agglobus). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (44 vehicles on 2026-11-13). | Agglobus – Communauté d’agglomération du Centre Littoral |
| **Chamonix buses** (api.pysae.com) | Transit layer live vehicles, Chamonix-Mont-Blanc, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/gtfs-reseau-chamonix-mobilite). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (11 vehicles on 2026-11-13). | Communauté de communes de la Vallée de Chamonix-Mont-Blanc |
| **Chantilly Aire’MOB** (api.oisemob.cityway.fr) | Transit layer live vehicles, Chantilly, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/donnees-theoriques-et-temps-reel-du-reseau-airemob-communaute-de-communes-de-laire-cantilienne). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (2 vehicles on 2026-11-13). | Aire’MOB – Communauté de communes de l’Aire Cantilienne |
| **Cherbourg Cap Cotentin** (app.pysae.com) | Transit layer live vehicles, Cherbourg-en-Cotentin, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/horaires-theoriques-et-en-temps-reel-des-bus-et-autocars-circulant-sur-le-reseau-cap-cotentin). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (53 vehicles on 2026-11-13). | Cap Cotentin – Communauté d’agglomération du Cotentin |
| **Chinon CVL Mobilité** (cvlmobilite.plateforme-2cloud.com) | Transit layer live vehicles, Chinon, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/reseau-cvlmobilite-plan-de-transport-theorique-ligne-a-format-gtfs). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (7 vehicles on 2026-11-13). | CVL Mobilité – Communauté de communes Chinon, Vienne et Loire |
| **Clermont (Oise) Le Bus** (api.oisemob.cityway.fr) | Transit layer live vehicles, Clermont, Oise, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/donnees-theoriques-et-temps-reel-du-reseau-le-bus-communaute-de-communes-du-clermontois). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (4 vehicles on 2026-11-13). | Le Bus – Communauté de communes du Clermontois |
| **Compiègne TIC** (api.oisemob.cityway.fr) | Transit layer live vehicles, Compiègne, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/donnees-theoriques-et-temps-reel-du-reseau-tic-urbain-communaute-dagglomeration-de-la-region-de-compiegne-et-de-la-basse-automne). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (19 vehicles on 2026-11-13). | TIC – Communauté d’agglomération de la Région de Compiègne et de la Basse Automne |
| **Compiègne TIC interurbain** (api.oisemob.cityway.fr) | Transit layer live vehicles, Compiègne, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/donnees-theoriques-et-temps-reel-du-reseau-tic-interurbain-communaute-dagglomeration-de-la-region-de-compiegne-et-de-la-basse-automne). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (21 vehicles on 2026-11-13). | TIC – Communauté d’agglomération de la Région de Compiègne et de la Basse Automne |
| **Cosne-sur-Loire Papillon** (api.pysae.com) | Transit layer live vehicles, Cosne-Cours-sur-Loire, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/donnees-du-reseau-de-bus-papillon-a-cosne-cours-sur-loire). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (2 vehicles on 2026-11-13). Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Papillon – Communauté de communes Coeur de Loire |
| **Creil AXO** (api.oisemob.cityway.fr) | Transit layer live vehicles, Creil, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/donnees-theoriques-et-temps-reel-du-reseau-axo-communaute-dagglomeration-creil-sud-oise). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (28 vehicles on 2026-11-13). | AXO – Communauté d’agglomération Creil Sud Oise |
| **Crépy-en-Valois Mobi** (api.oisemob.cityway.fr) | Transit layer live vehicles, Crépy-en-Valois, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/donnees-theoriques-et-temps-reel-du-reseau-mobi-communaute-de-communes-du-pays-de-valois). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (5 vehicles on 2026-11-13). | Mobi – Communauté de communes du Pays de Valois |
| **Cœur du Var Le TACO** (api.pysae.com) | Transit layer live vehicles, Le Luc, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/le-taco-1). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (1 vehicles on 2026-11-13). Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Le TACO – Région Provence-Alpes-Côte d’Azur (CC Coeur du Var) |
| **Dieppe DeepMob** (proxy.transport.data.gouv.fr) | Transit layer live vehicles, Dieppe, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/deepmob-dieppe-maritime). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (12 vehicles on 2026-11-13). Served by the national access point’s own proxy of the operator feed. Published through the Atoumod (Normandy) hub; its positions stalled for about ten minutes once on 2026-11-13. Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | DeepMob – Communauté d’agglomération de la Région Dieppoise |
| **Dijon Divia** (proxy.transport.data.gouv.fr) | Transit layer live vehicles, Dijon, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/gtfs-diviamobilites). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (149 vehicles on 2026-11-13). Served by the national access point’s own proxy of the operator feed. Speeds are km/h: readings ran 4.42 times the measured movement on 2026-11-13, so the proxy converts them. Lines T1 and T2 are the tramway. Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | DiviaMobilités – Dijon Métropole |
| **Dole Grandole Mobilités** (proxy.transport.data.gouv.fr) | Transit layer live vehicles, Dole, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/reseau-de-transport-du-grand-dole). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (18 vehicles on 2026-11-13). Served by the national access point’s own proxy of the operator feed. | Grandole Mobilités – Communauté d’agglomération du Grand Dole |
| **Draguignan TEDbus** (pysae.com) | Transit layer live vehicles, Draguignan, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/reseau-tedbus-lignes-regulieres-dracenie-provence-verdon-agglomeration). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (15 vehicles on 2026-11-13). Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | TEDbus – Dracénie Provence Verdon Agglomération |
| **Figeac Le Bus** (zenbus.net) | Transit layer live vehicles, Figeac, France | ODbL (https://transport.data.gouv.fr/datasets/horaires-theoriques-du-reseau-figeac-le-bus-gtfs). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (3 vehicles on 2026-11-13). ODbL asks for credit and share-alike on a derived database; the layer draws positions and redistributes no database. Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Figeac - Le Bus – Région Occitanie (CC Grand-Figeac) |
| **Flers Némus** (flers-agglo.plateforme-2cloud.com) | Transit layer live vehicles, Flers, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/donnees-theoriques-du-reseau-urbain-de-flers-agglo-au-format-gtfs). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (5 vehicles on 2026-11-13). Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Nemus – Communauté d’agglomération Flers Agglo |
| **Fougères SURF** (proxy.transport.data.gouv.fr) | Transit layer live vehicles, Fougères, France | ODbL (https://transport.data.gouv.fr/datasets/reseau-urbain-surf). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (8 vehicles on 2026-11-13). ODbL asks for credit and share-alike on a derived database; the layer draws positions and redistributes no database. Served by the national access point’s own proxy of the operator feed. Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | SURF – Communauté d’agglomération Fougères Agglomération |
| **Fréjus–Saint-Raphaël Le Bus** (api.pysae.com) | Transit layer live vehicles, Fréjus, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/reseau-transport-urbain-le-bus). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (31 vehicles on 2026-11-13). Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Le Bus – Estérel Côte d’Azur Agglomération |
| **Gap L’Agglo en Bus** (gtfs-rt.infra-hubup.fr) | Transit layer live vehicles, Gap, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/horaires-theoriques-et-temps-reels-du-reseau-de-transports-lagglo-en-bus-communaute-dagglomeration-gap-tallard-durance). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (11 vehicles on 2026-11-13). | L’Agglo en Bus – Communauté d’agglomération Gap-Tallard-Durance |
| **Guingamp-Paimpol Mobilité** (proxy.transport.data.gouv.fr) | Transit layer live vehicles, Guingamp, France | ODbL (https://transport.data.gouv.fr/datasets/reseau-urbain-scolaire-guingamp-paimpol-mobilite). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (13 vehicles on 2026-11-13). ODbL asks for credit and share-alike on a derived database; the layer draws positions and redistributes no database. Served by the national access point’s own proxy of the operator feed. | Guingamp-Paimpol Mobilité – Communauté d’agglomération Guingamp-Paimpol Agglomération de l’Armor à l’Argoat |
| **Guérande Lila Presqu’île** (proxy.transport.data.gouv.fr) | Transit layer live vehicles, Guérande, France | ODbL (https://transport.data.gouv.fr/datasets/reseau-urbain-scolaire-lila). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (20 vehicles on 2026-11-13). ODbL asks for credit and share-alike on a derived database; the layer draws positions and redistributes no database. Served by the national access point’s own proxy of the operator feed. Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Lila Presqu’ile – Communauté d’agglomération de la Presqu’île de Guérande Atlantique (CAP ATLANTIQUE) |
| **Haguenau Ritmo** (zenbus.net) | Transit layer live vehicles, Haguenau, France | ODbL (https://transport.data.gouv.fr/datasets/horaires-theoriques-et-temps-reel-du-reseau-ritmo-haguenau-gtfs-gtfs-rt). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (20 vehicles on 2026-11-13). ODbL asks for credit and share-alike on a derived database; the layer draws positions and redistributes no database. Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Ritmo – Communauté d’agglomération de Haguenau |
| **Hazebrouck Hop Bus** (gtfs-rt.infra-hubup.fr) | Transit layer live vehicles, Hazebrouck, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/hop-bus-le-reseau-100-gratuit-du-coeur-de-flandre). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (8 vehicles on 2026-11-13). Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Hop Bus – Communauté d’agglomération Coeur de Flandre |
| **Honfleur Hobus** (proxy.transport.data.gouv.fr) | Transit layer live vehicles, Honfleur, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/hobus-honfleur). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (2 vehicles on 2026-11-13). Served by the national access point’s own proxy of the operator feed. Published through the Atoumod (Normandy) hub; its positions stalled for about ten minutes once on 2026-11-13. Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Hobus – Communauté de communes du Pays de Honfleur-Beuzeville |
| **Issoire Cherpa** (zenbus.net) | Transit layer live vehicles, Issoire, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/cherpa-horaires-lignes-regulieres). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (1 vehicles on 2026-11-13). Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Cherpa – Agglo Pays d’Issoire |
| **Lavaur Lisatis** (zenbus.net) | Transit layer live vehicles, Lavaur, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/reseau-de-transport-urbain-lisatis). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (3 vehicles on 2026-11-13). Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | LISATIS – Région Occitanie (CC Tarn-Agout) |
| **Le Mans SETRAM** (proxy.transport.data.gouv.fr) | Transit layer live vehicles, Le Mans, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/gtfs-du-reseau-des-transports-bus-et-tramway-setram-circulant-sur-le-territoire-le-mans-metropole). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (102 vehicles on 2026-11-13). Served by the national access point’s own proxy of the operator feed. Speeds are km/h: readings ran 3.67 times the measured movement on 2026-11-13, so the proxy converts them. Lines T1 and T2 are the tramway. | SETRAM – Communauté urbaine Le Mans Métropole |
| **Le Tampon CarSud** (zenbus.net) | Transit layer live vehicles, Le Tampon, La Réunion, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/referentiel-topologique-reseau-carsud). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (22 vehicles on 2026-11-13). | CarSud – Communauté d’agglomération du Sud |
| **Liancourt Le Libellule** (api.oisemob.cityway.fr) | Transit layer live vehicles, Liancourt, France | ODbL (https://transport.data.gouv.fr/datasets/donnees-theoriques-et-temps-reel-du-reseau-le-libellule-communaute-du-liancourtois-la-vallee-doree). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (1 vehicles on 2026-11-13). ODbL asks for credit and share-alike on a derived database; the layer draws positions and redistributes no database. | Libellule – Communauté de communes du Liancourtois |
| **Lisieux Astrobus** (proxy.transport.data.gouv.fr) | Transit layer live vehicles, Lisieux, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/astrobus-lisieux-normandie). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (6 vehicles on 2026-11-13). Served by the national access point’s own proxy of the operator feed. Published through the Atoumod (Normandy) hub; its positions stalled for about ten minutes once on 2026-11-13. Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Astrobus – Communauté d’agglomération Lisieux Normandie |
| **Longwy TGL** (proxy.transport.data.gouv.fr) | Transit layer live vehicles, Longwy, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/horaires-theoriques-du-reseau-tgl). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (21 vehicles on 2026-11-13). Served by the national access point’s own proxy of the operator feed. Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | TGL – Syndicat mixte intercommunal des transports de l’agglomération de Longwy |
| **Lunel Olé** (ole.plateforme-2cloud.com) | Transit layer live vehicles, Lunel, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/offre-de-transport-du-reseau-ole-lunel-agglo-gtfs-et-gtfs-rt). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (2 vehicles on 2026-11-13). | Olé – Communauté d’agglomération Lunel Agglo |
| **Lunéville Lunéo** (pysae.com) | Transit layer live vehicles, Lunéville, France | ODbL (https://transport.data.gouv.fr/datasets/horaires-theoriques-et-temps-reel-du-reseau-lulu-en-bus-ex-luneo-gtfs-gtfs-rt). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (2 vehicles on 2026-11-13). ODbL asks for credit and share-alike on a derived database; the layer draws positions and redistributes no database. Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Lunéo – PETR du Pays du Lunévillois |
| **Martinique Centre (CACEM)** (ext.saemartinique.ovh:4435) | Transit layer live vehicles, Fort-de-France, Martinique, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/gtfs-urbain-de-la-zone-centre). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (28 vehicles on 2026-11-13). | de la zone Centre (CACEM) – Martinique Transport |
| **Martinique Sud (CAESM)** (api.pysae.com) | Transit layer live vehicles, Southern Martinique, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/gtfs-urbain-de-la-zone-sud). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (42 vehicles on 2026-11-13). Routes 4001 to 4004 are the Vedettes boats. | de la zone Sud (CAESM) – Martinique Transport |
| **Mayenne May’bus** (zenbus.net) | Transit layer live vehicles, Mayenne, France | ODbL (https://transport.data.gouv.fr/datasets/horaires-theoriques-et-temps-reel-du-reseau-maybus-mayenne-gtfs-gtfs-rt). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (2 vehicles on 2026-11-13). ODbL asks for credit and share-alike on a derived database; the layer draws positions and redistributes no database. Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | May’bus – Communauté de communes Mayenne Communauté |
| **Mende TUM** (zenbus.net) | Transit layer live vehicles, Mende, France | ODbL (https://transport.data.gouv.fr/datasets/horaires-theoriques-et-temps-reel-du-reseau-max-mende-mobilites-bus-gtfs-gtfs-rt). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (1 vehicles on 2026-11-13). ODbL asks for credit and share-alike on a derived database; the layer draws positions and redistributes no database. Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | TUM – Région Occitanie (CC Coeur de Lozère) |
| **Menton Zest** (proxy.transport.data.gouv.fr) | Transit layer live vehicles, Menton, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/horaires-reseau-zest). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (22 vehicles on 2026-11-13). Served by the national access point’s own proxy of the operator feed. | Zest – Communauté d’agglomération de la Riviera Française |
| **Metz Le Met’** (proxy.transport.data.gouv.fr) | Transit layer live vehicles, Metz, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/fichiers-gtfs-eurometropole-de-metz). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (140 vehicles on 2026-11-13). Served by the national access point’s own proxy of the operator feed. Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Le Met’ – Metz Métropole |
| **Montluçon Maelis** (proxy.transport.data.gouv.fr) | Transit layer live vehicles, Montluçon, France | ODbL (https://transport.data.gouv.fr/datasets/horaires-theoriques-et-reel-du-reseau-maelis-montlucon-communaute-gtfs). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (15 vehicles on 2026-11-13). ODbL asks for credit and share-alike on a derived database; the layer draws positions and redistributes no database. Served by the national access point’s own proxy of the operator feed. Speeds are km/h: readings ran 3.3 times the measured movement on 2026-11-13, so the proxy converts them. The feed carries no route ids. | Maelis – Communauté d’agglomération Montluçon Communauté |
| **Montélimar Montélibus** (proxy.transport.data.gouv.fr) | Transit layer live vehicles, Montélimar, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/horaires-montelibus). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (20 vehicles on 2026-11-13). Served by the national access point’s own proxy of the operator feed. | Montelibus – Communauté d’agglomération Montélimar Agglomération |
| **Moulins Aléo** (api.pysae.com) | Transit layer live vehicles, Moulins, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/donnees-du-reseau-de-transport-aleo). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (16 vehicles on 2026-11-13). | Aléo – Communauté d’agglomération Moulins Communauté |
| **Narbonne Citibus** (feed-citibus-narbonne.ratpdev.com) | Transit layer live vehicles, Narbonne, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/offre-de-transport-communaute-dagglomeration-le-grand-narbonne). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (54 vehicles on 2026-11-13). Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Citibus – Communauté d’agglomération Le Grand Narbonne |
| **Nice Lignes d’Azur** (ara-api.enroute.mobi) | Transit layer live vehicles, Nice, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/donnees-statiques-et-dynamiques-du-reseau-de-transport-lignes-dazur). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (241 vehicles on 2026-11-13). Lines L1, L2 and L3 are the tramway. Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Lignes d’Azur – Métropole Nice Côte d’Azur |
| **Nogent-le-Rotrou Nosbus** (api.pysae.com) | Transit layer live vehicles, Nogent-le-Rotrou, France | ODbL (https://transport.data.gouv.fr/datasets/reseau-urbain-nosbus). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (2 vehicles on 2026-11-13). ODbL asks for credit and share-alike on a derived database; the layer draws positions and redistributes no database. Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Nosbus – Région Centre-Val de Loire (CC du Perche) |
| **Noyon Lib’Bus** (api.oisemob.cityway.fr) | Transit layer live vehicles, Noyon, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/donnees-theoriques-et-temps-reel-du-reseau-libbus-communaute-de-communes-du-pays-noyonnais). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (2 vehicles on 2026-11-13). | Lib’Bus – Communauté de communes du Pays Noyonnais |
| **Oloron-Sainte-Marie La Navette** (zenbus.net) | Transit layer live vehicles, Oloron-Sainte-Marie, France | ODbL (https://transport.data.gouv.fr/datasets/horaires-theoriques-et-temps-reel-du-reseau-oloron-sainte-marie-la-navette-gtfs-gtfs-rt). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (2 vehicles on 2026-11-13). ODbL asks for credit and share-alike on a derived database; the layer draws positions and redistributes no database. Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | La Navette Oloron Sainte-Marie – Communauté de communes du Haut Béarn |
| **Orange TCVO** (tcvo.2cloud.app) | Transit layer live vehicles, Orange, France | ODbL (https://transport.data.gouv.fr/datasets/transport-en-commun-de-la-ville-dorange-ccpop-1). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (5 vehicles on 2026-11-13). ODbL asks for credit and share-alike on a derived database; the layer draws positions and redistributes no database. | TCVO – Pays d’Orange en Provence |
| **Pays de l’Or Transp’Or** (proxy.transport.data.gouv.fr) | Transit layer live vehicles, Mauguio, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/offre-transport-en-commun-du-reseau-transpor-gtfs). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (6 vehicles on 2026-11-13). Served by the national access point’s own proxy of the operator feed. Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Transp’Or – Communauté d’agglomération du Pays de l’Or |
| **Pays des Écrins buses** (app.pysae.com) | Transit layer live vehicles, L’Argentière-la-Bessée, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/transports-en-commun-pays-des-ecrins). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (2 vehicles on 2026-11-13). | Communauté de communes du Pays des Ecrins |
| **Perpignan Sankéo** (zenbus.net) | Transit layer live vehicles, Perpignan, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/gtfs-sankeo). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (50 vehicles on 2026-11-13). | Sankéo – Communauté urbaine Perpignan Méditerranée Métropole |
| **Pont-Sainte-Maxence TOHM** (api.oisemob.cityway.fr) | Transit layer live vehicles, Pont-Sainte-Maxence, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/donnees-theoriques-et-temps-reel-du-reseau-tohm-communaute-de-communes-des-pays-doise-et-dhalatte). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (5 vehicles on 2026-11-13). | TOHM – Communauté de communes des Pays d’Oise et d’Halatte |
| **Pontivy PondiBUS** (pysae.com) | Transit layer live vehicles, Pontivy, France | ODbL (https://transport.data.gouv.fr/datasets/reseau-urbain-pondibus). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (2 vehicles on 2026-11-13). ODbL asks for credit and share-alike on a derived database; the layer draws positions and redistributes no database. Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | PondiBUS – Communauté de communes Pontivy Communauté |
| **Porto-Vecchio A Citadina** (pysae.com) | Transit layer live vehicles, Porto-Vecchio, Corsica, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/reseau-a-citadina-porto-vecchio-horaires-theoriques-et-temps-reel). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (2 vehicles on 2026-11-13). Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | A Citadina – Communauté de communes du Sud Corse |
| **Quimper QUB** (feed-qub-quimper.ratpdev.com) | Transit layer live vehicles, Quimper, France | ODbL (https://transport.data.gouv.fr/datasets/horaires-theoriques-et-du-reseau-de-transports-qub-transports-urbains-de-quimper-bretagne-occidentale). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (49 vehicles on 2026-11-13). ODbL asks for credit and share-alike on a derived database; the layer draws positions and redistributes no database. Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Qub – Communauté d’agglomération Quimper Bretagne Occidentale |
| **Riom RLV Mobilités** (proxy.transport.data.gouv.fr) | Transit layer live vehicles, Riom, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/horaires-rlv-mobilites). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (7 vehicles on 2026-11-13). Served by the national access point’s own proxy of the operator feed. | RLV Mobilités – Communauté d’agglomération Riom Limagne et Volcans |
| **Rosny-sous-Bois Titus** (zenbus.net) | Transit layer live vehicles, Rosny-sous-Bois, France | ODbL (https://transport.data.gouv.fr/datasets/horaires-theoriques-et-temps-reel-du-reseau-titus-rosny-sous-bois-gtfs-gtfs-rt). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (2 vehicles on 2026-11-13). ODbL asks for credit and share-alike on a derived database; the layer draws positions and redistributes no database. Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Titus – Île-de-France Mobilités |
| **Rumilly J’ybus** (proxy.transport.data.gouv.fr) | Transit layer live vehicles, Rumilly, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/offre-de-transports-jybus-a-rumilly). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (6 vehicles on 2026-11-13). Served by the national access point’s own proxy of the operator feed. | Jybus – Communauté de communes Rumilly Terre de Savoie |
| **Rémi coaches** (api.okina.fr) | Transit layer live vehicles, Centre-Val de Loire, France | ODbL (https://transport.data.gouv.fr/datasets/remi-offre-theorique-mobilite-reseau-interurbain-regional). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (100 vehicles on 2026-11-13). ODbL asks for credit and share-alike on a derived database; the layer draws positions and redistributes no database. Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Rémi – Centre-Val de Loire |
| **Réunion Car Jaune** (pysae.com) | Transit layer live vehicles, La Réunion, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/horaires-theoriques-au-format-gtfs-et-horaires-temps-reel-au-format-gtfs-rt-du-reseau-car-jaune-a-la-reunion). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (59 vehicles on 2026-11-13). Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Car Jaune – La Réunion |
| **Sablé-sur-Sarthe Réso** (gtfs-rt.infra-hubup.fr) | Transit layer live vehicles, Sablé-sur-Sarthe, France | ODbL (https://transport.data.gouv.fr/datasets/reseau-urbain-reso). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (2 vehicles on 2026-11-13). ODbL asks for credit and share-alike on a derived database; the layer draws positions and redistributes no database. Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Réso – Communauté de communes du Pays Sabolien |
| **Saint-Brevin Brévibus** (pysae.com) | Transit layer live vehicles, Saint-Brevin-les-Pins, France | ODbL (https://transport.data.gouv.fr/datasets/reseau-urbain-brevibus). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (1 vehicles on 2026-11-13). ODbL asks for credit and share-alike on a derived database; the layer draws positions and redistributes no database. Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Brévibus – Communauté de communes du Sud Estuaire |
| **Saint-Malo MAT** (proxy.transport.data.gouv.fr) | Transit layer live vehicles, Saint-Malo, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/reseau-urbain-mat). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (30 vehicles on 2026-11-13). Served by the national access point’s own proxy of the operator feed. | MAT – Communauté d’agglomération du Pays de Saint Malo Agglomération |
| **Saint-Omer Mouvéo** (proxy.transport.data.gouv.fr) | Transit layer live vehicles, Saint-Omer, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/transports-en-commun-audomarois-1). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (32 vehicles on 2026-11-13). Served by the national access point’s own proxy of the operator feed. | Mouvéo – Communauté d’agglomération du Pays de Saint-Omer |
| **Saint-Pierre Alternéo** (proxy.transport.data.gouv.fr) | Transit layer live vehicles, Saint-Pierre, La Réunion, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/donnees-du-reseau-alterneo). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (17 vehicles on 2026-11-13). Served by the national access point’s own proxy of the operator feed. Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Alternéo – Communauté d’agglomération CIVIS (Communauté Intercommunale des Villes Solidaires) |
| **Saint-Sulpice-la-Pointe buses** (zenbus.net) | Transit layer live vehicles, Saint-Sulpice-la-Pointe, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/reseau-de-transport-urbain-de-la-ville-de-st-sulpice-la-pointe). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (2 vehicles on 2026-11-13). Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | ST SULPICE LA POINTE – Région Occitanie (CC Tarn-Agout) |
| **Saintes Buss** (zenbus.net) | Transit layer live vehicles, Saintes, France | ODbL (https://transport.data.gouv.fr/datasets/horaires-theoriques-et-temps-reel-du-reseau-buss-saintes-gtfs-gtfs-rt). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (19 vehicles on 2026-11-13). ODbL asks for credit and share-alike on a derived database; the layer draws positions and redistributes no database. Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Buss – Communauté d’agglomération de Saintes |
| **Sarlat Bus** (zenbus.net) | Transit layer live vehicles, Sarlat-la-Canéda, France | ODbL (https://transport.data.gouv.fr/datasets/horaires-theoriques-et-temps-reel-du-reseau-sarlatbus-gtfs-gtfs-rt). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (1 vehicles on 2026-11-13). ODbL asks for credit and share-alike on a derived database; the layer draws positions and redistributes no database. Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Sarlat Bus – Communauté de communes Sarlat-Périgord Noir |
| **Sarthe Illygo** (pysae.com) | Transit layer live vehicles, Sarthe, France | ODbL (https://transport.data.gouv.fr/datasets/reseau-urbain-illygo). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (5 vehicles on 2026-11-13). ODbL asks for credit and share-alike on a derived database; the layer draws positions and redistributes no database. Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Illygo – Pôle Métropolitain Mobilités Le Mans – Sarthe |
| **Sète Agglopôle Mobilité** (sete.ceccli.com) | Transit layer live vehicles, Sète, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/reseau-bus-sete-agglopole-mobilite). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (48 vehicles on 2026-11-13). | Sète Agglopole Mobilité – Communauté d’agglomération Sète Agglopôle Méditerranée |
| **Tarbes–Lourdes TLP Mobilités** (zenbus.net) | Transit layer live vehicles, Tarbes, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/horaires-theoriques-du-reseau-tarbes-lourdes-tlp-mobilites-gtfs). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (24 vehicles on 2026-11-13). | TLP – Communauté d’agglomération Tarbes-Lourdes-Pyrénées |
| **Troyes TCAT** (proxy.transport.data.gouv.fr) | Transit layer live vehicles, Troyes, France | ODbL (https://transport.data.gouv.fr/datasets/donnees-tcat-troyes-champagne-metropole-1). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (52 vehicles on 2026-11-13). ODbL asks for credit and share-alike on a derived database; the layer draws positions and redistributes no database. Served by the national access point’s own proxy of the operator feed. | TCAT – Communauté d’agglomération Troyes Champagne Métropole |
| **Valence–Romans Citéa** (proxy.transport.data.gouv.fr) | Transit layer live vehicles, Valence, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/ce-jeu-de-donnees-contient-la-liste-des-arrets-des-horaires-et-des-parcours-theoriques-du-reseau-de-transport-urbain-et-interurbain-de-vrm). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (130 vehicles on 2026-11-13). Served by the national access point’s own proxy of the operator feed. | Citéa – Valence-Romans déplacements |
| **Valenciennes Transvilles** (ara-api.enroute.mobi) | Transit layer live vehicles, Valenciennes, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/simouv-horaires-theoriques-format-gtfs-et-temps-reel-format-siri-transvilles-valenciennes). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (87 vehicles on 2026-11-13). Lines T1 and T2 (route ids 190 and 191) are the tramway. Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Transvilles – Syndicat intercommunal de mobilité et d’organisation urbaine du Valenciennois |
| **Vannes Kicéo** (proxy.transport.data.gouv.fr) | Transit layer live vehicles, Vannes, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/reseau-urbain-kiceo). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (63 vehicles on 2026-11-13). Served by the national access point’s own proxy of the operator feed. Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Kicéo – Communauté d’agglomération Golfe du Morbihan - Vannes Agglomération |
| **Vendôme Move** (pysae.com) | Transit layer live vehicles, Vendôme, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/gtfs-move-vendome). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (7 vehicles on 2026-11-13). Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Move – Communauté d’agglomération Territoires Vendômois |
| **Vernon SNgo!** (proxy.transport.data.gouv.fr) | Transit layer live vehicles, Vernon, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/sngo-vernon-les-andelys-seine-normandie-agglo). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (7 vehicles on 2026-11-13). Served by the national access point’s own proxy of the operator feed. Published through the Atoumod (Normandy) hub; its positions stalled for about ten minutes once on 2026-11-13. Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | SNgo! – Communauté d’agglomération Seine Normandie Agglomération |
| **Vesoul Moova** (proxy.transport.data.gouv.fr) | Transit layer live vehicles, Vesoul, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/horaires-theoriques-du-reseau-moova-communaute-dagglomeration-de-vesoul-gtfs). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (7 vehicles on 2026-11-13). Served by the national access point’s own proxy of the operator feed. | moova – Communauté d’agglomération de Vesoul |
| **Vichy Mobivie** (proxy.transport.data.gouv.fr) | Transit layer live vehicles, Vichy, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/mobivie-reseau-urbain-vichy-communaute). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (11 vehicles on 2026-11-13). Served by the national access point’s own proxy of the operator feed. | Mobivie – Communauté d’agglomération Vichy Communauté |
| **Vienne L’va** (feed-vienne-mobi.ratpdev.com) | Transit layer live vehicles, Vienne, France | ODbL (https://transport.data.gouv.fr/datasets/reseau-lva). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (44 vehicles on 2026-11-13). ODbL asks for credit and share-alike on a derived database; the layer draws positions and redistributes no database. | L’va – Communauté d’agglomération Vienne Condrieu |
| **Vierzon Le Vib’** (proxy.transport.data.gouv.fr) | Transit layer live vehicles, Vierzon, France | ODbL (https://transport.data.gouv.fr/datasets/reseau-urbain-le-vib). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (4 vehicles on 2026-11-13). ODbL asks for credit and share-alike on a derived database; the layer draws positions and redistributes no database. Served by the national access point’s own proxy of the operator feed. Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Le Vib’ – Région Centre-Val de Loire (CC Vierzon-Sologne-Berry) |
| **Yvetot Vikibus** (proxy.transport.data.gouv.fr) | Transit layer live vehicles, Yvetot, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/vikibus-yvetot-normandie). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (3 vehicles on 2026-11-13). Served by the national access point’s own proxy of the operator feed. Published through the Atoumod (Normandy) hub; its positions stalled for about ten minutes once on 2026-11-13. Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Vikibus – Communauté de communes Yvetot Normandie |
| **liO Occitanie coaches** (lio.2cloud.app) | Transit layer live vehicles, Occitanie, France | ODbL (https://transport.data.gouv.fr/datasets/reseau-lio-occitanie). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (243 vehicles on 2026-11-13). ODbL asks for credit and share-alike on a derived database; the layer draws positions and redistributes no database. | liO Occitanie – Occitanie |
| **Évreux Transurbain** (proxy.transport.data.gouv.fr) | Transit layer live vehicles, Évreux, France | Licence Ouverte 2.0 (https://transport.data.gouv.fr/datasets/transurbain-evreux-portes-de-normandie). Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (24 vehicles on 2026-11-13). Served by the national access point’s own proxy of the operator feed. Published through the Atoumod (Normandy) hub; its positions stalled for about ten minutes once on 2026-11-13. Where a route id is not the line name, the name comes from `routes.txt` in the same record’s GTFS. | Transurbain – Communauté d’agglomération Evreux Portes de Normandie |
| **Metro Bilbao** (ctb-gtfs-rt.s3.eu-south-2.amazonaws.com) | Transit layer live vehicles, Bilbao, Spain | CC BY 4.0 (https://data.ctb.eus/en/pages/legal-notice). Legal notice read 2026-11-13. Reuse is allowed for commercial and non-commercial purposes on condition that the source and the date of the last update are mentioned, hence the dated credit. The consortium reserves the right to set other conditions. 15 vehicles on 2026-11-13. | Consorcio de Transportes de Bizkaia (data.ctb.eus) |
| **PKS Rzeszów** (www.mpkrzeszow.pl) | Transit layer live vehicles, Rzeszów, Poland | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-3428). Same server as the MPK Rzeszów feed; its open-data page was read 2026-11-13. Keyless feed on www.mpkrzeszow.pl, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 71 vehicles on 2026-11-13. The feed carries no route ids. | PKS w Rzeszowie S.A. |
| **Metro St. Louis** (gtfs.metrostlouis.org) | Transit layer live vehicles, St. Louis, MO | Metro Transit developer terms of use (https://www.metrostlouis.org/developer-resources/). Developer resources page read 2026-11-13. Acceptance is by use. Agency trademarks may not be used with the data unless approved, so the credit is the name as text. 127 vehicles on 2026-11-13. | Metro Transit – St. Louis |
| **Community Transit** (s3.amazonaws.com) | Transit layer live vehicles, Snohomish County, WA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-1448). Community Transit’s open data page (https://www.communitytransit.org/OpenData, read 2026-11-13) lists this feed for developers, with disclaimers only. Keyless feed on s3.amazonaws.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 137 vehicles on 2026-11-13. | Community Transit |
| **Beach Cities Transit** (redondobeachbct.com) | Transit layer live vehicles, Redondo Beach, CA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-1566). The City of Redondo Beach transit pages were read 2026-11-13. Keyless feed on redondobeachbct.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 9 vehicles on 2026-11-13. The feed carries no route ids. | Beach Cities Transit |
| **Madison Metro Transit** (metromap.cityofmadison.com) | Transit layer live vehicles, Madison, WI | City of Madison developer licence agreement (https://www.cityofmadison.com/metro/business/information-for-developers/developer-license-agreement-and-terms-of-use). Agreement read 2026-11-13. Acceptance is by use; the licence is limited to uses that assist transit riders or promote public transport, which a live vehicle map is. The credit is the wording the agreement offers. 101 vehicles on 2026-11-13. | Data provided under license granted by City of Madison, WI, Metro Transit |
| **MVgo Mountain View** (mtma.tripshot.com) | Transit layer live vehicles, Mountain View, CA | ODC-BY 1.0 (https://mvgo.org/developers/). Developers page read 2026-11-13. ODC-BY asks for attribution on public use. 7 vehicles on 2026-11-13. The feed carries no route ids. | MVgo – Mountain View Transportation Management Association |
| **Emery Go-Round** (emerygoround.tripshot.com) | Transit layer live vehicles, Emeryville, CA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-2227). The Emery Go-Round site was read 2026-11-13. Keyless feed on emerygoround.tripshot.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 13 vehicles on 2026-11-13. The feed carries no route ids. | Emery Go-Round |
| **Valley Regional Transit** (s3.amazonaws.com) | Transit layer live vehicles, Boise, ID | CC BY 3.0 (https://www.valleyregionaltransit.org/about-us/resources/). Resources page read 2026-11-13; it lists this realtime file among the works. 29 vehicles on 2026-11-13. The feed carries no route ids. | Valley Regional Transit |
| **Greater Portland Metro Bus** (gtfsrt.gptd.cadavl.com) | Transit layer live vehicles, Portland, ME | Greater Portland Metro developer terms (https://www.gpmetro.org/about-us/projects-initiatives/developers/). Developers page read 2026-11-13. No credit wording or registration is asked for. 30 vehicles on 2026-11-13. The feed carries no route ids. | Greater Portland Metro |
| **Greater Cleveland RTA** (gtfs-rt.gcrta.vontascloud.com) | Transit layer live vehicles, Cleveland, OH | GCRTA Developer’s License Agreement (https://www.riderta.com/developers). Agreement read 2026-11-13. It asks licensees to “Clearly acknowledge GCRTA as the provider of the Data”, forbids implying GCRTA commissioned the product and forbids its logos, so the credit is text. Acceptance is by use. 294 vehicles on 2026-11-13. | Greater Cleveland Regional Transit Authority (GCRTA) |
| **Fairfax Connector** (www.fairfaxcounty.gov) | Transit layer live vehicles, Fairfax County, VA | Fairfax County transportation data licence (https://www.fairfaxcounty.gov/connector/bustracker/data). Terms read 2026-11-13. They require the statement “Visit fairfaxconnector.com for more information” with a link, which the credit carries, and limit use to assisting transit users. 94 vehicles on 2026-11-13. | Fairfax Connector. Visit fairfaxconnector.com for more information |
| **Butler County RTA** (www.buztrakr.com) | Transit layer live vehicles, Wayne Township, OH | Public realtime vehicle feed (https://gtfsrt.io/). BCRTA’s GTFS page (https://www.butlercountyrta.com/gtfs-download/, read 2026-11-13) links this host. Keyless feed on www.buztrakr.com, listed in the gtfsrt.io directory as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 18 vehicles on 2026-11-13. The feed carries no route ids. | Butler County RTA |
| **Société de transport collectif de Pierre-De Saurel** (zenbus.net) | Transit layer live vehicles, Sorel-Tracy, QC, Canada | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-2380). Keyless feed on zenbus.net, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 5 vehicles on 2026-11-13. | Société de transport collectif de Pierre-De Saurel |
| **Regional Municipality of Wood Buffalo Transit** (rmwb-gtfsrt.civilia.ca) | Transit layer live vehicles, Fort McMurray, AB, Canada | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-4691-vp). Keyless feed on rmwb-gtfsrt.civilia.ca, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 9 vehicles on 2026-11-13. | Regional Municipality of Wood Buffalo Transit |
| **Bus Mont-Tremblant** (zenbus.net) | Transit layer live vehicles, Mont-Tremblant, QC, Canada | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-5619-vp). Keyless feed on zenbus.net, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 1 vehicles on 2026-11-13. | Bus Mont-Tremblant |
| **Saint Jean Sur Richelieu** (zenbus.net) | Transit layer live vehicles, Saint-Jean-sur-Richelieu, QC, Canada | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-5631-vp). Keyless feed on zenbus.net, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 9 vehicles on 2026-11-13. | Saint Jean Sur Richelieu |
| **L'Inter des Laurentides** (zenbus.net) | Transit layer live vehicles, Saint-Sauveur, QC, Canada | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-5723-vp). Keyless feed on zenbus.net, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 1 vehicles on 2026-11-13. | L'Inter des Laurentides |
| **MRC du Haut-Saint-Laurent** (gtfs-rt.infra-hubup.fr) | Transit layer live vehicles, Salaberry-de-Valleyfield, QC, Canada | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-6693-tu_vp). Keyless feed on gtfs-rt.infra-hubup.fr, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 3 vehicles on 2026-11-13. | MRC du Haut-Saint-Laurent |
| **Empresa Municipal de Transportes de Fuenlabrada (EMTF)** (api.control.optibus.co) | Transit layer live vehicles, Fuenlabrada, Spain | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-2402). Keyless feed on api.control.optibus.co, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 26 vehicles on 2026-11-13. | Empresa Municipal de Transportes de Fuenlabrada (EMTF) |
| **Orosháza local bus** (gtfs.gpspositions.net) | Transit layer live vehicles, Orosháza, Hungary | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-3484). Keyless feed on gtfs.gpspositions.net, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 2 vehicles on 2026-11-13. | FlexCom Kommunikációs Kft. |
| **TEP PARMA** (s3.eu-south-1.amazonaws.com) | Transit layer live vehicles, Parma, Italy | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-3452). Keyless feed on s3.eu-south-1.amazonaws.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 62 vehicles on 2026-11-13. | TEP PARMA |
| **Chișinău RTEC and PUA** (chisinau-rt-feed.gtfs.ro) | Transit layer live vehicles, Chișinău, Moldova | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-2342). Keyless feed on chisinau-rt-feed.gtfs.ro, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 409 vehicles on 2026-11-13. | Regia Transport Electric Chișinău, Î.M. Parcul Urban de Autobuze |
| **Transbus Buzău** (gtfsagent.transportpublic.ro) | Transit layer live vehicles, Buzău, Romania | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-2113). Keyless feed on gtfsagent.transportpublic.ro, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 2 vehicles on 2026-11-13. | Transbus Buzău |
| **Merced County Transit (The Bus)** (thebuslive.com) | Transit layer live vehicles, Merced, CA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-1506). Keyless feed on thebuslive.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 27 vehicles on 2026-11-13. The feed carries no route ids. | Merced County Transit (The Bus) |
| **Intercity Transit** (its.rideralerts.com) | Transit layer live vehicles, Olympia, WA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-1537). Keyless feed on its.rideralerts.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 63 vehicles on 2026-11-13. | Intercity Transit |
| **Stanislaus Regional Transit Authority (StanRTA)** (max.availtec.com) | Transit layer live vehicles, Modesto, CA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-1614). Keyless feed on max.availtec.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 54 vehicles on 2026-11-13. | Stanislaus Regional Transit Authority (StanRTA) |
| **Tompkins Consolidated Area Transit (TCAT)** (realtimetcatbus.availtec.com) | Transit layer live vehicles, Ithaca, NY | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-1649). Keyless feed on realtimetcatbus.availtec.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 26 vehicles on 2026-11-13. | Tompkins Consolidated Area Transit (TCAT) |
| **Riverside Transit Agency** (rtabus.com) | Transit layer live vehicles, Riverside, CA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-1665). Keyless feed on rtabus.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 148 vehicles on 2026-11-13. | Riverside Transit Agency |
| **Towson Loop** (passio3.com) | Transit layer live vehicles, Towson, MD | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-1787). Keyless feed on passio3.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 7 vehicles on 2026-11-13. | Towson Loop |
| **Commerce Municipal Bus Lines** (citycommbus.com) | Transit layer live vehicles, Commerce, CA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-1794). Keyless feed on citycommbus.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 9 vehicles on 2026-11-13. The feed carries no route ids. | Commerce Municipal Bus Lines |
| **Mountain Line Transit** (mountainline.syncromatics.com) | Transit layer live vehicles, Flagstaff, AZ | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-1980). Keyless feed on mountainline.syncromatics.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 21 vehicles on 2026-11-13. The feed carries no route ids. | Mountain Line Transit |
| **Ben Franklin Transit** (myride.bft.org) | Transit layer live vehicles, Pasco, WA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-2125). Keyless feed on myride.bft.org, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 55 vehicles on 2026-11-13. | Ben Franklin Transit |
| **Montebello Bus Lines** (mbl.rideralerts.com) | Transit layer live vehicles, Montebello, CA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-2218). Keyless feed on mbl.rideralerts.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 36 vehicles on 2026-11-13. | Montebello Bus Lines |
| **Spirit Bus** (passio3.com) | Transit layer live vehicles, Monterey Park, CA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-2221). Keyless feed on passio3.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 3 vehicles on 2026-11-13. | Spirit Bus |
| **Middletown Area Transit** (passio3.com) | Transit layer live vehicles, Portland, CT | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-2271). Keyless feed on passio3.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 8 vehicles on 2026-11-13. | Middletown Area Transit |
| **Via Mobility** (passio3.com) | Transit layer live vehicles, Boulder, CO | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-2398). Keyless feed on passio3.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 9 vehicles on 2026-11-13. | Via Mobility |
| **Butte Regional Transit (B-Line)** (planmyride.blinetransit.com) | Transit layer live vehicles, Chico, CA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-2428). Keyless feed on planmyride.blinetransit.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 20 vehicles on 2026-11-13. | Butte Regional Transit (B-Line) |
| **University of Georgia** (passio3.com) | Transit layer live vehicles, Athens, GA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-2619). Keyless feed on passio3.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 33 vehicles on 2026-11-13. | University of Georgia |
| **Transit Authority of River City (TARC)** (tarc.rideralerts.com) | Transit layer live vehicles, Louisville, KY | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-2665). Keyless feed on tarc.rideralerts.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 70 vehicles on 2026-11-13. | Transit Authority of River City (TARC) |
| **South Metro Area Regional Transit (SMART)** (mysmartbus.com) | Transit layer live vehicles, Wilsonville, OR | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-2707). Keyless feed on mysmartbus.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 13 vehicles on 2026-11-13. The feed carries no route ids. | South Metro Area Regional Transit (SMART) |
| **ClackCo Connects (Clackamas County)** (passio3.com) | Transit layer live vehicles, Clackamas County, OR | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-2744). Keyless feed on passio3.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 5 vehicles on 2026-11-13. | ClackCo Connects (Clackamas County) |
| **Sandy Area Metro** (passio3.com) | Transit layer live vehicles, Sandy, OR | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-2747). Keyless feed on passio3.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 6 vehicles on 2026-11-13. | Sandy Area Metro |
| **Champaign-Urbana Mass Transit District** (gtfs-rt.mtd.org) | Transit layer live vehicles, Champaign, IL | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-2889). Keyless feed on gtfs-rt.mtd.org, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 72 vehicles on 2026-11-13. | Champaign-Urbana Mass Transit District |
| **Clovis Transit** (passio3.com) | Transit layer live vehicles, Clovis, CA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-2897). Keyless feed on passio3.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 14 vehicles on 2026-11-13. | Clovis Transit |
| **Frederick County TransIT** (passio3.com) | Transit layer live vehicles, Frederick, MD | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-3070). Keyless feed on passio3.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 14 vehicles on 2026-11-13. | Frederick County TransIT |
| **South Bend Public Transportation Corporation** (passio3.com) | Transit layer live vehicles, South Bend, IN | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-3077). Keyless feed on passio3.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 23 vehicles on 2026-11-13. | South Bend Public Transportation Corporation |
| **Cecil Transit** (passio3.com) | Transit layer live vehicles, Elkton, MD | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-3080). Keyless feed on passio3.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 4 vehicles on 2026-11-13. | Cecil Transit |
| **NY Waterway** (nywaterway.connexionz.net) | Transit layer live vehicles, New York, NY | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-3199). Keyless feed on nywaterway.connexionz.net, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 3 vehicles on 2026-11-13. The feed carries no route ids. | NY Waterway |
| **El Paso Transportation Authority** (data.peaktransit.com) | Transit layer live vehicles, El Paso County, TX | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-3204). Keyless feed on data.peaktransit.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 6 vehicles on 2026-11-13. | El Paso Transportation Authority |
| **Monroe County Transportation Authority (MCTA)** (ponytracker.availtec.com) | Transit layer live vehicles, Pocono Township, PA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-3436). Keyless feed on ponytracker.availtec.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 7 vehicles on 2026-11-13. | Monroe County Transportation Authority (MCTA) |
| **Shore Transit** (myride.shoretransit.org) | Transit layer live vehicles, Salisbury, MD | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-3443). Keyless feed on myride.shoretransit.org, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 3 vehicles on 2026-11-13. | Shore Transit |
| **Rogue Valley Transportation District** (gtfsrt.rvtd.cadavl.com) | Transit layer live vehicles, Medford, OR | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-3458). Keyless feed on gtfsrt.rvtd.cadavl.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 13 vehicles on 2026-11-13. The feed carries no route ids. | Rogue Valley Transportation District |
| **Broward County Transit** (myride2.broward.org) | Transit layer live vehicles, Broward County, FL | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-3475). Keyless feed on myride2.broward.org, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 149 vehicles on 2026-11-13. | Broward County Transit |
| **University of Minnesota** (data.peaktransit.com) | Transit layer live vehicles, Minneapolis, MN | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/mdb-3528). Keyless feed on data.peaktransit.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 19 vehicles on 2026-11-13. | University of Minnesota |
| **Greenlink** (gtfsrt.greenlink.cadavl.com) | Transit layer live vehicles, Greenville, SC | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-2266-vp_1). Keyless feed on gtfsrt.greenlink.cadavl.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 13 vehicles on 2026-11-13. | Greenlink |
| **Sacramento Regional Transit** (bustime.sacrt.com) | Transit layer live vehicles, Sacramento, CA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-3391-vp). Keyless feed on bustime.sacrt.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 137 vehicles on 2026-11-13. | Sacramento Regional Transit |
| **GoDurham** (godurham.rideralerts.com) | Transit layer live vehicles, Durham, NC | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-4062-vp). Keyless feed on godurham.rideralerts.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 48 vehicles on 2026-11-13. | GoDurham |
| **Cascades East Transit** (passio3.com) | Transit layer live vehicles, Bend, OR | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-4067-vp). Keyless feed on passio3.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 18 vehicles on 2026-11-13. | Cascades East Transit |
| **Capital Area Transit** (cat.rideralerts.com) | Transit layer live vehicles, Harrisburg, PA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-4299-vp). Keyless feed on cat.rideralerts.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 25 vehicles on 2026-11-13. | Capital Area Transit |
| **City of Santa Clarita Transit** (apps.santaclaritatransit.com) | Transit layer live vehicles, Santa Clarita, CA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-4328-vp). Keyless feed on apps.santaclaritatransit.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 44 vehicles on 2026-11-13. The feed carries no route ids. | City of Santa Clarita Transit |
| **Akron Metro Regional Transit Authority** (realtimemetro.availtec.com) | Transit layer live vehicles, Akron, OH | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-4332-vp). Keyless feed on realtimemetro.availtec.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 69 vehicles on 2026-11-13. | Akron Metro Regional Transit Authority |
| **Whatcom Transportation Authority** (bustracker.ridewta.com) | Transit layer live vehicles, Bellingham, WA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-4358-vp). Keyless feed on bustracker.ridewta.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 47 vehicles on 2026-11-13. | Whatcom Transportation Authority |
| **Santa Barbara Metropolitan Transit District** (bustracker.sbmtd.gov) | Transit layer live vehicles, Santa Barbara, CA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-4360-vp). Keyless feed on bustracker.sbmtd.gov, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 60 vehicles on 2026-11-13. | Santa Barbara Metropolitan Transit District |
| **Spokane Transit Authority** (gtfsbridge.spokanetransit.com) | Transit layer live vehicles, Spokane, WA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-4363-vp). Keyless feed on gtfsbridge.spokanetransit.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 123 vehicles on 2026-11-13. | Spokane Transit Authority |
| **Torrance Transit** (www.mybusinfo.com) | Transit layer live vehicles, Torrance, CA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-4364-vp). Keyless feed on www.mybusinfo.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 47 vehicles on 2026-11-13. | Torrance Transit |
| **Metropolitan Tulsa Transit Authority** (tulsa.rideralerts.com) | Transit layer live vehicles, Tulsa, OK | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-4374-vp). Keyless feed on tulsa.rideralerts.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 40 vehicles on 2026-11-13. | Metropolitan Tulsa Transit Authority |
| **MARC Train (Maryland Transit Administration)** (mdotmta-gtfs-rt.s3.amazonaws.com) | Transit layer live vehicles, Baltimore, MD | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-4451-vp). Keyless feed on mdotmta-gtfs-rt.s3.amazonaws.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 2 vehicles on 2026-11-13. | MARC Train (Maryland Transit Administration) |
| **Fresno Area Express** (gis4u.fresno.gov) | Transit layer live vehicles, Fresno, CA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-4483-vp). Keyless feed on gis4u.fresno.gov, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 106 vehicles on 2026-11-13. | Fresno Area Express |
| **Antelope Valley Transit Authority** (track-it.avta.com) | Transit layer live vehicles, Palmdale, CA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-4485-vp). Keyless feed on track-it.avta.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 36 vehicles on 2026-11-13. | Antelope Valley Transit Authority |
| **River Valley Transit** (my.ridervt.com) | Transit layer live vehicles, Williamsport, PA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-4549-vp). Keyless feed on my.ridervt.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 14 vehicles on 2026-11-13. | River Valley Transit |
| **Area Transit Authority** (rideata.rideralerts.com) | Transit layer live vehicles, DuBois, PA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-4552-vp). Keyless feed on rideata.rideralerts.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 13 vehicles on 2026-11-13. | Area Transit Authority |
| **County of Lackawanna Transit System** (coltsivl.availtec.com) | Transit layer live vehicles, Scranton, PA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-4554-vp). Keyless feed on coltsivl.availtec.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 19 vehicles on 2026-11-13. | County of Lackawanna Transit System |
| **Luzerne County Transportation Authority** (realtimelctabus.availtec.com) | Transit layer live vehicles, Wilkes-Barre, PA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-4556-vp). Keyless feed on realtimelctabus.availtec.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 22 vehicles on 2026-11-13. | Luzerne County Transportation Authority |
| **Butler Transit Authority** (butlerivl.availtec.com) | Transit layer live vehicles, Butler, PA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-4660-vp). Keyless feed on butlerivl.availtec.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 4 vehicles on 2026-11-13. | Butler Transit Authority |
| **Indiana County Transit Authority** (indigobus.availtec.com) | Transit layer live vehicles, Indiana, PA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-4662-vp). Keyless feed on indigobus.availtec.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 7 vehicles on 2026-11-13. | Indiana County Transit Authority |
| **Shenango Valley Shuttle Service** (svss.availtec.com) | Transit layer live vehicles, Hermitage, PA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-4664-vp). Keyless feed on svss.availtec.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 3 vehicles on 2026-11-13. | Shenango Valley Shuttle Service |
| **Hazleton Public Transit** (realtimehpts.availtec.com) | Transit layer live vehicles, Hazleton, PA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-4666-vp). Keyless feed on realtimehpts.availtec.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 8 vehicles on 2026-11-13. | Hazleton Public Transit |
| **Altoona Metro Transit** (amtran.rideralerts.com) | Transit layer live vehicles, Altoona, PA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-4670-vp). Keyless feed on amtran.rideralerts.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 12 vehicles on 2026-11-13. | Altoona Metro Transit |
| **Cambria County Transit Authority** (live.camtranbus.com) | Transit layer live vehicles, Dale, PA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-4672-vp). Keyless feed on live.camtranbus.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 21 vehicles on 2026-11-13. | Cambria County Transit Authority |
| **Centre County Transit Authority** (realtime.catabus.com) | Transit layer live vehicles, State College, PA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-4673-vp). Keyless feed on realtime.catabus.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 34 vehicles on 2026-11-13. | Centre County Transit Authority |
| **Crawford Area Transportation Authority** (catabus.rideralerts.com) | Transit layer live vehicles, Troy Township, PA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-4675-vp). Keyless feed on catabus.rideralerts.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 6 vehicles on 2026-11-13. | Crawford Area Transportation Authority |
| **The Rapid** (connect.ridetherapid.org) | Transit layer live vehicles, Grand Rapids, MI | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-4676-vp). Keyless feed on connect.ridetherapid.org, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 78 vehicles on 2026-11-13. | The Rapid |
| **Kalamazoo Metro Transit** (trackmybus.kmetro.org) | Transit layer live vehicles, Kalamazoo, MI | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-4677-vp). Keyless feed on trackmybus.kmetro.org, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 26 vehicles on 2026-11-13. | Kalamazoo Metro Transit |
| **Schuylkill Transportation System** (sts.rideralerts.com) | Transit layer live vehicles, Pottsville, PA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-4689-vp). Keyless feed on sts.rideralerts.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 7 vehicles on 2026-11-13. | Schuylkill Transportation System |
| **Western Reserve Transit Authority** (myvalleystops.wrtaonline.com) | Transit layer live vehicles, Youngstown, OH | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-4692-vp). Keyless feed on myvalleystops.wrtaonline.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 29 vehicles on 2026-11-13. | Western Reserve Transit Authority |
| **Athens Clarke County Transit** (bustracker.accgov.com) | Transit layer live vehicles, Athens, GA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-4783-vp). Keyless feed on bustracker.accgov.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 21 vehicles on 2026-11-13. | Athens Clarke County Transit |
| **Manatee County Area Transit** (realtimemcat.availtec.com) | Transit layer live vehicles, Manatee County, FL | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-4784-vp). Keyless feed on realtimemcat.availtec.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 24 vehicles on 2026-11-13. | Manatee County Area Transit |
| **Lehigh and Northampton Transportation Authority** (realtimelanta.availtec.com) | Transit layer live vehicles, Allentown, PA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-4785-vp). Keyless feed on realtimelanta.availtec.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 48 vehicles on 2026-11-13. | Lehigh and Northampton Transportation Authority |
| **Norwalk Transit District** (mystop.norwalktransit.com) | Transit layer live vehicles, Norwalk, CT | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-4790-vp). Keyless feed on mystop.norwalktransit.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 20 vehicles on 2026-11-13. | Norwalk Transit District |
| **Valley Transit** (itransitnw.com) | Transit layer live vehicles, Walla Walla, WA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-4793-vp). Keyless feed on itransitnw.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 10 vehicles on 2026-11-13. The feed carries no route ids. | Valley Transit |
| **Muskegon Area Transit System** (muskegon.connexionz.net) | Transit layer live vehicles, Muskegon, MI | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-4832-vp). Keyless feed on muskegon.connexionz.net, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 8 vehicles on 2026-11-13. The feed carries no route ids. | Muskegon Area Transit System |
| **Bustang** (open-data.rtd-denver.com) | Transit layer live vehicles, Denver, CO | RTD GTFS-realtime licence agreement (https://www.rtd-denver.com/business-center/open-spatial-data/gtfs-realtime-license-agreement). Served from RTD’s open-data host beside the Denver RTD feed, under the same click-through agreement (see `rtd-denver`). Same server and basis as that feed. 10 vehicles on 2026-11-13. | Bustang (CDOT), via RTD open data |
| **Link Transit** (link.rideralerts.com) | Transit layer live vehicles, Wenatchee, WA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-5502-vp). Keyless feed on link.rideralerts.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 33 vehicles on 2026-11-13. | Link Transit |
| **Mid Mon Valley Transit Authority** (mmvta.rideralerts.com) | Transit layer live vehicles, Charleroi, PA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-5504-vp). Keyless feed on mmvta.rideralerts.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 9 vehicles on 2026-11-13. | Mid Mon Valley Transit Authority |
| **Lebanon Transit** (realtime.lebanontransit.org) | Transit layer live vehicles, Lebanon, PA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-5532-vp). Keyless feed on realtime.lebanontransit.org, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 7 vehicles on 2026-11-13. | Lebanon Transit |
| **rabbittransit** (realtime.rabbittransit.org) | Transit layer live vehicles, York, PA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-5539-vp). Keyless feed on realtime.rabbittransit.org, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 21 vehicles on 2026-11-13. | rabbittransit |
| **Norwalk Transit System** (nts.rideralerts.com) | Transit layer live vehicles, Norwalk, CA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-5546-vp). Keyless feed on nts.rideralerts.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 24 vehicles on 2026-11-13. | Norwalk Transit System |
| **Ride Gwinnett** (realtimegwinnett.availtec.com) | Transit layer live vehicles, Gwinnett County, GA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-5550-vp). Keyless feed on realtimegwinnett.availtec.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 29 vehicles on 2026-11-13. | Ride Gwinnett |
| **StarTran** (startran.connexionz.net) | Transit layer live vehicles, Lincoln, NE | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-5554-vp). Keyless feed on startran.connexionz.net, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 23 vehicles on 2026-11-13. The feed carries no route ids. | StarTran |
| **Yamhill County Transit Area** (ycta.connexionz.net) | Transit layer live vehicles, Yamhill County, OR | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-5555-vp). Keyless feed on ycta.connexionz.net, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 6 vehicles on 2026-11-13. The feed carries no route ids. | Yamhill County Transit Area |
| **Greater Peoria Mass Transit** (clk.rideralerts.com) | Transit layer live vehicles, West Peoria, IL | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-5581-vp). Keyless feed on clk.rideralerts.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 24 vehicles on 2026-11-13. | Greater Peoria Mass Transit |
| **Racine Transit** (racine.connexionz.net) | Transit layer live vehicles, Racine, WI | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-5582-vp). Keyless feed on racine.connexionz.net, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 14 vehicles on 2026-11-13. The feed carries no route ids. | Racine Transit |
| **Berks Area Regional Transportation Authority** (busfinder.bartabus.com) | Transit layer live vehicles, Reading, PA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-5839-vp). Keyless feed on busfinder.bartabus.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 27 vehicles on 2026-11-13. | Berks Area Regional Transportation Authority |
| **Red Rose Transit Authority** (busfinder.redrosetransit.com) | Transit layer live vehicles, Lancaster, PA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-5840-vp). Keyless feed on busfinder.redrosetransit.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 22 vehicles on 2026-11-13. | Red Rose Transit Authority |
| **Concho Valley Transit District** (passio3.com) | Transit layer live vehicles, San Angelo, TX | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-5865-vp). Keyless feed on passio3.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 5 vehicles on 2026-11-13. | Concho Valley Transit District |
| **Culver CityBus** (nextccbus.org) | Transit layer live vehicles, Culver City, CA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-5892-vp). Keyless feed on nextccbus.org, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 40 vehicles on 2026-11-13. | Culver CityBus |
| **Billings Metropolitan Transit** (passio3.com) | Transit layer live vehicles, Billings, MT | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-5894-vp). Keyless feed on passio3.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 13 vehicles on 2026-11-13. | Billings Metropolitan Transit |
| **Skagit Transit** (strweb.skagittransit.org) | Transit layer live vehicles, Burlington, WA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-5896-vp). Keyless feed on strweb.skagittransit.org, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 21 vehicles on 2026-11-13. | Skagit Transit |
| **Lakeland Area Mass Transit District** (www.ccbusinfo.com) | Transit layer live vehicles, Lakeland, FL | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-5898-vp). Keyless feed on www.ccbusinfo.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 29 vehicles on 2026-11-13. | Lakeland Area Mass Transit District |
| **Housatonic Area Regional Transit** (passio3.com) | Transit layer live vehicles, Danbury, CT | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-5903-vp). Keyless feed on passio3.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 12 vehicles on 2026-11-13. | Housatonic Area Regional Transit |
| **Bis-Man Transit** (passio3.com) | Transit layer live vehicles, Bismarck, ND | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-6096-vp). Keyless feed on passio3.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 7 vehicles on 2026-11-13. | Bis-Man Transit |
| **Chapel Hill Transit** (mychtransit.org) | Transit layer live vehicles, Chapel Hill, NC | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-6626-vp). Keyless feed on mychtransit.org, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 35 vehicles on 2026-11-13. The feed carries no route ids. | Chapel Hill Transit |
| **Wichita Transit** (bus.wichitatransit.org) | Transit layer live vehicles, Wichita, KS | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-6669-vp). Keyless feed on bus.wichitatransit.org, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 23 vehicles on 2026-11-13. | Wichita Transit |
| **New River Transit Authority** (passio3.com) | Transit layer live vehicles, Beckley, WV | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-6714-vp). Keyless feed on passio3.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 5 vehicles on 2026-11-13. | New River Transit Authority |
| **City of Irvine** (passio3.com) | Transit layer live vehicles, Irvine, CA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-6725-vp). Keyless feed on passio3.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 6 vehicles on 2026-11-13. | City of Irvine |
| **North Central Regional Transit District** (bluebustracker.availtec.com) | Transit layer live vehicles, Rio Arriba County, NM | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-6744-vp). Keyless feed on bluebustracker.availtec.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 17 vehicles on 2026-11-13. | North Central Regional Transit District |
| **City of Mobile** (realtimemobile.availtec.com) | Transit layer live vehicles, Mobile, AL | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-6774-vp). Keyless feed on realtimemobile.availtec.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 12 vehicles on 2026-11-13. | City of Mobile |
| **Capital Area Transit System** (cats.rideralerts.com) | Transit layer live vehicles, Baton Rouge, LA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-6784-vp). Keyless feed on cats.rideralerts.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 29 vehicles on 2026-11-13. | Capital Area Transit System |
| **Westmoreland County Transit Authority** (wcta.rideralerts.com) | Transit layer live vehicles, Hempfield Township, PA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-6786-vp). Keyless feed on wcta.rideralerts.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 13 vehicles on 2026-11-13. | Westmoreland County Transit Authority |
| **City of Jacksonville** (passio3.com) | Transit layer live vehicles, Jacksonville, NC | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-6820-vp). Keyless feed on passio3.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 5 vehicles on 2026-11-13. | City of Jacksonville |
| **GoCary** (www.gocarylive.org) | Transit layer live vehicles, Cary, NC | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-6821-vp). Keyless feed on www.gocarylive.org, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 16 vehicles on 2026-11-13. | GoCary |
| **Bloomington Transit** (s3.amazonaws.com) | Transit layer live vehicles, Bloomington, IN | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-6882-vp). Keyless feed on s3.amazonaws.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 27 vehicles on 2026-11-13. The feed carries no route ids. | Bloomington Transit |
| **NCSU Wolfline** (passio3.com) | Transit layer live vehicles, Raleigh, NC | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-6896-vp). Keyless feed on passio3.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 21 vehicles on 2026-11-13. | NCSU Wolfline |
| **Endless Mountains Transportation Authority** (best.rideralerts.com) | Transit layer live vehicles, Ulster Township, PA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-7022-vp). Keyless feed on best.rideralerts.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 7 vehicles on 2026-11-13. | Endless Mountains Transportation Authority |
| **Lower Anthracite Transit System** (lats.rideralerts.com) | Transit layer live vehicles, Mount Carmel Township, PA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-7024-vp). Keyless feed on lats.rideralerts.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 2 vehicles on 2026-11-13. | Lower Anthracite Transit System |
| **Pottstown Area Rapid Transit** (part.rideralerts.com) | Transit layer live vehicles, Pottstown, PA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-7026-vp). Keyless feed on part.rideralerts.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 3 vehicles on 2026-11-13. | Pottstown Area Rapid Transit |
| **Fayette Area Coordinated Transportation** (fact.rideralerts.com) | Transit layer live vehicles, South Union Township, PA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-7028-vp). Keyless feed on fact.rideralerts.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 5 vehicles on 2026-11-13. | Fayette Area Coordinated Transportation |
| **Freedom Transit** (freedom.rideralerts.com) | Transit layer live vehicles, Chartiers Township, PA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-7029-vp). Keyless feed on freedom.rideralerts.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 5 vehicles on 2026-11-13. | Freedom Transit |
| **New Castle Area Transit Authority** (ncata.rideralerts.com) | Transit layer live vehicles, New Castle, PA | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-7031-vp). Keyless feed on ncata.rideralerts.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 12 vehicles on 2026-11-13. | New Castle Area Transit Authority |
| **Lexington Transit Authority** (mystop.lextran.com) | Transit layer live vehicles, Lexington, KY | Public realtime vehicle feed (https://mobilitydatabase.org/feeds/gtfs_rt/tld-7044-vp). Keyless feed on mystop.lextran.com, listed in the Mobility Database as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 44 vehicles on 2026-11-13. | Lexington Transit Authority |
| **MetroLINK Quad Cities** (bustracker.metroqc.com) | Transit layer live vehicles, Moline, IL | Public realtime vehicle feed (https://www.transit.land/feeds/f-9zrs-metrorockislandcountymetropolitanmasstransitdistrict~rt). Keyless feed on bustracker.metroqc.com, listed in the Transitland Atlas as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 33 vehicles on 2026-11-13. | MetroLINK Quad Cities |
| **Streamline Bozeman** (ridestreamline.com) | Transit layer live vehicles, Bozeman, MT | Public realtime vehicle feed (https://www.transit.land/feeds/f-c815-streamlinetransit~mt~us~rt). Keyless feed on ridestreamline.com, listed in the Transitland Atlas as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 1 vehicles on 2026-11-13. The feed carries no route ids. | Streamline Bozeman |
| **Coast RTA** (coastrta.transloc.com) | Transit layer live vehicles, Myrtle Beach, SC | Public realtime vehicle feed (https://www.transit.land/feeds/f-coast~rta~sc~us~rt). Keyless feed on coastrta.transloc.com, listed in the Transitland Atlas as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 9 vehicles on 2026-11-13. | Coast RTA |
| **LAX airport shuttles** (laxtransportation.transloc.com) | Transit layer live vehicles, Los Angeles, CA | Public realtime vehicle feed (https://www.transit.land/feeds/f-lax~flyaway~rt). Keyless feed on laxtransportation.transloc.com, listed in the Transitland Atlas as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 6 vehicles on 2026-11-13. | LAX airport shuttles |
| **Mission Viejo Shuttle** (mvshuttle.transloc.com) | Transit layer live vehicles, Mission Viejo, CA | Public realtime vehicle feed (https://www.transit.land/feeds/f-mission~viejo~shuttle~rt). Keyless feed on mvshuttle.transloc.com, listed in the Transitland Atlas as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 2 vehicles on 2026-11-13. | Mission Viejo Shuttle |
| **LAX FlyAway** (laxflyaway.transloc.com) | Transit layer live vehicles, Los Angeles, CA | Public realtime vehicle feed (https://www.transit.land/feeds/f-laxflyaway~rt). Keyless feed on laxflyaway.transloc.com, listed in the Transitland Atlas as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 4 vehicles on 2026-11-13. | LAX FlyAway |
| **Triton Transit (UC San Diego)** (api.us.sparelabs.com) | Transit layer live vehicles, San Diego, CA | Public realtime vehicle feed (https://www.transit.land/feeds/f-9muy-tritontransit~rt). Keyless feed on api.us.sparelabs.com, listed in the Transitland Atlas as this operator’s vehicle positions. Shipped on the same basis as Metro Transit and OVapi, and credited as a courtesy; switch it off if the operator objects. 11 vehicles on 2026-11-13. | Triton Transit (UC San Diego) |
| **Zagreb ZET** (zet.hr) | Transit layer live vehicles, Zagreb, Croatia | Open Licence – Republic of Croatia (https://www.zet.hr/odredbe/datoteke-u-gtfs-formatu/669). ZET’s GTFS page, read 2026-11-13, places its GTFS and GTFS-realtime data under the Croatian open licence. The feed mixes trams and buses; route ids do not tell them apart, so the default is a guess. 345 vehicles on 2026-11-13. | Zagrebački električni tramvaj (ZET) |
| **Toyama Chitetsu Bus** (gtfs-rt-files.buscatch.jp) | Transit layer live vehicles, Toyama Prefecture, Japan | CC0 1.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-chitetsu-chitetsubus-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. Vehicle positions were seen on 2026-11-14 at 08:00 Japan time (26 vehicles). The centre is the middle of the vehicles seen then. | 富山地方鉄道 (Toyama Chitetsu Bus) |
| **Imizu Kitokito Bus** (gtfs-rt-files.buscatch.jp) | Transit layer live vehicles, Toyama Prefecture, Japan | CC0 1.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-imizucity-imizushi-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. Vehicle positions were seen on 2026-11-14 at 08:00 Japan time (1 vehicle). The centre is the catalogue’s bounding-box centre for the network. | 射水市 (Imizu Kitokito Bus) |
| **Kaetsunō Bus Himi loop** (gtfs-rt-files.buscatch.jp) | Transit layer live vehicles, Toyama Prefecture, Japan | CC0 1.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-kaetsunou-kaetsunouhimi-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. Vehicle positions were seen on 2026-11-14 at 08:00 Japan time (1 vehicle). The centre is the catalogue’s bounding-box centre for the network. | 加越能バス (Kaetsunō Bus Himi loop) |
| **Kaetsunō Bus** (gtfs-rt-files.buscatch.jp) | Transit layer live vehicles, Toyama Prefecture, Japan | CC0 1.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-kaetsunou-kaetsunouippan-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. Vehicle positions were seen on 2026-11-14 at 08:00 Japan time (13 vehicles). The centre is the middle of the vehicles seen then. | 加越能バス (Kaetsunō Bus) |
| **Kaetsunō World Heritage Bus** (gtfs-rt-files.buscatch.jp) | Transit layer live vehicles, Toyama Prefecture, Japan | CC0 1.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-kaetsunou-kaetsunousekaiisan-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. Vehicle positions were seen on 2026-11-14 at 08:00 Japan time (1 vehicle). The centre is the catalogue’s bounding-box centre for the network. | 加越能バス (Kaetsunō World Heritage Bus) |
| **Kamiichi Town Bus** (gtfs-rt-files.buscatch.jp) | Transit layer live vehicles, Toyama Prefecture, Japan | CC0 1.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-kamiichitown-kamiichi-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. Vehicle positions were seen on 2026-11-14 at 08:00 Japan time (1 vehicle). The centre is the catalogue’s bounding-box centre for the network. | 上市町 (Kamiichi Town Bus) |
| **Kurobe City Bus** (gtfs-rt-files.buscatch.jp) | Transit layer live vehicles, Toyama Prefecture, Japan | CC0 1.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-kurobecity-ishida-aimoto-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. The feed answered with a well-formed, empty message at 01:40 and again at 08:00 Japan time on Saturday 2026-11-14, so its positions have not been seen yet. The centre is the catalogue’s bounding-box centre for the network. | 黒部市 (Kurobe City Bus) |
| **Kurobe Shinkansen–Ikuji Bus** (gtfs-rt-files.buscatch.jp) | Transit layer live vehicles, Toyama Prefecture, Japan | CC0 1.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-kurobecity-shinkansenikujisen-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. The feed answered with a well-formed, empty message at 01:40 and again at 08:00 Japan time on Saturday 2026-11-14, so its positions have not been seen yet. The centre is the catalogue’s bounding-box centre for the network. | 黒部市 (Kurobe Shinkansen–Ikuji Bus) |
| **Namerikawa Noru my car** (gtfs-rt-files.buscatch.jp) | Transit layer live vehicles, Toyama Prefecture, Japan | CC0 1.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-namerikawacity-norumycar-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. The feed answered with a well-formed, empty message at 01:40 and again at 08:00 Japan time on Saturday 2026-11-14, so its positions have not been seen yet. The centre is the catalogue’s bounding-box centre for the network. | 滑川市 (Namerikawa Noru my car) |
| **Nanto City Bus** (gtfs-rt-files.buscatch.jp) | Transit layer live vehicles, Toyama Prefecture, Japan | CC0 1.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-nantocity-nanbus-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. Vehicle positions were seen on 2026-11-14 at 08:00 Japan time (2 vehicles). The centre is the catalogue’s bounding-box centre for the network. | 南砺市 (Nanto City Bus) |
| **Nyūzen Noran my car** (gtfs-rt-files.buscatch.jp) | Transit layer live vehicles, Toyama Prefecture, Japan | CC0 1.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-nyuzentown-noranmaicar-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. The feed answered with a well-formed, empty message at 01:40 and again at 08:00 Japan time on Saturday 2026-11-14, so its positions have not been seen yet. The centre is the catalogue’s bounding-box centre for the network. | 入善町 (Nyūzen Noran my car) |
| **Oyabe City Bus** (gtfs-rt-files.buscatch.jp) | Transit layer live vehicles, Toyama Prefecture, Japan | CC0 1.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-oyabecity-oyabecitybus-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. The feed answered with a well-formed, empty message at 01:40 and again at 08:00 Japan time on Saturday 2026-11-14, so its positions have not been seen yet. The centre is the catalogue’s bounding-box centre for the network. | 小矢部市 (Oyabe City Bus) |
| **Takaoka City Bus** (gtfs-rt-files.buscatch.jp) | Transit layer live vehicles, Toyama Prefecture, Japan | CC0 1.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-takaokacity-koueibus-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. The feed answered with a well-formed, empty message at 01:40 and again at 08:00 Japan time on Saturday 2026-11-14, so its positions have not been seen yet. The centre is the catalogue’s bounding-box centre for the network. | 高岡市 (Takaoka City Bus) |
| **Tateyama Town Bus** (gtfs-rt-files.buscatch.jp) | Transit layer live vehicles, Toyama Prefecture, Japan | CC0 1.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-tateyamatown-tateyama-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. The feed answered with a well-formed, empty message at 01:40 and again at 08:00 Japan time on Saturday 2026-11-14, so its positions have not been seen yet. The centre is the catalogue’s bounding-box centre for the network. | 立山町 (Tateyama Town Bus) |
| **Tokoname Gruun** (realtime.gtfs.info) | Transit layer live vehicles, Aichi Prefecture, Japan | CC0 1.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-tokonamecity-Gruun-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. Vehicle positions were seen on 2026-11-14 at 08:00 Japan time (3 vehicles). The centre is the catalogue’s bounding-box centre for the network. | 常滑市 (Tokoname Gruun) |
| **Tonami City Bus** (gtfs-rt-files.buscatch.jp) | Transit layer live vehicles, Toyama Prefecture, Japan | CC0 1.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-tonamicity-tonamishieibasu-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. The feed answered with a well-formed, empty message at 01:40 and again at 08:00 Japan time on Saturday 2026-11-14, so its positions have not been seen yet. The centre is the catalogue’s bounding-box centre for the network. | 砺波市 (Tonami City Bus) |
| **Asahi Asahimachi Bus** (gtfs-rt-files.buscatch.jp) | Transit layer live vehicles, Toyama Prefecture, Japan | CC0 1.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-toyama-asahitown-asahimachibus-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. The feed answered with a well-formed, empty message at 01:40 and again at 08:00 Japan time on Saturday 2026-11-14, so its positions have not been seen yet. The centre is the catalogue’s bounding-box centre for the network. | 富山県朝日町 (Asahi Asahimachi Bus) |
| **Toyama Fuchū Community Bus** (gtfs-rt-files.buscatch.jp) | Transit layer live vehicles, Toyama Prefecture, Japan | CC0 1.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-toyamacity-fuchucommunitybus-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. The feed answered with a well-formed, empty message at 01:40 and again at 08:00 Japan time on Saturday 2026-11-14, so its positions have not been seen yet. The centre is the catalogue’s bounding-box centre for the network. | 富山市 (Toyama Fuchū Community Bus) |
| **Toyama Horikawa-Minami Community Bus** (gtfs-rt-files.buscatch.jp) | Transit layer live vehicles, Toyama Prefecture, Japan | CC0 1.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-toyamacity-horikawaminamicommunitybus-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. The feed answered with a well-formed, empty message at 01:40 and again at 08:00 Japan time on Saturday 2026-11-14, so its positions have not been seen yet. The centre is the catalogue’s bounding-box centre for the network. | 富山市 (Toyama Horikawa-Minami Community Bus) |
| **Toyama Jōjō Community Bus** (gtfs-rt-files.buscatch.jp) | Transit layer live vehicles, Toyama Prefecture, Japan | CC0 1.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-toyamacity-jojocommunitybus-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. The feed answered with a well-formed, empty message at 01:40 and again at 08:00 Japan time on Saturday 2026-11-14, so its positions have not been seen yet. The centre is the catalogue’s bounding-box centre for the network. | 富山市 (Toyama Jōjō Community Bus) |
| **Toyama Kureha Ikiiki Bus** (gtfs-rt-files.buscatch.jp) | Transit layer live vehicles, Toyama Prefecture, Japan | CC0 1.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-toyamacity-kurehaikiikibus-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. The feed answered with a well-formed, empty message at 01:40 and again at 08:00 Japan time on Saturday 2026-11-14, so its positions have not been seen yet. The centre is the catalogue’s bounding-box centre for the network. | 富山市 (Toyama Kureha Ikiiki Bus) |
| **Toyama Maidohaya Bus** (gtfs-rt-files.buscatch.jp) | Transit layer live vehicles, Toyama Prefecture, Japan | CC0 1.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-toyamacity-maidohayabus-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. The feed answered with a well-formed, empty message at 01:40 and again at 08:00 Japan time on Saturday 2026-11-14, so its positions have not been seen yet. The centre is the catalogue’s bounding-box centre for the network. | 富山市 (Toyama Maidohaya Bus) |
| **Toyama Mizuhashi Fureai Community Bus** (gtfs-rt-files.buscatch.jp) | Transit layer live vehicles, Toyama Prefecture, Japan | CC0 1.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-toyamacity-mizuhashifureaicommunitybus-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. The feed answered with a well-formed, empty message at 01:40 and again at 08:00 Japan time on Saturday 2026-11-14, so its positions have not been seen yet. The centre is the catalogue’s bounding-box centre for the network. | 富山市 (Toyama Mizuhashi Fureai Community Bus) |
| **Toyama Ōyama Community Bus** (gtfs-rt-files.buscatch.jp) | Transit layer live vehicles, Toyama Prefecture, Japan | CC0 1.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-toyamacity-oyamacommunitybus-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. Vehicle positions were seen on 2026-11-14 at 08:00 Japan time (1 vehicle). The centre is the catalogue’s bounding-box centre for the network. | 富山市 (Toyama Ōyama Community Bus) |
| **Toyama Yamada Community Bus** (gtfs-rt-files.buscatch.jp) | Transit layer live vehicles, Toyama Prefecture, Japan | CC0 1.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-toyamacity-yamadacommunitybus-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. Vehicle positions were seen on 2026-11-14 at 08:00 Japan time (2 vehicles). The centre is the catalogue’s bounding-box centre for the network. | 富山市 (Toyama Yamada Community Bus) |
| **Toyama Yatsuo Community Bus** (gtfs-rt-files.buscatch.jp) | Transit layer live vehicles, Toyama Prefecture, Japan | CC0 1.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-toyamacity-yatsuocommunitybus-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. Vehicle positions were seen on 2026-11-14 at 08:00 Japan time (1 vehicle). The centre is the catalogue’s bounding-box centre for the network. | 富山市 (Toyama Yatsuo Community Bus) |
| **Uozu Citizens’ Bus** (gtfs-rt-files.buscatch.jp) | Transit layer live vehicles, Toyama Prefecture, Japan | CC0 1.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-uozucity-junkai-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. Vehicle positions were seen on 2026-11-14 at 08:00 Japan time (4 vehicles). The centre is the catalogue’s bounding-box centre for the network. | 魚津市 (Uozu Citizens’ Bus) |
| **Uozu Omotenashi direct bus** (gtfs-rt-files.buscatch.jp) | Transit layer live vehicles, Toyama Prefecture, Japan | CC0 1.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-uozucity-omotenashi-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. The feed answered with a well-formed, empty message at 01:40 and again at 08:00 Japan time on Saturday 2026-11-14, so its positions have not been seen yet. The centre is the catalogue’s bounding-box centre for the network. | 魚津市 (Uozu Omotenashi direct bus) |
| **Chita Aiai Bus** (realtime.gtfs.info) | Transit layer live vehicles, Aichi Prefecture, Japan | CC BY 4.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-chitacity-chita-aiaibus-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. Vehicle positions were seen on 2026-11-14 at 08:00 Japan time (1 vehicle). The centre is the catalogue’s bounding-box centre for the network. | 知多市 (Chita Aiai Bus) |
| **Ise Okage Bus** (bus-vision.jp) | Transit layer live vehicles, Mie Prefecture, Japan | CC BY 4.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-isecity-communitybus-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. Vehicle positions were seen on 2026-11-14 at 08:00 Japan time (5 vehicles). The centre is the middle of the vehicles seen then. | 伊勢市 (Ise Okage Bus) |
| **Keisei Bus Chiba West (Shiohama)** (s3-ajt-mobusta-gtfs.s3.ap-northeast-1.amazonaws.com) | Transit layer live vehicles, Chiba Prefecture, Japan | CC BY 4.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-keisei-transitbus-keiseitransitbus-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. Vehicle positions were seen on 2026-11-14 at 08:00 Japan time (17 vehicles). The centre is the middle of the vehicles seen then. | 京成バス千葉ウエスト株式会社 (Keisei Bus Chiba West (Shiohama)) |
| **Komono Kamoshika-gō** (bus-vision.jp) | Transit layer live vehicles, Mie Prefecture, Japan | CC BY 4.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-komonotown-communitybus-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. The feed answered with a well-formed, empty message at 01:40 and again at 08:00 Japan time on Saturday 2026-11-14, so its positions have not been seen yet. The centre is the catalogue’s bounding-box centre for the network. | 菰野町 (Komono Kamoshika-gō) |
| **Kumamoto Bus** (km.bus-vision.jp) | Transit layer live vehicles, Kumamoto Prefecture, Japan | CC BY 4.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-kuma-bus-kuma-bus-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. Vehicle positions were seen on 2026-11-13 around midnight and again on 2026-11-14 at 08:00 Japan time (15 vehicles). The centre is the middle of the vehicles seen then. | 熊本バス (Kumamoto Bus) |
| **Kumamoto Toshi Bus** (km.bus-vision.jp) | Transit layer live vehicles, Kumamoto Prefecture, Japan | CC BY 4.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-kumamoto-toshibus-kumamoto-toshibus-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. Vehicle positions were seen on 2026-11-13 around midnight and again on 2026-11-14 at 08:00 Japan time (31 vehicles). The centre is the middle of the vehicles seen then. | 熊本都市バス (Kumamoto Toshi Bus) |
| **Kumamoto Dentetsu Bus** (km.bus-vision.jp) | Transit layer live vehicles, Kumamoto Prefecture, Japan | CC BY 4.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-kumamotodentetsu-kumamotodentetsu-bus-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. Vehicle positions were seen on 2026-11-13 around midnight and again on 2026-11-14 at 08:00 Japan time (22 vehicles). The centre is the middle of the vehicles seen then. | 熊本電鉄 (Kumamoto Dentetsu Bus) |
| **Mie Kōtsū Chūsei office** (bus-vision.jp) | Transit layer live vehicles, Mie Prefecture, Japan | CC BY 4.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-mie-kotsu-sancochusei-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. Vehicle positions were seen on 2026-11-14 at 08:00 Japan time (31 vehicles). The centre is the middle of the vehicles seen then. | 三重交通 (Mie Kōtsū Chūsei office) |
| **Mie Kōtsū Iga office** (bus-vision.jp) | Transit layer live vehicles, Mie Prefecture, Japan | CC BY 4.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-mie-kotsu-sancoiga-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. Vehicle positions were seen on 2026-11-14 at 08:00 Japan time (11 vehicles). The centre is the middle of the vehicles seen then. | 三重交通 (Mie Kōtsū Iga office) |
| **Mie Kōtsū Nanki office** (bus-vision.jp) | Transit layer live vehicles, Mie Prefecture, Japan | CC BY 4.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-mie-kotsu-sancoinanki-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. Vehicle positions were seen on 2026-11-14 at 08:00 Japan time (6 vehicles). The centre is the middle of the vehicles seen then. | 三重交通 (Mie Kōtsū Nanki office) |
| **Mie Kōtsū Ise office** (bus-vision.jp) | Transit layer live vehicles, Mie Prefecture, Japan | CC BY 4.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-mie-kotsu-sancoise-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. Vehicle positions were seen on 2026-11-14 at 08:00 Japan time (13 vehicles). The centre is the middle of the vehicles seen then. | 三重交通 (Mie Kōtsū Ise office) |
| **Mie Kōtsū Kuwana office** (bus-vision.jp) | Transit layer live vehicles, Mie Prefecture, Japan | CC BY 4.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-mie-kotsu-sancokuwana-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. Vehicle positions were seen on 2026-11-14 at 08:00 Japan time (22 vehicles). The centre is the middle of the vehicles seen then. | 三重交通 (Mie Kōtsū Kuwana office) |
| **Mie Kōtsū Matsusaka office** (bus-vision.jp) | Transit layer live vehicles, Mie Prefecture, Japan | CC BY 4.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-mie-kotsu-sancomatsusaka-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. Vehicle positions were seen on 2026-11-14 at 08:00 Japan time (9 vehicles). The centre is the middle of the vehicles seen then. | 三重交通 (Mie Kōtsū Matsusaka office) |
| **Mie Kōtsū Shima office** (bus-vision.jp) | Transit layer live vehicles, Mie Prefecture, Japan | CC BY 4.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-mie-kotsu-sancoshima-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. Vehicle positions were seen on 2026-11-14 at 08:00 Japan time (8 vehicles). The centre is the middle of the vehicles seen then. | 三重交通 (Mie Kōtsū Shima office) |
| **Mie Kōtsū Yokkaichi office** (bus-vision.jp) | Transit layer live vehicles, Mie Prefecture, Japan | CC BY 4.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-mie-kotsu-sancoyokkaichi-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. Vehicle positions were seen on 2026-11-14 at 08:00 Japan time (24 vehicles). The centre is the middle of the vehicles seen then. | 三重交通 (Mie Kōtsū Yokkaichi office) |
| **Nagai Bus** (nagai.nolbe.net) | Transit layer live vehicles, Gunma Prefecture, Japan | CC BY 4.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-nagai-unyu-Nagaibus-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. Vehicle positions were seen on 2026-11-14 at 08:00 Japan time (7 vehicles). The centre is the middle of the vehicles seen then. | 永井運輸株式会社 (Nagai Bus) |
| **Nagano City Bus** (realtime.gtfs.info) | Transit layer live vehicles, Nagano Prefecture, Japan | CC BY 4.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-naganocity-shiei_noriaibus-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. The feed answered with a well-formed, empty message at 01:40 and again at 08:00 Japan time on Saturday 2026-11-14, so its positions have not been seen yet. The centre is the catalogue’s bounding-box centre for the network. | 長野市 (Nagano City Bus) |
| **Owariasahi Asapī-gō** (gtfs-rt-files.buscatch.jp) | Transit layer live vehicles, Aichi Prefecture, Japan | CC BY 4.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-owariasahicity-communitybus-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. The feed answered with a well-formed, empty message at 01:40 and again at 08:00 Japan time on Saturday 2026-11-14, so its positions have not been seen yet. The centre is the catalogue’s bounding-box centre for the network. | 尾張旭市 (Owariasahi Asapī-gō) |
| **Sankō Bus** (km.bus-vision.jp) | Transit layer live vehicles, Kumamoto Prefecture, Japan | CC BY 4.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-sankobus-sankobus-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. Vehicle positions were seen on 2026-11-13 around midnight and again on 2026-11-14 at 08:00 Japan time (132 vehicles). The centre is the middle of the vehicles seen then. | 産交バス (Sankō Bus) |
| **Takeya Kōtsū** (realtime.gtfs.info) | Transit layer live vehicles, Miyagi Prefecture, Japan | CC BY 4.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-takeyakoutu-takeyakotsu-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. The feed answered with a well-formed, empty message at 01:40 and again at 08:00 Japan time on Saturday 2026-11-14, so its positions have not been seen yet. The centre is the catalogue’s bounding-box centre for the network. | 株式会社タケヤ交通 (Takeya Kōtsū) |
| **Tsuchiura Tsuchimaru Bus** (realtime.gtfs.info) | Transit layer live vehicles, Ibaraki Prefecture, Japan | CC BY 4.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-tsuchiuracity-tsuchimarubus-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. Vehicle positions were seen on 2026-11-14 at 08:00 Japan time (3 vehicles). The centre is the catalogue’s bounding-box centre for the network. | 土浦市 (Tsuchiura Tsuchimaru Bus) |
| **Yanbaru Express Bus** (gtfs.yanbaru-bus-navi.com) | Transit layer live vehicles, Okinawa Prefecture, Japan | CC BY 4.0 (https://mobilitydatabase.org/feeds/gtfs_rt/jbda-yanbaru-expressbus-yanbaru-express-bus-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. The feed answered with a well-formed, empty message at 01:40 and again at 08:00 Japan time on Saturday 2026-11-14, so its positions have not been seen yet. The centre is the catalogue’s bounding-box centre for the network. | 合同会社やんばる急行バス (Yanbaru Express Bus) |
| **Kenkō Hokubu Kōtsū** (api-public.odpt.org) | Transit layer live vehicles, Kōchi Prefecture, Japan | CC BY 4.0 (https://mobilitydatabase.org/feeds/gtfs_rt/odpt-KenkoHokubuKotsu-Localbus-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. Vehicle positions were seen on 2026-11-14 at 08:00 Japan time (6 vehicles). The centre is the middle of the vehicles seen then. | 株式会社県交北部交通 (Kenkō Hokubu Kōtsū) |
| **Kōchi Kōryō Kōtsū** (api-public.odpt.org) | Transit layer live vehicles, Kōchi Prefecture, Japan | CC BY 4.0 (https://mobilitydatabase.org/feeds/gtfs_rt/odpt-KochiKoryoKotsu-Localbus-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. Vehicle positions were seen on 2026-11-14 at 08:00 Japan time (3 vehicles). The centre is the catalogue’s bounding-box centre for the network. | 高知高陵交通株式会社 (Kōchi Kōryō Kōtsū) |
| **Kōchi Seinan Kōtsū** (api-public.odpt.org) | Transit layer live vehicles, Kōchi Prefecture, Japan | CC BY 4.0 (https://mobilitydatabase.org/feeds/gtfs_rt/odpt-KochiSeinanTraffic-Localbus-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. Vehicle positions were seen on 2026-11-14 at 08:00 Japan time (11 vehicles). The centre is the middle of the vehicles seen then. | 高知西南交通株式会社 (Kōchi Seinan Kōtsū) |
| **Susaki City Bus** (api-public.odpt.org) | Transit layer live vehicles, Kōchi Prefecture, Japan | CC BY 4.0 (https://mobilitydatabase.org/feeds/gtfs_rt/odpt-SusakiCity-Citybus-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. Vehicle positions were seen on 2026-11-14 at 08:00 Japan time (2 vehicles). The centre is the catalogue’s bounding-box centre for the network. | 須崎市 (Susaki City Bus) |
| **Aomori City community bus** (toshisei.aomoricitybus.com) | Transit layer live vehicles, Aomori Prefecture, Japan | CC BY 4.0 (https://mobilitydatabase.org/feeds/gtfs_rt/odpt-UrbanDevelopment_AomoriCity-AllLines-vp). The Mobility Database record gives this licence for the feed; the quote is the licence it links. Vehicle positions were seen on 2026-11-13 around midnight Japan time. The centre is the catalogue’s bounding-box centre for the network. The catalogue’s ODPT address redirects to this host, so the feed is registered at its own address. | 青森市 (Aomori City community bus) |
| **Radio Browser** | Geolocated internet-radio station directory and station-level tags | Public-domain directory data under PDDL 1.0; individual broadcaster stream terms apply | "Radio Browser" plus a link to the selected broadcaster |
| **Re:Earth Terrain** (Mapterhorn) | Terrain (keyless globe stacks — OSM etc. — + `/api/terrain/heights` ellipsoidal-height lookups) | Terrain mesh: CC BY 4.0; geoid: EGM2008 (NGA, public domain) | "Terrain (keyless globe stacks): Re:Earth Terrain / Mapterhorn (CC BY 4.0) / EGM2008 (NGA)" |
| **OpenSeaMap** (`tiles.openseamap.org`) | Sea Marks layer: raster overlay of buoys, lighthouses and ports (#10) | Chart tiles CC BY-SA 2.0; data ODbL 1.0 via OpenStreetMap | "Sea marks © OpenSeaMap contributors (CC BY-SA 2.0) · Data © OpenStreetMap contributors (ODbL)" |
@@ -268,7 +574,7 @@ The optional Local ADS-B layer and the broadcast-FM receiver use radio you recei
- **Houston TranStar cameras.** Keyless. The camera list is the public `traffic.houstontranstar.org/data/layers/cctvSnapshots_json.js` catalog (~1,000 cameras across Greater Houston); frames are stills at `www.houstontranstar.org/snapshots/cctv/<id>.jpg`, synthesized from a validated numeric id rather than taken from the payload, and only that host is registered. Cameras whose catalog id is `0` (a different, non-snapshot class) and cameras outside Greater Houston are dropped. TranStar's `dir` field is the side of the freeway the camera sits on, not the way it faces: TranStar's own map shows it as "Traffic closest to the camera is traveling …" (South → eastbound, North → westbound, West → southbound, East → northbound). That travel direction (90°, 270°, 180°, 0°) seeds the heading as a low-confidence prior with the low-confidence pose; `None` or an unknown value uses the shared id-hash fallback at low confidence. Headings are corrected with the in-app calibration gizmo. Off by default. TranStar's [Content Usage terms](https://traffic.houstontranstar.org/disclaimer.aspx) prohibit copying or distributing the site's information, and external framing or linking to specific images, without TxDOT's prior written permission; its FAQ grants permission-free use only for the RSS feeds. This project does not hold that permission for downstream installations, so the pack loads only when an operator who holds TxDOT's written permission sets `CCTV_HOUSTON_ENABLED=1`; with the flag unset, empty or any other value, the server makes no request to TranStar. Once enabled, it loads the 250 cameras nearest downtown, Uptown, the Medical Center, IAH and Galveston; `CCTV_HOUSTON_MAX_SOURCES` (8–400) changes the cap. Snapshots update about every 3 minutes, which is also the ambient still cadence. Frames are fetched from TranStar and relayed to the browser on demand, buffered only transiently per request, sent with `Cache-Control: no-store`, and not archived.
- **Autostrada del Brennero (A22) webcams.** Keyless. The camera list is one request to the Open Data Hub tourism API (`tourism.api.opendatahub.com/v1/WebcamInfo?source=a22`), run by NOI Techpark in South Tyrol, which republishes Autobrennero's own list of 13 motorway webcams with coordinates and kilometre markers. Frames are the operator's stills on `www.autobrennero.it/WebCamImg/km<N>.jpg`, refreshed about once a minute, and only the exact image for each camera's kilometre is registered. The feed names no bearing, so headings use the id-hash fallback at low confidence. The road climbs from about 20 m in the Po valley to about 1,370 m at the Brenner Pass, so each camera's ground elevation comes from a per-kilometre table sampled from the Copernicus GLO-90 DEM (via Open-Meteo's elevation API); a camera not in the table uses a 200 m prior. The Open Data Hub tags every record CC0 (`ClosedData: false`, Autobrennero as licence holder), but that tag is the aggregator's metadata and Autobrennero publishes no terms of its own for the images, so they are credited to the operator as a courtesy and are not redistributed. Frames are fetched at request time and never stored. Disable with `CCTV_A22_ENABLED=0`.
- **Camera frame content.** Public camera frames can contain people, vehicles and license plates, and the camera layer does nothing with them beyond putting them on the map. A successful upstream response is relayed as the provider served it: nothing in the camera pipeline blurs, redacts, enhances or restores it, and nothing there runs face, plate or object detection or otherwise recognises or classifies what is in the picture. (The ALPR layer described below maps where plate-reader cameras are, from locations contributors tagged in OpenStreetMap; it reads nothing from any camera frame.) When an upstream has no frame for a camera, what you see instead is a Google Street View still or the app's own placeholder card; the panel's source badge names which of them you are looking at, and a refresh that fails after a frame has arrived leaves the last good picture on screen rather than replacing it. The browser resamples each frame for display: onto a fixed 1920x1080 surface for the camera's projection plane in the scene, and onto a 192x108 canvas for the small ambient card. That scaling is the only change made to the picture, and the only pixels the camera layer reads back are a 64x36 downscale hashed to tell whether the picture has changed. Live streams are piped through; the still path reads the image into memory to pass it on — TxDOT wraps its JPEG in a JSON envelope, which is decoded there — and no frame is written to disk (the disk cache, `.gev-cache/`, holds feed JSON for other layers and never camera imagery). Outside that pipeline, the voice assistant is the one feature that sends imagery anywhere: when it answers a question about what is in view it may attach a downscaled screenshot of the rendered scene — including any camera plane on screen — to the request it sends to the voice model. Frames are fetched only from server-registered camera URLs — a client cannot hand the proxy a URL (see [SECURITY.md](SECURITY.md)). What the app does stays inside the line README draws: no named-person search, no face recognition, no tracking individuals.
- **Transit (GTFS-Realtime).** The proxy requests only registered operator feeds, validates redirects, bounds responses, and uses conditional requests, short snapshot caching and failure backoff. All fifty-two registered feeds, covering forty-nine regions, are live-enabled; each can be disabled independently. Vehicles use delayed playback between reports, with report age and waiting states shown separately. Session-local selected trails are available for every feed. MBTA additionally retains up to 15 minutes of recently observed positions in the running proxy, so available history can survive a browser reload; server restart clears it. History reads never fetch upstream, and other feeds have no proxy retention. Nothing is archived to disk or collected in the background. Operator text credits are included as a courtesy and do not imply endorsement. Heights are aligned to work with Google 3D tiles; subway markers are shown at street level because these feeds do not supply depth. The TTC feed is BusTime, the surface system: it carries buses and streetcars and no subway at all. About four in ten of its vehicles report no route at all (unassigned or deadheading), and those are shown with the feed default rather than a route-established mode. It sends no ETag or Last-Modified, so its conditional requests fall through to the ordinary snapshot cache. Three Golden Horseshoe neighbours run alongside it — MiWay, Hamilton HSR and Durham Region Transit — each bus-only and each polled only near its own region. Durham Region Transit publishes no bearing on any vehicle, so those sprites take their heading from observed movement like any other feed that omits it. Guelph, Kingston and Barrie extend the same pattern eastward and north. Hamilton, Guelph, Burlington, YRT and Rio’s SMTR publish route ids that are not the number on the vehicle, so those entries carry a route-name table taken from each operator’s own published GTFS; any id missing from a table renders unchanged rather than blank. A label is never invented: YRT runs a route `9101` that appears nowhere in its published routes, so it stays as the feed sends it. Burlington’s is the one that cannot be shortcut: `351` is route 1 while `3510` is route 10, so the table is a real join rather than a trimmed prefix. GO Transit / Metrolinx is deliberately absent: its REALTIME feed requires an API key issued by manual review, which the keyless admission rule excludes (its static schedule download is keyless, but carries no vehicle positions). Barrie and YRT/Viva each invite acceptance of their licence through a form, and each licence also states that using the data is itself acceptance; this deployment relies on that clause, which is recorded in both entries. Grand River Transit in Waterloo is absent for a different reason: it answers, but its feed header was months stale and it publishes no per-vehicle timestamps, so it would render vehicles that look live and are not. Ottawa’s OC Transpo falls to the same keyless admission rule as GO Transit — its realtime feed requires an API key. London Transit and Thunder Bay Transit publish vehicle positions over plain HTTP with no HTTPS endpoint available. Every other Ontario system — Brampton, Oakville, Niagara, Milton, Windsor, Greater Sudbury, UP Express and a dozen smaller operators — publishes static GTFS schedules only, with no realtime vehicle positions to register. Between the nine included and these exclusions, every Ontario realtime vehicle-position feed catalogued in the Mobility Database is accounted for.
- **Transit (GTFS-Realtime).** The proxy requests only registered operator feeds, validates redirects, bounds responses, and uses conditional requests, short snapshot caching and failure backoff. All 358 registered feeds are live-enabled; each can be disabled independently. Of those, 112 are French networks taken from the national access point, transport.data.gouv.fr: each is the GTFS-RT vehicle feed of a dataset record whose licence field is Licence Ouverte 2.0 or ODbL, and each returned live vehicle positions on 2026-11-13. Their rows live in `src/data/transitFeedsFrance.js`, with line names for the feeds that publish internal route keys in `src/data/transitRouteNamesFrance.js`, copied from each record’s own GTFS `routes.txt`. A network that was already here through its operator’s own endpoint (Bordeaux, Montpellier, Rouen, Toulon, Le Havre, Tours) was not added a second time, and neither was the Atoumod aggregate, which repeats Normandy networks listed one by one. Feeds republished by bus-tracker.fr, feeds served over plain HTTP, and the three Fluo Grand Est feeds, whose positions ran seven to fifteen minutes old, are left out. A further 139 feeds come from the open GTFS-Realtime catalogues (Mobility Database, Transitland Atlas), most of them in the United States; their rows are in `src/data/transitFeedsCatalogue.js`. Ten are operators whose published terms were read on 2026-11-13 and permit display (Metro Bilbao, Metro St. Louis, Madison, MVgo, Valley Regional Transit, Greater Portland Metro, Greater Cleveland RTA, Fairfax Connector, Zagreb ZET, and Bustang under RTD’s agreement); each row quotes the grant. The other 129 are keyless endpoints the catalogue lists as the operator’s own, usually on the operator’s tracking vendor (Avail, Passio, Connexionz, TransLoc); each links its catalogue record, is credited as a courtesy, and ships on the same basis as Metro Transit and OVapi. Seven catalogue feeds answer keyless but are excluded because their terms do not allow this use: MTA New York City Bus (the terms require an API key and forbid serving data straight from MTA servers), Detroit DDOT (use only with the city’s permission), Everett Transit (registration required), Duluth Transit (display of arrival information needs written consent), Greater Dayton RTA (an unpublished developer agreement governs), CTtransit and Pittsburgh Regional Transit (their licences cover static GTFS only). Eight more are held until their terms can be read, because the page was unreachable or empty: Sofia, Lviv, Saint-Avold, Des Moines DART, Springfield SMTD, Knoxville KAT, Pioneer Valley PVTA and Lafayette CityBus. The BusOne proxy feeds for Italian and Austrian operators are a third party’s republication and are left out, as are five more data.gov.my feeds that would share the API’s four requests a minute with the two already here. Fifty-five Japanese bus networks, most of them in Toyama, Mie, Kumamoto and Kōchi prefectures, are in `src/data/transitFeedsJapan.js`; the Mobility Database records each under CC0 1.0 or CC BY 4.0. Vehicle positions have been seen for 34 of them (33 on 2026-11-14 at 08:00 Japan time, a Saturday, and Aomori the night before); the other 21, mostly municipal community buses, answered with an empty message then and overnight, and stay out of the coverage heat-map until their positions are seen. Each row says which case it is. Vehicles use delayed playback between reports, with report age and waiting states shown separately. Session-local selected trails are available for every feed. MBTA additionally retains up to 15 minutes of recently observed positions in the running proxy, so available history can survive a browser reload; server restart clears it. History reads never fetch upstream, and other feeds have no proxy retention. Nothing is archived to disk or collected in the background. Operator text credits are included as a courtesy and do not imply endorsement. Heights are aligned to work with Google 3D tiles; subway markers are shown at street level because these feeds do not supply depth. The TTC feed is BusTime, the surface system: it carries buses and streetcars and no subway at all. About four in ten of its vehicles report no route at all (unassigned or deadheading), and those are shown with the feed default rather than a route-established mode. It sends no ETag or Last-Modified, so its conditional requests fall through to the ordinary snapshot cache. Three Golden Horseshoe neighbours run alongside it — MiWay, Hamilton HSR and Durham Region Transit — each bus-only and each polled only near its own region. Durham Region Transit publishes no bearing on any vehicle, so those sprites take their heading from observed movement like any other feed that omits it. Guelph, Kingston and Barrie extend the same pattern eastward and north. Hamilton, Guelph, Burlington, YRT and Rio’s SMTR publish route ids that are not the number on the vehicle, so those entries carry a route-name table Line truncated
- **Rail (GTFS-Realtime trains).** Each feed in `src/data/railFeeds.js` records its licence, its credit and the passage of its terms the decision rests on, and a feed is switched on only when those terms were read and cover this use, or, for those that publish no licence at all, on the basis its entry records. Such a basis is never a licence, and the credit does not present it as one: its label says there is no licence ("No licence published", "No licence stated") or names the publication the use rests on. Five enabled feeds publish no licence for their train positions. MARC is used on what its publication says (open publication with a no-endorsement disclaimer), and METRO light rail on the same basis as the Transit layer's Metro Transit feed. Tri-Rail and Charlotte's LYNX are used without a published licence by project owner decision of 2026-11-10. The fifth is Irish Rail, whose train positions publish no licence while its NTA timetable is CC BY 4.0. The registry lists 30 feeds, all switched on, and every one is keyless: its realtime feed and its static timetable are published for anyone to fetch, so no feed needs a key, an account or a registration, and the server holds no rail credential. No rail request carries a credential of the deployer's; one feed's published URL includes a fixed public value its publisher prints for everyone (Bordeaux's `apiKey`). `/api/rail/feeds` lists the offered feeds, `/api/rail/trains/<feedId>` returns one feed's train snapshot, `/api/rail/updates/<feedId>` its trip updates, and `/api/rail/paths/<feedId>` and `/api/rail/schedule/<feedId>` its path and schedule packs, when built. The proxy requests only registered feeds and reuses the Transit proxy's request policy (a short snapshot cache with single-flight refresh, serve-stale, admission limits, the failure cooldown ladder, redirects followed hop by hop only on the feed's own https origin, and an 8 MiB body cap unless a feed sets its own, at most 64 MiB). Many operators publish trains in the same feed as their buses, so each feed has a classifier: the proxy keeps only vehicles it recognises as trains, tags each with a category (`transit`, `local`, `regional`, `national` or `international`) and a mode (`rail`, `metro` or `tram`), and drops everything else server-side, counted in the snapshot as `dropped`; the browser never receives a bus. Every train shown is live, where its operator last reported it: 29 feeds publish live GPS positions (SJ Nord's through SIRI VM), and Irish Rail reports the station or timing point a train last passed. No train is placed or moved from a timetable; a feed whose live positions fail shows as unavailable, and its trains age out as any quiet train does. 22 feeds register trip updates, polled while one of their trains is selected and that feed's schedule pack is loaded. 28 feeds work out of the box. Packs are an opt-in extra for live trains: nothing is downloaded when the app starts, and `node scripts/build-rail-paths.mjs --feed <id>` (repeatable) or `--all` downloads a feed's static GTFS (29 of the 30 have one) and writes a path pack (the operator's track shapes) and a schedule pack (the stop times for a window of days) to `.cache/rail-paths/` (or to `RAIL_PATHS_DIR` when set, the directory the server then serves). With them, a live train is drawn on its operator's route line and its card names its stops, its next stop and, from the trip updates, their delays. Renfe long and medium distance and KTMB, whose vehicles name no route, are classified from their pack's routes, so `/api/rail/feeds` lists them only once that pack is built. Lines are the operator's own shapes as published: nothing is routed or redrawn from other map data, and no line is drawn where an operator publishes no shape. **Share-alike sources bind the deployer.** A pack built from a ShareAlike or ODbL source is a derived database of it, so a deployer who serves it publicly makes it subject to the same licence and must offer it under that licence with the attribution kept. That covers the Montpellier packs (ODbL). For the ODbL datasets of France's national access point, its special conditions also require that "Les bases de données ainsi repartagées doivent être publiées sur le Point d'accès national transport.data.gouv.fr, dans le format d'origine" ([Licence ODbL](https://doc.transport.data.gouv.fr/le-point-d-acces-national/cadre-juridique/conditions-dutilisation-des-donnees/licence-odbl), read 2026-11-10): a deployer who serves the Montpellier packs publicly takes on republishing that derived data there, as GTFS. The build downloads each static GTFS itself, over https and with no credential. A feed's `staticRouteTypes` lists the route types it keeps when its classifier accepts every route of a mode-specific feed. A frequency-based trip becomes one run per departure on its template's stops and run times. Packs are build output, not part of the repository, and cover a fixed window of days, so they are rebuilt before it ends, anLine truncated
- **Radio country coverage (optional).** Set `RADIO_PRIORITY_COUNTRIES=IN,PL` in the local `.env` and restart to include stations beyond the global click charts. The operator may choose up to eight unique ISO alpha-2 country codes; no key is needed. Each country adds one bounded query (at most 200 rows) and reserves up to 40 unique, usable stations inside the existing 750-station catalog. Country seeds precede specialist-tag seeds and global popularity fill; unused slots return to the shared pool. This is a coverage preference, not an exhaustive national directory or a guarantee of stations in every city. Countries with no eligible HTTPS MP3/AAC geolocated stations remain empty. An unset list preserves global selection. Country requests share the directory cache and three-worker pool; failed country queries are reported in coverage without blocking a healthy global refresh. Failed/degraded refreshes back off for one minute, with at most three mirrors per query.
-7
View File
@@ -1,7 +0,0 @@
- Give counts real plural forms in every language: the wildlife count, the
Data Library list, the News time window, the GhostMaps event age and the
bridge radar range now read "1 Tag" and "7 Tage", «0,75 МОР. МИЛИ» and
«12 МОР. МИЛЬ». Street level words "the view centre" in each language's
grammar, and Latest, FOCUS, CONFIRMED and the course readout each have
their own translation where one word served two places (German, @gekh,
#1700).
@@ -0,0 +1,26 @@
- Add 112 French networks to the Transit layer, from Nice, Dijon, Angers,
Brest, Le Mans, Metz, Amiens, Avignon and Valenciennes to small-town
networks, the liO, Aléop and Rémi regional coaches, Réunion, Martinique and
French Guiana. Each is the keyless vehicle feed of a transport.data.gouv.fr
record under Licence Ouverte 2.0 or ODbL, recorded in the registry and
DATA_SOURCES.md. Trams and boats take their own mode, feeds that publish
km/h (Dijon, Le Mans, Bourg-en-Bresse, Blois, Montluçon) are converted to
m/s, and internal route keys read as the line on the vehicle. Networks
already in the layer are not added a second time (#1716).
- Add 139 more keyless feeds to the Transit layer from the open GTFS-Realtime
catalogues, most of them United States agencies (Sacramento, Spokane,
Cleveland, St. Louis, Madison, Louisville, Fresno, Broward County and many
smaller systems), plus Zagreb, Bilbao's metro, Chișinău, Parma and a few
Québec networks. Operators whose terms were read are credited as those
terms ask, and every feed is recorded in DATA_SOURCES.md. Feeds whose
terms need a key, registration or permission (New York City buses,
Detroit, Pittsburgh and others) are left out (#1716).
- Add 55 Japanese bus networks to the Transit layer, the first in Toyama,
Mie, Kumamoto, Kōchi, Aichi, Okinawa and Aomori prefectures, each recorded
under CC0 1.0 or CC BY 4.0 with the operator credited in Japanese (#1716).
- Show where Transit has coverage. From orbit each feed is a soft green
spot, hotter where networks cluster; at continental and regional zoom the
spots become patches the size of each network's service area, drawn under
the vehicles; close in they are off. Drawn from the feed registry, so no
feed is polled for it, and only feeds whose live positions have been seen
are shown (#1716).
+1 -2
View File
@@ -87,8 +87,7 @@ menu.onChoose = (code) => switchLocale(code); // switched in place and stored (i
- **Pass literals.** `t('Close')`, not `t(label)` (unless `label` holds a `msg()` value) and never a template literal with `${…}`.
- **Use placeholders, not concatenation.** `t('Flying to {place}…', { place })`, not `t('Flying to') + ' ' + place`. Word order differs between languages.
- **A placeholder takes a name, not a phrase.** When code has no name to pass and would fall back to a phrase ("the view centre", "this spot"), give that case a message of its own: `t('{source} at the view centre', { source })`. Other languages put a phrase in a different case after a preposition, which a name in its nominative form cannot follow.
- **Use `tn()` for counts**, not `count === 1 ? … : …`. Russian has three forms. That includes a number the English writes with a symbol or abbreviation, so both English forms read the same (`tn(hours, 'Last {hours} h', 'Last {hours} h', { hours })`): other languages inflect the words around it («Última 1 h», «Últimas 24 h»). Fractions have a form of their own too (ru «0,75 МОР. МИЛИ»).
- **Use `tn()` for counts**, not `count === 1 ? … : …`. Russian has three forms.
- **Translate the label, not the value.** Layer ids, enums, share-link parameters, API fields, voice tool schemas and feed data (callsigns, vessel and place names) stay as they are; translate only the text shown for them.
- **No `t()` at module top level.** Keep the English in `msg()` and call `t()` when rendering.
- **Numbers and dates** go through `formatNumber`, `formatDate`, `formatRelativeTime` and `formatUtcDayMonth` from `src/i18n/index.js`, which follow the active language.
+1 -1
View File
@@ -8,7 +8,7 @@ Catalog: `src/i18n/locales/ru.json`. General rules: [TRANSLATORS.md](../TRANSLAT
- Sentence case, not Title Case: "Live Flights" → «Рейсы в реальном времени».
- Quotes inside Russian text are «ёлочки». Write ё where it belongs: её, ещё, всё.
- In short labels, a standard abbreviation with a period beats a wrapped line: НЕОПРЕД., СЛЕД.
- Units: км, м, км/ч, м/с, уз (knots), фт (feet), ч, мин, с; in UPPERCASE text КМ, М, КМ/С, УЗ, ФТ. MW is МВт in any case. `°` and `%` stay. Nautical miles on the bridge radar are «мор. миля», a noun that follows the count: «3 МОР. МИЛИ», «12 МОР. МИЛЬ», «0,75 МОР. МИЛИ».
- Units: км, м, км/ч, м/с, уз (knots), фт (feet), ч, мин, с; in UPPERCASE text КМ, М, КМ/С, УЗ, ФТ. MW is МВт in any case. `°` and `%` stay.
## Plurals
+1 -1
View File
@@ -12,7 +12,7 @@ Translation source: meirm (#312).
- The apostrophe is always ʼ (U+02BC): обʼєкт, звʼязок, памʼять. Not ' or ’.
- Quotes inside Ukrainian text are «ялинки»; a button or layer name inside a sentence goes in them: Увімкніть «Вуличні знімки».
- In short labels, a standard abbreviation with a period beats a wrapped line: ПОПЕР., ДАЛЬН., КАЛІБР.
- Units: км, м, км/год, м/с, вуз (knots), фт (feet), год, хв, с, МГц, дБ, гПа; in UPPERCASE text КМ, М, КМ/С, ВУЗ, ФТ. Nautical miles on the bridge radar are «мор. миля», a noun that follows the count: «3 МОР. МИЛІ», «12 МОР. МИЛЬ», «0,75 МОР. МИЛІ». MW is МВт in any case. `°` and `%` stay. Decimal comma in coordinates written as text: 28,2710° пн. ш.
- Units: км, м, км/год, м/с, вуз (knots), фт (feet), год, хв, с, МГц, дБ, гПа; in UPPERCASE text КМ, М, КМ/С, ВУЗ, ФТ. MW is МВт in any case. `°` and `%` stay. Decimal comma in coordinates written as text: 28,2710° пн. ш.
- Coordinates: пн. ш. / пд. ш. / сх. д. / зх. д.; the HUD hemisphere letters are Пн, Пд, Сх, Зх.
## Plurals
+10
View File
@@ -801,6 +801,16 @@
"server/providers/transitHistory.js",
"server/providers/transitHistory.test.mjs",
"src/data/rioRouteNames.js",
"src/data/transitFeedsJapan.js",
"src/data/transitFeedsJapan.test.mjs",
"src/data/transitCoverage.js",
"src/data/transitCoverage.test.mjs",
"src/layers/transit/coverage.js",
"src/data/transitFeedsCatalogue.js",
"src/data/transitFeedsCatalogue.test.mjs",
"src/data/transitFeedsFrance.js",
"src/data/transitFeedsFrance.test.mjs",
"src/data/transitRouteNamesFrance.js",
"src/data/transitFeeds.js",
"src/data/transitFeeds.test.mjs",
"src/data/transitProxy.js",
+48
View File
@@ -3304,6 +3304,10 @@
"src/data/transit.js",
"src/data/transitFeeds.js",
"src/data/rioRouteNames.js",
"src/data/transitFeedsFrance.js",
"src/data/transitFeedsJapan.js",
"src/data/transitFeedsCatalogue.js",
"src/data/transitRouteNamesFrance.js",
"src/data/transitIcons.js",
"src/data/transitPresetStyle.js",
"src/layers/transit/controls.js",
@@ -3318,6 +3322,8 @@
"src/layers/transit/state.js",
"src/layers/transit/testing.js",
"src/layers/transit/viewport.js",
"src/layers/transit/coverage.js",
"src/data/transitCoverage.js",
"src/data/cameraSensitivity.js",
"src/data/contactPlayback.js",
"src/data/contactTrailRenderer.js",
@@ -4287,6 +4293,10 @@
"src/data/railTimeZones.js",
"src/data/transitFeeds.js",
"src/data/rioRouteNames.js",
"src/data/transitFeedsFrance.js",
"src/data/transitFeedsJapan.js",
"src/data/transitFeedsCatalogue.js",
"src/data/transitRouteNamesFrance.js",
"src/data/transitIcons.js",
"src/data/transitPresetStyle.js",
"src/layers/transit/controls.js",
@@ -4301,6 +4311,8 @@
"src/layers/transit/state.js",
"src/layers/transit/testing.js",
"src/layers/transit/viewport.js",
"src/layers/transit/coverage.js",
"src/data/transitCoverage.js",
"src/data/cameraSensitivity.js",
"src/data/contactPlayback.js",
"src/data/contactTrailRenderer.js",
@@ -5139,6 +5151,10 @@
"src/data/gtfsRealtime.js",
"src/data/transitFeeds.js",
"src/data/rioRouteNames.js",
"src/data/transitFeedsFrance.js",
"src/data/transitFeedsJapan.js",
"src/data/transitFeedsCatalogue.js",
"src/data/transitRouteNamesFrance.js",
"src/geoDistance.js",
"src/data/transitProxy.js",
"src/sources/httpBody.js",
@@ -5156,6 +5172,10 @@
"src/data/gtfsRealtime.js",
"src/data/transitFeeds.js",
"src/data/rioRouteNames.js",
"src/data/transitFeedsFrance.js",
"src/data/transitFeedsJapan.js",
"src/data/transitFeedsCatalogue.js",
"src/data/transitRouteNamesFrance.js",
"src/geoDistance.js",
"src/data/transitProxy.js",
"src/sources/transitHistory.js"
@@ -5190,6 +5210,10 @@
"src/data/transit.js",
"src/data/transitFeeds.js",
"src/data/rioRouteNames.js",
"src/data/transitFeedsFrance.js",
"src/data/transitFeedsJapan.js",
"src/data/transitFeedsCatalogue.js",
"src/data/transitRouteNamesFrance.js",
"src/data/transitIcons.js",
"src/data/transitPresetStyle.js",
"src/data/transitProxy.js",
@@ -5208,6 +5232,8 @@
"src/layers/transit/testing.js",
"src/layers/transit/trails.js",
"src/layers/transit/viewport.js",
"src/layers/transit/coverage.js",
"src/data/transitCoverage.js",
"src/overlays/worldOverlay.js",
"src/overlays/worldOverlayDraw.js",
"src/overlays/worldOverlayTokens.js",
@@ -5253,6 +5279,10 @@
"src/data/inputOwnership.js",
"src/data/transitFeeds.js",
"src/data/rioRouteNames.js",
"src/data/transitFeedsFrance.js",
"src/data/transitFeedsJapan.js",
"src/data/transitFeedsCatalogue.js",
"src/data/transitRouteNamesFrance.js",
"src/geoDistance.js",
"src/data/transitIcons.js",
"src/data/transitPresetStyle.js",
@@ -5268,6 +5298,8 @@
"src/layers/transit/state.js",
"src/layers/transit/testing.js",
"src/layers/transit/viewport.js",
"src/layers/transit/coverage.js",
"src/data/transitCoverage.js",
"src/data/cameraSensitivity.js",
"src/data/contactPlayback.js",
"src/data/contactTrailRenderer.js",
@@ -5325,6 +5357,10 @@
"src/data/railNoPositions.js",
"src/data/transitFeeds.js",
"src/data/rioRouteNames.js",
"src/data/transitFeedsFrance.js",
"src/data/transitFeedsJapan.js",
"src/data/transitFeedsCatalogue.js",
"src/data/transitRouteNamesFrance.js",
"src/geoDistance.js",
"src/data/transitProxy.js",
"src/data/gtfsRealtime.js",
@@ -5355,6 +5391,10 @@
"src/data/railNoPositions.js",
"src/data/transitFeeds.js",
"src/data/rioRouteNames.js",
"src/data/transitFeedsFrance.js",
"src/data/transitFeedsJapan.js",
"src/data/transitFeedsCatalogue.js",
"src/data/transitRouteNamesFrance.js",
"src/geoDistance.js",
"src/data/transitProxy.js",
"src/data/gtfsRealtime.js",
@@ -5371,6 +5411,10 @@
"modules": [
"src/data/transitFeeds.js",
"src/data/rioRouteNames.js",
"src/data/transitFeedsFrance.js",
"src/data/transitFeedsJapan.js",
"src/data/transitFeedsCatalogue.js",
"src/data/transitRouteNamesFrance.js",
"src/geoDistance.js",
"src/data/transitProxy.js",
"src/data/gtfsRealtime.js",
@@ -5638,6 +5682,10 @@
"src/layers/transit/policy.js",
"src/data/transitFeeds.js",
"src/data/rioRouteNames.js",
"src/data/transitFeedsFrance.js",
"src/data/transitFeedsJapan.js",
"src/data/transitFeedsCatalogue.js",
"src/data/transitRouteNamesFrance.js",
"src/layers/transit/movement.js",
"src/data/contactPlayback.js",
"src/data/layerSnapshot.js",
+142
View File
@@ -0,0 +1,142 @@
/**
* Coverage points for the Transit layer's globe view: one soft spot per
* registered feed, hotter where networks cluster.
*
* Built from the registry alone. No feed is polled to draw it, so it says
* where vehicles CAN be shown, not where any are right now. Only feeds whose
* live positions have been seen count: a registry row marked
* `liveSeen: false` (added while its services were not running) gets no
* spot until it is confirmed.
*
* Pure: no Cesium, no DOM.
*/
import { greatCircleKm } from '../geoDistance.js';
/** Feeds within this distance of a feed count as its neighbours. */
export const COVERAGE_NEIGHBOUR_KM = 150;
/**
* Radius of a spot from orbit, km: a lone feed, and the densest cluster.
* Far larger than any network: at whole-globe scale a real service area is
* under a pixel, and the point is to be seen.
*/
export const COVERAGE_FAR_RADIUS_KM = Object.freeze({ lone: 150, dense: 230 });
/**
* Radius of a spot at regional zoom, km: the feed's own polling radius,
* held between these bounds so a village network is still a visible patch
* and a regional coach network does not paint a whole country.
*/
export const COVERAGE_NEAR_RADIUS_KM = Object.freeze({ min: 22, max: 75 });
/** Heat is drawn in this many steps, one draw batch each. */
export const COVERAGE_HEAT_BUCKETS = 6;
/**
* Share of full strength one spot carries: 1 for a lone network, less for one
* in a crowd. Spots in a cluster overlap, and at full strength each they
* pile into a flat white blob with visible disc edges; thinned by the square
* root of the crowd they add up to one smooth field that still brightens
* toward its centre.
* @param {number} neighbours
* @returns {number} 0..1
*/
export function coverageSpotStrength(neighbours) {
const crowd = Math.max(0, Number(neighbours) || 0);
return Number((0.3 + 0.7 / Math.sqrt(1 + crowd)).toFixed(3));
}
/**
* The bus green of the vehicle markers, from a deep green for a lone network
* to a pale core where many overlap. The lone end is saturated on purpose: a
* light translucent green vanishes into pale basemaps and desert imagery.
*/
export const COVERAGE_PALETTE = Object.freeze([
{ at: 0.0, rgb: [24, 196, 106] },
{ at: 0.5, rgb: [94, 240, 138] },
{ at: 1.0, rgb: [206, 255, 196] },
]);
/**
* Palette colour at a normalized heat.
* @param {number} t 0..1 (clamped)
* @returns {[number, number, number]} RGB, 0..255.
*/
export function coverageColorAt(t) {
const v = Math.min(1, Math.max(0, Number(t) || 0));
let i = 1;
while (i < COVERAGE_PALETTE.length - 1 && COVERAGE_PALETTE[i].at < v) i += 1;
const a = COVERAGE_PALETTE[i - 1];
const b = COVERAGE_PALETTE[i];
const k = (v - a.at) / (b.at - a.at || 1);
return [0, 1, 2].map((c) => Math.round(a.rgb[c] + (b.rgb[c] - a.rgb[c]) * k));
}
/**
* One coverage point per feed that has a centre and has been seen live.
*
* `heat` is logarithmic in the number of neighbours and normalized against
* the densest feed, so a lone network is always 0 (the same deep green and
* the same size) however crowded the busiest region is, and a hundred French
* networks do not wash out one in Bismarck. Heat is then stepped into
* COVERAGE_HEAT_BUCKETS buckets, which set the spot's colour and strength.
*
* @param {ReadonlyArray<{id?: string, center: {lat: number, lon: number}}>} feeds
* @param {{neighbourKm?: number}} [options]
* @returns {Array<{id: string|null, lat: number, lon: number, neighbours: number,
* heat: number, bucket: number, farRadiusKm: number, nearRadiusKm: number,
* strength: number, rgb: [number, number, number]}>}
*/
export function buildTransitCoveragePoints(
feeds,
{ neighbourKm = COVERAGE_NEIGHBOUR_KM } = {},
) {
const centred = (feeds || []).filter(
(feed) =>
feed?.liveSeen !== false &&
Number.isFinite(feed?.center?.lat) &&
Number.isFinite(feed?.center?.lon),
);
const neighbours = centred.map(
(feed) =>
centred.filter(
(other) =>
other !== feed &&
greatCircleKm(feed.center, other.center) <= neighbourKm,
).length,
);
const densest = Math.max(0, ...neighbours);
return centred.map((feed, index) => {
const heat = densest
? Math.log1p(neighbours[index]) / Math.log1p(densest)
: 0;
const top = COVERAGE_HEAT_BUCKETS - 1;
const bucket = Math.round(heat * top);
return {
id: feed.id ?? null,
lat: feed.center.lat,
lon: feed.center.lon,
neighbours: neighbours[index],
heat,
bucket,
farRadiusKm: Math.round(
COVERAGE_FAR_RADIUS_KM.lone +
(COVERAGE_FAR_RADIUS_KM.dense - COVERAGE_FAR_RADIUS_KM.lone) * heat,
),
nearRadiusKm: Math.min(
COVERAGE_NEAR_RADIUS_KM.max,
Math.max(
COVERAGE_NEAR_RADIUS_KM.min,
Number(feed.loadRadiusKm) || COVERAGE_NEAR_RADIUS_KM.min,
),
),
// Colour and strength follow the bucket, so every spot in a batch
// shares one material.
strength: coverageSpotStrength(
Math.expm1((bucket / top) * Math.log1p(densest || 1)),
),
rgb: coverageColorAt(bucket / top),
};
});
}
+190
View File
@@ -0,0 +1,190 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import {
COVERAGE_FAR_RADIUS_KM,
COVERAGE_HEAT_BUCKETS,
COVERAGE_NEAR_RADIUS_KM,
buildTransitCoveragePoints,
coverageColorAt,
coverageSpotStrength,
} from './transitCoverage.js';
import { TRANSIT_ENABLED_FEEDS } from './transitFeeds.js';
import {
ACTIVATION_ENTER_ALTITUDE_M,
ACTIVATION_EXIT_ALTITUDE_M,
COVERAGE_OPACITY_STOPS,
COVERAGE_PEAK_ALPHA,
coverageOpacityAt,
} from '../layers/transit/policy.js';
const feed = (id, lat, lon) => ({ id, center: { lat, lon } });
test('an empty registry gives no points, and a feed without a centre is skipped', () => {
assert.deepEqual(buildTransitCoveragePoints([]), []);
assert.deepEqual(buildTransitCoveragePoints(null), []);
const points = buildTransitCoveragePoints([
feed('a', 10, 10),
{ id: 'no-centre' },
{ id: 'bad', center: { lat: NaN, lon: 3 } },
]);
assert.deepEqual(
points.map((p) => p.id),
['a'],
);
});
test('a lone feed is the smallest, deepest spot', () => {
const [point] = buildTransitCoveragePoints([feed('lone', 46.8, -100.8)]);
assert.equal(point.neighbours, 0);
assert.equal(point.heat, 0);
assert.equal(point.bucket, 0);
assert.equal(point.strength, 1);
assert.equal(point.farRadiusKm, COVERAGE_FAR_RADIUS_KM.lone);
assert.deepEqual(point.rgb, coverageColorAt(0));
});
test('a lone feed looks the same however dense the busiest region is', () => {
const lone = feed('lone', 46.8, -100.8);
const cluster = Array.from({ length: 40 }, (_, i) =>
feed(`c${i}`, 48 + (i % 8) * 0.1, 2 + Math.floor(i / 8) * 0.1),
);
const alone = buildTransitCoveragePoints([lone])[0];
const crowded = buildTransitCoveragePoints([lone, ...cluster]);
assert.deepEqual(
crowded.find((p) => p.id === 'lone'),
alone,
);
const hottest = crowded.find((p) => p.id === 'c0');
assert.equal(hottest.neighbours, 39);
assert.equal(hottest.heat, 1);
assert.equal(hottest.bucket, COVERAGE_HEAT_BUCKETS - 1);
assert.equal(hottest.farRadiusKm, COVERAGE_FAR_RADIUS_KM.dense);
assert.ok(hottest.strength < 1, 'a spot in a crowd is thinner');
});
test('a spot in a crowd is thinner, so a cluster sums smoothly instead of clipping', () => {
assert.equal(coverageSpotStrength(0), 1);
assert.equal(coverageSpotStrength(-3), 1);
assert.equal(coverageSpotStrength(NaN), 1);
let previous = 1;
for (const crowd of [1, 3, 8, 15, 28, 100]) {
const strength = coverageSpotStrength(crowd);
assert.ok(strength < previous, `thinner with ${crowd} neighbours`);
assert.ok(strength > 0.3, 'never invisible');
// The crowd as a whole still outshines a lone feed.
assert.ok(strength * (1 + crowd) > 1);
previous = strength;
}
const [lone] = buildTransitCoveragePoints([feed('lone', 0, 0)]);
assert.equal(lone.strength, 1);
});
test('neighbours are counted by distance, across the antimeridian too', () => {
const points = buildTransitCoveragePoints([
feed('west', 0, 179.8),
feed('east', 0, -179.8),
feed('far', 0, 170),
]);
const by = Object.fromEntries(points.map((p) => [p.id, p.neighbours]));
assert.deepEqual(by, { west: 1, east: 1, far: 0 });
});
test('the palette runs from the lone green to a pale core and clamps', () => {
assert.deepEqual(coverageColorAt(-1), coverageColorAt(0));
assert.deepEqual(coverageColorAt(2), coverageColorAt(1));
assert.deepEqual(coverageColorAt(NaN), coverageColorAt(0));
const brightness = (t) => coverageColorAt(t).reduce((a, b) => a + b, 0);
let previous = 0;
for (let t = 0; t <= 1.0001; t += 0.1) {
assert.ok(brightness(t) >= previous, `does not darken at ${t.toFixed(1)}`);
previous = brightness(t);
}
});
test('a feed whose live positions have not been seen gets no spot', () => {
const points = buildTransitCoveragePoints([
feed('seen', 10, 10),
{ ...feed('unseen', 10.1, 10.1), liveSeen: false },
]);
assert.deepEqual(
points.map((p) => p.id),
['seen'],
);
assert.equal(points[0].neighbours, 0, 'an unseen feed is not a neighbour');
// The registry's own unconfirmed rows stay out; the confirmed ones are in.
const unseen = TRANSIT_ENABLED_FEEDS.filter((f) => f.liveSeen === false);
assert.ok(unseen.length > 0);
const real = new Set(
buildTransitCoveragePoints(TRANSIT_ENABLED_FEEDS).map((p) => p.id),
);
for (const row of unseen) assert.equal(real.has(row.id), false, row.id);
assert.ok(real.has('kumamoto-toshi-bus'));
assert.ok(real.has('sendai-city-bus'));
});
test('every feed seen live gets exactly one spot, and dense regions read hotter', () => {
const points = buildTransitCoveragePoints(TRANSIT_ENABLED_FEEDS);
assert.equal(
points.length,
TRANSIT_ENABLED_FEEDS.filter((f) => f.liveSeen !== false).length,
);
assert.equal(new Set(points.map((p) => p.id)).size, points.length);
const heat = (id) => points.find((p) => p.id === id).heat;
assert.ok(heat('axo-creil') > heat('mbta'), 'the Oise outranks Boston');
for (const point of points) {
assert.ok(point.heat >= 0 && point.heat <= 1);
assert.ok(
point.farRadiusKm >= COVERAGE_FAR_RADIUS_KM.lone &&
point.farRadiusKm <= COVERAGE_FAR_RADIUS_KM.dense,
);
assert.ok(
point.nearRadiusKm >= COVERAGE_NEAR_RADIUS_KM.min &&
point.nearRadiusKm <= COVERAGE_NEAR_RADIUS_KM.max,
);
assert.ok(point.bucket >= 0 && point.bucket < COVERAGE_HEAT_BUCKETS);
}
});
test('a regional patch is the feed’s own service area, within bounds', () => {
const at = (loadRadiusKm) =>
buildTransitCoveragePoints([{ ...feed('f', 0, 0), loadRadiusKm }])[0]
.nearRadiusKm;
assert.equal(at(30), 30);
assert.equal(at(5), COVERAGE_NEAR_RADIUS_KM.min);
assert.equal(at(210), COVERAGE_NEAR_RADIUS_KM.max);
assert.equal(at(undefined), COVERAGE_NEAR_RADIUS_KM.min);
});
test('wide spots own the globe view, service-area patches the regional view, and they overlap', () => {
const far = (h) => coverageOpacityAt(h, 'far');
const near = (h) => coverageOpacityAt(h, 'near');
assert.equal(far(20_000_000), 1);
assert.equal(far(Infinity), 1);
assert.equal(near(20_000_000), 0);
assert.equal(far(500_000), 0);
assert.ok(near(500_000) >= 0.5);
assert.equal(far(0), 0);
assert.equal(near(0), 0);
assert.equal(near(60_000), 0, 'off close in, where vehicles are the picture');
assert.equal(far(NaN), 0);
assert.equal(near(NaN), 0);
assert.equal(coverageOpacityAt(20_000_000), 1, 'the default set is far');
// From 250 km up there is never a height with nothing drawn, and the
// cross-fade has no dip: the two sets together stay well visible.
for (let h = 250_000; h <= 6_000_000; h += 25_000) {
assert.ok(far(h) + near(h) >= 0.45, `visible at ${h / 1000} km`);
}
// Both sides of the altitude gate are covered.
assert.ok(
far(ACTIVATION_ENTER_ALTITUDE_M) + near(ACTIVATION_ENTER_ALTITUDE_M) > 0.5,
);
assert.ok(far(ACTIVATION_EXIT_ALTITUDE_M) > 0.5);
// The far set only grows with height.
let previous = 0;
for (let h = 0; h <= 4_000_000; h += 20_000) {
assert.ok(far(h) >= previous, `far opacity does not fall at ${h} m`);
previous = far(h);
}
assert.ok(COVERAGE_PEAK_ALPHA > 0.5 && COVERAGE_PEAK_ALPHA <= 1);
assert.equal(COVERAGE_OPACITY_STOPS.far.at(-1)[1], 1);
});
+64
View File
@@ -1,5 +1,9 @@
import { greatCircleKm } from '../geoDistance.js';
import { RIO_ROUTE_NAMES } from './rioRouteNames.js';
import { CATALOGUE_TRANSIT_FEED_ROWS } from './transitFeedsCatalogue.js';
import { FRANCE_TRANSIT_FEED_ROWS } from './transitFeedsFrance.js';
import { JAPAN_TRANSIT_FEED_ROWS } from './transitFeedsJapan.js';
import { FRANCE_ROUTE_NAMES } from './transitRouteNamesFrance.js';
/**
* @module transitFeeds
@@ -10,6 +14,10 @@ import { RIO_ROUTE_NAMES } from './rioRouteNames.js';
* `/api/transit/vehicles/<id>` for a registered id (see SECURITY.md: proxies
* never fetch client-supplied URLs). Adding a feed means adding a row here,
* a DATA_SOURCES.md row with its license, and a credit in dataCredits.js.
* The French networks listed on transport.data.gouv.fr are rows of the same
* shape in `transitFeedsFrance.js`, and feeds added from the open catalogues
* are in `transitFeedsCatalogue.js` and `transitFeedsJapan.js`; all are appended
* to the registry below.
*
* Admission rules for a feed:
* - No key, token, or registration required (identify-yourself headers are
@@ -562,6 +570,58 @@ function transitFeed(fields) {
});
}
/**
* A French network row (`transitFeedsFrance.js`) as a registry entry. Every
* one is a bus network unless its row says otherwise: `routeModes` names the
* route ids that are trams or boats, and a route id it does not name stays a
* default, never a resolved "bus". The licence name, record link and terms
* note are built from the row's `licence`, `record`, `vehicles` and `note`.
* A feed with a table in
* `transitRouteNamesFrance.js` reads its line names from it; an id missing
* from the table renders unchanged.
* @param {object} row
* @returns {Readonly<object>}
*/
function franceTransitFeed(row) {
const { routeModes, licence, record, vehicles, note, ...fields } = row;
const odbl = licence === 'odc-odbl';
const names = Object.hasOwn(FRANCE_ROUTE_NAMES, row.id)
? FRANCE_ROUTE_NAMES[row.id]
: null;
return transitFeed({
defaultMode: 'bus',
...fields,
license: odbl ? 'ODbL' : 'Licence Ouverte 2.0',
licenseUrl: `https://transport.data.gouv.fr/datasets/${record}`,
terms: {
quote: `licence: ${licence}`,
note: [
`Dataset record’s licence field quoted; this is the record’s own GTFS-RT vehicle feed (${vehicles} vehicles on 2026-11-13).`,
odbl
? 'ODbL asks for credit and share-alike on a derived database; the layer draws positions and redistributes no database.'
: '',
note ?? '',
]
.filter(Boolean)
.join(' '),
},
...(routeModes
? {
routeMode: (routeId) =>
routeId && Object.hasOwn(routeModes, routeId)
? routeModes[routeId]
: 'unknown',
}
: {}),
...(names
? {
routeLabel: (routeId) =>
routeId && Object.hasOwn(names, routeId) ? names[routeId] : routeId,
}
: {}),
});
}
/**
* Registry of feeds. Order is presentation order in the stats/credit text.
* `loadRadiusKm` is the distance from `center` inside which the feed is polled.
@@ -1586,6 +1646,10 @@ export const TRANSIT_FEED_REGISTRY = Object.freeze([
},
defaultMode: 'bus',
}),
...FRANCE_TRANSIT_FEED_ROWS.map(franceTransitFeed),
...[...CATALOGUE_TRANSIT_FEED_ROWS, ...JAPAN_TRANSIT_FEED_ROWS].map((row) =>
transitFeed({ defaultMode: 'bus', ...row }),
),
]);
/**
+5
View File
@@ -713,8 +713,13 @@ test('feeds that publish km/h are marked for conversion, and only those', () =>
.map((f) => f.id)
.sort();
assert.deepEqual(kmh, [
'azalys-blois',
'carris-metropolitana-lisboa',
'divia-dijon',
'maelis-montlucon',
'mpm-toulon',
'rubis-bourg-en-bresse',
'setram-le-mans',
'tam-montpellier',
]);
});
File diff suppressed because it is too large. Load diff
+125
View File
@@ -0,0 +1,125 @@
import { readFileSync } from 'node:fs';
import test from 'node:test';
import assert from 'node:assert/strict';
import {
TRANSIT_FEED_REGISTRY,
TRANSIT_FEED_ID_PATTERN,
getTransitFeed,
publicTransitCatalog,
transitFeedsInRange,
transitModeFor,
} from './transitFeeds.js';
import { CATALOGUE_TRANSIT_FEED_ROWS } from './transitFeedsCatalogue.js';
test('every catalogue row becomes a live, keyless feed that covers its own centre', () => {
const ids = new Set();
for (const row of CATALOGUE_TRANSIT_FEED_ROWS) {
assert.match(row.id, TRANSIT_FEED_ID_PATTERN);
assert.equal(ids.has(row.id), false, `${row.id} is unique`);
ids.add(row.id);
const feed = getTransitFeed(row.id);
assert.ok(feed, `${row.id} is routable`);
assert.ok(
publicTransitCatalog().some((entry) => entry.id === row.id),
`${row.id} is offered to the browser`,
);
const url = new URL(row.url);
assert.equal(url.protocol, 'https:');
assert.equal(/key=/i.test(url.search), false, `${row.id} has no key`);
assert.match(
feed.terms.note,
/\d+ vehicles on 2026-11-13\./,
`${row.id} records the day it was seen live`,
);
assert.ok(
transitFeedsInRange(row.center.lat, row.center.lon).some(
(entry) => entry.id === row.id,
),
`${row.id} covers its own centre`,
);
}
});
test('a catalogue row either quotes terms that were read or links its catalogue record', () => {
let read = 0;
for (const row of CATALOGUE_TRANSIT_FEED_ROWS) {
if (row.license === 'Public realtime vehicle feed') {
assert.equal(row.terms.quote, undefined, `${row.id} quotes nothing`);
assert.match(
row.terms.note,
/Keyless feed on .+ Shipped on the same basis as Metro Transit and OVapi|Same server and basis/,
`${row.id} names the basis it ships on`,
);
assert.match(
row.licenseUrl,
/^https:\/\/(mobilitydatabase\.org|www\.transit\.land|gtfsrt\.io)\//,
`${row.id} links its catalogue record`,
);
} else {
read++;
assert.ok(row.terms.quote, `${row.id} quotes the grant`);
assert.match(
row.terms.note,
/read 2026-11-13|same click-through agreement/,
`${row.id} says when its terms were read`,
);
}
}
assert.equal(read, 10);
});
test('feeds whose terms forbid this use, or could not be read, are not registered', () => {
const hosts = new Set(
TRANSIT_FEED_REGISTRY.map((feed) => new URL(feed.url).hostname),
);
for (const host of [
// Terms exclude keyless public display.
'gtfsrt.prod.obanyc.com',
'www.myddotbus.com',
'everett.mapstrat.com',
'duluthtransit.com',
'ridetime.greaterdaytonrta.org',
'cttprdtmgtfs.ctttrpcloud.com',
'truetime.portauthority.org',
// Terms could not be read.
'gtfs.sofiatraffic.bg',
'track.ua-gis.com',
'www.ridedart.com',
'ride.smtd.org',
'knoxville.syncromatics.com',
'bustracker.pvta.com',
'bus.gocitybus.com',
// A third party's republication.
'proxy.busone.app',
]) {
assert.equal(hosts.has(host), false, `${host} is not fetched`);
}
});
test('licences that ask for specific credit get it', () => {
const bilbao = getTransitFeed('metro-bilbao');
assert.equal(bilbao.creditDated, true);
assert.equal(transitModeFor(bilbao, null), 'subway');
const fairfax = getTransitFeed('fairfax-connector');
assert.match(fairfax.attribution, /Visit fairfaxconnector\.com/);
assert.equal(fairfax.sourceUrl, 'https://www.fairfaxconnector.com');
assert.match(getTransitFeed('gcrta-cleveland').attribution, /GCRTA/);
assert.equal(transitModeFor(getTransitFeed('marc-train-md'), null), 'rail');
assert.equal(transitModeFor(getTransitFeed('ny-waterway'), null), 'ferry');
});
test('every catalogue feed is documented with its licence', () => {
const lines = readFileSync(
new URL('../../DATA_SOURCES.md', import.meta.url),
'utf8',
).split('\n');
for (const row of CATALOGUE_TRANSIT_FEED_ROWS) {
const line = lines.find((l) => l.startsWith(`| **${row.name}** `));
assert.ok(line, `${row.name} has a DATA_SOURCES row`);
assert.ok(line.includes(row.license), `${row.name} row names its licence`);
assert.ok(
line.includes(row.licenseUrl),
`${row.name} row links its source`,
);
}
});
File diff suppressed because it is too large. Load diff
+201
View File
@@ -0,0 +1,201 @@
import { readFileSync } from 'node:fs';
import test from 'node:test';
import assert from 'node:assert/strict';
import {
TRANSIT_FEED_REGISTRY,
TRANSIT_FEED_ID_PATTERN,
getTransitFeed,
publicTransitCatalog,
transitFeedsInRange,
transitModeFor,
transitModeResolved,
transitRouteLabel,
} from './transitFeeds.js';
import { FRANCE_TRANSIT_FEED_ROWS } from './transitFeedsFrance.js';
import { FRANCE_ROUTE_NAMES } from './transitRouteNamesFrance.js';
import {
TRANSIT_ADMISSION_MAX_GLOBAL,
TRANSIT_ADMISSION_WINDOW_MS,
TRANSIT_PROXY_TTL_MS,
} from './transitProxy.js';
const FRANCE_IDS = new Set(FRANCE_TRANSIT_FEED_ROWS.map((row) => row.id));
test('every French row becomes a live feed under its record’s open licence', () => {
assert.equal(FRANCE_IDS.size, FRANCE_TRANSIT_FEED_ROWS.length);
for (const row of FRANCE_TRANSIT_FEED_ROWS) {
assert.match(row.id, TRANSIT_FEED_ID_PATTERN);
const feed = getTransitFeed(row.id);
assert.ok(feed, `${row.id} is routable`);
assert.ok(
publicTransitCatalog().some((entry) => entry.id === row.id),
`${row.id} is offered to the browser`,
);
assert.ok(
['lov2', 'odc-odbl'].includes(row.licence),
`${row.id} states an open licence`,
);
assert.equal(
feed.license,
row.licence === 'lov2' ? 'Licence Ouverte 2.0' : 'ODbL',
);
assert.equal(
feed.licenseUrl,
`https://transport.data.gouv.fr/datasets/${row.record}`,
`${row.id} links its dataset record`,
);
assert.equal(feed.terms.quote, `licence: ${row.licence}`);
assert.match(
feed.terms.note,
/\(\d+ vehicles on 2026-11-13\)/,
`${row.id} records the day it was seen live`,
);
assert.ok(row.vehicles > 0, `${row.id} had vehicles when it was added`);
assert.ok(
transitFeedsInRange(row.center.lat, row.center.lon).some(
(entry) => entry.id === row.id,
),
`${row.id} covers its own centre`,
);
}
});
test('no French row repeats a feed that is already registered', () => {
const seen = new Map();
for (const feed of TRANSIT_FEED_REGISTRY) {
const url = new URL(feed.url);
const key = `${url.origin}${url.pathname.replace(/\/$/, '')}${url.search}`;
assert.equal(
seen.has(key),
false,
`${feed.id} and ${seen.get(key)} fetch the same upstream`,
);
seen.set(key, feed.id);
}
// The networks that were already here through the operator's own endpoint
// stay single: no French row points at a dataset record one of them cites.
const earlier = TRANSIT_FEED_REGISTRY.filter(
(feed) => !FRANCE_IDS.has(feed.id),
);
for (const id of [
'tbm-bordeaux',
'tam-montpellier',
'astuce-rouen',
'mpm-toulon',
'lia-le-havre',
'filbleu-tours',
]) {
assert.ok(earlier.some((feed) => feed.id === id));
}
const earlierRecords = new Set(earlier.map((feed) => feed.licenseUrl));
for (const row of FRANCE_TRANSIT_FEED_ROWS) {
assert.equal(
earlierRecords.has(getTransitFeed(row.id).licenseUrl),
false,
`${row.id} is not a second copy of an earlier feed`,
);
}
});
test('one viewpoint never asks for more feeds than the proxy admits', () => {
// The browser polls each in-range feed once per proxy TTL, and the proxy
// admits a fixed number of upstream requests a minute across all feeds.
const pollsPerFeed = TRANSIT_ADMISSION_WINDOW_MS / TRANSIT_PROXY_TTL_MS;
for (const feed of TRANSIT_FEED_REGISTRY) {
const inRange = transitFeedsInRange(feed.center.lat, feed.center.lon);
assert.ok(
inRange.length * pollsPerFeed <= TRANSIT_ADMISSION_MAX_GLOBAL,
`${inRange.length} feeds overlap at ${feed.id}`,
);
}
});
test('French trams and boats take their mode; every other route stays a default', () => {
const cases = [
['divia-dijon', '4-T1', 'tram'],
['bibus-brest', 'A', 'tram'],
['setram-le-mans', 'T2', 'tram'],
['lignes-dazur-nice', 'L2', 'tram'],
['irigo-angers', 'C', 'tram'],
['orizo-avignon', 'T1', 'tram'],
['transvilles-valenciennes', 'NAVINEO:Line::190:LOC', 'tram'],
['aleop-pays-de-la-loire', 'YEU', 'ferry'],
['martinique-sud', '4001', 'ferry'],
];
for (const [id, routeId, mode] of cases) {
const feed = getTransitFeed(id);
assert.equal(transitModeFor(feed, routeId), mode, `${id} ${routeId}`);
assert.equal(transitModeResolved(feed, routeId), true);
assert.equal(transitModeFor(feed, 'no-such-route'), 'bus');
assert.equal(
transitModeResolved(feed, 'no-such-route'),
false,
`${id} defaults rather than resolves an unlisted route`,
);
}
const busOnly = getTransitFeed('ametis-amiens');
assert.equal(transitModeFor(busOnly, '7'), 'bus');
assert.equal(transitModeResolved(busOnly, '7'), false);
});
test('French feeds that publish km/h are marked for conversion, and only those', () => {
assert.deepEqual(
FRANCE_TRANSIT_FEED_ROWS.filter((row) => row.speedUnit === 'km/h')
.map((row) => row.id)
.sort(),
[
'azalys-blois',
'divia-dijon',
'maelis-montlucon',
'rubis-bourg-en-bresse',
'setram-le-mans',
],
);
for (const row of FRANCE_TRANSIT_FEED_ROWS.filter((r) => r.speedUnit)) {
assert.match(getTransitFeed(row.id).terms.note, /Speeds are km\/h/);
}
});
test('French route-name tables belong to registered feeds and never blank a line', () => {
for (const [id, names] of Object.entries(FRANCE_ROUTE_NAMES)) {
assert.ok(FRANCE_IDS.has(id), `${id} is a registered French feed`);
const feed = getTransitFeed(id);
for (const [routeId, name] of Object.entries(names)) {
assert.ok(typeof name === 'string' && name.trim() === name && name);
assert.notEqual(name, routeId, `${id} ${routeId} is not a no-op`);
assert.equal(transitRouteLabel(feed, routeId), name);
}
assert.equal(transitRouteLabel(feed, 'no-such-route'), 'no-such-route');
assert.equal(transitRouteLabel(feed, null), null);
}
assert.equal(transitRouteLabel(getTransitFeed('divia-dijon'), '4-T1'), 'T1');
assert.equal(
transitRouteLabel(
getTransitFeed('transvilles-valenciennes'),
'NAVINEO:Line::190:LOC',
),
'T1',
);
// A feed whose ids already read as the line has no table and is left alone.
assert.equal(transitRouteLabel(getTransitFeed('ametis-amiens'), '7'), '7');
});
test('every French feed is documented with its licence', () => {
const lines = readFileSync(
new URL('../../DATA_SOURCES.md', import.meta.url),
'utf8',
).split('\n');
for (const row of FRANCE_TRANSIT_FEED_ROWS) {
const feed = getTransitFeed(row.id);
const line = lines.find((l) => l.startsWith(`| **${feed.name}** `));
assert.ok(line, `${feed.name} has a DATA_SOURCES row`);
assert.ok(
line.includes(feed.licenseUrl),
`${feed.name} row links its record`,
);
assert.ok(
line.includes(feed.license),
`${feed.name} row names its licence`,
);
}
});
File diff suppressed because it is too large. Load diff
+74
View File
@@ -0,0 +1,74 @@
import { readFileSync } from 'node:fs';
import test from 'node:test';
import assert from 'node:assert/strict';
import {
TRANSIT_FEED_ID_PATTERN,
getTransitFeed,
publicTransitCatalog,
transitFeedsInRange,
} from './transitFeeds.js';
import { JAPAN_TRANSIT_FEED_ROWS } from './transitFeedsJapan.js';
test('every Japanese row is a live, keyless feed under CC0 or CC BY', () => {
const ids = new Set();
for (const row of JAPAN_TRANSIT_FEED_ROWS) {
assert.match(row.id, TRANSIT_FEED_ID_PATTERN);
assert.equal(ids.has(row.id), false, `${row.id} is unique`);
ids.add(row.id);
assert.ok(getTransitFeed(row.id), `${row.id} is routable`);
assert.ok(
publicTransitCatalog().some((entry) => entry.id === row.id),
`${row.id} is offered to the browser`,
);
assert.ok(['CC0 1.0', 'CC BY 4.0'].includes(row.license));
assert.match(
row.licenseUrl,
/^https:\/\/mobilitydatabase\.org\/feeds\/gtfs_rt\//,
`${row.id} links its catalogue record`,
);
assert.match(
row.terms.quote,
row.license === 'CC0 1.0'
? /creativecommons\.org\/publicdomain\/zero\/1\.0/
: /creativecommons\.org\/licenses\/by\/4\.0/,
`${row.id} quotes the licence it names`,
);
assert.match(
row.terms.note,
/Vehicle positions were seen on|its positions have not been seen yet/,
`${row.id} says whether positions were seen`,
);
assert.equal(
row.liveSeen === false,
/have not been seen yet/.test(row.terms.note),
`${row.id} is flagged exactly when its positions are unseen`,
);
assert.equal(new URL(row.url).protocol, 'https:');
assert.ok(
// Japan, Hokkaidō to Okinawa.
row.center.lat > 24 &&
row.center.lat < 46 &&
row.center.lon > 122 &&
row.center.lon < 146,
`${row.id} is centred in Japan`,
);
assert.ok(
transitFeedsInRange(row.center.lat, row.center.lon).some(
(entry) => entry.id === row.id,
),
`${row.id} covers its own centre`,
);
}
});
test('every Japanese feed is documented with its licence', () => {
const lines = readFileSync(
new URL('../../DATA_SOURCES.md', import.meta.url),
'utf8',
).split('\n');
for (const row of JAPAN_TRANSIT_FEED_ROWS) {
const line = lines.find((l) => l.startsWith(`| **${row.name}** `));
assert.ok(line, `${row.name} has a DATA_SOURCES row`);
assert.ok(line.includes(row.license) && line.includes(row.licenseUrl));
}
});
File diff suppressed because it is too large. Load diff
+11 -89
View File
@@ -77,22 +77,8 @@
"{severity} only": "{severity} فقط",
"All categories": "كل الفئات",
"Reading the news…": "جارٍ قراءة الأخبار…",
"News, last {hours} hours": {
"zero": "الأخبار، آخر {hours} ساعة",
"one": "الأخبار، آخر ساعة ({hours})",
"two": "الأخبار، آخر ساعتين ({hours})",
"few": "الأخبار، آخر {hours} ساعات",
"many": "الأخبار، آخر {hours} ساعة",
"other": "الأخبار، آخر {hours} ساعة"
},
"Last {hours} h": {
"zero": "آخر {hours} ساعة",
"one": "آخر ساعة ({hours})",
"two": "آخر ساعتين ({hours})",
"few": "آخر {hours} ساعات",
"many": "آخر {hours} ساعة",
"other": "آخر {hours} ساعة"
},
"News, last {hours} hours": "الأخبار، الساعات الأخيرة: {hours}",
"Last {hours} h": "آخر {hours} س",
"Time window": "الفترة الزمنية",
"Conflicts": "النزاعات",
"Local": "محلي",
@@ -101,23 +87,9 @@
"Hotspots": "بؤر ساخنة",
"Severity": "الخطورة",
"Category": "الفئة",
"Nothing reported near here in the last {hours} h": {
"zero": "لم يُبلَّغ عن شيء قريب من هنا في آخر {hours} ساعة",
"one": "لم يُبلَّغ عن شيء قريب من هنا في آخر ساعة ({hours})",
"two": "لم يُبلَّغ عن شيء قريب من هنا في آخر ساعتين ({hours})",
"few": "لم يُبلَّغ عن شيء قريب من هنا في آخر {hours} ساعات",
"many": "لم يُبلَّغ عن شيء قريب من هنا في آخر {hours} ساعة",
"other": "لم يُبلَّغ عن شيء قريب من هنا في آخر {hours} ساعة"
},
"Nothing reported near here in the last {hours} h": "لم يُبلَّغ عن شيء قريب من هنا في آخر {hours} س",
"Latest news": "آخر الأخبار",
"No news matches these filters in the last {hours} h": {
"zero": "لا أخبار تطابق هذه المرشحات في آخر {hours} ساعة",
"one": "لا أخبار تطابق هذه المرشحات في آخر ساعة ({hours})",
"two": "لا أخبار تطابق هذه المرشحات في آخر ساعتين ({hours})",
"few": "لا أخبار تطابق هذه المرشحات في آخر {hours} ساعات",
"many": "لا أخبار تطابق هذه المرشحات في آخر {hours} ساعة",
"other": "لا أخبار تطابق هذه المرشحات في آخر {hours} ساعة"
},
"No news matches these filters in the last {hours} h": "لا أخبار تطابق هذه المرشحات في آخر {hours} س",
"Load older news": "تحميل أخبار أقدم",
"How to read the map": "كيف تقرأ الخريطة",
"Colour: severity · icon: type of event": "اللون: الخطورة · الرمز: نوع الحدث",
@@ -287,14 +259,7 @@
"ALTITUDE": "الارتفاع",
"CONTACT": "الهدف",
"CONTACTS · 250 KM": "الأهداف · 250 كم",
"RINGS {spacing} NM": {
"zero": "الحلقات كل {spacing} ميل بحري",
"one": "الحلقات كل ميل بحري ({spacing})",
"two": "الحلقات كل ميلين بحريين ({spacing})",
"few": "الحلقات كل {spacing} أميال بحرية",
"many": "الحلقات كل {spacing} ميلًا بحريًا",
"other": "الحلقات كل {spacing} ميل بحري"
},
"RINGS {spacing} NM": "الحلقات كل {spacing} ميل بحري",
"{count} CONTACTS": {
"zero": "لا أهداف ({count})",
"one": "هدف واحد ({count})",
@@ -423,14 +388,7 @@
"ROUTE DATA UNAVAILABLE": "بيانات المسار غير متاحة",
"CONTACT NAVIGATION OFF": "التنقل بين الأهداف متوقف",
"THE BRIDGE STAYS WITH THE SELECTED VESSEL": "تبقى غرفة القيادة مع السفينة المحددة",
"{range} NM": {
"zero": "{range} ميل بحري",
"one": "ميل بحري واحد ({range})",
"two": "ميلان بحريان ({range})",
"few": "{range} أميال بحرية",
"many": "{range} ميلًا بحريًا",
"other": "{range} ميل بحري"
},
"{range} NM": "{range} ميل بحري",
"AIS DESTINATION · CREW REPORTED": "وجهة AIS · أبلغ عنها الطاقم",
"FROM": "من",
"TO": "إلى",
@@ -514,7 +472,6 @@
"Current style: {style} — click for next": "النمط الحالي: {style} — انقر للتالي",
"TRACK ACQUIRED": "تم التقاط الهدف",
"{label} · COURSE {heading}°": "{label} · المسار {heading}°",
"vessel|{label} · COURSE {heading}°": "{label} · المسار {heading}°",
"{label} · HEADING {heading}°": "{label} · الاتجاه {heading}°",
"{label} · NO HEADING": "{label} · لا اتجاه",
"{label} · NADIR VIEW": "{label} · عرض باتجاه النظير",
@@ -716,7 +673,6 @@
"NEAREST": "الأقرب",
"CCTV camera": "كاميرا CCTV",
"FOCUS": "تركيز",
"site status|FOCUS": "تركيز",
"COVERAGE OFF": "التغطية متوقفة",
"AUTO HOP OFF": "التنقل التلقائي متوقف",
"PROJECTION ON": "الإسقاط مفعّل",
@@ -1107,7 +1063,6 @@
"awaiting first AIS message…": "بانتظار أول رسالة AIS…",
"EST. DOWNRANGE": "تقدير على امتداد المسار",
"CONFIRMED": "مؤكَّد",
"sightings filter|CONFIRMED": "مؤكَّدة",
"PAD / RTLS": "منصة الإطلاق / RTLS",
"Pick a shape, then click the map.": "اختر شكلًا، ثم انقر على الخريطة.",
"Enter to place the pin, Esc to cancel.": "Enter لوضع الدبوس، وEsc للإلغاء.",
@@ -2589,7 +2544,6 @@
"Observed history": "سجل الأرصاد",
"Later observation": "رصد لاحق",
"Latest": "الأحدث",
"news list|Latest": "الأحدث",
"Newest frame per product": "أحدث إطار لكل منتج",
"Replay observed history": "إعادة تشغيل سجل الأرصاد",
"Imagery on Esri · Google 3D returns when cleared": "الصور على Esri · تعود Google 3D عند المسح",
@@ -3762,14 +3716,7 @@
"Photo of {name}": "صورة {name}",
"Acartia": "Acartia",
"CC BY 4.0": "CC BY 4.0",
"{count} sightings in view": {
"zero": "{count} مشاهدة في نطاق العرض",
"one": "مشاهدة واحدة ({count}) في نطاق العرض",
"two": "مشاهدتان ({count}) في نطاق العرض",
"few": "{count} مشاهدات في نطاق العرض",
"many": "{count} مشاهدة في نطاق العرض",
"other": "{count} مشاهدة في نطاق العرض"
},
"{count} sightings in view": "المشاهدات في نطاق العرض: {count}",
"Close sighting": "إغلاق المشاهدة",
"Wildlife observed within 48 h (whales 7 d). Color and badge glyph show the taxon group. Sensitive species are shown only as 0.2° cells; Salish Sea marine mammal reports via Acartia are rounded to 0.01°. Not a census.": "حياة برية شوهدت خلال 48 ساعة (الحيتان 7 أيام). يوضح اللون ورمز الشارة المجموعة التصنيفية. تُعرض الأنواع الحساسة في خلايا بحجم 0.2° فقط؛ وتُقرّب مشاهدات الثدييات البحرية في بحر ساليش عبر Acartia إلى 0.01°. ليست إحصاءً شاملًا.",
"Open {name} on iNaturalist": "فتح {name} على iNaturalist",
@@ -3780,37 +3727,20 @@
"{days}d": "{days} ي",
"All markers": "كل العلامات",
"Show markers of every age": "عرض العلامات من جميع الأعمار",
"Maximum event age: {days}d; undated markers are kept": {
"zero": "الحد الأقصى لعمر الحدث: {days} يوم؛ تبقى العلامات غير المؤرخة ظاهرة",
"one": "الحد الأقصى لعمر الحدث: يوم واحد ({days})؛ تبقى العلامات غير المؤرخة ظاهرة",
"two": "الحد الأقصى لعمر الحدث: يومان ({days})؛ تبقى العلامات غير المؤرخة ظاهرة",
"few": "الحد الأقصى لعمر الحدث: {days} أيام؛ تبقى العلامات غير المؤرخة ظاهرة",
"many": "الحد الأقصى لعمر الحدث: {days} يومًا؛ تبقى العلامات غير المؤرخة ظاهرة",
"other": "الحد الأقصى لعمر الحدث: {days} يوم؛ تبقى العلامات غير المؤرخة ظاهرة"
},
"Maximum event age: {days}d; undated markers are kept": "الحد الأقصى لعمر الحدث: {days} ي؛ تبقى العلامات غير المؤرخة ظاهرة",
"event age filter|All": "الكل",
"Event age": "عمر الحدث",
"Event age: {days}d · undated kept": {
"zero": "عمر الحدث: {days} يوم · غير المؤرخة تبقى ظاهرة",
"one": "عمر الحدث: يوم واحد ({days}) · غير المؤرخة تبقى ظاهرة",
"two": "عمر الحدث: يومان ({days}) · غير المؤرخة تبقى ظاهرة",
"few": "عمر الحدث: {days} أيام · غير المؤرخة تبقى ظاهرة",
"many": "عمر الحدث: {days} يومًا · غير المؤرخة تبقى ظاهرة",
"other": "عمر الحدث: {days} يوم · غير المؤرخة تبقى ظاهرة"
},
"Event age: {days}d · undated kept": "عمر الحدث: {days} ي · غير المؤرخة تبقى ظاهرة",
"Close camera preview": "إغلاق معاينة الكاميرا",
"Refresh map still": "تحديث صورة الخريطة الثابتة",
"The map still uses a separate request and may show a different moment.": "تستخدم صورة الخريطة طلبًا منفصلًا وقد تعرض لحظة مختلفة.",
"Video plays from Québec 511, which sees your IP address.": "يُشغَّل الفيديو من Québec 511، الذي يرى عنوان IP الخاص بك.",
"Press OPEN to load the photo": "اضغط «فتح» لتحميل الصورة",
"Captured {month}": "التُقطت في {month}",
"this spot": "هذا الموضع",
"the view centre": "مركز العرض",
"{source} at {place}": "{source} في {place}",
"{source} at this spot": "{source} في هذا الموضع",
"{source} at the view centre": "{source} في مركز العرض",
"Street level at {place}": "مستوى الشارع في {place}",
"Street level at this spot": "مستوى الشارع في هذا الموضع",
"Street level at the view centre": "مستوى الشارع في مركز العرض",
"Switching map": "جارٍ تبديل الخريطة",
"Opening imagery": "جارٍ فتح الصور",
"Street View is ready: press {open} to load it": "Street View جاهز: اضغط «{open}» لتحميله",
@@ -3902,7 +3832,6 @@
"{source} imagery could not be opened": "تعذّر فتح صور {source}",
"{place} has no position to look for imagery at": "{place}: لا موضع للبحث عن الصور فيه",
"No {source} imagery near {place}": "لا توجد صور {source} قرب {place}",
"No {source} imagery near the view centre": "لا توجد صور {source} قرب مركز العرض",
"{reason} (filters on: {filters})": "{reason} (المرشحات المفعّلة: {filters})",
"tiles unavailable": "البلاطات غير متاحة",
"zoom in to load this layer": "قرّب لتحميل هذه الطبقة",
@@ -4023,13 +3952,6 @@
"REMOVE ALL": "إزالة الكل",
"Confirm: remove every added entry from Data Layers": "تأكيد: إزالة كل الإدخالات المُضافة من طبقات البيانات",
"Remove every added entry from Data Layers": "إزالة كل الإدخالات المُضافة من طبقات البيانات",
"Showing {shown} of {total}": {
"zero": "عرض {shown} من {total}",
"one": "عرض {shown} من {total}",
"two": "عرض {shown} من {total}",
"few": "عرض {shown} من {total}",
"many": "عرض {shown} من {total}",
"other": "عرض {shown} من {total}"
},
"Showing {shown} of {total}": "عرض {shown} من {total}",
"BROWSE DATA LIBRARY": "تصفّح مكتبة البيانات"
}
+12 -50
View File
@@ -65,14 +65,8 @@
"{severity} only": "Nur {severity}",
"All categories": "Alle Kategorien",
"Reading the news…": "Nachrichten werden gelesen…",
"News, last {hours} hours": {
"one": "Nachrichten der letzten {hours} Stunde",
"other": "Nachrichten der letzten {hours} Stunden"
},
"Last {hours} h": {
"one": "Letzte {hours} h",
"other": "Letzte {hours} h"
},
"News, last {hours} hours": "Nachrichten, letzte {hours} h",
"Last {hours} h": "Letzte {hours} h",
"Time window": "Zeitraum",
"Conflicts": "Konflikte",
"Local": "Lokal",
@@ -81,15 +75,9 @@
"Hotspots": "Brennpunkte",
"Severity": "Schweregrad",
"Category": "Kategorie",
"Nothing reported near here in the last {hours} h": {
"one": "In der letzten {hours} h nichts in der Nähe gemeldet",
"other": "In den letzten {hours} h nichts in der Nähe gemeldet"
},
"Nothing reported near here in the last {hours} h": "In den letzten {hours} h nichts in der Nähe gemeldet",
"Latest news": "Neueste Nachrichten",
"No news matches these filters in the last {hours} h": {
"one": "Keine Nachrichten der letzten {hours} h passen zu diesen Filtern",
"other": "Keine Nachrichten der letzten {hours} h passen zu diesen Filtern"
},
"No news matches these filters in the last {hours} h": "Keine Nachrichten der letzten {hours} h passen zu diesen Filtern",
"Load older news": "Ältere Nachrichten laden",
"How to read the map": "So liest man die Karte",
"Colour: severity · icon: type of event": "Farbe: Schweregrad · Symbol: Art des Ereignisses",
@@ -210,7 +198,6 @@
"Previous — prior visited contact in the 250 km window": "Zurück: zuvor besuchter Kontakt im 250-km-Fenster",
"PREVIOUS": "ZURÜCK",
"FOCUS": "FOKUS",
"site status|FOCUS": "FOKUS",
"Next — nearest unvisited contact in the 250 km window": "Weiter: nächstgelegener unbesuchter Kontakt im 250-km-Fenster",
"NEXT": "WEITER",
"Open-source mapped/observed context. Missing broadcasts, unloaded map areas, or unmapped sites are not evidence of absence.": "Kontext aus offenen Quellen, kartiert/beobachtet. Fehlende Funksignale, nicht geladene Kartenbereiche oder nicht kartierte Standorte sind kein Beleg für Abwesenheit.",
@@ -315,7 +302,7 @@
"ORBITAL VELOCITY": "BAHNGESCHWINDIGKEIT",
"SUB-SATELLITE POINT": "SUBSATELLITENPUNKT",
"NORTH UP": "NORDEN OBEN",
"CURRENTLY OVER": "UNTER DEM SATELLITEN",
"CURRENTLY OVER": "AKTUELL ÜBER",
"{division}, {country}": "{division}, {country}",
"{region} · near {place}": "{region} · nahe {place}",
"NORAD {id}": "NORAD {id}",
@@ -572,10 +559,7 @@
"ROUTE DATA UNAVAILABLE": "ROUTENDATEN NICHT VERFÜGBAR",
"CONTACT NAVIGATION OFF": "KONTAKTNAVIGATION AUS",
"THE BRIDGE STAYS WITH THE SELECTED VESSEL": "DIE BRÜCKE BLEIBT BEIM GEWÄHLTEN SCHIFF",
"{range} NM": {
"one": "{range} SM",
"other": "{range} SM"
},
"{range} NM": "{range} SM",
"AIS DESTINATION · CREW REPORTED": "AIS-ZIEL · VON DER BESATZUNG GEMELDET",
"DEST {bearing}": "DEST {bearing}",
"Disable cockpit weather effects": "Cockpit-Wettereffekte deaktivieren",
@@ -621,7 +605,6 @@
"Reclassify as TR-3B": "Als TR-3B umklassifizieren",
"TRACK ACQUIRED": "TRACK ERFASST",
"{label} · COURSE {heading}°": "{label} · KURS {heading}°",
"vessel|{label} · COURSE {heading}°": "{label} · KURS {heading}°",
"{label} · HEADING {heading}°": "{label} · STEUERKURS {heading}°",
"{label} · NO HEADING": "{label} · KEIN STEUERKURS",
"{label} · NADIR VIEW": "{label} · NADIRANSICHT",
@@ -853,10 +836,7 @@
"Contact cockpit summary": "Cockpit-Zusammenfassung des Kontakts",
"CONTACT": "KONTAKT",
"CONTACTS · 250 KM": "KONTAKTE · 250 KM",
"RINGS {spacing} NM": {
"one": "RINGE {spacing} SM",
"other": "RINGE {spacing} SM"
},
"RINGS {spacing} NM": "RINGE {spacing} SM",
"{count} CONTACTS": {
"one": "{count} KONTAKT",
"other": "{count} KONTAKTE"
@@ -2424,7 +2404,6 @@
"Observed history": "Beobachteter Verlauf",
"Later observation": "Spätere Beobachtung",
"Latest": "Neueste",
"news list|Latest": "Neueste",
"Newest frame per product": "Neuester Frame je Produkt",
"Replay observed history": "Beobachteten Verlauf abspielen",
"Imagery on Esri · Google 3D returns when cleared": "Bilder auf Esri · nach LÖSCHEN wieder Google 3D",
@@ -3153,7 +3132,6 @@
"Left panels": "Linke Bereiche",
"Right panels": "Rechte Bereiche",
"CONFIRMED": "BESTÄTIGT",
"sightings filter|CONFIRMED": "BESTÄTIGT",
"PAD / RTLS": "STARTPLATZ / RTLS",
"fire confidence filter|All": "Alle",
"fire confidence filter|Nominal+": "Mittel+",
@@ -3414,10 +3392,7 @@
"Photo of {name}": "Foto von {name}",
"Acartia": "Acartia",
"CC BY 4.0": "CC BY 4.0",
"{count} sightings in view": {
"one": "{count} Beobachtung im Bild",
"other": "{count} Beobachtungen im Bild"
},
"{count} sightings in view": "Beobachtungen im Bild: {count}",
"Close sighting": "Beobachtung schließen",
"Wildlife observed within 48 h (whales 7 d). Color and badge glyph show the taxon group. Sensitive species are shown only as 0.2° cells; Salish Sea marine mammal reports via Acartia are rounded to 0.01°. Not a census.": "In den letzten 48 h beobachtete Wildtiere (Wale 7 Tage). Farbe und Symbol der Markierung zeigen die Artengruppe. Empfindliche Arten erscheinen nur als 0,2°-Zellen; Acartia-Meldungen zu Meeressäugern aus der Salish-See werden auf 0,01° gerundet. Keine Bestandszählung.",
"Open {name} on iNaturalist": "{name} auf iNaturalist öffnen",
@@ -3428,29 +3403,20 @@
"{days}d": "{days} T",
"All markers": "Alle Markierungen",
"Show markers of every age": "Markierungen jeden Alters anzeigen",
"Maximum event age: {days}d; undated markers are kept": {
"one": "Maximales Ereignisalter: {days} Tag; undatierte Markierungen bleiben erhalten",
"other": "Maximales Ereignisalter: {days} Tage; undatierte Markierungen bleiben erhalten"
},
"Maximum event age: {days}d; undated markers are kept": "Maximales Ereignisalter: {days} T; undatierte Markierungen bleiben erhalten",
"event age filter|All": "Alle",
"Event age": "Ereignisalter",
"Event age: {days}d · undated kept": {
"one": "Ereignisalter: {days} Tag · undatierte bleiben",
"other": "Ereignisalter: {days} Tage · undatierte bleiben"
},
"Event age: {days}d · undated kept": "Ereignisalter: {days} T · undatierte bleiben",
"Close camera preview": "Kameravorschau schließen",
"Refresh map still": "Kartenstandbild aktualisieren",
"The map still uses a separate request and may show a different moment.": "Das Kartenstandbild wird separat abgerufen und kann einen anderen Moment zeigen.",
"Video plays from Québec 511, which sees your IP address.": "Das Video wird von Québec 511 abgespielt; die IP-Adresse ist für diesen Anbieter sichtbar.",
"Press OPEN to load the photo": "Auf ÖFFNEN klicken, um das Foto zu laden",
"Captured {month}": "Aufgenommen im {month}",
"this spot": "diese Stelle",
"the view centre": "die Bildmitte",
"{source} at {place}": "{source}: {place}",
"{source} at this spot": "{source} an dieser Stelle",
"{source} at the view centre": "{source} in der Bildmitte",
"Street level at {place}": "Straßenebene: {place}",
"Street level at this spot": "Straßenebene an dieser Stelle",
"Street level at the view centre": "Straßenebene in der Bildmitte",
"Switching map": "Karte wird gewechselt",
"Opening imagery": "Bilder werden geöffnet",
"Street View is ready: press {open} to load it": "Street View ist bereit: Auf {open} klicken, um es zu laden",
@@ -3542,7 +3508,6 @@
"{source} imagery could not be opened": "Bilder von {source} konnten nicht geöffnet werden",
"{place} has no position to look for imagery at": "{place} hat keine Position, an der nach Bildern gesucht werden kann",
"No {source} imagery near {place}": "Keine Bilder von {source} in der Nähe von {place}",
"No {source} imagery near the view centre": "Keine Bilder von {source} in der Nähe der Bildmitte",
"{reason} (filters on: {filters})": "{reason} (aktive Filter: {filters})",
"tiles unavailable": "Kacheln nicht verfügbar",
"zoom in to load this layer": "hineinzoomen, um diese Ebene zu laden",
@@ -3639,9 +3604,6 @@
"REMOVE ALL": "ALLE ENTFERNEN",
"Confirm: remove every added entry from Data Layers": "Bestätigen: alle hinzugefügten Einträge aus Datenebenen entfernen",
"Remove every added entry from Data Layers": "Alle hinzugefügten Einträge aus Datenebenen entfernen",
"Showing {shown} of {total}": {
"one": "{shown} von {total} angezeigt",
"other": "{shown} von {total} angezeigt"
},
"Showing {shown} of {total}": "{shown} von {total} angezeigt",
"BROWSE DATA LIBRARY": "DATENBIBLIOTHEK DURCHSUCHEN"
}
+11 -59
View File
@@ -68,16 +68,8 @@
"{severity} only": "Solo {severity}",
"All categories": "Todas las categorías",
"Reading the news…": "Leyendo las noticias…",
"News, last {hours} hours": {
"one": "Noticias de la última {hours} hora",
"many": "Noticias de las últimas {hours} de horas",
"other": "Noticias de las últimas {hours} horas"
},
"Last {hours} h": {
"one": "Última {hours} h",
"many": "Últimas {hours} h",
"other": "Últimas {hours} h"
},
"News, last {hours} hours": "Noticias desde hace {hours} h",
"Last {hours} h": "Desde hace {hours} h",
"Time window": "Periodo",
"Conflicts": "Conflictos",
"Local": "Local",
@@ -86,17 +78,9 @@
"Hotspots": "Focos",
"Severity": "Gravedad",
"Category": "Categoría",
"Nothing reported near here in the last {hours} h": {
"one": "No hay noticias cerca de aquí en la última {hours} h",
"many": "No hay noticias cerca de aquí en las últimas {hours} h",
"other": "No hay noticias cerca de aquí en las últimas {hours} h"
},
"Nothing reported near here in the last {hours} h": "No hay noticias cerca de aquí desde hace {hours} h",
"Latest news": "Últimas noticias",
"No news matches these filters in the last {hours} h": {
"one": "En la última {hours} h no hay noticias que coincidan con estos filtros",
"many": "En las últimas {hours} h no hay noticias que coincidan con estos filtros",
"other": "En las últimas {hours} h no hay noticias que coincidan con estos filtros"
},
"No news matches these filters in the last {hours} h": "Desde hace {hours} h no hay noticias que coincidan con estos filtros",
"Load older news": "Cargar noticias anteriores",
"How to read the map": "Cómo leer el mapa",
"Colour: severity · icon: type of event": "Color: gravedad · icono: tipo de suceso",
@@ -155,11 +139,7 @@
"ALTITUDE": "ALTITUD",
"CONTACT": "CONTACTO",
"CONTACTS · 250 KM": "CONTACTOS · 250 KM",
"RINGS {spacing} NM": {
"one": "ANILLOS {spacing} MN",
"many": "ANILLOS {spacing} MN",
"other": "ANILLOS {spacing} MN"
},
"RINGS {spacing} NM": "ANILLOS {spacing} MN",
"{count} CONTACTS": {
"one": "{count} CONTACTO",
"many": "{count} DE CONTACTOS",
@@ -286,11 +266,7 @@
"ROUTE DATA UNAVAILABLE": "DATOS DE RUTA NO DISPONIBLES",
"CONTACT NAVIGATION OFF": "NAVEGACIÓN DE CONTACTOS DESACTIVADA",
"THE BRIDGE STAYS WITH THE SELECTED VESSEL": "EL PUENTE PERMANECE EN EL BUQUE SELECCIONADO",
"{range} NM": {
"one": "{range} MN",
"many": "{range} MN",
"other": "{range} MN"
},
"{range} NM": "{range} MN",
"AIS DESTINATION · CREW REPORTED": "DESTINO AIS · NOTIFICADO POR LA TRIPULACIÓN",
"FROM": "DESDE",
"TO": "HACIA",
@@ -376,7 +352,6 @@
"Current style: {style} — click for next": "Estilo actual: {style} — haz clic para el siguiente",
"TRACK ACQUIRED": "RASTREO ADQUIRIDO",
"{label} · COURSE {heading}°": "{label} · RUMBO {heading}°",
"vessel|{label} · COURSE {heading}°": "{label} · RUMBO {heading}°",
"{label} · HEADING {heading}°": "{label} · PROA {heading}°",
"{label} · NO HEADING": "{label} · PROA N/D",
"{label} · NADIR VIEW": "{label} · VISTA AL NADIR",
@@ -571,7 +546,6 @@
"NEAREST": "MÁS CERCANA",
"CCTV camera": "Cámara CCTV",
"FOCUS": "ENFOCAR",
"site status|FOCUS": "ENFOCADO",
"COVERAGE OFF": "COBERTURA DESACTIVADA",
"AUTO HOP OFF": "SALTO AUTO: NO",
"PROJECTION ON": "PROYECCIÓN ACTIVADA",
@@ -925,7 +899,6 @@
"awaiting first AIS message…": "esperando el primer mensaje AIS…",
"EST. DOWNRANGE": "DIST. ESTIMADA",
"CONFIRMED": "CONFIRMADA",
"sightings filter|CONFIRMED": "CONFIRMADAS",
"PAD / RTLS": "PLATAFORMA / RTLS",
"MISSION CONTROL · FIRST LAUNCH": "CENTRO DE MANDO · PRIMER INICIO",
"Choose your first view": "Elige tu primera vista",
@@ -1696,7 +1669,6 @@
"Observed history": "Historial observado",
"Later observation": "Observación posterior",
"Latest": "Último",
"news list|Latest": "Últimas",
"Newest frame per product": "Fotograma más reciente por producto",
"Replay observed history": "Reproducir el historial observado",
"S on another day replaces it · × unpins": "S en otro día lo reemplaza · × quita la fijación",
@@ -3501,11 +3473,7 @@
"Photo of {name}": "Foto de {name}",
"Acartia": "Acartia",
"CC BY 4.0": "CC BY 4.0",
"{count} sightings in view": {
"one": "{count} avistamiento a la vista",
"many": "{count} de avistamientos a la vista",
"other": "{count} avistamientos a la vista"
},
"{count} sightings in view": "Avistamientos a la vista: {count}",
"Close sighting": "Cerrar avistamiento",
"Wildlife observed within 48 h (whales 7 d). Color and badge glyph show the taxon group. Sensitive species are shown only as 0.2° cells; Salish Sea marine mammal reports via Acartia are rounded to 0.01°. Not a census.": "Fauna y flora observadas en las últimas 48 h (cetáceos 7 días). El color y el símbolo de la insignia indican el grupo taxonómico. Las especies sensibles solo se muestran en celdas de 0,2°; los informes de mamíferos marinos de Acartia en el mar de Salish se redondean a 0,01°. No es un censo.",
"Open {name} on iNaturalist": "Abrir {name} en iNaturalist",
@@ -3516,31 +3484,20 @@
"{days}d": "{days} d",
"All markers": "Todos los marcadores",
"Show markers of every age": "Mostrar marcadores de cualquier antigüedad",
"Maximum event age: {days}d; undated markers are kept": {
"one": "Antigüedad máxima: {days} día; se conservan los marcadores sin fecha",
"many": "Antigüedad máxima: {days} de días; se conservan los marcadores sin fecha",
"other": "Antigüedad máxima: {days} días; se conservan los marcadores sin fecha"
},
"Maximum event age: {days}d; undated markers are kept": "Antigüedad máxima: {days} d; se conservan los marcadores sin fecha",
"event age filter|All": "Todos",
"Event age": "Antigüedad",
"Event age: {days}d · undated kept": {
"one": "Antigüedad: {days} día · se conservan los marcadores sin fecha",
"many": "Antigüedad: {days} de días · se conservan los marcadores sin fecha",
"other": "Antigüedad: {days} días · se conservan los marcadores sin fecha"
},
"Event age: {days}d · undated kept": "Antigüedad: {days} d · se conservan los marcadores sin fecha",
"Close camera preview": "Cerrar vista previa de la cámara",
"Refresh map still": "Actualizar imagen fija del mapa",
"The map still uses a separate request and may show a different moment.": "La imagen del mapa usa una solicitud independiente y puede mostrar otro momento.",
"Video plays from Québec 511, which sees your IP address.": "El vídeo se reproduce desde Québec 511, que ve tu dirección IP.",
"Press OPEN to load the photo": "Pulsa ABRIR para cargar la foto",
"Captured {month}": "Capturada en {month}",
"this spot": "este punto",
"the view centre": "el centro de la vista",
"{source} at {place}": "{source} en {place}",
"{source} at this spot": "{source} en este punto",
"{source} at the view centre": "{source} en el centro de la vista",
"Street level at {place}": "A pie de calle en {place}",
"Street level at this spot": "A pie de calle en este punto",
"Street level at the view centre": "A pie de calle en el centro de la vista",
"Switching map": "Cambiando de mapa",
"Opening imagery": "Abriendo imágenes",
"Street View is ready: press {open} to load it": "Street View está listo: pulsa {open} para cargarlo",
@@ -3632,7 +3589,6 @@
"{source} imagery could not be opened": "No se pudieron abrir las imágenes de {source}",
"{place} has no position to look for imagery at": "{place} no tiene una posición donde buscar imágenes",
"No {source} imagery near {place}": "No hay imágenes de {source} cerca de {place}",
"No {source} imagery near the view centre": "No hay imágenes de {source} cerca del centro de la vista",
"{reason} (filters on: {filters})": "{reason} (filtros activos: {filters})",
"tiles unavailable": "teselas no disponibles",
"Environment": "Medio ambiente",
@@ -3715,11 +3671,7 @@
"switch on a dataset to load features": "activa un conjunto de datos para cargar elementos",
"Data Library at a glance": "La biblioteca de datos de un vistazo",
"Map features": "Elementos del mapa",
"Showing {shown} of {total}": {
"one": "Mostrando {shown} de {total}",
"many": "Mostrando {shown} de {total}",
"other": "Mostrando {shown} de {total}"
},
"Showing {shown} of {total}": "Mostrando {shown} de {total}",
"Datasets": "Conjuntos de datos",
"Themes": "Temas",
"zoom in to load this layer": "acércate para cargar esta capa",
+11 -59
View File
@@ -68,16 +68,8 @@
"{severity} only": "{severity} uniquement",
"All categories": "Toutes les catégories",
"Reading the news…": "Lecture des actualités…",
"News, last {hours} hours": {
"one": "Actualités de la dernière {hours} heure",
"many": "Actualités des dernières {hours} d'heures",
"other": "Actualités des dernières {hours} heures"
},
"Last {hours} h": {
"one": "Dernière {hours} h",
"many": "Dernières {hours} h",
"other": "Dernières {hours} h"
},
"News, last {hours} hours": "Actualités sur {hours} h",
"Last {hours} h": "Sur {hours} h",
"Time window": "Période",
"Conflicts": "Conflits",
"Local": "Local",
@@ -86,17 +78,9 @@
"Hotspots": "Foyers",
"Severity": "Gravité",
"Category": "Catégorie",
"Nothing reported near here in the last {hours} h": {
"one": "Rien de signalé près d'ici cette dernière {hours} h",
"many": "Rien de signalé près d'ici ces dernières {hours} h",
"other": "Rien de signalé près d'ici ces dernières {hours} h"
},
"Nothing reported near here in the last {hours} h": "Rien de signalé près d'ici en {hours} h",
"Latest news": "Dernières actualités",
"No news matches these filters in the last {hours} h": {
"one": "Aucune actualité de la dernière {hours} h ne correspond à ces filtres",
"many": "Aucune actualité des dernières {hours} h ne correspond à ces filtres",
"other": "Aucune actualité des dernières {hours} h ne correspond à ces filtres"
},
"No news matches these filters in the last {hours} h": "Aucune actualité ne correspond à ces filtres sur {hours} h",
"Load older news": "Charger des actualités plus anciennes",
"How to read the map": "Comment lire la carte",
"Colour: severity · icon: type of event": "Couleur : gravité · icône : type d'événement",
@@ -600,7 +584,6 @@
"Previous — prior visited contact in the 250 km window": "Précédent — contact visité précédemment dans la fenêtre de 250 km",
"PREVIOUS": "PRÉC.",
"FOCUS": "CENTRER",
"site status|FOCUS": "VISÉ",
"Next — nearest unvisited contact in the 250 km window": "Suivant — contact non visité le plus proche dans la fenêtre de 250 km",
"NEXT": "SUIV.",
"Named areas ({n})": "Zones nommées ({n})",
@@ -1849,11 +1832,7 @@
"ROUTE DATA UNAVAILABLE": "DONNÉES DE ROUTE INDISPONIBLES",
"CONTACT NAVIGATION OFF": "NAVIGATION DES CONTACTS DÉSACTIVÉE",
"THE BRIDGE STAYS WITH THE SELECTED VESSEL": "LA PASSERELLE RESTE SUR LE NAVIRE SÉLECTIONNÉ",
"{range} NM": {
"one": "{range} NM",
"many": "{range} NM",
"other": "{range} NM"
},
"{range} NM": "{range} NM",
"AIS DESTINATION · CREW REPORTED": "DESTINATION AIS · DÉCLARÉE PAR L'ÉQUIPAGE",
"DEST {bearing}": "DEST {bearing}",
"Disable cockpit weather effects": "Désactiver les effets météo du cockpit",
@@ -1901,7 +1880,6 @@
"Reclassify as TR-3B": "Reclasser en TR-3B",
"TRACK ACQUIRED": "PISTE ACQUISE",
"{label} · COURSE {heading}°": "{label} · ROUTE {heading}°",
"vessel|{label} · COURSE {heading}°": "{label} · ROUTE {heading}°",
"{label} · HEADING {heading}°": "{label} · CAP {heading}°",
"{label} · NO HEADING": "{label} · SANS CAP",
"{label} · NADIR VIEW": "{label} · VUE AU NADIR",
@@ -2174,7 +2152,6 @@
"Observed history": "Historique des observations",
"Later observation": "Observation suivante",
"Latest": "Dernière",
"news list|Latest": "Dernières",
"Newest frame per product": "Image la plus récente par produit",
"Replay observed history": "Rejouer l'historique des observations",
"Imagery on Esri · Google 3D returns when cleared": "Sur Esri · EFFACER rétablit Google 3D",
@@ -2903,11 +2880,7 @@
"Contact cockpit summary": "Résumé cockpit du contact",
"CONTACT": "CONTACT",
"CONTACTS · 250 KM": "CONTACTS · 250 KM",
"RINGS {spacing} NM": {
"one": "CERCLES {spacing} NM",
"many": "CERCLES {spacing} NM",
"other": "CERCLES {spacing} NM"
},
"RINGS {spacing} NM": "CERCLES {spacing} NM",
"{count} CONTACTS": {
"one": "{count} CONTACT",
"many": "{count} DE CONTACTS",
@@ -3234,7 +3207,6 @@
"Left panels": "Panneaux de gauche",
"Right panels": "Panneaux de droite",
"CONFIRMED": "CONFIRMÉE",
"sightings filter|CONFIRMED": "CONFIRMÉES",
"PAD / RTLS": "PAS DE TIR / RTLS",
"fire confidence filter|All": "Toutes",
"fire confidence filter|Nominal+": "Nominale+",
@@ -3501,11 +3473,7 @@
"Photo of {name}": "Photo : {name}",
"Acartia": "Acartia",
"CC BY 4.0": "CC BY 4.0",
"{count} sightings in view": {
"one": "{count} observation dans la vue",
"many": "{count} d'observations dans la vue",
"other": "{count} observations dans la vue"
},
"{count} sightings in view": "Observations dans la vue : {count}",
"Close sighting": "Fermer l'observation",
"Wildlife observed within 48 h (whales 7 d). Color and badge glyph show the taxon group. Sensitive species are shown only as 0.2° cells; Salish Sea marine mammal reports via Acartia are rounded to 0.01°. Not a census.": "Faune observée au cours des dernières 48 h (cétacés 7 jours). La couleur et le pictogramme du badge indiquent le groupe taxonomique. Les espèces sensibles sont limitées à des cellules de 0,2° ; les signalements de mammifères marins en mer des Salish provenant d'Acartia sont arrondis à 0,01°. Pas un recensement.",
"Open {name} on iNaturalist": "Ouvrir {name} sur iNaturalist",
@@ -3516,31 +3484,20 @@
"{days}d": "{days} j",
"All markers": "Tous les marqueurs",
"Show markers of every age": "Afficher les marqueurs de tout âge",
"Maximum event age: {days}d; undated markers are kept": {
"one": "Ancienneté maximale : {days} j ; marqueurs sans date conservés",
"many": "Ancienneté maximale : {days} j ; marqueurs sans date conservés",
"other": "Ancienneté maximale : {days} j ; marqueurs sans date conservés"
},
"Maximum event age: {days}d; undated markers are kept": "Ancienneté maximale : {days} j ; marqueurs sans date conservés",
"event age filter|All": "Tous",
"Event age": "Ancienneté",
"Event age: {days}d · undated kept": {
"one": "Ancienneté : {days} j · marqueurs sans date conservés",
"many": "Ancienneté : {days} j · marqueurs sans date conservés",
"other": "Ancienneté : {days} j · marqueurs sans date conservés"
},
"Event age: {days}d · undated kept": "Ancienneté : {days} j · marqueurs sans date conservés",
"Close camera preview": "Fermer l'aperçu de la caméra",
"Refresh map still": "Actualiser l'image fixe sur la carte",
"The map still uses a separate request and may show a different moment.": "L'image fixe de la carte utilise une requête distincte et peut montrer un autre moment.",
"Video plays from Québec 511, which sees your IP address.": "La vidéo est lue depuis Québec 511, qui voit votre adresse IP.",
"Press OPEN to load the photo": "Appuyez sur OUVRIR pour charger la photo",
"Captured {month}": "Prise en {month}",
"this spot": "cet endroit",
"the view centre": "le centre de la vue",
"{source} at {place}": "{source} : {place}",
"{source} at this spot": "{source} à cet endroit",
"{source} at the view centre": "{source} au centre de la vue",
"Street level at {place}": "Niveau rue : {place}",
"Street level at this spot": "Niveau rue à cet endroit",
"Street level at the view centre": "Niveau rue au centre de la vue",
"Switching map": "Changement de carte",
"Opening imagery": "Ouverture des images",
"Street View is ready: press {open} to load it": "Street View est prêt : appuyez sur {open} pour le charger",
@@ -3632,7 +3589,6 @@
"{source} imagery could not be opened": "Impossible d'ouvrir les images de {source}",
"{place} has no position to look for imagery at": "{place} n'a pas de position où chercher des images",
"No {source} imagery near {place}": "Aucune image {source} près de {place}",
"No {source} imagery near the view centre": "Aucune image {source} près du centre de la vue",
"{reason} (filters on: {filters})": "{reason} (filtres actifs : {filters})",
"tiles unavailable": "tuiles indisponibles",
"zoom in to load this layer": "zoomez pour charger cette couche",
@@ -3735,10 +3691,6 @@
"REMOVE ALL": "TOUT RETIRER",
"Confirm: remove every added entry from Data Layers": "Confirmer : retirer du panneau Couches toutes les entrées ajoutées",
"Remove every added entry from Data Layers": "Retirer du panneau Couches toutes les entrées ajoutées",
"Showing {shown} of {total}": {
"one": "{shown} sur {total} affichée",
"many": "{shown} sur {total} affichées",
"other": "{shown} sur {total} affichées"
},
"Showing {shown} of {total}": "Affichées : {shown} sur {total}",
"BROWSE DATA LIBRARY": "PARCOURIR LA BIBLIOTHÈQUE DE DONNÉES"
}
+11 -59
View File
@@ -478,7 +478,6 @@
"PREVIOUS": "הקודם",
"Previous — prior visited contact in the 250 km window": "הקודם — מגע שכבר ביקרת בו בחלון של 250 ק\"מ",
"FOCUS": "התמקד",
"site status|FOCUS": "במוקד",
"NEXT": "הבא",
"Next — nearest unvisited contact in the 250 km window": "הבא — המגע הקרוב ביותר שלא ביקרת בו בחלון של 250 ק\"מ",
"Named areas ({n})": "אזורים בעלי שם ({n})",
@@ -833,7 +832,6 @@
"ORBIT REPLAY · {mission}": "שחזור מסלול · {mission}",
"PAUSED · {title}": "מושהה · {title}",
"CONFIRMED": "מאושר",
"sightings filter|CONFIRMED": "מאושרות",
"PAD / RTLS": "כן שיגור / RTLS",
"UNSPECIFIED": "לא צוין",
"{value} KM DOWNRANGE": "{value} ק\"מ לאורך המסלול",
@@ -1270,11 +1268,7 @@
"Wildlife observed within 48 h (whales 7 d). Color and badge glyph show the taxon group. Sensitive species are shown only as 0.2° cells; Salish Sea marine mammal reports via Acartia are rounded to 0.01°. Not a census.": "חיות בר נצפו ב-48 השעות האחרונות (לווייתנים · 7 ימים). הצבע וגליף התג מציגים את קבוצת הטקסון. מינים רגישים מוצגים כתאי 0.2° בלבד; דיווחי יונקי הים של Salish Sea דרך Acartia מעוגלים ל-0.01°. אינו מפקד אוכלוסין.",
"iNaturalist contributors · Acartia {count} (Salish Sea) · licences per record": "תורמי iNaturalist · Acartia {count} (Salish Sea) · רישיונות לכל רשומה",
"iNaturalist contributors · licences per record": "תורמי iNaturalist · רישיונות לכל רשומה",
"{count} sightings in view": {
"one": "{count} תצפית בתצוגה",
"two": "{count} תצפיות בתצוגה",
"other": "{count} תצפיות בתצוגה"
},
"{count} sightings in view": "{count} תצפיות בתצוגה",
"Zoom in for local sightings": "התקרב לתצפיות מקומיות",
"No recent sightings in view": "אין תצפיות אחרונות בתצוגה",
"Acartia feed unavailable": "פיד Acartia אינו זמין",
@@ -1743,7 +1737,6 @@
"SOURCE STATUS UNAVAILABLE": "מצב המקור אינו זמין",
"TRACK ACQUIRED": "המעקב ננעל",
"{label} · COURSE {heading}°": "{label} · מהלך {heading}°",
"vessel|{label} · COURSE {heading}°": "{label} · מהלך {heading}°",
"Context could not restore every layer; try again": "ההקשר לא שיחזר את כל השכבות; נסה שוב",
"No selected data layers": "אין שכבות נתונים נבחרות",
"{count} data layers could not be cleared": {
@@ -2005,7 +1998,6 @@
"Later observation": "תצפית מאוחרת",
"Newest frame per product": "השקופית החדשה לכל מוצר",
"Latest": "האחרונה",
"news list|Latest": "האחרונות",
"Replay observed history": "הצגת ההיסטוריה הנצפית שוב",
"Imagery on Esri · Google 3D returns when cleared": "צילומים ב-Esri · Google 3D חוזר כשמנקים",
"Point the camera at the ground to use the view": "כוון את המצלמה אל הקרקע כדי להשתמש בתצוגה",
@@ -3246,17 +3238,9 @@
"event age filter|All": "הכול",
"{days}d": "{days} ימ׳",
"Show markers of every age": "הצגת סמנים בכל גיל",
"Maximum event age: {days}d; undated markers are kept": {
"one": "גיל אירוע מרבי: {days} יום; סמנים ללא תאריך נשמרים",
"two": "גיל אירוע מרבי: {days} ימים; סמנים ללא תאריך נשמרים",
"other": "גיל אירוע מרבי: {days} ימים; סמנים ללא תאריך נשמרים"
},
"Maximum event age: {days}d; undated markers are kept": "גיל אירוע מרבי: {days} ימ׳; סמנים ללא תאריך נשמרים",
"All markers": "כל הסמנים",
"Event age: {days}d · undated kept": {
"one": "גיל האירוע: {days} יום · ללא תאריך נשמרים",
"two": "גיל האירוע: {days} ימים · ללא תאריך נשמרים",
"other": "גיל האירוע: {days} ימים · ללא תאריך נשמרים"
},
"Event age: {days}d · undated kept": "גיל האירוע: {days} ימ׳ · ללא תאריך נשמרים",
"30-DAY MISSION INDEX UNAVAILABLE": "רשימת המשימות ל-30 יום אינה זמינה",
"STATIONS": "תחנות",
"Crewed stations and the craft that visit them": "תחנות מאוישות והחלליות המבקרות בהן",
@@ -3292,11 +3276,7 @@
"LIVE AIS": "AIS חי",
"CONTACT NAVIGATION OFF": "ניווט המגעים כבוי",
"THE BRIDGE STAYS WITH THE SELECTED VESSEL": "הגשר נשאר עם האונייה הנבחרת",
"{range} NM": {
"one": "{range} NM",
"two": "{range} NM",
"other": "{range} NM"
},
"{range} NM": "{range} NM",
"AIS DESTINATION · CREW REPORTED": "יעד AIS · דווח על ידי הצוות",
"FWD": "קדימה",
"AFT": "אחורה",
@@ -3315,13 +3295,10 @@
"Video plays from Québec 511, which sees your IP address.": "הווידאו זורם מ-Québec 511, שרואה את כתובת ה-IP שלך.",
"Press OPEN to load the photo": "לחץ על \"פתח\" כדי לטעון את התמונה",
"Captured {month}": "צולם ב-{month}",
"this spot": "המקום הזה",
"the view centre": "מרכז התצוגה",
"{source} at {place}": "{source}: {place}",
"{source} at this spot": "{source} במקום הזה",
"{source} at the view centre": "{source} במרכז התצוגה",
"Street level at {place}": "צילומי רחוב: {place}",
"Street level at this spot": "צילומי רחוב במקום הזה",
"Street level at the view centre": "צילומי רחוב במרכז התצוגה",
"Switching map": "מחליף מפה",
"Opening imagery": "פותח צילומים",
"Street View is ready: press {open} to load it": "Street View מוכן: לחץ על \"{open}\" כדי לטעון אותו",
@@ -3381,11 +3358,7 @@
"Zoom in (+)": "התקרבות (+)",
"Zoom to the imaging sensor swath": "זום אל רצועת הסריקה של חיישן הצילום",
"SENSOR": "חיישן",
"RINGS {spacing} NM": {
"one": "טבעות {spacing} NM",
"two": "טבעות {spacing} NM",
"other": "טבעות {spacing} NM"
},
"RINGS {spacing} NM": "טבעות {spacing} NM",
"{count} CONTACTS": {
"one": "{count} מגע",
"two": "{count} מגעים",
@@ -3531,36 +3504,20 @@
"{severity} and above": "{severity} ומעלה",
"{severity} only": "{severity} בלבד",
"All categories": "כל הקטגוריות",
"Last {hours} h": {
"one": "השעה האחרונה ({hours})",
"two": "{hours} שע׳ אחרונות",
"other": "{hours} שע׳ אחרונות"
},
"Last {hours} h": "{hours} שע׳ אחורה",
"News from {area}": "חדשות מ-{area}",
"Within {km} km of the view centre": "בטווח {km} ק\"מ ממרכז התצוגה",
"Reading the news…": "קורא את החדשות…",
"News, last {hours} hours": {
"one": "חדשות, השעה האחרונה ({hours})",
"two": "חדשות, {hours} השעות האחרונות",
"other": "חדשות, {hours} השעות האחרונות"
},
"News, last {hours} hours": "חדשות, {hours} שע׳ אחורה",
"Time window": "חלון זמן",
"News sections": "מדורי חדשות",
"Hotspots": "מוקדים",
"Severity": "חומרה",
"Category": "קטגוריה",
"Zoom in to see local news": "התקרב כדי לראות חדשות מקומיות",
"Nothing reported near here in the last {hours} h": {
"one": "לא דווח דבר בסביבה בשעה האחרונה ({hours})",
"two": "לא דווח דבר בסביבה ב־{hours} השעות האחרונות",
"other": "לא דווח דבר בסביבה ב־{hours} השעות האחרונות"
},
"Nothing reported near here in the last {hours} h": "לא דווח דבר בסביבה בחלון של {hours} שע׳",
"Latest news": "חדשות אחרונות",
"No news matches these filters in the last {hours} h": {
"one": "אין חדשות התואמות למסננים אלה בשעה האחרונה ({hours})",
"two": "אין חדשות התואמות למסננים אלה ב־{hours} השעות האחרונות",
"other": "אין חדשות התואמות למסננים אלה ב־{hours} השעות האחרונות"
},
"No news matches these filters in the last {hours} h": "אין חדשות התואמות למסננים אלה בחלון של {hours} שע׳",
"Load older news": "טעינת חדשות ישנות יותר",
"How to read the map": "איך לקרוא את המפה",
"Colour: severity · icon: type of event": "צבע: חומרה · סמל: סוג האירוע",
@@ -3632,7 +3589,6 @@
"{source} imagery could not be opened": "לא ניתן היה לפתוח את הצילומים של {source}",
"{place} has no position to look for imagery at": "ל-{place} אין מיקום לחיפוש צילומים",
"No {source} imagery near {place}": "אין צילומים של {source} ליד {place}",
"No {source} imagery near the view centre": "אין צילומים של {source} ליד מרכז התצוגה",
"{reason} (filters on: {filters})": "{reason} (מסננים פעילים: {filters})",
"tiles unavailable": "האריחים אינם זמינים",
"zoom in to load this layer": "התקרב כדי לטעון את השכבה הזאת",
@@ -3735,10 +3691,6 @@
"REMOVE ALL": "הסרת הכול",
"Confirm: remove every added entry from Data Layers": "אישור: הסרת כל הפריטים שנוספו משכבות נתונים",
"Remove every added entry from Data Layers": "הסרת כל הפריטים שנוספו משכבות נתונים",
"Showing {shown} of {total}": {
"one": "מוצג {shown} מתוך {total}",
"two": "מוצגים {shown} מתוך {total}",
"other": "מוצגים {shown} מתוך {total}"
},
"Showing {shown} of {total}": "מוצגים {shown} מתוך {total}",
"BROWSE DATA LIBRARY": "עיון בספריית הנתונים"
}
+12 -60
View File
@@ -68,16 +68,8 @@
"{severity} only": "Solo {severity}",
"All categories": "Tutte le categorie",
"Reading the news…": "Lettura delle notizie…",
"News, last {hours} hours": {
"one": "Notizie dell'ultima {hours} ora",
"many": "Notizie delle ultime {hours} di ore",
"other": "Notizie delle ultime {hours} ore"
},
"Last {hours} h": {
"one": "Ultima {hours} h",
"many": "Ultime {hours} h",
"other": "Ultime {hours} h"
},
"News, last {hours} hours": "Notizie, periodo in ore: {hours}",
"Last {hours} h": "Periodo: {hours} h",
"Time window": "Periodo",
"Conflicts": "Conflitti",
"Local": "Locale",
@@ -86,17 +78,9 @@
"Hotspots": "Focolai",
"Severity": "Gravità",
"Category": "Categoria",
"Nothing reported near here in the last {hours} h": {
"one": "Nessuna segnalazione qui vicino nell'ultima {hours} h",
"many": "Nessuna segnalazione qui vicino nelle ultime {hours} h",
"other": "Nessuna segnalazione qui vicino nelle ultime {hours} h"
},
"Nothing reported near here in the last {hours} h": "Nessuna segnalazione qui vicino · periodo: {hours} h",
"Latest news": "Ultime notizie",
"No news matches these filters in the last {hours} h": {
"one": "Nessuna notizia dell'ultima {hours} h corrisponde a questi filtri",
"many": "Nessuna notizia delle ultime {hours} h corrisponde a questi filtri",
"other": "Nessuna notizia delle ultime {hours} h corrisponde a questi filtri"
},
"No news matches these filters in the last {hours} h": "Nessuna notizia corrisponde a questi filtri · periodo: {hours} h",
"Load older news": "Carica notizie precedenti",
"How to read the map": "Come leggere la mappa",
"Colour: severity · icon: type of event": "Colore: gravità · icona: tipo di evento",
@@ -600,7 +584,6 @@
"Previous — prior visited contact in the 250 km window": "Precedente — contatto visitato in precedenza nella finestra di 250 km",
"PREVIOUS": "PREC",
"FOCUS": "FOCUS",
"site status|FOCUS": "FOCUS",
"Next — nearest unvisited contact in the 250 km window": "Successivo — contatto non visitato più vicino nella finestra di 250 km",
"NEXT": "SUCC",
"Named areas ({n})": "Aree con nome ({n})",
@@ -958,7 +941,7 @@
"ORBITAL VELOCITY": "VELOCITÀ ORBITALE",
"SUB-SATELLITE POINT": "PUNTO SUBSATELLITARE",
"NORTH UP": "NORD IN ALTO",
"CURRENTLY OVER": "SOTTO IL SATELLITE",
"CURRENTLY OVER": "ATTUALMENTE SOPRA",
"{division}, {country}": "{division}, {country}",
"{region} · near {place}": "{region} · vicino a {place}",
"NORAD {id}": "NORAD {id}",
@@ -1849,11 +1832,7 @@
"ROUTE DATA UNAVAILABLE": "DATI ROTTA NON DISPONIBILI",
"CONTACT NAVIGATION OFF": "NAVIGAZIONE CONTATTI DISATTIVATA",
"THE BRIDGE STAYS WITH THE SELECTED VESSEL": "LA PLANCIA RESTA SULLA NAVE SELEZIONATA",
"{range} NM": {
"one": "{range} MN",
"many": "{range} MN",
"other": "{range} MN"
},
"{range} NM": "{range} MN",
"AIS DESTINATION · CREW REPORTED": "DESTINAZIONE AIS · DICHIARATA DALL'EQUIPAGGIO",
"DEST {bearing}": "DEST {bearing}",
"Disable cockpit weather effects": "Disattiva gli effetti meteo del cockpit",
@@ -1901,7 +1880,6 @@
"Reclassify as TR-3B": "Riclassifica come TR-3B",
"TRACK ACQUIRED": "TRACCIA ACQUISITA",
"{label} · COURSE {heading}°": "{label} · ROTTA {heading}°",
"vessel|{label} · COURSE {heading}°": "{label} · ROTTA {heading}°",
"{label} · HEADING {heading}°": "{label} · PRUA {heading}°",
"{label} · NO HEADING": "{label} · PRUA N/D",
"{label} · NADIR VIEW": "{label} · VISTA AL NADIR",
@@ -2174,7 +2152,6 @@
"Observed history": "Storico osservato",
"Later observation": "Osservazione successiva",
"Latest": "Più recente",
"news list|Latest": "Più recenti",
"Newest frame per product": "Fotogramma più recente per prodotto",
"Replay observed history": "Rivedi lo storico osservato",
"Imagery on Esri · Google 3D returns when cleared": "Immagini su Esri · Google 3D torna con CANCELLA",
@@ -2903,11 +2880,7 @@
"Contact cockpit summary": "Riepilogo contatto del cockpit",
"CONTACT": "CONTATTO",
"CONTACTS · 250 KM": "CONTATTI · 250 KM",
"RINGS {spacing} NM": {
"one": "CERCHI {spacing} MN",
"many": "CERCHI {spacing} MN",
"other": "CERCHI {spacing} MN"
},
"RINGS {spacing} NM": "CERCHI {spacing} MN",
"{count} CONTACTS": {
"one": "{count} CONTATTO",
"many": "{count} DI CONTATTI",
@@ -3234,7 +3207,6 @@
"Left panels": "Pannelli a sinistra",
"Right panels": "Pannelli a destra",
"CONFIRMED": "CONFERMATA",
"sightings filter|CONFIRMED": "CONFERMATE",
"PAD / RTLS": "RAMPA / RTLS",
"fire confidence filter|All": "Tutti",
"fire confidence filter|Nominal+": "Nominale+",
@@ -3501,11 +3473,7 @@
"Photo of {name}": "Foto di {name}",
"Acartia": "Acartia",
"CC BY 4.0": "CC BY 4.0",
"{count} sightings in view": {
"one": "{count} avvistamento nella vista",
"many": "{count} di avvistamenti nella vista",
"other": "{count} avvistamenti nella vista"
},
"{count} sightings in view": "Avvistamenti nella vista: {count}",
"Close sighting": "Chiudi avvistamento",
"Wildlife observed within 48 h (whales 7 d). Color and badge glyph show the taxon group. Sensitive species are shown only as 0.2° cells; Salish Sea marine mammal reports via Acartia are rounded to 0.01°. Not a census.": "Fauna osservata nelle ultime 48 h (cetacei 7 giorni). Colore e simbolo del contrassegno indicano il gruppo tassonomico. Le specie sensibili sono mostrate solo in celle di 0,2°; le segnalazioni di mammiferi marini di Acartia nel mar dei Salish sono arrotondate a 0,01°. Non è un censimento.",
"Open {name} on iNaturalist": "Apri {name} su iNaturalist",
@@ -3516,31 +3484,20 @@
"{days}d": "{days} g",
"All markers": "Tutti i marcatori",
"Show markers of every age": "Mostra i marcatori di qualsiasi età",
"Maximum event age: {days}d; undated markers are kept": {
"one": "Età massima degli eventi: {days} giorno; marcatori senza data mantenuti",
"many": "Età massima degli eventi: {days} di giorni; marcatori senza data mantenuti",
"other": "Età massima degli eventi: {days} giorni; marcatori senza data mantenuti"
},
"Maximum event age: {days}d; undated markers are kept": "Età massima degli eventi: {days} g; marcatori senza data mantenuti",
"event age filter|All": "Tutti",
"Event age": "Età degli eventi",
"Event age: {days}d · undated kept": {
"one": "Età degli eventi: {days} giorno · senza data mantenuti",
"many": "Età degli eventi: {days} di giorni · senza data mantenuti",
"other": "Età degli eventi: {days} giorni · senza data mantenuti"
},
"Event age: {days}d · undated kept": "Età degli eventi: {days} g · senza data mantenuti",
"Close camera preview": "Chiudi anteprima della telecamera",
"Refresh map still": "Aggiorna immagine fissa sulla mappa",
"The map still uses a separate request and may show a different moment.": "L'immagine sulla mappa usa una richiesta separata e può mostrare un momento diverso.",
"Video plays from Québec 511, which sees your IP address.": "Il video viene riprodotto da Québec 511, che vede il tuo indirizzo IP.",
"Press OPEN to load the photo": "Premi APRI per caricare la foto",
"Captured {month}": "Scattata: {month}",
"this spot": "questo punto",
"the view centre": "il centro della vista",
"{source} at {place}": "{source}: {place}",
"{source} at this spot": "{source} in questo punto",
"{source} at the view centre": "{source} al centro della vista",
"Street level at {place}": "Vista stradale: {place}",
"Street level at this spot": "Vista stradale in questo punto",
"Street level at the view centre": "Vista stradale al centro della vista",
"Switching map": "Cambio mappa",
"Opening imagery": "Apertura delle immagini",
"Street View is ready: press {open} to load it": "Street View è pronto: premi {open} per caricarlo",
@@ -3632,7 +3589,6 @@
"{source} imagery could not be opened": "Impossibile aprire le immagini di {source}",
"{place} has no position to look for imagery at": "{place} non ha una posizione in cui cercare immagini",
"No {source} imagery near {place}": "Nessuna immagine di {source} vicino a {place}",
"No {source} imagery near the view centre": "Nessuna immagine di {source} vicino al centro della vista",
"{reason} (filters on: {filters})": "{reason} (filtri attivi: {filters})",
"tiles unavailable": "tile non disponibili",
"zoom in to load this layer": "ingrandisci per caricare questo livello",
@@ -3735,10 +3691,6 @@
"REMOVE ALL": "RIMUOVI TUTTO",
"Confirm: remove every added entry from Data Layers": "Conferma: rimuovi da Livelli dati tutte le voci aggiunte",
"Remove every added entry from Data Layers": "Rimuovi da Livelli dati tutte le voci aggiunte",
"Showing {shown} of {total}": {
"one": "{shown} di {total} mostrata",
"many": "{shown} di {total} mostrate",
"other": "{shown} di {total} mostrate"
},
"Showing {shown} of {total}": "Mostrati: {shown} su {total}",
"BROWSE DATA LIBRARY": "ESPLORA LIBRERIA DATI"
}
+11 -39
View File
@@ -62,12 +62,8 @@
"{severity} only": "{severity}のみ",
"All categories": "すべてのカテゴリ",
"Reading the news…": "ニュースを読み込み中…",
"News, last {hours} hours": {
"other": "直近{hours}時間のニュース"
},
"Last {hours} h": {
"other": "直近{hours}時間"
},
"News, last {hours} hours": "直近{hours}時間のニュース",
"Last {hours} h": "直近{hours}時間",
"Time window": "期間",
"Conflicts": "紛争",
"Local": "ローカル",
@@ -76,13 +72,9 @@
"Hotspots": "ホットスポット",
"Severity": "深刻度",
"Category": "カテゴリ",
"Nothing reported near here in the last {hours} h": {
"other": "直近{hours}時間、この付近の報道はありません"
},
"Nothing reported near here in the last {hours} h": "直近{hours}時間、この付近の報道はありません",
"Latest news": "最新ニュース",
"No news matches these filters in the last {hours} h": {
"other": "直近{hours}時間で条件に合うニュースはありません"
},
"No news matches these filters in the last {hours} h": "直近{hours}時間で条件に合うニュースはありません",
"Load older news": "以前のニュースを読み込む",
"How to read the map": "地図の見方",
"Colour: severity · icon: type of event": "色:深刻度 · アイコン:出来事の種類",
@@ -572,7 +564,6 @@
"Previous — prior visited contact in the 250 km window": "前へ:250 km圏内で直前に訪れたコンタクト",
"PREVIOUS": "前へ",
"FOCUS": "フォーカス",
"site status|FOCUS": "フォーカス",
"Next — nearest unvisited contact in the 250 km window": "次へ:250 km圏内で最も近い未訪問のコンタクト",
"NEXT": "次へ",
"Named areas ({n})": "名前付きエリア({n})",
@@ -1785,9 +1776,7 @@
"ROUTE DATA UNAVAILABLE": "経路データなし",
"CONTACT NAVIGATION OFF": "コンタクトナビゲーション オフ",
"THE BRIDGE STAYS WITH THE SELECTED VESSEL": "ブリッジは選択中の船舶に固定",
"{range} NM": {
"other": "{range}海里"
},
"{range} NM": "{range}海里",
"AIS DESTINATION · CREW REPORTED": "AIS目的地 · 乗組員入力",
"DEST {bearing}": "目的地 {bearing}",
"Disable cockpit weather effects": "コックピットの天候エフェクトを無効にする",
@@ -1833,7 +1822,6 @@
"Reclassify as TR-3B": "TR-3Bに再分類",
"TRACK ACQUIRED": "追跡開始",
"{label} · COURSE {heading}°": "{label} · 対地針路 {heading}°",
"vessel|{label} · COURSE {heading}°": "{label} · 対地針路 {heading}°",
"{label} · HEADING {heading}°": "{label} · 船首方位 {heading}°",
"{label} · NO HEADING": "{label} · 船首方位なし",
"{label} · NADIR VIEW": "{label} · 直下視",
@@ -2090,7 +2078,6 @@
"Observed history": "観測履歴",
"Later observation": "次の観測",
"Latest": "最新",
"news list|Latest": "最新",
"Newest frame per product": "プロダクトごとの最新フレーム",
"Replay observed history": "観測履歴を再生",
"Imagery on Esri · Google 3D returns when cleared": "画像はEsri上に表示 · 消去するとGoogle 3Dに戻ります",
@@ -2743,9 +2730,7 @@
"Contact cockpit summary": "コンタクトのコックピット概要",
"CONTACT": "コンタクト",
"CONTACTS · 250 KM": "コンタクト · 250 km",
"RINGS {spacing} NM": {
"other": "距離環 {spacing}海里"
},
"RINGS {spacing} NM": "距離環 {spacing}海里",
"{count} CONTACTS": {
"other": "コンタクト {count}件"
},
@@ -3072,7 +3057,6 @@
"Left panels": "左パネル",
"Right panels": "右パネル",
"CONFIRMED": "確認済み",
"sightings filter|CONFIRMED": "確認済み",
"PAD / RTLS": "射場 / RTLS",
"fire confidence filter|All": "すべて",
"fire confidence filter|Nominal+": "中以上",
@@ -3327,9 +3311,7 @@
"Photo of {name}": "{name}の写真",
"Acartia": "Acartia",
"CC BY 4.0": "CC BY 4.0",
"{count} sightings in view": {
"other": "表示範囲に{count}件の目撃情報"
},
"{count} sightings in view": "表示範囲に{count}件の目撃情報",
"Close sighting": "目撃情報を閉じる",
"Wildlife observed within 48 h (whales 7 d). Color and badge glyph show the taxon group. Sensitive species are shown only as 0.2° cells; Salish Sea marine mammal reports via Acartia are rounded to 0.01°. Not a census.": "過去48時間以内に観察された野生生物(クジラ類は7日間)。色とバッジのアイコンは分類群を表します。保護が必要な種は0.2°のセルとしてのみ表示し、セイリッシュ海のAcartiaによる海生哺乳類の目撃情報は0.01°に丸めます。個体数調査ではありません。",
"Open {name} on iNaturalist": "iNaturalistで{name}を開く",
@@ -3340,27 +3322,20 @@
"{days}d": "{days}日",
"All markers": "すべてのマーカー",
"Show markers of every age": "日付にかかわらずすべてのマーカーを表示",
"Maximum event age: {days}d; undated markers are kept": {
"other": "イベントの最大経過日数:{days}日。日付のないマーカーは保持"
},
"Maximum event age: {days}d; undated markers are kept": "イベントの最大経過日数:{days}日。日付のないマーカーは保持",
"event age filter|All": "すべて",
"Event age": "経過日数",
"Event age: {days}d · undated kept": {
"other": "経過日数:{days}日以内 · 日付なしは保持"
},
"Event age: {days}d · undated kept": "経過日数:{days}日以内 · 日付なしは保持",
"Close camera preview": "カメラのプレビューを閉じる",
"Refresh map still": "地図上の静止画を更新",
"The map still uses a separate request and may show a different moment.": "地図上の静止画は別のリクエストで取得されるため、異なる時点を表示する場合があります。",
"Video plays from Québec 511, which sees your IP address.": "動画はQuébec 511から再生され、お使いのIPアドレスはQuébec 511側から見えます。",
"Press OPEN to load the photo": "[開く]を押して写真を読み込む",
"Captured {month}": "{month}撮影",
"this spot": "この地点",
"the view centre": "表示中心",
"{source} at {place}": "{place}の{source}",
"{source} at this spot": "この地点の{source}",
"{source} at the view centre": "表示中心の{source}",
"Street level at {place}": "{place}のストリートレベル",
"Street level at this spot": "この地点のストリートレベル",
"Street level at the view centre": "表示中心のストリートレベル",
"Switching map": "地図を切り替え中",
"Opening imagery": "画像を開いています",
"Street View is ready: press {open} to load it": "ストリートビューの準備ができました:[{open}]を押して読み込んでください",
@@ -3452,7 +3427,6 @@
"{source} imagery could not be opened": "{source}の画像を開けませんでした",
"{place} has no position to look for imagery at": "{place}には画像を探す位置がありません",
"No {source} imagery near {place}": "{place}の近くに{source}の画像はありません",
"No {source} imagery near the view centre": "表示中心の近くに{source}の画像はありません",
"{reason} (filters on: {filters})": "{reason}(有効なフィルター:{filters})",
"tiles unavailable": "タイルを利用できません",
"zoom in to load this layer": "ズームインしてこのレイヤーを読み込む",
@@ -3543,8 +3517,6 @@
"REMOVE ALL": "すべて削除",
"Confirm: remove every added entry from Data Layers": "確認:追加したすべての項目をデータレイヤーから削除",
"Remove every added entry from Data Layers": "追加したすべての項目をデータレイヤーから削除",
"Showing {shown} of {total}": {
"other": "{total}件中{shown}件を表示"
},
"Showing {shown} of {total}": "{total}件中{shown}件を表示",
"BROWSE DATA LIBRARY": "データライブラリを見る"
}
+13 -61
View File
@@ -68,16 +68,8 @@
"{severity} only": "Apenas {severity}",
"All categories": "Todas as categorias",
"Reading the news…": "Lendo as notícias…",
"News, last {hours} hours": {
"one": "Notícias da última {hours} hora",
"many": "Notícias das últimas {hours} de horas",
"other": "Notícias das últimas {hours} horas"
},
"Last {hours} h": {
"one": "Última {hours} h",
"many": "Últimas {hours} h",
"other": "Últimas {hours} h"
},
"News, last {hours} hours": "Notícias de até {hours} h atrás",
"Last {hours} h": "Até {hours} h atrás",
"Time window": "Período",
"Conflicts": "Conflitos",
"Local": "Local",
@@ -86,17 +78,9 @@
"Hotspots": "Focos",
"Severity": "Gravidade",
"Category": "Categoria",
"Nothing reported near here in the last {hours} h": {
"one": "Nada noticiado aqui perto na última {hours} h",
"many": "Nada noticiado aqui perto nas últimas {hours} h",
"other": "Nada noticiado aqui perto nas últimas {hours} h"
},
"Nothing reported near here in the last {hours} h": "Nada noticiado aqui perto desde {hours} h atrás",
"Latest news": "Últimas notícias",
"No news matches these filters in the last {hours} h": {
"one": "Nenhuma notícia da última {hours} h corresponde a estes filtros",
"many": "Nenhuma notícia das últimas {hours} h corresponde a estes filtros",
"other": "Nenhuma notícia das últimas {hours} h corresponde a estes filtros"
},
"No news matches these filters in the last {hours} h": "Nenhuma notícia de até {hours} h atrás corresponde a estes filtros",
"Load older news": "Carregar notícias anteriores",
"How to read the map": "Como ler o mapa",
"Colour: severity · icon: type of event": "Cor: gravidade · ícone: tipo de evento",
@@ -600,7 +584,6 @@
"Previous — prior visited contact in the 250 km window": "Anterior — contato visitado anteriormente na janela de 250 km",
"PREVIOUS": "ANT.",
"FOCUS": "FOCAR",
"site status|FOCUS": "EM FOCO",
"Next — nearest unvisited contact in the 250 km window": "Próximo — contato não visitado mais próximo na janela de 250 km",
"NEXT": "PRÓX.",
"Named areas ({n})": "Áreas com nome ({n})",
@@ -956,7 +939,7 @@
"ORBITAL VELOCITY": "VELOCIDADE ORBITAL",
"SUB-SATELLITE POINT": "PONTO SUBSATÉLITE",
"NORTH UP": "NORTE PARA CIMA",
"CURRENTLY OVER": "SOB O SATÉLITE",
"CURRENTLY OVER": "SOBREVOANDO AGORA",
"{division}, {country}": "{division}, {country}",
"{region} · near {place}": "{region} · perto de {place}",
"NORAD {id}": "NORAD {id}",
@@ -1849,11 +1832,7 @@
"ROUTE DATA UNAVAILABLE": "DADOS DE ROTA INDISPONÍVEIS",
"CONTACT NAVIGATION OFF": "NAVEGAÇÃO DE CONTATOS DESLIGADA",
"THE BRIDGE STAYS WITH THE SELECTED VESSEL": "O PASSADIÇO PERMANECE NA EMBARCAÇÃO SELECIONADA",
"{range} NM": {
"one": "{range} MN",
"many": "{range} MN",
"other": "{range} MN"
},
"{range} NM": "{range} MN",
"AIS DESTINATION · CREW REPORTED": "DESTINO AIS · INFORMADO PELA TRIPULAÇÃO",
"DEST {bearing}": "DEST {bearing}",
"Disable cockpit weather effects": "Desativar efeitos de clima na cabine",
@@ -1900,8 +1879,7 @@
"Restore real aircraft": "Restaurar a aeronave real",
"Reclassify as TR-3B": "Reclassificar como TR-3B",
"TRACK ACQUIRED": "RASTRO ADQUIRIDO",
"{label} · COURSE {heading}°": "{label} · CURSO {heading}°",
"vessel|{label} · COURSE {heading}°": "{label} · RUMO {heading}°",
"{label} · COURSE {heading}°": "{label} · RUMO {heading}°",
"{label} · HEADING {heading}°": "{label} · PROA {heading}°",
"{label} · NO HEADING": "{label} · SEM PROA",
"{label} · NADIR VIEW": "{label} · VISTA AO NADIR",
@@ -2174,7 +2152,6 @@
"Observed history": "Histórico observado",
"Later observation": "Observação posterior",
"Latest": "Mais recente",
"news list|Latest": "Mais recentes",
"Newest frame per product": "Quadro mais recente por produto",
"Replay observed history": "Reproduzir o histórico observado",
"Imagery on Esri · Google 3D returns when cleared": "Imagens sobre o Esri · LIMPAR restaura o Google 3D",
@@ -2905,11 +2882,7 @@
"Contact cockpit summary": "Resumo do contato na cabine",
"CONTACT": "CONTATO",
"CONTACTS · 250 KM": "CONTATOS · 250 KM",
"RINGS {spacing} NM": {
"one": "ANÉIS {spacing} MN",
"many": "ANÉIS {spacing} MN",
"other": "ANÉIS {spacing} MN"
},
"RINGS {spacing} NM": "ANÉIS {spacing} MN",
"{count} CONTACTS": {
"one": "{count} CONTATO",
"many": "{count} DE CONTATOS",
@@ -3234,7 +3207,6 @@
"Left panels": "Painéis à esquerda",
"Right panels": "Painéis à direita",
"CONFIRMED": "CONFIRMADA",
"sightings filter|CONFIRMED": "CONFIRMADOS",
"PAD / RTLS": "PLATAFORMA / RTLS",
"fire confidence filter|All": "Todas",
"fire confidence filter|Nominal+": "Nominal+",
@@ -3501,11 +3473,7 @@
"Photo of {name}": "Foto de {name}",
"Acartia": "Acartia",
"CC BY 4.0": "CC BY 4.0",
"{count} sightings in view": {
"one": "{count} avistamento na vista",
"many": "{count} de avistamentos na vista",
"other": "{count} avistamentos na vista"
},
"{count} sightings in view": "Avistamentos na vista: {count}",
"Close sighting": "Fechar avistamento",
"Wildlife observed within 48 h (whales 7 d). Color and badge glyph show the taxon group. Sensitive species are shown only as 0.2° cells; Salish Sea marine mammal reports via Acartia are rounded to 0.01°. Not a census.": "Vida selvagem observada nas últimas 48 h (cetáceos 7 dias). A cor e o símbolo do emblema indicam o grupo taxonômico. Espécies sensíveis aparecem apenas em células de 0,2°; os relatos de mamíferos marinhos do mar de Salish via Acartia são arredondados para 0,01°. Não é um censo.",
"Open {name} on iNaturalist": "Abrir {name} no iNaturalist",
@@ -3516,31 +3484,20 @@
"{days}d": "{days} d",
"All markers": "Todos os marcadores",
"Show markers of every age": "Mostrar marcadores de qualquer idade",
"Maximum event age: {days}d; undated markers are kept": {
"one": "Idade máxima do evento: {days} dia; marcadores sem data são mantidos",
"many": "Idade máxima do evento: {days} de dias; marcadores sem data são mantidos",
"other": "Idade máxima do evento: {days} dias; marcadores sem data são mantidos"
},
"Maximum event age: {days}d; undated markers are kept": "Idade máxima do evento: {days} d; marcadores sem data são mantidos",
"event age filter|All": "Todos",
"Event age": "Idade do evento",
"Event age: {days}d · undated kept": {
"one": "Idade do evento: {days} dia · sem data mantidos",
"many": "Idade do evento: {days} de dias · sem data mantidos",
"other": "Idade do evento: {days} dias · sem data mantidos"
},
"Event age: {days}d · undated kept": "Idade do evento: {days} d · sem data mantidos",
"Close camera preview": "Fechar prévia da câmera",
"Refresh map still": "Atualizar imagem fixa no mapa",
"The map still uses a separate request and may show a different moment.": "A imagem no mapa usa uma solicitação separada e pode mostrar outro momento.",
"Video plays from Québec 511, which sees your IP address.": "O vídeo é reproduzido a partir do Québec 511, que vê o seu endereço IP.",
"Press OPEN to load the photo": "Clique em ABRIR para carregar a foto",
"Captured {month}": "Capturada em {month}",
"this spot": "este ponto",
"the view centre": "o centro da vista",
"{source} at {place}": "{source}: {place}",
"{source} at this spot": "{source} neste ponto",
"{source} at the view centre": "{source} no centro da vista",
"Street level at {place}": "Nível da rua: {place}",
"Street level at this spot": "Nível da rua neste ponto",
"Street level at the view centre": "Nível da rua no centro da vista",
"Switching map": "Mudando de mapa",
"Opening imagery": "Abrindo imagens",
"Street View is ready: press {open} to load it": "O Street View está pronto: clique em {open} para carregar",
@@ -3632,7 +3589,6 @@
"{source} imagery could not be opened": "Não foi possível abrir as imagens de {source}",
"{place} has no position to look for imagery at": "{place} não tem uma posição para buscar imagens",
"No {source} imagery near {place}": "Nenhuma imagem de {source} perto de {place}",
"No {source} imagery near the view centre": "Nenhuma imagem de {source} perto do centro da vista",
"{reason} (filters on: {filters})": "{reason} (filtros ativos: {filters})",
"tiles unavailable": "blocos indisponíveis",
"zoom in to load this layer": "aproxime o zoom para carregar esta camada",
@@ -3735,10 +3691,6 @@
"REMOVE ALL": "REMOVER TUDO",
"Confirm: remove every added entry from Data Layers": "Confirmar: remover de \"Camadas de dados\" todas as entradas adicionadas",
"Remove every added entry from Data Layers": "Remover de \"Camadas de dados\" todas as entradas adicionadas",
"Showing {shown} of {total}": {
"one": "Mostrando {shown} de {total}",
"many": "Mostrando {shown} de {total}",
"other": "Mostrando {shown} de {total}"
},
"Showing {shown} of {total}": "Mostrando {shown} de {total}",
"BROWSE DATA LIBRARY": "EXPLORAR BIBLIOTECA DE DADOS"
}
+11 -69
View File
@@ -71,18 +71,8 @@
"{severity} only": "Только: {severity}",
"All categories": "Все категории",
"Reading the news…": "Читаем новости…",
"News, last {hours} hours": {
"one": "Новости за последний {hours} час",
"few": "Новости за последние {hours} часа",
"many": "Новости за последние {hours} часов",
"other": "Новости за последние {hours} часа"
},
"Last {hours} h": {
"one": "За {hours} ч",
"few": "За {hours} ч",
"many": "За {hours} ч",
"other": "За {hours} ч"
},
"News, last {hours} hours": "Новости за последние {hours} ч",
"Last {hours} h": "За {hours} ч",
"Time window": "Период",
"Conflicts": "Конфликты",
"Local": "Местные",
@@ -91,19 +81,9 @@
"Hotspots": "Горячие точки",
"Severity": "Тяжесть",
"Category": "Категория",
"Nothing reported near here in the last {hours} h": {
"one": "За последний {hours} ч поблизости ничего не сообщалось",
"few": "За последние {hours} ч поблизости ничего не сообщалось",
"many": "За последние {hours} ч поблизости ничего не сообщалось",
"other": "За последние {hours} ч поблизости ничего не сообщалось"
},
"Nothing reported near here in the last {hours} h": "За последние {hours} ч поблизости ничего не сообщалось",
"Latest news": "Последние новости",
"No news matches these filters in the last {hours} h": {
"one": "За последний {hours} ч нет новостей по этим фильтрам",
"few": "За последние {hours} ч нет новостей по этим фильтрам",
"many": "За последние {hours} ч нет новостей по этим фильтрам",
"other": "За последние {hours} ч нет новостей по этим фильтрам"
},
"No news matches these filters in the last {hours} h": "За последние {hours} ч нет новостей по этим фильтрам",
"Load older news": "Загрузить более ранние новости",
"How to read the map": "Как читать карту",
"Colour: severity · icon: type of event": "Цвет: тяжесть · значок: тип события",
@@ -199,7 +179,6 @@
"Previous — prior visited contact in the 250 km window": "Назад — предыдущий посещённый контакт в радиусе 250 км",
"PREVIOUS": "ПРЕД.",
"FOCUS": "ФОКУС",
"site status|FOCUS": "ФОКУС",
"Next — nearest unvisited contact in the 250 km window": "Далее — ближайший непосещённый контакт в радиусе 250 км",
"NEXT": "СЛЕД.",
"Open-source mapped/observed context. Missing broadcasts, unloaded map areas, or unmapped sites are not evidence of absence.": "Контекст из открытых источников. Отсутствие трансляций, незагруженные области карты или неотмеченные объекты — не доказательство отсутствия.",
@@ -367,7 +346,6 @@
"Cancel replay": "Отменить повтор",
"EST. DOWNRANGE": "РАСЧЁТ ПО ТРАССЕ",
"CONFIRMED": "ПОДТВЕРЖДЕНО",
"sightings filter|CONFIRMED": "ПОДТВЕРЖДЕНО",
"PAD / RTLS": "ПЛОЩАДКА / RTLS",
"PLANNED · ": "ПЛАН · ",
"SUPPLIED TRAJECTORY POINTS": "ПРЕДОСТАВЛЕННЫЕ ТОЧКИ ТРАЕКТОРИИ",
@@ -567,12 +545,7 @@
"ROUTE DATA UNAVAILABLE": "ДАННЫЕ МАРШРУТА НЕДОСТУПНЫ",
"CONTACT NAVIGATION OFF": "НАВИГАЦИЯ ПО КОНТАКТАМ ВЫКЛЮЧЕНА",
"THE BRIDGE STAYS WITH THE SELECTED VESSEL": "МОСТИК ОСТАЁТСЯ НА ВЫБРАННОМ СУДНЕ",
"{range} NM": {
"one": "{range} МОР. МИЛЯ",
"few": "{range} МОР. МИЛИ",
"many": "{range} МОР. МИЛЬ",
"other": "{range} МОР. МИЛИ"
},
"{range} NM": "{range} МОР. МИЛ.",
"AIS DESTINATION · CREW REPORTED": "ПУНКТ НАЗНАЧЕНИЯ AIS · УКАЗАН ЭКИПАЖЕМ",
"DEST {bearing}": "НАЗН. {bearing}",
"Disable cockpit weather effects": "Выключить погодные эффекты кабины",
@@ -618,7 +591,6 @@
"Select flight {title}": "Выбрать рейс {title}",
"TRACK ACQUIRED": "ЦЕЛЬ ЗАХВАЧЕНА",
"{label} · COURSE {heading}°": "{label} · ПУТЕВОЙ УГОЛ {heading}°",
"vessel|{label} · COURSE {heading}°": "{label} · ПУТЕВОЙ УГОЛ {heading}°",
"{label} · HEADING {heading}°": "{label} · КУРС {heading}°",
"{label} · NO HEADING": "{label} · НЕТ КУРСА",
"{label} · NADIR VIEW": "{label} · ВИД В НАДИР",
@@ -870,12 +842,7 @@
"EXIT BRIDGE": "ВЫЙТИ С МОСТИКА",
"EXIT ORBIT": "ВЫЙТИ С ОРБИТЫ",
"CONTACTS · 250 KM": "КОНТАКТЫ · 250 КМ",
"RINGS {spacing} NM": {
"one": "КОЛЬЦА {spacing} МОР. МИЛЯ",
"few": "КОЛЬЦА {spacing} МОР. МИЛИ",
"many": "КОЛЬЦА {spacing} МОР. МИЛЬ",
"other": "КОЛЬЦА {spacing} МОР. МИЛИ"
},
"RINGS {spacing} NM": "КОЛЬЦА {spacing} МОР. МИЛ.",
"{count} CONTACTS": {
"one": "{count} КОНТАКТ",
"few": "{count} КОНТАКТА",
@@ -1732,7 +1699,6 @@
"Observed history": "История наблюдений",
"Later observation": "Более позднее наблюдение",
"Latest": "Последние",
"news list|Latest": "Последние",
"Newest frame per product": "Самый свежий кадр каждого продукта",
"Replay observed history": "Воспроизвести историю наблюдений",
"S on another day replaces it · × unpins": "S в другой день заменяет его · × открепляет",
@@ -3588,12 +3554,7 @@
"Photo of {name}": "Фото: {name}",
"Acartia": "Acartia",
"CC BY 4.0": "CC BY 4.0",
"{count} sightings in view": {
"one": "{count} наблюдение в кадре",
"few": "{count} наблюдения в кадре",
"many": "{count} наблюдений в кадре",
"other": "{count} наблюдения в кадре"
},
"{count} sightings in view": "Наблюдений в кадре: {count}",
"Close sighting": "Закрыть наблюдение",
"Wildlife observed within 48 h (whales 7 d). Color and badge glyph show the taxon group. Sensitive species are shown only as 0.2° cells; Salish Sea marine mammal reports via Acartia are rounded to 0.01°. Not a census.": "Наблюдения живой природы за 48 ч (китообразные — 7 дней). Цвет и символ значка обозначают таксономическую группу. Уязвимые виды показаны только ячейками 0,2°; сообщения Acartia о морских млекопитающих моря Селиш округлены до 0,01°. Это не учёт численности.",
"Open {name} on iNaturalist": "Открыть {name} в iNaturalist",
@@ -3604,33 +3565,20 @@
"{days}d": "{days} дн.",
"All markers": "Все метки",
"Show markers of every age": "Показать метки любого возраста",
"Maximum event age: {days}d; undated markers are kept": {
"one": "Максимальный возраст события: {days} дн.; метки без даты остаются",
"few": "Максимальный возраст события: {days} дн.; метки без даты остаются",
"many": "Максимальный возраст события: {days} дн.; метки без даты остаются",
"other": "Максимальный возраст события: {days} дн.; метки без даты остаются"
},
"Maximum event age: {days}d; undated markers are kept": "Максимальный возраст события: {days} дн.; метки без даты остаются",
"event age filter|All": "Все",
"Event age": "Возраст события",
"Event age: {days}d · undated kept": {
"one": "Возраст события: {days} дн. · метки без даты остаются",
"few": "Возраст события: {days} дн. · метки без даты остаются",
"many": "Возраст события: {days} дн. · метки без даты остаются",
"other": "Возраст события: {days} дн. · метки без даты остаются"
},
"Event age: {days}d · undated kept": "Возраст события: {days} дн. · метки без даты остаются",
"Close camera preview": "Закрыть просмотр камеры",
"Refresh map still": "Обновить кадр на карте",
"The map still uses a separate request and may show a different moment.": "Кадр на карте запрашивается отдельно и может показывать другой момент.",
"Video plays from Québec 511, which sees your IP address.": "Видео воспроизводится с Québec 511, который видит ваш IP-адрес.",
"Press OPEN to load the photo": "Нажмите ОТКРЫТЬ, чтобы загрузить снимок",
"Captured {month}": "Снято: {month}",
"this spot": "эта точка",
"the view centre": "центр вида",
"{source} at {place}": "{source}: {place}",
"{source} at this spot": "{source} в этой точке",
"{source} at the view centre": "{source} в центре вида",
"Street level at {place}": "Уличные снимки: {place}",
"Street level at this spot": "Уличные снимки в этой точке",
"Street level at the view centre": "Уличные снимки в центре вида",
"Switching map": "Смена карты",
"Opening imagery": "Открытие снимков",
"Street View is ready: press {open} to load it": "Просмотр улиц готов: нажмите {open}, чтобы загрузить",
@@ -3722,7 +3670,6 @@
"{source} imagery could not be opened": "Не удалось открыть снимки {source}",
"{place} has no position to look for imagery at": "У места «{place}» нет координат для поиска снимков",
"No {source} imagery near {place}": "Нет снимков {source} рядом с местом «{place}»",
"No {source} imagery near the view centre": "Нет снимков {source} рядом с центром вида",
"{reason} (filters on: {filters})": "{reason} (включены фильтры: {filters})",
"tiles unavailable": "тайлы недоступны",
"Environment": "Окружающая среда",
@@ -3811,12 +3758,7 @@
"switch on a dataset to load features": "включите набор данных, чтобы загрузить объекты",
"Data Library at a glance": "Библиотека данных вкратце",
"Map features": "Объекты на карте",
"Showing {shown} of {total}": {
"one": "Показано {shown} из {total}",
"few": "Показано {shown} из {total}",
"many": "Показано {shown} из {total}",
"other": "Показано {shown} из {total}"
},
"Showing {shown} of {total}": "Показано {shown} из {total}",
"Datasets": "Наборы данных",
"Themes": "Темы",
"zoom in to load this layer": "приблизьте, чтобы загрузить этот слой",
+11 -49
View File
@@ -67,30 +67,18 @@
"{severity} and above": "{severity} och uppåt",
"{severity} only": "Endast ”{severity}”",
"All categories": "Alla kategorier",
"Last {hours} h": {
"one": "Senaste {hours} h",
"other": "Senaste {hours} h"
},
"Last {hours} h": "Senaste {hours} h",
"Reading the news…": "Läser in nyheterna …",
"News, last {hours} hours": {
"one": "Nyheter, senaste {hours} h",
"other": "Nyheter, senaste {hours} h"
},
"News, last {hours} hours": "Nyheter, senaste {hours} h",
"Time window": "Tidsfönster",
"News sections": "Nyhetssektioner",
"Hotspots": "Oroshärdar",
"Severity": "Allvarlighetsgrad",
"Category": "Kategori",
"Zoom in to see local news": "Zooma in för att se lokala nyheter",
"Nothing reported near here in the last {hours} h": {
"one": "Inget rapporterat i närheten senaste {hours} h",
"other": "Inget rapporterat i närheten senaste {hours} h"
},
"Nothing reported near here in the last {hours} h": "Inget rapporterat i närheten senaste {hours} h",
"Latest news": "Senaste nyheterna",
"No news matches these filters in the last {hours} h": {
"one": "Inga nyheter matchar filtren senaste {hours} h",
"other": "Inga nyheter matchar filtren senaste {hours} h"
},
"No news matches these filters in the last {hours} h": "Inga nyheter matchar filtren senaste {hours} h",
"Load older news": "Ladda äldre nyheter",
"How to read the map": "Så läses kartan",
"Colour: severity · icon: type of event": "Färg: allvarlighetsgrad · ikon: typ av händelse",
@@ -210,7 +198,6 @@
"Previous — prior visited contact in the 250 km window": "Förra – senast besökta kontakt inom 250 km",
"PREVIOUS": "FÖRRA",
"FOCUS": "FOKUS",
"site status|FOCUS": "FOKUS",
"Next — nearest unvisited contact in the 250 km window": "Nästa – närmaste obesökta kontakt inom 250 km",
"NEXT": "NÄSTA",
"Open-source mapped/observed context. Missing broadcasts, unloaded map areas, or unmapped sites are not evidence of absence.": "Kartlagd/observerad kontext från öppna källor. Uteblivna sändningar, kartområden som inte har laddats eller platser som inte är kartlagda bevisar inte att något saknas.",
@@ -578,7 +565,6 @@
"Reclassify as TR-3B": "Klassa om som TR-3B",
"TRACK ACQUIRED": "SPÅR LÅST",
"{label} · COURSE {heading}°": "{label} · FÄRDRIKTNING {heading}°",
"vessel|{label} · COURSE {heading}°": "{label} · FÄRDRIKTNING {heading}°",
"Context could not restore every layer; try again": "Läget ”Kontext” kunde inte återställa alla lager – försök igen",
"No selected data layers": "Inga valda datalager",
"{count} data layers could not be cleared": {
@@ -2340,7 +2326,6 @@
"Observed history": "Observerad historik",
"Later observation": "Senare observation",
"Latest": "Senaste",
"news list|Latest": "Senaste",
"Newest frame per product": "Senaste bildruta per produkt",
"Replay observed history": "Spela upp observerad historik",
"Imagery on Esri · Google 3D returns when cleared": "Bilder på Esri · Google 3D återkommer när de rensas",
@@ -3064,7 +3049,6 @@
"Left panels": "Vänstra paneler",
"Right panels": "Högra paneler",
"CONFIRMED": "BEKRÄFTAD",
"sightings filter|CONFIRMED": "BEKRÄFTADE",
"PAD / RTLS": "RAMP / RTLS",
"fire confidence filter|All": "Alla",
"fire confidence filter|Nominal+": "Normal+",
@@ -3325,10 +3309,7 @@
"Photo of {name}": "Foto av {name}",
"Acartia": "Acartia",
"CC BY 4.0": "CC BY 4.0",
"{count} sightings in view": {
"one": "{count} observation i vyn",
"other": "{count} observationer i vyn"
},
"{count} sightings in view": "Observationer i vyn: {count}",
"Close sighting": "Stäng observationen",
"Wildlife observed within 48 h (whales 7 d). Color and badge glyph show the taxon group. Sensitive species are shown only as 0.2° cells; Salish Sea marine mammal reports via Acartia are rounded to 0.01°. Not a census.": "Djur, växter och svampar observerade de senaste 48 h (valar 7 d). Färg och symbol visar artgruppen. Känsliga arter visas bara som rutor på 0,2°; rapporter om marina däggdjur i Salish Sea via Acartia avrundas till 0,01°. Ingen inventering.",
"Open {name} on iNaturalist": "Öppna {name} på iNaturalist",
@@ -3339,29 +3320,20 @@
"{days}d": "{days} d",
"All markers": "Alla markörer",
"Show markers of every age": "Visa markörer oavsett ålder",
"Maximum event age: {days}d; undated markers are kept": {
"one": "Högsta ålder på händelser: {days} d; markörer utan datum behålls",
"other": "Högsta ålder på händelser: {days} d; markörer utan datum behålls"
},
"Maximum event age: {days}d; undated markers are kept": "Högsta ålder på händelser: {days} d; markörer utan datum behålls",
"event age filter|All": "Alla",
"Event age": "Händelsernas ålder",
"Event age: {days}d · undated kept": {
"one": "Händelsernas ålder: {days} d · utan datum behålls",
"other": "Händelsernas ålder: {days} d · utan datum behålls"
},
"Event age: {days}d · undated kept": "Händelsernas ålder: {days} d · utan datum behålls",
"Close camera preview": "Stäng förhandsvisningen av kameran",
"Refresh map still": "Uppdatera stillbilden på kartan",
"The map still uses a separate request and may show a different moment.": "Stillbilden på kartan hämtas separat och kan visa ett annat ögonblick.",
"Video plays from Québec 511, which sees your IP address.": "Videon spelas upp från Québec 511, som ser din IP-adress.",
"Press OPEN to load the photo": "Tryck på ÖPPNA för att ladda fotot",
"Captured {month}": "Tagen {month}",
"this spot": "den här platsen",
"the view centre": "vyns mitt",
"{source} at {place}": "{source} vid {place}",
"{source} at this spot": "{source} på den här platsen",
"{source} at the view centre": "{source} i vyns mitt",
"Street level at {place}": "Gatunivå vid {place}",
"Street level at this spot": "Gatunivå på den här platsen",
"Street level at the view centre": "Gatunivå i vyns mitt",
"Switching map": "Byter karta",
"Opening imagery": "Öppnar bilder",
"Street View is ready: press {open} to load it": "Street View är redo: tryck på {open} för att ladda den",
@@ -3395,10 +3367,7 @@
"LIVE AIS": "LIVE-AIS",
"CONTACT NAVIGATION OFF": "KONTAKTNAVIGERING AV",
"THE BRIDGE STAYS WITH THE SELECTED VESSEL": "BRYGGAN STANNAR PÅ DET VALDA FARTYGET",
"{range} NM": {
"one": "{range} NM",
"other": "{range} NM"
},
"{range} NM": "{range} NM",
"AIS DESTINATION · CREW REPORTED": "AIS-DESTINATION · ANGIVEN AV BESÄTTNINGEN",
"{label} · NADIR VIEW": "{label} · NADIRVY",
"SITES STANDBY": "PLATSER I VÄNTLÄGE",
@@ -3477,10 +3446,7 @@
"Zoom in (+)": "Zooma in (+)",
"Zoom to the imaging sensor swath": "Zooma till sensorns avbildningsstråk",
"SENSOR": "SENSOR",
"RINGS {spacing} NM": {
"one": "RINGAR {spacing} NM",
"other": "RINGAR {spacing} NM"
},
"RINGS {spacing} NM": "RINGAR {spacing} NM",
"{count} CONTACTS": {
"one": "{count} KONTAKT",
"other": "{count} KONTAKTER"
@@ -3534,7 +3500,6 @@
"{source} imagery could not be opened": "Bilder från {source} kunde inte öppnas",
"{place} has no position to look for imagery at": "{place} har ingen position att söka efter bilder vid",
"No {source} imagery near {place}": "Inga bilder från {source} nära {place}",
"No {source} imagery near the view centre": "Inga bilder från {source} nära vyns mitt",
"{reason} (filters on: {filters})": "{reason} (aktiva filter: {filters})",
"1 h/s": "1 h/s",
"1 d/s": "1 d/s",
@@ -3639,9 +3604,6 @@
"REMOVE ALL": "TA BORT ALLA",
"Confirm: remove every added entry from Data Layers": "Bekräfta: ta bort alla tillagda poster från Datalager",
"Remove every added entry from Data Layers": "Ta bort alla tillagda poster från Datalager",
"Showing {shown} of {total}": {
"one": "Visar {shown} av {total}",
"other": "Visar {shown} av {total}"
},
"Showing {shown} of {total}": "Visar {shown} av {total}",
"BROWSE DATA LIBRARY": "BLÄDDRA I DATABIBLIOTEKET"
}
+12 -70
View File
@@ -71,18 +71,8 @@
"{severity} only": "Лише {severity}",
"All categories": "Усі категорії",
"Reading the news…": "Читаємо новини…",
"News, last {hours} hours": {
"one": "Новини за останню {hours} годину",
"few": "Новини за останні {hours} години",
"many": "Новини за останні {hours} годин",
"other": "Новини за останні {hours} години"
},
"Last {hours} h": {
"one": "За {hours} год",
"few": "За {hours} год",
"many": "За {hours} год",
"other": "За {hours} год"
},
"News, last {hours} hours": "Новини за {hours} год",
"Last {hours} h": "За {hours} год",
"Time window": "Період",
"Conflicts": "Конфлікти",
"Local": "Місцеві",
@@ -91,19 +81,9 @@
"Hotspots": "Гарячі точки",
"Severity": "Тяжкість",
"Category": "Категорія",
"Nothing reported near here in the last {hours} h": {
"one": "За останню {hours} год поблизу нічого не повідомлялося",
"few": "За останні {hours} год поблизу нічого не повідомлялося",
"many": "За останні {hours} год поблизу нічого не повідомлялося",
"other": "За останні {hours} год поблизу нічого не повідомлялося"
},
"Nothing reported near here in the last {hours} h": "За {hours} год поблизу нічого не повідомлялося",
"Latest news": "Останні новини",
"No news matches these filters in the last {hours} h": {
"one": "За останню {hours} год немає новин за цими фільтрами",
"few": "За останні {hours} год немає новин за цими фільтрами",
"many": "За останні {hours} год немає новин за цими фільтрами",
"other": "За останні {hours} год немає новин за цими фільтрами"
},
"No news matches these filters in the last {hours} h": "За {hours} год немає новин за цими фільтрами",
"Load older news": "Завантажити давніші новини",
"How to read the map": "Як читати карту",
"Colour: severity · icon: type of event": "Колір: тяжкість · значок: тип події",
@@ -614,7 +594,6 @@
"Previous — prior visited contact in the 250 km window": "Назад — попередній переглянутий контакт у радіусі 250 км",
"PREVIOUS": "НАЗАД",
"FOCUS": "ФОКУС",
"site status|FOCUS": "ФОКУС",
"Next — nearest unvisited contact in the 250 km window": "Далі — найближчий ще не переглянутий контакт у радіусі 250 км",
"NEXT": "ДАЛІ",
"Named areas ({n})": "Іменовані зони ({n})",
@@ -977,7 +956,7 @@
"ORBITAL VELOCITY": "ОРБІТАЛЬНА ШВИДКІСТЬ",
"SUB-SATELLITE POINT": "ПІДСУПУТНИКОВА ТОЧКА",
"NORTH UP": "ПІВНІЧ УГОРІ",
"CURRENTLY OVER": "ПІД СУПУТНИКОМ",
"CURRENTLY OVER": "ЗАРАЗ НАД",
"{division}, {country}": "{division}, {country}",
"{region} · near {place}": "{region} · поблизу: {place}",
"NORAD {id}": "NORAD {id}",
@@ -1880,12 +1859,7 @@
"ROUTE DATA UNAVAILABLE": "ДАНІ МАРШРУТУ НЕДОСТУПНІ",
"CONTACT NAVIGATION OFF": "НАВІГАЦІЮ КОНТАКТАМИ ВИМКНЕНО",
"THE BRIDGE STAYS WITH THE SELECTED VESSEL": "МІСТОК ЗАЛИШАЄТЬСЯ НА ВИБРАНОМУ СУДНІ",
"{range} NM": {
"one": "{range} МОР. МИЛЯ",
"few": "{range} МОР. МИЛІ",
"many": "{range} МОР. МИЛЬ",
"other": "{range} МОР. МИЛІ"
},
"{range} NM": "{range} МОР. МИЛ.",
"AIS DESTINATION · CREW REPORTED": "ПРИЗНАЧЕННЯ AIS · ВКАЗАНО ЕКІПАЖЕМ",
"DEST {bearing}": "ПРИЗН. {bearing}",
"Disable cockpit weather effects": "Вимкнути погодні ефекти кабіни",
@@ -1934,7 +1908,6 @@
"Reclassify as TR-3B": "Перекласифікувати як TR-3B",
"TRACK ACQUIRED": "ТРЕК ЗАХОПЛЕНО",
"{label} · COURSE {heading}°": "{label} · ШЛЯХОВИЙ КУТ {heading}°",
"vessel|{label} · COURSE {heading}°": "{label} · ШЛЯХОВИЙ КУТ {heading}°",
"{label} · HEADING {heading}°": "{label} · КУРС {heading}°",
"{label} · NO HEADING": "{label} · НЕМАЄ КУРСУ",
"{label} · NADIR VIEW": "{label} · ВИГЛЯД У НАДИР",
@@ -2215,7 +2188,6 @@
"Observed history": "Історія спостережень",
"Later observation": "Наступне спостереження",
"Latest": "Останні",
"news list|Latest": "Останні",
"Newest frame per product": "Найсвіжіший кадр кожного продукту",
"Replay observed history": "Відтворити історію спостережень",
"Imagery on Esri · Google 3D returns when cleared": "Підкладка: Esri · скидання поверне Google 3D",
@@ -2982,12 +2954,7 @@
"Contact cockpit summary": "Зведення контакту в кабіні",
"CONTACT": "КОНТАКТ",
"CONTACTS · 250 KM": "КОНТАКТИ · 250 КМ",
"RINGS {spacing} NM": {
"one": "КІЛЬЦЯ {spacing} МОР. МИЛЯ",
"few": "КІЛЬЦЯ {spacing} МОР. МИЛІ",
"many": "КІЛЬЦЯ {spacing} МОР. МИЛЬ",
"other": "КІЛЬЦЯ {spacing} МОР. МИЛІ"
},
"RINGS {spacing} NM": "КІЛЬЦЯ {spacing} МОР. МИЛ.",
"{count} CONTACTS": {
"one": "{count} КОНТАКТ",
"few": "{count} КОНТАКТИ",
@@ -3328,7 +3295,6 @@
"Left panels": "Ліві панелі",
"Right panels": "Праві панелі",
"CONFIRMED": "ПІДТВЕРДЖЕНО",
"sightings filter|CONFIRMED": "ПІДТВЕРДЖЕНО",
"PAD / RTLS": "МІСЦЕ ЗАПУСКУ / RTLS",
"Name of {name}": "Назва: {name}",
"Change the colour of {name}": "Змінити колір: {name}",
@@ -3588,12 +3554,7 @@
"Photo of {name}": "Фото {name}",
"Acartia": "Acartia",
"CC BY 4.0": "CC BY 4.0",
"{count} sightings in view": {
"one": "{count} спостереження в кадрі",
"few": "{count} спостереження в кадрі",
"many": "{count} спостережень у кадрі",
"other": "{count} спостереження в кадрі"
},
"{count} sightings in view": "Спостережень у кадрі: {count}",
"Close sighting": "Закрити спостереження",
"Wildlife observed within 48 h (whales 7 d). Color and badge glyph show the taxon group. Sensitive species are shown only as 0.2° cells; Salish Sea marine mammal reports via Acartia are rounded to 0.01°. Not a census.": "Спостереження живої природи за 48 год (китоподібні — 7 днів). Колір і символ значка позначають таксономічну групу. Вразливі види показано лише комірками 0,2°; повідомлення Acartia про морських ссавців моря Селіш округлено до 0,01°. Не перепис.",
"Open {name} on iNaturalist": "Відкрити {name} в iNaturalist",
@@ -3604,33 +3565,20 @@
"{days}d": "{days} дн",
"All markers": "Усі мітки",
"Show markers of every age": "Показати мітки будь-якого віку",
"Maximum event age: {days}d; undated markers are kept": {
"one": "Максимальний вік події: {days} дн; мітки без дати залишаються",
"few": "Максимальний вік події: {days} дн; мітки без дати залишаються",
"many": "Максимальний вік події: {days} дн; мітки без дати залишаються",
"other": "Максимальний вік події: {days} дн; мітки без дати залишаються"
},
"Maximum event age: {days}d; undated markers are kept": "Максимальний вік події: {days} дн; мітки без дати залишаються",
"event age filter|All": "Усі",
"Event age": "Вік події",
"Event age: {days}d · undated kept": {
"one": "Вік події: {days} дн · мітки без дати залишаються",
"few": "Вік події: {days} дн · мітки без дати залишаються",
"many": "Вік події: {days} дн · мітки без дати залишаються",
"other": "Вік події: {days} дн · мітки без дати залишаються"
},
"Event age: {days}d · undated kept": "Вік події: {days} дн · мітки без дати залишаються",
"Close camera preview": "Закрити перегляд камери",
"Refresh map still": "Оновити кадр на карті",
"The map still uses a separate request and may show a different moment.": "Кадр на карті запитується окремо та може показувати інший момент.",
"Video plays from Québec 511, which sees your IP address.": "Відео відтворюється з Québec 511, який бачить вашу IP-адресу.",
"Press OPEN to load the photo": "Натисніть «ВІДКРИТИ», щоб завантажити фото",
"Captured {month}": "Знято: {month}",
"this spot": "це місце",
"the view centre": "центр карти",
"{source} at {place}": "{source}: {place}",
"{source} at this spot": "{source} у цьому місці",
"{source} at the view centre": "{source} у центрі карти",
"Street level at {place}": "Вуличні знімки: {place}",
"Street level at this spot": "Вуличні знімки в цьому місці",
"Street level at the view centre": "Вуличні знімки в центрі карти",
"Switching map": "Перемикання карти",
"Opening imagery": "Відкриття знімків",
"Street View is ready: press {open} to load it": "Перегляд вулиць готовий: натисніть «{open}», щоб завантажити",
@@ -3722,7 +3670,6 @@
"{source} imagery could not be opened": "Не вдалося відкрити знімки {source}",
"{place} has no position to look for imagery at": "Для місця «{place}» немає координат для пошуку знімків",
"No {source} imagery near {place}": "Немає знімків {source} поблизу: {place}",
"No {source} imagery near the view centre": "Немає знімків {source} поблизу центру карти",
"{reason} (filters on: {filters})": "{reason} (увімкнено фільтри: {filters})",
"tiles unavailable": "тайли недоступні",
"zoom in to load this layer": "наблизьте карту, щоб завантажити цей шар",
@@ -3831,11 +3778,6 @@
"REMOVE ALL": "ВИДАЛИТИ ВСЕ",
"Confirm: remove every added entry from Data Layers": "Підтвердити: видалити всі додані записи з «Шарів даних»",
"Remove every added entry from Data Layers": "Видалити всі додані записи з «Шарів даних»",
"Showing {shown} of {total}": {
"one": "Показано {shown} з {total}",
"few": "Показано {shown} з {total}",
"many": "Показано {shown} з {total}",
"other": "Показано {shown} з {total}"
},
"Showing {shown} of {total}": "Показано {shown} з {total}",
"BROWSE DATA LIBRARY": "ВІДКРИТИ БІБЛІОТЕКУ ДАНИХ"
}
+11 -39
View File
@@ -62,12 +62,8 @@
"{severity} only": "仅{severity}",
"All categories": "所有类别",
"Reading the news…": "正在读取新闻…",
"News, last {hours} hours": {
"other": "最近 {hours} 小时的新闻"
},
"Last {hours} h": {
"other": "最近 {hours} 小时"
},
"News, last {hours} hours": "最近 {hours} 小时的新闻",
"Last {hours} h": "最近 {hours} 小时",
"Time window": "时间范围",
"Conflicts": "冲突",
"Local": "本地",
@@ -76,13 +72,9 @@
"Hotspots": "热点",
"Severity": "严重程度",
"Category": "类别",
"Nothing reported near here in the last {hours} h": {
"other": "最近 {hours} 小时附近无报道"
},
"Nothing reported near here in the last {hours} h": "最近 {hours} 小时附近无报道",
"Latest news": "最新新闻",
"No news matches these filters in the last {hours} h": {
"other": "最近 {hours} 小时没有符合这些筛选条件的新闻"
},
"No news matches these filters in the last {hours} h": "最近 {hours} 小时没有符合这些筛选条件的新闻",
"Load older news": "加载更早的新闻",
"How to read the map": "如何解读地图",
"Colour: severity · icon: type of event": "颜色:严重程度 · 图标:事件类型",
@@ -571,7 +563,6 @@
"Previous — prior visited contact in the 250 km window": "上一个:250 km 范围内先前访问过的目标",
"PREVIOUS": "上一个",
"FOCUS": "聚焦",
"site status|FOCUS": "聚焦",
"Next — nearest unvisited contact in the 250 km window": "下一个:250 km 范围内最近的未访问目标",
"NEXT": "下一个",
"Named areas ({n})": "已命名区域({n})",
@@ -938,7 +929,6 @@
"Cancel replay": "取消回放",
"EST. DOWNRANGE": "预估落点距离",
"CONFIRMED": "已确认",
"sightings filter|CONFIRMED": "已确认",
"PAD / RTLS": "发射台 / RTLS",
"PLANNED · ": "计划 · ",
"SUPPLIED TRAJECTORY POINTS": "提供的轨迹点",
@@ -1760,9 +1750,7 @@
"ROUTE DATA UNAVAILABLE": "航线数据不可用",
"CONTACT NAVIGATION OFF": "目标导航已关闭",
"THE BRIDGE STAYS WITH THE SELECTED VESSEL": "驾驶台保持在所选船舶上",
"{range} NM": {
"other": "{range} 海里"
},
"{range} NM": "{range} 海里",
"AIS DESTINATION · CREW REPORTED": "AIS 目的地 · 船员申报",
"DEST {bearing}": "目的地 {bearing}",
"Disable cockpit weather effects": "停用座舱天气效果",
@@ -1808,7 +1796,6 @@
"Reclassify as TR-3B": "重新归类为 TR-3B",
"TRACK ACQUIRED": "已获取航迹",
"{label} · COURSE {heading}°": "{label} · 对地航向 {heading}°",
"vessel|{label} · COURSE {heading}°": "{label} · 对地航向 {heading}°",
"{label} · HEADING {heading}°": "{label} · 船首向 {heading}°",
"{label} · NO HEADING": "{label} · 无船首向",
"{label} · NADIR VIEW": "{label} · 天底视图",
@@ -2061,7 +2048,6 @@
"Observed history": "观测历史",
"Later observation": "较晚观测",
"Latest": "最新",
"news list|Latest": "最新",
"Newest frame per product": "每个产品的最新一帧",
"Replay observed history": "回放观测历史",
"Imagery on Esri · Google 3D returns when cleared": "影像显示在 Esri 底图上 · 清除后恢复 Google 3D",
@@ -2643,9 +2629,7 @@
"Contact cockpit summary": "目标座舱摘要",
"CONTACT": "目标",
"CONTACTS · 250 KM": "目标 · 250 km",
"RINGS {spacing} NM": {
"other": "距标圈 {spacing} 海里"
},
"RINGS {spacing} NM": "距标圈 {spacing} 海里",
"{count} CONTACTS": {
"other": "{count} 个目标"
},
@@ -3327,9 +3311,7 @@
"Photo of {name}": "{name} 的照片",
"Acartia": "Acartia",
"CC BY 4.0": "CC BY 4.0",
"{count} sightings in view": {
"other": "视野内有 {count} 次目击"
},
"{count} sightings in view": "视野内有 {count} 次目击",
"Close sighting": "关闭目击记录",
"Wildlife observed within 48 h (whales 7 d). Color and badge glyph show the taxon group. Sensitive species are shown only as 0.2° cells; Salish Sea marine mammal reports via Acartia are rounded to 0.01°. Not a census.": "近 48 小时内观察到的野生生物(鲸类为 7 天)。颜色与徽章图标表示分类群。敏感物种仅以 0.2° 网格显示;Acartia 提供的萨利希海海洋哺乳动物目击位置四舍五入到 0.01°。并非种群普查。",
"Open {name} on iNaturalist": "在 iNaturalist 上打开 {name}",
@@ -3340,27 +3322,20 @@
"{days}d": "{days} 天",
"All markers": "所有标记",
"Show markers of every age": "显示所有时间的标记",
"Maximum event age: {days}d; undated markers are kept": {
"other": "仅显示 {days} 天内的事件;保留无日期标记"
},
"Maximum event age: {days}d; undated markers are kept": "仅显示 {days} 天内的事件;保留无日期标记",
"event age filter|All": "全部",
"Event age": "事件时间",
"Event age: {days}d · undated kept": {
"other": "事件时间:{days} 天内 · 保留无日期标记"
},
"Event age: {days}d · undated kept": "事件时间:{days} 天内 · 保留无日期标记",
"Close camera preview": "关闭摄像头预览",
"Refresh map still": "刷新地图静止画面",
"The map still uses a separate request and may show a different moment.": "地图静止画面通过单独的请求获取,可能显示不同的时刻。",
"Video plays from Québec 511, which sees your IP address.": "视频从 Québec 511 播放,Québec 511 会看到你的 IP 地址。",
"Press OPEN to load the photo": "点击“打开”加载照片",
"Captured {month}": "拍摄于 {month}",
"this spot": "此处",
"the view centre": "视野中心",
"{source} at {place}": "{place} 的 {source}",
"{source} at this spot": "此处的 {source}",
"{source} at the view centre": "视图中心的 {source}",
"Street level at {place}": "{place} 的街景",
"Street level at this spot": "此处的街景",
"Street level at the view centre": "视图中心的街景",
"Switching map": "正在切换地图",
"Opening imagery": "正在打开影像",
"Street View is ready: press {open} to load it": "街景已就绪:点击“{open}”加载",
@@ -3452,7 +3427,6 @@
"{source} imagery could not be opened": "无法打开 {source} 影像",
"{place} has no position to look for imagery at": "{place} 没有可查找影像的位置",
"No {source} imagery near {place}": "{place} 附近没有 {source} 影像",
"No {source} imagery near the view centre": "视图中心附近没有 {source} 影像",
"{reason} (filters on: {filters})": "{reason}(已开启筛选:{filters})",
"tiles unavailable": "瓦片不可用",
"zoom in to load this layer": "放大以加载此图层",
@@ -3543,8 +3517,6 @@
"REMOVE ALL": "全部移除",
"Confirm: remove every added entry from Data Layers": "确认:从数据图层中移除所有已添加条目",
"Remove every added entry from Data Layers": "从数据图层中移除所有已添加条目",
"Showing {shown} of {total}": {
"other": "显示 {shown} / {total}"
},
"Showing {shown} of {total}": "显示 {shown} / {total}",
"BROWSE DATA LIBRARY": "浏览数据资源库"
}
+11 -39
View File
@@ -62,12 +62,8 @@
"{severity} only": "僅{severity}",
"All categories": "所有類別",
"Reading the news…": "正在讀取新聞…",
"News, last {hours} hours": {
"other": "最近 {hours} 小時的新聞"
},
"Last {hours} h": {
"other": "最近 {hours} 小時"
},
"News, last {hours} hours": "最近 {hours} 小時的新聞",
"Last {hours} h": "最近 {hours} 小時",
"Time window": "時間範圍",
"Conflicts": "衝突",
"Local": "本地",
@@ -76,13 +72,9 @@
"Hotspots": "熱點",
"Severity": "嚴重程度",
"Category": "類別",
"Nothing reported near here in the last {hours} h": {
"other": "最近 {hours} 小時附近無報道"
},
"Nothing reported near here in the last {hours} h": "最近 {hours} 小時附近無報道",
"Latest news": "最新新聞",
"No news matches these filters in the last {hours} h": {
"other": "最近 {hours} 小時沒有符合這些篩選條件的新聞"
},
"No news matches these filters in the last {hours} h": "最近 {hours} 小時沒有符合這些篩選條件的新聞",
"Load older news": "加載更早的新聞",
"How to read the map": "如何解讀地圖",
"Colour: severity · icon: type of event": "顏色:嚴重程度 · 圖標:事件類型",
@@ -571,7 +563,6 @@
"Previous — prior visited contact in the 250 km window": "上一個:250 km 範圍內先前訪問過的目標",
"PREVIOUS": "上一個",
"FOCUS": "聚焦",
"site status|FOCUS": "聚焦",
"Next — nearest unvisited contact in the 250 km window": "下一個:250 km 範圍內最近的未訪問目標",
"NEXT": "下一個",
"Named areas ({n})": "已命名區域({n})",
@@ -933,7 +924,6 @@
"Cancel replay": "取消回放",
"EST. DOWNRANGE": "預估落點距離",
"CONFIRMED": "已確認",
"sightings filter|CONFIRMED": "已確認",
"PAD / RTLS": "發射臺 / RTLS",
"PLANNED · ": "計劃 · ",
"SUPPLIED TRAJECTORY POINTS": "提供的軌跡點",
@@ -1752,9 +1742,7 @@
"ROUTE DATA UNAVAILABLE": "航線數據不可用",
"CONTACT NAVIGATION OFF": "目標導航已關閉",
"THE BRIDGE STAYS WITH THE SELECTED VESSEL": "駕駛臺保持在所選船舶上",
"{range} NM": {
"other": "{range} 海里"
},
"{range} NM": "{range} 海里",
"AIS DESTINATION · CREW REPORTED": "AIS 目的地 · 船員申報",
"DEST {bearing}": "目的地 {bearing}",
"Disable cockpit weather effects": "停用座艙天氣效果",
@@ -1800,7 +1788,6 @@
"Reclassify as TR-3B": "重新歸類為 TR-3B",
"TRACK ACQUIRED": "已獲取航跡",
"{label} · COURSE {heading}°": "{label} · 對地航向 {heading}°",
"vessel|{label} · COURSE {heading}°": "{label} · 對地航向 {heading}°",
"{label} · HEADING {heading}°": "{label} · 船首向 {heading}°",
"{label} · NO HEADING": "{label} · 無船首向",
"{label} · NADIR VIEW": "{label} · 天底視圖",
@@ -2051,7 +2038,6 @@
"Observed history": "觀測歷史",
"Later observation": "較晚觀測",
"Latest": "最新",
"news list|Latest": "最新",
"Newest frame per product": "每個產品的最新一幀",
"Replay observed history": "回放觀測歷史",
"Imagery on Esri · Google 3D returns when cleared": "影像顯示在 Esri 底圖上 · 清除後恢復 Google 3D",
@@ -2633,9 +2619,7 @@
"Contact cockpit summary": "目標座艙摘要",
"CONTACT": "目標",
"CONTACTS · 250 KM": "目標 · 250 km",
"RINGS {spacing} NM": {
"other": "距標圈 {spacing} 海里"
},
"RINGS {spacing} NM": "距標圈 {spacing} 海里",
"{count} CONTACTS": {
"other": "{count} 個目標"
},
@@ -3327,9 +3311,7 @@
"Photo of {name}": "{name} 的照片",
"Acartia": "Acartia",
"CC BY 4.0": "CC BY 4.0",
"{count} sightings in view": {
"other": "視野內有 {count} 次目擊"
},
"{count} sightings in view": "視野內有 {count} 次目擊",
"Close sighting": "關閉目擊記錄",
"Wildlife observed within 48 h (whales 7 d). Color and badge glyph show the taxon group. Sensitive species are shown only as 0.2° cells; Salish Sea marine mammal reports via Acartia are rounded to 0.01°. Not a census.": "近 48 小時內觀察到的野生生物(鯨類為 7 天)。顏色與徽章圖標表示分類群。敏感物種僅以 0.2° 網格顯示;Acartia 提供的薩利希海海洋哺乳動物目擊位置四捨五入到 0.01°。並非種群普查。",
"Open {name} on iNaturalist": "在 iNaturalist 上打開 {name}",
@@ -3340,27 +3322,20 @@
"{days}d": "{days} 天",
"All markers": "所有標記",
"Show markers of every age": "顯示所有時間的標記",
"Maximum event age: {days}d; undated markers are kept": {
"other": "僅顯示 {days} 天內的事件;保留無日期標記"
},
"Maximum event age: {days}d; undated markers are kept": "僅顯示 {days} 天內的事件;保留無日期標記",
"event age filter|All": "全部",
"Event age": "事件時間",
"Event age: {days}d · undated kept": {
"other": "事件時間:{days} 天內 · 保留無日期標記"
},
"Event age: {days}d · undated kept": "事件時間:{days} 天內 · 保留無日期標記",
"Close camera preview": "關閉攝像頭預覽",
"Refresh map still": "刷新地圖靜止畫面",
"The map still uses a separate request and may show a different moment.": "地圖靜止畫面通過單獨的請求獲取,可能顯示不同的時刻。",
"Video plays from Québec 511, which sees your IP address.": "視頻從 Québec 511 播放,Québec 511 會看到你的 IP 地址。",
"Press OPEN to load the photo": "點擊“打開”加載照片",
"Captured {month}": "拍攝於 {month}",
"this spot": "此處",
"the view centre": "視野中心",
"{source} at {place}": "{place} 的 {source}",
"{source} at this spot": "此處的 {source}",
"{source} at the view centre": "視圖中心的 {source}",
"Street level at {place}": "{place} 的街景",
"Street level at this spot": "此處的街景",
"Street level at the view centre": "視圖中心的街景",
"Switching map": "正在切換地圖",
"Opening imagery": "正在打開影像",
"Street View is ready: press {open} to load it": "街景已就緒:點擊“{open}”加載",
@@ -3452,7 +3427,6 @@
"{source} imagery could not be opened": "無法打開 {source} 影像",
"{place} has no position to look for imagery at": "{place} 沒有可查找影像的位置",
"No {source} imagery near {place}": "{place} 附近沒有 {source} 影像",
"No {source} imagery near the view centre": "視圖中心附近沒有 {source} 影像",
"{reason} (filters on: {filters})": "{reason}(已開啟篩選:{filters})",
"tiles unavailable": "瓦片不可用",
"zoom in to load this layer": "放大以加載此圖層",
@@ -3543,8 +3517,6 @@
"REMOVE ALL": "全部移除",
"Confirm: remove every added entry from Data Layers": "確認:從數據圖層中移除所有已添加條目",
"Remove every added entry from Data Layers": "從數據圖層中移除所有已添加條目",
"Showing {shown} of {total}": {
"other": "顯示 {shown} / {total}"
},
"Showing {shown} of {total}": "顯示 {shown} / {total}",
"BROWSE DATA LIBRARY": "瀏覽數據資源庫"
}
-1
View File
@@ -685,7 +685,6 @@
"FLIR",
"FM MHZ",
"FOCUS",
"site status|FOCUS",
"FOV",
"FOV {value}°",
"FT",
+4 -7
View File
@@ -762,12 +762,9 @@ export function createGhostMapsLayer({
title:
days === null
? t('Show markers of every age')
: tn(
days,
'Maximum event age: {days}d; undated markers are kept',
'Maximum event age: {days}d; undated markers are kept',
{ days: formatNumber(days) },
),
: t('Maximum event age: {days}d; undated markers are kept', {
days: formatNumber(days),
}),
active: days === _ageDays,
onClick: () => setAgeDays(days),
})),
@@ -802,7 +799,7 @@ export function createGhostMapsLayer({
};
}),
legend: [],
info: `${_ageDays === null ? t('All markers') : tn(_ageDays, 'Event age: {days}d · undated kept', 'Event age: {days}d · undated kept', { days: formatNumber(_ageDays) })} · ${info}`,
info: `${_ageDays === null ? t('All markers') : t('Event age: {days}d · undated kept', { days: formatNumber(_ageDays) })} · ${info}`,
infoTitle: t(
'S2 Underground publishes these KMZ products to GitHub. New uploads are detected within seconds and replace the previous edition automatically. Click a marker for its report.',
),
-30
View File
@@ -1,7 +1,6 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import * as Cesium from 'cesium';
import { setLocale } from '../../i18n/index.js';
import { createGhostMapsLayer } from './index.js';
import { GHOSTMAPS_PRODUCTS, GHOSTMAPS_LATEST_DROP } from './catalog.js';
@@ -249,35 +248,6 @@ test('age controls default to seven days and widening restores filtered and expi
assert.equal(ageChip(layer, null).active, true);
});
test('the event age agrees with its number of days', async (t) => {
t.after(() => setLocale('en'));
const { layer, viewer } = fixture(t, { reports: [{ name: 'Undated' }] });
await layer.update(viewer);
const info = () =>
layer.getRowControls().info.split(' · ').slice(0, 2).join(' · ');
assert.equal(
ageChip(layer, 1).title,
'Maximum event age: 1d; undated markers are kept',
);
setLocale('de');
assert.equal(
ageChip(layer, 1).title,
'Maximales Ereignisalter: 1 Tag; undatierte Markierungen bleiben erhalten',
);
assert.equal(
ageChip(layer, 7).title,
'Maximales Ereignisalter: 7 Tage; undatierte Markierungen bleiben erhalten',
);
assert.equal(info(), 'Ereignisalter: 7 Tage · undatierte bleiben');
await ageChip(layer, 1).onClick();
assert.equal(info(), 'Ereignisalter: 1 Tag · undatierte bleiben');
setLocale('es');
assert.equal(
info(),
'Antigüedad: 1 día · se conservan los marcadores sin fecha',
);
});
test('age preferences persist independently of product choices and reject invalid storage', async (t) => {
const values = new Map([['gev.ghostmaps.products', '["cip"]']]);
const storage = {
@@ -69,38 +69,3 @@ test('the mission panel translates only the fallback status', (t) => {
assert.equal(shownStatus(UNKNOWN_LAUNCH_STATUS), 'Desconocido');
assert.equal(shownStatus('Launch Successful'), 'Launch Successful');
});
test('a confirmed landing position is worded apart from the CONFIRMED sightings chip', (t) => {
t.after(() => setLocale('en'));
const position = () =>
createPanel({
state: {
_selectedLaunchId: 'mission-1',
_launches: [
{
id: 'mission-1',
name: 'Example',
status: 'Launch Successful',
payloads: [],
recoveryStages: [
{
name: 'B1080',
endpoint: { lat: 28.41, lon: -80.6, accuracy: 'CONFIRMED' },
},
],
},
],
_replayTracks: new Map(),
},
parts: {
overlays: { shortMissionLabel: (name) => name },
policyHelpers: { missionPathPresentation: () => ({}) },
replay: { presentReplay: () => ({}) },
},
}).presentMission().stages[0].position;
assert.match(position(), / · CONFIRMED$/);
// One landing, singular: sv BEKRÄFTAD, where the sightings chip says
// BEKRÄFTADE.
setLocale('sv');
assert.match(position(), / · BEKRÄFTAD$/);
});
+167
View File
@@ -0,0 +1,167 @@
import * as Cesium from 'cesium';
import { TRANSIT_ENABLED_FEEDS } from '../../data/transitFeeds.js';
import { buildTransitCoveragePoints } from '../../data/transitCoverage.js';
import { COVERAGE_PEAK_ALPHA, coverageOpacityAt } from './policy.js';
/** Height of the spots above the ellipsoid, metres: on the surface. */
const SPOT_HEIGHT_M = 0;
/**
* A Gaussian falloff from the centre of each spot to exactly zero at its
* rim. No plateau and no edge, so overlapping spots sum into one smooth
* field instead of showing where each circle ends.
*/
const GLOW_SHADER = `
czm_material czm_getMaterial(czm_materialInput materialInput) {
czm_material material = czm_getDefaultMaterial(materialInput);
vec2 p = (materialInput.st - 0.5) * 2.0;
float sigma2 = 2.0 * 0.46 * 0.46;
float rim = exp(-1.0 / sigma2);
float glow = clamp((exp(-dot(p, p) / sigma2) - rim) / (1.0 - rim), 0.0, 1.0);
material.diffuse = color.rgb;
material.alpha = color.a * glow;
return material;
}`;
/**
* The coverage glow.
*
* Above the altitude gate the layer polls nothing and draws no vehicles, so
* a person looking at the whole Earth had no way to tell where Transit has
* anything to show. This draws one soft spot per feed seen live, built once
* from the registry: wide spots from orbit, cross-fading into patches the
* size of each feed's service area as a backdrop under the vehicles at
* continental and regional zoom, and off close in. Overlapping spots blend,
* so regions with many networks read hotter. It never polls a feed.
*
* Spots are flat discs drawn in the OPAQUE pass with ordinary alpha
* blending, not billboards and not draped imagery. Translucent billboards
* go through Cesium's order-independent transparency, whose weights clamp at
* orbital distances and turn a faint glow into a dark disc with a rim; and
* the photoreal tiles do not take a draped raster. A disc blended in the
* opaque pass is drawn over the tiles and the globe alike, under the vehicle
* markers, and is smooth at any strength.
*
* @param {object} context
* @returns {object}
*/
export function createCoverage({ state }) {
function batch(points, radiusKm, set) {
const [r, g, b] = points[0].rgb;
const material = new Cesium.Material({
translucent: false,
fabric: {
uniforms: { color: Cesium.Color.fromBytes(r, g, b, 0) },
source: GLOW_SHADER,
},
});
const vertexFormat =
Cesium.MaterialAppearance.MaterialSupport.TEXTURED.vertexFormat;
const primitive = new Cesium.Primitive({
geometryInstances: points.map(
(point) =>
new Cesium.GeometryInstance({
geometry: new Cesium.EllipseGeometry({
center: Cesium.Cartesian3.fromDegrees(point.lon, point.lat),
semiMajorAxis: radiusKm(point) * 1000,
semiMinorAxis: radiusKm(point) * 1000,
height: SPOT_HEIGHT_M,
vertexFormat,
}),
}),
),
appearance: new Cesium.MaterialAppearance({
material,
flat: true,
translucent: false,
materialSupport: Cesium.MaterialAppearance.MaterialSupport.TEXTURED,
renderState: {
// No depth test: at orbital distances the photoreal mesh is a few
// coarse facets that bulge kilometres off the ellipsoid, and a
// disc tested against it comes out speckled. Back-face culling
// does the hiding instead. A disc lies along the surface, so it
// faces away from the camera exactly when it is over the horizon.
depthTest: { enabled: false },
depthMask: false,
cull: { enabled: true, face: Cesium.CullFace.BACK },
blending: Cesium.BlendingState.ALPHA_BLEND,
},
}),
asynchronous: false,
allowPicking: false,
show: false,
});
state._viewer.scene.primitives.add(primitive);
// A regional patch is the network's real footprint, and neighbours there
// overlap far less than the wide orbit spots do, so it is not thinned.
const strength = set === 'near' ? 1 : points[0].strength;
return { primitive, material, strength, set };
}
function build() {
if (!state._viewer?.scene?.primitives) return null;
const buckets = new Map();
for (const point of buildTransitCoveragePoints(TRANSIT_ENABLED_FEEDS)) {
if (!buckets.has(point.bucket)) buckets.set(point.bucket, []);
buckets.get(point.bucket).push(point);
}
const batches = [];
for (const points of buckets.values()) {
batches.push(batch(points, (point) => point.farRadiusKm, 'far'));
batches.push(batch(points, (point) => point.nearRadiusKm, 'near'));
}
return batches;
}
/**
* Match the glow to the camera. Cheap enough for every camera event: the
* spots are built on the first call that needs them and never again, and a
* zoom only moves one colour uniform per batch.
* @param {number} altitude Camera height above the ellipsoid, metres.
*/
function sync(altitude) {
if (!state._enabled || !state._viewer) return;
const opacity = {
far: coverageOpacityAt(altitude, 'far'),
near: coverageOpacityAt(altitude, 'near'),
};
const key = `${opacity.far}/${opacity.near}`;
if (key === state._coverageOpacity) return;
state._coverageOpacity = key;
// Nothing built and nothing to show: do not build for a session that
// never leaves street level.
if (!state._coverageSpots) {
if (opacity.far === 0 && opacity.near === 0) return;
try {
state._coverageSpots = build();
} catch (error) {
// A host that cannot build geometry (headless tests) has no glow.
state._coverageSpots = [];
console.warn('[Data:Transit] Coverage glow unavailable:', error);
}
}
for (const entry of state._coverageSpots || []) {
const value = opacity[entry.set];
entry.primitive.show = value > 0;
entry.material.uniforms.color = Cesium.Color.clone(
entry.material.uniforms.color,
).withAlpha(value * COVERAGE_PEAK_ALPHA * entry.strength);
}
}
function hide() {
state._coverageOpacity = null;
for (const entry of state._coverageSpots || [])
entry.primitive.show = false;
}
function destroy() {
state._coverageOpacity = null;
for (const entry of state._coverageSpots || []) {
state._viewer?.scene?.primitives?.remove(entry.primitive);
}
state._coverageSpots = null;
}
return { sync, hide, destroy };
}
+2
View File
@@ -6,6 +6,7 @@ import { createRendering } from './rendering.js';
import { createSelection } from './selection.js';
import { createIngestion } from './ingestion.js';
import { createViewport } from './viewport.js';
import { createCoverage } from './coverage.js';
import { createQueries } from './queries.js';
import { createControls } from './controls.js';
import { createLifecycle } from './lifecycle.js';
@@ -49,6 +50,7 @@ export function createTransitLayer({
parts.selection = createSelection(context);
parts.rendering = createRendering(context);
parts.ingestion = createIngestion(context);
parts.coverage = createCoverage(context);
parts.viewport = createViewport(context);
parts.queries = createQueries(context);
parts.controls = createControls(context);
+3
View File
@@ -234,6 +234,7 @@ export function createLifecycle({ state, services, parts }) {
state._preRenderRemove = null;
}
parts.ingestion.abortAllInFlight();
parts.coverage.hide();
state._activeFeeds.clear();
state._feedStatus.clear();
for (const entry of state._vehicles.values()) {
@@ -267,6 +268,7 @@ export function createLifecycle({ state, services, parts }) {
async update() {
if (!state._enabled) return;
parts.ingestion.sweepAgedVehicles(Date.now());
parts.coverage.sync(parts.viewport.getCameraAltitude());
if (state._activeFeeds.size === 0) return;
const generation = state._generation;
await Promise.all(
@@ -282,6 +284,7 @@ export function createLifecycle({ state, services, parts }) {
*/
destroy(viewer) {
this.disable(viewer);
parts.coverage.destroy();
if (state._markers) {
unregisterSpriteCollection('transit', state._markers);
viewer?.scene?.primitives?.remove(state._markers);
+56
View File
@@ -31,6 +31,62 @@ export const TRANSIT_POLL_MS = 15_000;
*/
/** Camera altitude (m) above which the layer idles: a national fleet still reads at 3,000 km. */
export const ACTIVATION_ALTITUDE_M = 3_000_000;
/**
* How strongly the coverage glow shows at each camera height (m), as
* [height, opacity] stops joined by straight lines. There are two sets of
* spots and they cross-fade:
*
* - `far`: wide spots, far larger than any network, so coverage reads from
* orbit. Full above the altitude gate, gone by regional zoom.
* - `near`: patches the size of each feed's own service area, drawn as a
* backdrop under the vehicles at continental and regional zoom so a person
* can see which neighbouring cities are covered. Off close in, where a
* city's own vehicles are the picture.
*
* Between them there is no height from 250 km up with nothing drawn.
*/
export const COVERAGE_OPACITY_STOPS = Object.freeze({
far: Object.freeze([
Object.freeze([1_200_000, 0]),
Object.freeze([3_400_000, 1]),
]),
near: Object.freeze([
Object.freeze([60_000, 0]),
Object.freeze([250_000, 0.8]),
Object.freeze([1_500_000, 0.9]),
Object.freeze([3_400_000, 0]),
]),
});
/** Fine enough that a zoom reads as a continuous fade, not as steps. */
const COVERAGE_FADE_STEPS = 100;
/** Alpha at the centre of a lone spot at full strength. */
export const COVERAGE_PEAK_ALPHA = 0.9;
/**
* Opacity of one set of coverage spots at a camera height, quantized so a
* zoom does not restyle the glow on every camera event.
* @param {number} altitude Camera height above the ellipsoid, metres.
* @param {'far'|'near'} [set='far']
* @returns {number} 0..1
*/
export function coverageOpacityAt(altitude, set = 'far') {
const stops = COVERAGE_OPACITY_STOPS[set] || COVERAGE_OPACITY_STOPS.far;
const last = stops[stops.length - 1][1];
if (!Number.isFinite(altitude)) return altitude === Infinity ? last : 0;
let value = last;
if (altitude <= stops[0][0]) value = stops[0][1];
else {
for (let i = 1; i < stops.length; i++) {
if (altitude <= stops[i][0]) {
const [h0, v0] = stops[i - 1];
const [h1, v1] = stops[i];
value = v0 + ((v1 - v0) * (altitude - h0)) / (h1 - h0);
break;
}
}
}
return Math.round(value * COVERAGE_FADE_STEPS) / COVERAGE_FADE_STEPS;
}
export const ACTIVATION_ENTER_ALTITUDE_M = ACTIVATION_ALTITUDE_M - 150_000;
export const ACTIVATION_EXIT_ALTITUDE_M = ACTIVATION_ALTITUDE_M + 150_000;
/** Debounce (ms) for camera-change proximity checks. */
@@ -56,6 +56,7 @@ test('leaving a feed whose tick failed repaints its error away', async () => {
sweepAgedVehicles() {},
},
rendering: { requestVisibility() {}, syncRenderHold() {} },
coverage: { sync() {} },
};
parts.viewport = createViewport({ state, services, parts });
const queries = createQueries({ state, parts }).methods;
+3
View File
@@ -42,6 +42,9 @@ export function createState({ services }) {
state._cameraChangedAttached = false;
state._cameraDebounceTimer = null;
state._altitudeGateOpen = false;
/** Coverage glow: its draw batches and the last opacities drawn. */
state._coverageSpots = null;
state._coverageOpacity = null;
/** Camera sensitivity as we found it, so disable() can hand it back. */
state._priorPercentageChanged = null;
/** The value this layer actually wrote, for an identity-guarded restore. */
+3
View File
@@ -83,6 +83,7 @@ export function createViewport({ state, services, parts }) {
if (!state._enabled || !state._viewer) return;
refreshViewBounds();
const altitude = getCameraAltitude();
parts.coverage.sync(altitude);
const wasGateOpen = state._altitudeGateOpen;
state._altitudeGateOpen = altitudeGateOpen(altitude);
let changed = state._altitudeGateOpen !== wasGateOpen;
@@ -132,6 +133,8 @@ export function createViewport({ state, services, parts }) {
// A person dragging the globe should not wait a third of a second for the
// vehicles under the cursor to start moving again.
refreshViewBounds();
// The glow follows the zoom as it happens, not a third of a second later.
parts.coverage.sync(getCameraAltitude());
clearTimeout(state._cameraDebounceTimer);
state._cameraDebounceTimer = setTimeout(() => {
state._cameraDebounceTimer = null;
@@ -542,7 +542,7 @@ test('retention never revives an incumbent card after the observation window exp
test('all heights and the sampled fallback use the same sightings-in-view count label', () => {
const h = harness();
h.state.renderedRows = [sighting];
assert.equal(h.layer.getStats().countLabel, '1 sighting in view');
assert.equal(h.layer.getStats().countLabel, '1 sightings in view');
h.state.sightingCount = 2000;
assert.equal(h.layer.getStats().count, 2000);
assert.equal(
@@ -560,32 +560,6 @@ test('all heights and the sampled fallback use the same sightings-in-view count
}
});
test('the sightings count takes the plural form of its number', (t) => {
t.after(() => setLocale('en'));
const h = harness();
const label = (count) => {
h.state.sightingCount = count;
return h.layer.getStats().countLabel;
};
setLocale('ru');
assert.equal(label(1), '1 наблюдение в кадре');
assert.equal(label(3), '3 наблюдения в кадре');
assert.equal(label(5), '5 наблюдений в кадре');
setLocale('de');
assert.equal(label(1), '1 Beobachtung im Bild');
assert.equal(label(2000), '2.000 Beobachtungen im Bild');
});
test('the CONFIRMED chip names the sightings, apart from a confirmed launch landing', (t) => {
t.after(() => setLocale('en'));
const h = harness();
assert.equal(h.chip('quality-confirmed').label, 'CONFIRMED');
setLocale('sv');
assert.equal(h.chip('quality-confirmed').label, 'BEKRÄFTADE');
setLocale('es');
assert.equal(h.chip('quality-confirmed').label, 'CONFIRMADAS');
});
test('a stale fallback with a failed-refresh deadline remains DEGRADED, retryable and dated to the cached data', async () => {
const h = harness({
getSnapshotDetail: async () => ({
+5 -9
View File
@@ -1,4 +1,4 @@
import { t, tn, formatNumber, translateKnown } from '../../i18n/index.js';
import { t, formatNumber, translateKnown } from '../../i18n/index.js';
import { msg } from '../../i18n/marker.js';
import { translateFeedError } from '../../ui/statusText.js';
import { wildlifeIconicGroup } from './model.js';
@@ -137,8 +137,7 @@ export function createControls({ state, services, parts }) {
const chips = [
chip({
id: WILDLIFE_CONFIRMED_CHIP_ID,
// The sightings, plural; a launch landing is CONFIRMED alone.
label: t('CONFIRMED', { context: 'sightings filter' }),
label: t('CONFIRMED'),
title: t('Show only community-confirmed (research-grade) sightings'),
params: {
confirmed: confirmedFailed ? state.confirmed : !state.confirmed,
@@ -215,12 +214,9 @@ export function createControls({ state, services, parts }) {
stale: state.stale,
loading,
refreshing,
countLabel: tn(
count,
'{count} sighting in view',
'{count} sightings in view',
{ count: formatNumber(count) },
),
countLabel: t('{count} sightings in view', {
count: formatNumber(count),
}),
loadingLabel: loading
? t('loading...')
: refreshing
@@ -1987,7 +1987,7 @@ test('unavailable grids fail closed to visible sampled sprites without a global
assert.equal(h.clicks.collection.values[0].id, 'wildlife:inat:1');
assert.ok(h.clicks.collection.values[0].width * 0.5 >= 8);
assert.equal(h.layer.getStats().count, 1);
assert.equal(h.layer.getStats().countLabel, '1 sighting in view');
assert.match(h.layer.getStats().countLabel, /sightings in view/);
assert.equal(h.layer.getStats().partial, undefined);
assert.equal(layerFeedState(h.layer.getStats()), 'degraded');
assert.match(h.layer.getStats().error, /Malformed iNaturalist grid response/);
@@ -2024,7 +2024,7 @@ test('an oversized view coarsens to a complete grid within the six-tile cap', as
await h.update();
assert.equal(h.clicks.collection.values.length, 1);
assert.equal(h.clicks.collection.values[0].id, 'wildlife:inat:1');
assert.match(h.layer.getStats().countLabel, /sightings? in view/);
assert.match(h.layer.getStats().countLabel, /sightings in view/);
assert.equal(layerFeedState(h.layer.getStats()), 'nominal');
h.layer.destroy();
});
-40
View File
@@ -7,7 +7,6 @@ import assert from 'node:assert/strict';
import { createPinia } from 'pinia';
import { createApp, defineComponent, h, nextTick } from 'vue';
import { CockpitViewController } from './cockpitController.js';
import { setLocale } from '../i18n/index.js';
import { useCockpitStore } from './stores/cockpit.js';
import CockpitView from './views/CockpitView.vue';
import ContextView from './views/ContextView.vue';
@@ -356,33 +355,6 @@ test('the bridge radar shows nearby ships without its own and steps its range',
assert.ok(!$('#cockpit-radar') || $('#cockpit-radar').hidden);
});
test('the radar range and ring spacing agree with their distance (ru)', async (t) => {
const { $, cockpit } = fixture(t);
t.after(() => setLocale('en'));
setLocale('ru');
cockpit.enter();
await settle();
const shown = () => [
$('#cockpit-radar-range').textContent.trim(),
$('.cockpit-radar-rings').textContent.trim(),
];
// The ring spacing is a fraction at the short ranges: Intl.PluralRules
// gives 0.75 and 1.5 the form of their own.
const expected = [
['3 МОР. МИЛИ', 'КОЛЬЦА 0,75 МОР. МИЛИ'],
['6 МОР. МИЛЬ', 'КОЛЬЦА 1,5 МОР. МИЛИ'],
['12 МОР. МИЛЬ', 'КОЛЬЦА 3 МОР. МИЛИ'],
['24 МОР. МИЛИ', 'КОЛЬЦА 6 МОР. МИЛЬ'],
];
for (const [index, labels] of expected.entries()) {
if (index) {
$('#cockpit-radar-range').click();
await settle();
}
assert.deepEqual(shown(), labels);
}
});
test('contact navigation does not jump ship from the bridge', async (t) => {
const { cockpit, navigations } = fixture(t);
cockpit.enter();
@@ -1229,18 +1201,6 @@ test('a ship with no true heading is held, and labelled, on its course', async (
signals.some(([, , , detail]) => /COURSE 095°/.test(detail)),
JSON.stringify(signals),
);
// A ship's course has a word of its own: pt RUMO, an aircraft's CURSO.
t.after(() => setLocale('en'));
setLocale('pt');
signals.length = 0;
cockpit.exit();
await settle();
cockpit.enter();
await settle();
assert.ok(
signals.some(([, , , detail]) => /· RUMO 095°$/.test(detail)),
JSON.stringify(signals),
);
});
test('both entries name the subject the same way', async () => {
+2 -5
View File
@@ -1,5 +1,5 @@
/** Instrument values, routes and vision controls for the Cockpit controller. */
import { formatNumber, t, tn } from '../i18n/index.js';
import { formatNumber, t } from '../i18n/index.js';
import {
COCKPIT_VISION_MODES,
normalizeCockpitVisionMode,
@@ -379,10 +379,7 @@ export function updateRadar(info) {
);
this.publishRadar({
...picture,
// A plural, as the ring spacing is: ru «3 МОР. МИЛИ», «12 МОР. МИЛЬ».
rangeLabel: tn(rangeNm, '{range} NM', '{range} NM', {
range: formatNumber(rangeNm),
}),
rangeLabel: t('{range} NM', { range: formatNumber(rangeNm) }),
});
}
-8
View File
@@ -13,7 +13,6 @@ import { createPinia } from 'pinia';
import { createApp, defineComponent, h, nextTick } from 'vue';
import * as Cesium from 'cesium';
import { CockpitViewController } from './cockpitController.js';
import { setLocale, t as translate } from '../i18n/index.js';
import { useCockpitStore } from './stores/cockpit.js';
import { useHudStore } from './stores/hud.js';
import CockpitView from './views/CockpitView.vue';
@@ -535,13 +534,6 @@ test('a site row turns the camera onto it, holds it, and reads its off-nadir ang
assert.match(held.className, /^track actionable$/);
assert.match(held.detail, /^FOCUS · BASE · OFF-NADIR/);
assert.equal(siteRow(scene, 'alpha').getAttribute('aria-label'), 'Release the camera from Camp Alpha');
// The held site's FOCUS is a status, worded apart from the FOCUS command.
t.after(() => setLocale('en'));
setLocale('es');
await refreshRows(scene);
const heldEs = rows(scene).find((row) => row.target?.id === SITES.alpha.id);
assert.match(heldEs.detail, /^ENFOCADO · /);
assert.equal(translate('FOCUS'), 'ENFOCAR', 'the command keeps its verb');
});
test('another site row switches the focus; the held site row ends it', async (t) => {
+1 -2
View File
@@ -132,8 +132,7 @@ function siteRows(info, { settled = true } = {}) {
}),
});
const words = [installationClassLabel(site.class), angle];
// A status, not the FOCUS command: es «ENFOCADO», not «ENFOCAR».
if (focused) words.unshift(t('FOCUS', { context: 'site status' }));
if (focused) words.unshift(t('FOCUS'));
return {
key: `site:${site.id}`,
// The held site reads as the subject does.
-14
View File
@@ -7,7 +7,6 @@ import assert from 'node:assert/strict';
import { createPinia } from 'pinia';
import { createApp, defineComponent, h, nextTick } from 'vue';
import { CockpitViewController } from './cockpitController.js';
import { setLocale } from '../i18n/index.js';
import { useCockpitStore } from './stores/cockpit.js';
import CockpitView from './views/CockpitView.vue';
import ContextView from './views/ContextView.vue';
@@ -256,16 +255,3 @@ test('entering asks for a panel layout before Vue shows the cards', async (t) =>
await new Promise((resolve) => setTimeout(resolve, 50));
assert.deepEqual(laid, ['context', 'signals']);
});
test('an aircraft is acquired on its CURSO in Portuguese; a ship keeps RUMO', async (t) => {
const { cockpit } = fixture(t);
t.after(() => setLocale('en'));
setLocale('pt');
const signals = [];
cockpit.pushCockpitSignal = (...args) => signals.push(args);
cockpit.enter();
await nextTick();
const acquired = signals.find(([key]) => key === 'track');
assert.ok(acquired, JSON.stringify(signals));
assert.equal(acquired[3], 'UAL123 · CURSO 092°');
});
+1 -3
View File
@@ -326,11 +326,9 @@ export function enter({ kind = null } = {}) {
'track',
t('TRACK ACQUIRED'),
// A ship with no true heading is held on its course over ground; one
// with neither is named without a direction. A ship's course has a
// word of its own: pt «RUMO», where an aircraft's is «CURSO».
// with neither is named without a direction.
info.trackSource === 'course'
? t('{label} · COURSE {heading}°', {
context: 'vessel',
label: info.name,
heading: trackHeading,
})
+11 -34
View File
@@ -1,6 +1,6 @@
<script setup>
import { computed } from 'vue';
import { formatNumber, t, tn } from '../../i18n/index.js';
import { t } from '../../i18n/index.js';
import UiButton from '../kit/UiButton.vue';
import UiEmpty from '../kit/UiEmpty.vue';
import UiSelect from '../kit/UiSelect.js';
@@ -63,15 +63,9 @@ const categoryOptions = computed(() => [
const windowOptions = computed(() =>
(props.view?.windowChoices ?? []).map((hours) => ({
value: String(hours),
label: lastHours(hours),
label: t('Last {hours} h', { hours }),
})),
);
// The window offers 1 h, so every hour count is a plural: es «Última 1 h».
function lastHours(hours) {
return tn(hours, 'Last {hours} h', 'Last {hours} h', {
hours: formatNumber(hours),
});
}
// The longest choice is the server's whole window, kept as no choice.
const chooseWindow = (hours) =>
setFilter('hours', hours === props.view?.windowChoices?.[0] ? null : hours);
@@ -115,16 +109,7 @@ const clear = () => props.onParams({ clear: true });
<section
v-if="view"
class="news-readout"
:aria-label="
tn(
view.windowHours,
'News, last {hours} hour',
'News, last {hours} hours',
{
hours: formatNumber(view.windowHours),
},
)
"
:aria-label="t('News, last {hours} hours', { hours: view.windowHours })"
>
<UiSelect
v-if="windowOptions.length > 1"
@@ -135,7 +120,7 @@ const clear = () => props.onParams({ clear: true });
@update:model-value="chooseWindow(Number($event))"
/>
<p v-else class="news-readout__window ui-mono">{{
lastHours(view.windowHours)
t('Last {hours} h', { hours: view.windowHours })
}}</p>
<div
class="news-readout__sections"
@@ -211,12 +196,9 @@ const clear = () => props.onParams({ clear: true });
v-else-if="!view.inView.items.length && !view.inView.loading"
class="news-readout__empty"
:title="
tn(
view.windowHours,
'Nothing reported near here in the last {hours} h',
'Nothing reported near here in the last {hours} h',
{ hours: formatNumber(view.windowHours) },
)
t('Nothing reported near here in the last {hours} h', {
hours: view.windowHours,
})
"
/>
<ol
@@ -241,9 +223,7 @@ const clear = () => props.onParams({ clear: true });
class="news-readout__section"
:aria-label="t('Latest news')"
>
<h3 class="news-readout__head ui-mono">{{
t('Latest', { context: 'news list' })
}}</h3>
<h3 class="news-readout__head ui-mono">{{ t('Latest') }}</h3>
<UiEmpty
v-if="view.key"
class="news-readout__empty"
@@ -267,12 +247,9 @@ const clear = () => props.onParams({ clear: true });
v-else-if="!view.loading && !view.error"
class="news-readout__empty"
:title="
tn(
view.windowHours,
'No news matches these filters in the last {hours} h',
'No news matches these filters in the last {hours} h',
{ hours: formatNumber(view.windowHours) },
)
t('No news matches these filters in the last {hours} h', {
hours: view.windowHours,
})
"
/>
<div class="news-readout__footer">
-50
View File
@@ -1,7 +1,6 @@
import '../testSupport/registerDom.mjs';
import test from 'node:test';
import assert from 'node:assert/strict';
import { setLocale, t as translate } from '../i18n/index.js';
import { createNewsPanel } from './newsPanel.js';
import {
NEWS_CATEGORIES,
@@ -386,55 +385,6 @@ test('the window choice offers shorter windows; the longest is the server window
assert.deepEqual(calls.at(-1)[1], { filters: { hours: null } });
});
test('the time window agrees with its number of hours', (t) => {
t.after(() => setLocale('en'));
setLocale('es');
const { news, panel } = fixture();
news.update(view({ windowHours: 24, windowChoices: [24, 12, 6, 3, 1] }));
const choice = panel.querySelector(
'select.news-readout__window-choice, .news-readout__window-choice select',
);
assert.deepEqual(
[...choice.options].map((option) => option.textContent),
['Últimas 24 h', 'Últimas 12 h', 'Últimas 6 h', 'Últimas 3 h', 'Última 1 h'],
);
news.update(view({ windowHours: 1, items: [], hasMore: false }));
assert.equal(
panel.querySelector('.news-readout__window').textContent,
'Última 1 h',
);
assert.equal(
panel.querySelector('.news-readout').getAttribute('aria-label'),
'Noticias de la última 1 hora',
);
assert.match(
panel.textContent,
/En la última 1 h no hay noticias que coincidan con estos filtros/,
);
setLocale('ru');
news.update(view({ windowHours: 1, items: [], hasMore: false }));
assert.equal(
panel.querySelector('.news-readout').getAttribute('aria-label'),
'Новости за последний 1 час',
);
news.update(view({ windowHours: 12, items: [], hasMore: false }));
assert.equal(
panel.querySelector('.news-readout').getAttribute('aria-label'),
'Новости за последние 12 часов',
);
news.destroy();
});
test('the Latest news heading is worded apart from the timeline button (fr)', (t) => {
t.after(() => setLocale('en'));
setLocale('fr');
const { news, panel } = fixture();
news.update(view());
assert.equal(panel.querySelector('.news-readout__head').textContent, 'Dernières');
assert.equal(translate('Latest'), 'Dernière', 'the timeline keeps its own');
news.destroy();
});
test('the panel names the window the server serves', () => {
const { news, panel } = fixture();
news.update(view({ windowHours: 12 }));
+1 -3
View File
@@ -118,11 +118,9 @@ const ringFractions = computed(() =>
? radar.value.ringsNm.map((ring) => ring / radar.value.rangeNm)
: [],
);
// The spacing is a fraction at the shorter ranges (0.75, 1.5 NM), which
// Intl.PluralRules gives a form of its own: ru «0,75 МОР. МИЛИ».
const ringLabel = computed(() =>
radar.value?.ringsNm.length
? tn(radar.value.ringsNm[0], 'RINGS {spacing} NM', 'RINGS {spacing} NM', {
? t('RINGS {spacing} NM', {
spacing: formatNumber(radar.value.ringsNm[0]),
})
: '',
@@ -163,20 +163,6 @@ test('filters narrow the list as the viewer types and picks', async (t_) => {
assert.deepEqual(shownIds(), ['nasa-eonet-events']);
});
test('the shown count agrees with its number (he)', async (t_) => {
const { owner } = mount(t_);
setLocale('he');
owner.open();
await settle();
const status = () => $('.data-library-status').textContent.trim();
assert.match(status(), /^מוצגים\s+\S*3\S*\s+מתוך/);
const search = $('#data-library input[type="search"]');
search.value = 'eonet';
search.dispatchEvent(new Event('input'));
await settle();
assert.match(status(), /^מוצג\s+\S*1\S*\s+מתוך/);
});
test('Add becomes Remove on the same focused button; Zoom closes first', async (t_) => {
const { owner, library } = mount(t_);
owner.open();
+5 -11
View File
@@ -1,7 +1,7 @@
<script setup>
import { storeToRefs } from 'pinia';
import { computed, nextTick, useTemplateRef, watch } from 'vue';
import { formatNumber, t, tn } from '../../../i18n/index.js';
import { t, tn } from '../../../i18n/index.js';
import UiButton from '../../kit/UiButton.vue';
import UiSelect from '../../kit/UiSelect.js';
import {
@@ -53,18 +53,12 @@ watch(
const tiles = computed(() => libraryStatTiles(props.view.summary));
const themes = computed(() => libraryThemeOptions());
// The words for the shown entries agree with their count: he «מוצג 1».
const status = computed(() =>
props.view.ready
? tn(
props.view.shown.length,
'Showing {shown} of {total}',
'Showing {shown} of {total}',
{
shown: formatNumber(props.view.shown.length),
total: formatNumber(props.view.total),
},
)
? t('Showing {shown} of {total}', {
shown: props.view.shown.length,
total: props.view.total,
})
: t('Checking what this instance serves…'),
);
const resetText = computed(() => {
-2
View File
@@ -3917,8 +3917,6 @@ async function requestStreetLevel(
};
// Then the place: a name that geocodes to nothing changes nothing else.
// "the view centre" is English for the model; the card (speech.js) gives
// it messages of its own, since it is a phrase and not a place name.
label =
query ||
(entity ? String(entity.label || entity.id) : '') ||
+11 -32
View File
@@ -332,16 +332,6 @@ const ERROR_PATTERNS = [
place: localizePlaceName(place),
}),
],
// show_street_level names no place when it looks at the view centre. The
// phrase is not a name: it has a message of its own, so each language
// words it in the case its preposition asks for.
[
/^No (.+) imagery near the view centre$/,
([, source]) =>
t('No {source} imagery near the view centre', {
source: translateKnown(source),
}),
],
[
/^No (.+) imagery near (.+)$/,
([, source, place]) =>
@@ -1122,21 +1112,14 @@ export function planStepLabel(name, args = {}) {
}
case 'show_street_level': {
const source = STREET_LEVEL_SOURCE_NAMES[args.provider];
// "This spot" and "the view centre" are phrases, not place names:
// each is a message of its own, worded in the grammar of the language.
if (args.query) {
const place = shownPlace(args.query, 32);
return source
? t('{source} at {place}', { source, place })
: t('Street level at {place}', { place });
}
if (args.latitude != null)
return source
? t('{source} at this spot', { source })
: t('Street level at this spot');
const place = args.query
? shownPlace(args.query, 32)
: args.latitude != null
? t('this spot')
: t('the view centre');
return source
? t('{source} at the view centre', { source })
: t('Street level at the view centre');
? t('{source} at {place}', { source, place })
: t('Street level at {place}', { place });
}
case 'set_layer_visibility': {
const on = args.enabled !== false;
@@ -1212,9 +1195,6 @@ export function narrationLabel(name, args = {}) {
}
}
/** The place show_street_level reports when it names none (gevActions). */
const VIEW_CENTRE_LABEL = 'the view centre';
/** On-screen labels for progress steps. */
const STEP_LABELS = Object.freeze({
resolve: msg('Finding places'),
@@ -1239,11 +1219,10 @@ export function progressStepLabel(step, label) {
: step
? spokenLabel(step, 24)
: t('Working');
// The join is a catalog string so each language spaces its colon. The
// view centre is a phrase show_street_level reports in English, not a name.
const state =
label === VIEW_CENTRE_LABEL ? t('the view centre') : spokenLabel(label, 32);
return label ? t('{name}: {state}', { name: base, state }) : base;
// The join is a catalog string so each language spaces its colon.
return label
? t('{name}: {state}', { name: base, state: spokenLabel(label, 32) })
: base;
}
/**
+1 -49
View File
@@ -10,7 +10,7 @@ import {
} from './speech.js';
import { presentResult } from './resultDisplay.js';
import { countWords, findHedges } from './speechLint.js';
import { setLocale, t } from '../i18n/index.js';
import { setLocale } from '../i18n/index.js';
function envelope(name, result, args) {
return attachVoiceResult(name, result, args);
@@ -779,51 +779,3 @@ test('progress step labels join through the catalog colon', () => {
setLocale('en');
}
});
test('the street-level card words "the view centre" and "this spot" as phrases, not names', () => {
setLocale('de');
try {
assert.equal(
planStepLabel('show_street_level', { provider: 'mapillary' }),
'Mapillary in der Bildmitte',
);
assert.equal(
planStepLabel('show_street_level', { latitude: 1, longitude: 2 }),
'Straßenebene an dieser Stelle',
);
assert.equal(
planStepLabel('show_street_level', { query: 'Alexanderplatz', provider: 'kartaview' }),
'KartaView: Alexanderplatz',
);
const empty = envelope('show_street_level', {
ok: false,
stage: 'imagery',
noImagery: true,
atViewCentre: true,
label: 'the view centre',
providerName: 'Mapillary',
error: 'No Mapillary imagery near the view centre',
});
assert.deepEqual(empty.display.lines, [
'Keine Bilder von Mapillary in der Nähe der Bildmitte',
]);
assert.equal(empty.say, 'No Mapillary imagery near the view centre.');
const named = envelope('show_street_level', {
ok: false,
stage: 'imagery',
noImagery: true,
label: 'Alexanderplatz',
providerName: 'Mapillary',
error: 'No Mapillary imagery near Alexanderplatz',
});
assert.deepEqual(named.display.lines, [
'Keine Bilder von Mapillary in der Nähe von Alexanderplatz',
]);
assert.equal(
progressStepLabel('imagery', 'the view centre'),
`${t('Opening imagery')}: die Bildmitte`,
);
} finally {
setLocale('en');
}
});