S'abonner au Flux RSS

Mot-clé - openstreetmap

Fil des billets - Fil des commentaires

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.

mercredi, juin 22 2011

Nouvelles cartes des éoliennes

En avril 2010 j'ai réalisé une première carte des éoliennes en france, cette carte utilise un fichier de données GML comme source de données. Afin de pouvoir réaliser une carte mondiale des éoliennes en particulier et des sources d'énergie en général j'ai mis en place une instance GeoServer avec une base de données Postgis comme source.

Ceci m'a permis de réaliser cette nouvelle carte de couverture mondiale qui recense aujourd'hui 40 781 éoliennes au plan mondial.

Cette carte sera mise à jour une fois par semaine dans un premier temps puis quotidiennement si la puissance machine le permet.

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.

dimanche, mai 22 2011

Leaflet, un nouveau concurrent pour OpenLayers ?

Dans un précédent billet j'évoquais les possibilités de réduction de taille de la librairie OpenLayers, avoisinant le méga de données en natif je trouve cette librairie un peu trop gourmande. En réduisant au maximum les fonctionnalités j'arrivais à une taille de 154Ko ce qui permettait d'afficher des tuiles issue d'OpenStreetMap et d'avoir les fonctionnalités de déplacement et de zoom de base.

Si la problématique de la taille est primordiale dans votre déploiement de carte ligne vous serez intéressé par la nouvelle librairie Leaflet que vient de publier Cloudmade. Conçue pour les applis web et mobiles Leaflet ne pèse à ce jour que 64Ko. On ne retrouve que les fonctions de bases, mais déjà bien assez pour la plupart des cartes vues sur le web. Les fonctions de bases sont présentes avec en plus des possibilités d'ajout d'objets géometriques et les interactions minimales pour ouvrir les classiques popups. Publiée sous licence BSD le code est disponible sur Github, vous pourrez y signaler des bugs éventuels ou demander des nouvelles fonctionnalités sur la page de suivi d'anomalie.

Même si tous les exemples utilisent comme source le service MApzen de Cloudmade, il est possible d'utiliser n'importe quel serveur de tuile. J'ai fait une carte sommaire de la Bretagne avec les tuiles OSM standards, je suis assez emballé de la rapidité d'affichage,

Je vous invite à laisser en commentaire vos impressions et éventuellement à débattre de ses avantages/inconvénients par rapport à OpenLayers ; dont on attend la version 2.11 dans les jours/semaines à venir.

lundi, janvier 31 2011

Service de frame pour cartes libres

Une remarque fréquemment entendue lors des présentations du projet OpenStreetMap est l'apparente compléxité à mettre une carte sur son site ; comparaison généralement faite avec d'autres services de cartes en ligne que nous ne nommerons pas ici.

Il est déjà possible d'obtenir un code d'iframe grâce au bouton Export sur le site du projet ; mais cette option n'est pas suffisemment connue ni facilement accessible à la diffusion des cartes dans les pages contact des sites web.

Pour remédier à cela et participer à la diffusion du projet OSM j'ai mis en ligne un service web de mise à disposition de frame nommé cartosm.eu.

Le service permet la création du code HMTL à insérer sur un site web pour y ajouter une iframe contenant une carte avec différentes options. Les cartes générées sont configurables pour y inclure une épingle, les rendre fixes, ajouter un lien vers une carte plus grande, ...


La carte ci-dessus est ajoutée à ce billet en y insérant le code HTML suivant :

<iframe width="330" height="250" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="http://cartosm.eu/map?lon=-3.4549803733223&lat=47.637733494058&zoom=18&width=330&height=250 &mark=true&nav=true&pan=true&style=default"></iframe><br /><div id="cartosmlink"><a href="http://www.openstreetmap.org/?lat=47.637733494058&lon=-3.4549803733223&zoom=18&layers=M" style="text-align:left;">Voir sur une carte plus grande</a></div>

vendredi, janvier 21 2011

Réduire la taille de la librairie OpenLayers

La librairie OpenLayers est constituée d'un ensemble de classe, de fonctions, de librairies externes, qui sont séparés dans 292 fichiers Javascript. Le principe de la construction de la librairie est de rassembler tous les fichiers pour n'avoir au final qu'un seul .js à mettre sur votre serveur web. Nous allons décrire ici la méthode qui permet de pour choisir quelles parties seront incluses dans le fichier final. Pour ma part j'ai l'habitude d'exclure tous les objets type Marker des cartes qui ne sont composées que de tuiles de bases, on enlèvera de même tous les contrôles inutilisés.

Tout d'abord, récupérez l'archive contenant les sources sur le site du projet, la version à la rédaction de ce billet est la 2.10.

wget http://www.openlayers.org/download/OpenLayers-2.10.tar.gz

Décompressez ensuite l'archive obtenue et placez vous dans le répertoire build qui contient les scripts de construction.

tar xvfz OpenLayers-2.10.tar.gz
cd OpenLayers-2.10/build/

On trouve dans le répertoires les scripts build.py et buildUncompressed.py écrits en python. Les fichiers de profile full.cfg library.cfg, et lite.cfg, le fichier de licence et un traditionnel README.txt qui contient un peu d'aide, juste un peu.

Le script nommé build.py prend 2 options. La première permet de spécifier le fichier de profile à utiliser (par défaut full.cfg) et la deuxième le nom du fichier généré (par défaut OpenLayers.js)

exécution du programme :

./build.py

ou

./build.py full

on note que le fichier de profil est à indiquer sans l'extension .cfg

build.py utilise jsmin (présent dans le répertoire tools/ de l'archive) pour minifier le code généré, si vous ne souhaitez pas le faire il vous faudra alors utiliser le script buildUncompressed.py pour construire votre librairie. La génération non compressée aboutit à un fichier de 2.6M, on réservera cette version pour les devs :-)

Par défault le script build.py utilise le fichier de configuration full.cfg qui comme son nom l'indique contient l'ensemble des librairies et classes du projet OpenLayers ainsi que les inclusions externes. Les fichiers sont placés dans le répertoire lib/ dans la racine de l'archive. La création du build full donne

Total files merged: 269
Compressing using jsmin.

Pour une taille de 929K.

Une compilation avec la configuration plus légère en utilisant le profile lite.cfg aboutit à 128K pour seulement 23 fichiers de sources utilisés, le gain est net et sans appel.

On aboutit avec ce fichier au minimum requis pour afficher une carte dans une page web, un minimum de contôles sont toutefois nécessaires pour permettre à l'internaute d'interagir sur la carte. C'est dans ce sens que j'ai créé le fichier ci-dessous qui me permet d'aboutir à un fichier de 154K ce qui fait tout de même un gain de 80% en taille.

[first]
OpenLayers/SingleFile.js
OpenLayers.js
OpenLayers/BaseTypes.js
OpenLayers/BaseTypes/Class.js
OpenLayers/Util.js

[last]

[include]
OpenLayers/Map.js
OpenLayers/Layer/TMS.js
OpenLayers/Control/Attribution.js
OpenLayers/Control/PanZoom.js
OpenLayers/Control/Navigation.js
OpenLayers/Control/ArgParser.js

[exclude]

Un fichier de profile se décrit en 4 sections qui contiennent chacune un ensemble de nom de fichier faisant référence au répertoire lib/ de la racine. Les fichiers présents dans include sont inclus dans le fichier final quand ceux de la section exclude en sont exclus. Il est possible de laisser la section include vide et de ne seulement spécifier que ceux qui ne seront pas utilisés, dans ce cas tous les fichiers sources sont inclus ; c'est d'ailleurs le choix fait dans le profil full.

Un fichier présent dans la section first sera inclus en début de processus, pour la section last il sera poussé à la fin du fichier, un fichier présent dans l'une de ces 2 sections doit figurer également dans la section include sinon une erreur se produit. La section include à prédominance sur la section exclude, un fichier présent dans les 2 sera inclus au final.

Dans la version par défaut la localisation française n'est pas incluse, on ajoutera la ligne "OpenLayers/Lang/fr.js" dans la section include pour corriger cela, raison de plus pour les francophones de construire eux mêmes leur librairie.

Il ne faut pas voir la finalité de la réduction de taille comme un gain en temps de transferts, au vu du volume de tuiles qui accompagnent une carte cela ne serait pas pertinent. Le gain le plus intéressant se trouve au niveau de l'exécution du code javascript dans le navigateur pour une part. D'autre part moins on à de code exposé, moins on a de bugs potentiels.

Un dernier intérêt à mettre en place cette méthode et vous l'aurez vite compris c'est que vous pouvez inclure votre propre code Javascript dans la lib et ne plus avoir qu'un seul fichier .js à charger pour animer vos cartes, et un fichier de moins, c'est une socket de moins, des octets en moins, une ligne de log en moins ...

- page 1 de 2