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('https://gtfs.ovapi.nl/nl/vehiclePositions.pb') feed.ParseFromString(response.content) print(feed) 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"]==1) | (df["route_type"]==2) | (df["route_type"]==3)] Source.stream(df, rollover=len(df["longitude"])) labels = LabelSet(x='x',y='y',x_offset=5,y_offset=5,source=Source,render_mode='canvas') ## 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") 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",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=[('route_id','@route_id'),('Type','@route_type'),('Route','@route_long_name')] p.add_tools(my_hover) p.circle('x', 'y', source=Source) curdoc().add_root(p) curdoc().add_periodic_callback(update,5000) p.legend.location = "top_left"