package com.schneeloch.bostonbusmap_library.parser;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.util.Map;
import com.google.common.base.Optional;
import com.schneeloch.bostonbusmap_library.parser.gson.MbtaRealtimeRoot;
import com.schneeloch.bostonbusmap_library.parser.gson.Mode;
import com.schneeloch.bostonbusmap_library.parser.gson.Route;
import com.schneeloch.bostonbusmap_library.parser.gson.Trip;
import com.schneeloch.bostonbusmap_library.data.BusLocation;
import com.schneeloch.bostonbusmap_library.data.CommuterTrainLocation;
import com.schneeloch.bostonbusmap_library.data.Direction;
import com.schneeloch.bostonbusmap_library.data.Directions;
import com.schneeloch.bostonbusmap_library.data.SubwayTrainLocation;
import com.schneeloch.bostonbusmap_library.data.TransitSourceTitles;
import com.schneeloch.bostonbusmap_library.data.VehicleLocations;
import com.schneeloch.bostonbusmap_library.data.VehicleLocations.Key;
import com.schneeloch.bostonbusmap_library.database.Schema;
import com.schneeloch.bostonbusmap_library.transit.MbtaRealtimeTransitSource;
import com.schneeloch.bostonbusmap_library.transit.TransitSource;
import com.schneeloch.bostonbusmap_library.util.LogUtil;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.google.gson.Gson;
public class MbtaRealtimeVehicleParser {
private final TransitSourceTitles routeKeysToTitles;
private final VehicleLocations busMapping;
private final long lastFeedUpdateInMillis;
private final Directions directionsObj;
private final ImmutableSet<String> routeNames;
public MbtaRealtimeVehicleParser(TransitSourceTitles routeKeysToTitles,
VehicleLocations busMapping, Directions directionsObj, ImmutableSet<String> routeNames)
{
this.routeKeysToTitles = routeKeysToTitles;
this.busMapping = busMapping;
this.directionsObj = directionsObj;
this.routeNames = routeNames;
this.lastFeedUpdateInMillis = System.currentTimeMillis();
}
public void runParse(Reader data, TransitSource transitSource) throws IOException {
BufferedReader bufferedReader = new BufferedReader(data, 2048);
MbtaRealtimeRoot root = new Gson().fromJson(bufferedReader, MbtaRealtimeRoot.class);
parseTree(root, transitSource);
}
private void parseTree(MbtaRealtimeRoot root, TransitSource transitSource) {
if (root.mode == null) {
return;
}
Map<Key, BusLocation> newSubwayVehicles = Maps.newHashMap();
Map<Key, BusLocation> newCommuterRailVehicles = Maps.newHashMap();
for (Mode mode : root.mode) {
for (Route route : mode.route) {
String routeName;
Schema.Routes.SourceId transitSourceId;
if (MbtaRealtimeTransitSource.gtfsNameToRouteName.containsKey(route.route_id)) {
routeName = MbtaRealtimeTransitSource.gtfsNameToRouteName.get(route.route_id);
transitSourceId = MbtaRealtimeTransitSource.routeNameToTransitSource.get(routeName);
}
else {
// this is weird because if we get a route id we would have requested it
LogUtil.i("Route id not found: " + route.route_id);
continue;
}
for (com.schneeloch.bostonbusmap_library.parser.gson.Direction direction : route.direction) {
String directionId = direction.direction_name;
for (Trip trip : direction.trip) {
String tripHeadsign = trip.trip_headsign;
String tripName = trip.trip_name;
if (trip.vehicle != null) {
String vehicleId = trip.vehicle.vehicle_id;
if (trip.vehicle.vehicle_lat == null || trip.vehicle.vehicle_lon == null) {
continue;
}
float latitude = Float.parseFloat(trip.vehicle.vehicle_lat);
float longitude = Float.parseFloat(trip.vehicle.vehicle_lon);
Optional<Integer> bearing;
if (trip.vehicle.vehicle_bearing != null) {
bearing = Optional.of(Integer.parseInt(trip.vehicle.vehicle_bearing));
}
else {
bearing = Optional.absent();
}
String id;
if (MbtaRealtimeTransitSource.routeNameToTransitSource.get(routeName) == Schema.Routes.SourceId.CommuterRail) {
id = tripName;
}
else {
id = vehicleId;
}
VehicleLocations.Key key = new VehicleLocations.Key(transitSourceId, routeName, id);
Direction directionObj = new Direction(tripHeadsign, directionId, routeName, true);
String newDirectionId = directionId + "_" + tripHeadsign;
directionsObj.add(newDirectionId, directionObj);
BusLocation location = transitSource.createVehicleLocation(latitude,
longitude, id, lastFeedUpdateInMillis, bearing, routeName, tripHeadsign);
if (transitSourceId == Schema.Routes.SourceId.CommuterRail) {
newCommuterRailVehicles.put(key, location);
}
else {
newSubwayVehicles.put(key, location);
}
}
}
}
}
}
busMapping.update(Schema.Routes.SourceId.CommuterRail, routeNames, false, newCommuterRailVehicles);
busMapping.update(Schema.Routes.SourceId.Subway, routeNames, false, newSubwayVehicles);
}
}