included code and requirements, next step is to make a button that can toggle between busses and trams
commit
ae7799d775
@ -0,0 +1,68 @@ |
|||||||
|
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 #, Vendors |
||||||
|
from bokeh.transform import factor_cmap |
||||||
|
import time |
||||||
|
|
||||||
|
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"]==1) | (df["route_type"]==2) | (df["route_type"]==3)] |
||||||
|
print(df["longitude"]) |
||||||
|
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,1000) |
||||||
|
p.legend.location = "top_left" |
@ -0,0 +1,29 @@ |
|||||||
|
attrs==22.1.0 |
||||||
|
bokeh==2.4.3 |
||||||
|
certifi==2022.6.15 |
||||||
|
charset-normalizer==2.1.0 |
||||||
|
click==8.1.3 |
||||||
|
click-plugins==1.1.1 |
||||||
|
cligj==0.7.2 |
||||||
|
Fiona==1.8.21 |
||||||
|
gtfs-realtime-bindings==0.0.7 |
||||||
|
idna==3.3 |
||||||
|
Jinja2==3.1.2 |
||||||
|
MarkupSafe==2.1.1 |
||||||
|
munch==2.5.0 |
||||||
|
numpy==1.23.1 |
||||||
|
packaging==21.3 |
||||||
|
pandas==1.4.3 |
||||||
|
Pillow==9.2.0 |
||||||
|
protobuf==3.20.1 |
||||||
|
pyparsing==3.0.9 |
||||||
|
pyproj==3.3.1 |
||||||
|
python-dateutil==2.8.2 |
||||||
|
pytz==2022.1 |
||||||
|
PyYAML==6.0 |
||||||
|
requests==2.28.1 |
||||||
|
Shapely==1.8.2 |
||||||
|
six==1.16.0 |
||||||
|
tornado==6.2 |
||||||
|
typing_extensions==4.3.0 |
||||||
|
urllib3==1.26.11 |
Loading…
Reference in new issue