Skip to content

Commit

Permalink
Suppression parties commune avec tuto osm postgis
Browse files Browse the repository at this point in the history
  • Loading branch information
Guts committed Sep 4, 2023
1 parent dd1fd13 commit 4629e52
Showing 1 changed file with 21 additions and 294 deletions.
315 changes: 21 additions & 294 deletions content/articles/2022/2022-06-07_ferrargis-carte-de-ferraris-qgis.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,14 @@ authors:
categories:
- article
- tutoriel
date: "2022-06-07 10:20"
date: "2023-09-15 10:20"
description: "Description pour le SEO."
icon: simple/ferrari
image: "https://cdn.geotribu.fr/img/articles-blog-rdp/articles/qgis_ferraris/export_aix_large.png"
license: default
tags:
- cartographie
- OpenStreetMap
- osm2pgsql
- Osmium
- PostgreSQL
- QGIS
---

Expand All @@ -25,7 +23,7 @@ tags:

# FerrarGIS, un style de carte de Ferraris (1777) avec QGIS

:calendar: Date de publication initiale : 7 juin 2022
:calendar: Date de publication initiale : 15 septembre 2023

Prérequis :

Expand Down Expand Up @@ -54,230 +52,33 @@ L'occasion d'un petit tutoriel, non pas pour manipuler les styles de QGIS et bri

----

## Les outils
### Configuration Base Postg

### Installer osm2pgsql
Pour continuer, je dispose :

![logo osm2pgsql](https://cdn.geotribu.fr/img/logos-icones/logiciels_librairies/osm2pgsql.png "logo osm2pgsql"){: .img-rdp-news-thumb }
- [ ] d'un cluster PostgreSQL (15 en l'occurrence mais ça doit fonctionner avec des versions plus anciennes) sur le port `54352`
- [ ] d'une base de données que j'ai appelée `osm_ferrargis`
- [ ] sur laquelle j'ai activé les extensions `postgis` et `hstore`
- [ ] à laquelle je me connecte de façon sécurisée à l'aide des fichiers `~/.pgpass` et `~/.pg_service.conf` dont je mets ci-dessous une idée de ce qu'il y a dedans :

Afin d'importer les données OpenStreetMap dans PostgreSQL, on va devoir utiliser [osm2pgsql](/?q=osm2pgsql*) qui est un outil en ligne de commande maintenu par la communauté OSM. Pour l'installation, rien de plus simple.

Sur Debian et dérivés comme Ubuntu :

```sh
sudo apt install osm2pgsql
```

Sur Windows, le [tutoriel de LearnOSM](https://learnosm.org/en/osm-data/osm2pgsql/) est très bien !

- Oui, une question Joséphine ?
- Monsieur, il est en anglais votre tuto et dans plein d'autres langues sauf en Français !
- Mon ange, c'est une excellente remarque que vous faites là ! C'est justement l'occasion de vous proposer pour contribuer à la traduction de ce merveilleux support !
- Ah ouais, bonne idée, ça me fera un bon exercice pour travailler la [version en anglais](https://www.edulide.fr/blog/reussir-version-anglais/) !

[Faites chauffer DeepL et Transifex pour contribuer à LearnOSM :fontawesome-solid-language:](https://learnosm.org/en/contribute/translator/){: .md-button }
{: align=middle }

### Installer et configurer PostgreSQL

![logo PostgreSQL](https://cdn.geotribu.fr/img/logos-icones/logiciels_librairies/postgresql.png "logo PostgreSQL"){: .img-rdp-news-thumb }

Installer PostgreSQL n'a rien de sorcier, tant le travail de packaging et de distribution est remarquablement réalisé et documenté, comme en témoigne [la page de téléchargement](https://www.postgresql.org/download/). Mais c'est toujours bon de se noter les commandes à utiliser pour installer les versions depuis les dépôts communautaires.

Par exemple, sur les distributions Linux comme Ubuntu :

```sh
# quelques dépendances communes
sudo apt install curl gpg gnupg2 software-properties-common apt-transport-https lsb-release ca-certificates
# on télécharge et on inscrit la clé permettant de certifier la provenance des paquets logiciels
curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/postgresql.gpg
# on référence le dépôt communautaire dans les sources logicielles du système
echo "deb http://apt.postgresql.org/pub/repos/apt/ `lsb_release -cs`-pgdg main" | sudo tee /etc/apt/sources.list.d/pgdg.list
# on installe PostgreSQL
sudo apt install postgresql-14 postgresql-client-14 postgresql-14-postgis-3
```

Le truc avec le packaging de PostgreSQL sur Debian et Ubuntu c'est que les scripts de post-installation créent par défaut un cluster `main`. C'est sympa de faire une partie du taf mais ce serait plus correct de demander avant quand même, en plus, le cluster est même pas optimisé !
Quand je fais installer un four en terre chez moi, je ne m'attends pas à ce que l'artisan me fasse une calzone mal cuite juste après la dernière pierre posée ! :pizza:

#### Création d'un cluster optimisé

C'est parti pour la création d'un cluster aux ~~petits oignons~~ petites olives ! On commence par lister les versions installées et les ports respectifs :

```bash
> grep -H '^port' /etc/postgresql/*/main/postgresql.conf
/etc/postgresql/12/main/postgresql.conf:port = 5432 # (change requires restart)
/etc/postgresql/14/main/postgresql.conf:port = 54342 # (change requires restart)
```

Puis les clusters existants :

```bash
> pg_lsclusters
Ver Cluster Port Status Owner Data directory Log file
12 main 5432 online postgres /var/lib/postgresql/12/main /var/log/postgresql/postgresql-12-main.log
14 main 54342 online postgres /var/lib/postgresql/14/main /var/log/postgresql/postgresql-14-main.log
```

L'objectif est donc de créer un cluster dédié avec des paramètres optimisés pour les tâches souhaitées (import de données OSM) et par rapport à l'ordinateur utilisé (un Dell XPS 15 7590 avec un Intel Core i7-9750H de 9e génération - voir la [fiche technique](https://www.dell.com/support/manuals/fr-fr/xps-15-7590-laptop/xps-15-7590-setup-and-specifications/processeurs?guid=guid-bfa52f40-8ad1-4df0-8d0f-942766bc2118&lang=fr-fr)).

Pour cela, on va s'appuyer sur deux éléments :

- la [documentation d'osm2pgsql](https://osm2pgsql.org/doc/manual.html#tuning-the-postgresql-server) qui recommande des paramètres de configuration
- les outils comme [PGTune](https://pgtune.leopard.in.ua/) qui permettent de générer une configuration selon les capacités de la machine et le type d'application

[![PGTune - Dell XPS 15 7590](https://cdn.geotribu.fr/img/articles-blog-rdp/articles/qgis_ferraris/pgtune_dell-xps-15-7590_osm_data.png "PGTune - Dell XPS 15 7590"){: .img-center loading=lazy}](https://cdn.geotribu.fr/img/articles-blog-rdp/articles/qgis_ferraris/pgtune_dell-xps-15-7590_osm_data.png "PGTune - Dell XPS 15 7590"){: data-mediabox="lightbox-gallery" data-title="PGTune - Dell XPS 15 7590"}

C'est parti, on crée un cluster `ferrargis` en passant directement les options qui nous intéressent. Notez que je réduis certains paramètres pour garder la main sur mon interface graphique et qu'en cas de valeurs différentes entre PGTune et osm2pgsql, j'ai choisi de donner la priorité à ce dernier :

```bash title="Commande multi-ligne pour créer un cluster PostgreSQL"
sudo pg_createcluster 14 ferrargis \
--port=54342 \
--pgoption autovacuum_work_mem='2GB' \
--pgoption checkpoint_completion_target='0.9' \
--pgoption checkpoint_timeout='60min' \
--pgoption default_statistics_target='500' \
--pgoption effective_cache_size='10GB' \
--pgoption effective_io_concurrency='200' \
--pgoption maintenance_work_mem='10GB' \
--pgoption min_wal_size='4GB' \
--pgoption max_connections='40' \
--pgoption max_wal_size='12GB' \
--pgoption max_worker_processes='10' \
--pgoption max_parallel_workers_per_gather='6' \
--pgoption max_parallel_workers='10' \
--pgoption max_parallel_maintenance_workers='4' \
--pgoption max_wal_senders='0' \
--pgoption random_page_cost='1.1' \
--pgoption shared_buffers='1GB' \
--pgoption wal_buffers='16MB' \
--pgoption wal_level='minimal' \
--pgoption work_mem='50MB' \
-- --data-checksums --lc-messages=C --auth-host=scram-sha-256 --auth-local=peer
```

<!-- 1. Le port doit être différent de ceux déjà utilisés par les autres clusters. -->

<!-- markdownlint-disable MD046 -->
??? example "Le détail de l'exécution sur ma machine"

```bash
Creating new PostgreSQL cluster 14/ferrargis ...
/usr/lib/postgresql/14/bin/initdb -D /var/lib/postgresql/14/ferrargis --no-instructions --data-checksums --lc-messages=C --data-checksums --lc-messages=C --auth-host=scram-sha-256 --auth-local=peer
Les fichiers de ce système de bases de données appartiendront à l'utilisateur « postgres ».
Le processus serveur doit également lui appartenir.

L'instance sera initialisée avec les locales
COLLATE: fr_FR.UTF-8
CTYPE: fr_FR.UTF-8
MESSAGES: C
MONETARY: fr_FR.UTF-8
NUMERIC: fr_FR.UTF-8
TIME: fr_FR.UTF-8
L'encodage par défaut des bases de données a été configuré en conséquence
avec « UTF8 ».
La configuration de la recherche plein texte a été initialisée à « french ».

Les sommes de contrôle des pages de données sont activées.

correction des droits sur le répertoire existant /var/lib/postgresql/14/ferrargis... ok
création des sous-répertoires... ok
sélection de l'implémentation de la mémoire partagée dynamique...posix
sélection de la valeur par défaut pour max_connections... 100
sélection de la valeur par défaut pour shared_buffers... 128MB
sélection du fuseau horaire par défaut... Europe/Paris
création des fichiers de configuration... ok
lancement du script bootstrap...ok
exécution de l'initialisation après bootstrap... ok
synchronisation des données sur disque... ok
Ver Cluster Port Status Owner Data directory Log file
14 ferrargis 54342 down postgres /var/lib/postgresql/14/ferrargis /var/log/postgresql/postgresql-14-ferrargis.log
```
<!-- markdownlint-enable MD046 -->

Il est évidemment possible de changer les paramètres du cluster par la suite, soit via une instuction SQL `ALTER SYSTEM`, soit en éditant le `postgresql.conf` :

```bash
sudo nano /etc/postgresql/14/ferrargis/postgresql.conf
# puis redémarrer le serveur
sudo systemctl restart postgresql@14-ferrargis
```

Démarrer l'instance :

```bash
sudo systemctl start postgresql@14-ferrargis
# ou
sudo pg_ctlcluster 14 ferrargis start
```conf title="Ligne dans le fichier ~/.pgpass (en CHMOD 0600)"
localhost:54352:*:nom_utilisateur_session:mot_de_passe
```

!!! tip "Astuce pour avoir une Calzone réussie à chaque installation"
Il est possible de changer le comportement des scripts de post-installation du packaging PostgreSQL en modifiant le fichier `/etc/postgresql-common/createcluster.conf`, soit pour désactiver la création automatisée du cluster `main`, soit pour en modifier les paramètres par défaut (par exemple avec `initdb_options = '--data-checksums --lc-messages=C'`).
Et cette section dans mon fichier `~/.pg`

#### Créer le rôle et gérer l'accès

Comme on travaille à la maison, on va se faciliter la vie et créer un rôle en base correspondant à l'utilisateur système (trouvable avec la commande `whoami`) de façon à utiliser le mode d'authentification `peer`) :

```bash
sudo -u postgres createuser -p 54342 --createdb --pwprompt --superuser "$(whoami)"
```

De façon à ne pas stocker de mot de passe en clair dans les applications clientes comme QGIS et pour se faciliter la vie, on se crée un fichier `.pgpass` dans le répertoire personnel de l'utilisateur :

```bash
echo "localhost:54342:*:$(whoami):motdepasse_assigned_a_mon_utilisateur" >> ~/.pgpass
```

De même, de façon à garder la connexion la plus générique possible dans le but de rendre la suite le plus facilement reproductible possible, on stocke les paramètres de connexion dans le fichier `PGSERVICE` (voir [la doc officielle de PostgreSQL](https://www.postgresql.org/docs/current/libpq-pgservice.html) et [celle de QGIS](https://docs.qgis.org/3.22/fr/docs/user_manual/managing_data_source/opening_data.html#pg-service-file)) :

- emplacement par défaut : `~/.pg_service.conf` (Linux) ou `%APPDATA%/postgresql/.pg_service.conf` (Windows)
- ou personnalisable via une variable d'environnement `PGSERVICEFILE` pointant sur le fichier directement (nommage libre) ou `PGSYSCONFDIR` pointant sur le répertoire où trouver le fichier (qui doit forcément être nommé `pg_service.conf`)

```ini
```ini title="Section dans le fichier ~/.pg_service.conf"
[local_ferrargis]
dbname=osm
dbname=osm_ferrargis
host=localhost
port=54342
```

#### Créer et configurer la base de données

![logo PostGIS](https://cdn.geotribu.fr/img/logos-icones/logiciels_librairies/postgis.png "logo PostGIS"){: .img-rdp-news-thumb }

Créer la base de données :

```bash
createdb --owner $(whoami) --port 54342 --encoding=UTF8 osm
```

S'y connecter pour tester puis ressortir :

```bash
> psql -p 54342 -U $(whoami) osm
psql (14.3 (Ubuntu 14.3-1.pgdg20.04+1))
Saisissez « help » pour l'aide.
osm=# \q
>
```
Activer PostGIS :
```bash
psql -p 54342 -U $(whoami) osm -c "CREATE EXTENSION postgis;"
```
Activer HSTore :
```bash
psql -p 54342 -U $(whoami) osm -c "CREATE EXTENSION hstore;"
port=54352
```

----

## Les données

### Télécharger OSM sur la Belgique
### Télécharger OSM sur Aix-en-Provence

![logo OpenStreetMap](https://cdn.geotribu.fr/img/logos-icones/OpenStreetMap/Openstreetmap.png "logo OpenStreetMap"){: .img-rdp-news-thumb }

Expand All @@ -287,17 +88,10 @@ Un petit tour par GeoFabrik pour télécharger les données de la Belgique : <ht

On peut également utiliser un outil en ligne de commande, par exemple `wget` avec l'option `-N` qui permet de télécharger uniquement si le fichier distant (ici le serveur GeoFabrik) est plus récent par rapport à la version locale (sur votre machine) :

```bash
wget -N https://download.geofabrik.de/europe/belgium-latest.osm.pbf -P /tmp/osmdata/belgium
```sh
wget -N http://download.geofabrik.de/europe/france/provence-alpes-cote-d-azur-latest.osm.pbf -P /tmp/osmdata/paca
```

<video width="100%" controls>
<!-- markdownlint-disable MD033 -->
<source src="https://cdn.geotribu.fr/img/articles-blog-rdp/articles/qgis_ferraris/wget_osm_geofabrik_belgium.webm" type="video/webM">
Votre navigateur ne supporte pas la balise video HTML 5.
<!-- markdownlint-enable MD033 -->
</video>

### Optionnel : découper les données

![logo Osmium Tool](https://cdn.geotribu.fr/img/logos-icones/logiciels_librairies/osmium.svg "logo Osmium Tool"){: .img-rdp-news-thumb }
Expand All @@ -310,10 +104,10 @@ On installe [Osmium](https://osmcode.org/osmium-tool/) :
sudo apt install osmium-tool
```

Et on découpe sur la zone qui nous intéresse, par exemple Bruxelles :
Et on découpe sur la zone qui nous intéresse, par exemple Aix-en-Provence :

```sh
osmium extract -b 4.29,50.815,4.47,50.90 /tmp/osmdata/belgium/belgium-latest.osm.pbf -o /tmp/osmdata/belgium/brussels.osm.pbf
osmium extract -b 5.21,43.42,5.72,43.66 /tmp/osmdata/paca/provence-alpes-cote-d-azur-latest.osm.pbf -o /tmp/osmdata/paca/aixenprovence.osm.pbf
```

!!! tip "Vigilance"
Expand All @@ -322,76 +116,9 @@ osmium extract -b 4.29,50.815,4.47,50.90 /tmp/osmdata/belgium/belgium-latest.osm
### Import des données

```bash
osm2pgsql --create --database osm --port 54342 --cache 1000 --number-processes 4 /tmp/osmdata/belgium/belgium-latest.osm.pbf
# si vous avez utilisez la commande osmium pour découper les données sur Bruxelles
# osm2pgsql --create --database osm --port 54342 --cache 1000 --number-processes 4 /tmp/osmdata/belgium/brussels.osm.pbf
osm2pgsql --create --database osm_ferrargis --port 54352 --cache 1000 --number-processes 4 /tmp/osmdata/paca/aixenprovence.osm.pbf
```

Détail des options :
- `--create` : créer les données, quitte à les écraser si elles existent déjà dans la base
- `--database` : nom de la base de données
- `--port` : port de connexion à la base de données
- `--cache` : gère la taille du cache (en MB) à allouer pour l'import des noeuds OSM. Je pensais au début que la valeur par défaut (800) suffirait mais j'ai eu l'erreur : *Node cache size is too small to fit all nodes. Please increase cache size*. Dépend de la RAM de votre machine.
- `--number-processes` : nom de processus à utiliser pour paralléliser les tâches qui peuvent l'être
Pour celles et ceux que ça intéresse, voici le détail de l'exécution sur mon ordinateur qui a pris 187 secondes :

<!-- markdownlint-disable MD046 -->
??? example "Le détail de l'exécution sur ma machine"

```bash
> osm2pgsql --create --database osm --port 54342 --cache 1000 --number-processes 4 /tmp/osmdata/belgium/belgium-latest.osm.pbf
osm2pgsql version 1.2.1 (64 bit id space)
Allocating memory for dense node cache
Allocating dense node cache in one big chunk
Allocating memory for sparse node cache
Sharing dense sparse
Node-cache: cache=1000MB, maxblocks=16000*65536, allocation method=3
Using built-in tag processing pipeline
Using projection SRS 3857 (Spherical Mercator)
Setting up table: planet_osm_point
Setting up table: planet_osm_line
Setting up table: planet_osm_polygon
Setting up table: planet_osm_roads
Reading in file: /tmp/osmdata/belgium/belgium-latest.osm.pbf
Using PBF parser.
Processing: Node(53962k 8993.7k/s) Way(8267k 145.05k/s) Relation(81920 11702.86/s) parse time: 70s
Node stats: total(53962322), max(9777797946) in 6s
Way stats: total(8267595), max(1064657400) in 57s
Relation stats: total(87197), max(14192617) in 7s
node cache: stored: 53962322(100.00%), storage efficiency: 50.16% (dense blocks: 170, sparse nodes: 53094157), hit rate: 100.00%
Sorting data and creating indexes for planet_osm_point
Sorting data and creating indexes for planet_osm_line
Sorting data and creating indexes for planet_osm_roads
Sorting data and creating indexes for planet_osm_polygon
Copying planet_osm_roads to cluster by geometry finished
Creating geometry index on planet_osm_roads
Copying planet_osm_point to cluster by geometry finished
Creating geometry index on planet_osm_point
Creating indexes on planet_osm_roads finished
All indexes on planet_osm_roads created in 5s
Completed planet_osm_roads
Creating indexes on planet_osm_point finished
All indexes on planet_osm_point created in 15s
Completed planet_osm_point
Copying planet_osm_line to cluster by geometry finished
Creating geometry index on planet_osm_line
Creating indexes on planet_osm_line finished
Copying planet_osm_polygon to cluster by geometry finished
Creating geometry index on planet_osm_polygon
All indexes on planet_osm_line created in 44s
Completed planet_osm_line
Creating indexes on planet_osm_polygon finished
All indexes on planet_osm_polygon created in 117s
Completed planet_osm_polygon
Osm2pgsql took 187s overall
```
<!-- markdownlint-enable MD046 -->

----

## La carto sur QGIS
Expand Down

0 comments on commit 4629e52

Please sign in to comment.