Skip to content

Latest commit

 

History

99 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

French Postal Code

Regions, departments, communes and postal codes of France, with one GPS point per postal code and the history of changes.

CI Release License: MIT PHP 8.4 Laravel 13 PHPStan max


Dataset of the regions, departments, communes and postal codes of France (metropolitan France, DROM and COM), with one GPS point per postal code and the history of changes (mergers, code changes, creations, deletions).

It is built from official open sources, updated automatically, and designed so that an application can attach its addresses to it through a foreign key.

What the dataset contains

Table Content
regions The regions (code, name).
departments The departments and the overseas collectivities (code, name, region).
communes The communes and the municipal arrondissements, with their INSEE code, their department and the centre of the commune.
cities One row per commune and per postal code, for example "37200 Tours", with its GPS point.
commune_successions For an old INSEE code, the code that succeeds it, the nature of the change and its date.
reference_changes The changes detected between two updates (regions, departments, postal codes).

Every table carries a validity period (valid_from, valid_to): a row is never deleted, its validity is closed. Identifiers are therefore stable over time.

regions ──< departments ──< communes ──< cities <── addresses (table of your application)

One GPS point per postal code

Tours (37261) has three postal codes, and each one has its own point:

Postal code Latitude Longitude Addresses used
37000 47.3858 0.6886 18,746
37100 47.4164 0.6930 10,489
37200 47.3661 0.7044 1,007

The point of a postal code is the median of the address positions of the Base Adresse Nationale (BAN) for that postal code in that commune. The coordinate_source column always tells where the point comes from:

  1. ban: median of the BAN addresses (the vast majority of cities).
  2. nominatim: search of the postal code and the commune on Nominatim, for cities with no address in the BAN.
  3. commune_centre: centre of the commune, as the last fallback.

address_count gives the number of addresses used: a postal code with very few addresses is less reliable.

Sources and licences

Source Usage Licence
INSEE, Code officiel géographique Regions, departments, communes, history since 1943 and commune events. Licence Ouverte
La Poste, base officielle des codes postaux Link between a commune and its postal codes. Licence Ouverte
geo.api.gouv.fr Centre of each commune. Licence Ouverte
Base Adresse Nationale GPS point of each postal code. Licence Ouverte
Nominatim (OpenStreetMap) Fallback for cities with no address in the BAN. ODbL

Attaching addresses

An application stores its addresses with a foreign key to cities:

$city = City::current()
    ->where('postal_code', '37200')
    ->whereRelation('commune', 'insee_code', '37261')
    ->firstOrFail();

$address = Address::create([
    'line'    => '3 rue Jules Massenet',
    'city_id' => $city->id,
]);

$address->city
    ->commune
    ->department
    ->region
    ->name; // Centre-Val de Loire

For the addresses.city_id foreign key to work, the cities table must live in the same database as addresses.

Migrating old codes

When a commune merges or changes its code, its old codes keep pointing to it through commune_successions.
Example: Saint-Florent-des-Bois merged in 2016 into "Rives de l'Yon", which took over the code 85213, while Chaillé-sous-les-Ormeaux (85043) was absorbed.

make resolve CODE=85043 POSTAL_CODE=85310
# 2016-01-01  absorbed: 85043 -> 85213
# 2016-01-01  code_reused: 85213 -> 85213
# Current communes: 85213
# city #33125  85310  RIVES DE L YON  (46.590263, -1.333875)

The result follows succession chains (A to B to C), reports a commune that disappeared without a successor, lists every successor of a split commune and warns when the original postal code is no longer in use. The same information is in the exported files (commune_successions, and replaced_by_city_id in cities) so you can migrate your data without going through this repository.

Limits of the history

  • For communes, departments and regions, the history goes back to 1943 (the overseas COM have none before the first import).
  • INSEE publishes no event for postal codes: their tracking relies on the comparison between two updates and starts at the first import kept.

Usage

Requirements: Docker and Make.

make start          # starts PHP 8.4, MySQL 8.4, Redis and Horizon, installs the dependencies, migrates the database
make update         # updates the dataset (official files, then GPS points), on the queue
make update-sync    # same, in this terminal with a progress bar
make update-force   # same, importing every file again even if it did not change
make status         # state of the dataset and of the last update
make export         # exports to CSV, JSON and SQL in storage/app/exports
make build-dataset  # update then export in one go (build-dataset-force imports every file again)
make stop           # stops the project and removes its containers and volumes

make update downloads the official files and only re-imports the ones that changed. The GPS points are computed by parallel jobs, one per department, then a check verifies that every city has a point, that every department was processed and that no job failed. A full update takes about 15 minutes.

The matching php artisan commands:

  • dataset:update (--sync, --force, --skip-coordinates)
  • dataset:status
  • dataset:resolve
  • dataset:export.

Published files

The exports are attached to the releases of the repository and published on data.gouv.fr. They contain one file per table, in CSV, JSON and SQL.

Content of the dataset and downloads by format

Usage statistics of the dataset and the repository

Development

make quality    # Pint, PHPStan (max level), Rector, PHPInsights, Markdownlint
make test       # PHPUnit

The repository uses zairakai/laravel-dev-tools (quality tools, git hooks, Makefile).
Commits follow Conventional Commits with the ticket number (type(scope): #123 subject) and the repository only accepts merge commits on rebased branches.
The architecture is described in docs/architecture.md and how to publish a version in docs/release.md.
See also CONTRIBUTING.md, SECURITY.md and the code of conduct.

Licence

MIT for the code. The data remain subject to the licences of their sources (see above).


Made by Stanislas Poisson (Zairakai)

GitHub GitLab LinkedIn Twitch Linktree Support the stream

About

Dataset of the regions, departments, communes and postal codes of France, with one GPS point per postal code and the history of changes. Built from INSEE, La Poste, BAN and geo.api.gouv.fr.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

87 stars

Watchers

5 watching

Forks

Releases

Used by

Contributors

Languages