Accueil / Blog / Métier / Archives / Carte des vélos de Toulouse avec Leaflet

Carte des vélos de Toulouse avec Leaflet

Par Mathieu Leplatre publié 31/05/2011

Les bookmarks, un peu comme les cahiers de recettes, c'est bien de les remplir mais encore faut-il trouver les bons au moment adéquate ! Même quand il s'agit d'outils, de bibliothèques et de services Web, il faut trouver l'occasion de les tester avant le grand soir ! Et si on veut en faire un article de blog, alors là, il faut en plus donner envie d'y goûter :)

Ici, je prends plein d'ingrédients trouvés au bord des chemins :

Je secoue bien fort ! (sans oublier de saupoudrer de jquery) et j'obtiens une carte interactive des stations vélos de Toulouse !

La liste des stations

Sur le site http://velonow.info, je récupère un fichier XML qui contient la liste statique des stations de vélo et leurs identifiants.

C'est l'occasion d'utiliser pyquery pour le transformer en GeoJSON. Gawel nous l'avait présenté aux djangocongs, il s'agit du portage de l'API de JQuery en python !

from pyquery import PyQuery as pq

d = pq(url='http://server.com/file.xml')
for m in map(lambda e: pq(e), d.find('marker')):
    pt = geojson.Point([m.attr('lng'),
                        m.attr('lat')])
    ...
    ...

Je trouve ça génial d'avoir la même syntaxe de manipulation du DOM en python et en javascript ! Et pour faire du webscrapping, c'est top !

Affichage de la carte

Cloudmade a créé leaflet qui rejoint Tile5 et Polymaps en tant que challenger d'Openlayers !

C'est une bibliothèque légère, jolie, fluide, optimisée pour les mobiles, et même compatible Internet Explorer !

Pour afficher une carte centrée sur la localisation du visiteur de la page, il suffit de faire ça :

var map = new L.Map('map');

var cloudmadeUrl = 'http://{s}.tile.cloudmade.com/BC9A493B41014CAABB98F0471D759707/997/256/{z}/{x}/{y}.png',
    cloudmade = new L.TileLayer(cloudmadeUrl);

map.addLayer(cloudmade);
map.locateAndSetView();

Pour l'instant, Leaflet ne gère pas les couches au format GeoJSON, en attendant la prochaine release, nous allons ajouter les points des stations en 2 coups de cuillère à pot :

$.getJSON(url, function(data) {
    $.each(data.features, function(i, f) {
        var cc = f.geometry.coordinates;
        var marker = new L.Marker(new L.LatLng(cc[1], cc[0]));
        map.addLayer(marker);
    });
});

Détails d'une station en popup

Les détails d'une station (nombre de vélos, emplacements, libres, occupés) sont disponibles en fournissant un identifiant sur le site de velo toulouse. Mais lorsqu'on appelle la page en Ajax, le corps de la réponse XML est vide. Une protection contre la bidouillabilité sûrement.

C'est là que Yahoo Query Language nous aide ! On passe par Yahoo pour accèder aux ressources du Web avec des requêtes similaires aux bases de données !

var yql = "select * from xml where url = '" + url + "'",
 yqlurl = 'http://query.yahooapis.com/v1/public/yql?q=' + encodeURIComponent(yql);
$.get(yqlurl, function(data) {
    // show data in pop up !
});

Je fais une petite fonction pour transformer l'XML récupéré en objet :

function xml2obj(xmldata) {
    d = {};
    $(xmldata).children().each(function(index, value){
        d[$(value).get(0).nodeName] = $(value).text();
    });
    return d;
}
<station>
    <free>12</free>
    <available>4</available>
    <total>16</total>
</station>

devient :

{
    free : 12,
    available : 4,
    total: 16
}

Pour mettre en forme ces informations dans la pop-up, nous allons utiliser mustache ! Conceptuellement, il s'agit tout simplement d'un moteur de template avec une syntaxe simplifiée ! Il y a une implémentation dans quasiment tous les languages, dont Javascript.

Cela évite principalement de faire du code javascript pour la mise en forme des données, notamment pour celles récupérées en JSON via Ajax.

On construit une chaîne avec les fameuses {{}} et on fournit un objet pour substituer les valeurs :

var data = xml2obj($(xmldata).find('station')),
    template = "<h2>Station #{{ number }}</h2>
 <p>{{ address }}</p> 
 {{# station }} 
 <ul> 
 <li>{{ available }} available</li> 
 <li>{{ free }} free slots</li> 
 </ul> 
 {{/ station }}",
    content = Mustache.to_html(template, data);
// Show marker popup !
marker.bindPopup(content).openPopup();

Et voilà !

ABONNEZ-VOUS À LA NEWSLETTER !
Voir aussi
How to create an Angular library How to create an Angular library 08/02/2017

Having a light and clean distribution AND running tests on Travis, showing demo on Github Pages, ...

Elections.js génère des cartes pour vous Elections.js génère des cartes pour vous 30/03/2015

Le travail sur les cartes pour les élections départementales a débouché sur la création d'un ...

Bien gérer le passage au développement front end Bien gérer le passage au développement front end 21/02/2017

Adaptation des équipes à de nouveaux enjeux.

Faire une boucle for dans un template Angular 2 Faire une boucle for dans un template Angular 2 11/07/2016

Quand on n'a pas d'itérable sous la main

Retour sur le petit déjeuner "Quel framework JS pour 2017 ?" Retour sur le petit déjeuner "Quel framework JS pour 2017 ?" 09/12/2016

Si vous n'avez pas pu assister à notre session toulousaine ou à notre session nantaise, voici la ...