FR:User:Petrovsk/Up to date OSM file

From OpenStreetMap Wiki
Jump to navigation Jump to search

Pour maintenir mes cartes Garmin à jour, je téléchargeais régulièrement l'extrait français de Geofabrik. Un des inconvénients des extraits est qu'ils provoquent des pertes de données à leurs limites. Comme je suis près de la frontière espagnole, certaines de mes sorties se trouvaient dans des zones blanches de la carte.
Pour moi l'idéal serait de faire des cartes seulement pour ma zone de prédilection, et que les données source soient mises à jour automatiquement. Cela peut être fait avec osmosis et j'obtiendrai au final un fichier .osm.pbf (fichier OSM compressé) qui sera mis à jour quotidiennement.

Obtention des données

Ma zone s'étendant sur deux pays, je la découperai dans l'extrait européen de Geofabrik. Commençons par le télécharger :

cd ~/OSM/Datasets
curl -OL "http://download.geofabrik.de/openstreetmap/europe.osm.pbf"

Pendant ce temps, je crée un dossier de travail dans lequel mon fichier OSM sera maintenu à jour :

mkdir ~/OSM/base_locale

Après avoir défini la bounding box de la zone qui m'intéresse, je la découpe avec osmosis, et je la nomme LRmax.osm.pbf.

osmosis --rb europe.osm.pbf \
--bb left=1.16 right=3.75 top=44.37 bottom=42.29 \
--wb omitmetadata=true LRmax.osm.pbf

Je déplace le fichier final dans le dossier de travail :

mv LRmax.osm.pbf "../base_locale/LRmax/"

Configuration initiale

Cela consiste à mettre en place le système RRI (Read Replication Interval) d'osmosis, gérant le suivi des fichiers différentiels.

osmosis --read-replication-interval-init

Cela crée le fichier configuration.txt que nous allons modifier.
Cette configuration est initialement prévue pour des mises à jour horaires; c'est utile pour qu'un serveur de cartes local suive l'évolution de la base de donnée OSM. Comme je peux me contenter de mises à jour quotidiennes, nous allons faire les changements suivants :

Les fichiers différentiels quotidiens, à télécharger sur le site planet.openstreetmap.org, sont dans le dossier replication/day au lieu de minute-replicate :

baseUrl=https://planet.openstreetmap.org/replication/day

Et modifier :

maxInterval = 0

Ces modifications peuvent s'automatiser par les commandes suivantes :

sed 's/minute-replicate/replication\/day/' configuration.txt > temp.txt
sed 's/maxInterval = 3600/maxInterval = 0/' temp.txt > configuration.txt
rm temp.txt

Nous récupérons sur le serveur de réplication le fichier correspondant à l'état actuel de la base :

curl -OL "https://planet.openstreetmap.org/replication/day/state.txt"

La base est initialisée et prête à être mise à jour dans les jours qui suivent.
L'ensemble de ces commandes peut-être regroupé dans un script nommé "initbase.sh" par exemple :

#!/bin/sh
cd ~/OSM/Datasets
curl -OL "http://download.geofabrik.de/openstreetmap/europe.osm.pbf"
osmosis --rb europe.osm.pbf \
--bb left=1.16 right=3.75 top=44.37 bottom=42.29 \
--wb omitmetadata=true LRmax.osm.pbf
mv LRmax.osm.pbf "../base_locale/LRmax/"
cd ~/OSM/base_locale
osmosis --read-replication-interval-init
sed 's/minute-replicate/replication\/day/' configuration.txt > temp.txt
sed 's/maxInterval = 3600/maxInterval = 0/' temp.txt > configuration.txt
rm temp.txt
curl -OL "https://planet.openstreetmap.org/replication/day/state.txt"

Je le rends exécutable :

chmod +x ~/OSM/base_locale/initbase.sh

Mise à jour

La commande de mise à jour elle-même est la suivante (avec les options abrégées) :

osmosis --rri --simc --rb LRmax.osm.pbf \
--ac --bb left=1.16 right=3.75 top=44.37 bottom=42.29 \
--wb omitmetadata=true tmp.osm.pbf

Osmosis va télécharger les fichiers différentiels quotidiens correspondant à l'intervalle depuis la configuration initiale (ou la dernière mise à jour), et créer un fichier à jour nommé tmp.osm.pbf que l'on renommera LRmax.osm.pbf comme l'original :

mv tmp.osm.pbf LRmax.osm.pbf

Pour simplifier, je place ces lignes dans un script que je nomme majbase.sh par exemple :

#!/bin/sh
cd ~/OSM/base_locale
osmosis --rri --simc --rb LRmax.osm.pbf \
--ac --bb left=1.16 right=3.75 top=44.37 bottom=42.29 \
--wb omitmetadata=true tmp.osm.pbf
mv tmp.osm.pbf LRmax.osm.pbf

Je le rends exécutable :

chmod +x ~/OSM/base_locale/majbase.sh

C'est l'occasion de caser dans le script des commandes supplémentaires, pour créer des cartes Garmin par exemple.

Automatiser la mise à jour quotidienne

Pour déclencher quotidiennement la mise à jour, nous allons utiliser cron, une spécificité du monde UNIX présente du coup dans Mac OS. Les actions cron sont stockées dans le crontab. Il y en a un par compte utilisateur sur la machine et s'affiche à l'aide de la commande suivante :

crontab -l

Le Terminal est censé afficher ceci :

# min hour mday month wday command

Comme dans les scripts, le # introduit une ligne de commentaire. Chaque ligne cron indique la date et la commande à réaliser. La syntaxe sera comme suit : minutes (0 à 59), heures (0 à 23), jour du mois (1 à 31), mois (1 à 12 ou jan à dec), jour de la semaine (mon à sun), la commande à réaliser et éventuellement le type de sortie (mail si rien indiqué, enregistrement d'un fichier log ou rien en indiquant &> /dev/null).
J'ai choisi de déclencher mon script tous les jours à 13h20, en enregistrant un fichier log (pour savoir où il y a eu des erreurs en cas de problème). Dans cron cela devient :

20 13 * * * ~/OSM/base_locale/majbase.sh &> ~/OSM/base_locale/last.log

Éditer directement le crontab demande d'utiliser l'éditeur de texte vim dans le Terminal. Ce sera plus simple d'enregistrer la ligne cron dans un fichier, cela me permettra aussi de désactiver le crontab lorsque je passe plusieurs jours hors-ligne. Au lieu de désactivation il vaut mieux parler de supression au sujet de la commande :

crontab -r

Après son passage, si l'on demande à voir l'état de cron on obtient ceci :

crontab: no crontab for Petrovsk

Nous enregistrons les lignes suivantes dans le fichier cronfile (ou tout autre nom) dans le dossier base_locale :

# min hour mday month wday command
20 13 * * * ~/OSM/base_locale/majbase.sh &> ~/OSM/base_locale/last.log

Nous pourrons ainsi l'activer simplement :

crontab cronfile