Données OSM
Cette page documente le chargement de données OpenStreetMap dans GeOxygene implémenté dans le module geoxygene-osm.
Utilisation via le plugin OSM
La première entrée du menu OSM permet d’importer un fichier de données .osm. Ce format est dérivé de XML et contient les données OSM sous forme de triplets RDF. Parser ce fichier et convertir les informations est un processus long (plusieurs minutes pour de gros fichiers), le déroulement du chargement s’affiche dans la barre de progression ci-dessous. L’étape la plus longue est la lecture de l’ensemble des points du fichier, puis le chargeur lit les lignes et les relations, et enfin convertit toute l’information parsée en objets CartAGen.
Ces objets sont affichés après chargement avec un style par défaut qui reproduit le style OpenStreetMap par défaut (voir exemple ci-dessous). Ce style par défaut n’est pas complet, et il est possible de le compléter en modifiant les fichiers sld présents dans le répertoire resources/sld.
Structure d’un fichier .osm
Le fichier commence par lister l’ensemble des points de la zone, notamment ceux qui constituent les objets linéaires et surfaciques (voir exemples ci-dessous). Les coordonnées sont données en WGS84.
<?xml version='1.0' encoding='UTF-8'?>
<osm version="0.6" generator="osmconvert 0.7P" timestamp="2013-12-12T20:55:02Z">
<node id="354718511" visible="true" version="3" changeset="525232" timestamp="2009-04-13T22:51:35Z"
user="RedFox" uid="10610" lat="42.8837240" lon="-0.4035712"/>
<node id="354718548" visible="true" version="3" changeset="525232" timestamp="2009-04-13T22:52:28Z"
user="RedFox" uid="10610" lat="42.8847835" lon="-0.4043782"/>
<node id="354718549" visible="true" version="3" changeset="525232" timestamp="2009-04-13T22:52:26Z"
user="RedFox" uid="10610" lat="42.8848781" lon="-0.4049507"/>
Ces nœuds peuvent également être “taggés” (on leur a ajouté des propriétés par un tag RDF) s’ils représentent un objet géographique ponctuel comme le repère géodésique ci-dessous. Ces tags correspondent la plupart du temps aux recommandations du projet OpenStreetMap que l’on peut retrouver sur ce wiki. Dans cet exemple, on retrouve des tags de nature métadonnées comme “source” et d’autres de nature attributaire comme “ele” qui donne l’altitude du point.
<?xml version='1.0' encoding='UTF-8'?>
<osm version="0.6" generator="osmconvert 0.7P" timestamp="2013-12-12T20:55:02Z">
<node id="670195943" visible="true" version="1" changeset="4176402" timestamp="2010-03-20T05:58:55Z"
user="Eric S" uid="45284" lat="42.8959309" lon="-0.4054379">
<tag k="description" v="Table d'orientation : Axe et sommet - Point vu en place en 1949"/>
<tag k="ele" v="2031.91"/>
<tag k="man_made" v="survey_point"/>
<tag k="note" v="Ne pas déplacer ce point, cf. - Do not move this node, see -
http://wiki.openstreetmap.org/wiki/WikiProject_France/Repères_Géodésiques#Permanence_des_rep.C3.A8res"/>
<tag k="ref" v="6432013 - 1"/>
<tag k="source" v="©IGN 2010 dans le cadre de la cartographie réglementaire"/>
<tag k="url"
v="http://ancien-geodesie.ign.fr/fiche_point.asp?num_site=6432013&no_ptg=01&numero_f50=1547"/>
</node>
Une fois tous les points de la zone décrits, le fichier contient la liste de toutes les lignes avec leurs tags associés. Un polygone est ici une ligne dont le point final est identique au point initial. Les points sont listés par la identifiant unique (voir exemple ci-dessous). Les données géographiques ont en général un tag principal (dont la liste est disponible sur le wiki, voir plus haut), qui correspond au nom de la classe dans une modélisation relationnelle ou orientée-objet. Dans notre exemple ci-dessous, le tag principal est “highway” (qui correspond aux routes) avec la valeur “track” : c’est une route de type piste.
<?xml version='1.0' encoding='UTF-8'?>
<osm version="0.6" generator="osmconvert 0.7P" timestamp="2013-12-12T20:55:02Z">
<way id="167651914" visible="true" version="1" changeset="11918076" timestamp="2012-06-16T18:39:15Z"
user="Slyan" uid="342924">
<nd ref="1790350049"/>
<nd ref="1790350043"/>
<nd ref="1790350064"/>
<nd ref="1790350066"/>
<nd ref="1790350070"/>
<nd ref="1790350072"/>
<tag k="highway" v="track"/>
</way>
Enfin, le fichier contient la liste des relations, qui sont des relations sémantiques reliant deux (ou plus) objets (nœud ou ligne) du fichier. L’exemple ci-dessous montre une relation précisant que deux lignes forment le cours principal du cours d’eau appelé “Le Soussouéou Gave”. Les autres cours d’eau portant ce nom sont alors considérés comme bras annexes du cours d’eau. Ces relations permettent aussi de définir des partages topologiques. Pour l’instant, les relations sont parsées et chargées, mais elles ne sont pas utilisées dans la construction des objets géographiques.
<?xml version='1.0' encoding='UTF-8'?>
<osm version="0.6" generator="osmconvert 0.7P" timestamp="2013-12-12T20:55:02Z">
<relation id="2108120" visible="true" version="3" changeset="16345406" timestamp="2013-05-29T23:38:22Z"
user="RedFox" uid="10610">
<member type="way" ref="155642448" role="main_stream"/>
<member type="way" ref="223612562" role="main_stream"/>
<tag k="name" v="Le Soussouéou Gave"/>
<tag k="ref:sandre" v="Q6040500"/>
<tag k="type" v="waterway"/>
<tag k="waterway" v="stream"/>
</relation>
Schéma de données de CartAGen
Dans CartAGen, les données géographiques sont gérées de manière plus complexe que dans une utilisation simple de GeOxygene. Les bâtiments sont placés dans une classe de bâtiments qui implémente l’interface des bâtiments qui modélise l’ensemble des propriétés et relations classiques d’un bâtiment dans une BD géographique (par exemple, sa hauteur, sa nature et l’îlot auquel il appartient). Ainsi, cela autorise les traitements sur les données géographiques qui sont spécifiques aux bâtiments de prendre en paramètre cette interface, et toutes les implémentations possibles de cette interface vont pouvoir utiliser ce traitement.
Dans le cas d’OSM, une implémentation spécifique de toutes ces interfaces géographiques (voir figure ci-dessous) a été réalisée et les données OSM sont chargées dans ces classes implémentant les interfaces de CartAGen (OsmBuilding implémente IBuilding).
Le chargeur va s’occuper de ces classes de manière transparente et l’utilisateur aura une couche par classe nommée par le nom de la population associée à la classe (par exemple “buildings pour les objets qui implémentent IBuilding).
Principes du chargement
Mapping OSM/CartAGen
Le schéma de données CartAGen est un schéma orienté-objets avec des classes géographiques prédéfinies, chacune possédant un type de géométrie, alors que le schéma OSM se contente de mettre des tags sur des points ou des lignes. Le passage de l’un à l’autre n’est donc pas direct. En effet, suivant ni les types de géométries, ni le tag principal ne permettent d’apparier directement à des classes : le tag highway peut décrire une route linéaire (à mettre dans la classe OsmRoadLine) ou un parking surfacique (à mettre dans la classe OsmRoadArea) suivant le type de géométrie taguée. Nous proposons donc pour réaliser cet appariement d’utiliser un objet Mapping composant d’une liste d’appariement (objets de la classe OsmMatching) dont le diagramme de classes UML est présenté ci-dessous. Un “matching” énumère les combinaisons de tag permettant de peupler une classe du schéma CartAGen.
Un mapping par défaut est fourni dans le module mais il ne gère pas encore tous les types d’objets présents dans OSM et doit donc être complété au besoin. Un extrait ci-dessous montre comment on décrit l’appariement pour la classe WaterArea.
OsmMatching lakematching = new OsmMatching("natural", IWaterArea.class, GeometryType.POLYGON);
lakematching.addTagValue("water");
lakematching.addTagValue("lake");
this.matchings.add(lakematching);
Factory d’objets Cartagen “OSM”
Chaque implémentation du schéma de données CartAGen est muni d’une factory (au sens des design patterns) qui permet de créer les objets géographiques de manière générique. On ne fait pas new OsmRoadLine(line) mais getSchemaFactory().createRoadLine(line) en récupérant la factory de l’implémentation courante, stockée sur le plugin CartAGen. Si on charge des données OSM, la factory courante du plugin sera bien celle d’OSM qui créera de manière transparente un objet de la classe OsmRoadLine. Dans le cas du chargement OSM, la factory est dotée d’une méthode createGeneObj(...) qui est capable d’appeler la bonne méthode de création à partir des informations parsées (les nœuds et les tags OSM) et des informations du mapping (le nom de la classe CartAGen et le type de géométrie).
public OsmGeneObj createGeneObj(Class<?> classObj, OSMResource resource, Collection<OSMResource> nodes) {
if (IRoadLine.class.isAssignableFrom(classObj)) {
ILineString line = OsmGeometryConversion.convertOSMLine((OSMWay) resource.getGeom(), nodes);
return (OsmGeneObj) this.createRoadLine(line, 0);
}
if (ICable.class.isAssignableFrom(classObj)) {
ILineString line = OsmGeometryConversion.convertOSMLine((OSMWay) resource.getGeom(), nodes);
return (OsmGeneObj) this.createCable(line);
}
// ...
Conservation des tags OSM
Si certains tags sont utilisés pour remplir des attributs des objets Java, tous sont conservés dans une map définie sur la classe OsmGeneObj, ce qui permet de les interroger. L’appel à la méthode générique des IFeature getAttribute(String name) va chercher les valeurs dans ces tags pour les objets OSM contrairement au fonctionnement générique de la méthode.
De plus, il est possible de visualiser tous les tags des objets sélectionnés en cliquant sur l’entrée “Browse tags” du menu ajouté par le plugin OSM.
Attention, pour l’instant, le chargeur convertit les coordonnées en Lambert93 et ne projette donc correctement que des données situées en France métropolitaine. Une version améliorée du chargeur gérant plusieurs projections est prévue car des données OSM sont disponibles partout dans le monde.