S'abonner au Flux RSS

Mot-clé - cartographie

Fil des billets - Fil des commentaires

vendredi, juin 22 2012

L'OpenData toulousain

La communauté urbaine de Toulouse à récemment lancé son portail des données libres, le site accessible sur http://data.grandtoulouse.fr/ dispose à la date de publication de ce billet de 48 jeux de données couvrant des domaines comme l'éducation, les résultats électoraux ou encore la topographie avec l'altimétrie des voies. Je ne suis pas toulousain mais je me suis tout de même penché sur les données publiées avec un regard de bon père de famille, j'ai pour cela regardé de près les données liées aux écoles et aux équipements sportifs.

Pour les tout petits on trouve les coordonnées des crèches sur la commune de Balma, de même que pour les équipement sportifs seules cette ville a mis ses données à disposition semble-t'il. Pour les écoles on dispose déjà de beaucoup plus d'informations 90 écoles élémentaires publiques et 105 maternelles, cela donne déjà plus de données à analyser, au passage je ne note aucune donnée sur Blagnac dans ces fichiers. Je n'ai pas trouvé de données pour l'enseignement supérieur, ni collèges ni lycées, le portail étant jeune gageons qu'il gagnera en exhaustivité avec le temps.

Sur les formats de données c'est un peu disparate il ne faut pas hésiter à retraiter, les données géographiques sont parfois en 2 dimensions, parfois en 3. Les fichiers kmz ne sont pas directement exploitables pour les conversions, certains champs de données contenant directement du code HTML par exemple. Les fichiers CSV contiennent parfois une colonne avec les coordonnées géographiques parfois non. Le bilan global reste tout de même positif, même si il a fallu parfois utiliser les fichier MapInfo, parfois les kml, parfois les CSV pour obtenir un résultat homogène, mais sur l'ensemble j'ai réussit à récupérer les données que je cherchais dans ce qui était publié.

L'ensemble de ces données a été mise en oeuvre sur une carte en ligne.

Dernier point les données ont été publiées sous licence Open Data Commons Open Database License.

Merci à la CU de Toulouse et vivement la suite des données ....

PS : je cherche toujours le lien direct pour télécharger les fichiers sans passer par l'interface web

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, mai 24 2011

Leaflet la sobre, OpenLayers la gourmande

En utilisant Leaflet sur quelques pages de test je trouvais son comportement assez rapide en comparaison à OpenLayers, voulant comprendre ce qui pourrait expliquer ce sentiment j'ai décidé de mesurer le nombre de tuiles téléchargées par chacune des librairie pour une utilisation identique. J'ai pour cela monté ce soir un rapide test que je vous livre ici.

Le protocole de test est le suivant, une page contenant 2 cartes identiques de 512px par 512px, une pour LeafLet et l'autre pour OpenLayers. Les deux cartes sont déplacées simultanément en appelant des commandes identiques.

Les commandes de déplacement sont décrites ci-dessous avec à chaque fois le nombre de tuiles totale téléchargées depuis le début du test comptées depuis le serveur web.

Au chargement de la page

  • Leaflet : 9 tuiles
  • OpenLayers : 42 tuiles
  • ratio : 4.6

Deux zoom out :

  • Leaflet : 27 tuiles
  • OpenLayers : 126 tuiles

Deux zoom in (toujours sans changer de position) :

  • Leaflet : 27 tuiles
  • OpenLayers : 192 tuiles

Déplacement d'un degré au nord puis d'un degré à l'est

  • Leaflet : 33 tuiles
  • OpenLayers : 212 tuiles

Deux zoom in

  • Leaflet : 51 tuiles
  • OpenLayers : 296 tuiles

Pan de 100px à gauche, puis 100px en bas

  • Leaflet : 54 tuiles
  • OpenLayers : 316 tuiles
  • ratio : 5.85

Là le match est sans appel, Leaflet gagne haut la main dans le registre de la sobriété. Mais si OpenLayers déborde sur les cotés alors la différence va s'amenuiser lors d'une ballade sur la carte. Ce que j'ai fais en tournant un peu en rond, quelques zoom out et in pour me recentrer et au final après une visite autour d'un point fixe on obtient :

  • Leaflet : 182 tuiles
  • OpenLayers : 1449 tuiles
  • ratio : 7.96

La ratio final de 7.96 comparé au ratio inital de 4.6 lors du chargement de la page me laisse un peu pantois sur l'efficacité du chargement des tuiles périphériques par OpenLayers.

lundi, mai 23 2011

Rendu de tuile dynamique sous Debian Squeeze

Nous allons mettre en oeuvre une méthode génération de tuile à la volée en utilisant l'outil TileCache sur une distribution Debian Squeeze. Le principe de TileCache exposé ici et de servir par Apache un cgi qui va générer une tuile en utilisant le moteur de rendu mapnik et la stocker sur le disque pour ne pas avoir à la regénérer à chaque appel. La procédure part d'une installation minimale de la dernière version stable de Debian à savoir Squeeze.

Première étape, installer quelques outils de travail qui ne sont pas liés au sujet qui ici nous importe mais dont nous aurons besoin. Cette action se fait avec l'utilisateur root évidemement, chaque futur changement d'utilisateur unix sera clairement explicité.

apt-get install subversion wget unzip bzip2 apache2

Sans trop détailler cette partie nous allons installer une base de données spatiale.

apt-get install postgresql postgis postgresql-8.4-postgis osm2pgsql

Si votre environnement par défaut n'utilise pas une locale en UTF-8 vous aurez à recréer votre cluster postgres, pour cela détruisez l'actuel (toutes données seront perdues) et recréé le par défaut en UTF-8. Les trois commandes suivantes supprime le cluster actuel, créé le nouveau et le démarre.

pg_dropcluster --stop 8.4 main
pg_createcluster 8.4 main --locale fr_FR.UTF-8
pg_ctlcluster 8.4 main start

Pour les manipulations purement postgresql on travaille toujours avec l'utilisateur unix postgres, On passe donc sous cet utilisateur

su - postgres

On vérifie que le cluster est par défaut en utf-8 avec la commande :

psql -l

La colone encoding doit indique 'UTF8'

On créée un utilisateur sans privilèges particulier qui sera utilisé plus loin dans la configuration de mapnik.

createuser -S -D -R -P render

on considère dans la suite du billet que vous affectez ici le mot de passe 'render' à cet utilisateur ; dans la vrai vie personne n'ose faire une chose pareille évidemment :-)

Création de la base de données nommée render, que l'on affecte à l'utilisateur "render"

createdb -O render render

Les trois commandes suivantes servent à spatialiser la base. Cela permet de stocker et manipuler les objets géométriques directement avec des primitives postgres.

createlang plpgsql render
psql -q -d render -f /usr/share/postgresql/8.4/contrib/postgis-1.5/postgis.sql
psql -q -d render -f /usr/share/postgresql/8.4/contrib/postgis-1.5/spatial_ref_sys.sql

Les 3 commandes précédentes doivent être siliencieuses en cas de succès.

On rend la propriété des objets créés à notre utilisateur "render" (les commandes ont été lancées avec le user "postgres")

psql -d render -c 'ALTER TABLE geometry_columns OWNER TO render'
psql -d render -c 'ALTER TABLE spatial_ref_sys OWNER TO render'
psql -d render -c 'ALTER VIEW geography_columns OWNER TO render'

Il nous reste à effectuer l'installation du moteur de rendu mapnik et à charger le fichier de données dans la base de données Désormais nous allons travailler avec un utilisateur dédié au rendering

Retour en root pour installer la paquets nécessaires

apt-get install python-mapnik mapnik-utils

et création d'un utilisateur lambda

adduser render

On passe sous cet utilisateur render pour la suite.

su - render

Installation de mapnik depuis le dépôt svn officiel d'openstreetmap dans le répertoire /home/render/mapnik

svn co http://svn.openstreetmap.org/applications/rendering/mapnik

Toutes les informations nécessaires au rendu ne sont pas stockées dans la base de données, une partie est utilisée depuis des fichiers de formes appelés Shapefiles. On trouvera par exemple dans ceux-ci le contour des continents, qui contrairement aux autres données dans OSM bougent bien peu. Avant de pouvoir faire nos rendus nous allons donc les récupérer grâce à un script bash qui télécharge les fichiers nécessaires et les décompresse dans le répertoire courant :

cd mapnik && bash get-coastlines.sh

Là vous pouvez aller prendre un café, un sandwich ou une entrecôte suivant le débit de votre liaison internet. Le total des fichiers réléchargés dépasse les 450Mo.

A cette étape nous nous rappochons d'OpenStreetMap et allons récupérer les données pour les charger dans notre base. Nous récupérons le fichier pour la région Basse-Normandie, à vous d'adapter pour coller à votre besoin. Les deux sources de fichiers d'export les plus utilisés aujourd'hui sont Geofabrik et Cloudmade, arbitrairement nous utiliserons Cloudmade.

wget http://downloads.cloudmade.com/europe/western_europe/france/basse-normandie/basse-normandie.osm.bz2

Le chargement des données dans la base se fait avec le logiciel osm2pgsql, celui-ci utilise en entrée un fichier de données (comme celui fraichement téléchargé) et un fichier de style qui permet de filtrer les clés sur les objets en fonction de ce que l'on veut afficher sur notre carte. Le packaging de debian évoluant moins rapidement que les tags dans OSM nous allons légèrement adapter le fichier de style ajoutant la clé 'addr:housename' au fichier de style pour que notre démonstration fonctionne.

cp /usr/share/osm2pgsql/default.style .
echo 'node,way addr:housename text linear' >> default.style

Longue étape, le chargement des données se fait avec la commande :

osm2pgsql -s -S default.style -d render basse-normandie.osm.bz2

là encore pour pouvez aller vous ressourcer en alcaloïde méthylxanthine ,

Avec les sources de mapnik est distibué le style utilisé pour le rendu sur le site openstreetmap.org autant l'utiliser. Étant assez complexe il est découpé en plusieurs fichiers xml qu'il faut réassembler en spécifiant la connexion à postgresql qui sera utilisée pour le rendu. Cela se fait en utilisant le script pyhton generate_xml.py de la façon suivante :

./generate_xml.py --host=localhost --port=5432 --user=render --password=render --dbname=render osm.xml > osm-local.xml

Le fichier osm-local.xml sera celui utilisé au final par mapnik, il fait tout de même 9682 lignes, on voit bien l'intérêt du découpage.

J'en profite pour féliciter ceux qui sont arrivés jusque ici et les rassurent aussi, on voit le bout.

Si on fait le point, nous avons nos données de stockées dans la base et le moteur de rendu est installé et configuré, ne nous reste donc plus qu'à passer au sujet principal de ce billet, à savoir TileCache :

Installation se fait au travers du paquet eponyme

apt-get install tilecache

La configuration s'effectue dans le fichier dans /etc/tilecache.cfg auquel nous ajouterons juste une section finale composée de :

[osm]
type=Mapnik
mapfile=/home/render/mapnik/osm-local.xml
spherical_mercator=true
tms_type=google

Cette simple configuration conclue l'installation et il ne nous reste qu'à tester l'ensemble

Par défaut TileCache va stocker les tuiles générées dans /tmp/tilecache à vous d'adapter au besoin. Dans un prochain billet on verra le cache des tuiles directement dans Memcached.

Ma machine de test s'appelle geti que vous remplacerez dans l'url suivante par le nom de votre machine

L'appel de cette url devrait vous afficher la ville de Cherbourg

http://geti/cgi-bin/tilecache.cgi/1.0.0/osm/12/2029/1395.png

Vous reconnaitrez facilement la forme de l'url que vous pourrez utiliser avec Leaflet par exemple.

Pour tester plus en avant votre installation vous pouvez récupérer un fichier simple de test disponible sur mon serveur, adaptez le nom de la machine dans le code et placez le fichier à la racine de votre site web, vous disposerez d'une carte navigable avec des tuiles générées à la volée !

wget http://carto.quiedeville.org/leaflet/article-test.html

Bugs, problèmes, mécompréhension, les commentaires sont ouverts.