4
02 déc 2010

Introduction


MapQuest propose depuis peu une API permettant de 'jouer' avec les données OpenStreetMap. Il s'agit là d'une avancée significative selon moi pour la démocratisation de cette base de données géographiques. MapQuest propose donc plusieurs services basés sur OSM :

  • un service d'itinéraire ;
  • un service de géocodage ;
  • un service d'affichage de tuiles prégénérées par MapQuest ;
  • un service d'élévation (je ne pense pas qu'il soit basé sur OSM ...).

Initialisation


Avant toute chose, commençons par préparer les bibliothèques dont nous aurons besoin. En fait il n'y en a qu'une : OpenLayers.
Il faut donc télécharger la dernière version de ce célèbre client carto et le décompresser quelque part dans notre répertoire de travail (je donne ici le code pour aller vite sous Ubuntu, ce n'est pas beaucoup différent pour d'autres plateformes) :


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

Et voilà, nous avons donc un répertoire qui contient la bibliothèque OpenLayers dans sa dernière version.

Préparons notre page Web :


GeoTribu - MapQuest / OSM




Et ajoutons un peu de style pour afficher cette carte pleine page (pour le coup, pas besoin de trop se fouler :-) ):

Affichage des tuiles


La théorie

MapQuest autorise l'utilisation leurs tuiles générées via les données OSM. Pour générer ces tuiles, ils utilisent Mapnik et ont mis à disposition sous licence MIT les feuilles de style utilisées.
Le système d'URL pour accéder aux tuiles est le même que pour les tuiles OSM :

Les tuiles font 256 pixels sur 256 pixels.
Voici un exemple (à gauche la slippy map Mapnik par défaut et à droite MapQuest) sur ma petite commune que j'ai mappé modestement (avec plein de fautes de tag, j'en suis sûr) avec mes petites mimines, mon Garmin et mon vélo :

  

Et là vous allez me demander comment on fait pour trouver le x et le y qui va bien dans l'URL. Et bien, le web fourmille d'outils qui font ce que l'on cherche : je vous invite à lire ce lien sur le système de nommage des tuiles OSM et d'utiliser cet outil très utile pour calculer ces deux chiffres.

La pratique

Tout d'abord la fonction init(), où vous ne verrez rien de bien nouveau si vous suivez de temps en temps ce blog, dans l'ordre :

  • les options de la carte : les contrôles, les projections, niveau de zoom ;
  • l'ajout d'une couche ;
  • le positionnement du centre de la carte ;
  • seule la définition de la couche TMS est nouvelle.

Ce qui donne en Javascript :


function init(){
map = new OpenLayers.Map ("map", {
controls:[
new OpenLayers.Control.Navigation(),
new OpenLayers.Control.PanZoomBar()],
maxExtent: new OpenLayers.Bounds(-20037508.34,-20037508.34,20037508.34,20037508.34),
maxResolution: 156543.0399,
numZoomLevels: 19,
units: 'm',
projection: new OpenLayers.Projection("EPSG:900913"),
displayProjection: new OpenLayers.Projection("EPSG:4326")
});

var mapquest = new OpenLayers.Layer.TMS("MapQuest", "http://otile1.mqcdn.com/tiles/1.0.0/osm/", {
type: 'png',
getURL: osm_getTileURL,
displayOutsideMaxExtent: true,
isBaseLayer: true
});

map.addLayer(mapquest);

var lonLat = new OpenLayers.LonLat(lon, lat).transform(new OpenLayers.Projection("EPSG:4326"), new OpenLayers.Projection("EPSG:900913"));
map.setCenter (lonLat, zoom);
}

La nouveauté vient donc de la couche TMS OSM qui est modulo pas grand chose mais modulo quand même, presque identique à la spécification TMS OSGEO qui permet de définir l'URL d'une pyramide de tuiles (la différence entre les deux provient du fait que les coordonnées commencent en haut à gauche et non en bas à gauche ... lire la page consacrée sur le wiki pour plus d'infos) ... vite reprendre de l'air ... TMS OSM, TSM OSGeo, WMTS, caches WMS, toutes ces normes pour afficher des petites images ... à croire que c'est fait exprès pour paumer les gens :/

Ce n'est pas très important (enfin si, mais pas indispensable), le tout est de comprendre qu'une couche TMS est définie par une URL de base (cf. la théorie juste au-dessus) et ici donc par une fonction qui permet de calculer les zoom, x et y, les mettre dans le bon ordre et afficher les tuiles : ce qui est fait par la fonction osm_getTileURL(bounds) que voilà :


function osm_getTileURL(bounds) {
var res = this.map.getResolution();
var x = Math.round((bounds.left - this.maxExtent.left) / (res * this.tileSize.w));
var y = Math.round((this.maxExtent.top - bounds.top) / (res * this.tileSize.h));
var z = this.map.getZoom();
var limit = Math.pow(2, z);

if (y < 0 || y >= limit) {
return OpenLayers.Util.getImagesLocation() + "404.png";
} else {
x = ((x % limit) + limit) % limit;
return this.url + z + "/" + x + "/" + y + "." + this.type;
}
}

Il nous reste à initialiser les variables map, lat, lon et zoom et nous avons notre carte avec des tuiles MapQuest :-) :


var lat = 49.6987;
var lon = 2.7898;
var zoom = 15;
var map;