Where's my train?
See the subway trains moving within the boroughs of New York at realtime using this app.
See It Live
Here is a schematic diagram of this design.
The app fetches real-time transit data from the MTA datamine.
MTA provides API endpoints for train arrival and departure times following the GTFS format.
The list of MTA "feeds" can be found here.
Extraction and implementation of data follow these basic steps:
- Fetch serialized data from the MTA
- Decode data using protobuf.js/gtfs-realtime.js
- Parse and normalize the data
- Construct train and map objects with new data
MTA provides data of every station in NYCT including its name and geolocation.
Routes for individual train lines are also provided.
Using these two datasets, a polyline can be generated on the map by plotting geolocations of stations corresponding to the static route data.
A request to MTA is made through client-side scripting, hence, an Origin header is required. To bypass CORS on client-side, requests are made to an external proxy server (https://cors-anywhere.herokuapp.com/). Requests are asynchronous and makes updates to the app component when data is received with 200 status.
The MTA serializes the transit data using GTFS and NYCT protocol buffers.
Using Google's GTFS-realtime Bindings, the serialized data is parsed into JavaScript objects.
MTA sets routes for each train with a tripId. Each id is used to reference a unique marker object on the map.
Each route from the feed data is represented by an array (stopTimeUpdate) that lists the estimated time of arrivals at each station along with a stopId.
An example of a train feed:
{
stopTimeUpdate: [
{
arrival: StopTimeEvent,
departure: StopTimeEvent,
stopId: "701S"
}, {
arrival: StopTimeEvent,
departure: StopTimeEvent,
stopId: "701S"
},
...
}, {
arrival: StopTimeEvent,
departure: StopTimeEvent,
stopId: "726S"
}
],
trip: {
routeId: "7"
startDate: date
tripId: "128200_7..S"
}
}