Extraction de parcours de bus OSM en JsonGraph


In [1]:
import requests
import json

In [2]:
lines_metadata = {}
stops_by_lines = {}
stops = []

In [3]:
network = "RTUD"
operator = "RTUD"
overpass_base_url = "http://overpass-api.de/api/interpreter?data="

overpass_query_lines = """
    [out:json];
    (relation["type"="route"]["network"="{}"]["operator"="{}"];)->.a;
    relation(br)["type"="route_master"];
    out meta;""".format(network, operator)

get_lines = requests.get(overpass_base_url + overpass_query_lines)
if not get_lines.status_code == 200 :
    print ("erreur à l'appel d'Overpass pour récupérer les lignes")
    exit
    
lines = get_lines.json()['elements']

In [4]:
routes_id = {}

for a_line in lines :
    lines_metadata[a_line['id']]=a_line['tags']
    routes_id[a_line['id']] = a_line["members"][0]['ref'] #for now, we only inspect one route of each line

In [5]:
def get_overpass_query_for_stops(route_id):
    return """ [out:json];relation({});(._;>;);out;""".format(route_id)


for a_line_id, a_route_id in routes_id.items() :
    get_route = requests.get(overpass_base_url + get_overpass_query_for_stops(a_route_id))
    if not get_route.status_code == 200:
        break
    all_info = get_route.json()['elements']
    route_info = [elem for elem in all_info if elem['type']=='relation']
    route_members = route_info[0]['members']
    route_stops = [elem for elem in route_members if elem['role']=='platform' and elem['type']=='node']
    stop_list_ids = [elem['ref'] for elem in route_stops]
    stops_by_lines[a_line_id] = stop_list_ids
    stop_info = [elem for elem in all_info if elem["id"] in stop_list_ids]
    stops += stop_info
    

    
print (stops_by_lines)
print (stops)


{6941657: [], 6932554: [4822825493, 4822825492, 4822825491, 4822825490, 4822825486, 4822825484, 4822825482, 4822825481, 4822825480, 4822825479, 4822825478, 4822825628, 4822825477, 4822825475, 4822825474, 4822825473, 4822825471, 4822825470, 4822825467, 4822825466, 2155045951, 4430659470, 4822825476, 4822825495], 6937875: [5300752876, 5300752879, 5300752877, 4822825473, 4822825626, 4822825458, 4822825508, 4822825456], 6937499: [], 7835159: [4822825456, 5300791450, 5300791451, 4822825483, 4822825485, 4822825489, 4822825454, 4822825493, 4822825490, 4822825480]}
[{'id': 4822825456, 'tags': {'bench': 'yes', 'bus': 'yes', 'wheelchair': 'yes', 'name': 'Charles de Gaulle', 'public_transport': 'platform', 'shelter': 'yes', 'highway': 'bus_stop'}, 'lat': 44.0931619, 'lon': 6.2355234, 'type': 'node'}, {'id': 4822825458, 'tags': {'public_transport': 'platform', 'bus': 'yes', 'wheelchair': 'yes', 'highway': 'bus_stop', 'name': 'Rond-Point du 4 Septembre 1970'}, 'lat': 44.0893608, 'lon': 6.2270895, 'type': 'node'}, {'id': 4822825473, 'tags': {'wheelchair': 'yes', 'bus': 'yes', 'highway': 'bus_stop', 'public_transport': 'platform', 'survey:date': '2017-07-26', 'shelter': 'yes', 'name': 'Georges Pompidou'}, 'lat': 44.085788, 'lon': 6.215886, 'type': 'node'}, {'id': 4822825508, 'tags': {'wheelchair': 'yes', 'bus': 'yes', 'highway': 'bus_stop', 'public_transport': 'platform', 'tactile_paving': 'yes', 'shelter': 'no', 'name': 'Pierre Gassendi'}, 'lat': 44.0903636, 'lon': 6.2308899, 'type': 'node'}, {'id': 4822825626, 'tags': {'public_transport': 'platform', 'bus': 'yes', 'wheelchair': 'yes', 'highway': 'bus_stop', 'name': 'Les Arcades'}, 'lat': 44.0879891, 'lon': 6.2208534, 'type': 'node'}, {'id': 5300752876, 'tags': {'public_transport': 'platform', 'bus': 'yes', 'highway': 'bus_stop', 'name': 'Le Moulin'}, 'lat': 44.0803118, 'lon': 6.208642, 'type': 'node'}, {'id': 5300752877, 'tags': {'public_transport': 'platform', 'bus': 'yes', 'wheelchair': 'yes', 'highway': 'bus_stop', 'name': 'Chemin du Marquis'}, 'lat': 44.0819127, 'lon': 6.2153388, 'type': 'node'}, {'id': 5300752879, 'tags': {'public_transport': 'platform', 'bus': 'yes', 'wheelchair': 'yes', 'highway': 'bus_stop', 'name': 'Chemin du Moulin'}, 'lat': 44.080952, 'lon': 6.2114053, 'type': 'node'}, {'id': 2155045951, 'tags': {'wheelchair': 'yes', 'bus': 'yes', 'name': 'Lycée Pierre-Gilles de Gennes', 'public_transport': 'platform', 'survey:date': '2017-06-29', 'highway': 'bus_stop', 'network': 'TUD'}, 'lat': 44.0727314, 'lon': 6.1808373, 'type': 'node'}, {'id': 4430659470, 'tags': {'bench': 'yes', 'bus': 'yes', 'wheelchair': 'yes', 'name': 'Digne-les-Bains - Centre Hospitalier', 'public_transport': 'platform', 'shelter': 'yes', 'highway': 'bus_stop', 'network': 'TUD'}, 'lat': 44.0704794, 'lon': 6.1779864, 'type': 'node'}, {'id': 4822825466, 'tags': {'public_transport': 'platform', 'bus': 'yes', 'highway': 'bus_stop', 'network': 'TUD/LER', 'name': 'Digne-les-Bains - Centre Technique'}, 'lat': 44.0764315, 'lon': 6.1854896, 'type': 'node'}, {'id': 4822825467, 'tags': {'wheelchair': 'yes', 'bus': 'yes', 'name': 'Centre Commercial', 'public_transport': 'platform', 'highway': 'bus_stop', 'network': 'TUD'}, 'lat': 44.0765987, 'lon': 6.1882807, 'type': 'node'}, {'id': 4822825470, 'tags': {'public_transport': 'platform', 'bus': 'yes', 'wheelchair': 'yes', 'highway': 'bus_stop', 'name': 'Les Alpilles'}, 'lat': 44.0838055, 'lon': 6.2049399, 'type': 'node'}, {'id': 4822825471, 'tags': {'bench': 'yes', 'bus': 'yes', 'wheelchair': 'yes', 'name': 'Les Baumelles', 'public_transport': 'platform', 'shelter': 'yes', 'highway': 'bus_stop', 'network': 'RTUD'}, 'lat': 44.0850029, 'lon': 6.2086473, 'type': 'node'}, {'id': 4822825473, 'tags': {'wheelchair': 'yes', 'bus': 'yes', 'highway': 'bus_stop', 'public_transport': 'platform', 'survey:date': '2017-07-26', 'shelter': 'yes', 'name': 'Georges Pompidou'}, 'lat': 44.085788, 'lon': 6.215886, 'type': 'node'}, {'id': 4822825474, 'tags': {'public_transport': 'platform', 'bus': 'yes', 'wheelchair': 'yes', 'highway': 'bus_stop', 'name': 'Centre de Secours'}, 'lat': 44.0835314, 'lon': 6.217903, 'type': 'node'}, {'id': 4822825475, 'tags': {'public_transport': 'platform', 'bus': 'yes', 'wheelchair': 'yes', 'highway': 'bus_stop', 'name': 'La Sèbe'}, 'lat': 44.0862439, 'lon': 6.2233432, 'type': 'node'}, {'id': 4822825476, 'tags': {'wheelchair': 'yes', 'bus': 'yes', 'name': 'La Paix', 'public_transport': 'platform', 'highway': 'bus_stop', 'network': 'RTUD'}, 'lat': 44.0740949, 'lon': 6.1773745, 'type': 'node'}, {'id': 4822825477, 'tags': {'wheelchair': 'yes', 'bus': 'yes', 'name': 'Rond-Point du 4 Septembre 1970', 'public_transport': 'platform', 'highway': 'bus_stop', 'network': 'TUD'}, 'lat': 44.0890233, 'lon': 6.2258232, 'type': 'node'}, {'id': 4822825478, 'tags': {'bench': 'yes', 'bus': 'yes', 'name': 'Digne − Gare Routière', 'public_transport': 'platform', 'wheelchair': 'yes', 'highway': 'bus_stop'}, 'lat': 44.0915068, 'lon': 6.2310985, 'type': 'node'}, {'id': 4822825479, 'tags': {'wheelchair': 'yes', 'bus': 'yes', 'highway': 'bus_stop', 'public_transport': 'platform', 'tactile_paving': 'no', 'name': 'Tampinet'}, 'lat': 44.092178, 'lon': 6.2310304, 'type': 'node'}, {'id': 4822825480, 'tags': {'public_transport': 'platform', 'bus': 'yes', 'wheelchair': 'limited', 'highway': 'bus_stop', 'name': 'Hôtel de Ville'}, 'lat': 44.0931829, 'lon': 6.2352823, 'type': 'node'}, {'id': 4822825481, 'tags': {'public_transport': 'platform', 'bus': 'yes', 'wheelchair': 'yes', 'highway': 'bus_stop', 'name': 'Maria Borrély'}, 'lat': 44.0940213, 'lon': 6.237241, 'type': 'node'}, {'id': 4822825482, 'tags': {'public_transport': 'platform', 'bus': 'yes', 'wheelchair': 'yes', 'highway': 'bus_stop', 'name': 'Chemin du Bourg'}, 'lat': 44.0955672, 'lon': 6.2414541, 'type': 'node'}, {'id': 4822825484, 'tags': {'public_transport': 'platform', 'bus': 'yes', 'wheelchair': 'yes', 'highway': 'bus_stop', 'name': 'Notre-Dame du Bourg / Crypte'}, 'lat': 44.0967365, 'lon': 6.2422869, 'type': 'node'}, {'id': 4822825486, 'tags': {'public_transport': 'platform', 'bus': 'yes', 'highway': 'bus_stop', 'name': 'Parc Mexico'}, 'lat': 44.0960616, 'lon': 6.2377694, 'type': 'node'}, {'id': 4822825490, 'tags': {'public_transport': 'platform', 'bus': 'yes', 'wheelchair': 'yes', 'highway': 'bus_stop', 'name': 'Alphonse Richard'}, 'lat': 44.0956019, 'lon': 6.2349612, 'type': 'node'}, {'id': 4822825491, 'tags': {'public_transport': 'platform', 'bus': 'yes', 'highway': 'bus_stop', 'name': 'Victor Hugo'}, 'lat': 44.1001762, 'lon': 6.2315132, 'type': 'node'}, {'id': 4822825492, 'tags': {'bus': 'yes', 'highway': 'bus_stop', 'public_transport': 'platform'}, 'lat': 44.1021481, 'lon': 6.231131, 'type': 'node'}, {'id': 4822825493, 'tags': {'public_transport': 'platform', 'bus': 'yes', 'wheelchair': 'yes', 'highway': 'bus_stop', 'name': 'Novellini/A. David-Neel'}, 'lat': 44.1015965, 'lon': 6.2336918, 'type': 'node'}, {'id': 4822825495, 'tags': {'public_transport': 'platform', 'bus': 'yes', 'wheelchair': 'yes', 'highway': 'bus_stop', 'name': 'Les Augiers'}, 'lat': 44.0805642, 'lon': 6.17436, 'type': 'node'}, {'id': 4822825628, 'tags': {'wheelchair': 'yes', 'bus': 'yes', 'highway': 'bus_stop', 'public_transport': 'platform', 'survey:date': '2017-08-28', 'tactile_paving': 'no', 'shelter': 'no', 'name': 'La Gineste'}, 'lat': 44.0910711, 'lon': 6.2286063, 'type': 'node'}, {'id': 4822825454, 'tags': {'public_transport': 'platform', 'bus': 'yes', 'wheelchair': 'yes', 'highway': 'bus_stop', 'name': 'Novellini/A. David-Neel'}, 'lat': 44.1015455, 'lon': 6.2335912, 'type': 'node'}, {'id': 4822825456, 'tags': {'bench': 'yes', 'bus': 'yes', 'wheelchair': 'yes', 'name': 'Charles de Gaulle', 'public_transport': 'platform', 'shelter': 'yes', 'highway': 'bus_stop'}, 'lat': 44.0931619, 'lon': 6.2355234, 'type': 'node'}, {'id': 4822825480, 'tags': {'public_transport': 'platform', 'bus': 'yes', 'wheelchair': 'limited', 'highway': 'bus_stop', 'name': 'Hôtel de Ville'}, 'lat': 44.0931829, 'lon': 6.2352823, 'type': 'node'}, {'id': 4822825483, 'tags': {'public_transport': 'platform', 'bus': 'yes', 'wheelchair': 'yes', 'highway': 'bus_stop', 'name': 'Notre-Dame du Bourg / Crypte'}, 'lat': 44.0969397, 'lon': 6.2422179, 'type': 'node'}, {'id': 4822825485, 'tags': {'public_transport': 'platform', 'bus': 'yes', 'highway': 'bus_stop', 'name': 'Parc Mexico'}, 'lat': 44.0960914, 'lon': 6.2376186, 'type': 'node'}, {'id': 4822825489, 'tags': {'public_transport': 'platform', 'bus': 'yes', 'wheelchair': 'yes', 'highway': 'bus_stop', 'name': 'Alphonse Richard'}, 'lat': 44.0957743, 'lon': 6.2349819, 'type': 'node'}, {'id': 4822825490, 'tags': {'public_transport': 'platform', 'bus': 'yes', 'wheelchair': 'yes', 'highway': 'bus_stop', 'name': 'Alphonse Richard'}, 'lat': 44.0956019, 'lon': 6.2349612, 'type': 'node'}, {'id': 4822825493, 'tags': {'public_transport': 'platform', 'bus': 'yes', 'wheelchair': 'yes', 'highway': 'bus_stop', 'name': 'Novellini/A. David-Neel'}, 'lat': 44.1015965, 'lon': 6.2336918, 'type': 'node'}, {'id': 5300791450, 'tags': {'public_transport': 'platform', 'bus': 'yes', 'highway': 'bus_stop', 'name': 'Camping Tennis'}, 'lat': 44.100299, 'lon': 6.2495296, 'type': 'node'}, {'id': 5300791451, 'tags': {'bench': 'yes', 'bus': 'yes', 'wheelchair': 'yes', 'name': 'Les Truyas', 'public_transport': 'platform', 'shelter': 'yes', 'highway': 'bus_stop'}, 'lat': 44.1028367, 'lon': 6.2527958, 'type': 'node'}]

In [6]:
nodes = []

for stop in stops:
    stop_name = ""
    if 'name' in stop['tags']:
        stop_name = stop['tags']['name']
    nodes.append({
        "id": stop['id'],
        "lat" : stop['lat'],
        "lon" : stop['lon'],
        "label": stop_name} )

nodes


Out[6]:
[{'id': 4822825456,
  'label': 'Charles de Gaulle',
  'lat': 44.0931619,
  'lon': 6.2355234},
 {'id': 4822825458,
  'label': 'Rond-Point du 4 Septembre 1970',
  'lat': 44.0893608,
  'lon': 6.2270895},
 {'id': 4822825473,
  'label': 'Georges Pompidou',
  'lat': 44.085788,
  'lon': 6.215886},
 {'id': 4822825508,
  'label': 'Pierre Gassendi',
  'lat': 44.0903636,
  'lon': 6.2308899},
 {'id': 4822825626,
  'label': 'Les Arcades',
  'lat': 44.0879891,
  'lon': 6.2208534},
 {'id': 5300752876, 'label': 'Le Moulin', 'lat': 44.0803118, 'lon': 6.208642},
 {'id': 5300752877,
  'label': 'Chemin du Marquis',
  'lat': 44.0819127,
  'lon': 6.2153388},
 {'id': 5300752879,
  'label': 'Chemin du Moulin',
  'lat': 44.080952,
  'lon': 6.2114053},
 {'id': 2155045951,
  'label': 'Lycée Pierre-Gilles de Gennes',
  'lat': 44.0727314,
  'lon': 6.1808373},
 {'id': 4430659470,
  'label': 'Digne-les-Bains - Centre Hospitalier',
  'lat': 44.0704794,
  'lon': 6.1779864},
 {'id': 4822825466,
  'label': 'Digne-les-Bains - Centre Technique',
  'lat': 44.0764315,
  'lon': 6.1854896},
 {'id': 4822825467,
  'label': 'Centre Commercial',
  'lat': 44.0765987,
  'lon': 6.1882807},
 {'id': 4822825470,
  'label': 'Les Alpilles',
  'lat': 44.0838055,
  'lon': 6.2049399},
 {'id': 4822825471,
  'label': 'Les Baumelles',
  'lat': 44.0850029,
  'lon': 6.2086473},
 {'id': 4822825473,
  'label': 'Georges Pompidou',
  'lat': 44.085788,
  'lon': 6.215886},
 {'id': 4822825474,
  'label': 'Centre de Secours',
  'lat': 44.0835314,
  'lon': 6.217903},
 {'id': 4822825475, 'label': 'La Sèbe', 'lat': 44.0862439, 'lon': 6.2233432},
 {'id': 4822825476, 'label': 'La Paix', 'lat': 44.0740949, 'lon': 6.1773745},
 {'id': 4822825477,
  'label': 'Rond-Point du 4 Septembre 1970',
  'lat': 44.0890233,
  'lon': 6.2258232},
 {'id': 4822825478,
  'label': 'Digne − Gare Routière',
  'lat': 44.0915068,
  'lon': 6.2310985},
 {'id': 4822825479, 'label': 'Tampinet', 'lat': 44.092178, 'lon': 6.2310304},
 {'id': 4822825480,
  'label': 'Hôtel de Ville',
  'lat': 44.0931829,
  'lon': 6.2352823},
 {'id': 4822825481,
  'label': 'Maria Borrély',
  'lat': 44.0940213,
  'lon': 6.237241},
 {'id': 4822825482,
  'label': 'Chemin du Bourg',
  'lat': 44.0955672,
  'lon': 6.2414541},
 {'id': 4822825484,
  'label': 'Notre-Dame du Bourg / Crypte',
  'lat': 44.0967365,
  'lon': 6.2422869},
 {'id': 4822825486,
  'label': 'Parc Mexico',
  'lat': 44.0960616,
  'lon': 6.2377694},
 {'id': 4822825490,
  'label': 'Alphonse Richard',
  'lat': 44.0956019,
  'lon': 6.2349612},
 {'id': 4822825491,
  'label': 'Victor Hugo',
  'lat': 44.1001762,
  'lon': 6.2315132},
 {'id': 4822825492, 'label': '', 'lat': 44.1021481, 'lon': 6.231131},
 {'id': 4822825493,
  'label': 'Novellini/A. David-Neel',
  'lat': 44.1015965,
  'lon': 6.2336918},
 {'id': 4822825495, 'label': 'Les Augiers', 'lat': 44.0805642, 'lon': 6.17436},
 {'id': 4822825628,
  'label': 'La Gineste',
  'lat': 44.0910711,
  'lon': 6.2286063},
 {'id': 4822825454,
  'label': 'Novellini/A. David-Neel',
  'lat': 44.1015455,
  'lon': 6.2335912},
 {'id': 4822825456,
  'label': 'Charles de Gaulle',
  'lat': 44.0931619,
  'lon': 6.2355234},
 {'id': 4822825480,
  'label': 'Hôtel de Ville',
  'lat': 44.0931829,
  'lon': 6.2352823},
 {'id': 4822825483,
  'label': 'Notre-Dame du Bourg / Crypte',
  'lat': 44.0969397,
  'lon': 6.2422179},
 {'id': 4822825485,
  'label': 'Parc Mexico',
  'lat': 44.0960914,
  'lon': 6.2376186},
 {'id': 4822825489,
  'label': 'Alphonse Richard',
  'lat': 44.0957743,
  'lon': 6.2349819},
 {'id': 4822825490,
  'label': 'Alphonse Richard',
  'lat': 44.0956019,
  'lon': 6.2349612},
 {'id': 4822825493,
  'label': 'Novellini/A. David-Neel',
  'lat': 44.1015965,
  'lon': 6.2336918},
 {'id': 5300791450,
  'label': 'Camping Tennis',
  'lat': 44.100299,
  'lon': 6.2495296},
 {'id': 5300791451,
  'label': 'Les Truyas',
  'lat': 44.1028367,
  'lon': 6.2527958}]

In [7]:
edges = []

for line in stops_by_lines:
    stops = stops_by_lines[line]

    for i in range(len(stops) -1 ):
        current_edge = {"relation":"bus"}
        current_edge["metadata"] = lines_metadata[line]
        current_edge["source"] = stops[i]
        current_edge["target"] = stops[i+1]
        edges.append(current_edge)

len(edges)


Out[7]:
39

In [8]:
with open("edges.json", "w") as edges_files :
    json.dump(edges, edges_files, indent=1, sort_keys=True)

with open("nodes.json", "w") as nodes_files :
    json.dump(nodes, nodes_files, indent=0)

In [9]:
stops_by_lines


Out[9]:
{6932554: [4822825493,
  4822825492,
  4822825491,
  4822825490,
  4822825486,
  4822825484,
  4822825482,
  4822825481,
  4822825480,
  4822825479,
  4822825478,
  4822825628,
  4822825477,
  4822825475,
  4822825474,
  4822825473,
  4822825471,
  4822825470,
  4822825467,
  4822825466,
  2155045951,
  4430659470,
  4822825476,
  4822825495],
 6937499: [],
 6937875: [5300752876,
  5300752879,
  5300752877,
  4822825473,
  4822825626,
  4822825458,
  4822825508,
  4822825456],
 6941657: [],
 7835159: [4822825456,
  5300791450,
  5300791451,
  4822825483,
  4822825485,
  4822825489,
  4822825454,
  4822825493,
  4822825490,
  4822825480]}