MapServer, substitution de variable et mise en cache.

12 juin 2009

Vous le savez sans doute, MapServer permet de réaliser du « runtime substitution» , soit de la substitution dynamique de variable à l’exécution. En clair, votre requête, CGI ou WMS (ce qui revient peu ou prou au même), intègre un paramètre complémentaire dont la valeur va être interprétée au sein du fichier .map.

Pour être plus clair, imaginons que vous  cartographiez les trajets routiers effectués par des utilisateurs. Chaque utilisateur ne doit voir que ses propres trajets parce qu’on est pas chez Big Brother. En rajoutant un paramètre user_id à la requête envoyée à MapServer, on peut filtrer le contenu renvoyé par le fichier .map. La chaîne SQL de récupération des données devient alors :

DATA « the_geom from trajets WHERE user_id = %user_id%» 

C’est tout simple donc. En intégrant entre pourcentages le même paramètre que celui envoyé dans la requête, MapServer lui substitue la valeur associée, et le contenu renvoyé est ainsi filtré. On peut aussi ajouter des expressions régulières pour valider les valeurs envoyées et éviter une bonne grosse SQL injection.

Tout cela est connu et très pratique. Ca tord un peu le coup à l’aspect normalisé quand c’est utilisé en WMS, mais les normes ça sert aussi à être dépassé. Néanmoins, il reste un obstacle à la mise en cache des résultats. TileCache par exemple, qui joue un rôle de proxy, ne fait suivre au serveur WMS que les attributs de la norme WMS, et génère alors une erreur car %user_id% sans rien y subsitituer n’est pas utilisable en SQL. C’est pourtant pratique de mettre aussi ce type de résultat en cache.

Mais il y a une solution ! L’Alaska Ocean Observation System publie un patch qui permet de faire suivre au travers de TileCache n’importe quel attribut complémentaire pour peu qu’il soit déclaré dans le tilecache.cfg (fichier de configuration du cache). Ils l’ont fait pour faire du WMS-T (WMS temporel, enrichi d’une variable temporelle pour récupérer des observations par exemple), et étendu à tout attribut complémentaire, ce qui mérite d’être salué.

Une des complications impliquée par ce genre de techique est la multiplication des arborescence, puisqu’un cache spécifique sera créé pour chaque valeur du paramètre. Avec des milliers d’utilisateurs dans mon exemple, ça peut rapidement poser problème. Mais pourquoi alors ne pas utiliser un cache mémoire (Tilecache avec MemCache), d’une taille pré-définie ? Avec quelques giga-octets, on pourra y stocker un bon nombre de tuiles, sans jamais surcharger le système. Les plus récemment créées remplaceront les plus anciennes quand le cache sera plein. Cette méthode s’adapte aussi assez bien au temps (presque) réel, puisqu’on peut paramétrer le durée de vie des données stockées par MemCache. Pour un suivi de conditions de circulation (bouchons…), on peut ainsi quand-même profiter d’un cache qui dure le temps de la validité de la donnée. Mais même 10 minutes, si de nombreux utilisateurs se connectent, c’est un considérable allégement de la charge système.

Petit résumé :

Dans OpenLayers :

layer = new OpenLayers.Layer.WMS("Couche dynamique en cache",
"http://serveur.com/tilecache/",
{layers: 'layer_test',format:'PNG',user_id:myUserId},
{isBaseLayer:true,visibility:true});

on a donc surchargé la définition de la couche avec un paramètre user_id qui prend la valeur de la variable javascript myUserId.

Dans Tilecache.cfg :

on ajoute à la définition du layer WMS : extra_params=user_id

Dans le MapFile :

On intègre le paramètre à la chaîne DATA (ou FILTER, ou EXPRESSION, ou CONNECTION selon les besoins) : DATA « the_geom FROM trajets WHERE user_id = %user_id%» 

on ajoute une ligne dans le bloc METADATA de la couche pour valider le user_id:

‘user_id_validation_string’ ‘^[0-9]{1,2}$’ qui impose un entier fait de deux chiffres au maximum.

Fresh meat

25 avril 2009

Deux sorties dignes d’intérêt ces derniers jours : OpenJump 1.3 et MapServer 5.4.

Concernant le premier, on note l’arrivée de nouvelles méthodes de discrétisation (moyenne, seuils naturels et Jenks notamment) et d’informations statistiques sur les couches (min, max, moyenne…), ainsi que de nouvelles fonctions d’édition des géométries (auto-complétion des polygones sur tracé existant, simplification de polygones sans incohérence, double fenêtrage synchrone…) qui en font un outil de choix pour tout ce qui touche à la manipulation des données.

MapServer voit quant à lui intégrées les améliorations promises par le Toronto Code Sprint. J’ai fait quelques tests habituels sur des extraits de larges couches PostGIS et Shapefile, et les résultats sont assez troublants. Voici un comparatif avec la version 5.2 pour la génération d’une image de 600 x 600 pixels comprenant deux couches, communes et ROUTE250 sur une zone couvrant à peu près la Gironde :

image générée avec le driver AGG

5.2 5.4
Postgis GIF 0.142 0.159
PNG 0.388 0.386
AGG 0.920 0.707
Shapefile GIF 0.101 0.101
PNG 0.297 0.318
AGG 0.920 0.842
SHP + QIX GIF 0.058 0.060
PNG 0.315 0.284
AGG 0.834 0.606

Il y a à mon avis quelques informations utiles à tirer de ces résultats, qui n’ont pas vocation à présenter des index de performance pure, mais bien à comparer les deux versions dans des situations analogues. Considérons le format GIF comme celui de référence car impactant le moins de temps final de création de l’image.

Premièrement, on note une perte de performances légère (moins de 10 %) entre la version 5.2 et la nouvelle version 5.4 en GIF. Paul Ramsey m’a expliqué que c’est dû au passage à un curseur texte pour parcourir la base de données en lieu et place du précédent curseur binaire, plus performant certes, mais beaucoup plus difficile à maintenir et à utiliser dans le code car devant être manipulé au sein de transactions (et je veux bien le croire…).

Deuxièmement, on note toujours l’avantage significatif du shapefile, a fortiori quand il est indexé. Les modifications indiquées ci-dessus portent le ratio à 1.5 avec un Shapefile standard et à plus de 2 avec un fichier .qix. On peut en conclure que pour obtenir les meilleures performances, c’est cette association SHP + QIX + GIF qu’il faut choisir.

Cependant le rapport s’inverse avec les autres formats, comme si le nouvel handicap de l’accès à Postgis était compensé par une meilleure prise en charge du PNG et de l’AGG/PNG. C’est avec ce dernier choix, l’anticrénelage AGG, que l’amélioration est la plus significative, preuve s’il en fallait que Thomas Bonfort (créateur et mainteneur de l’intégration AGG dans MapServer) n’aura pas fait le déplacement à Toronto pour rien. Mais ce que je ne comprends pas, c’est qu’une image PNG ou AGG semble mieux bénéficier des données indexées (Postgis ou qix) que d’un simple shapefile. Thomas, si tu lis ces lignes…
In fine, 20 % de mieux pour le couple le plus sexy (PostGIS + AGG), c’est une vraie bonne nouvelle.

On est les champions !

24 avril 2009

Question : dans quelle discipline la France occupe-t-elle la première place devant l’Espagne, l’Allemagne et l’Australie ? Non, ce n’est le foot (l’Australie pff…), ni la chasse aux paradis fiscaux, mais l’activité OpenSource ! Des gens très sérieux (RedHat et le Georgia Institute for Technology) ont fait un index, l’OSI, pour OpenSource Index, et donc un classement non moins sérieux, avec une belle carte,  dans lequel la France obtient le premier rang pour son activité OpenSource. Elle le doit surtout à la note dans la catégorie « Gouverment» , ce qui va faire chaud au coeur de nos députés (qui utilisent Ubuntu), de la Gendarmerie Nationale qui a entrepris une migration de grande ampleur vers le libre, mais aussi de l’ADDULACT ou du BRGM. Qui sait, le dernier GeoSource a peut-être permis de faire la différence avec l’Espagne (2e du classement) qui la ramène un peu avec GvSIG

Pour mieux comprendre le classement, il y a toute la démarche qui est expliquée, du moins pour ceux qui ont le courage de lire les 23 pages serrées… Plus court, une FAQ répond aux questions d’usage, genre « Pourquoi mon pays n’apparaît pas dans la liste ?»  Et bien ce n’est pas parce que ton pays est tout nul en OpenSource, c’est tout simplement parce qu’il est tellement arriéré qu’on a même pas pu trouver une donnée pertinente. Content ? Pour les obsessionnels, le dernier paragraphe explique comment la carte a été créée : à partir d’un shapefile fourni par thematicmapping.org, les géométries ont été allégées des trucs inutiles (Corse, Sardaigne, Irlande du Nord…), puis simplifiées. Le tout a été transformé en GeoJSON (760 ko quand-même) par OGR, et est reprojeté à la volée par OpenLayers, ce qui explique sans doute pourquoi c’est si lent.

Vive la France, vive la République, vive le Logiciel Libre !

Tutoriel GeoDjango en français

27 mars 2009

L’excellent blog GeoTribu diffuse la traduction en français du tutoriel GeoDjango. Sacré boulot, bravo !

Labellisation IGN de Proj et GDAL

23 mars 2009

C’est enfin officiel, Proj et GDAL sont labellisés par l’IGN pour les transformations en Lambert93, de même que le paquetage FWTools pour Windows qui les contient. Quel bel exemple de la mobilisation de l’IGN pour les technologies OpenSource ! Merci à eux.