S'abonner au Flux RSS

Mot-clé - openstreetmap

Fil des billets - Fil des commentaires

mercredi, mai 7 2014

Monitorer OSRM

Avoir une application en production implique d'en assurer un monitoring de suivi afin de savoir si tout est au vert, cela permet de s'y mettre quand on a un système de qualité. Mais passons ces considérations philosogeek et revenons au sujet du jour à savoir le monitoring d'une instance OSRM, pour ma part j'utilise Nagios depuis de longues années et en suis toujours assez satisfait. J'ai pris un peu de temps ces derniers jours pour publier ma configuration sur le dépôt nagios-plugins-osrm.

Les appels API de base utilisent la fonction standard check_http cela permet de savoir si le service est up, mais sans analyse de la réponse.

En utilisant check_osrm_viaroute_result qui nécessite un check non standard (voir le README du dépôt) vous avez non seulement un retour sur le bon fonctionnement du service mais également sur les données retournée. Dans ce cas vous savez si OSRM trouve une route entre les deux points de coordonnées.

Dans la suite de cette publiucation je vais également prochainement publier mes sondes pour Nominatim.

jeudi, mars 6 2014

rosarks.eu

Je profite d'avoir la chance de pouvoir ré-écrire Lolix from scratch pour penser aux fonctionnalités qu'il m'aurait plu d'avoir quand je cherchais un travail, sur ce point j'ai toujours été surpris de voir à quel point les entreprises font bien peu d'effort pour aider les candidats à trouver leur locaux. Peut-être que les recruteurs imaginent que tout le monde sait où se trouve leur bureau, ou parce qu'ils imaginent cela comme une première épreuve pour mesurer le niveau de débrouilliardise du candidat, en tout état de cause personnellement je trouve qu'indiquer la sation de bus/tram/métro/vélocation à proximité ne peut être qu'un plus sur une offre d'emploi.

Lire la suite...

lundi, février 10 2014

OSM Pulsation

Je maintiens à jour une base de données pour Nominatim en utilisant les delta toutes les minutes, je me suis dit qu'il serait amusant de voir l'évolution des données au cours de la journée.

Lire la suite...

samedi, novembre 30 2013

Utiliser GraphHopper avec Jetty8 sous Debian

Actuellement la seule solution documentée pour utiliser GraphHopper est l'utilisation de jetty runner, celle-ci n'est pas satisfaisante dans un mode de production, elle requiert de mettre en place des scripts de lancement. Il est plus simple d'administrer un service de routing en utilisant par exemple jetty ou Tomcat, ce billet va se concentrer sur la configuration de jetty sous Debian Jessie.

Tout d'abord installer le serveur jetty

apt-get install jetty8

Puis on récupère l'archive .war que l'on copie dans le répertoire de webapp de jetty

cd /var/lib/jetty8/webapps
wget http://oss.sonatype.org/content/groups/public/com/graphhopper/graphhopper-web/0.2/graphhopper-web-0.2.war

Toujours dans le répertoire webapps on va renommer le fichier war de GraphHopper afin que le déploiement se fasse dans le contexte racine, de même que l'on va supprimer le répertoire existant nommé root. La raison de cette opération peu orthodoxe est que par défaut GraphHopper répond aux requêtes d'api sur l'url /api/ et qu'il n'est pas actuellement possible de paramétrer cela simplement. La seule méthode de contournement est d'indiquer un paramètre host dans l'url ce qui n'est pas des plus ergonomique.

mv graphhopper-web-0.2.war ROOT.war
rm -fr root/ 

On va déployer les fichiers de configuration et de données dans /home/routing, il faut créer ce répertoire, dans lequel on en crée de suite un autre nommé data qui contiendra les données précompilées par GraphHopper

mkdir /home/routing
mkdir /home/routing/data/

On crée un fichier de configuration dans le dossier en utilisant l'exemple fournit sur le site du projet, fichier que l'on renomme dans la foulée.

wget https://raw.github.com/graphhopper/graphhopper/master/config-example.properties
mv config-example.properties config.properties

Maintenant on va récupérer le fichier qui servira de source de données, on télécharge directement un fichier protobuff depuis le site de Geofabrik, par exemple le fichier de données de la région Nord-Pas de Calais :

wget http://download.geofabrik.de/europe/france/nord-pas-de-calais-latest.osm.pbf

On édite le fichier de configuration pour qu'il corresponde à notre utilisation en ajoutant deux paramètres à la fin de celui-ci. Le premier qui correspond au fichier protobuff utilisé et le second qui indique où GraphHopper doit créer ses fichiers de données.

# data source
osmreader.osm=/home/routing/nord-pas-de-calais-latest.osm.pbf
# repertoire de données
graph.location=/home/routing/data/

Au lancement de jetty GraphHopper va pré-traiter les données du fichier .pbf afin de préparer ses tables de recherches qu'il stockera dans le répertoire /home/routing/data/ Si vous voulez mettre les données à jour il suffit télécharger un nouveau fichier de données et de relancer jetty, le fichier de données étant plus récent GrapHopper relancera une analyse.

Le serveur jetty tournant sous Debian avec l'utilisateur jetty il faut définir les bons attibuts de propriété aux répertoires ainsi qu'à tous les fichiers présents dans celui-ci.

chown -R jetty.jetty /home/routing

Dernière modification, éditer le fichier /etc/default/jetty8 pour paramétrer le démarrage automatique et indiquer le fichier de configuration de GraphHopper

# change to 0 to allow Jetty to start
NO_START=0

# Additional arguments to pass to Jetty    
JETTY_ARGS=-Dgraphhopper.config=/home/routing/config.properties

Par défaut comme souvent sur Debian le démon va écouter seulement sur le localhost, à vous de régler le paramètre JETTY_HOST suivant vos besoins.

Il ne reste plus qu'à lancer jetty avec le script d'init avec l'utilisateur privilégié root

invoke-rc.d jetty8 restart

A ce stade GraphHopper est prêt à répondre sur le port 8989 de votre machine et à vous indiquer la route !

mardi, novembre 26 2013

Test de GraphHopper

GraphHopper est outil de routage comme OSRM qui a été traité dans un précédent billet.

La sortie hier la version 0.2 est l'occasion de tester ce nouvel outil, dont le développement a été commencé il y a un peu plus d'un an, et de le comparer à OSRM.

L'environnement de test est comme à mon habitude une distribution Debian, afin de minimiser le travail de déploiement on va se reposer au maximum sur les paquets. Graphhopper requiert une version 7 ou 8 de JRE, ce qui va nous obliger à utiliser la version testing aka Jessie, il faut tout d'abord installer le paquet default-jre.

apt-get install default-jre

La suite de la procédure décrite dans le Quickstart est claire et permet le lancement de GraphHopper après quelques récupérations de fichier en ligne dont jetty runner et le war de GraphHopper. La méthode de déploiement avec jetty runner est peu propice à une mise en production bien que fonctionnelle, j'ai bien essayé de déployer le .war avec Jetty ou Tomcat7 mais en vain, n'étant pas un expert java cela semble normal ; il sera sage d'attendre un peu de packaging autour de l'outil avant d'en envisager une exploitation sereine.

Le résultat obtenu diffère de OSRM qui ne fournit qu'une API quand GraphHopper propose une solution tout en un, on obtient directement une interface web interrogeable sur le port configuré (ici 8989), il est également possible d'interroger directement l'API sur l'url /api/route, pour un aperçu le résultat est identique à la démo en ligne. Basé sur Leaflet la fond de carte est agréablement complété d'un cadre matérialisant la bounding-box des données traitées.

Autre différence notoire est le temps de préparation des données, bien que l'on travaille directement avec des fichiers .pbf dans les deux cas sans passer par une base de données, GraphHopper comme osrm nécessite de construire les arbres de données. GraphHopper fait ceci directement lors du lancement quand osrm nécessite de passer par les étapes osrm-extract et osrm-prepare.

La différence majeure va venir du temps de précompilation, sur une machine avec 6 core, 12Gb de RAM et des disques SSD j'ai obtenu les résultats suivants. J'ai utilisé une première fois le fichier de la ville de Berlin et en second celui de la France, tous deux obtenus sur Geofabrik.

BerlinFrance
GraphHopper17 sec 32min
osrm37sec71min

Le résultat est assez net, le temps de précompilation des données est deux fois inférieur avec GraphHopper ce qui lui donne un avantage considérable pour qui voudrait mettre à jour ses données régulièrement sur une emprise de taille conséquente.

La prochaine étape sera de mesurer les temps de réponses des deux API, ce que je vais m'employer à faire rapidement avec Tsung, je publierai les résultats ici.

jeudi, avril 4 2013

Test de charge sur un serveur de tuile

J'ai eu par le passé à effectuer des tests de charge sur des serveurs de tuiles comme ceux mis en oeuvre sur le projet OpenStreetMap. Afin d'assurer des requêtes aléatoires sur tous les niveaux de zoom j'avais écrit à l'époque un plugin pour Tsung que je n'avais pas encore pris le temps de publier, voilà qui est chose faite.

Le plugin se nomme wmsosm.erl et est publié sur github en licence GPLv3. Il permet de générer la partie finale de l'url en z/x/y afin de pouvoir l'intégrer dans la balise request du scénario Tsung. L'utilisation se fait en appelant la fonction urlzxy du module wmsosm, voir l'exemple ci-dessous. Le détail de la mise en oeuvre d'un plugin Tsung est décrit dans la [documentation du projet| http://tsung.erlang-projects.org/user_manual.html] je ne m'étendrais pas sur le sujet.

<request subst="true">
  <http url='/%%wmsosm:urlzxy%%.png' version='1.1' method='GET'></http>
</request>

Le choix de la tuile dans un niveau de zoom donné est aléatoire. le choix du niveau de zoom est aléatoire mais avec pondération, le choix est fait de telle sorte que les niveaus de zooms élevés sortent plus souvent, techniquement le tirage est fait dans une liste qui contient 2 fois le zoom 2, 3 fois le zoom 3 et ainsi de suite.

Ci-dessous un exemple d'un extrait d'utilisation du plugin

"GET /7/88/93.png HTTP/1.1"
"GET /16/17017/19589.png HTTP/1.1"
"GET /11/1791/1872.png HTTP/1.1"
"GET /17/47098/51507.png HTTP/1.1"
"GET /17/40683/45092.png HTTP/1.1"
"GET /17/47025/51434.png HTTP/1.1"
"GET /17/38091/42500.png HTTP/1.1"
"GET /3/4/4.png HTTP/1.1"
"GET /10/839/874.png HTTP/1.1"
"GET /15/6096/7382.png HTTP/1.1"
"GET /18/114432/123250.png HTTP/1.1"
"GET /18/139028/149316.png HTTP/1.1"
"GET /3/4/4.png HTTP/1.1"
"GET /16/17609/19814.png HTTP/1.1"
"GET /12/39/200.png HTTP/1.1"
"GET /18/129410/138228.png HTTP/1.1"
"GET /18/117680/126498.png HTTP/1.1"
"GET /4/9/9.png HTTP/1.1"
"GET /10/836/865.png HTTP/1.1"
"GET /6/40/42.png HTTP/1.1"

Je travaille sur une version améliorée du plugin afin de tirer des blocs aléatoires de tuiles plutôt que des tuiles uniques, ce qui se rapprochera plus des cas réels d'utilisation. On déterminera de façon aléatoire une première tuile et des requêtes seront générées de façon ordonnées dans un ensemble de tuiles voisines paramétrable.

dimanche, juin 3 2012

Le routage avec OpenStreetMap

Dans l'ecosystème OpenStreetMap je n'avais pas encore testé le processus de Routage en général et encore moins le projet OSRM qui monte en ce moment. Actuellement en pleine phase de développement, la dernière version 0.3 n'en est pas moins utilisable. Ce billet sera un retour d'expérience sur l'installation et l'utilisation de ce projet, j'ai utilisé pour cela la version de développement disponible sur GitHub.

Installation

Plutôt que de décrire ici l'installation et la compilation d'OSRM j'ai mis à jour la partie Debian/Squeeze du wiki officiel.

Préparation des données

Les données OSM doivent être préparées et mises en forme pour que OSRM puisse les exploiter, c'est dans certes partie de formatage des données que OSRM tire sa rapidité dans les calculs d'itinéraires, vous pouvez vous en rendre compte en utilisant la démo officielle basée sur une base mondiale. Cette préparation se fait avec les commandes osrm-extract et osrm-prepare. Prenons pour exemple le fichier de la Croatie téléchargé depuis les exports de Geofabrik, la première commande sera :

./osrm-extract croatia.osm.pbf 

Cette commande d'extraction va générer 2 nouveaux fichiers dans le répertoire courant, croatia.osrm.names et croatia.osrm.restrictions, le deuxième sera utilisé de suites pour la préparation des données :

./osrm-prepare croatia.osrm croatia.osrm.restrictions

Une fois ces 2 étapes passées nous avons les fichiers nécessaires à l'utilisation d'OSRM.

Optimisation des traitements

Comme de nombreux process lié à OSM la manipulation des données requiert de la RAM et de l'espace disque de façon significative, OSRM utilise un fichier temporaire qui peut rapidement dépasser la centaine de Giga Octets si vous travaillez sur les zones de la taille de l'Europe ou équivalent. Pour spécifier à OSRM où placer son fichier de travail temporaire créez un fichier .stxxl contenant la ligne :

disk=/home/tmp/stxxl,50000,mmap

qui indique, l'emplacement, la taille en Go et la méthode utilisée pour y accéder, pour plus de détails voir la page Running OSRM du wiki officiel. Enfin la prise en compte du fichier se fait par la déclaration d'une variable d'environnement :

export STXXLCFG=/home/www/osrm/Project-OSRM/.stxxl

Exécution du serveur

Nous avons nos fichiers, lançons le serveur. Le pararamétrage de celui-ci se fait dans le fichier server.ini, il est à noter que pour le moment le nom et l'emplacement de ce fichier n'est pas paramétrable, il est définit en dur dans [Routed.cpp| https://github.com/DennisOSRM/Project-OSRM/blob/master/routed.cpp#L95] on note la jeunesse du projet à ce genre de détail. Le fichier de configuration permet de définir :

  • le nombre de thread lancés
  • l'adresse IP d'écoute pour le démon
  • le port d'écoute

Il définit de même l'emplacement des fichiers de données qui ont été préparés lors des étapes précédentes :

  • hsgrData=/home/osrm-data/croatia.osrm.hsgr
  • nodesData=/home/osrm-data/croatia.osrm.nodes
  • edgesData=/home/osrm-data/croatia.osrm.edges
  • ramIndex=/home/osrm-data/croatia.osrm.ramIndex
  • fileIndex=/home/osrm-data/croatia.osrm.fileIndex
  • namesData=/home/osrm-data/croatia.osrm.names
  • timestamp=/home/osrm-data/croatia.osrm.timestamp

On note que le fichier de données original n'est pas utilisé pas OSRM, seuls les fichiers générés le sont. Il faut avant de se lancer dans du routage mondial s'attarder un peu sur le poids de ces fichiers. On est partit avec un fichier .pbf de 28Mo et on obtient :

24M     croatia.osrm.edges
53M     croatia.osrm.fileIndex
75M     croatia.osrm.hsgr
168K    croatia.osrm.names
11M     croatia.osrm.nodes
8.1M    croatia.osrm.ramIndex
8.0K    croatia.osrm.restrictions

Soit un total de 207Mo pour les 28 de départ, je vous laisse faire la règle de 3 adequat sur un full planet ! Mais une fois de plus le jeu en vaut la chandelle.

Utilisation

OSRM implémente en partie HTTP/1.1, l'interrogation se fait au travers de requête GET, les résultats sont renvoyés sous forme de fichier JSON, l'API est décrite sur la wiki dans la page Server API. Il existe 3 commandes à ce jour locate, nearest et viaroute qui servent respectivement à trouver le noeud le plus proche, identifier le noeud le plus proche sur une route, et obtenir le trajet entre 2 points. Je ne détaille pas le format JSON de retour obtenu, c'est très bien expliqué dans Server API. Un service web classique se basera donc sur 3 appels successifs, un premier pour trouver le point de départ en utilisant nearest, un appel pour le point d'arrivée également avec nearest et la route entre ces points avec viaroute. Il faut noter que le format de résultat de viaroute suit celui utilisé par Navengine de Cloudmade

Exemples de requête :

http://server:5000/nearest?52.555485441735&13.342227642887

http://server:5000/viaroute?loc=52.5,&13.34&loc=49.25,16.32

Pour la mise en forme de la route sur un fond de carte, viaroute renvoit un multiline encodé avec le polylinealgorithm de Google Maps. Un exemple de décodage en JS est disponible dans l'implémentqion OSRM-Web OSRM.RoutingGeometry.js

Normalement vous avez tout pour monter votre service de routage, je me suis fait pour ma part une rapide implémentaiton http://carto.quiedeville.org/osrm/. Basée sur une partie de l'Europe vous pouvez l'utiliser en gardant à l'esprit que c'est du POC, donc souvent ça bug.

Bilan

Projet jeune par son manque de packaging et de personnalisation dans l'utilisation, mais très prometteur. J'ai particulièrement apprécié la possibilité de faire du multi-modal route / ferry par exemple.

mardi, décembre 6 2011

Bilan des backports pour Openstreetmap

L'avantage indéniable de Debian sur d'autres distributions est à mes yeux sa stabilité exemplaire, cela entraine malheureusement d'avoir régulièrement des versions un peu obsolète des logiciels empaquetés. Il est possible de contourner cela en créant des backports de la version de développement de Debian (Wheezy) vers la version stable (Squeeze). J'ai réalisé les backports des principaux outils utilisés dans l'univers OpenStreetMap, ceux-ci sont diponibles sur mon dépôt privé (voir ce billet pour la mise en place du dépôt sur votre machine.

A ce jour les outils ci-dessous sont disponibles dans ces versions :

  • dans-gdal-scripts 0.18
  • gdal 1.7.3
  • mapnik 2.0.0
  • osm2pgsql 0.70.5
  • openlayers 2.11
  • gpsprune 13.1
  • viking 1.2.1

Les paquets n'ont pas été poussés dans le dépôt des backports officiels car ils représentent une utilisation trop faible au vu de la communauté Debian, un paquet comme osm2pgql est utlilisé à ce jour par moins de 300 personnes d'après popcon quand les outils apache2 le sont par plus de 60000 (popcon apache2-utils).

mardi, novembre 29 2011

Installer mapnik2 sur Debian Squeeze

La version de mapnik disponible dans squeeze est actuellement la 0.7.1 alors que la version 2.0 de Mapnik est déjà disponible pour Wheezy, j'ai backporté les paquets nécessaires pour faire du rendu avec mpanik2 pour la version squeeze de debian. Les .deb sont disponibles au téléchargement sur http://osm.fsffrance.org/debian-backports/

Un README détaille les étapes et les dépendances pour installer Mapnik2 sur votre Debian Squeeze.

jeudi, novembre 17 2011

Remplir ses caches sur plusieurs niveaux de façon smart

J'utilise tilecache pour générer des tuiles à la volée sur des rendus plus ou moins complexe, et pour réduire un peu la charge du serveur de rendu j'ai mis en place des caches (avec varnish) au devant de celui-ci. L'architecture de cache repose sur 2 niveaux, un cache en frontal direct non public, et 3 caches devant celui-ci qui sont appelés pas les clients OpenLayers (ou autres) et ouvert sur le net. L'intérêt des 3 caches est de bénéficier de l'astuce bien connu des a.tile.., b.tile.., c.tile bien connu des utilisateurs d'OpenStreetMap. Avec tilecache est fournit tilecache_seed qui permet de remplir les cache mais celui-ci ne remplissait pas entièrement mon besoin. En effet il me faut remplir les 3 caches publics, avec l'ensemble des layers rendus et ceci sans mettre à genoux le serveur de rendu. Idéalement l'opération se ferait en une passe sans avoir à ancer plusieurs commandes à la suite. Pour cela j'ai écrit un script perl qui rassemble toutes ces fonctionnalités plus quelques autres.

Le script permet de spécifier autant de serveur à remplir que souhaité, un ensemble de cache à générer, une bbox sur la zone voulue, et un couple de zoom min et max. Lors du lancement le script va extraire un premier serveur du groupe de serveurs indiqués, il va ensuite boucler pour générer tous les layers sur ce serveur sur la première tuile du zoom min, de cette façon le cache en frontal de la machine de rendu va se remplir. Ensuite il va appeler les mêmes tuiles sur les autres serveurs, à cet instant nous avons donc dans tous les caches, tous les layers dans l'espace d'une tuile. Le script va ensuite boucler de même pour toutes les autres tuiles en descendant dans les niveau de zoom après avoir complété le précédent.

Des problèmes fréquemement rencontrés avec des processus comme les remplissage de cache, la saturation du backend, la rupture d'un élément obligent à tout reprendre ou stopper le processus. J'ai essayé d'être le plus smart possible et de faire en sorte que le script aille le plus loin possible en générant le moins d'erreur, les mécanismes mis en oeuvre sont décrits ci-dessous :

  • suppression automatique d'un serveur défaillant, en cours de remplissage un des serveurs caches fait défaut, au bout de 10 réponses consécutives en erreur le serveur est ignoré et le remplissage continu sur les autres normalement
  • réduction de la sollicitation du backend, en cours de remplissage si le serveur source surcharge, à chaquer erreur 503 reçues le remplissage ralentit, le temps d'attente entre tuiles est augmenté afin de réduire la charge endurée. De même au bout d'un nombre de requête sans erreur le temps d'attente est réduit pour éviter un de traitement trop long. Si le temps d'attente dépasse un seuil le processus prend fin.
  • une option simulate permet de se rendre compte avant de le faire que l'on va faire plus de 3 millions de requêtes HTTP, des fois cela peut-être long :-)

Bien évidemment le script peut-être utlisé au plus simple avec un layer et un seul serveur de cache en direct, si vous n'aimez pas tilecache_seed.

Le script est nommé fill-cache.pl (original) et publié sur Gitorious dans le projet osmtools

Comme tout script/programme celui-ci n'est évidemement pas finit et peut être amélioré, alors comme il est libre, profitez-en, contribuez ! Si vous ne codez pas et avez l'idée de génie, un petit commentaire sur ce billet pourrait voir vos voeux se réaliser.

- page 1 de 2