library(sf)
library(ggplot2)
library(glue)
library(ggspatial)
library(dplyr)
library(stringr)
library(purrr)
library(httr)Day 24 of 30DayMapChallenge: « Places and their names » (previously).
BDTOPO is the most detailed topographic GIS database for France, made by IGN under a free licence. It includes names. It’s massive (40 GB) so take a break while downloading…
Config
Data
Basemap
# See https://r.iresmi.net/posts/2021/simplifying_polygons_layers/
dep <- read_sf("~/data/adminexpress/adminexpress-cog-simpl-000-2024.gpkg",
layer = "departement") |>
filter(insee_dep < "971")Download and extract
url_bdtopo <- glue("https://data.geopf.fr/telechargement/download/BDTOPO/\\
BDTOPO_3-5_TOUSTHEMES_GPKG_WGS84G_FRA_2025-09-15/\\
BDTOPO_3-5_TOUSTHEMES_GPKG_WGS84G_FRA_2025-09-15.7z.0")
glue("{url_bdtopo}{sprintf('%02i', 1:10)}") |>
walk(\(x) RETRY("GET", x,
write_disk(basename(x),
overwrite = TRUE)),
.progress = TRUE)
system("7z e BDTOPO_3-5_TOUSTHEMES_GPKG_WGS84G_FRA_2025-09-15.7z.001 -r toponymie.gpkg")Get suffix
More information (in french)
toponymy <- read_sf("toponymie.gpkg",
query = r"[
SELECT *
FROM toponymie
WHERE classe_de_l_objet IN ("Lieu-dit non habité",
"Zone d'habitation")
]") |>
st_filter(dep)
suffix <- toponymy |>
mutate(suffix = case_when(
str_detect(graphie_du_toponyme, "ac$") ~ "-acum → -ac",
str_detect(graphie_du_toponyme, "(ey|ay)$") ~ "-acum → -ey -ay",
str_detect(graphie_du_toponyme, "illy$") ~ "-acum → -illy",
str_detect(graphie_du_toponyme, "at$") ~ "-acum → -at")) |>
filter(!is.na(suffix)) Map
suffix |>
bind_cols(st_coordinates(suffix)) |>
ggplot() +
geom_sf(data = dep) +
geom_sf(aes(color = suffix), size = .1, alpha = .2) +
facet_wrap(~ suffix, ncol = 1) +
coord_sf() +
labs(title = "French localities suffix",
subtitle = "from gallo-roman -acum",
caption = glue("data: IGN BDTOPO 2025
https://r.iresmi.net - {Sys.Date()}")) +
theme_void() +
theme(plot.caption = element_text(size = 7, color = "grey40"),
plot.margin = unit(c(.2, .2, .2, .2), units = "cm"),
legend.position = "none")
