You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
78 lines
3.1 KiB
78 lines
3.1 KiB
from google.transit import gtfs_realtime_pb2
|
|
import requests
|
|
import pandas as pd
|
|
import numpy as np
|
|
|
|
from bokeh.layouts import column
|
|
from bokeh.palettes import brewer
|
|
from bokeh.plotting import figure, curdoc
|
|
from bokeh.models import GeoJSONDataSource, Button, HoverTool, LinearColorMapper, LabelSet, ColumnDataSource
|
|
from bokeh.tile_providers import get_provider
|
|
from bokeh.transform import factor_cmap
|
|
import time
|
|
import urllib
|
|
|
|
def lonlattowebmercator(df, lon="LON", lat="LAT"):
|
|
k = 6378137
|
|
df["x"] = df[lon] * (k * np.pi/180.0)
|
|
df["y"] = np.log(np.tan((90+df[lat]) * np.pi/360.0)) * k
|
|
return df
|
|
|
|
def getPositions():
|
|
## Get the live locations of the vehicles
|
|
feed = gtfs_realtime_pb2.FeedMessage()
|
|
response = requests.get('http://gtfs.ovapi.nl/nl/vehiclePositions.pb')
|
|
feed.ParseFromString(response.content)
|
|
vehicle_positions = []
|
|
|
|
for entity in feed.entity:
|
|
entry = [entity.vehicle.vehicle.label, int(entity.vehicle.trip.route_id), float(entity.vehicle.position.latitude), float(entity.vehicle.position.longitude)]
|
|
vehicle_positions.append(entry)
|
|
df_vehiclePositions = pd.DataFrame(vehicle_positions, columns=["vehicle_label", "route_id", "latitude", "longitude"])
|
|
df_vehiclePositions = df_vehiclePositions[df_vehiclePositions["longitude"]!=0]
|
|
df_vehiclePositions = lonlattowebmercator(df_vehiclePositions, lon="longitude", lat="latitude")
|
|
return(df_vehiclePositions)
|
|
|
|
def update():
|
|
df_vehiclePositions = getPositions()
|
|
df_routes = pd.read_csv("gtfs-data/routes.txt")
|
|
|
|
## Merge tables
|
|
df = df_vehiclePositions.merge(df_routes, on="route_id", how="right")
|
|
df = df[df["route_type"]!=2]
|
|
df = add_route_types(df, route_translation)
|
|
Source.stream(df, rollover=len(df["longitude"]))
|
|
labels = LabelSet(x='x',y='y',x_offset=5,y_offset=5,source=Source,render_mode='canvas')
|
|
|
|
def add_route_types(df, route_translation):
|
|
df['route_type_long'] = [route_translation[key] for key in df['route_type']]
|
|
df['color'] = [brewer['Set1'][9][key] for key in df['route_type']]
|
|
return(df)
|
|
|
|
|
|
|
|
## Get initial values
|
|
df_vehiclePositions = getPositions()
|
|
df_routes = pd.read_csv("gtfs-data/routes.txt")
|
|
|
|
## Merge tables
|
|
df = df_vehiclePositions.merge(df_routes, on="route_id", how="right")
|
|
df = df[df["route_type"]!=2]
|
|
route_translation = {0:"Tram", 1:"Metro", 2:"Rail", 3:"Bus", 4:"Ferry"}
|
|
df = add_route_types(df,route_translation)
|
|
Source = ColumnDataSource(df)
|
|
|
|
## Plot
|
|
## Initialize our plot figure
|
|
x_range,y_range=([400000,700000], [6500000, 7500000])
|
|
OSM = get_provider('OSM')
|
|
p = figure(title="A gtfs feed, check out git.sgeboers.nl/sgeboers/gtfs for more information",x_range=x_range, y_range=y_range, x_axis_type='mercator',y_axis_type='mercator',sizing_mode='stretch_both',plot_width=1500,plot_height=1000)
|
|
p.add_tile(OSM)
|
|
my_hover=HoverTool()
|
|
my_hover.tooltips=[('Type','@route_type_long'),('Route id','@route_short_name'),('Route','@route_long_name')]
|
|
|
|
p.add_tools(my_hover)
|
|
p.circle('x', 'y', source=Source, legend_field='route_type_long', color='color', size=10)
|
|
curdoc().add_root(p)
|
|
curdoc().add_periodic_callback(update,5000)
|
|
p.legend.location = "top_left"
|
|
|