France/Données de la Communauté de Communes de Concarneau Cornouaille

From OpenStreetMap Wiki
Jump to navigation Jump to search

L'annonce par François V.

Bonjour,

Il y a peu de temps, la CC de Concarneau Cornouaille votait l'ouverture de ses données SIG.
Aujourd'hui, celles-ci sont disponibles pour OSM à cette adresse : [http://dl.free.fr/mlOSilcKP http://dl.free.fr/mlOSilcKP] extrait).
Ci-dessous, le mail attestant de la provenance des données.

Je n'ai pas trop le temps en ce moment de regarder pour un import.
Quelqu'un est volontaire ?

Les données

http://dl.free.fr/i70SlzW7i sous la forme d'un fichier .zip contenant les adresses d'une part et les tronçons d'autre part. Le tout est projeté en RGF 93 / Lambert zone 7.

Travaux publiés

Marc 09:51, 23 December 2010 (UTC)

Pour rappel :

Public domain
All my contributions to OpenStreetMap are released into the public domain. This applies worldwide.
In case this is not legally possible, I grant anyone the right to use my contributions for any purpose, without any conditions, unless such conditions are required by law.

Cela inclut le texte de cet article, mais évidemment aussi tout le code et les résultats obtenus avec.

J'ai extrait toutes les informations dans une base Spatialite dans laquelle j'ai dû rajouter la définition de la projection utilisée.

SRID : 27567
Libellé : RGF 93 / Lambert zone 7
Proj4Text : +proj=lcc +lat_1=47.25 +lat_2=48.75 +lat_0=48.0 +lon_0=3 +x_0=1700000 +y_0=7200000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs

NOM_VOIE

Premier travail : normaliser les libellés des voies qui sont tous en majuscules et quelques abréviations. Je vous livre un brouillon de substitution des libellés France/Données de la Communauté de Communes de Concarneau Cornouaille/substitutions. Je vous encourage à le compléter en particulier aux locaux qui pourront corriger et/ou accentuer les toponymes bretons.

Afin que la requête de génération du fichier OSM (ci-dessous) fonctionne, il faut importer le tableau dans un fichier .CSV et lui-même doit être importé dans Spatialite, par exemple nous le nom de normalisation. Cela donne une table de la forme :

CREATE TABLE "normalisation" (
"PK_UID" INTEGER PRIMARY KEY AUTOINCREMENT,
"NOM_VOIE" TEXT,
"ref" TEXT,
"name" TEXT)

La table contient les références des voies quand c'est possible. Les références conservées sont celles des voies nationales (RN devient N), les voies départementales (RD -> D), les voies communales (C xxx) ; les chemins d'exploitations n'ont pas de référence.

A ce stade je me pose la question des chemins ruraux à qui j'ai saisis des références (CR xxx). Une idée ? --Marc 17:03, 2 January 2011 (UTC)

NB_VOIE

Il semble que cela contienne le nombre de voies indépendamment des sens de circulations. Dans OSM, les lanes, indiquent le nombre de voies par sens de circulation. Point à confirmer par la source.

TYPE_VOIE

case trim(type_voie)
	when "Autoroutiere" then "motorway"
	when "Principale" then "primary"
	when "Regionale" then "secondary"
	when "Liaison locale" then "tertiary"
	when "Locale" then "unclassified"
	when "Chemin" then "path"
	when "Chemin empierre" then "path"
	when "Sentier" then "pedestrian"
	when "En construction" then "construction"
	when "Escalier" then "steps"
	else "road"
end

SENS_VOIE

case sens_voie 
	when "Double sens" then "0"
	when "Sens inverse" then "-1"
	when "Sens unique" then "1"
	else NULL
end

Créer la table des nodes

Afin de faciliter l'import et la réutilisation des points dans OSM, je fabrique une table de nodes à partir de tous les tronçons et leur géométries.

  • Une petite astuce pour parcourir tous les nœuds d'un LINESTRING, c'est de croiser la requête avec une table d'entiers allant de 1 au nombre maximum de POINTs sur une LINESTRING : pour ce faire, j'utilise tout simplement la colonne ROWID de la table des tronçons.
  • Après j'ajoute l'id (négatif) de chaque node à partir de son ROWID et son index unique.
  • Je déclare la colonne point comme élément spatial.
  • Enfin je vérifie le résultat par un select qui me donne 35809 lignes ou nodes uniques.
CREATE TABLE node AS 
	SELECT DISTINCT
		NULL AS id, 
		PointN(t.geometry, cpt.rowid) AS point,
		X(Transform(PointN(t.geometry, cpt.rowid), 4326)) AS lon,
		Y(Transform(PointN(t.geometry, cpt.rowid), 4326)) AS lat
		FROM Troncons AS t
		JOIN Troncons AS cpt on cpt.rowid <= NumPoints(t.geometry);

UPDATE node SET id = -ROWID;

CREATE UNIQUE INDEX i_node_id ON node (id);
SELECT RecoverGeometryColumn('node', 'point', 27567, 'POINT', 2);

SELECT id, AsText(point) FROM node;

Créer la table associative des nodes et des ways

Cette table permet de connaitre la liste des nœuds constituant chaque tronçon et cela de manière ordonnée.

On refait en gros la même sélection que précédemment, sauf que cette fois on parcourt tous les POINTs et que l'on lie chaque POINT avec son référent dans la table node. On ne garde que l'identifiant du way (qui n'est pas celui du tronçon, mais une valeur négative unique), l'identifiant du nœud trouvé dans la table node (négatif lui aussi) et donc son rang dans le LINESTRING.

Pour accélérer la requête, j'ai ajouté un index classique (non-spatial) sur la colonne point. Comme je fais une simple comparaison des représentations binaire pour retrouver mes nœuds, cela est suffisant.

Pour terminer, on ajoute un index afin de faciliter la reconstruction ultérieure des ways avec leurs nodes.

CREATE UNIQUE INDEX i_node_point ON node (point);

CREATE TABLE way_node AS
	SELECT 
		-t.ROWID AS way,
		t.PK_UID AS PK_UID,
		n.id AS node,
		cpt.rowid AS rang
		FROM Troncons AS t
		JOIN Troncons AS cpt ON cpt.rowid <= NumPoints(t.geometry)
		JOIN node AS n ON PointN(t.geometry, cpt.rowid) = n.point;

CREATE UNIQUE INDEX i_way_node_way_rang ON way_node (way, rang);

Générer une image vectorielle du filaire

Pour voir le résultat intermédiaire de ces traitement, fabriquons un fichier .SVG à partir des éléments node et way recréés à partir des tronçons.

On rédige le fichier SQL suivant (svg.sql) :

.header OFF
.separator " "
.charset UTF-8
.output "4c.svg"

select '<?xml version="1.0" encoding="utf-8"?>';
select '<?xml-stylesheet type="text/css" href="svg.css" charset="utf-8" ?>';
select '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">';
select '<svg xml:lang="fr"';
select '  xmlns="http://www.w3.org/2000/svg"';
select '  xmlns:xlink="http://www.w3.org/1999/xlink"';
select '  version="1.2" baseProfile="tiny"';
select '  viewBox="1178840 -7229888 18581 31024"';
select '>';
select '<title>4C</title>';

select 
'<path d="' || asSVG(LineFromText('LINESTRING(' || group_concat(X(n.point) || ' ' || Y(n.point)) || ')', 27567)) || '" style="stroke:blue; stroke-width: 20; fill:none;" />'
from way_nodes as wn
join node as n on n.id = wn.node
group by wn.way
order by wn.way, wn.rang;

select '</svg>';

Et on l'exécute par : spatialite db.sqlite ".read svg.sql utf-8"... et voilà ! Le résultat est en ligne.

Générer le fichier OSM

La même méthode que précédemment va générer un fichier XML au format d'OSM, avec le fichier légèrement plus complexe pour intégrer toutes les informations disponibles dans l'extraction initiale de la 4C.

Note importante : Tournez 7 fois votre souris sur son tapis, avant d'utiliser le résultat de ce fichier dans la Vraie Vie d'OSM.

Version 0.4

Les nodes, les ways + tags, plus sélection dans une BBOX d'un sous-ensemble (sans optimisation)

.header OFF
.separator " "
.charset UTF-8

-- Au cas ou, on refait l'index de la table normalisation.
CREATE UNIQUE INDEX IF NOT EXISTS  i_normalisation_NOM_VOIE ON normalisation (NOM_VOIE);

-- Création d'une vue pour simplifier la requête finale des ways.
CREATE TEMPORARY VIEW v_way AS
SELECT 
	wn.way AS id_way,
	wn.rang AS rang,
	wn.node AS id_node,
	case TRIM(t.TYPE_VOIE)
		when 'Autoroutiere' then 'motorway'
		when 'Principale' then 'primary'
		when 'Regionale' then 'secondary'
		when 'Liaison locale' then 'tertiary'
		when 'Locale' then 'unclassified'	-- unclassified ou residential, c''est toute la question !
		when 'Chemin' then 'track'		-- Ces chemins sont-ils fermés aux véhicules à moteur ?
		when 'Chemin empierre' then 'track'	-- Idem ?
		when 'Sentier' then 'path'
		when 'En construction' then 'construction'
		when 'Escalier' then 'steps'
		else 'road'
	end AS highway,
	case TRIM(t.TYPE_VOIE)
		when 'Chemin empierre' then 'paved'
		else NULL
	end AS surface,
	norm.name AS name,
	norm.ref AS ref,
	case t.SENS_VOIE
		when 'Double sens' then 'no'
		when 'Sens inverse' then '-1'
		when 'Sens unique' then 'yes'
		else NULL
	end AS oneway,
	case t.NB_VOIE
		when 4 then '2'
		else NULL
	end AS lanes,
	case t.LARG_VOIE
		when 99 then NULL
		else t.LARG_VOIE
	end AS est_width
	FROM way_node AS wn
	JOIN Troncons AS t ON wn.PK_UID = t.PK_UID
	LEFT JOIN normalisation AS norm ON norm.NOM_VOIE = t.NOM_VOIE;
	
.output "4c.osm"

SELECT '<?xml version="1.0" encoding="UTF-8"?>';
SELECT '<osm version="0.6" generator="Spatialite">';

SELECT
	'<node id="' || id ||
	'" lat="' || Y(Transform(point, 4326)) ||
	'" lon="' || X(Transform(point, 4326)) ||
	'" />'
	FROM node AS n
	WHERE	X(Transform(n.point, 4326)) between -3.86 and -3.84 AND
		Y(Transform(n.point, 4326)) between 47.785 and 47.80;	

SELECT
	'<way id="' || w.id_way || '">' AS way,
	Group_concat('<nd ref="' || w.id_node || '" />', '') AS nodes,
	'<tag k="highway" v="' || highway || '" />' AS highway,
	'<tag k="surface" v="' || surface || '" />' AS surface,
	coalesce('<tag k="name" v="' || name || '" />', '<tag k="noname" v="yes" />') AS name,
	'<tag k="ref" v="' || ref || '" />' AS ref,
	'<tag k="oneway" v="' || oneway || '" />' AS oneway,
	'<tag k="lanes" v="' || lanes || '" />' AS lanes,
	'<tag k="est_width" v="' || est_width || '" />' AS est_width,
	'<tag k="source" v="Concarneau Cornouaille - 12/2010" />' AS source,
	'</way>' AS "/way"
	FROM v_way AS w
	JOIN node AS n ON w.id_node = n.id
	WHERE	X(Transform(n.point, 4326)) between -3.86 and -3.84 AND
		Y(Transform(n.point, 4326)) between 47.785 and 47.80
	GROUP BY w.id_way
	HAVING Count(w.id_node) > 1
	ORDER BY w.id_way DESC, w.rang ASC;
	
SELECT '</osm>';

Première upload & remarques

Marc 22:17, 10 January 2011 (UTC) vient de faire faire sa première upload par Éric (car sans JOSM il se trouva fort dépourvu). J'ai centré mon test sur une zone peu remplie, où les erreurs seront donc sans grandes conséquences : à la Pointe de Trevignon. J'ai corrigé les doublons et découvert les éléments suivants dans le filaire de la 4C :

  • Entre chaque intersection il y a un tronçons (donc les ways sont courts et nécessitent peut-être d'être reconstitués) ;
  • Corolaire les ronds-points sont tronçonnés entre chaque entrée/sortie ;
  • Les ronds-points ne portent pas le tag junction=roundabout, mais à contrario on un oneway=no ;
  • Les références sont rares ;
  • Les ways highway=residential n'apparaissent pas (tout est confondu dans highway=unclassified) ;

Modifs de toponymie à faire

A l'examen, je vois des retouches à apporter aux étiquettes des voies (tirets en trop). Je le ferai quand plusd'imports auront été réalisés. --Ch. Rogel 14:01, 11 January 2011 (UTC)