> Là, je suis un peu speed, mais je peux essayer de faire une réponse un peu 
> détaillée tant que c'est chaud ce week-end (si je vais pas faire du 
> voilier...)

La bonne nouvelle, c'est qu'Eridan, à Brest, ne peut (veut?) plus louer de 
voilier pour le solo, et, tous mes acolytes marins étant indisponibles, me 
voici coincé à Paris pour le week-end, et donc je peux tâcher de donner 
quelques détails sur le "making-of" de la carte sur les emprunts toxiques. En 
particulier sur la géolocalisation, qui, comme l'a souligné Pieren, nous a 
causé quelques problèmes.

Je précise d'emblée combien je considère OSM comme un projet intéressant, à 
soutenir, à utiliser. Preuve en est que je bataille à Libé pour utiliser OSM 
chaque fois que possible. (Et c'est pas gagné d'avance...)
Et donc, s'il y a quelques critiques dans la suite de ce mail, c'est uniquement 
dans un but constructif. :)

Voici donc avec quelque détail comment nous avons procédé pour la 
géolocalisation automatiques des clients Dexia.

== Structure du fichier ==

Le fichier qu'on nous a donné à traiter en entrée était remarquablement bien 
structuré (merci Dexia, ).
Une colonne pour typer les clients (région, département, commune, communauté 
urbaine, etc.). Cette donnée se retrouve dans les "catégories de clients" de la 
carte, avec quelques regroupements (notamment dans "autres", mais pas 
seulement).

Ensuite, pour chaque ligne, concernant les données pouvant servir à la 
géolocalisation, les colonnes disponibles étaient :
- pays (systématiquement "FRANCE")
- région, en toutes lettres (ex.: "Picardie")
- code département (01, 02...)
- code postal
- ville (avec des valeurs brutes parfois un peu polluées, par exemple : "ST 
MEDARD EN JALLES CEDEX", "RENNES Cedex 9", "CHARLEVILLE MEZIERES CDX")
- adresse, avec à boire et à manger dans le champ, voici quelques exemples :
    
    - 15, RUE FRANCIADE                  C.S.3414
    - HOTEL DE VILLE                     PLACE CARNOT                       BP 
20
    - MAIRIE
    - ODARC                              19 AVENUE NOEL FRANCHINI
    - LIEU DIT CASETTA
    - SERVICES FINANCIERS                27, AVENUE IMPERATRICE-EUGENIE
    - DIR DES AFF. ECO ET FINANCIERES    BD DU GOUVERNEUR FELIX EBOUE       BP 
109
    - 8 Rue du Rh“ne
    - ECOPOLE                            ZI ET PORTUAIRE DE BOUROGNE
    - PPINIÔRES D'ENTREPRISES           LA MARE · JOUY
    - Mr XXX YYY /B 454 SPF/DEF    Bureau financement et tresorerie   3,Avenue 
Victoria
    - SOUS DIRECTION DE LA DETTE ET DU    CONTROLE EXTERNE                  
HOTEL DU DEPARTEMENT
    - 159 RUE PDF FRANCOIS MITTERAND     BP 125
    - HOTEL DU DEPARTEMENT               2  16 BOULEVARD SOUFFLOT           MMe 
XXX YYY-DGA Finances
    - 93 AVENUE F ET I JOLIOT CURIE
    - 22 AVE DU 3EME MILENAIRE           BP26
    - 22 -24 VIADUC KENNEDY              CASE OFFICIELLE No36
    - Maison de la Communaut‚            sise 2 avenue du G‚n‚ral           De 
Gaulle
    - MAISON DE REPOS ET                 DE CONVALESCENCE
    - 27Bis AllŠes Jean-JaurŠs
    - etc.

== Obstacles rencontrés ==

Notre précédente (et unique) expérience de géolocalisation automatique 
remontait à la carte sur la loi SRU. Les données pour cette carte consistaient 
"simplement" en une liste de communes, et plutôt des communes importantes 
puisque concernées par la loi SRU.

Nous avions utilisé Nominatim pour la géolocalisation automatique, et les 
résultats étaient parfaits. Mais, j'insiste, les données étaient 
particulièrement homogènes et bien cartographiées dans OSM.

Ayant cette bonne expérience de Nominatim, nous sommes partis sur la même 
piste. Mais cette fois, la bataille fut autrement plus ardue.

Notre code comporte deux parties: une partie javascript front-end exploitant 
des geojson, et une partie backend en amont générant ces geojson une bonne fois 
pour toutes.

Pour la géolocalisation, comme principe général, nous avons généré une chaîne à 
chercher par ligne du fichier, en fonction de son type. Par exemple, pour une 
région, nous n'envoyions que le nom de la région. Pour une commune, seulement 
le contenu de la colonne "Ville". Pour les organismes tels que les communautés 
de communes, les syndicats mixtes, les offices HLM, nous envoyions une chaîne 
composée avec l'adresse (nettoyée de ce qui pouvait l'être automatiquement) et 
la ville.

Voici les paramètres envoyés à Nominatim:

        params = {
            'q' : querystring,
            'format' : 'json',
            'polygon': 1,
            'addressdetails': 1,
            'countrycodes': 'fr',
            'osm_type': osm_type,
        }

Quelques premières remarques:

- querystring correspond bien évidemment à la chaîne générée en python
- 'osm_type' était défini dynamiquement selon les types de clients (comme vous 
pouvez le voir sur la carte, il y a des points pour les communes, les 
communautés urbaines, etc. et des polygons pour les régions et les 
départements).
- le paramètre "polygon", permettant d'avoir les polygonpoints d'un point, 
était envoyé en permanence, une optimisation aurait été de ne l'envoyer que 
pour les régions et les départements
- countrycodes n'a pas toujours été utilisé
- on ne le voit pas ici, mais il est arrivé dans le cas de traitements manuels 
qu'un exclude_place_ids soit précisé

A la première itération globale du script, fantastique! nous avions des points 
par centaines et des polygones sur notre carte.

En y regardant d'un peu plus près, on a vu qu'il manquait des données et que 
certaines étaient erronées.

Je vais diviser les problèmes en trois catégories: ceux concernant les 
polygones (régions et départements), ceux concernant les communes, et ceux 
concernant les clients ayant une adresse précise.

Quelle que soit la catégorie, on verra que les problèmes ont trois sources 
générales: notre inexpérience de Nominatim et OSM d'une part, des infos 
erronées dans le fichier en entrée d'autre part, des "incohérences" dans les 
données d'OSM enfin.

* Régions et départements

Comme dit plus haut, à la première itération du script, plein de départements 
et régions sont apparus sur notre carte, ce qui était plutôt bon signe.
Mais très vite, on a remarqué qu'il en manquait.

Il y avait apparemment trois types de manques:

- soit Nominatim renvoyait un polygonpoints vide (exemple: Finistère)
- soit les données renvoyées étaient verrolées (tous les départements autour 
des Charentes étaient concernés, mais aussi le Calvados ; apparemment le node 
Bénauges mettait le bazar - à l'heure où j'écris, c'est toujours le cas sur la 
vue détail de MapQuest, par exemple: 
http://open.mapquestapi.com/nominatim/v1/details.php?place_id=79143957)
- soit Nominatim ne connaissait tout simplement pas (ex.: Côtes-d'Armor)

Nous avons donc dû chercher des sources alternatives, parmi lesquelles:

- un export d'OSM en shp fait par Freed (merci !), mais malheureusement 
incomplet (l'Aquitaine ou la Corse par exemple n'avaient pas le bon polygon)
- un script permettant de parser sauvagement les pages détails de MapQuest, par 
exemple: http://open.mapquestapi.com/nominatim/v1/details.php?place_id=79266078
- pour la Corse, l'Aquitaine et Poitou-Charentes, des shp glanés sur Internet

* Communes

Là encore, l'expérience de la carte SRU nous a joué un tour: dans un premier 
temps, nous n'avions envoyé QUE le nom de la ville à Nominatim.

Le premier piège dans lequel nous sommes tombés est que le paramètre 
countrycodes: "fr" empêchait la géolocalisation de tous les points situés en 
dehors de la France métropolitaine.

Nous l'avons donc provisoirement retiré, mais alors bonjour les faux-amis. Par 
exemple, recherchez "Nice 02" (02 étant un reliquat d'un nettoyage partiel de 
"CEDEX 02") dans Nominatim, et vous verrez du pays ;) Le bled en question, aux 
Etats-Unis, est un vrai attrape-mouches avec ses rues portant le nom de villes 
françaises.

Ensuite, les nombreuses homonymies nous ont piégés, et quelques maires de 
communes pointées à tort n'étaient pas contents, et à juste titre!

A force de jouer avec Nominatim, nous avions remarqué que le display_name avait 
presque systématiquement la structure suivante (plus ou moins détaillée selon 
l'item): numéro de rue, rue, ville, département, région, pays

Ainsi, pour essayer de cibler avec plus de précision, nous avons généré une 
chaîne équivalente pour les communes (mais sans l'adresse): ville, département, 
région, France. Résultat: 100% de réussite... sauf en Bretagne! "Paimpol, 
Côtes-d'Armor, Bretagne, France" ne donne aucun résultat, alors que "Paimpol, 
Bretagne, France" donne le bon. Idem pour "Douarnenez, Finistère, Bretagne, 
France", mais là "Douarnenez, Bretagne, France" ne donne rien non plus, il faut 
mettre seulement "Douarnenez, Finistère, France" pour avoir une réponse. 
C'était le cas aussi pour quelques communes isolées hors de Bretagne, 
"Saint-Lary-Soulan", par exemple, qui ne veut pas qu'on lui accole 
"Hautes-Pyrénées".

Autre problème: certaines avaient des noms d'usage non reconnus, par exemple: 
"LE TEIL D'ARDECHE", "LA MURE D'ISERE", "OUISTREHAM RIVA-BELLA".

Parfois, l'absence d'une apostrophe donnait des mauvais résultats, par exemple 
"COURNON D AUVERGNE".

Enfin, quelques communes étaient tout simplement inconnues de notre cher 
Nominatim, par exemple: "CONNANTRE", "LINGUIZZETTA", "REAUP-LISSE", "SAINT 
LANGIS LES MORTAGNE", "SAINT-PAUL-DE-JARRAT"...

Il est à noter que les codes postaux que nous avions dans le fichier ont généré 
plus de bruit en général qu'ils nous ont été utiles, et donc rapidement nous 
les avons ignorés pour la géolocalisation. En revanche, nous les avons affichés 
sur les popups des points, sur la carte, car cela nous aidait (et les 
internautes) à repérer les erreurs en la consultant.

* Points ayant une adresse précise

Il s'agit des syndicats mixtes, communautés de communes, communautés urbaines, 
organismes de logement, etc. C'est la catégorie qui nous a donné le plus de mal.

Comme on a pu le voir plus haut, la colonne "adresse" avait des valeurs très 
polluées.

La première étape fut donc de trouver le plus de règles possibles pour les 
nettoyer automatiquement.

Néanmoins, 460 lignes ont dû être traitées à la main. "Traitées à la main", 
cela consistait à nettoyer la chaîne envoyée à Nominatim avant un nouvel envoi. 
Parfois cela revenait à corriger une faute (ajouter un "R" à "MITTERAND" par 
exemple), parfois c'était beaucoup plus laborieux, et il fallait en passer par 
une recherche internet, des essais sur Nominatim, etc. Souvent, nous avons dû 
mettre des données approchantes: par exemple, la rue d'à côté quand une rue 
n'existait pas, ou parfois même le nom du village seulement quand aucune rue 
n'était disponible. Le plus gros écueil de ce contournement est que parfois 
deux points on pu être géolocalisés au même endroit, et sont donc affichés l'un 
sur l'autre, sans pour l'instant de possibilité de les différencier, dès lors 
qu'ils sont dans la même catégorie de clients (sinon, bien sûr, il suffit de 
décocher une catégorie pour avoir accès à l'autre).

Une fois toutes ces lignes traitées à la main, nous sommes tombés dans un autre 
piège. Pour une raison que je n'explique pas, même quand on précise lors de 
l'appel à Nominatim un osm_type, la réponse contient des items de tous les 
types.
Or, selon les catégories des clients, notre script cherchait un osm_type 
précis: une "relation" pour les régions et les départements, un "node" pour les 
autres.
Sauf que, et nous ne nous en sommes rendu compte que bien tard, quand on donne 
à Nominatim un nom de rue sans lui donner de numéro, la réponse est de type 
"way", et ce même si on précise "osm_type": "node" dans l'appel (j'ai aussi 
essayé avec la valeur "N", vu que je n'ai pas bien compris le point de la doc à 
ce sujet: http://open.mapquestapi.com/nominatim/ ; remarque: la page wiki, 
elle, laisse à penser que le paramètre ne serait utile que pour le reverse: 
http://wiki.openstreetmap.org/wiki/Nominatim).

Par conséquent, de nombreux points étaient ignorés par le script, qui attendait 
des "node", mais ne trouvait que des "way". N'ayant pas anticipé ce point, ces 
erreurs n'étaient pas mises au jour par le script. Et nous avons mis un peu de 
temps à nous en rendre compte.

La géolocalisation des adresses est, comme je disais, ce qui a coûté le plus de 
temps de contournement. Voici quelques exemples où l'on aurait pu attendre une 
réponse de Nominatim:

- "BOULEVARD DE LATTRE DE TASSIGNY TARBES", il faut ajouter "DU GENERAL" pour 
avoir une réponse => "BOULEVARD DU GENERAL DE LATTRE DE TASSIGNY TARBES"
- "42, CHEMIN POURPIER, SAINT-PAUL" => "42, CHEMIN DU GRAND POURPIER, 
SAINT-PAUL"
- "16 AVENUE GEORGE LEVY, VENISSIEUX" => "16, AVENUE DU DOCTEUR GEORGES LEVY, 
VENISSIEUX"
- "28/32 RUE DU XXE CORPS AMERICAIN METZ" => "28/32 AVENUE DU XXE CORPS 
AMERICAIN METZ"
- "rue du 12eme arrondissement MORTAIN" => "rue du XIIeme arrondissement 
MORTAIN"

Il y a aussi des erreurs parfois, par exemple "BOULEVARD SALVATOR ALLENDE", à 
SAINT-HERBAIN, au lieu de SalvaDor.

Ajoutons à ça, donc, un grand nombre de rue tout simplement pas encore 
cartographiées.


Malheureusement, on n'a pas noté systématiquement, lors de nos traitements 
manuels, pourquoi telle ou telle adresse avait posé problème. Et donc je ne 
cite ici que quelques exemples de mémoire. Je ne sais pas si ça peut aider, 
mais je dois pouvoir mettre à disposition les adresses en question, dans un 
fichier brut.


== Bilan ==

Rapidement:

- 5500 lignes à traiter, ça donne forcément un nombre de cas particuliers 
élevé...

- si c'était à refaire, je pense que je partirais plutôt sur la piste 
d'installer un PostgreSQL avec les données OSM de la France en local (avec ma 
propre indexation) plutôt que d'interroger Nominatim ; mais peut-être que 
j'aurais dit l'inverse si j'avais suivi cette option ;) Par ailleurs, 
maintenant que j'ai en local toutes les coordonnées des départements, des 
régions, et de milliers de ville, je ne partirai pas de zéro la prochaine 
fois...

- tout le monde a été très content du résultat à Libé, mais je dois dire que 
quand je vais voir le journaliste en lui disant: "ahem, il me reste 460 points 
à traiter à la main, on fait moit'-moit' ?" et qu'il me répond "Euh, mais 
Google, il les trouve, lui?", je sais que je perds quelques points ;)

- rien à voir avec la géolocalisation, mais clairement on a perdu pas mal de 
temps et de cheveux dans les méandres d'OpenLayers, dont la documentation et 
l'API sont certainement sponsorisés par les laboratoires Servier, ou au moins 
par un marchant d'aspirine. J'attendais que Leaflet gère le geojson pour 
envisager de l'utiliser, c'est maintenant chose faite, et je crois que je suis 
mûr pour faire l'expérience lors de notre prochaine carte ; voire pour Chimère, 
sur lequel nous avons commencé à travailler 
(https://gitorious.org/~yohanboniface/chimere/djangoize/commits/refactoring), 
pour l'instant surtout moi pour un projet perso 
(http://epicures.enix.org:8000/), mais comme souvent c'est en éclaireur d'une 
utilisation au boulot plus tard.


D'avance merci pour vos remarques !

Yohan, marin à terre

_______________________________________________
Talk-fr mailing list
[email protected]
http://lists.openstreetmap.org/listinfo/talk-fr

Répondre à