← Retour aux issues

Suivi installation Osm2pgsql et Underpass

publié le , mis à jour
Avatar github de etienneJretienneJr

Issue créée pour tracer les actions réalisées sur le serveur pour la création de la base OSM au schéma Osm2pgsql et le déploiement de l'instance underpass.

installation et réglage de osm2pgsql

installation osm2pgsql

En suivant : https://osm2pgsql.org/doc/install.html sudo apt install osm2pgsql besoin de 383 MB On est sous ubuntu 24 => installation release 1.11.0

Remarque : il est possible de forcer l'installation de la nouvelle version 2.0.1 à condition de compiler soi même, en suivant le readme. C'est ce que mael a fait pour les premiers tests.

installation postgreSQL

déjà fait lors de la commande précédente => a installé la version 16.8

création de la DB

https://osm2pgsql.org/doc/manual-v1.html#preparing-the-database En utilisant le user ubuntu avec lequel je suis connecté au serveur pour profiter ensuite de la peer authentification. ➡️​ Je ne sais pas si c'est une bonne idée, si il ne faut pas plutôt créer un utilisateur spécifique ?

sudo -u postgres createuser ubuntu
sudo -u postgres createdb --encoding=UTF8 --owner=ubuntu osm
sudo -u postgres psql osm --command='CREATE EXTENSION postgis;'
sudo -u postgres psql osm --command='CREATE EXTENSION hstore;'

Si besoin de vider la base : sudo -u postgres psql postgres --command='DROP DATABASE osm;'

ajustement de la configuration

https://osm2pgsql.org/doc/manual-v1.html#tuning-the-postgresql-server en suivant strictement les valeurs proposées ➡️​ alors qu'elles sont annoncées pour 64GB de RAM et un disque SSD... pour trouver où est la conf : sudo -u postgres psql -c 'SHOW config_file' puis : sudo vi /etc/postgresql/16/main/postgresql.conf et modifications de valeurs puis redémarrage : sudo service postgresql restart

Remplissage de la DB

Réfléxion sur la taille de la DB et le besoin de filtrage

Pour pouvoir faire les updates automatiques à partir des diff, il est nécessaire d'activer l'option --slim. Cela entraine la création de 3 tables pour stocker TOUS les _nodes, _ways et _relations de l'extrait traité. C'est nécessaire pour enregistrer les ajouts ou suppression d'éléments à chaque update. Et cela même si les tables "filtrées" spécifiques de osm2pgsql et contenant la géométrie (tables _point, _line et _polygon) ne contiennent que quelques éléments. Donc contrairement à ce que son nom laisse croire, cette option coûte cher en espace disque ! Exempls sur la Bretagne :

  • l'extrait compressé fait 346 Mo
  • j'avais imagine un filtrage (dans cartes-v1.style) pour que la base fasse 300Mo, mais
  • activer --slim coûte déjà 3782 Mo (sans aucun élément filtré)
  • activer --slim --extra-attributes coûte 4636 Mo (sans aucun élément filtré)
  • avec en plus les éléments filtrés selon cartes-v1.style, la base fait 4973 Mo
    • soit +337 Mo pour les éléments filtrés avec leur géométrie, c'est logique
  • au maximum la base fait 8151 Mo (avec --hstore-all pour stocker tous les objets avec tous leurs tags, et toutes leurs géométries)
    • si on ne demande pas les extra attributes, elle fait 6300 MB
    • si on supprime manuellement les tags (remplacés par null), ça ne marche pas

téléchargement d'un extrait d'OSM

OSM-FR osm-fr ne fournit plus l'extrait europe mais seulement pays par pays.

Geofabrik Attention, les public downloads de geofabrik (disponibles sans connexion) n'ont pas les metadata curl -O https://ftp5.gwdg.de/pub/misc/openstreetmap/download.geofabrik.de/europe-latest.osm.pbf (30GB, 8min20)

Besoin de se connecter via l'oauth osm pour accéder à : https://osm-internal.download.geofabrik.de/europe.html Et je ne sais pas le faire en ligne de commande sur le serveur 🤔​

import dans la base (pour vérif perfs)

osm2pgsql -U ubuntu -d osm -c bretagne-latest.osm.pbf

  • l'import prend 2m33s (pour le 1er serveur de test sans SSD)
    • au lieu de 6min si on oublie d'ajuster la configuration
    • et au lieu de 2min chez moi
  • la base fait 1875MB
    • au lieu de 2366MB chez moi. Peut -être des améliorations entre osm2pgsql v1.6 (chez moi) et 1.11 (sur le serveur) ?

transfert du fichier de style personnalisé

scp cartes-v1.style ubuntu@xx.xx.xx.xx:~/cartes-v1.style

import de la France

osm2pgsql -U ubuntu -d osm -c -s -S cartes-v1.style --extra-attributes --hstore-all --hstore-match-only france-latest.osm.pbf explication :

  • création initiale : -c
  • en mode slim (nécessaire pour ensuite gérer les update) : -s
  • en utilisant un style personnalisé pour la sélection des tags pertinents : -S cartes-v1.style
  • on garde les metadata : --extra-attributes (si on les a dans l'extrait évidemment)
  • on garde l'intégralité des tags dans la colonne tags au format hstore (sinon ça enlève les tags déjà dans une colonne) : --hstore-all
  • mais en revanche, pour alléger la base, on supprime les éléments qui n'ont aucun des tags listés dans le style --hstore-match-only

remarque : il est possible de lister plusieurs fichiers à la suite sur la ligne de commande pour qu'ils soient traités ensemble : osm2pgsql -U ubuntu -d osm -c -s -S cartes-v1.style --extra-attributes --hstore-all --hstore-match-only france.osm.pbf suisse.osm.pbf belgique.osm.pbf mais alors on ne pourra faire les update automatique avec osm2pgsql-replication ...

import de l'Europe

à partir du fichier public de geofabrik (donc sans metadata) : osm2pgsql -U ubuntu -d osm -c -s -S cartes-v1.style --hstore-all --hstore-match-only pbf/geofabrik/europe-latest.osm.pbf

Attention : à partir de l'Europe, il est très fortement recommandé d'utiliser le mode --flat-nodes FILE pour stocker les nodes dans un fichier et pas dans la base. Le fichier va prendre un peu plus de 100 GB quelle que soit la taille de l'extrait utilisé. Dans ce cas, il est conseillé de désactive le cache avec --cache 0

2 avril : nouveau test d'import France

avec les géométries de tous les objets

  • avec un fichier style "vide" (sans aucun tag sélectionné pour mise en colonne), mais l'option --hstore-all pour enregistrer les tags en entier, et donc calculer les géométries de tous les objets.
  • il faudra utiliser l'option --proj=4632 pour que les géométries soient compatibles avec Underpass-API
  • il faudra utiliser l'option --flat-nodes FILE --middle-with-nodes pour :
    • stocker TOUS les nodes dans un fichier plutôt que dans la base
    • mais quand même stocker dans la base les nodes qui ont des tags pour que l'api maison puisse les trouver (il y a 25 M de nodes avec tag sur les 507 M de nodes en France)

osm2pgsql -U ubuntu -d osmFrance -c -s --flat-nodes DB-flat-nodes --middle-with-nodes --proj=4632 -S vide.style --hstore-all france.osm.pbf

  • sans les métadata : le remplissage prend 1h14. La base fait 58 GB + le fichier flat-nodes de 95GB (taille fixe quel que soit l'extrait)
2025-04-02 23:15:39  Reading input files done in 2761s (46m 1s).                          
2025-04-02 23:15:39    Processed 507325455 nodes in 457s (7m 37s) - 1110k/s
2025-04-02 23:15:39    Processed 71276568 ways in 1567s (26m 7s) - 45k/s
2025-04-02 23:15:39    Processed 1061360 relations in 737s (12m 17s) - 1k/s
2025-04-02 23:43:35  Done postprocessing on table 'planet_osm_ways' in 1623s (27m 3s)
2025-04-02 23:43:35  Done postprocessing on table 'planet_osm_rels' in 120s (2m 0s)
2025-04-02 23:43:35  All postprocessing on table 'planet_osm_point' done in 217s (3m 37s).
2025-04-02 23:43:35  All postprocessing on table 'planet_osm_line' done in 731s (12m 11s).
2025-04-02 23:43:35  All postprocessing on table 'planet_osm_polygon' done in 101s (1m 41s).
  • avec les métadata : le remplissage prend 1h21. La base fait 73 GB + le fichier flat-nodes de 95GB (taille fixe quel que soit l'extrait)
Processing: Node(507325k 489.2k/s) Way(71276k 41.93k/s) Relation(1059500 1473.6/s)
2025-04-03 07:20:38  Writing 81392 entries to table 'planet_osm_users'...
2025-04-03 07:20:39  Reading input files done in 3458s (57m 38s).                         
2025-04-03 07:20:39    Processed 507325455 nodes in 1037s (17m 17s) - 489k/s
2025-04-03 07:20:39    Processed 71276568 ways in 1700s (28m 20s) - 42k/s
2025-04-03 07:20:39    Processed 1061360 relations in 721s (12m 1s) - 1k/s
2025-04-03 07:44:22  Done postprocessing on table 'planet_osm_ways' in 1329s (22m 9s)
2025-04-03 07:44:22  Done postprocessing on table 'planet_osm_rels' in 117s (1m 57s)
2025-04-03 07:44:22  All postprocessing on table 'planet_osm_point' done in 298s (4m 58s).
2025-04-03 07:44:22  All postprocessing on table 'planet_osm_line' done in 899s (14m 59s).
2025-04-03 07:44:22  All postprocessing on table 'planet_osm_polygon' done in 152s (2m 32s).

Installation et démarrage d'Underpass-API avec docker

adaptation du code à Osm2pgsql

Une PR a été créée pour ajouter la gestion du schéma osm2pgsql. En attendant, j'utilise mon fork : git clone https://github.com/etienneJr/Underpass-API.git récupération de la branche : git switch osm2pgsql-backend

Modifs dans le code

Pour que ça marche avec docker, il faut modifier backends/postgres_osm2pgsql/docker-compose.yaml :

  • supprimer/commenter le service osm2pgsql
  • supprimer/commenter le service postgress
  • modifier la ligne avec l'url de la DB : DATABASE_URL: postgres://readonlyuser:iwanttoreadfree@51.159.100.169:5432/osm
  • supprimer/commenter depends_on: - postgres

installations diverses

  • installation de docker lui même : sudo apt install docker.io version 26.1.3-0ubuntu1~24.04.1 (302MB)
  • maj liste : sudo apt-get update
  • installation plugin compose : sudo apt-get install docker-compose-plugin ❌ échec E: Unable to locate package docker-compose-plugin
  • installation manuelle du plugin compose en suivant ça
  • ajout du user ubuntu dans le groupe docker (d'après ça) : sudo usermod -a -G docker ubuntu puis newgrp docker
  • build du container docker compose --profile '*' build

démarrage

  • en foreground (ctrl+c pour arrêter) : docker compose up
  • en background (reste actif) : docker-compose up -d (comment on l'arrête alors ?)
    • le yaml a l'option restart: unless-stopped donc a priori il redémarre tout seul ?!? enfin il faut peut-être changer en always. Cf cette page mais qui est pour docker sans compose. Il est écrit qu'il faut désactiver l'option restart: si on préfère utiliser systemd.

Utilisation

Bizarrement, on ne peut tester l'url dans overpass-turbo. Peut-être à cause du http:// sans s ?

✅​ chercher 1 élément donné à partir de son type+id fonctionne (encore heureux !)

[out:json][timeout:25];
node(4164995705);
out center meta;
time curl 'http://51.159.100.169:9292/interpreter' -X POST -H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' --data-raw 'data=%5Bout%3Ajson%5D%5Btimeout%3A25%5D%3B%0Anode%284164995705%29%3B%0Aout%20center%20meta%3B' > result.json

✅ filtrage par tag et par bbox

  • en local :
  • en prod sur France : ✅ 350ms exemple qui renvoie 419 aires de jeux à Rennes :
[out:json][timeout:25];
nwr["leisure"="playground"](48.05,-1.75,48.15,-1.6);
out center;
time curl 'http://51.159.100.169:9292/interpreter' -X POST -H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' --data-raw 'data=%5Bout%3Ajson%5D%5Btimeout%3A25%5D%3B%0Anwr%5B%22leisure%22%3D%22playground%22%5D%2848.05%2C-1.75%2C48.15%2C-1.6%29%3B%0Aout%20center%3B' > result.json

​ ✅ filtrage par tag et par area issue d'un way

  • en local
  • en prod : ✅ ≃600ms

fonctionne bien (donne les 2 aires de jeux du Parc des Gayeulles) mais fournit toute la géométrie des ways aires de jeux alors que je demandais juste les tags

[out:json][timeout:25];
area(23255048)->.a;
nwr["leisure"="playground"](area.a);
out tags;
time curl 'http://51.159.100.169:9292/interpreter' -X POST -H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' --data-raw 'data=%5Bout%3Ajson%5D%5Btimeout%3A25%5D%3B%0Aarea%2823255048%29-%3E.a%3B%0Anwr%5B%22leisure%22%3D%22playground%22%5D%28area.a%29%3B%0Aout%20tags%3B' > result.json

​ ✅ filtrage par tag et par area issue d'une relation

  • en local
  • en prod avec géométries brutes : ✅ ≃600ms

Attention il faut que la relation soit dans la BDD, et typiquement les villes n'y sont pas pour l'instant ... J'ai eu besoin de corriger les ID des areas provenant de relation pour ajouter le facteur 3600000000 cher à Overpass, mais maintenant c'est bon ça marche. Exemple avec les aires de jeu dans le parc du Thabor

[out:json][timeout:25];
area(id:3606848340)->.a;
nwr["leisure"="playground"](area.a);
out center tags;
time curl 'http://51.159.100.169:9292/interpreter' -X POST -H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' --data-raw 'data=%5Bout%3Ajson%5D%5Btimeout%3A25%5D%3B%0Aarea%28id%3A3606848340%29-%3E.a%3B%0Anwr%5B%22leisure%22%3D%22playground%22%5D%28area.a%29%3B%0Aout%20center%20tags%3B' > result.json

​ ⚠️​ filtrage avec is_in puis tag les leisure à une coordonnées données -> 2 éléments

[out:json][timeout:25];
is_in(48.114093,-1.667733);
area._["leisure"];
out tags;
time curl 'http://51.159.100.169:9292/interpreter' -X POST -H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' --data-raw 'data=%5Bout%3Ajson%5D%5Btimeout%3A25%5D%3B%0Ais_in%2848.114093%2C-1.667733%29%3B%0Aarea._%5B%22leisure%22%5D%3B%0Aout%20tags%3B' > result.json

à tester mais a priori devrait marcher

​ ⚠️​ filtrage avec around

à tester, mais a priori ne devrait pas marcher !


✏️ Participer à la discussion