# Tachwire camera data — sources and licence

`es.json` (Spain) is built by `tools/cameras/build_es.py` from the sources below. It is published
openly at https://tachwire.app/data/cameras/es.json; `index.json` next to it gives the current
version and its SHA-256.

## Licence of the database

`es.json` contains data from OpenStreetMap and is therefore a Derived Database made available under
the **Open Database License (ODbL) 1.0**: https://opendatacommons.org/licenses/odbl/1-0/ .
You may copy, adapt and share it under the same licence, with the attributions below. Individual
contents keep their own licences (CC BY 4.0 and the Spanish public-sector reuse terms), which require
the attributions listed here.

## Attributions

Each entry of `sources` in `es.json` carries `attribution` (the wording below, with the source's own
date), `licenceURL` and `changes`. The app shows them under Road cameras → Data sources and More →
Licenses, always with the date of the source; https://tachwire.app/licenses shows the same list.
The formulas are given in the publisher's language, as their terms prescribe.

- **OpenStreetMap** — camera points where no official list exists (records with `"source": "osm"`),
  and part of the speed limits (see below):
  "Contains information from OpenStreetMap, © OpenStreetMap contributors, available under the Open
  Database License (ODbL)" — https://www.openstreetmap.org/copyright
- **Dirección General de Tráfico (DGT)**, lists published on dgt.es — fixed radars and section control
  ("Puntos y tramos de control de velocidad"), automatic enforcement devices ("Equipos automáticos de
  detección de infracciones"): "Fuente: Dirección General de Tráfico (DGT), dgt.es — actualizado DD.MM.AAAA".
- **DGT, National Access Point** (nap.dgt.es, CC BY 4.0) — radar coordinates and low-emission zones:
  "© DGT — Punto de Acceso Nacional (nap.dgt.es), CC BY 4.0 — actualizado DD.MM.AAAA". Modified.
- **Instituto Geográfico Nacional (IGN)** — kilometre posts used to turn road + PK into coordinates and
  direction: "Obra derivada de IGR-RT AAAA CC-BY 4.0 scne.es". Modified.
- **Servei Català de Trànsit, Generalitat de Catalunya** — fixed radars and section control in Catalonia
  (radars.txt), and the places where its speed-camera trailers are set up (radars-remolc.txt, records
  with `"source": "sct-radars-remolc"`): "© Generalitat de Catalunya — Servei Català de Trànsit,
  actualitzat DD.MM.AAAA". Modified.
- **Ayuntamiento de Madrid** — radars, red-light cameras, low-emission-zone cameras and Distrito Centro
  cameras (datos.madrid.es, CC BY 4.0): "Origen de los datos: Ayuntamiento de Madrid (CC BY 4.0), DD.MM.AAAA".
  Modified.
- **Ayuntamiento de Málaga** — red-light cameras (datosabiertos.malaga.eu): "Datos: Ayuntamiento de
  Málaga (CC BY 4.0), DD.MM.AAAA". Modified. The portal labels the set "CC BY 4.0" in its title and
  "CC BY-SA 4.0" in its licence field.

The full texts of the licences: ODbL 1.0 in `LICENSE.txt` next to this file; CC BY 4.0 at
https://creativecommons.org/licenses/by/4.0/legalcode .

## Changes made to the source data

- Road + PK positions are interpolated between IGN kilometre posts; DGT's own NAP coordinates are used
  where the same radar appears there.
- The direction of travel (`bearing`) comes from the road geometry and the PDF's "Creciente/Decreciente";
  OpenStreetMap `direction` fills it where an official point has none.
- Directions from the OpenStreetMap road under a point (since 04.10.2026): a point with no direction
  gets the axis of the nearest road within 20 m and `bothWays: true`; an OpenStreetMap
  `direction=forward`/`backward` becomes the bearing of the way at the point; an OpenStreetMap
  `direction` that runs against the one-way road under it (within 15 m, more than 145° off) is turned
  round; a Servei Català de Trànsit point whose direction an OpenStreetMap camera within 50 m gave it,
  and which lies on the one-way carriageway running the other way, is moved onto that camera's position.
- OpenStreetMap points that fine nobody are left out: speed displays (`speed_camera=display`, `fine=no`,
  or a note such as "radar pedagògic, no multa" — Barcelona's educational displays).
- Speed-camera trailer places (`"type": "mobile_trailer"`) are announced as a possible mobile radar, not
  as a fixed camera, and carry no over-the-limit tone. OpenStreetMap speed points within 150 m of such a
  place are dropped in favour of it; a place within 150 m of a fixed official speed camera is left out
  (the camera is there). OpenStreetMap points mapped as a trailer place ("radar de remolque") and not
  in the official list keep that type.
- Duplicates closer than 30 m (same type and direction) are merged; OpenStreetMap points within 150 m of an
  official camera of the same kind are dropped in favour of the official one.
- Low-emission zones: one entry per DGT `controlledZone` (one set of rules), its polygons as `parts`
  with `holes` — a polygon inside another and wound the other way is a hole (Barcelona's Rondes), one
  inside and wound the same way adds nothing and is left out; polygons simplified to about 10 m (finer
  where 10 m would make two outlines cross); pieces under 200 m² left out. The same zone published
  twice keeps the newest record (Barcelona: `RondasDeBarcelona.xml` of 2025, with the Ronda holes of the
  2023 record that lie inside it); a file carrying another town's zone (`Lleida.xml`'s "ZBE Terrassa",
  which is Rubí's polygon) gives way to that town's own record. `labels` is the set of environmental
  stickers that may not enter, read from DGT's sticker condition. `hours` is given where the schedule
  is certain (DGT's times are local whatever their "Z" says; Catalan "working days" are Monday to
  Friday without public holidays). Format of the zone fields: see "Zones" at the end of this file.
- Speed limits (`limit`) partly come from OpenStreetMap; each camera's `limitSource` says where its
  limit came from: `"official"` — the source list itself; `"osm-camera"` — the `maxspeed` of an OSM
  camera at the same place; `"osm-road"` — the `maxspeed` of the OSM road the camera stands on (the
  nearest road within 20 m running in the camera's direction; only plain numbers in km/h, the
  direction-specific `maxspeed:forward`/`backward` where present; for section control only when the
  road's limit at the start and at the end agree). `null` when the limit is unknown.
- `limitVariable: true` (present only when true) marks a camera whose limit is not one fixed number at
  all times: OpenStreetMap tags the camera, or the road under it in the camera's direction, with
  `maxspeed=signals`/`variable`, a `maxspeed:variable*` key or a `maxspeed:conditional` (time or
  condition dependent limit). `limit` is kept as published. A section with the mark at one end has it
  at both. When an OpenStreetMap camera so tagged is merged into an official one, the official camera
  takes the mark. None of the official Spanish lists says which limits are variable.
- Mobile-radar stretches are not included; the Servei Català de Trànsit trailer places are (above).

---

# France — `fr.json`

`fr.json` is built by `tools/cameras/build_fr.py` and published at
https://tachwire.app/data/cameras/fr.json (current version and SHA-256 in `index.json`).

## What it contains, and why no cameras

French law (Code de la route, art. R413-15, as amended by décret n° 2012-3) forbids any device that
warns of, or informs about, the location of enforcement equipment. Following the protocol signed by
the driver-assistance makers (AFFTAC) with the Ministry of the Interior on 28.07.2011, `fr.json`
carries no camera positions and no camera types:

- `cameras` is always empty;
- `dangerZones` are «zones de danger»: stretches of road at least 4 km long on motorways, 2 km
  outside built-up areas and 300 m in built-up areas, drawn along the OpenStreetMap road network.
  A zone may or may not contain enforcement equipment; nothing in it says what, where or how many.
  Each entry has `id`, `road`, `bearing` (direction of travel at the start, `null` when the zone
  applies both ways), `bothWays`, `limit` (km/h or `null`), `limitSource`, `path` (polyline
  `[[lat, lon], …]` in the direction of travel, simplified to about 10 m), `lengthM`, `kind`
  (`motorway` | `rural` | `urban`), `source` and `listDate`, and `limitVariable: true` (present only
  when true) where an OpenStreetMap road along the zone has a variable or conditional limit, as for
  `es.json`;
- `zones` are the low-emission zones (ZFE) in force for passenger cars, with `labels` = the Crit'Air
  classes that may not enter and the schedule as published.

## Licence of the database

`fr.json` contains data from OpenStreetMap (the zones follow its roads) and is therefore a Derived
Database made available under the **Open Database License (ODbL) 1.0**, like `es.json`. The French
public-sector data in it is reused under the **Licence Ouverte / Open Licence 2.0** (Etalab), which
asks for the source and the date of its last update, given below.

## Attributions

- **Ministère de l'Intérieur — « Liste des radars fixes en France »** (data.gouv.fr, Licence Ouverte
  2.0): "Source : Ministère de l'Intérieur — « Liste des radars fixes en France », data.gouv.fr,
  mise à jour du JJ.MM.AAAA". Modified: used only to build the danger zones.
- **Sécurité routière — carte des radars** (radars.securite-routiere.gouv.fr; public-sector
  information, free reuse under CRPA art. L321-1): "Source : Sécurité routière —
  radars.securite-routiere.gouv.fr, consulté le JJ.MM.AAAA". Modified: used only to build the danger
  zones (the radars the national list lacks, direction of travel, road, length of average-speed
  sections, the speed limit for cars).
- **Base nationale consolidée des zones à faibles émissions** (transport.data.gouv.fr, Licence
  Ouverte 2.0): "Source : Base nationale consolidée des zones à faibles émissions —
  transport.data.gouv.fr, mise à jour du JJ.MM.AAAA". Modified.
- **OpenStreetMap** (Geofabrik extract of France, ODbL 1.0): "Contains information from
  OpenStreetMap, © OpenStreetMap contributors, available under the Open Database License (ODbL)" —
  https://www.openstreetmap.org/copyright

## Changes made to the source data

- Each radar becomes a zone of the minimum length of its class (motorway, outside or inside a
  built-up area; any doubt goes to the longer class), laid along the road in the direction of
  travel; the radar sits at an undisclosed place inside it, well after the start of the zone except
  where the road begins at a junction it cannot be followed through. The class comes from the road type,
  the French implicit-limit tags of OpenStreetMap (FR:urban, FR:rural, FR:motorway) and the speed
  limit.
- The direction of travel comes from the radar card's «A vers B» text (matched to OpenStreetMap
  places), else from OpenStreetMap enforcement relations; when it is unknown the zone applies both
  ways (on dual carriageways, one zone per carriageway).
- Average-speed sections become one zone covering the whole section (both possible sides of the
  published point when OpenStreetMap does not tell which end it is) plus margins.
- Overlapping or adjacent zones on the same road and direction are merged into one; a zone and its
  exact reverse become one zone with `bothWays`.
- `limit` is the official limit of the radars inside the zone (card «Vitesse VL», else the list's
  VMA; `limitSource` `"official"`) when OpenStreetMap does not contradict it at a radar or over more
  than a fifth of the zone; else the numeric OpenStreetMap `maxspeed` when one value covers the zone
  and its radars (`"osm-road"`); else `null`.
- ZFE: only the rows in force on the build date that restrict passenger cars; the strictest row
  when several are in force for the same area; one zone per row, all its polygons and holes as `parts`;
  polygons simplified to about 10 m, pieces under 200 m² left out; `from`/`until` span the rows in force
  for the same area; `hours` from `vp_horaires` where it reads unambiguously.
- Mobile-radar routes are not included.

---

# Portugal — `pt.json`

`pt.json` is built by `tools/cameras/build_pt.py` and published at
https://tachwire.app/data/cameras/pt.json (current version and SHA-256 in `index.json`). Same format
as `es.json`: fixed speed cameras (`speed`), average-speed sections (`section_start` / `section_end`
pairs sharing `section`) and Lisbon's low-emission zones (`zones`).

## Licence of the database

`pt.json` contains data from OpenStreetMap and is therefore a Derived Database made available under
the **Open Database License (ODbL) 1.0**, like `es.json`. The other contents keep their own terms,
which ask for the attributions below.

## Attributions

- **ANSR — Autoridade Nacional de Segurança Rodoviária**, SINCRO speed-control places published on
  radaresavista.pt (the PDF list "Locais de Controlo de Velocidade do SINCRO" and the map's
  coordinates; terms: https://radaresavista.pt/termos-e-condicoes/): "Fonte: ANSR — Autoridade
  Nacional de Segurança Rodoviária, radaresavista.pt — atualizado DD.MM.AAAA". Modified.
- **Câmara Municipal de Lisboa** — "Localização de radares" (dados.cm-lisboa.pt, CC0 1.0):
  "Fonte: Câmara Municipal de Lisboa — dados.cm-lisboa.pt (CC0), DD.MM.AAAA". Modified.
- **Câmara Municipal de Lisboa** — "Zonas de Emissões Reduzidas" (dados.cm-lisboa.pt; CC BY 4.0 on
  the portal, the map layer itself states CC0): "© Câmara Municipal de Lisboa — dados.cm-lisboa.pt,
  DD.MM.AAAA". Modified.
- **OpenStreetMap** (ODbL 1.0) — camera points the official lists lack (records with
  `"source": "osm"`), the road network used for positions, directions and section ends, and part of
  the speed limits: "Contains information from OpenStreetMap, © OpenStreetMap contributors, available
  under the Open Database License (ODbL)" — https://www.openstreetmap.org/copyright

## Changes made to the source data

- ANSR's PDF list decides which places exist (only "Instalado"; its road, kilometre, side, direction
  words and limit win over the map's); the map gives their coordinates, matched by road, kilometre,
  type and direction.
- Every point is moved onto the nearest suitable OpenStreetMap road within 30 m (never further). The
  direction of travel (`bearing`) is that road's heading, on the carriageway that runs the list's
  "Norte-Sul" / "Sul-Norte" / "Este-Oeste" / "Oeste-Este"; where the road crosses that course and
  the words cannot tell the carriageways apart, the direction of an OpenStreetMap camera within
  120 m decides. "Ambos" (C/D) places work both ways (`bothWays`).
- Average-speed sections: the published coordinate is the start; the end is found by following the
  road for the published length (Km final − Km inicial), and taken from an OpenStreetMap
  `enforcement=average_speed` relation's `to` member where one ends within 600 m of that point.
  A section published for both directions becomes two sections, one per direction. Where neither
  OpenStreetMap nor the kilometre direction tells which way the kilometres grow, the end lying in
  the second municipality the PDF names is used.
- Lisbon's radars: the layer's `ANGLE` is a map-symbol rotation that does not match the roads, so the
  direction comes from the carriageway the radar stands on (both ways on a two-way street).
- OpenStreetMap cameras within 150 m of an official camera of the same kind are dropped in favour of
  the official one (lending it their `maxspeed` where it has no limit); OpenStreetMap cameras closer
  than 30 m to each other are merged; nodes or relations whose tags cite a commercial camera database
  are not used; radars marked as only triggering a traffic light are not included.
- `limitSource` as for `es.json`: `"official"`, `"osm-camera"`, `"osm-road"` (numeric `maxspeed` of
  the road within 20 m in the camera's direction; for a section only when both ends agree), or
  `null`.
- `limitVariable` as for `es.json`.
- ZER polygons are simplified to about 10 m; `labels` is the minimum Euro emission standard the zone
  requires ("Euro 3" for ZER 1, "Euro 2" for ZER 2); the schedule is not in the data and is left out.
  ZER 1 is cut out of ZER 2 and carries `parent` = ZER 2.
- Mobile radars (PSP/GNR monthly announcements) are not included.

---

# Italy — `it.json`

`it.json` is built by `tools/cameras/build_it.py` and published at
https://tachwire.app/data/cameras/it.json (current version and SHA-256 in `index.json`). Same format
as `es.json`, plus `city` on ZTL and low-emission-zone gates and `kind` (`"ztl"` | `"lez"`) on zones:

- `ztl_access` — gates of limited-traffic zones (ZTL; Milan's Area C; pedestrian-area gates);
- `zbe_access` — gates of low-emission zones (Milan's Area B, Florence's Scudo Verde);
- `bus_lane` — bus-lane cameras (Bologna, Florence); `other` — Florence "porte telematiche" whose
  purpose the source does not state;
- `speed`, `section_start` / `section_end` (Tutor average-speed sections), `red_light`;
- `zones` — ZTL outlines (Milan, Turin, Bologna, Bergamo, Cremona, Pavia, Genoa, Trento) and the
  low-emission zone Area B.

Italian law (Codice della Strada, art. 45 c. 9-bis) forbids devices that signal and locate speed
enforcement devices (art. 142 c. 6); the Ministry of the Interior's circolare 300/A/1/24236/144/5/20/5
of 06.07.2007 does not count navigators that hold a list of fixed posts among them. The file is such a
list: fixed posts, which art. 142 c. 6-bis requires to be signed and visible, and Tutor sections as their
operators publish them — nothing about whether a device is working, and no mobile posts. The app
announces the posts and the sections with their limits, and does not compute a section's average speed.

## Licence of the database

`it.json` contains data from OpenStreetMap and is therefore a Derived Database made available under
the **Open Database License (ODbL) 1.0**, like `es.json`. The municipal and regional open data in it
is reused under **CC BY 4.0** or **CC0 1.0** as stated by each publisher, with the attributions below.

## Attributions

Open data:

- **Comune di Milano** — "Varchi Area C", "Varchi Area B", "Aree pedonali e ZTL" (dati.comune.milano.it,
  CC BY 4.0): "Fonte: Comune di Milano — CC BY 4.0, GG.MM.AAAA". Modified.
- **Città di Torino / 5T** — "Perimetro, varchi e orari ZTL" (CC BY 4.0): "Fonte: Città di Torino / 5T —
  CC BY 4.0, GG.MM.AAAA". Modified.
- **Comune di Bologna** — "Elenco varchi", "Zona a traffico limitato", "Zona T" (opendata.comune.bologna.it,
  CC BY 4.0): "Fonte: Comune di Bologna — CC BY 4.0, GG.MM.AAAA". Modified.
- **Comune di Firenze** — "Porte telematiche", "Varchi Scudo Verde" (opendata.comune.fi.it, CC BY 4.0):
  "Fonte: Comune di Firenze — CC BY 4.0, GG.MM.AAAA". Modified.
- **Regione Lombardia** — ZTL gates of Bergamo, Cremona, Busto Arsizio, Pavia, Lecco (CC0 1.0) and Rho
  (CC BY 4.0); ZTL maps of Bergamo, Cremona, Pavia (CC BY 4.0) (dati.lombardia.it): "Fonte: Regione
  Lombardia — dati.lombardia.it (CC0 1.0 / CC BY 4.0), GG.MM.AAAA". Modified.
- **Regione Piemonte** — ZTL gates of Biella and Pinerolo (Yucca Smart Data Platform, CC BY 4.0):
  "Fonte: Regione Piemonte — Yucca Smart Data Platform — CC BY 4.0, GG.MM.AAAA". Modified.
- **Comune di Genova**, **Comune di Trento** — ZTL outlines (CC BY 4.0): "Fonte: Comune di Genova —
  CC BY 4.0, GG.MM.AAAA", "Fonte: Comune di Trento — CC BY 4.0, GG.MM.AAAA". Modified.
- **OpenStreetMap** (Geofabrik extract of Italy, ODbL 1.0) — cameras and gates the official lists lack
  (records with `"source": "osm"`), the road network used for positions, directions, Tutor section
  ends and part of the speed limits: "Contains information from OpenStreetMap, © OpenStreetMap
  contributors, available under the Open Database License (ODbL)" —
  https://www.openstreetmap.org/copyright

Lists published by public bodies without an open licence (reused with the source cited; the build
option `--open-only` leaves them out):

- **Polizia di Stato / Ministero dell'Interno — Servizio Polizia Stradale** — fixed speed-control posts
  on motorways and ordinary roads (poliziadistato.it, "Autovelox e tutor: dove sono"): "Fonte:
  Ministero dell'Interno — Servizio Polizia Stradale, GG.MM.AAAA". Modified.
- **Polizia di Stato** — "Elenco tratti controllati con il Tutor": "Fonte: Polizia di Stato — tratti
  controllati con il Tutor, aggiornato al GG.MM.AAAA". Modified.
- **Autostrade per l'Italia** — "Tratte autostradali con sistema Tutor" (autostrade.it/tutor): "Fonte:
  Autostrade per l'Italia — tratte autostradali con sistema Tutor, GG.MM.AAAA". Modified.

## Changes made to the source data

- Gates are moved onto the nearest OpenStreetMap road within 30 m. Their direction of travel is the
  way into the zone (towards the zone's inside or the city centre on a two-way street, the street's
  own direction on a one-way street); Turin's gates keep their published heading; Florence's Scudo
  Verde "OUT" gates face out of the zone; Bologna's gates follow the list's "centro" / "periferia".
- Milan's Area B gates are kept whatever their `stato` (active, pre-operation): the cameras stand
  there. Gates of one source closer than 25 m with the same direction are merged.
- Zone outlines are simplified to about 10 m (finer where 10 m would make two outlines cross); Trento's
  outline is converted from ETRS89 / UTM 32N. One zone per named ZTL of a city: every feature with that
  name adds its polygons, holes kept; identical copies (Genoa lists most of its ZTLs 5 to 15 times) and
  pieces lying inside another piece are left out, as are pieces under 200 m²; Genoa's numbered
  sub-zones are parts of their ZTL. A hole that crosses its own outline in the source is left out.
  `hours` only for Area B and Area C (working days 7:30–19:30); the other timetables are free text.
- `limit`: a value taken from OpenStreetMap outside 20–130 km/h is a mapping slip and is left out.
  Schedules are given where the source has them (Turin; Area B and Area C weekday hours).
- Polizia fixed posts (road + kilometre + comune): placed with OpenStreetMap kilometre posts, or by
  walking the carriageway from a junction whose kilometre Autostrade per l'Italia lists, or at the one
  OpenStreetMap camera on that road near the comune running the listed direction. Posts that cannot be
  placed that way (unnamed roads, no posts, several candidate cameras) are left out.
- Tutor sections: Autostrade per l'Italia's sections are placed at their named OpenStreetMap
  junctions, or found by walking the carriageway for the listed kilometres from a junction or
  kilometre post; a section running against the list's "Dir." is left out. The Polizia list adds only
  the sections of other operators, placed at the named junctions.
- OpenStreetMap: `highway=speed_camera` nodes, `enforcement=*` nodes and `type=enforcement` relations
  (maxspeed → `speed`, traffic_signals / red_light_camera → `red_light`, access → `ztl_access`,
  average_speed with `from` and `to` → a section). Left out: points outside Italy's border (the
  extract's border buffer, San Marino, the Vatican), cameras tagged as disused, removed, mobile or
  fake, cameras whose tags cite a commercial camera database, average-speed nodes without a section
  relation, and "sections" whose ends are under 500 m apart. OpenStreetMap points near an official
  point of the same kind (speed 150 m, red light 50 m, gates 35 m) are dropped in favour of it.
- `limitSource` as for `es.json`: `"osm-camera"`, `"osm-road"` (numeric `maxspeed` of the road within
  20 m in the camera's direction; for a section only when both ends agree), or `null`. No official
  Italian list gives limits.
- `limitVariable` as for `es.json`.
- Mobile speed checks (the Polizia weekly lists) are not included.

---

# Poland — `pl.json`

`pl.json` is built by `tools/cameras/build_pl.py` and published at
https://tachwire.app/data/cameras/pl.json (current version and SHA-256 in `index.json`). Same format
as `es.json`: fixed speed cameras (`speed`), average-speed sections (`section_start` / `section_end`
pairs sharing `section`), red-light cameras (`red_light`) and red-light cameras at railway level
crossings (`level_crossing`, a type of its own; an app that does not know it skips the point). No
zones: Warsaw's and Kraków's clean-transport zones (SCT) publish no official geometry.

## Licence of the database

`pl.json` contains data from OpenStreetMap and is therefore a Derived Database made available under
the **Open Database License (ODbL) 1.0**, like `es.json`. GITD's contents are public-sector
information that GITD makes available without reuse conditions (ustawa z dnia 11 sierpnia 2021 r. o
otwartych danych i ponownym wykorzystywaniu informacji sektora publicznego, Dz.U. 2021 poz. 1641);
GITD publishes the same list on dane.gov.pl under CC0 1.0.

## Attributions

- **Główny Inspektorat Transportu Drogowego (GITD) — CANARD**, "Mapa urządzeń"
  (https://www.canard.gitd.gov.pl/cms/web/guest/o-nas/mapa-urzadzen): the devices, their positions,
  the end of each average-speed section, road number and kilometre, the limit for cars and whether it
  applies with the kilometre increasing or decreasing: "Źródło: Główny Inspektorat Transportu
  Drogowego — CANARD, canard.gitd.gov.pl, stan na DD.MM.RRRR". Modified.
- **OpenStreetMap** (ODbL 1.0) — the road network, milestones (`highway=milestone`) and level
  crossings (`railway=level_crossing`) used for positions, directions and the level-crossing type:
  "Contains information from OpenStreetMap, © OpenStreetMap contributors, available under the Open
  Database License (ODbL)" — https://www.openstreetmap.org/copyright
- Cross-check only, nothing shipped: GITD's half-yearly list on dane.gov.pl ("GITD: CANARD",
  https://dane.gov.pl/pl/dataset/4364, CC0 1.0) — serial numbers, positions and the railway red lights.

## Changes made to the source data

- The map's three layers (point speed, section, red light) are read from the page; each device's card
  is read once. A device marked mobile would be left out (none on 04.10.2026).
- Every point is moved onto its road within 30 m (OpenStreetMap geometry, never further); a mast
  farther from the road stays where GITD put it.
- Direction of travel (`bearing`): GITD gives only "kilometre increasing" (ROSNACY) or "decreasing"
  (MALEJACY). Which way the kilometre grows at the camera is found by following the road (the way with
  the camera's road number) from the camera towards OpenStreetMap milestones and other CANARD devices
  on the same road whose kilometre is known, up to 30 km: a direction is kept only when every such
  anchor agrees (or at least three agree and no more than a fifth disagree). Where nothing settles it
  — no road number or kilometre on the card (municipal and district roads, former national roads),
  no anchor on the road — the camera works both ways (`bothWays`) along the road's heading.
- Average-speed sections: a card's first direction runs from the map's point to its second point, the
  second direction back (a length of 0 or "brak pomiaru" is a direction not measured). Some newer
  sections have one device per direction, both written the same way round: when their limits agree,
  the second is turned round. The bearing at each end comes from following the road from the start
  for the published length; where that walk does not reach the published end, from the road's
  heading that runs from the start towards the end.
- Red-light cameras: no direction is published, so they work both ways along the road's heading. A
  red-light camera within 60 m of an OpenStreetMap level crossing, or on a mast GITD names "PKP…", is a
  `level_crossing` (all five that the dane.gov.pl list calls "czerwone światło kolejowe" are among them).
- `limitSource`: `"official"` (the card's limit for cars); `"osm-road"` (numeric `maxspeed` of the road)
  only where a card has none — none on 04.10.2026. `limitVariable` as for `es.json` (from the road's
  `maxspeed:variable` / `maxspeed:conditional`, or a card limit with hours).
- Police mobile checks are not published by anyone officially and are not included.

---

# Austria — `at.json`

`at.json` is built by `tools/cameras/build_at.py` and published at
https://tachwire.app/data/cameras/at.json (current version and SHA-256 in `index.json`). Same format
as `es.json`: fixed speed cameras (`speed`), average-speed sections (`section_start` / `section_end`
pairs sharing `section`) and red-light cameras (`red_light`). Austria publishes no list of its fixed
cameras (nothing on data.gv.at; ASFINAG's section controls only in press releases), so every camera
is from OpenStreetMap. No zones: Austria's Umweltzonen (IG-L) bind lorries only.

## Licence of the database

`at.json` is a Derived Database of OpenStreetMap, made available under the **Open Database License
(ODbL) 1.0**.

## Attributions

- **OpenStreetMap** (ODbL 1.0) — `highway=speed_camera` nodes, `type=enforcement` relations, and the
  road network with its `maxspeed` (the Geofabrik extract of Austria): "Contains information from
  OpenStreetMap, © OpenStreetMap contributors, available under the Open Database License (ODbL)" —
  https://www.openstreetmap.org/copyright

## Changes made to the source data

- Left out: points tagged or described as speed displays, dummies, dismantled, out of order or mobile
  ("Nur Geschwindigkeitsanzeige", "Radar außer Betrieb", "demontiert", "Attrappe", `speed_camera=mobile`),
  and enforcement relations that are not speed, section or red-light checks (height, toll).
- One node that is the device of two relations (one per direction, or speed and red light) gives two
  cameras; the same camera mapped twice within 30 m is one.
- Direction of travel (`bearing`): the numeric `direction` tag, or the relation's `from` member; turned
  round where it runs against the one-way road under it; `direction=forward/backward` along the way.
  Where nothing says it, the camera works both ways (`bothWays`) along the road's heading. Section ends
  take the road's direction of travel running from the start towards the end.
- `limitSource`: `"osm-camera"` (the camera's or the relation's numeric `maxspeed`), `"osm-road"`
  (numeric `maxspeed` of the road under the camera, by direction) — only 20–130 km/h; red-light cameras
  carry no limit. `limitVariable` where the camera, relation or road has `maxspeed:variable` or
  `maxspeed:conditional` (the IG-L stretches with variable signs).

---

# Belgium — `be.json`

`be.json` is built by `tools/cameras/build_be.py` and published at
https://tachwire.app/data/cameras/be.json (current version and SHA-256 in `index.json`). Same format
as `es.json`: fixed speed cameras (`speed`), average-speed sections (`section_start` / `section_end`),
red-light cameras (`red_light`), and the low-emission zones of Brussels, Ghent and Antwerp (`zones[]`).

## Licence of the database

`be.json` contains data from OpenStreetMap and is therefore a Derived Database made available under
the **Open Database License (ODbL) 1.0**. Brussels Mobility's data is CC0 1.0; Ghent's is under the
Flemish "Modellicentie Gratis Hergebruik" v1.0; Antwerp's under its "Gratis Open Data Licentie".

## Attributions

- **Bruxelles Mobilité / Brussel Mobiliteit** (CC0 1.0) — "Caméras de vitesse régionales"
  (https://data.mobility.brussels/en/info/speedcameras/), the communes' radar cameras
  (https://data.mobility.brussels/en/info/speedcameras_municipal/) and the Low Emission Zone
  (https://data.mobility.brussels/en/info/lez_zone/): "Source: Bruxelles Mobilité".
- **Stad Gent** — "Lage Emissie Zone Gent" (https://data.stad.gent/explore/dataset/lage-emissie-zone-gent/),
  Modellicentie Gratis Hergebruik v1.0: "Bron: Stad Gent". Modified.
- **Stad Antwerpen** — "lage-emissiezone"
  (https://portaal-stadantwerpen.opendata.arcgis.com/datasets/lage-emissiezone), Gratis Open Data
  Licentie: "Bron: stad Antwerpen". Modified.
- **OpenStreetMap** (ODbL 1.0) — the cameras of Flanders and Wallonia, the road network with its
  `maxspeed` (the Geofabrik extract of Belgium) and the communes' positions: "Contains information from
  OpenStreetMap, © OpenStreetMap contributors, available under the Open Database License (ODbL)" —
  https://www.openstreetmap.org/copyright
- Cross-check only, nothing shipped: the radar list behind SPW's Trafiroutes map
  (https://trafiroutes.wallonie.be/) — its legal notice allows reuse only for a use that is neither
  commercial nor advertising — and AWV's "Trajectcontroles" map (https://wegenenverkeer.be/) — its
  disclaimer excludes maps from the general permission to reproduce. Neither places or keeps a camera.

## Changes made to the source data

- Brussels: every point of both camera layers is a speed camera (the regional layer mixes speed cameras
  and combined red-light + speed cameras; `radar_type` has no published meaning). Where the camera's
  direction text says "vers centre", "vers ring"/"vers faubourg" or "vers" a commune, the road's direction
  of travel that runs towards (away from) the Grand-Place or that commune's OpenStreetMap place is taken
  when the road leaves no doubt (one direction within 60°, the other beyond 120°); otherwise, and where
  there is no text, the camera works both ways along the road's heading.
- OpenStreetMap, as for `at.json` (left-out words in French and Dutch too: "radar pédagogique",
  "snelheidsdisplay", "hors service", "verwijderd"…). Relations for a combined red light and speed camera
  (`enforcement=traffic_signals;maxspeed`) are speed cameras; access (ANPR) cameras are not shipped. An
  OSM camera within 150 m of a Brussels camera is that camera: dropped, lending its direction and limit
  from within 50 m. Points and sections outside Belgium's boundary are left out. Sections mapped without
  `from`/`to` members are not shipped (their direction is not known).
- Limits: no official list has one — `"osm-camera"` or `"osm-road"`, 20–130 km/h only, as for `at.json`.
- Zones: Brussels' six polygons (the Region without the Ring), Ghent's two and Antwerp's are each one
  zone (one set of rules), simplified to 10 m; all three are in force at all times (no `hours`).
  Wallonia has no LEZ in force.

---

# Bulgaria — `bg.json`

`bg.json` is built by `tools/cameras/build_bg.py` and published at
https://tachwire.app/data/cameras/bg.json (current version and SHA-256 in `index.json`). Same format
as `es.json`: fixed speed cameras (`speed`), and average-speed sections and red-light cameras where
OpenStreetMap has them. Every camera is from OpenStreetMap: Bulgaria's official lists may not be reused
(below). No zones: Sofia's seasonal low-emission zone has no official geometry that may be reused.

## Licence of the database

`bg.json` is a Derived Database of OpenStreetMap, made available under the **Open Database License
(ODbL) 1.0**.

## Attributions

- **OpenStreetMap** (ODbL 1.0) — `highway=speed_camera` nodes, `type=enforcement` relations, and the
  road network with its `maxspeed` (the Geofabrik extract of Bulgaria): "Contains information from
  OpenStreetMap, © OpenStreetMap contributors, available under the Open Database License (ODbL)" —
  https://www.openstreetmap.org/copyright
- Cross-check only, nothing shipped: the average-speed sections map of the Национално тол управление
  (linked from https://bgtoll.bg/vaprosi-i-otgovori) — bgtoll.bg's general terms (§§ 51–52) reserve all
  rights in what the site publishes and say that publishing it is no consent to its use by others. It is
  read to measure how much of it OpenStreetMap covers, never to place or keep a camera. The police's
  regional lists give a road and a kilometre, no position, and mix fixed and mobile cameras: not used.

## Changes made to the source data

- As for `at.json`, with the Bulgarian words for a mobile spot, a dismantled or broken post, a dummy
  and a speed display ("мобилна", "демонтирана", "не работи", "фалшива", "табло за скорост") left out too.
- `limitSource`: `"osm-camera"` or `"osm-road"`, 20–130 km/h only — a mapped 140 (Bulgaria's motorway
  limit) is dropped with the rest of that filter's catch, so a motorway camera may carry no limit.

---

# Norway — `no.json`

`no.json` is built by `tools/cameras/build_no.py` and published at
https://tachwire.app/data/cameras/no.json (current version and SHA-256 in `index.json`). Same format
as `es.json`: fixed speed cameras (`speed`) and average-speed sections (`section_start` /
`section_end`). Everything is from the Norwegian Public Roads Administration's National Road Database
(NVDB); nothing from OpenStreetMap. No zones: Norway has no low-emission zone that binds cars.

## Licence of the database

`no.json` is made available under the **Norwegian Licence for Open Government Data (NLOD) 2.0**
(https://data.norge.no/nlod/no/2.0), the licence of its only source.

## Attributions

- **Statens vegvesen — Nasjonal vegdatabank (NVDB)** (NLOD 2.0), object types 162 ATK-punkt, 823
  Streknings-ATK, 105 Fartsgrense and 721 Fartsgrense, variabel, and the road network, read through
  NVDB API Les v4 (https://nvdbapiles.atlas.vegvesen.no/). In the wording NVDB's terms
  (https://www.nvdb.no/rammer-regelverk/vilkar-og-ansvar/vilkar-for-bruk-av-data/) prescribe:
  "Inneholder data under norsk lisens for offentlige data (NLOD) tilgjengeliggjort av Statens vegvesen."
  Changed by Tachwire as described below ("Tachwire har endret informasjonen").

## Changes made to the source data

- Fixed cameras (162): the camera's own position. Its "Kontrollretning" (with or against the
  metering) is turned into the direction of travel in degrees: the road link's direction at the camera
  (from the NVDB road network), reversed where the road's metering runs against the link, and reversed
  again for "Mot metreringsretning". Checked against the towns the cameras' names point to ("… mot
  Bergen"): about 9 in 10 run towards the named town, the rest on winding roads and in tunnels. A camera
  with no control direction (13 on 04.10.2026) works both ways along the road.
- Sections (823): the section's line along the road, chained from its road segments, turned into a
  start and an end point in its direction of control, each with the road's heading there. A section
  whose segments do not join up is left out (1 on 04.10.2026).
- `limitSource`: `"official"` — the Fartsgrense (105) on the road link at the camera; for a section,
  where it is the same at both ends. `limitVariable` where a Fartsgrense, variabel (721) covers the place.
- Red-light cameras and police mobile checks are not published in NVDB and are not included.

---

# Cyprus — `cy.json`

`cy.json` is built by `tools/cameras/build_cy.py` and published at
https://tachwire.app/data/cameras/cy.json (current version and SHA-256 in `index.json`). Same format
as `es.json`: fixed speed cameras (`speed`) of the Republic of Cyprus on the land it controls. Every
camera is from OpenStreetMap: the Cyprus Police publish their fixed places as text only (junction
names, no position). No mobile cameras, no zones.

## Licence of the database

`cy.json` is a Derived Database of OpenStreetMap, made available under the **Open Database License
(ODbL) 1.0**.

## Attributions

- **OpenStreetMap** (ODbL 1.0) — `highway=speed_camera` nodes, `type=enforcement` relations, the
  road network with its `maxspeed` (the Geofabrik extract of Cyprus), and the boundaries of the north
  (relation 2514541), the UN buffer zone (3263909) and the Sovereign Base Areas (3263728), read from
  polygons.openstreetmap.fr: "Contains information from OpenStreetMap, © OpenStreetMap contributors,
  available under the Open Database License (ODbL)" — https://www.openstreetmap.org/copyright
- Cross-check only, nothing shipped: the Cyprus Police's press releases listing the fixed camera
  places (https://www.cypruspolicenews.com/archives/31219, https://www.cypruspolicenews.com/archives/37054).
  Only the facts — which junction is watched — are compared with OpenStreetMap by the street names
  around each place; no text, position or limit is taken from them.

## Changes made to the source data

- The Republic only: every point inside the north, the UN buffer zone or the Sovereign Base Areas is
  left out (142 cameras in the north on 04.10.2026; none in the other two).
- Every fixed camera in Cyprus fines a red light, the stop line and speed at once; each is shipped as
  one `speed` camera with its limit. A `type=enforcement` + `enforcement=traffic_signals` relation
  whose device is a `highway=speed_camera` node is read as that speed camera.
- As for `at.json` otherwise, with the Greek words for an out-of-order post, a dummy, a speed display,
  a mobile camera and a removed post ("εκτός λειτουργίας", "ψεύτικη", "ένδειξη ταχύτητας",
  "κινητή κάμερα", "αφαιρέθηκε") left out too. Directions are taken from the road before nearby
  points are merged, so the cameras on each approach of a junction stay apart.
- `limitSource`: `"osm-camera"` or `"osm-road"`, 20–130 km/h only.

---

# Malaysia — `my.json`

`my.json` is built by `tools/cameras/build_my.py` and published at
https://tachwire.app/data/cameras/my.json (current version and SHA-256 in `index.json`). Same format
as `es.json`: the fixed AwAS cameras of Malaysia — speed (`speed`) and red light (`red_light`). The
Road Transport Department's list decides which places are in it; OpenStreetMap gives where each one
stands. No sections, no mobile cameras, no zones.

## Licence of the database

`my.json` is a Derived Database of OpenStreetMap, made available under the **Open Database License
(ODbL) 1.0**.

## Attributions

- **OpenStreetMap** (ODbL 1.0) — the positions, directions and limits: `highway=speed_camera` nodes,
  `type=enforcement` relations and the `maxspeed` of the roads around them, and the boundaries of
  Malaysia (relation 2108121), Singapore (536780) and Brunei (2103120), read from
  polygons.openstreetmap.fr: "Contains information from OpenStreetMap, © OpenStreetMap contributors,
  available under the Open Database License (ODbL)" — https://www.openstreetmap.org/copyright
- **Jabatan Pengangkutan Jalan Malaysia (JPJ)**, "Lokasi Penguatkuasaan Kamera AwAS", the list of
  15.07.2024 on jpj.gov.my
  (https://www.jpj.gov.my/pusat-media-3/informasi-perkhidmatan-jpj/penguatkuasaan/lokasipenguatkuasaankameraawas/)
  — which places are enforced. The list has no open licence, so only its facts are used: the road,
  the kilometre, the direction and the kind (speed or red light) of each active place. No text,
  position or limit is taken from it.

## Changes made to the source data

- Only the places of JPJ's list (46 active on 15.07.2024): each one matched by hand to the
  OpenStreetMap node at that road, kilometre and direction (`JPJ` in `build_my.py`, with a note for
  each doubtful one). A listed place OpenStreetMap does not have is left out — no position is
  worked out from a kilometre post: 12 on 04.10.2026 (the Menora tunnel, Nilai – Seremban, and red-light
  places in Kedah and Perak). The 3 places JPJ lists as suspended are left out.
- Every other OpenStreetMap camera in Malaysia is left out: old AES points no longer on the list,
  red-light cameras in Penang, Melaka, Kuala Lumpur and Johor Bahru the list does not name, and the
  cameras mapped on Borneo, where JPJ lists none.
- The kind is the list's (speed or red light), not the OpenStreetMap tag's. A red-light camera has no
  limit.
- Directions from the node's tag or its relation's `from` member, turned round where they run against
  the one-way carriageway the node stands on; where the node has none, the list's direction ("NB",
  "arah Kuala Kangsar") picks the carriageway at the node that runs towards that end. A place without
  a direction in the list or in OpenStreetMap works both ways along the road.
- `limitSource`: `"osm-camera"` or `"osm-road"`, 20–130 km/h only. Where a node's own `maxspeed` and
  its relation's disagree, the road's limit decides.

---

# Netherlands — `nl.json`

`nl.json` is built by `tools/cameras/build_nl.py` and published at
https://tachwire.app/data/cameras/nl.json (current version and SHA-256 in `index.json`). Same format
as `es.json`: fixed speed cameras (`speed`), average-speed sections (`section_start` / `section_end`)
and red-light cameras (`red_light`), and one phone/seatbelt camera (`seatbelt_phone`). Everything is from OpenStreetMap. No zones. Limits in km/h.

## Licence of the database

`nl.json` is a Derived Database of OpenStreetMap, made available under the **Open Database License
(ODbL) 1.0**.

## Attributions

- **OpenStreetMap** (ODbL 1.0) — `highway=speed_camera` nodes, `type=enforcement` relations (including
  `enforcement=average_speed` sections), the road network with its `maxspeed` (the Geofabrik extract
  of the Netherlands) and the country's boundary: "Contains information from OpenStreetMap, © OpenStreetMap
  contributors, available under the Open Database License (ODbL)" — https://www.openstreetmap.org/copyright
- No official source is used: the Netherlands publish no reusable list of its cameras with positions.

## Changes made to the source data

- As for `at.json`.
- `limitSource`: `"osm-camera"` or `"osm-road"`, 20–130 km/h only.

---

# Czechia — `cz.json`

`cz.json` is built by `tools/cameras/build_cz.py` and published at
https://tachwire.app/data/cameras/cz.json (current version and SHA-256 in `index.json`). Same format
as `es.json`: fixed speed cameras (`speed`), average-speed sections (`section_start` / `section_end`)
and red-light cameras (`red_light`). Everything is from OpenStreetMap. No zones. Limits in km/h.

## Licence of the database

`cz.json` is a Derived Database of OpenStreetMap, made available under the **Open Database License
(ODbL) 1.0**.

## Attributions

- **OpenStreetMap** (ODbL 1.0) — `highway=speed_camera` nodes, `type=enforcement` relations (including
  `enforcement=average_speed` sections), the road network with its `maxspeed` (the Geofabrik extract
  of Czechia) and the country's boundary: "Contains information from OpenStreetMap, © OpenStreetMap
  contributors, available under the Open Database License (ODbL)" — https://www.openstreetmap.org/copyright
- No official source is used: Czechia publishes no reusable list of its cameras with positions.

## Changes made to the source data

- As for `at.json`, with the Czech words for a mobile, removed, cancelled, dismantled or broken post, a dummy and a speed display ("mobilní", "odstraněn", "zrušen", "demontován", "nefunkční", "atrapa", "ukazatel rychlosti") left out too.
- `limitSource`: `"osm-camera"` or `"osm-road"`, 20–130 km/h only.

---

# Russia — `ru.json`

`ru.json` is built by `tools/cameras/build_ru.py --source merged` and published at
https://tachwire.app/data/cameras/ru.json (current version and SHA-256 in `index.json`). Same format as `es.json`:
fixed speed (`speed`), red-light (`red_light`) and level-crossing cameras of Russia. No Crimea or Sevastopol.

## Licence of the database

`ru.json` is made available under the **Open Database License (ODbL) 1.0**.

## Attributions

- **МВД России (Госавтоинспекция)** — places of the automatic enforcement cameras (`/r/NN/milestones/`) and the
  regional files in the form of ПП РФ № 754 (address, coordinates, the traffic watched, the offences). Public
  information (257-ФЗ ст. 22.1 ч. 12; 149-ФЗ ст. 7 ч. 2). The site's condition: «Единственным условием перепечатки и
  ретрансляции является ссылка на первоисточник» — Источник: МВД России, Госавтоинспекция, https://госавтоинспекция.рф
- **Портал открытых данных Правительства Москвы** — sets 61701 and 62601 (CC BY 4.0): «Данные: data.mos.ru».
- **OpenStreetMap** — road axes and numeric maxspeed (ODbL).

## Changes made to the source data

Official points (MVD milestones and ПП 754 files joined within 50 m; Moscow's set 61701 within 30 m) merged
with the earlier community base: a community record within 50 m of an official point is that point — the official
position and, where the official list names the offences, its kind; the direction per record and the camera's own
limit kept; the rest of both kept. Lane and parking complexes left out; no Crimea or Sevastopol.

# United Kingdom — `gb.json`

`gb.json` is built by `tools/cameras/build_gb.py` and published at
https://tachwire.app/data/cameras/gb.json (current version and SHA-256 in `index.json`, under `countriesV2`).
Same format as `es.json`, with one difference: **the limits are in miles per hour** — the file says
`"limitUnit": "mph"` and every `limit` is the number on the sign (30, not 48). England, Wales, Scotland and
Northern Ireland: fixed speed cameras (`speed`), average-speed sections (`section_start` / `section_end`),
red-light cameras (`red_light`), and the zones that bind private cars (London's ULEZ and Congestion Charge,
the Clean Air Zones of Birmingham and Bristol, Oxford's Zero Emission Zone, the Low Emission Zones of Glasgow,
Edinburgh, Dundee and Aberdeen). The UK has no national list of camera positions, so every camera is from
OpenStreetMap; mobile (van) sites are not included.

## Licence of the database

`gb.json` is a Derived Database of OpenStreetMap, made available under the **Open Database License (ODbL)
1.0**. London's ULEZ outline is public-sector information under the Open Government Licence v2.0, which
asks only for the attribution below.

## Attributions

- **OpenStreetMap** (ODbL 1.0) — `highway=speed_camera` nodes, `type=enforcement` relations, the road
  network with its `maxspeed` (the Geofabrik extract of the United Kingdom) and the outlines of every zone but
  the ULEZ: "Contains information from OpenStreetMap, © OpenStreetMap contributors, available under the Open
  Database License (ODbL)" — https://www.openstreetmap.org/copyright
- **Greater London Authority — London Wide Ultra Low Emission Zone 2023** (London Datastore,
  https://data.london.gov.uk/dataset/london-wide-ultra-low-emission-zone-2023-vd455): "Contains public sector
  information licensed under the Open Government Licence v2.0. Contains OS data © Crown copyright and database
  right" — https://www.nationalarchives.gov.uk/doc/open-government-licence/version/2/

## Changes made to the source data

- Left out: points tagged or described as speed displays, dummies, dismantled or mobile
  (`speed_camera=mobile`, "mobile" in a note), and enforcement relations that are not speed, section or
  red-light checks (access/ANPR, height, weight).
- Directions as for Austria: the `direction` tag or the relation's `from` member, turned round where it runs
  against the one-way road under it; otherwise both ways along the road.
- `limit` in mph, only where written with its unit: the camera's or relation's `maxspeed` ("30 mph",
  `limitSource` `"osm-camera"`) or the road's under it (`"osm-road"`), 10–70 mph. A bare number (OpenStreetMap
  reads it as km/h) and the implicit national limits (`GB:nsl_single`, `GB:motorway`) give no limit: nothing is
  converted or assumed. Red-light cameras carry no limit.
- ULEZ: converted from British National Grid (EPSG:27700) to WGS84 (OSGB36 → WGS84 Helmert, about 5 m) and
  simplified to 5 m. The other zones' outlines simplified to 10 m; their rules (minimum standards
  `labels`, `hours`, `from`, `charge`) are written from the operators' published schemes. The Congestion
  Charge is `kind: "charge"` — a charge for every car, not an emissions rule.

---

# Zones (all countries)

`zones[]` has one entry per set of rules — a Spanish `controlledZone`, a named Italian ZTL, a French
ZFE, a Lisbon ZER — never one per polygon:

- `id` — stable for the rule set (`es-zbe-8019-rondes`, `it-ztl-milano-area-c`, `fr-zfe-paris`,
  `pt-zer-lisboa-1`).
- `parts` — the geometry: `[{"outer": ring, "holes": [ring, …]}]`, rings as closed `[lat, lon]` lists.
  A point is in the zone when it is in some `outer` and in none of that part's `holes`.
- `polygon` — the same area as ONE closed ring, for apps that read only this field: every part and
  hole joined by zero-width bridges, so that the even-odd rule on this ring gives exactly the parts.
  The build checks this on at least 10 000 points per zone and fails on any difference.
- `parent` — the zone this one lies inside, where there is one (Madrid's Distrito Centro and Plaza
  Elíptica in Madrid's ZBE, Milan's Area C in Area B, Lisbon's ZER 1 in ZER 2).
- `district` — the zone's own name where its city has several zones.
- `hours` — `{"tz", "rules": [{"days": [1…7, ISO, 1 = Monday], "from": "HH:MM", "to": "HH:MM"}],
  "holidaysOff"}`, only where the schedule is certain; without it the zone counts as always in force.
- `from`, `until` — the enforcement window, `YYYY-MM-DD`, where the source gives one.
- `kind` — absent (or `lez`) for a low-emission zone, `ztl` for an Italian limited-traffic zone, `charge` for a
  road-user charge every car pays (London's Congestion Charge).
- `charge` (United Kingdom) — `daily`: a car below the standards may enter and pays a daily charge; `penalty`:
  entering with it is a contravention.
