Niveau | Débutant |
Logiciels utilisés |
Folium (module Python) Python version >= 2.7 (sauf petites modifications) |
Plateforme | Windows | Mac | Linux |
Vous voulez visualiser directement les résultats de vos traitements Python sur une carte interactive avec Leaflet, alors adoptez Folium de wrobstory (Python 2.7.x, mais il est possible de le faire fonctionner en Python 2.6.x moyennant quelques petites modifications dans les scripts). Le module a déjà été rapidement présenté dans la revue de presse du 24 mai 2013 de GeoTribu (Folium : Python et Leaflet sont dans un bateau). Il utilise les librairies JavaScript Leaflet.js et d3js pour fournir le résultat.
Principes
Pour débuter, rien de plus simple, quelques lignes de code suffisent pour créer un fichier html :
import folium
macarte = folium.Map(location=[50.7517,5.9106], zoom_start=13)
macarte.create_map(path='macarte.html')
et en l'ouvrant avec un navigateur, vous avez accès à Leaflet:
Il est possible de remarquer ici:
- que le fond de carte provient d'OpenStreetMap (par défaut), qu'il est centré sur les coordonnées en WGS84, 50.7517,5.9106 et que j'ai choisi un zoom de départ de 13;
- d'autres fonds sont possibles (tuiles OpenStreetMap, Stamen Terrain, Stamen Toner, Cloudemade et Mapbox avec une clé, par défaut), ou n'importe quel fond supporté par Leaflet:
tuiles = r'http://{s}.tiles.mestuiles.com/{z}/{x}/{y}.png'
Rajouter un popup montrant les coordonnées en cliquant sur la carte est un jeu d'enfant:
stamen = folium.Map(location=[50.7517,5.9106], tiles='Stamen Toner', zoom_start=13)
stamen.lat_lng_popover()
stamen.create_map(path='monstamen.html)
Ajouter des données vectorielles
L'intérêt est évidemment l'ajout de données vectorielles sur ce fond. Cela peut se faire de deux manières:
- avec des simples marqueurs (avec popup ici). Plusieurs sont disponibles, voir Folium: Circle Markers par exemple:
monpoint = folium.Map(location=[50.7517, 5.9106],zoom_start=13)
monpoint.simple_marker(location=[50.7517, 5.9106], popup='3290005')
monpoint.create_map(path='point.html')
autres marqueurs:
- à l'aide de fichiers aux formats GeoJSON ou TopoJSON, voir GeoJSON, nouveau lingua franca en géomatique ?
# fichier au format GeoJSON
mongeojson = "aachen.geojson"
carte = folium.Map(location=[50.63423,5.8303],tiles='Mapbox Bright', zoom_start=12)
carte.geo_json(geo_path=mongeojson)
carte.create_map(path='aachen.html')
- les polygones:
- ou avec des couleurs en fonction d'une variable (voir plus bas):
- les polylignes:
Enjolivures
Les nombreuses possibilités sont illustrées sur le site du module et sur le blog de l'auteur (wrobstory’s blocks);
- créer des cartes choroplèthes à l'aide des palettes de ColorBrewer. Le module permet la liaison de données entre les dataframes du module Pandas et des données Geo/TopoJSON:
- combiner l'ensemble avec d'autres modules Python comme vincent, du même auteur, qui offre les capacités de visualisation de JavaScript en Python:
- et le plus bel exemple est fourni par le travail de François Massot dans réserve parlementaire dont le projet a pour but de croiser différentes données (réserve parlementaire de 2011, données GEOFLA de l'IGN (communes), résultats des élections municipales pour les communes de plus de 3500 habitants et activité des députés) pour analyser les données de la réserve parlementaire.
- il combine différents modules Python pour aller chercher et télécharger les données sur Internet (Request et BeautifulSoup ) et pour les traiter ( Pandas et Fiona).
- les résultats son visualisés avec les modules matplotlib et Folium.
- un notebook IPython avec le traitement est disponible sur le site de François Massot et consultable à Analyse de la réserve parlementaire de 2011 (en cours)
(petits) inconvénients
Le seul problème que j'ai rencontré est dans la symbologie des données qualitatives. Elle ne peut être obtenue qu'en « trichant » du fait des jointures de Pandas. Je m'explique:
- pour représenter une carte de couleurs en fonction d'une variable qualitative ("id" ou "CODE" dans le fichier GeoJSON ci-dessous):
- il n'y a pas moyen d'utiliser directement ce fichier GeoJSON et je suis obligé de passer par une table intermédiaire du type:
- la classification des couleurs se fait sur ce champ "code" avec la jonction entre cette table et le fichier GeoJSON, avec Pandas. Le résultat est un fichier JSON (créé automatiquement par Folium) qui sera utilisé par d3js pour créer la carte:
import pandas as pd
geo = 'form.geojson'
table_sigles = 'sigles.csv'
# transformation du fichier csv en dataframe pandas
sigles = pd.read_csv(table_sigles)
map = folium.Map(location=[50.63423,5.8303],zoom_start=13)
map.geo_json(geo_path= geo, data=sigles,
columns=['sigle', 'code'], #colonnes de la table csv
key_on='feature.id', # lien avec le fichier GeoJSON
fill_color='YlGn', fill_opacity=0.9, line_opacity=0.4, # couleur pour chaque élément du fichier GeoJSON
legend_name='Sigles')
map.create_map(path='cretace.html')
Il est aussi encore impossible de créer un popup sur les données GeoJSON (à ma connaissance) comme dans le cas des fichiers GeoJSON placés dans GitHub (voir mon crétacé.geojson), ou plus généralement dans Using GeoJSON with Leaflet: "onEachFeature")
Conclusions
Tout cela ne doit pas masquer le grand intérêt de ce module et sa facilité d'utilisation:
- Il permet d'utiliser Leaflet de manière simple et sans se prendre la tête;
- Il permet aussi d'apprendre Leaflet par l'examen du fichier généré;
- Tout comme Leaflet, sans extension, les coordonnées des éléments géométriques doivent être dans le système de projection WGS84. Ce n'est pas un problème, car il est possible de changer de système de projection avec Python (voir Python: projections cartographiques, définitions et transformations de coordonnées sur le Portail);
- Transformer un fichier shapefile en un fichier GeoJSON est très facile avec un module comme Fiona, mais aussi avec osgeo/ogr ou pyshp (shapefile), de même pour la transformation d'une couche PostGIS ou d'une couche Spatialite (osgeo/ogr, Psycopg2, sqlite3 ou pyspatialite), le tout à l'aide de la geo_interface (voir Les modules Python à finalités géospatiales: quid, quando, ubi ?);
- ainsi ma couche originale, un fichier shapefile dans la projection EPSG31370:
Tous les traitements ont été effectués sur Mac OS X avec Python 2.6 ou Python 2.7
Site officiel : Folium
licence Creative Commons Paternité-Pas d'Utilisation Commerciale-Pas de Modification 2.0 France
Commentaires
il faut mettre en place un
il faut mettre en place un serveur (python peut suffire)
http://www.pythonforbeginners.com/modules-in-python/how-to-use-simplehtt...
aller dans un terminal sur le dossier ou est présent le html et rentrez Python -m SimpleHTTPServer
idem
idem pas de carte qui s'affiche????
Bonjour, pour ton souci il
Bonjour, pour ton souci il faut être connecter à internet pour voir le résultat.Et merci à Martin Laloux.
Je cherche comment integrer une carte dans une application en offline.
Si quelqu'un a une solution
Si quelqu'un a une solution merci de me l'envoyer dans le plus bref delais.
ouleur000@gmail.com
super!
Super, c'est exactement ce que je cherchais pour créer des cartes à la volée en python.
Seulement j'ai un problème, je n'arrive pas à ajouter de couche geojson (créé depuis qGis2.0), dès que je fais macarte.geo_json(geo_path=chemin_vers_mon_json) j'obtiens une page blanche :-/ Faut-il mettre un serveur web par derrière pour fournir des fichiers statiques?
Autre chose, avez-vous une astuce pour créer un fichier geojson depuis une base PostGis via Pandas?
Encore merci pour ces infos!
Bonjour, as tu trouvé une
Bonjour, as tu trouvé une solution a ton problème de visualisation de ton fichier .json ?
J'ai exactement le même problème rien ne s'affiche...
Poster un nouveau commentaire