Awesome
onebusaway-gtfs-realtime-visualizer
A demo application to visualize GTFS Realtime feeds.
Introduction
The goal of the GTFS Realtime specification is to provide both transit agencies and developers with a consistent way to exchange real-time public transit data. A specific feature of GTFS Realtime is support for vehicle positions, which allow an agency to specify information about vehicle locations.
We want to make it easy for developers to work with vehicle position using the GTFS Realtime format, so we've put together a quick demo project that shows how to consume a GTFS Realtime vehicle positions feed.
In the demo project, we'll walk you through a simple Java-based program that consumes a GTFS Realtime feed and visualizes it on a map.
If you want to follow along at home, you can download a ZIP of the source-code for the demo project or import the code from the Git repository directly. The project is designed to be built with Apache Maven, so download that if you are interested in building and running the project.
Running the Demo Project
Before we dig into how the demo application the works, let's see it in action! After you've downloaded the code for the project, open up a terminal and change to the root directory of the project. From there, run Maven to compile and package the application:
mvn package
Now that the project has been built, you should be able to run the resulting application bundle:
java -jar target/onebusaway-GTFS Realtime-visualizer-0.0.1-SNAPSHOT.jar \
--vehiclePositionsUrl=https://cdn.mbta.com/realtime/VehiclePositions.pb
This will start the application up using MBTA's GTFS Realtime feeds. When the application starts, you should see a message like:
=======================================================
The GTFS-realtime visualizer server has
started. Check it out at:
http://localhost:8080/
=======================================================
Note: In Java 9 and later versions, you may get an error like: java.lang.ClassNotFoundException: javax.annotation.PostConstruct
. Use this command:
java --add-modules java.xml.ws.annotation -jar target/onebusaway-gtfs-realtime-visualizer-0.0.1-SNAPSHOT.jar\
--vehiclePositionsUrl=https://cdn.mbta.com/realtime/VehiclePositions.pb
Refer this issue for details.
So browse to http://localhost:8080/ and take a look! The map update uses a number of HTML5 technologies, so be sure to use a modern browser like Google Chrome for the best experience. If all goes well, you should see a map of real-time vehicle positions that update over time.
Please note that if you use this application with your own GTFS-rt vehicle positions feed, the VehicleDescriptor
must contain the id
field, such as:
entity {
id: "vehicle_position_2403"
vehicle {
position {
latitude: 28.06235
longitude: -82.45927
bearing: 360.0
speed: 0.0
}
vehicle {
id: "2403" // This is required for this application
}
}
}
The id
field is required so that the vehicle path history can be drawn on the map over multiple refreshes of the feed.
Digging into the Code
So how does this all work? Let's look at the code! Most of the work with GTFS Realtime data is done in the following class:
org.onebusaway.gtfs_realtime.visualizer.VisualizerService
The class does the following:
- Periodically downloads vehicle data from the GTFS Realtime feeds.
- Extracts relevant position data.
- Notifies listeners of updated data.
Let's step through the code for each of these steps.
We setup a recurring task that downloads data from the GTFS Realtime feeds. The data comes in the form of a Protocol Buffer stream, which we can parse to create a FeedMessage:
FeedMessage feed = FeedMessage.parseFrom(_vehiclePositionsUrl.openStream());
The feed message contains a series of FeedEntity objects that contains information about a vehicle, a trip, or an alert. In our case, we are interested in vehicle position data, so we will look for a VehiclePosition for each entity, along with a Position for the vehicle.
for (FeedEntity entity : feed.getEntityList()) {
if (!entity.hasVehicle()) {
continue;
}
VehiclePosition vehicle = entity.getVehicle();
if (vehicle.hasPosition()) {
continue;
}
Position position = vehicle.getPosition();
Getting access to a vehicle location is that simple!
Of course, we've left out a few details. We take advantage of a couple of OneBusAway libraries to simplify our application:
- The onebusaway-gtfs-realtime-api module provides pre-packaged Java classes generated from the GTFS-realtime protocol buffer definition.
Next Steps
We provided this demo application as an example that you can build on when working with GTFS Realtime feeds. Integrating GTFS Realtime feeds with alerts, trip updates, and vehicle positions along with existing GTFS schedule data can be complex, but it can also allow you to build powerful applications.
Also be sure to check out all our GTFS Realtime resources.