/** * Constructs a new {@link FeedMessage.Builder} that can be used to build a new GTFS-realtime feed * message. The {@link FeedHeader} will already be filled in as a {@link * Incrementality#FULL_DATASET} and the timestamp of the feed will be set to NOW. This is the * minimal requirement for an empty feed so the feed could be returned 'as-is' at this point. * * @return a new feed message builder with a header already populated */ public static FeedMessage.Builder createFeedMessageBuilder() { long now = System.currentTimeMillis(); FeedHeader.Builder header = FeedHeader.newBuilder(); header.setTimestamp(now / 1000); header.setIncrementality(Incrementality.FULL_DATASET); header.setGtfsRealtimeVersion(GtfsRealtimeConstants.VERSION); FeedMessage.Builder feedMessageBuilder = FeedMessage.newBuilder(); feedMessageBuilder.setHeader(header); return feedMessageBuilder; }
/** * This method downloads the latest vehicle data, processes each vehicle in turn, and create a * GTFS-realtime feed of trip updates and vehicle positions as a result. */ private void refreshVehicles() throws IOException, JSONException { /** We download the vehicle details as an array of JSON objects. */ JSONArray vehicleArray = downloadVehicleDetails(); /** * The FeedMessage.Builder is what we will use to build up our GTFS-realtime feeds. We create a * feed for both trip updates and vehicle positions. */ FeedMessage.Builder tripUpdates = GtfsRealtimeLibrary.createFeedMessageBuilder(); FeedMessage.Builder vehiclePositions = GtfsRealtimeLibrary.createFeedMessageBuilder(); /** We iterate over every JSON vehicle object. */ for (int i = 0; i < vehicleArray.length(); ++i) { JSONObject obj = vehicleArray.getJSONObject(i); String trainNumber = obj.getString("trainno"); String route = obj.getString("dest"); String stopId = obj.getString("nextstop"); double lat = obj.getDouble("lat"); double lon = obj.getDouble("lon"); int delay = obj.getInt("late"); /** * We construct a TripDescriptor and VehicleDescriptor, which will be used in both trip * updates and vehicle positions to identify the trip and vehicle. Ideally, we would have a * trip id to use for the trip descriptor, but the SEPTA api doesn't include it, so we settle * for a route id instead. */ TripDescriptor.Builder tripDescriptor = TripDescriptor.newBuilder(); tripDescriptor.setRouteId(route); VehicleDescriptor.Builder vehicleDescriptor = VehicleDescriptor.newBuilder(); vehicleDescriptor.setId(trainNumber); /** * To construct our TripUpdate, we create a stop-time arrival event for the next stop for the * vehicle, with the specified arrival delay. We add the stop-time update to a TripUpdate * builder, along with the trip and vehicle descriptors. */ StopTimeEvent.Builder arrival = StopTimeEvent.newBuilder(); arrival.setDelay(delay * 60); StopTimeUpdate.Builder stopTimeUpdate = StopTimeUpdate.newBuilder(); stopTimeUpdate.setArrival(arrival); stopTimeUpdate.setStopId(stopId); TripUpdate.Builder tripUpdate = TripUpdate.newBuilder(); tripUpdate.addStopTimeUpdate(stopTimeUpdate); tripUpdate.setTrip(tripDescriptor); tripUpdate.setVehicle(vehicleDescriptor); /** * Create a new feed entity to wrap the trip update and add it to the GTFS-realtime trip * updates feed. */ FeedEntity.Builder tripUpdateEntity = FeedEntity.newBuilder(); tripUpdateEntity.setId(trainNumber); tripUpdateEntity.setTripUpdate(tripUpdate); tripUpdates.addEntity(tripUpdateEntity); /** * To construct our VehiclePosition, we create a position for the vehicle. We add the position * to a VehiclePosition builder, along with the trip and vehicle descriptors. */ Position.Builder position = Position.newBuilder(); position.setLatitude((float) lat); position.setLongitude((float) lon); VehiclePosition.Builder vehiclePosition = VehiclePosition.newBuilder(); vehiclePosition.setPosition(position); vehiclePosition.setTrip(tripDescriptor); vehiclePosition.setVehicle(vehicleDescriptor); /** * Create a new feed entity to wrap the vehicle position and add it to the GTFS-realtime * vehicle positions feed. */ FeedEntity.Builder vehiclePositionEntity = FeedEntity.newBuilder(); vehiclePositionEntity.setId(trainNumber); vehiclePositionEntity.setVehicle(vehiclePosition); vehiclePositions.addEntity(vehiclePositionEntity); } /** Build out the final GTFS-realtime feed messagse and save them. */ _gtfsRealtimeProvider.setTripUpdates(tripUpdates.build()); _gtfsRealtimeProvider.setVehiclePositions(vehiclePositions.build()); _log.info("vehicles extracted: " + tripUpdates.getEntityCount()); }