Vous consultez notre ancien site web, accédez au nouveau site sur www.openstreetmap.fr
freeroute (Marc Sibert)
Open Data 71 & Balades Vertes
Le Conseil Général de la Saône-et-Loire (71) a lancé son site Open Data depuis quelques temps déjà (septembre 2011). La Nuit des Cartes Vivantes 2012 (7 fev.) a été l’occasion d’un ballon d’essai avec l’extraction et l’exploitation des parcours des « Balades Vertes » et leur mise en valeur sous la forme d’une couche placée au-dessus du rendu Mapnik. Voici le résultat :
Juste pour faire court, voilà comment transformer le fichier original .shp en pointillés cliquables sur un fond OSM :
- Importer le fichier .shp dans une base Spatialite (en mémoire, par exemple) ;
- Transformer chaque ligne géographique (LINESTRING) en GeoJSON en prenant soin de conserver les autres attributs ;
- Sauvegarder le fichier .sqlite qui sera exporter sur le serveur LAMP qui va bien ;
- Ajouter une page HTML statique avec OpenLayers, plus un bonus PHP pour requêter la base SQLite et produire un flux full-geojson.
Et c’est ici en plein-écran : http://freeroute.fr/71
Présentation OSM à Courcouronnes le 25 juin 2011
Lancée par Liness et supportée par le RERS de Courcouronnes, je participe le 25 juin prochain 14h30 à une présentation OpenStreetMap et à petite Mapping Party à suivre.
.entry .olMapViewport img { max-width: none; }#map_1 {padding: 0; margin: 0;}#map_1 img{padding: 0; margin: 0;border:none;margin-top:0px;margin-right:0px;margin-left:0px;margin-bottom:0px;}/* = limit) { return OpenLayers.Util.getImagesLocation() + "404.png"; } else { x = ((x % limit) + limit) % limit; return this.url + z + "/" + x + "/" + y + "." + this.type; } }var lonLat = new OpenLayers.LonLat(2.41480350494385,48.6289510130882).transform(map.displayProjection, map.projection);map.setCenter (lonLat,17);var markers = new OpenLayers.Layer.Markers( "Marker" );map.addLayer(markers);var data = {};var currentPopup;data.icon = new OpenLayers.Icon("http://freeroute.fr/wp-content/plugins/osm/icons/wpttemp-green.png", new OpenLayers.Size(24,24), new OpenLayers.Pixel(0, -24));var ll = new OpenLayers.LonLat(2.41480350494385,48.6289510130882).transform(map.displayProjection, map.projection); var feature = new OpenLayers.Feature(markers, ll, data);feature.closeBox = true;feature.popupClass = OpenLayers.Class(OpenLayers.Popup.FramedCloud, {"autoSize": true, minSize: new OpenLayers.Size(150,150),"keepInMap": true } );feature.data.popupContentHTML = "RERS Courcouronnes1, Place du Printemps
91080 Courcouronnes";feature.data.overflow = "hidden";var marker = new OpenLayers.Marker(ll,data.icon.clone());marker.feature = feature;var markerClick = function(evt) { if (this.popup == null) { this.popup = this.createPopup(this.closeBox); map.addPopup(this.popup); this.popup.show(); } else { this.popup.toggle(); } OpenLayers.Event.stop(evt);};marker.events.register("mousedown", feature, markerClick);markers.addMarker(marker);map.addPopup(feature.createPopup(feature.closeBox));})(jQuery)/* ]]> */ Ordre du jour
- Introduction
- Présentation d’OpenStreetMap
La raison d’être d’OSM et la base de données (cf. la FAQ) - Licences et données libres
Licences CC-BY-SA 2.0 et ODbL (en cours) - Les objets stockés et leur caractérisation :
- Le Node (point) :
C’est l’élément de base, le seul ayant des coordonnées géographiques dans le repère WGS84 (longitude et latitude en degrés). - le Way (ligne brisée) :
Suivant les usages, le way représente une ligne ou une surface fermée (polygone). Il est composé de Nodes (ordonnés). - la Relation :
Regroupe des éléments (Nodes, Ways & Relations) avec des rôles (ordonnés). - les Tags (attributs) : {key = valeur}
Il s’agit de paires clé/valeur caractérisant chaque élément. Les tags sont uniques pour un élément donné. Si plusieurs valeurs sont admissibles, elles seront séparées par un « ; ».
- Le Node (point) :
- Présentation d’OpenStreetMap
- La Mapping Party
- Choisir les éléments à cartographier
- Présentation de Walking Papers
- Sur le terrain…
- Numérisation des résultats et injection dans les éditeurs
Exemples de scans dans le sud de Courcouronnes :- Scan – Lien pour Potlatch
- Lac et Parc : Scan – Lien pour Potlatch
- NAFSEP : Scan – Lien pour Potlatch
- La saisie dans OSM
- Le Wiki
- Les sources de données libres
- Les principaux éditeurs (Potlatch & JOSM)
- Aller plus loin dans JOSM
- Utiliser OSM
- Une constellation de services
- Les Composants d’OSM
- Mapnik
- Open MapQuest
- CloudMade
- Transport en Commun : ÖPNV-Karte
- Intégrer les cartes et les données avec OpenLayers
- Une constellation de services
Import des données de la 4C dans OSM
Suite à un appel à contributeurs sur la liste talk-fr@openstreetmap.org, je me suis lancé dans la manipulation de ces données. Sous la main, j’avais le fichier compressé transmis par la Communauté de Communes et le bel outil SpatiaLite et en particulier son interface graphique.
Finalement, les données sont en ligne mais ne feront pas l’objet d’un import massif. Pour les récupérer, il suffit de passer par freeroute.fr/4c et de sélectionner le cadre dont on souhaite récupérer les données. Une bulle vous propose un lien vers le fichier au format .osm. Les cadres correspondent à ceux de QualityStreetMap afin que le suivi de l’import puisse être facilité.
Vous pourrez retrouver tout le processus décrit en détail.
Les Autoroutes de France
Je me suis lancé dans la génération automatique de cartes, sous la forme de fichiers .svg directement générés à partir de requêtes SQL sur la base mondiale d’OpenStreetMap. Et voilà le résultat :
Données © OpenStreetMap & contributeurs – cc-by-sa 2.0 & ODbl
Attachons une base pour y mettre les nouvelles tables sans modifier la base « Planet » originale :
?View Code SQL1 ATTACH DATABASE 'boundaries.sqlite' AS boundaries;Suppression d’un historique et création d’une nouvelle table contenant tous les contours (du monde) :
?View Code SQL1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 DROP TABLE IF EXISTS boundaries.contour; CREATE TABLE boundaries.contour AS SELECT w.id AS id_way, ( SELECT LineFromText('LINESTRING(' || group_concat(X(n.coord) || ' ' || Y(n.coord)) || ')', 4326) FROM node AS n JOIN way_nodes AS wn ON wn.id_node=n.id WHERE wn.id_way=w.id ) AS geometrie FROM ( SELECT DISTINCT * FROM ( SELECT w.id FROM way AS w JOIN way_tags AS wt1 ON wt1.id_way=w.id JOIN tag AS t1 ON wt1.id_tag=t1.id AND t1.key="admin_level" AND t1.value="2" UNION SELECT w.id FROM way AS w JOIN way_tags AS wt1 ON wt1.id_way=w.id JOIN tag AS t1 ON wt1.id_tag=t1.id AND t1.key="natural" AND t1.value="coastline" ) EXCEPT SELECT w.id FROM way AS w JOIN way_tags AS wt1 ON wt1.id_way=w.id JOIN tag AS t1 ON wt1.id_tag=t1.id AND t1.key="maritime" AND (t1.value="yes" OR t1.value="true") ) AS w;Dans certains cas, il existe des Ways sans contenu :
?View Code SQL1 DELETE FROM boundaries.contour WHERE geometrie IS NULL;La colonne geometrie doit être déclarée comme spatiale et recevoir un index (MBR en mémoire) :
?View Code SQL1 2 SELECT RecoverGeometryColumn('boundaries.contour', 'geometrie', 4326, 'LINESTRING', 2); SELECT CreateMbrCache('boundaries.contour', 'geometrie');Envoi des prochaines sortie dans le fichier « .svg » :
?View Code SQL1 .output routes.svgCommençons la génération du fichier proprement dite par l’entête du fichier :
?View Code SQL1 2 3 4 5 SELECT '<?xml version="1.0"?>'; SELECT '<svg viewBox="100 -7200 1200 1200" xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny">'; SELECT '<title>Les autoroutes de France</title>'; SELECT '<desc>La France des Autoroutes</desc>';Le trait de cote de fait en recherchant les élément du contour inclus dans la BBOX [-10, 40, 15, 52] (en degrés WGS84). Les tracés sont ensuite projetés en Lambert 93 (SRID 2154) puis simplifiés, avant d’être passés d’une échelle du mètre au kilomètre (ce dernier point évite simplement d’avoir des coordonnées de très grandes valeurs) :
?View Code SQL1 2 3 4 5 6 7 8 9 SELECT <path d="' || AsSVG(ScaleCoords(Simplify(Transform(geometrie, 2154), 2000.0), 0.001)) || '" fill="none" stroke="black" stroke-width="2" />' FROM boundaries.contour WHERE rowid IN (SELECT rowid FROM boundaries.cache_contour_geometrie WHERE mbr = FilterMbrIntersects(-10, 40, 15, 52) );Le dessin des autoroutes se fait par superposition de deux traits (rouge large et jaune étroit). La sélection est faite par les relations type='route' et network='FR:A-road'.
?View Code SQL1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 SELECT (SELECT '<path d="' || AsSVG(ScaleCoords(Simplify(Transform(LineFromText('LINESTRING(' || group_concat(X(n.coord) || ' ' || Y(n.coord)) || ')', 4326), 2154), 1000.0), 0.001)) || '" fill="none" stroke="red" stroke-width="9" />' FROM node AS n JOIN way_nodes AS wn ON wn.id_node=n.id WHERE wn.id_way=rm.id_member ) || ' ' || (SELECT '<path d="' || AsSVG(ScaleCoords(Simplify(Transform(LineFromText('LINESTRING(' || group_concat(X(n.coord) || ' ' || Y(n.coord)) || ')', 4326), 2154), 1000.0), 0.001)) || '" fill="none" stroke="yellow" stroke-width="3" />' FROM node AS n JOIN way_nodes AS wn ON wn.id_node=n.id WHERE wn.id_way=rm.id_member ) FROM road AS r JOIN relation_members AS rm ON r.id_relation=rm.id_relation AND rm.type=2 JOIN way as w ON w.id=rm.id_member WHERE r.network='FR:A-road';Enfin, clôture du fichier .svg :
?View Code SQL1 SELECT '</svg>';Et voilà.
Le code source de cette page est dans le Domaine Public.
osm2sqlite
Il s’agit d’un nouveau développement, toujours en C++, d’une série de classes permettant l’import des flux XML d’OSM dans une base locale. Les fonctionnalités attendues sont :
- la lecture de fichiers planet et diffs ;
- le stockage dans une base de données locale ;
- des fonctions « spatiales » (index spatiaux, projections) ;
- un code « portable » sur différents environnements (Windows, Linux, etc.)
Pour éviter de réinventer la roue, voici les librairies existantes sur lesquelles s’appuie ce développement :
- The Expat XML Parser
- Expat est la librarie d’un parseur XML écrite en C. C’est un parseur orienté flux dans lequel une application enregistre des gestionnaires pour les éléments que le parseur peut rencontrer dans le document XML (comme une ouverture de tag). L’un des intérêts de cette librairie est sa légèreté et surtout son fonctionnement sur les flux, ce qui évite de charger en mémoire tout le document XML avant de commencer l’analyse.
- SpatiaLite 2.3.1 a complete Spatial DBMS in a nutshell
- Il s’agit de la librairie d’une base de données spatiale. Elle-même regroupe les fonctionnalités de plusieurs librairies dont :
- SQLite : un moteur de base de données (sans serveur) ;
- Geos : apporte le support du jeu des spécifications OpenGis® au niveau des requêtes SQL ;
- Proj.4 : permet les projections et autres changements de repères géographiques.
Elle permet aussi l’ajout d’index spatiaux sur les éléments géométriques de la base.
Il est sous licence LGPLv3 qui n’est pas la meilleure aux yeux de la Free Software Foundation, Inc., mais comme elle plutôt faite pour les librairies, je l’adopte.
Le mieux, c’est de retrouver tout le code sur GitHub à l’adresse : http://github.com/Marcussacapuces91/LibOsm
Par contre, je ne fournis pas le make file. Il faudra le rédiger vous-même suivant votre environnement de développement.
Il vous faudra aussi le fichier init_spatialite-2.3.sql disponible sur le site de SpatiaLite pour initialiser la base de données.
Le modèle de donnéesAfin de pouvoir utiliser les tables efficacement, il est intéressant de connaitre le modèle de données (le schéma) de la base de données.
Modèle de données On retrouve les principaux éléments d’OSM sous forme de tables, en particulier :
- Node (liste des nœuds) ;
- Way
- Relation
- Changeset
Ensuite, j’ai « factorisé » les User (id et nom utilisateur) et les Tags afin d’éviter de multiplier les références dans chaque enregistrement des tables ci-dessus.