Overpass
Overpass est une API permettant d'interroger des données OSM.
1 Mise en place d'un serveur Overpass (Debian)
Ce qui suit indique la méthodologie détaillée pour mettre en place une API Overpass sur un serveur Debian avec les données OSM mondiales et historiques ("ATTIC"), mises à jour une fois par heure.
Les données mondiales sont utilisées car les tests sur un export de données (France) n'ont pas été concluants. Une mise à jour à l'heure a été décidée plutôt qu'à la minute pour soulager le serveur.
1.1 Pré-requis
- Système d'exploitation Debian
- Un serveur avec un disque d'au moins 500 Go, de préférence un SSD, et au moins 8 Go de mémoire RAM.
- Un nom de domaine pointant vers le serveur.
1.2 Préparation
1.2.1 Création d'un utilisateur système
sudo adduser overpass --system --shell /bin/bash --group
sudo passwd overpass
> mot_de_passe
1.2.2 Création de répertoires
sudo mkdir -p "/opt/osm-3s/database/"
sudo mkdir "/opt/osm-3s/replicate/"
sudo mkdir "/opt/osm-3s/logs/"
sudo chown overpass:overpass -R /opt/osm-3s
1.3 Installation d'Overpass
1.3.1 Téléchargement
sudo wget https://dev.overpass-api.de/releases/osm-3s_v0.7.56.9.tar.gz -P /usr/local/src/
sudo tar -xvf /usr/local/src/osm-3s_v0.7.56.9.tar.gz -C /usr/local/src/
sudo chown overpass:overpass -R /usr/local/src/osm-3s_v0.7.56.9
1.3.2 Compilation et installation
cd /usr/local/src/osm-3s_v0.7.56.9
sudo -u overpass ./configure CXXFLAGS="-O2" --prefix=/opt/osm-3s/osm-3s_v0.7.56.9
sudo apt-get install -y g++ make expat libexpat1-dev zlib1g-dev
sudo -u overpass make
sudo -u overpass make install
1.4 Installation d'Apache
1.4.1 Installation
sudo apt-get install -y apache2 libapache2-mod-auth-openidc python-certbot-apache
sudo a2enmod cgid
sudo a2enmod ext_filter
sudo a2enmod headers
sudo a2enmod setenvif
sudo a2enmod rewrite
1.4.2 Configuration
Fichier de configuration "/etc/apache2/sites-available/000-default.conf" :
<VirtualHost *:80>
ServerName nom_de_domaine
ServerAdmin email_de_contact
DocumentRoot /var/www/html
DirectoryIndex index.html interpreter
ExtFilterDefine gzip mode=output cmd=/bin/gzip
ScriptAlias /api /opt/osm-3s/osm-3s_v0.7.56.9/cgi-bin/
LogLevel error
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
<Directory "/opt/osm-3s/osm-3s_v0.7.56.9/cgi-bin/">
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Require all granted
</Directory>
</VirtualHost>
NOTE : Le domaine "nom_de_domaine" lié à l'adresse IP du serveur doit être configuré dans les DNS du domaine. |
1.4.3 Service
Activation et redémarrage du service :
sudo systemctl enable apache2
sudo systemctl restart apache2
1.4.4 Pare-feu (Nftables)
Ajouter les règles suivantes :
inet filter input tcp dport {80,443} ct state new,established accept
inet filter output tcp sport {80,443} ct state established accept
1.4.5 Certificat Let's Encrypt
sudo certbot -d nom_de_domaine --apache -n --agree-tos --email email_de_contact
sudo certbot enhance -d nom_de_domaine -n --redirect --apache --cert-name nom_de_domaine
NOTE : Le renouvellement automatique est mis en place dans "/etc/cron.d/certbot". |
1.5 Données OSM
Avant de pouvoir utiliser l'API, il faut charger les données OSM. La méthode la plus rapide (plusieurs heures tout de même) et la plus complète est de cloner les données à l'instant T.
1.5.1 Clonage des données
su - overpass -c 'nohup /opt/osm-3s/osm-3s_v0.7.56.9/bin/download_clone.sh --db-dir=/opt/osm-3s/database --source=http://dev.overpass-api.de/api_drolbr/ --meta=attic > /opt/osm-3s/logs/download_clone.file &'
Lorsque le clonage est terminé, le répertoire "/opt/osm-3s/database" pèse environ 326 Go.
NOTE : "nohup" permet d'exécuter la commande en tâche de fond (la session peut être fermée). Le fichier "/opt/osm-3s/logs/download_clone.file" contiendra les messages renvoyés par la commande. |
1.5.2 Test
Une fois le clonage terminé, vérifier qu'Overpass trouve bien les données en exécutant "osm3s_query" et en entrant une requête (restaurants de Corse) :
/opt/osm-3s/osm-3s_v0.7.56.9/bin/osm3s_query --db-dir=/opt/osm-3s/database
<query type="node"><bbox-query n="41.969574" s="41.886688" w="8.630362" e="8.848629"/><has-kv k="amenity" v="restaurant"/></query><print/>
> CTRL+D
1.6 Dispatcher
"Dispatcher" est l'application qui permettra aux clients distants d'interroger les données OSM. Elle doit fonctionner en permanence, comme un service :
su - overpass -c 'nohup /opt/osm-3s/osm-3s_v0.7.56.9/bin/dispatcher --osm-base --db-dir=/opt/osm-3s/database --attic --rate-limit=2 > /opt/osm-3s/logs/dispatcher.file &'
Une deuxième instance doit être lancée pour gérer les "areas" (cf. plus loin) :
sudo cp -R /usr/local/src/osm-3s_v0.7.56.9/rules /opt/osm-3s/database/
sudo chown overpass:overpass -R /opt/osm-3s/database/rules
su - overpass -c 'nohup /opt/osm-3s/osm-3s_v0.7.56.9/bin/dispatcher --areas --db-dir=/opt/osm-3s/database > /opt/osm-3s/logs/dispatcher_areas.file &'
Les paramètres de "dispatcher" sont les suivants :
- --osm-base : dispatcher dédié aux "données".
- --areas : dispatcher dédié aux "areas".
- --meta : gère les métadonnées.
- --attic : gère les métadonnées et les données historiques.
- --db-dir=$DB_DIR : emplacement de la base de données.
- --terminate : arrête le programme.
- --status : affiche le statut du programme.
- --my-status : affiche les informations du client.
- --show-dir : affiche l'emplacement de la base de données.
- --purge=pid : oublie le "pid".
- --query_token : affiche le "pid" de la requête du client de même IP.
- --space=number : définit la limite de mémoire pour le total de tous les processus, en octets.
- --time=number : définit la limite d'unité de temps pour le total de tous les processus, en octets.
- --rate-limit=number : définit le nombre maximal autorisé d'accès simultanés depuis une IP unique.
1.7 Mise à jour
Pour le moment, les données OSM accessibles par l'API sont celles issues du clonage à un instant T.
Pour mettre à jour les données, deux autres scripts doivent fonctionner en permanence (le premier pour récupérer les données, le deuxième pour les intégrer dans la base).
Les mises à jour mondiales peuvent être récupérées chaque minute, chaque heure ou chaque jour :
- Les MAJ à la minute (en moyenne de 10 Ko à 2 Mo) génèrent beaucoup de fichiers et ne laissent jamais le serveur au repos.
- Les MAJ à l'heure (en moyenne de 1 Mo à 15 Mo) s’intègrent en base en 15 à 40 minutes et laissent donc du répit au serveur.
- Les MAJ à la journée (en moyenne de 40 Mo à 140 Mo) sont plus lourdes mais ne nécessitent qu'une seule intégration par jour.
Dans la suite, nous configurerons une MAJ à l'heure pour avoir un équilibre entre fraicheur des données et charge du serveur.
1.7.1 Replicate ID
Le "replicate ID" est l'identifiant de la version des données, qui sera mis à jour en même temps que les données. Attention, sa valeur diffère selon la source des mises à jour (minute, heure ou journée). Dans les données clonées, il s'agit du "replicate ID" à la minute.
Il faut donc d'abord connaitre le "replicate ID" des données clonées :
tail /opt/osm-3s/database/replicate_id
> 4495994
Dans cet exemple, l'identifiant est "4495994". Celui-ci correspond à la structure des dossiers sur "planet.openstreetmap.org" pour les mises à jour à la minute. A quelle date correspond-il ?
- Rajouter des 0 en début de chaîne pour obtenir une chaîne de 9 caractères : "004495994".
- Ajouter un / tous les 3 caractères : "004/495/994".
- Rajouter le suffixe ".state.txt" : "004/495/994.state.txt".
- Rajouter le préfixe "https://planet.openstreetmap.org/replication/minute/" : "https://planet.openstreetmap.org/replication/minute/004/495/994.state.txt".
- Ouvrir l'URL obtenue pour afficher le contenu du fichier :
#Mon Apr 12 14:11:14 UTC 2021
sequenceNumber=4495994
timestamp=2021-04-12T14\:11\:12Z
Les données datent donc du 12/04/2021 à 14H11 (temps universel, +2H en France, heure d'été).
Pour les mettre à jour à partir des données par heure, il faut trouver le "replicate ID" équivalent des MAJ par heure le plus proche et antérieur au 12/04/2021 à 14H11, certainement vers 14H00 (c'est à dire à l'heure antérieure la plus proche). Pour cela, il faut se rendre sur "https://planet.openstreetmap.org/replication/hour/000/" et rechercher le bon fichier à l'aide de l'horodatage :
Le bon candidat semble être "223.state.txt" :
#Mon Apr 12 14:02:14 UTC 2021
sequenceNumber=75223
timestamp=2021-04-12T14\:00\:00Z
En effet, le "replicate ID" par heure "75223" est daté du 12/04/2021 à 14H00, quelques minutes avant la date des données clonées. Donc si l'on applique les mises à jour à partir du "replicate ID" suivant ("75224"), notre base sera bien à jour heure par heure.
Il reste à écraser la valeur de l'ID par minute de la base de données par l'ID par heure que l'on a trouvé :
echo '75223' > /opt/osm-3s/database/replicate_id
1.7.2 Script de téléchargement
Le script "fetch_osc" va télécharger tous les fichiers de mise à jour au fil de l'eau dans le répertoire "/opt/osm-3s/replicate".
Par défaut, ce script vérifie toutes les 15 secondes la présence d'un nouveau fichier à télécharger. C'est beaucoup pour un fichier par heure, on augmente donc le délai à 5 minutes :
sed -i 's|sleep 15|sleep 300|g' /opt/osm-3s/osm-3s_v0.7.56.9/bin/fetch_osc.sh
On exécute ensuite le script en tâche de fond, en indiquant le "replicate id" de la base + 1, donc "75224" dans notre exemple :
su - overpass -c 'nohup /opt/osm-3s/osm-3s_v0.7.56.9/bin/fetch_osc.sh 75224 https://planet.openstreetmap.org/replication/hour/ /opt/osm-3s/replicate > /opt/osm-3s/logs/fetch_osc.file &'
1.7.3 Script de mise à jour
Le script "apply_osc_to_db" va appliquer les fichiers de mise à jour à la base de données.
Par défaut, ce script vérifie toutes les 5 secondes la présence d'un nouveau fichier à charger. C'est beaucoup pour un fichier par heure, on augmente donc le délai à 5 minutes :
sed -i 's|sleep 5|sleep 300|g' /opt/osm-3s/osm-3s_v0.7.56.9/bin/apply_osc_to_db.sh
On exécute ensuite le script en tâche de fond, en indiquant le "replicate id" de la base, donc "75223" dans notre exemple :
su - overpass -c 'nohup /opt/osm-3s/osm-3s_v0.7.56.9/bin/apply_osc_to_db.sh /opt/osm-3s/replicate 75223 --meta=attic > /opt/osm-3s/logs/apply_osc_to_db.file &'
1.8 Création des "areas"
Les "areas" permettent d'indiquer le nom d'une zone pour interroger les données via l'API, comme le nom d'une commune, au lieu de spécifier une emprise XY.
Un script permet de générer ces "areas". Pour les données mondiales, il dure environ 24H et est gourmand en ressources. Pour cette raison, nous recommandons de ne pas le laisser s'exécuter chaque jour, mais de l'exécuter par exemple une fois par mois :
sed -i 's|DB_DIR="`pwd`/$1"|DB_DIR="$1"|g' /opt/osm-3s/osm-3s_v0.7.56.9/bin/rules_loop.sh
sed -i 's|sleep 3|now=$(date +%s) \&\& next=$(date -d "1 month 01:00" +%s) \&\& diff=$(( $next - $now )) \&\& sleep $diff|g' /opt/osm-3s/osm-3s_v0.7.56.9/bin/rules_loop.sh
su - overpass -c 'nohup /opt/osm-3s/osm-3s_v0.7.56.9/bin/rules_loop.sh /opt/osm-3s/database > /opt/osm-3s/logs/rules_loop.file &'
La commande précédente corrige le script (variable "DB_DIR") et force une attente d'un mois entre chaque exécution (pause entre la date d'exécution et un mois plus tard à 1H du matin).
Une fois le script lancé, deux processus sont en mémoire : "rules_loop" et "osm3s_query".
Pour diminuer la priorité de ces processus, lancer la commande "top" ("c" affiche les détails des commandes, "q" quitte le programme) :
top -u overpass
> c
> q
Noter les "pid" de "osm3s_query" et de "rules_loop" et pour chacun des deux, lancer :
renice -n 19 -p XXX && ionice -c 2 -n 7 -p XXX
où XXX correspond au "pid" de "osm3s_query" puis de "rules_loop".
Par exemple :
renice -n 19 -p 30332 && ionice -c 2 -n 7 -p 30332
renice -n 19 -p 30329 && ionice -c 2 -n 7 -p 30329
1.9 Rotation des logs
La rotation des logs permet d'historiser les journaux et de ne pas les laisser trop grossir (100 Mo maximum dans l'exemple suivant).
1.9.1 Installation et configuration
sudo apt-get install -y logrotate
echo '/opt/osm-3s/logs/apply_osc_to_db.file {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 644 overpass overpass
size 100M
dateext
dateformat -%Y%m%d
}
/opt/osm-3s/logs/dispatcher_areas.file {
daily
rotate 30
nocompress
nodelaycompress
missingok
notifempty
create 644 overpass overpass
size 100M
dateext
dateformat -%Y%m%d
}
/opt/osm-3s/logs/dispatcher.file {
daily
rotate 30
nocompress
nodelaycompress
missingok
notifempty
create 644 overpass overpass
size 100M
dateext
dateformat -%Y%m%d
}
/opt/osm-3s/logs/fetch_osc.file {
daily
rotate 30
nocompress
nodelaycompress
missingok
notifempty
create 644 overpass overpass
size 100M
dateext
dateformat -%Y%m%d
}
/opt/osm-3s/logs/rules_loop.file {
daily
rotate 30
nocompress
nodelaycompress
missingok
notifempty
create 644 overpass overpass
size 100M
dateext
dateformat -%Y%m%d
}
/opt/osm-3s/database/apply_osc_to_db.log {
daily
rotate 30
nocompress
nodelaycompress
missingok
notifempty
create 644 overpass overpass
size 100M
dateext
dateformat -%Y%m%d
}
/opt/osm-3s/database/rules_loop.log {
daily
rotate 30
nocompress
nodelaycompress
missingok
notifempty
create 644 overpass overpass
size 100M
dateext
dateformat -%Y%m%d
}
/opt/osm-3s/database/transactions.log {
daily
rotate 30
nocompress
nodelaycompress
missingok
notifempty
create 644 overpass overpass
size 100M
dateext
dateformat -%Y%m%d
}
/opt/osm-3s/replicate/fetch_osc.log {
monthly
rotate 12
nocompress
nodelaycompress
missingok
notifempty
create 644 overpass overpass
size 100M
dateext
dateformat -%Y%m%d
}' > /etc/logrotate.d/osm
1.9.2 Test
logrotate -d /etc/logrotate.d/osm
1.9.3 Exécution réelle
logrotate /etc/logrotate.d/osm
1.10 Vérifications
A ce stade, l'API Overpass est opérationnelle, la base de données est mise à jour chaque heure et les "areas" sont regénérées une fois par mois.
La commande "top" permet de vérifier la présence des programmes en mémoire, "c" affiche le détail des commandes, "q" quitte le programme :
top -u overpass
> c
> q
- osm3s_query : création des "areas" en cours, programme lancé par "rules_loop".
- update_from_dir : mise à jour des données en cours, programme lancé par "apply_osc_to_db".
- dispatcher --osm-base : "dispatcher" pour les requêtes.
- dispatcher --areas : "dispatcher" pour les "areas".
- fetch_osc : téléchargement des mises à jour.
- apply_osc_to_db : intégration des mises à jour.
- rules_loop : création des "areas".