Un pilote : Orléans Métropole

Cette sous-partie explique le processus de mise en place du prototype de l'algorithme. d'audit.

La situation d'Orléans

La métropole d'Orléans dispose d'un jeu de données de stationnements vélo assez dense. Il est mis en Open Data et recense 626 stationnements. De même, OpenStreetMap recense à cette date 402 places, ce qui fait d'Orléans Métropole un très bon terrain d'expérimentation pour l'audit de données.

L'algorithme d'audit

Le choix d'un algorithme en langage Python s'impose en raison du traitement possible directement sur des tableurs Excel.

L'objectif est concaténer les lignes dont les coordonnées de longitude et latitude ont une valeur proche (plus ou moins à 15 mètres de différence en valeur). Ainsi, si une ligne (un stationnement) avec des coodonnées de longitude et latitude dans le jeu de données de la collectivité rencontre une ligne similaire dans le jeu de données OpenStreetMap, les deux lignes se compléteront automatiquement.

Ci-dessous, les versions expérimentales de l'algorithme crée à partir du jeu de données officielles de la métropole d'Orléans, et du jeu de données OpenStreetMap. Des commentaires figurent sur l'algorithme pour expliquer les démarches.

Algorithme intégrant uniquement les données optimisées

import pandas as pd
from geopy.distance import geodesic # pour calculer la distance entre deux coordonnées


osm=pd.read_excel("C:/Users/lamranay/Desktop/OrleansOSM.xlsx") #fichier xl
ct=pd.read_excel("C:/Users/lamranay/Desktop/OrleansCT.xlsx")


osm['latitude'] = osm['latitude'].astype(str) #transformer en chaine de caracteres pour garder le plus d'info possible eviter les arrondis
osm['longitude'] = osm['longitude'].astype(str)
ct['longitude'] = ct['longitude'].astype(str)
ct['latitude'] = ct['latitude'].astype(str)

new_df=pd.DataFrame([],columns=[])

for i in range(len(ct)):

    ct_city=(ct['latitude'][i], ct['longitude'][i]) # coordonnées issues de ct

    for j in range(len(osm)):

        osm_city=(osm['latitude'][j], osm['longitude'][j]) # coordonnées issues de osm

        if(geodesic(ct_city,osm_city).miles <=  0.009):# changer pour augementer la distance; 0.009 miles = 15 m

            cap=ct['Nombre de places'][i]
            if(pd.isnull(cap)):
              cap=osm['capacity'][j]

            covered=ct['Couverture'][i]
            if(pd.isnull(covered)):
              covered=osm['covered'][j]

            new_df = new_df.append({'Latitude' : osm['latitude'][j] , 'Longitude' : osm['longitude'][j], 'Commune' : ct['Commune'][i], 'Code INSEE': ct['Code INSEE'][i], 'Rue':ct['Rue'][i],'Capacité' : cap,'Couvert': covered,'Type':ct['Type'][i],'Geo shape': ct['geo_shape'][i],'Date' : ct['Maj'][i],'Num':ct['Numero'][i],'id':osm['@id'][j]}, ignore_index=True)
            print(geodesic(ct_city,osm_city).miles)
i=0
for i in range(len(ct)):
    if(ct['Numero'][i] in new_df['Num']):
        pass
    else:
        new_df = new_df.append({'Latitude' : ct['latitude'][i] , 'Longitude' : ct['longitude'][i], 'Commune' : ct['Commune'][i], 'Code INSEE': ct['Code INSEE'][i], 'Rue':ct['Rue'][i],'Capacité' : ct['Nombre de places'][i],'Couvert': ct['Couverture'][i],'Type':ct['Type'][i],'Geo shape': ct['geo_shape'][i],'Date' : ct['Maj'][i]}, ignore_index=True)

i=0
for i in range(len(osm)):
    if(osm['@id'][i] in new_df['id']):
        pass
    else:
        new_df = new_df.append({'Latitude' : osm['latitude'][i] , 'Longitude' : osm['longitude'][i],'Capacité' : osm['capacity'][i],'Couvert': osm['covered'][i],'Type':osm['bicycle_parking'][i]}, ignore_index=True)



new_df=new_df.drop("id",axis=1)
new_df=new_df.drop("Num",axis=1)



new_df.to_excel(r'C:/Users/lamranay/Desktop/Orleans_CT_OSM.xlsx') # à changer pour stocker le fichier ailleurs ou modifier le nom du fichier

Le programme sur Python a la capacité de travailler sur des jeux de données en ligne, à l'avenir, il sera possible de réaliser l'audit de données directement via les données disponibles sur transport.data.gouv.

Algorithme intégrant les données optimisées et les données ne pouvant pas être croisées

Un second algorithme a été pensé lors de la phase de test. Celui-ci permet de conserver les données de source OpenStreetMap ou officielle, ne présentant pas de cohérence l'une avec l'autre. Ainsi, la concaténation s'opère mais ne permet pas de compléter toutes les lignes. L'algorithme ainsi que le fichier obtenu se trouvent ci dessous

import pandas as pd

osm=pd.read_excel("/Users/*****/Desktop/OrleansOSM.xlsx") #fichier xl
ct=pd.read_excel("/Users/*****/Desktop/OrleansCT.xlsx")


osm['latitude'] = osm['latitude'].astype(str) #transformer en chaine de charcter pour garder le plus d'info possible eviter les arrondis
osm['longitude'] = osm['longitude'].astype(str)
ct['longitude'] = ct['longitude'].astype(str)
ct['latitude'] = ct['latitude'].astype(str)

from geopy.distance import geodesic # pour calculer la distance entre deux coordonnées
new_df=pd.DataFrame([],columns=[])

for i in range(len(ct)):
    ct_city=(ct['latitude'][i], ct['longitude'][i]) # coordonnées issues de ct
    for j in range(len(osm)):
        osm_city=(osm['latitude'][j], osm['longitude'][j]) # coordonnées issues de osm
        if(geodesic(ct_city,osm_city).miles <=  0.003):# changer pour augementer la distance
            cap=ct['Nombre de places'][i]
            if(pd.isnull(osm['capacity'][j])):
              cap=ct['Nombre de places'][i]

            covered=ct['Couverture'][i]
            if(pd.isnull(osm['covered'][j])):
                 covered=osm['covered'][j]
            new_df = new_df.append({'Latitude' : osm['latitude'][j] , 'Longitude' : osm['longitude'][j], 'Commune' : ct['Commune'][i], 'Code INSEE': ct['Code INSEE'][i], 'Rue':ct['Rue'][i],'Capacité' : cap,'Couvert': covered,'Type':ct['Type'][i],'Geo shape': ct['geo_shape'][i],'Date' : ct['Maj'][i]}, ignore_index=True)
            print(geodesic(ct_city,osm_city).miles)

new_df.to_excel(r'/Users/*****/Desktop/Orleans.xlsx') # à changer pour stocker le fichier ailleurs

Les points bloquants pour la réplicabilité

  • Les colonnes des fichiers du jeu de données des collectivités territoriales ne suivent pas le même format donc l’audit est difficilement réplicable en ce sens. Il est cependant possible de créer un dictionnaire de valeurs ou une commande de changement automatique de nom de colonnes. Par exemple : mis à jour, date, date d’ajout, horodateur, etc ont plus ou moins le même objectif. Le dictionnaire transformerait ces mots en « Date », par référence à la colonne du fichier national.

  • On ne garde que les points d’une distance inférieure à 15 mètres, l’approximation permet d'éliminer les doublons. Cependant cette valeur ne permet pas de réunir tous les doublons. Le curseur de cette distance minimale est à faire varier en fonction des spécificités de la donnée. Le point de tension est de ne pas trop l'augmenter pour éviter d'approximer des points qui ne doivent pas l'être, ni de trop le diminuer au risque de conserver de nombreux doublons.

  • Il n'est pas possible de garder la source de la donnée (si elle vient d'OpenStreetMap ou de la colectivité) puisque c’est la ligne obtenue par le produit des deux précédentes.

  • Le programme actuel n’intègre pas encore la prise en compte des données n’étant présente que sur OpenStreetMap ou que sur le jeu de données de la collectivité territoriale.

Last updated