@Override public void run() { GTFSFeed feed = new GTFSFeed(); GlobalTx gtx = VersionedDataStore.getGlobalTx(); AgencyTx atx = null; try { for (Tuple2<String, Integer> ssid : snapshots) { String agencyId = ssid.a; Agency agency = gtx.agencies.get(agencyId); com.conveyal.gtfs.model.Agency gtfsAgency = agency.toGtfs(); Logger.info("Exporting agency %s", gtfsAgency); if (ssid.b == null) { atx = VersionedDataStore.getAgencyTx(agencyId); } else { atx = VersionedDataStore.getAgencyTx(agencyId, ssid.b); } // write the agencies.txt entry feed.agency.put(agencyId, agency.toGtfs()); // write all of the calendars and calendar dates for (ServiceCalendar cal : atx.calendars.values()) { com.conveyal.gtfs.model.Service gtfsService = cal.toGtfs(toGtfsDate(startDate), toGtfsDate(endDate)); // note: not using user-specified IDs // add calendar dates if (atx.exceptions != null) { for (ScheduleException ex : atx.exceptions.values()) { for (LocalDate date : ex.dates) { if (date.isBefore(startDate) || date.isAfter(endDate)) // no need to write dates that do not apply continue; CalendarDate cd = new CalendarDate(); cd.date = date; cd.service = gtfsService; cd.exception_type = ex.serviceRunsOn(cal) ? 1 : 2; if (gtfsService.calendar_dates.containsKey(date)) throw new IllegalArgumentException( "Duplicate schedule exceptions on " + date.toString()); gtfsService.calendar_dates.put(date, cd); } } } feed.services.put(gtfsService.service_id, gtfsService); } Map<String, com.conveyal.gtfs.model.Route> gtfsRoutes = Maps.newHashMap(); // write the routes for (Route route : atx.routes.values()) { com.conveyal.gtfs.model.Route gtfsRoute = route.toGtfs(gtfsAgency, gtx); feed.routes.put(route.getGtfsId(), gtfsRoute); gtfsRoutes.put(route.id, gtfsRoute); } // write the trips on those routes // we can't use the trips-by-route index because we may be exporting a snapshot database // without indices for (Trip trip : atx.trips.values()) { if (!gtfsRoutes.containsKey(trip.routeId)) { Logger.warn("Trip {} has not matching route", trip); continue; } com.conveyal.gtfs.model.Route gtfsRoute = gtfsRoutes.get(trip.routeId); Route route = atx.routes.get(trip.routeId); com.conveyal.gtfs.model.Trip gtfsTrip = new com.conveyal.gtfs.model.Trip(); gtfsTrip.block_id = trip.blockId; gtfsTrip.route = gtfsRoute; gtfsTrip.trip_id = trip.getGtfsId(); // not using custom ids for calendars gtfsTrip.service = feed.services.get(trip.calendarId); gtfsTrip.trip_headsign = trip.tripHeadsign; gtfsTrip.trip_short_name = trip.tripShortName; gtfsTrip.direction_id = trip.tripDirection == TripDirection.A ? 0 : 1; TripPattern pattern = atx.tripPatterns.get(trip.patternId); Tuple2<String, Integer> nextKey = feed.shapePoints.ceilingKey(new Tuple2(pattern.id, null)); if ((nextKey == null || !pattern.id.equals(nextKey.a)) && pattern.shape != null && !pattern.useStraightLineDistances) { // this shape has not yet been saved double[] coordDistances = GeoUtils.getCoordDistances(pattern.shape); for (int i = 0; i < coordDistances.length; i++) { Coordinate coord = pattern.shape.getCoordinateN(i); Shape shape = new Shape(pattern.id, coord.y, coord.x, i + 1, coordDistances[i]); feed.shapePoints.put(new Tuple2(pattern.id, shape.shape_pt_sequence), shape); } } if (pattern.shape != null && !pattern.useStraightLineDistances) gtfsTrip.shape_id = pattern.id; if (trip.wheelchairBoarding != null) { if (trip.wheelchairBoarding.equals(AttributeAvailabilityType.AVAILABLE)) gtfsTrip.wheelchair_accessible = 1; else if (trip.wheelchairBoarding.equals(AttributeAvailabilityType.UNAVAILABLE)) gtfsTrip.wheelchair_accessible = 2; else gtfsTrip.wheelchair_accessible = 0; } else if (route.wheelchairBoarding != null) { if (route.wheelchairBoarding.equals(AttributeAvailabilityType.AVAILABLE)) gtfsTrip.wheelchair_accessible = 1; else if (route.wheelchairBoarding.equals(AttributeAvailabilityType.UNAVAILABLE)) gtfsTrip.wheelchair_accessible = 2; else gtfsTrip.wheelchair_accessible = 0; } feed.trips.put(gtfsTrip.trip_id, gtfsTrip); TripPattern patt = atx.tripPatterns.get(trip.patternId); Iterator<TripPatternStop> psi = patt.patternStops.iterator(); int stopSequence = 1; // write the stop times for (StopTime st : trip.stopTimes) { TripPatternStop ps = psi.next(); if (st == null) continue; Stop stop = atx.stops.get(st.stopId); if (!st.stopId.equals(ps.stopId)) { throw new IllegalStateException("Trip " + trip.id + " does not match its pattern!"); } com.conveyal.gtfs.model.StopTime gst = new com.conveyal.gtfs.model.StopTime(); gst.arrival_time = st.arrivalTime != null ? st.arrivalTime : Entity.INT_MISSING; gst.departure_time = st.departureTime != null ? st.departureTime : Entity.INT_MISSING; if (st.dropOffType != null) gst.drop_off_type = st.dropOffType.toGtfsValue(); else if (stop.dropOffType != null) gst.drop_off_type = stop.dropOffType.toGtfsValue(); if (st.pickupType != null) gst.pickup_type = st.pickupType.toGtfsValue(); else if (stop.dropOffType != null) gst.drop_off_type = stop.dropOffType.toGtfsValue(); gst.shape_dist_traveled = ps.shapeDistTraveled; gst.stop_headsign = st.stopHeadsign; gst.stop_id = stop.getGtfsId(); // write the stop as needed if (!feed.stops.containsKey(gst.stop_id)) { feed.stops.put(gst.stop_id, stop.toGtfs()); } gst.stop_sequence = stopSequence++; if (ps.timepoint != null) gst.timepoint = ps.timepoint ? 1 : 0; else gst.timepoint = Entity.INT_MISSING; gst.trip_id = gtfsTrip.trip_id; feed.stop_times.put(new Tuple2(gtfsTrip.trip_id, gst.stop_sequence), gst); } // create frequencies as needed if (trip.useFrequency != null && trip.useFrequency) { Frequency f = new Frequency(); f.trip = gtfsTrip; f.start_time = trip.startTime; f.end_time = trip.endTime; f.exact_times = 0; f.headway_secs = trip.headway; feed.frequencies.put(gtfsTrip.trip_id, f); } } } feed.toFile(output.getAbsolutePath()); } finally { gtx.rollbackIfOpen(); if (atx != null) atx.rollbackIfOpen(); } }
public static void upload(String imei, File data) { try { File pbFile = new File( Play.configuration.getProperty("application.uploadDataDirectory"), imei + "_" + new Date().getTime() + ".pb"); Logger.info(pbFile.toString()); data.renameTo(pbFile); byte[] dataFrame = new byte[(int) pbFile.length()]; ; DataInputStream dataInputStream = new DataInputStream(new BufferedInputStream(new FileInputStream(pbFile))); dataInputStream.read(dataFrame); Upload upload = Upload.parseFrom(dataFrame); Phone phone = Phone.find("imei = ?", imei).first(); if (phone == null) badRequest(); for (Upload.Route r : upload.getRouteList()) { if (r.getPointList().size() <= 1) continue; Agency a = Agency.find("gtfsAgencyId = ?", "DEFAULT").first(); Route route = new Route("", r.getRouteName(), RouteType.BUS, r.getRouteDescription(), a); route.phone = phone; route.routeNotes = r.getRouteNotes(); route.vehicleCapacity = r.getVehicleCapacity(); route.vehicleType = r.getVehicleType(); route.captureTime = new Date(r.getStartTime()); route.save(); List<String> points = new ArrayList<String>(); Integer pointSequence = 1; for (Upload.Route.Point p : r.getPointList()) { points.add(new Double(p.getLon()).toString() + " " + new Double(p.getLat()).toString()); RoutePoint.addRoutePoint(p, route.id, pointSequence); pointSequence++; } String linestring = "LINESTRING(" + StringUtils.join(points, ", ") + ")"; BigInteger tripShapeId = TripShape.nativeInsert(TripShape.em(), "", linestring, 0.0); TripPattern tp = new TripPattern(); tp.route = route; tp.headsign = r.getRouteName(); tp.shape = TripShape.findById(tripShapeId.longValue()); tp.save(); Integer sequenceId = 0; for (Upload.Route.Stop s : r.getStopList()) { BigInteger stopId = Stop.nativeInsert(Stop.em(), s); TripPatternStop tps = new TripPatternStop(); tps.stop = Stop.findById(stopId.longValue()); tps.stopSequence = sequenceId; tps.defaultTravelTime = s.getArrivalTimeoffset(); tps.defaultDwellTime = s.getDepartureTimeoffset() - s.getArrivalTimeoffset(); tps.pattern = tp; tps.board = s.getBoard(); tps.alight = s.getAlight(); tps.save(); sequenceId++; } // ProcessGisExport gisExport = new ProcessGisExport(tp.id); // gisExport.doJob(); } Logger.info("Routes uploaded: " + upload.getRouteList().size()); dataInputStream.close(); ok(); } catch (Exception e) { e.printStackTrace(); badRequest(); } }