-
Notifications
You must be signed in to change notification settings - Fork 0
/
GTFS-All2Utrecht.py
129 lines (106 loc) · 4.09 KB
/
GTFS-All2Utrecht.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import pandas as pd
import geopandas as gpd
import numpy as np
import urllib
import json
import csv
import zipfile
import sys
import matplotlib.pyplot as plt
from geopandas.tools import sjoin
from shapely.geometry import LineString, Point
with zipfile.ZipFile('gtfs-nl.zip') as z:
with z.open('stops.txt') as f:
routes = pd.read_csv(f)
routes = routes[['stop_lat', 'stop_lon']]
routes['Date'] = '03/17/2021'
routes['Time'] = '04:00PM'
routes['utc_lat'] = '52.088208'
routes['utc_lon'] = '5.113234'
routes = routes[['Date', 'Time', 'utc_lat', 'utc_lon', 'stop_lat', 'stop_lon']]
routes = routes.drop_duplicates()
routes['point'] = routes.apply(lambda x: Point(x.stop_lon, x.stop_lat), axis=1)
routes = gpd.GeoDataFrame(routes, geometry=routes['point']).set_crs("EPSG:4326")
world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))
nl = world[world.name == "Netherlands"]
routes = sjoin(routes, nl, how='left')
routes = routes[routes.name == 'Netherlands']
URL = 'http://localhost:8080/otp/routers/default/plan?'
legs = []
def get_value(obj, lvl1, lvl2=None):
res = None;
if obj and (lvl1 in obj):
res = obj[lvl1]
if res and lvl2:
if (lvl2 in res):
res = res[lvl2]
else:
res = None
return res
# Takes CSV input, creates URLs, stores data locally in row array
for c, d in routes.iterrows():
print(str(c) + ' / ' + str(len(routes)))
params = {'date': d['Date'],
'time': d['Time'],
'fromPlace': '%s,%s' % (d['stop_lat'], d['stop_lon']),
'toPlace': '%s,%s' % (d['utc_lat'], d['utc_lon']),
'maxWalkDistance': 2000,
'mode': 'WALK,TRANSIT',
'numItineraries': 1,
'arriveBy': 'false'}
req = urllib.request.Request(URL + urllib.parse.urlencode(params))
req.add_header('Accept', 'application/json')
response = urllib.request.urlopen(req)
trip = json.loads(response.read())
itineraries = get_value(trip, 'plan', 'itineraries')
if itineraries and len(itineraries) > 0:
try:
for leg in itineraries[0]['legs']:
mode = get_value(leg, 'mode')
if mode != 'WALK':
legs.append([mode, leg['legGeometry']['points']])
except:
print('Error routing')
legs_df = pd.DataFrame(legs)
legs_df.columns = ['mode', 'geometryPoints']
legs_df = legs_df.groupby(['geometryPoints']).count().reset_index().rename(columns={'mode': 'count'}).sort_values('count')
def pop_val(datastring, index):
b = None
res = shift = 0
while b is None or b >= 0x20:
b = ord(datastring[index]) - 63
res |= ( (b & 0x1f) << shift )
index += 1
shift += 5
if res & 1:
return ~(res >> 1), index
return (res >> 1), index
def decode(datastring):
coordinates = []
lat = lon = 0
idx = 0
while idx < len(datastring):
delta_lat, idx = pop_val(datastring, idx)
delta_lon, idx = pop_val(datastring, idx)
lat += delta_lat / 100000.0
lon += delta_lon / 100000.0
coordinates.append((lat, lon))
return coordinates
segments = []
for c, g in legs_df.iterrows():
cnt = g['count']
lat_prev = 0.0
lon_prev = 0.0
for s in decode(g['geometryPoints']):
segments.append([lat_prev, lon_prev, s[0], s[1], cnt])
lat_prev = s[0]
lon_prev = s[1]
segments_df = pd.DataFrame(segments, columns = ['lat_x', 'lon_x', 'lat_y', 'lon_y', 'count'])
segments_df = segments_df[segments_df.lat_x > 0.0]
segments_df = segments_df.groupby(['lat_x', 'lon_x', 'lat_y', 'lon_y']).sum().reset_index().sort_values('count')
segments_df['line'] = segments_df.apply(lambda x: LineString([Point(x["lon_x"], x["lat_x"]),
Point(x["lon_y"], x["lat_y"])]), axis=1)
geodata = gpd.GeoDataFrame(segments_df, geometry=segments_df['line'])
geodata['width'] = 5 * (geodata['count']) / (geodata['count'].max())
geodata.plot(figsize=(15, 15))
geodata.plot(figsize=(15, 15), linewidth=np.minimum(np.maximum(df5['width'], 0.1), 2.75))