vehicles 0.6.1 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop_todo.yml +164 -0
- data/CHANGELOG.md +274 -0
- data/README.md +55 -10
- data/data/PROVENANCE-vehicles.md +12 -0
- data/data/plates/PROVENANCE.md +5 -4
- data/data/plates/_decode/at-districts.yml +287 -0
- data/data/plates/_decode/ch-cantons.yml +110 -0
- data/data/plates/_decode/cn-issuing-offices.yml +463 -0
- data/data/plates/_decode/cn-provinces.yml +614 -0
- data/data/plates/_decode/cz-kraj.yml +159 -0
- data/data/plates/_decode/dk-serial-blocks.yml +327 -0
- data/data/plates/_decode/fr-departements.yml +191 -0
- data/data/plates/_decode/gb-age-identifiers.yml +170 -0
- data/data/plates/_decode/gb-memory-tags.yml +202 -0
- data/data/plates/_decode/gr-prefectures.yml +1408 -0
- data/data/plates/_decode/hr-cities.yml +315 -0
- data/data/plates/_decode/ie-counties.yml +227 -0
- data/data/plates/_decode/in-state-codes.yml +169 -0
- data/data/plates/_decode/is-districts-1938.yml +116 -0
- data/data/plates/_decode/it-provinces.yml +348 -0
- data/data/plates/_decode/jp-office-marks.yml +960 -0
- data/data/plates/_decode/jp-use-marks.yml +205 -0
- data/data/plates/_decode/kr-authority-marks.yml +146 -0
- data/data/plates/_decode/kr-use-syllables.yml +194 -0
- data/data/plates/_decode/lu-series-order.yml +638 -0
- data/data/plates/_decode/mx-entity-series.yml +380 -0
- data/data/plates/_decode/my-index-marks.yml +271 -0
- data/data/plates/_decode/no-counties-1913.yml +148 -0
- data/data/plates/_decode/no-districts.yml +901 -0
- data/data/plates/_decode/pl-powiats.yml +567 -0
- data/data/plates/_decode/pt-trailer-services.yml +96 -0
- data/data/plates/_decode/ro-counties.yml +213 -0
- data/data/plates/_decode/se-diplomatic.yml +220 -0
- data/data/plates/_decode/si-regions.yml +123 -0
- data/data/plates/_decode/sk-districts.yml +314 -0
- data/data/plates/_decode/th-registration-elements.yml +208 -0
- data/data/plates/_decode/ua-regions.yml +393 -0
- data/data/plates/_decode/za-licence-marks.yml +215 -0
- data/data/plates/_meta/classes.yml +1 -0
- data/data/plates/_meta/separators.yml +102 -0
- data/data/plates/ad.yml +961 -0
- data/data/plates/ar.yml +762 -0
- data/data/plates/at.yml +1424 -0
- data/data/plates/au-act.yml +472 -0
- data/data/plates/au-nsw.yml +282 -0
- data/data/plates/au-nt.yml +431 -0
- data/data/plates/au-qld.yml +272 -0
- data/data/plates/au-sa.yml +248 -0
- data/data/plates/au-tas.yml +302 -0
- data/data/plates/au-vic.yml +215 -0
- data/data/plates/au-wa.yml +309 -0
- data/data/plates/be.yml +1840 -0
- data/data/plates/br.yml +1152 -0
- data/data/plates/ca-ab.yml +430 -0
- data/data/plates/ca-bc.yml +697 -0
- data/data/plates/ca-mb.yml +499 -0
- data/data/plates/ca-nb.yml +537 -0
- data/data/plates/ca-nl.yml +743 -0
- data/data/plates/ca-ns.yml +808 -0
- data/data/plates/ca-nt.yml +610 -0
- data/data/plates/ca-nu.yml +280 -0
- data/data/plates/ca-on.yml +881 -0
- data/data/plates/ca-pe.yml +592 -0
- data/data/plates/ca-qc.yml +1036 -0
- data/data/plates/ca-sk.yml +256 -0
- data/data/plates/ca-yt.yml +656 -0
- data/data/plates/ch.yml +1273 -0
- data/data/plates/cn.yml +1431 -0
- data/data/plates/cy.yml +688 -0
- data/data/plates/cz.yml +1179 -0
- data/data/plates/de.yml +553 -118
- data/data/plates/dk.yml +1647 -0
- data/data/plates/ee.yml +1275 -0
- data/data/plates/es.yml +228 -32
- data/data/plates/fi.yml +1271 -0
- data/data/plates/fr.yml +1265 -0
- data/data/plates/gb.yml +1188 -0
- data/data/plates/gr.yml +721 -0
- data/data/plates/hr.yml +860 -0
- data/data/plates/hu.yml +959 -0
- data/data/plates/ie.yml +775 -0
- data/data/plates/in.yml +1172 -0
- data/data/plates/is.yml +667 -0
- data/data/plates/it.yml +1317 -0
- data/data/plates/jp.yml +3650 -0
- data/data/plates/kr.yml +1375 -0
- data/data/plates/li.yml +1010 -0
- data/data/plates/lt.yml +879 -0
- data/data/plates/lu.yml +842 -0
- data/data/plates/lv.yml +924 -0
- data/data/plates/mc.yml +1024 -0
- data/data/plates/mt.yml +854 -0
- data/data/plates/mx.yml +1372 -0
- data/data/plates/my.yml +685 -0
- data/data/plates/nl.yml +44 -0
- data/data/plates/no.yml +1018 -0
- data/data/plates/nz.yml +1699 -0
- data/data/plates/pl.yml +1296 -0
- data/data/plates/pt.yml +847 -0
- data/data/plates/ro.yml +785 -0
- data/data/plates/se.yml +1091 -0
- data/data/plates/si.yml +1105 -0
- data/data/plates/sk.yml +1439 -0
- data/data/plates/sm.yml +1119 -0
- data/data/plates/th.yml +1150 -0
- data/data/plates/ua.yml +1672 -0
- data/data/plates/us-ak.yml +763 -0
- data/data/plates/us-al.yml +457 -0
- data/data/plates/us-ar.yml +427 -0
- data/data/plates/us-as.yml +454 -0
- data/data/plates/us-az.yml +430 -0
- data/data/plates/us-ca.yml +892 -0
- data/data/plates/us-co.yml +452 -0
- data/data/plates/us-ct.yml +427 -0
- data/data/plates/us-dc.yml +614 -0
- data/data/plates/us-de.yml +551 -0
- data/data/plates/us-fl.yml +319 -96
- data/data/plates/us-ga.yml +644 -0
- data/data/plates/us-gu.yml +658 -0
- data/data/plates/us-hi.yml +585 -0
- data/data/plates/us-ia.yml +438 -0
- data/data/plates/us-id.yml +531 -0
- data/data/plates/us-il.yml +516 -0
- data/data/plates/us-in.yml +324 -0
- data/data/plates/us-ks.yml +351 -0
- data/data/plates/us-ky.yml +770 -0
- data/data/plates/us-la.yml +568 -0
- data/data/plates/us-ma.yml +379 -0
- data/data/plates/us-md.yml +536 -0
- data/data/plates/us-me.yml +445 -0
- data/data/plates/us-mi.yml +408 -0
- data/data/plates/us-mn.yml +411 -0
- data/data/plates/us-mo.yml +356 -0
- data/data/plates/us-mp.yml +402 -0
- data/data/plates/us-ms.yml +432 -0
- data/data/plates/us-mt.yml +619 -0
- data/data/plates/us-nc.yml +602 -0
- data/data/plates/us-nd.yml +419 -0
- data/data/plates/us-ne.yml +483 -0
- data/data/plates/us-nh.yml +394 -0
- data/data/plates/us-nj.yml +547 -0
- data/data/plates/us-nm.yml +574 -0
- data/data/plates/us-nv.yml +655 -0
- data/data/plates/us-ny.yml +592 -0
- data/data/plates/us-oh.yml +404 -0
- data/data/plates/us-ok.yml +513 -0
- data/data/plates/us-or.yml +392 -0
- data/data/plates/us-pa.yml +506 -0
- data/data/plates/us-pr.yml +507 -0
- data/data/plates/us-ri.yml +445 -0
- data/data/plates/us-sc.yml +605 -0
- data/data/plates/us-sd.yml +428 -0
- data/data/plates/us-tn.yml +471 -0
- data/data/plates/us-tx.yml +535 -0
- data/data/plates/us-ut.yml +384 -0
- data/data/plates/us-va.yml +567 -0
- data/data/plates/us-vi.yml +489 -0
- data/data/plates/us-vt.yml +458 -0
- data/data/plates/us-wa.yml +484 -0
- data/data/plates/us-wi.yml +509 -0
- data/data/plates/us-wv.yml +446 -0
- data/data/plates/us-wy.yml +523 -0
- data/data/plates/va.yml +604 -0
- data/data/plates/za.yml +1141 -0
- data/data/vehicles.json +160653 -105090
- data/lib/vehicles/configuration.rb +17 -3
- data/lib/vehicles/dataset.rb +73 -18
- data/lib/vehicles/fuzzy.rb +115 -0
- data/lib/vehicles/http.rb +48 -0
- data/lib/vehicles/make.rb +36 -6
- data/lib/vehicles/mcp_server.rb +5 -5
- data/lib/vehicles/model.rb +21 -2
- data/lib/vehicles/plates/series.rb +172 -18
- data/lib/vehicles/plates/template_fill.rb +188 -0
- data/lib/vehicles/plates/templates.rb +162 -0
- data/lib/vehicles/plates.rb +12 -0
- data/lib/vehicles/providers/hosted_provider.rb +28 -55
- data/lib/vehicles/validators/vehicle_make_validator.rb +3 -1
- data/lib/vehicles/validators/vehicle_model_validator.rb +1 -1
- data/lib/vehicles/version.rb +1 -1
- data/lib/vehicles.rb +32 -16
- data/rakelib/data_refresh.rake +109 -0
- data/rakelib/plates_refresh.rake +29 -0
- data/sig/vehicles.rbs +18 -0
- metadata +164 -2
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# plates/_decode/fr-departements.yml — the French département numbers, and the
|
|
2
|
+
# one thing a parse API must never do with them.
|
|
3
|
+
#
|
|
4
|
+
# THE FINDING THAT SHAPES THIS FILE. France has TWO département dimensions and
|
|
5
|
+
# they behave in opposite ways:
|
|
6
|
+
#
|
|
7
|
+
# 1. FNI (1950/1984-2009) — the département number was the LAST GROUP OF THE
|
|
8
|
+
# REGISTRATION NUMBER ITSELF, and it was geographic. The arrêté du
|
|
9
|
+
# 5 novembre 1984, art. 2, verbatim: "les certificats d'immatriculation
|
|
10
|
+
# sont délivrées soit par la préfecture du département du domicile du
|
|
11
|
+
# propriétaire" — the plate was issued by the préfecture of the owner's
|
|
12
|
+
# domicile, and a move to another département triggered a re-registration
|
|
13
|
+
# (art. 10 A/B, mutation). An FNI plate therefore DECODES, and this table
|
|
14
|
+
# is how.
|
|
15
|
+
#
|
|
16
|
+
# 2. SIV (2009-) — the département number is NOT part of the registration
|
|
17
|
+
# number at all. It sits in a right-hand blue band called the
|
|
18
|
+
# "identifiant territorial", it is a PLATE GRAPHIC, and the arrêté du
|
|
19
|
+
# 9 février 2009 fixant les caractéristiques des plaques, art. 9, says in
|
|
20
|
+
# terms: "Le choix de cet identifiant territorial est libre et peut ne pas
|
|
21
|
+
# avoir de lien avec le domicile du titulaire du certificat
|
|
22
|
+
# d'immatriculation." A SIV plate DOES NOT DECODE. Reading region off a
|
|
23
|
+
# modern French plate is the single most expensive mistake a plate-parse
|
|
24
|
+
# API can make, and PRD-PLATES §2.4 already names it ("France's SIV
|
|
25
|
+
# département band is OWNER-CHOSEN, not geographic ... the decode table
|
|
26
|
+
# must say so or the parse API will lie"). It says so.
|
|
27
|
+
#
|
|
28
|
+
# WHAT THE SIV BAND *DOES* CONSTRAIN, and it is worth carrying: art. 9 requires
|
|
29
|
+
# the band to be "constitué par le logo officiel d'une région ou de la
|
|
30
|
+
# collectivité européenne d'Alsace ET le numéro de l'un des départements de
|
|
31
|
+
# cette collectivité territoriale". So the PAIR (region logo, département
|
|
32
|
+
# number) must be internally consistent even though the pair is freely chosen —
|
|
33
|
+
# which is why every row below carries its région. A band showing the Bretagne
|
|
34
|
+
# logo over "75" is not a legal plate; a Parisian owner showing Bretagne/29 is.
|
|
35
|
+
# The band must also be identical front and rear (art. 9), and it is absent
|
|
36
|
+
# altogether on "véhicule de collection", "véhicule importé en transit" and
|
|
37
|
+
# "véhicule en transit temporaire" plates.
|
|
38
|
+
#
|
|
39
|
+
# SOURCE OF THE TABLE. The rows are the official French administrative
|
|
40
|
+
# découpage as served by the État's own API Géo (geo.api.gouv.fr, DINUM/
|
|
41
|
+
# Etalab), which republishes the INSEE Code officiel géographique. 101 rows:
|
|
42
|
+
# 96 metropolitan départements including Corse-du-Sud (2A) and Haute-Corse (2B),
|
|
43
|
+
# plus the five overseas départements 971-974 and 976. Fetched 2026-08-02.
|
|
44
|
+
#
|
|
45
|
+
# PERIOD DISCIPLINE (PRD-PLATES §2.4 — decode tables rot). This is the list in
|
|
46
|
+
# force TODAY. Historic FNI codes that are NOT in it are NOT invented here:
|
|
47
|
+
# * 20 = Corse before the 1976 split into 2A/2B;
|
|
48
|
+
# * 75 covering the whole former Seine before the 1968 Île-de-France
|
|
49
|
+
# reorganisation that created 91, 92, 93, 94 and 95;
|
|
50
|
+
# * 78 (Seine-et-Oise) before the same reorganisation;
|
|
51
|
+
# * 975 Saint-Pierre-et-Miquelon, 977/978 Saint-Barthélemy/Saint-Martin,
|
|
52
|
+
# 986/987/988 (Wallis, Polynésie, Nouvelle-Calédonie) — collectivités, not
|
|
53
|
+
# départements, and not in this primary;
|
|
54
|
+
# * the pre-1962 Algerian and Saharan codes.
|
|
55
|
+
# A plate older than the current découpage must be treated as UNRESOLVED rather
|
|
56
|
+
# than mapped through this table. The FNI series in plates/fr.yml carries
|
|
57
|
+
# matching: recall-only for the same reason.
|
|
58
|
+
jurisdiction: fr
|
|
59
|
+
topic: departements
|
|
60
|
+
authority:
|
|
61
|
+
name: API Géo (découpage administratif) — DINUM/Etalab, sur le Code officiel géographique de l'INSEE
|
|
62
|
+
url: "https://geo.api.gouv.fr/decoupage-administratif/departements"
|
|
63
|
+
sources:
|
|
64
|
+
- "https://geo.api.gouv.fr/departements?fields=code,nom,region # the 101 rows below, code + nom + région, fetched 2026-08-02"
|
|
65
|
+
- "https://www.insee.fr/fr/information/8740222 # INSEE Code officiel géographique au 1er janvier 2026 — the upstream register API Géo republishes"
|
|
66
|
+
- "https://www.legifrance.gouv.fr/loda/id/JORFTEXT000020237128 # arrêté du 9 février 2009 fixant les caractéristiques des plaques, art. 9 — the identifiant territorial, its (région, département) pairing rule, and the free-choice sentence"
|
|
67
|
+
- "https://www.legifrance.gouv.fr/loda/id/LEGITEXT000006075077 # arrêté du 5 novembre 1984, art. 2 and art. 10 — the FNI's préfecture-of-domicile issuance and the mutation-on-move rule that make the FNI suffix decodable"
|
|
68
|
+
period: { start: 2026 }
|
|
69
|
+
period_evidence: instrument-in-force
|
|
70
|
+
period_note: >-
|
|
71
|
+
2026 is the vintage of the COG edition read here, not the date these codes
|
|
72
|
+
came into use. Most are unchanged since 1790; the material changes for plate
|
|
73
|
+
decoding are 1968 (Île-de-France), 1976 (Corse 20 -> 2A/2B) and 2011 (Mayotte
|
|
74
|
+
976 becomes a département). None of those transitions is sourced in this pass.
|
|
75
|
+
|
|
76
|
+
# Decoding rules a consumer needs:
|
|
77
|
+
# * FNI numbers END with the département group, so parse RIGHT to LEFT: take
|
|
78
|
+
# the trailing 2 or 3 characters, then the letter group, then the digits.
|
|
79
|
+
# * The group is 2 characters for metropolitan France (including the literals
|
|
80
|
+
# 2A and 2B) and 3 digits for the overseas départements.
|
|
81
|
+
# * SIV numbers contain no département group at all. If a consumer has the
|
|
82
|
+
# BAND as a separate observation (from an image, never from the string),
|
|
83
|
+
# it decodes to a place of the owner's choosing, not of registration.
|
|
84
|
+
applies_to:
|
|
85
|
+
- "plates/fr.yml#fr-fni-1984 # geographic, decodable"
|
|
86
|
+
- "plates/fr.yml#fr-siv-standard # NOT decodable — band only, owner-chosen"
|
|
87
|
+
decodes_registration_number: fni-only
|
|
88
|
+
maximal_munch: false
|
|
89
|
+
|
|
90
|
+
codes:
|
|
91
|
+
- { code: "01", name: "Ain", region: "Auvergne-Rhône-Alpes", region_code: "84" }
|
|
92
|
+
- { code: "02", name: "Aisne", region: "Hauts-de-France", region_code: "32" }
|
|
93
|
+
- { code: "03", name: "Allier", region: "Auvergne-Rhône-Alpes", region_code: "84" }
|
|
94
|
+
- { code: "04", name: "Alpes-de-Haute-Provence", region: "Provence-Alpes-Côte d'Azur", region_code: "93" }
|
|
95
|
+
- { code: "05", name: "Hautes-Alpes", region: "Provence-Alpes-Côte d'Azur", region_code: "93" }
|
|
96
|
+
- { code: "06", name: "Alpes-Maritimes", region: "Provence-Alpes-Côte d'Azur", region_code: "93" }
|
|
97
|
+
- { code: "07", name: "Ardèche", region: "Auvergne-Rhône-Alpes", region_code: "84" }
|
|
98
|
+
- { code: "08", name: "Ardennes", region: "Grand Est", region_code: "44" }
|
|
99
|
+
- { code: "09", name: "Ariège", region: "Occitanie", region_code: "76" }
|
|
100
|
+
- { code: "10", name: "Aube", region: "Grand Est", region_code: "44" }
|
|
101
|
+
- { code: "11", name: "Aude", region: "Occitanie", region_code: "76" }
|
|
102
|
+
- { code: "12", name: "Aveyron", region: "Occitanie", region_code: "76" }
|
|
103
|
+
- { code: "13", name: "Bouches-du-Rhône", region: "Provence-Alpes-Côte d'Azur", region_code: "93" }
|
|
104
|
+
- { code: "14", name: "Calvados", region: "Normandie", region_code: "28" }
|
|
105
|
+
- { code: "15", name: "Cantal", region: "Auvergne-Rhône-Alpes", region_code: "84" }
|
|
106
|
+
- { code: "16", name: "Charente", region: "Nouvelle-Aquitaine", region_code: "75" }
|
|
107
|
+
- { code: "17", name: "Charente-Maritime", region: "Nouvelle-Aquitaine", region_code: "75" }
|
|
108
|
+
- { code: "18", name: "Cher", region: "Centre-Val de Loire", region_code: "24" }
|
|
109
|
+
- { code: "19", name: "Corrèze", region: "Nouvelle-Aquitaine", region_code: "75" }
|
|
110
|
+
- { code: "21", name: "Côte-d'Or", region: "Bourgogne-Franche-Comté", region_code: "27" }
|
|
111
|
+
- { code: "22", name: "Côtes-d'Armor", region: "Bretagne", region_code: "53" }
|
|
112
|
+
- { code: "23", name: "Creuse", region: "Nouvelle-Aquitaine", region_code: "75" }
|
|
113
|
+
- { code: "24", name: "Dordogne", region: "Nouvelle-Aquitaine", region_code: "75" }
|
|
114
|
+
- { code: "25", name: "Doubs", region: "Bourgogne-Franche-Comté", region_code: "27" }
|
|
115
|
+
- { code: "26", name: "Drôme", region: "Auvergne-Rhône-Alpes", region_code: "84" }
|
|
116
|
+
- { code: "27", name: "Eure", region: "Normandie", region_code: "28" }
|
|
117
|
+
- { code: "28", name: "Eure-et-Loir", region: "Centre-Val de Loire", region_code: "24" }
|
|
118
|
+
- { code: "29", name: "Finistère", region: "Bretagne", region_code: "53" }
|
|
119
|
+
- { code: "2A", name: "Corse-du-Sud", region: "Corse", region_code: "94" }
|
|
120
|
+
- { code: "2B", name: "Haute-Corse", region: "Corse", region_code: "94" }
|
|
121
|
+
- { code: "30", name: "Gard", region: "Occitanie", region_code: "76" }
|
|
122
|
+
- { code: "31", name: "Haute-Garonne", region: "Occitanie", region_code: "76" }
|
|
123
|
+
- { code: "32", name: "Gers", region: "Occitanie", region_code: "76" }
|
|
124
|
+
- { code: "33", name: "Gironde", region: "Nouvelle-Aquitaine", region_code: "75" }
|
|
125
|
+
- { code: "34", name: "Hérault", region: "Occitanie", region_code: "76" }
|
|
126
|
+
- { code: "35", name: "Ille-et-Vilaine", region: "Bretagne", region_code: "53" }
|
|
127
|
+
- { code: "36", name: "Indre", region: "Centre-Val de Loire", region_code: "24" }
|
|
128
|
+
- { code: "37", name: "Indre-et-Loire", region: "Centre-Val de Loire", region_code: "24" }
|
|
129
|
+
- { code: "38", name: "Isère", region: "Auvergne-Rhône-Alpes", region_code: "84" }
|
|
130
|
+
- { code: "39", name: "Jura", region: "Bourgogne-Franche-Comté", region_code: "27" }
|
|
131
|
+
- { code: "40", name: "Landes", region: "Nouvelle-Aquitaine", region_code: "75" }
|
|
132
|
+
- { code: "41", name: "Loir-et-Cher", region: "Centre-Val de Loire", region_code: "24" }
|
|
133
|
+
- { code: "42", name: "Loire", region: "Auvergne-Rhône-Alpes", region_code: "84" }
|
|
134
|
+
- { code: "43", name: "Haute-Loire", region: "Auvergne-Rhône-Alpes", region_code: "84" }
|
|
135
|
+
- { code: "44", name: "Loire-Atlantique", region: "Pays de la Loire", region_code: "52" }
|
|
136
|
+
- { code: "45", name: "Loiret", region: "Centre-Val de Loire", region_code: "24" }
|
|
137
|
+
- { code: "46", name: "Lot", region: "Occitanie", region_code: "76" }
|
|
138
|
+
- { code: "47", name: "Lot-et-Garonne", region: "Nouvelle-Aquitaine", region_code: "75" }
|
|
139
|
+
- { code: "48", name: "Lozère", region: "Occitanie", region_code: "76" }
|
|
140
|
+
- { code: "49", name: "Maine-et-Loire", region: "Pays de la Loire", region_code: "52" }
|
|
141
|
+
- { code: "50", name: "Manche", region: "Normandie", region_code: "28" }
|
|
142
|
+
- { code: "51", name: "Marne", region: "Grand Est", region_code: "44" }
|
|
143
|
+
- { code: "52", name: "Haute-Marne", region: "Grand Est", region_code: "44" }
|
|
144
|
+
- { code: "53", name: "Mayenne", region: "Pays de la Loire", region_code: "52" }
|
|
145
|
+
- { code: "54", name: "Meurthe-et-Moselle", region: "Grand Est", region_code: "44" }
|
|
146
|
+
- { code: "55", name: "Meuse", region: "Grand Est", region_code: "44" }
|
|
147
|
+
- { code: "56", name: "Morbihan", region: "Bretagne", region_code: "53" }
|
|
148
|
+
- { code: "57", name: "Moselle", region: "Grand Est", region_code: "44" }
|
|
149
|
+
- { code: "58", name: "Nièvre", region: "Bourgogne-Franche-Comté", region_code: "27" }
|
|
150
|
+
- { code: "59", name: "Nord", region: "Hauts-de-France", region_code: "32" }
|
|
151
|
+
- { code: "60", name: "Oise", region: "Hauts-de-France", region_code: "32" }
|
|
152
|
+
- { code: "61", name: "Orne", region: "Normandie", region_code: "28" }
|
|
153
|
+
- { code: "62", name: "Pas-de-Calais", region: "Hauts-de-France", region_code: "32" }
|
|
154
|
+
- { code: "63", name: "Puy-de-Dôme", region: "Auvergne-Rhône-Alpes", region_code: "84" }
|
|
155
|
+
- { code: "64", name: "Pyrénées-Atlantiques", region: "Nouvelle-Aquitaine", region_code: "75" }
|
|
156
|
+
- { code: "65", name: "Hautes-Pyrénées", region: "Occitanie", region_code: "76" }
|
|
157
|
+
- { code: "66", name: "Pyrénées-Orientales", region: "Occitanie", region_code: "76" }
|
|
158
|
+
- { code: "67", name: "Bas-Rhin", region: "Grand Est", region_code: "44" }
|
|
159
|
+
- { code: "68", name: "Haut-Rhin", region: "Grand Est", region_code: "44" }
|
|
160
|
+
- { code: "69", name: "Rhône", region: "Auvergne-Rhône-Alpes", region_code: "84" }
|
|
161
|
+
- { code: "70", name: "Haute-Saône", region: "Bourgogne-Franche-Comté", region_code: "27" }
|
|
162
|
+
- { code: "71", name: "Saône-et-Loire", region: "Bourgogne-Franche-Comté", region_code: "27" }
|
|
163
|
+
- { code: "72", name: "Sarthe", region: "Pays de la Loire", region_code: "52" }
|
|
164
|
+
- { code: "73", name: "Savoie", region: "Auvergne-Rhône-Alpes", region_code: "84" }
|
|
165
|
+
- { code: "74", name: "Haute-Savoie", region: "Auvergne-Rhône-Alpes", region_code: "84" }
|
|
166
|
+
- { code: "75", name: "Paris", region: "Île-de-France", region_code: "11" }
|
|
167
|
+
- { code: "76", name: "Seine-Maritime", region: "Normandie", region_code: "28" }
|
|
168
|
+
- { code: "77", name: "Seine-et-Marne", region: "Île-de-France", region_code: "11" }
|
|
169
|
+
- { code: "78", name: "Yvelines", region: "Île-de-France", region_code: "11" }
|
|
170
|
+
- { code: "79", name: "Deux-Sèvres", region: "Nouvelle-Aquitaine", region_code: "75" }
|
|
171
|
+
- { code: "80", name: "Somme", region: "Hauts-de-France", region_code: "32" }
|
|
172
|
+
- { code: "81", name: "Tarn", region: "Occitanie", region_code: "76" }
|
|
173
|
+
- { code: "82", name: "Tarn-et-Garonne", region: "Occitanie", region_code: "76" }
|
|
174
|
+
- { code: "83", name: "Var", region: "Provence-Alpes-Côte d'Azur", region_code: "93" }
|
|
175
|
+
- { code: "84", name: "Vaucluse", region: "Provence-Alpes-Côte d'Azur", region_code: "93" }
|
|
176
|
+
- { code: "85", name: "Vendée", region: "Pays de la Loire", region_code: "52" }
|
|
177
|
+
- { code: "86", name: "Vienne", region: "Nouvelle-Aquitaine", region_code: "75" }
|
|
178
|
+
- { code: "87", name: "Haute-Vienne", region: "Nouvelle-Aquitaine", region_code: "75" }
|
|
179
|
+
- { code: "88", name: "Vosges", region: "Grand Est", region_code: "44" }
|
|
180
|
+
- { code: "89", name: "Yonne", region: "Bourgogne-Franche-Comté", region_code: "27" }
|
|
181
|
+
- { code: "90", name: "Territoire de Belfort", region: "Bourgogne-Franche-Comté", region_code: "27" }
|
|
182
|
+
- { code: "91", name: "Essonne", region: "Île-de-France", region_code: "11" }
|
|
183
|
+
- { code: "92", name: "Hauts-de-Seine", region: "Île-de-France", region_code: "11" }
|
|
184
|
+
- { code: "93", name: "Seine-Saint-Denis", region: "Île-de-France", region_code: "11" }
|
|
185
|
+
- { code: "94", name: "Val-de-Marne", region: "Île-de-France", region_code: "11" }
|
|
186
|
+
- { code: "95", name: "Val-d'Oise", region: "Île-de-France", region_code: "11" }
|
|
187
|
+
- { code: "971", name: "Guadeloupe", region: "Guadeloupe", region_code: "01" }
|
|
188
|
+
- { code: "972", name: "Martinique", region: "Martinique", region_code: "02" }
|
|
189
|
+
- { code: "973", name: "Guyane", region: "Guyane", region_code: "03" }
|
|
190
|
+
- { code: "974", name: "La Réunion", region: "La Réunion", region_code: "04" }
|
|
191
|
+
- { code: "976", name: "Mayotte", region: "Mayotte", region_code: "06" }
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# plates/_decode/gb-age-identifiers.yml — the British age identifier.
|
|
2
|
+
#
|
|
3
|
+
# THE SOURCE FINDING: this is the most precisely decodable date signal in the
|
|
4
|
+
# whole plates dataset, and — like the memory tags — it is NOT law. VERA 1994
|
|
5
|
+
# § 23(4) does not reach the composition of a mark, so the twice-yearly code
|
|
6
|
+
# is an administrative allocation published in DVLA's leaflet INF104 and, for
|
|
7
|
+
# the export series, in HMRC's VAT manual. Both are authority publications and
|
|
8
|
+
# therefore PRIMARY under PRD-PLATES § 4.
|
|
9
|
+
#
|
|
10
|
+
# THE RULE, and it is complete and mechanical:
|
|
11
|
+
# a vehicle first registered March-August of year YY takes the code YY
|
|
12
|
+
# a vehicle first registered September of YY to February of YY+1 takes YY+50
|
|
13
|
+
# INF104 § 05 tabulates it from "Sept 2001 - Feb 2002 = 51" to "March 2029 -
|
|
14
|
+
# Aug 2029 = 29 / Sept 2029 - Feb 2030 = 79" and closes: "This pattern will
|
|
15
|
+
# continue until all possible variations have been used." HMRC VATNINMT3500
|
|
16
|
+
# states the SAME rule for the export series and carries its table to
|
|
17
|
+
# "March 2049 - August 2049 = 49" and "Sept 2049 - Feb 2050 = 99".
|
|
18
|
+
#
|
|
19
|
+
# EVERY ROW BELOW CARRIES ITS SOURCE. Rows marked `source: inf104` are printed
|
|
20
|
+
# in INF104's table. Rows marked `source: hmrc-continuation` are printed in
|
|
21
|
+
# HMRC's table but not in INF104's — they are as sourced as the others, from a
|
|
22
|
+
# second government publication, and are marked separately only so a verifier
|
|
23
|
+
# can see which authority each half came from. NOTHING here is extrapolated
|
|
24
|
+
# past 2049/50: the codes after that are undecided ("until all possible
|
|
25
|
+
# variations have been used" is not a formula) and are recorded as a gap.
|
|
26
|
+
#
|
|
27
|
+
# Referenced by: gb-standard-2001, gb-motorcycle-2001, gb-green-zev-2020,
|
|
28
|
+
# gb-export-x (plates/gb.yml) via age_encoding.
|
|
29
|
+
jurisdiction: gb
|
|
30
|
+
topic: age-identifiers
|
|
31
|
+
authority:
|
|
32
|
+
name: Driver and Vehicle Licensing Agency (DVLA)
|
|
33
|
+
url: "https://www.gov.uk/government/publications/vehicle-registration-numbers-and-number-plates"
|
|
34
|
+
sources:
|
|
35
|
+
- "https://assets.publishing.service.gov.uk/media/6694e379fc8e12ac3edafc60/inf104-vehicle-registration-numbers-and-number-plates.pdf # INF104 (4/22) § 05 'Age identifiers' — every row marked source: inf104, plus the continuation sentence"
|
|
36
|
+
- "https://www.gov.uk/hmrc-internal-manuals/vat-new-means-transport-northern-ireland/vatninmt3500 # HMRC VATNINMT3500 — the same rule stated for the export series and tabulated to 'Sept 2049 - Feb 2050 = 99'; every row marked source: hmrc-continuation"
|
|
37
|
+
licence: "Crown copyright, Open Government Licence v3.0"
|
|
38
|
+
period: { start: 2001 }
|
|
39
|
+
period_evidence: enabling-instrument
|
|
40
|
+
period_note: >-
|
|
41
|
+
The scheme began with the current format on 1 September 2001 (INF104 § 03;
|
|
42
|
+
S.I. 2001/561 reg 1(1)(b)), and 51 is the first identifier issued.
|
|
43
|
+
|
|
44
|
+
rule:
|
|
45
|
+
march_to_august: "code = YY (the two-digit year)"
|
|
46
|
+
september_to_february: "code = YY + 50 (of the year the period STARTS in)"
|
|
47
|
+
changeover_days: ["1 March", "1 September"]
|
|
48
|
+
first_code: "51"
|
|
49
|
+
last_published_code: "99"
|
|
50
|
+
values_never_issued: ["00", "01", "50"]
|
|
51
|
+
values_never_issued_note: >-
|
|
52
|
+
DERIVED, NOT QUOTED. 00 and 50 cannot arise from the rule. 01 would be
|
|
53
|
+
March-August 2001, which precedes the format's 1 September 2001 start, and
|
|
54
|
+
INF104's table opens at 51. This is the exclusion `format.regex_strict`
|
|
55
|
+
encodes in plates/gb.yml; `format.regex` deliberately does not.
|
|
56
|
+
|
|
57
|
+
direction_of_inference: >-
|
|
58
|
+
ONE-SIDED, and a parse API must say so. The age identifier gives the period
|
|
59
|
+
in which the MARK was issued, which is an UPPER bound on the vehicle's age
|
|
60
|
+
and never a lower one, because a mark may be transferred to an older vehicle
|
|
61
|
+
and INF104 § 04 forbids only the reverse: "You can't use a registration
|
|
62
|
+
number to make your vehicle appear younger than it actually is." A 21-plate
|
|
63
|
+
car was registered no earlier than March 2021; a 21-plate car may lawfully
|
|
64
|
+
BE older than that only if the mark was assigned to it at first registration
|
|
65
|
+
in that window, which is the ordinary case — but a personalised mark on the
|
|
66
|
+
same car could be from any era, so the inference runs only from mark to
|
|
67
|
+
earliest-possible-registration, never from mark to build year.
|
|
68
|
+
|
|
69
|
+
codes:
|
|
70
|
+
- { code: "51", from: "2001-09", to: "2002-02", source: inf104 }
|
|
71
|
+
- { code: "02", from: "2002-03", to: "2002-08", source: inf104 }
|
|
72
|
+
- { code: "52", from: "2002-09", to: "2003-02", source: inf104 }
|
|
73
|
+
- { code: "03", from: "2003-03", to: "2003-08", source: inf104 }
|
|
74
|
+
- { code: "53", from: "2003-09", to: "2004-02", source: inf104 }
|
|
75
|
+
- { code: "04", from: "2004-03", to: "2004-08", source: inf104 }
|
|
76
|
+
- { code: "54", from: "2004-09", to: "2005-02", source: inf104 }
|
|
77
|
+
- { code: "05", from: "2005-03", to: "2005-08", source: inf104 }
|
|
78
|
+
- { code: "55", from: "2005-09", to: "2006-02", source: inf104 }
|
|
79
|
+
- { code: "06", from: "2006-03", to: "2006-08", source: inf104 }
|
|
80
|
+
- { code: "56", from: "2006-09", to: "2007-02", source: inf104 }
|
|
81
|
+
- { code: "07", from: "2007-03", to: "2007-08", source: inf104 }
|
|
82
|
+
- { code: "57", from: "2007-09", to: "2008-02", source: inf104 }
|
|
83
|
+
- { code: "08", from: "2008-03", to: "2008-08", source: inf104 }
|
|
84
|
+
- { code: "58", from: "2008-09", to: "2009-02", source: inf104 }
|
|
85
|
+
- { code: "09", from: "2009-03", to: "2009-08", source: inf104 }
|
|
86
|
+
- { code: "59", from: "2009-09", to: "2010-02", source: inf104 }
|
|
87
|
+
- { code: "10", from: "2010-03", to: "2010-08", source: inf104 }
|
|
88
|
+
- { code: "60", from: "2010-09", to: "2011-02", source: inf104 }
|
|
89
|
+
- { code: "11", from: "2011-03", to: "2011-08", source: inf104 }
|
|
90
|
+
- { code: "61", from: "2011-09", to: "2012-02", source: inf104 }
|
|
91
|
+
- { code: "12", from: "2012-03", to: "2012-08", source: inf104 }
|
|
92
|
+
- { code: "62", from: "2012-09", to: "2013-02", source: inf104 }
|
|
93
|
+
- { code: "13", from: "2013-03", to: "2013-08", source: inf104 }
|
|
94
|
+
- { code: "63", from: "2013-09", to: "2014-02", source: inf104 }
|
|
95
|
+
- { code: "14", from: "2014-03", to: "2014-08", source: inf104 }
|
|
96
|
+
- { code: "64", from: "2014-09", to: "2015-02", source: inf104 }
|
|
97
|
+
- { code: "15", from: "2015-03", to: "2015-08", source: inf104 }
|
|
98
|
+
- { code: "65", from: "2015-09", to: "2016-02", source: inf104 }
|
|
99
|
+
- { code: "16", from: "2016-03", to: "2016-08", source: inf104 }
|
|
100
|
+
- { code: "66", from: "2016-09", to: "2017-02", source: inf104 }
|
|
101
|
+
- { code: "17", from: "2017-03", to: "2017-08", source: inf104 }
|
|
102
|
+
- { code: "67", from: "2017-09", to: "2018-02", source: inf104 }
|
|
103
|
+
- { code: "18", from: "2018-03", to: "2018-08", source: inf104 }
|
|
104
|
+
- { code: "68", from: "2018-09", to: "2019-02", source: inf104 }
|
|
105
|
+
- { code: "19", from: "2019-03", to: "2019-08", source: inf104 }
|
|
106
|
+
- { code: "69", from: "2019-09", to: "2020-02", source: inf104 }
|
|
107
|
+
- { code: "20", from: "2020-03", to: "2020-08", source: inf104 }
|
|
108
|
+
- { code: "70", from: "2020-09", to: "2021-02", source: inf104 }
|
|
109
|
+
- { code: "21", from: "2021-03", to: "2021-08", source: inf104 }
|
|
110
|
+
- { code: "71", from: "2021-09", to: "2022-02", source: inf104 }
|
|
111
|
+
- { code: "22", from: "2022-03", to: "2022-08", source: inf104 }
|
|
112
|
+
- { code: "72", from: "2022-09", to: "2023-02", source: inf104 }
|
|
113
|
+
- { code: "23", from: "2023-03", to: "2023-08", source: inf104 }
|
|
114
|
+
- { code: "73", from: "2023-09", to: "2024-02", source: inf104 }
|
|
115
|
+
- { code: "24", from: "2024-03", to: "2024-08", source: inf104 }
|
|
116
|
+
- { code: "74", from: "2024-09", to: "2025-02", source: inf104 }
|
|
117
|
+
- { code: "25", from: "2025-03", to: "2025-08", source: inf104 }
|
|
118
|
+
- { code: "75", from: "2025-09", to: "2026-02", source: inf104 }
|
|
119
|
+
- { code: "26", from: "2026-03", to: "2026-08", source: inf104 }
|
|
120
|
+
- { code: "76", from: "2026-09", to: "2027-02", source: inf104 }
|
|
121
|
+
- { code: "27", from: "2027-03", to: "2027-08", source: inf104 }
|
|
122
|
+
- { code: "77", from: "2027-09", to: "2028-02", source: inf104 }
|
|
123
|
+
- { code: "28", from: "2028-03", to: "2028-08", source: inf104 }
|
|
124
|
+
- { code: "78", from: "2028-09", to: "2029-02", source: inf104 }
|
|
125
|
+
- { code: "29", from: "2029-03", to: "2029-08", source: inf104 }
|
|
126
|
+
- { code: "79", from: "2029-09", to: "2030-02", source: inf104 }
|
|
127
|
+
- { code: "30", from: "2030-03", to: "2030-08", source: hmrc-continuation }
|
|
128
|
+
- { code: "80", from: "2030-09", to: "2031-02", source: hmrc-continuation }
|
|
129
|
+
- { code: "31", from: "2031-03", to: "2031-08", source: hmrc-continuation }
|
|
130
|
+
- { code: "81", from: "2031-09", to: "2032-02", source: hmrc-continuation }
|
|
131
|
+
- { code: "32", from: "2032-03", to: "2032-08", source: hmrc-continuation }
|
|
132
|
+
- { code: "82", from: "2032-09", to: "2033-02", source: hmrc-continuation }
|
|
133
|
+
- { code: "33", from: "2033-03", to: "2033-08", source: hmrc-continuation }
|
|
134
|
+
- { code: "83", from: "2033-09", to: "2034-02", source: hmrc-continuation }
|
|
135
|
+
- { code: "34", from: "2034-03", to: "2034-08", source: hmrc-continuation }
|
|
136
|
+
- { code: "84", from: "2034-09", to: "2035-02", source: hmrc-continuation }
|
|
137
|
+
- { code: "35", from: "2035-03", to: "2035-08", source: hmrc-continuation }
|
|
138
|
+
- { code: "85", from: "2035-09", to: "2036-02", source: hmrc-continuation }
|
|
139
|
+
- { code: "36", from: "2036-03", to: "2036-08", source: hmrc-continuation }
|
|
140
|
+
- { code: "86", from: "2036-09", to: "2037-02", source: hmrc-continuation }
|
|
141
|
+
- { code: "37", from: "2037-03", to: "2037-08", source: hmrc-continuation }
|
|
142
|
+
- { code: "87", from: "2037-09", to: "2038-02", source: hmrc-continuation }
|
|
143
|
+
- { code: "38", from: "2038-03", to: "2038-08", source: hmrc-continuation }
|
|
144
|
+
- { code: "88", from: "2038-09", to: "2039-02", source: hmrc-continuation }
|
|
145
|
+
- { code: "39", from: "2039-03", to: "2039-08", source: hmrc-continuation }
|
|
146
|
+
- { code: "89", from: "2039-09", to: "2040-02", source: hmrc-continuation }
|
|
147
|
+
- { code: "40", from: "2040-03", to: "2040-08", source: hmrc-continuation }
|
|
148
|
+
- { code: "90", from: "2040-09", to: "2041-02", source: hmrc-continuation }
|
|
149
|
+
- { code: "41", from: "2041-03", to: "2041-08", source: hmrc-continuation }
|
|
150
|
+
- { code: "91", from: "2041-09", to: "2042-02", source: hmrc-continuation }
|
|
151
|
+
- { code: "42", from: "2042-03", to: "2042-08", source: hmrc-continuation }
|
|
152
|
+
- { code: "92", from: "2042-09", to: "2043-02", source: hmrc-continuation }
|
|
153
|
+
- { code: "43", from: "2043-03", to: "2043-08", source: hmrc-continuation }
|
|
154
|
+
- { code: "93", from: "2043-09", to: "2044-02", source: hmrc-continuation }
|
|
155
|
+
- { code: "44", from: "2044-03", to: "2044-08", source: hmrc-continuation }
|
|
156
|
+
- { code: "94", from: "2044-09", to: "2045-02", source: hmrc-continuation }
|
|
157
|
+
- { code: "45", from: "2045-03", to: "2045-08", source: hmrc-continuation }
|
|
158
|
+
- { code: "95", from: "2045-09", to: "2046-02", source: hmrc-continuation }
|
|
159
|
+
- { code: "46", from: "2046-03", to: "2046-08", source: hmrc-continuation }
|
|
160
|
+
- { code: "96", from: "2046-09", to: "2047-02", source: hmrc-continuation }
|
|
161
|
+
- { code: "47", from: "2047-03", to: "2047-08", source: hmrc-continuation }
|
|
162
|
+
- { code: "97", from: "2047-09", to: "2048-02", source: hmrc-continuation }
|
|
163
|
+
- { code: "48", from: "2048-03", to: "2048-08", source: hmrc-continuation }
|
|
164
|
+
- { code: "98", from: "2048-09", to: "2049-02", source: hmrc-continuation }
|
|
165
|
+
- { code: "49", from: "2049-03", to: "2049-08", source: hmrc-continuation }
|
|
166
|
+
- { code: "99", from: "2049-09", to: "2050-02", source: hmrc-continuation }
|
|
167
|
+
|
|
168
|
+
not_modelled:
|
|
169
|
+
- "Codes for periods after February 2050. INF104 says the pattern continues 'until all possible variations have been used' and neither authority publishes what happens when 99 is reached; extrapolating past the published tables was declined."
|
|
170
|
+
- "The Northern Irish and pre-2001 systems encode no date at all — see plates/gb.yml#gb-ni-standard and #gb-prefix-1984 — so this table must never be applied to them."
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
# plates/_decode/gb-memory-tags.yml — DVLA memory tags (current British format).
|
|
2
|
+
#
|
|
3
|
+
# THE SOURCE FINDING, and it is the mirror image of the German one: this table
|
|
4
|
+
# is NOT in any statutory instrument and never could be. VERA 1994 § 23(4)
|
|
5
|
+
# empowers regulations over "(a) the size, shape and character of registration
|
|
6
|
+
# marks to be fixed on any vehicle, and (b) the manner in which registration
|
|
7
|
+
# marks are to be displayed" — not over WHICH letters a mark is made of. The
|
|
8
|
+
# composition of a British mark is an administrative allocation by the
|
|
9
|
+
# Secretary of State under § 23(1), and DVLA publishes it in the leaflet
|
|
10
|
+
# INF104. So where plates/_decode/es-provinces.yml is enacted law and the
|
|
11
|
+
# German district list is a Bundesanzeiger publication, this is a leaflet —
|
|
12
|
+
# and a leaflet from the issuing authority is still a PRIMARY (PRD-PLATES § 4:
|
|
13
|
+
# "Government/authority pages ... PRIMARY").
|
|
14
|
+
#
|
|
15
|
+
# Every row below is INF104 (4/22) § 05 "DVLA memory tags and age identifiers",
|
|
16
|
+
# transcribed in the leaflet's own order and its own grouping (postal area
|
|
17
|
+
# letter -> DVLA office -> tag list). WHERE INF104 PRINTS A RANGE it is kept as
|
|
18
|
+
# a range and NOT expanded, because expanding it would require deciding what
|
|
19
|
+
# the range does with I, Q and Z — a decision the leaflet makes elsewhere, in
|
|
20
|
+
# prose, and which is recorded here as `range_rule` rather than baked silently
|
|
21
|
+
# into 25 invented rows.
|
|
22
|
+
#
|
|
23
|
+
# EVERY TAG IS QUOTED, AND IT HAS TO BE. Psych resolves the bare scalar NO to
|
|
24
|
+
# the boolean false (as it does ON, OFF, TRUE, YES), and "NO" is a real
|
|
25
|
+
# Newcastle memory tag. An unquoted tag list therefore silently turns one row
|
|
26
|
+
# into `false` and a decode lookup misses it forever. This is the same class of
|
|
27
|
+
# defect plates/de.yml records for bare YAML dates, found here by round-tripping
|
|
28
|
+
# the file through YAML.safe_load and re-checking every tag against /\A[A-Z]{2}\z/
|
|
29
|
+
# — a check worth keeping in any future decode-table pass.
|
|
30
|
+
#
|
|
31
|
+
# Referenced by: gb-standard-2001, gb-motorcycle-2001, gb-green-zev-2020
|
|
32
|
+
# (plates/gb.yml) via region_encoding.
|
|
33
|
+
jurisdiction: gb
|
|
34
|
+
topic: memory-tags
|
|
35
|
+
authority:
|
|
36
|
+
name: Driver and Vehicle Licensing Agency (DVLA)
|
|
37
|
+
url: "https://www.gov.uk/government/publications/vehicle-registration-numbers-and-number-plates"
|
|
38
|
+
sources:
|
|
39
|
+
- "https://assets.publishing.service.gov.uk/media/6694e379fc8e12ac3edafc60/inf104-vehicle-registration-numbers-and-number-plates.pdf # INF104 (4/22) § 05 — every row of this file, plus the three charset bullets and the HW / MN+MAN notes"
|
|
40
|
+
- "https://www.gov.uk/government/publications/vehicle-registration-numbers-and-number-plates # INF104 landing page, updated 12 April 2022 (stable citation)"
|
|
41
|
+
- "https://www.legislation.gov.uk/ukpga/1994/22/section/23 # VERA 1994 s 23(1) and (4) — why this table is administrative and not statutory"
|
|
42
|
+
licence: "Crown copyright, Open Government Licence v3.0 (DVLA publication)"
|
|
43
|
+
period: { start: 2001 }
|
|
44
|
+
period_evidence: enabling-instrument
|
|
45
|
+
period_note: >-
|
|
46
|
+
The memory-tag scheme began with the current format on 1 September 2001
|
|
47
|
+
(INF104 § 03). Individual OFFICE allocations have changed since — DVLA closed
|
|
48
|
+
its local offices in 2013 and the office names below are the issuing offices
|
|
49
|
+
as INF104 (4/22) prints them, which a decode must treat as the historical
|
|
50
|
+
allocation point, not as a list of open counters. Rows are never deleted:
|
|
51
|
+
a mark issued under a withdrawn allocation stays on the road, exactly as
|
|
52
|
+
plates/_decode/de-districts.yml requires for German codes.
|
|
53
|
+
|
|
54
|
+
# What the tag means, and what it does NOT mean.
|
|
55
|
+
semantics: >-
|
|
56
|
+
INF104 § 03: the first two characters are a "2 letter memory tag (these refer
|
|
57
|
+
to the region in the country where a vehicle is first registered)". The FIRST
|
|
58
|
+
letter is the postal area; the SECOND selects the DVLA office within it.
|
|
59
|
+
caveat: >-
|
|
60
|
+
A memory tag records WHERE THE VEHICLE WAS FIRST REGISTERED. It is not the
|
|
61
|
+
keeper's address, not the vehicle's current location, and not stable across
|
|
62
|
+
a re-registration or a transfer of a personalised mark. Any consumer using
|
|
63
|
+
it as a present-tense geographic signal is using it wrongly, and a parse API
|
|
64
|
+
must return it labelled as first-registration provenance.
|
|
65
|
+
|
|
66
|
+
charset_rules:
|
|
67
|
+
excluded_from_tags: ["I", "Q", "Z"]
|
|
68
|
+
z_rule: "Z is used only as a random letter (positions 5-7), never in a memory tag"
|
|
69
|
+
q_rule: "Q is excluded from memory tags because it remains in service as the prefix of the indeterminate-age Q series (plates/gb.yml#gb-q)"
|
|
70
|
+
first_letters_used: [A, B, C, D, E, F, G, H, K, L, M, N, O, P, R, S, V, W, Y]
|
|
71
|
+
first_letters_absent: [I, J, Q, T, U, X, Z]
|
|
72
|
+
first_letters_absent_note: >-
|
|
73
|
+
J, T, U and X simply do not appear as postal-area letters in INF104 § 05's
|
|
74
|
+
table; I, Q and Z are excluded by the leaflet's own bullet. The absence is
|
|
75
|
+
recorded as a fact about the published table, not as a rule DVLA states.
|
|
76
|
+
bullets_verbatim:
|
|
77
|
+
- "We will not use I, Q or Z in local memory tags identifiers"
|
|
78
|
+
- "We will still issue existing 'Q' marks"
|
|
79
|
+
- "We will only use Z as a random letter"
|
|
80
|
+
range_rule: >-
|
|
81
|
+
Where INF104 prints a range ("BA - BY", "EA - EY", "MA - MY", "OA - OY",
|
|
82
|
+
"RA - RY", "VA - VY") the second letter runs A to Y inclusive, minus the
|
|
83
|
+
excluded I and Q (Z is above Y and so is excluded by the range itself).
|
|
84
|
+
This expansion is DERIVED from the bullets above; it is stated here once
|
|
85
|
+
rather than written into the rows, so a consumer can see exactly which
|
|
86
|
+
codes are transcribed and which are computed.
|
|
87
|
+
|
|
88
|
+
areas:
|
|
89
|
+
- letter: A
|
|
90
|
+
name: Anglia
|
|
91
|
+
offices:
|
|
92
|
+
- { office: Peterborough, tags: ["AA", "AB", "AC", "AD", "AE", "AF", "AG", "AH", "AJ", "AK", "AL", "AM", "AN"] }
|
|
93
|
+
- { office: Norwich, tags: ["AO", "AP", "AR", "AS", "AT", "AU"] }
|
|
94
|
+
- { office: Ipswich, tags: ["AV", "AW", "AX", "AY"] }
|
|
95
|
+
- letter: B
|
|
96
|
+
name: Birmingham
|
|
97
|
+
offices:
|
|
98
|
+
- { office: Birmingham, range: "BA-BY" }
|
|
99
|
+
- letter: C
|
|
100
|
+
name: Cymru
|
|
101
|
+
offices:
|
|
102
|
+
- { office: Cardiff, tags: ["CA", "CB", "CC", "CD", "CE", "CF", "CG", "CH", "CJ", "CK", "CL", "CM", "CN", "CO"] }
|
|
103
|
+
- { office: Swansea, tags: ["CP", "CR", "CS", "CT", "CU", "CV"] }
|
|
104
|
+
- { office: Bangor, tags: ["CW", "CX", "CY"] }
|
|
105
|
+
- letter: D
|
|
106
|
+
name: Deeside to Shrewsbury
|
|
107
|
+
offices:
|
|
108
|
+
- { office: Chester, tags: ["DA", "DB", "DC", "DD", "DE", "DF", "DG", "DH", "DJ", "DK"] }
|
|
109
|
+
- { office: Shrewsbury, tags: ["DL", "DM", "DN", "DO", "DP", "DR", "DS", "DT", "DU", "DV", "DW", "DX", "DY"] }
|
|
110
|
+
- letter: E
|
|
111
|
+
name: Essex
|
|
112
|
+
offices:
|
|
113
|
+
- { office: Chelmsford, range: "EA-EY" }
|
|
114
|
+
- letter: F
|
|
115
|
+
name: Forest & Fens
|
|
116
|
+
offices:
|
|
117
|
+
- { office: Nottingham, tags: ["FA", "FB", "FC", "FD", "FE", "FF", "FG", "FH", "FJ", "FK", "FL", "FM", "FN", "FP"] }
|
|
118
|
+
- { office: Lincoln, tags: ["FR", "FS", "FT", "FV", "FW", "FX", "FY"] }
|
|
119
|
+
- letter: G
|
|
120
|
+
name: Garden of England
|
|
121
|
+
offices:
|
|
122
|
+
- { office: Maidstone, tags: ["GA", "GB", "GC", "GD", "GE", "GF", "GG", "GH", "GJ", "GK", "GL", "GM", "GN", "GO"] }
|
|
123
|
+
- { office: Brighton, tags: ["GP", "GR", "GS", "GT", "GU", "GV", "GW", "GX", "GY"] }
|
|
124
|
+
- letter: H
|
|
125
|
+
name: Hampshire & Dorset
|
|
126
|
+
offices:
|
|
127
|
+
- { office: Bournemouth, tags: ["HA", "HB", "HC", "HD", "HE", "HF", "HG", "HH", "HJ"] }
|
|
128
|
+
- { office: Portsmouth, tags: ["HK", "HL", "HM", "HN", "HO", "HP", "HR", "HS", "HT", "HU", "HV", "HW", "HX", "HY"],
|
|
129
|
+
note: "INF104, verbatim: '(HW will be used exclusively for Isle of Wight residents)' — the only sub-office geographic reservation in the table" }
|
|
130
|
+
- letter: K
|
|
131
|
+
name: null
|
|
132
|
+
name_note: "INF104 gives no regional name for the K area — the 'Letter' and 'Postal area' columns are blank beside Borehamwood and Northampton. Recorded as null rather than invented."
|
|
133
|
+
offices:
|
|
134
|
+
- { office: Borehamwood, tags: ["KA", "KB", "KC", "KD", "KE", "KF", "KG", "KH", "KJ", "KK", "KL"] }
|
|
135
|
+
- { office: Northampton, tags: ["KM", "KN", "KO", "KP", "KR", "KS", "KT", "KU", "KV", "KW", "KX", "KY"] }
|
|
136
|
+
- letter: L
|
|
137
|
+
name: London
|
|
138
|
+
offices:
|
|
139
|
+
- { office: Wimbledon, tags: ["LA", "LB", "LC", "LD", "LE", "LF", "LG", "LH", "LJ"] }
|
|
140
|
+
- { office: Borehamwood, tags: ["LK", "LL", "LM", "LN", "LO", "LP", "LR", "LS", "LT"] }
|
|
141
|
+
- { office: Sidcup, tags: ["LU", "LV", "LW", "LX", "LY"] }
|
|
142
|
+
- letter: M
|
|
143
|
+
name: Manchester & Merseyside
|
|
144
|
+
offices:
|
|
145
|
+
- { office: Manchester, range: "MA-MY",
|
|
146
|
+
note: "INF104, verbatim: '(MN + MAN Reserved for the Isle of Man)'. The Isle of Man is a separate jurisdiction (ISO 3166-1 IM) with its own registration system; MN is withheld from the British range and MAN is withheld as a three-letter group so that no British mark collides with a Manx one." }
|
|
147
|
+
- letter: N
|
|
148
|
+
name: North
|
|
149
|
+
offices:
|
|
150
|
+
- { office: Newcastle, tags: ["NA", "NB", "NC", "ND", "NE", "NG", "NH", "NJ", "NK", "NL", "NM", "NN", "NO"],
|
|
151
|
+
note: "NF is absent from INF104's Newcastle list and is not assigned elsewhere in the table; transcribed as printed, not corrected" }
|
|
152
|
+
- { office: Stockton, tags: ["NP", "NR", "NS", "NT", "NU", "NV", "NW", "NX", "NY"] }
|
|
153
|
+
- letter: O
|
|
154
|
+
name: Oxford
|
|
155
|
+
offices:
|
|
156
|
+
- { office: Oxford, range: "OA-OY" }
|
|
157
|
+
- letter: P
|
|
158
|
+
name: Preston
|
|
159
|
+
offices:
|
|
160
|
+
- { office: Preston, tags: ["PA", "PB", "PC", "PD", "PE", "PF", "PG", "PH", "PJ", "PK", "PL", "PM", "PN", "PO", "PP", "PR", "PS", "PT"] }
|
|
161
|
+
- { office: Carlisle, tags: ["PU", "PV", "PW", "PX", "PY"] }
|
|
162
|
+
- letter: R
|
|
163
|
+
name: Reading
|
|
164
|
+
offices:
|
|
165
|
+
- { office: Theale, range: "RA-RY", note: "the postal area is Reading; the issuing office INF104 names is Theale" }
|
|
166
|
+
- letter: S
|
|
167
|
+
name: Scotland
|
|
168
|
+
offices:
|
|
169
|
+
- { office: Glasgow, tags: ["SA", "SB", "SC", "SD", "SE", "SF", "SG", "SH", "SJ"] }
|
|
170
|
+
- { office: Edinburgh, tags: ["SK", "SL", "SM", "SN", "SO"] }
|
|
171
|
+
- { office: Dundee, tags: ["SP", "SR", "SS", "ST"] }
|
|
172
|
+
- { office: Aberdeen, tags: ["SU", "SV", "SW"] }
|
|
173
|
+
- { office: Inverness, tags: ["SX", "SY"] }
|
|
174
|
+
- letter: V
|
|
175
|
+
name: Severn Valley
|
|
176
|
+
offices:
|
|
177
|
+
- { office: Worcester, range: "VA-VY" }
|
|
178
|
+
- letter: W
|
|
179
|
+
name: West of England
|
|
180
|
+
offices:
|
|
181
|
+
- { office: Exeter, tags: ["WA", "WB", "WC", "WD", "WE", "WF", "WG", "WH", "WJ"] }
|
|
182
|
+
- { office: Truro, tags: ["WK", "WL"] }
|
|
183
|
+
- { office: Bristol, tags: ["WM", "WN", "WO", "WP", "WR", "WS", "WT", "WU", "WV", "WW", "WX", "WY"] }
|
|
184
|
+
- letter: Y
|
|
185
|
+
name: Yorkshire
|
|
186
|
+
offices:
|
|
187
|
+
- { office: Leeds, tags: ["YA", "YB", "YC", "YD", "YE", "YF", "YG", "YH", "YJ", "YK", "YL"] }
|
|
188
|
+
- { office: Sheffield, tags: ["YM", "YN", "YO", "YP", "YR", "YS", "YT", "YV"] }
|
|
189
|
+
- { office: Beverley, tags: ["YU", "YW", "YX", "YY"] }
|
|
190
|
+
|
|
191
|
+
# Ambiguity notes a parse API must carry.
|
|
192
|
+
ambiguity:
|
|
193
|
+
- "MAXIMAL MUNCH DOES NOT APPLY HERE, unlike es-provinces: a British memory tag is ALWAYS exactly two characters, because the age identifier that follows is always exactly two digits. There is no longest-match problem."
|
|
194
|
+
- "A tag decodes only in the current (post-1.9.2001) format. The same two letters at the start of a pre-2001 mark are NOT a memory tag: in the suffix system they are the first two of a three-letter area code, and in the prefix system the leading letter is a YEAR code. A parse API must establish the series before consulting this table."
|
|
195
|
+
- "X is never a memory-tag first letter, which is what makes the export series (plates/gb.yml#gb-export-x, 'XA51 ABC') mechanically separable from an ordinary mark despite sharing its shape."
|
|
196
|
+
- "Northern Irish marks have no memory tag at all and must not be decoded through this table (see plates/gb.yml#gb-ni-standard)."
|
|
197
|
+
|
|
198
|
+
# What this table deliberately does NOT contain.
|
|
199
|
+
not_modelled:
|
|
200
|
+
- "The pre-2001 local-office area codes (the trailing two letters of a suffix or prefix mark). No primary was located; recorded as a gap in the gb dossier."
|
|
201
|
+
- "The Northern Irish district letters. No primary was located; recorded as a gap."
|
|
202
|
+
- "Which office issued which tag AT A GIVEN DATE. INF104 publishes one snapshot; DVLA local offices closed in 2013 and the leaflet was reissued 4/22 without a period column, so per-row period discipline is impossible from this source and is not faked."
|