From 153d6afd62957275532bae388250a5f3183d3c96 Mon Sep 17 00:00:00 2001 From: Landon Reed Date: Fri, 26 Jul 2019 10:21:29 -0400 Subject: [PATCH 1/5] fix(GTFSFeed): remove unneeded expensive indexes In previous versions of datatools-server, these indexes (stopCountByStopTime, stopStopTimeSet, tripsPerService, and servicesPerDate) were used to calculate various service statistics. However, GTFSFeed is no longer used for this operation and these very expensive (memory and time) indexes cause major slowdowns for large feeds. --- src/main/java/com/conveyal/gtfs/GTFSFeed.java | 23 ------------------- 1 file changed, 23 deletions(-) diff --git a/src/main/java/com/conveyal/gtfs/GTFSFeed.java b/src/main/java/com/conveyal/gtfs/GTFSFeed.java index 643feaefb..f84e30cc8 100644 --- a/src/main/java/com/conveyal/gtfs/GTFSFeed.java +++ b/src/main/java/com/conveyal/gtfs/GTFSFeed.java @@ -196,29 +196,6 @@ else if (feedId == null || feedId.isEmpty()) { for (GTFSError error : errors) { LOG.info("{}", error); } - LOG.info("Building stop to stop times index"); - Bind.histogram(stop_times, stopCountByStopTime, (key, stopTime) -> stopTime.stop_id); - Bind.secondaryKeys(stop_times, stopStopTimeSet, (key, stopTime) -> new String[] {stopTime.stop_id}); - LOG.info("Building trips per service index"); - Bind.secondaryKeys(trips, tripsPerService, (key, trip) -> new String[] {trip.service_id}); - LOG.info("Building services per date index"); - Bind.secondaryKeys(services, servicesPerDate, (key, service) -> { - - LocalDate startDate = service.calendar != null - ? service.calendar.start_date - : service.calendar_dates.keySet().stream().sorted().findFirst().get(); - LocalDate endDate = service.calendar != null - ? service.calendar.end_date - : service.calendar_dates.keySet().stream().sorted().reduce((first, second) -> second).get(); - // end date for Period.between is not inclusive - int daysOfService = (int) ChronoUnit.DAYS.between(startDate, endDate.plus(1, ChronoUnit.DAYS)); - return IntStream.range(0, daysOfService) - .mapToObj(offset -> startDate.plusDays(offset)) - .filter(service::activeOn) - .map(date -> date.format(dateFormatter)) - .toArray(size -> new String[size]); - }); - loaded = true; } From e48bbc79ec4f4602677045f13864dc3219b32d70 Mon Sep 17 00:00:00 2001 From: Landon Reed Date: Fri, 26 Jul 2019 10:32:28 -0400 Subject: [PATCH 2/5] refactor(GTFSFeed): remove functions related to indexes removed --- src/main/java/com/conveyal/gtfs/GTFSFeed.java | 114 +---- .../com/conveyal/gtfs/stats/FeedStats.java | 393 ------------------ .../com/conveyal/gtfs/stats/StopStats.java | 281 ------------- .../java/com/conveyal/gtfs/GTFSFeedTest.java | 24 -- 4 files changed, 8 insertions(+), 804 deletions(-) delete mode 100644 src/main/java/com/conveyal/gtfs/stats/FeedStats.java delete mode 100644 src/main/java/com/conveyal/gtfs/stats/StopStats.java diff --git a/src/main/java/com/conveyal/gtfs/GTFSFeed.java b/src/main/java/com/conveyal/gtfs/GTFSFeed.java index f84e30cc8..b7d5572ca 100644 --- a/src/main/java/com/conveyal/gtfs/GTFSFeed.java +++ b/src/main/java/com/conveyal/gtfs/GTFSFeed.java @@ -6,7 +6,6 @@ import com.conveyal.gtfs.model.*; import com.conveyal.gtfs.model.Calendar; import com.conveyal.gtfs.validator.Validator; -import com.conveyal.gtfs.stats.FeedStats; import com.conveyal.gtfs.validator.service.GeoUtils; import com.google.common.collect.*; import com.google.common.eventbus.EventBus; @@ -14,10 +13,8 @@ import com.vividsolutions.jts.algorithm.ConvexHull; import com.vividsolutions.jts.geom.*; import com.vividsolutions.jts.index.strtree.STRtree; -import com.vividsolutions.jts.simplify.DouglasPeuckerSimplifier; import org.geotools.referencing.GeodeticCalculator; import org.mapdb.BTreeMap; -import org.mapdb.Bind; import org.mapdb.DB; import org.mapdb.DBMaker; import org.mapdb.Fun; @@ -33,17 +30,12 @@ import java.io.IOError; import java.io.IOException; import java.io.OutputStream; -import java.time.LocalDate; -import java.time.ZoneId; import java.time.format.DateTimeFormatter; -import java.time.temporal.ChronoUnit; import java.util.*; -import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentNavigableMap; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; -import java.util.stream.IntStream; import java.util.stream.StreamSupport; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; @@ -86,13 +78,14 @@ public class GTFSFeed implements Cloneable, Closeable { // public final ConcurrentMap stopCountByStopTime; - /* Map from stop (stop_id) to stopTimes tuples (trip_id, stop_sequence) */ - public final NavigableSet> stopStopTimeSet; - public final ConcurrentMap stopCountByStopTime; - - public final NavigableSet> tripsPerService; - - public final NavigableSet> servicesPerDate; + // TODO: Remove these indexes from GTFSFeed. +// /* Map from stop (stop_id) to stopTimes tuples (trip_id, stop_sequence) */ +// public final NavigableSet> stopStopTimeSet; +// public final ConcurrentMap stopCountByStopTime; +// +// public final NavigableSet> tripsPerService; +// +// public final NavigableSet> servicesPerDate; /* A fare is a fare_attribute and all fare_rules that reference that fare_attribute. */ public final Map fares; @@ -275,11 +268,6 @@ public void validate () { ///////////////// } - public FeedStats calculateStats() { - FeedStats feedStats = new FeedStats(this); - return feedStats; - } - /** * Static factory method returning a new instance of GTFSFeed containing the contents of * the GTFS file at the supplied filesystem path. @@ -581,87 +569,6 @@ public double getTripSpeed (String trip_id, boolean straightLine) { return distance / time; // meters per second } - /** Get list of stop_times for a given stop_id. */ - public List getStopTimesForStop (String stop_id) { - SortedSet> index = this.stopStopTimeSet - .subSet(new Tuple2<>(stop_id, null), new Tuple2(stop_id, Fun.HI)); - - return index.stream() - .map(tuple -> this.stop_times.get(tuple.b)) - .collect(Collectors.toList()); - } - - public List getTripsForService (String service_id) { - SortedSet> index = this.tripsPerService - .subSet(new Tuple2<>(service_id, null), new Tuple2(service_id, Fun.HI)); - - return index.stream() - .map(tuple -> this.trips.get(tuple.b)) - .collect(Collectors.toList()); - } - - /** Get list of services for each date of service. */ - public List getServicesForDate (LocalDate date) { - String dateString = date.format(dateFormatter); - SortedSet> index = this.servicesPerDate - .subSet(new Tuple2<>(dateString, null), new Tuple2(dateString, Fun.HI)); - - return index.stream() - .map(tuple -> this.services.get(tuple.b)) - .collect(Collectors.toList()); - } - - public List getDatesOfService () { - return this.servicesPerDate.stream() - .map(tuple -> LocalDate.parse(tuple.a, dateFormatter)) - .collect(Collectors.toList()); - } - - /** Get list of distinct trips (filters out multiple visits by a trip) a given stop_id. */ - public List getDistinctTripsForStop (String stop_id) { - return getStopTimesForStop(stop_id).stream() - .map(stopTime -> this.trips.get(stopTime.trip_id)) - .distinct() - .collect(Collectors.toList()); - } - - /** Get the likely time zone for a stop using the agency of the first stop time encountered for the stop. */ - public ZoneId getAgencyTimeZoneForStop (String stop_id) { - StopTime stopTime = getStopTimesForStop(stop_id).iterator().next(); - - Trip trip = this.trips.get(stopTime.trip_id); - Route route = this.routes.get(trip.route_id); - Agency agency = route.agency_id != null ? this.agency.get(route.agency_id) : this.agency.get(0); - - return ZoneId.of(agency.agency_timezone); - } - - // TODO: code review - public Geometry getMergedBuffers() { - if (this.mergedBuffers == null) { -// synchronized (this) { - Collection polygons = new ArrayList<>(); - for (Stop stop : this.stops.values()) { - if (getStopTimesForStop(stop.stop_id).isEmpty()) { - continue; - } - if (stop.stop_lat > -1 && stop.stop_lat < 1 || stop.stop_lon > -1 && stop.stop_lon < 1) { - continue; - } - Point stopPoint = gf.createPoint(new Coordinate(stop.stop_lon, stop.stop_lat)); - Polygon stopBuffer = (Polygon) stopPoint.buffer(.01); - polygons.add(stopBuffer); - } - Geometry multiGeometry = gf.buildGeometry(polygons); - this.mergedBuffers = multiGeometry.union(); - if (polygons.size() > 100) { - this.mergedBuffers = DouglasPeuckerSimplifier.simplify(this.mergedBuffers, .001); - } -// } - } - return this.mergedBuffers; - } - public Polygon getConvexHull() { if (this.convexHull == null) { synchronized (this) { @@ -765,11 +672,6 @@ private GTFSFeed (DB db) { tripPatternMap = db.getTreeMap("patternForTrip"); - stopCountByStopTime = db.getTreeMap("stopCountByStopTime"); - stopStopTimeSet = db.getTreeSet("stopStopTimeSet"); - tripsPerService = db.getTreeSet("tripsPerService"); - servicesPerDate = db.getTreeSet("servicesPerDate"); - errors = db.getTreeSet("errors"); } } diff --git a/src/main/java/com/conveyal/gtfs/stats/FeedStats.java b/src/main/java/com/conveyal/gtfs/stats/FeedStats.java deleted file mode 100644 index 4a134b274..000000000 --- a/src/main/java/com/conveyal/gtfs/stats/FeedStats.java +++ /dev/null @@ -1,393 +0,0 @@ -package com.conveyal.gtfs.stats; - -import com.conveyal.gtfs.GTFSFeed; -import com.conveyal.gtfs.model.Agency; -import com.conveyal.gtfs.model.Service; -import com.conveyal.gtfs.model.Stop; -import com.conveyal.gtfs.model.Trip; -import com.conveyal.gtfs.stats.model.AgencyStatistic; -import com.vividsolutions.jts.geom.Geometry; - -import java.awt.geom.Point2D; -import java.awt.geom.Rectangle2D; -import java.time.DayOfWeek; -import java.time.LocalDate; -import java.time.LocalTime; -import java.time.format.DateTimeFormatter; -import java.time.temporal.ChronoUnit; -import java.util.*; -import java.util.stream.Collectors; -import java.util.stream.IntStream; - -/** - * Retrieves a base set of statistics from the GTFS. - * - */ -public class FeedStats { - - private GTFSFeed feed = null; - public String feed_id = null; - public PatternStats pattern = null; - public StopStats stop = null; - public RouteStats route = null; - - public FeedStats(GTFSFeed f) { - this.feed = f; - this.feed_id = f.feedId; - this.pattern = new PatternStats(feed, this); - this.stop = new StopStats(feed, this); - this.route = new RouteStats(feed, this); - } - - public Integer getAgencyCount() { - return feed.agency.size(); - } - - public Integer getRouteCount() { - return feed.routes.size(); - } - - public Integer getTripCount() { - return feed.trips.size(); - } - - public Integer getTripCount(LocalDate date) { - return getTripsForDate(date).size(); - } - - - public Integer getStopCount() { - return feed.stops.size(); - } - - public Integer getStopTimesCount() { - return feed.stop_times.size(); - } - - // calendar date range start/end assume a service calendar based schedule - // returns null for schedules without calendar service schedules - - public LocalDate getCalendarServiceRangeStart() { - - int startDate = 0; - for (Service service : feed.services.values()) { - if (service.calendar == null) - continue; -// if (startDate == 0 || service.calendar.start_date < startDate) { -// startDate = service.calendar.start_date; -// } - } - if (startDate == 0) - return null; - - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd"); - return LocalDate.parse(String.valueOf(startDate), formatter); - } - - public LocalDate getCalendarServiceRangeEnd() { - - int endDate = 0; - - for (Service service : feed.services.values()) { - if (service.calendar == null) - continue; - -// if (endDate == 0 || service.calendar.end_date > endDate) { -// endDate = service.calendar.end_date; -// } - } - if (endDate == 0) - return null; - - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd"); - return LocalDate.parse(String.valueOf(endDate), formatter); - } - - public LocalDate getCalendarDateStart() { - LocalDate startDate = null; - for (Service service : feed.services.values()) { - for (LocalDate date : service.calendar_dates.keySet()) { - if (startDate == null - || date.isBefore(startDate)) - startDate = date; - } - } - return startDate; - } - - public LocalDate getCalendarDateEnd() { - LocalDate endDate = null; - for (Service service : feed.services.values()) { - for (LocalDate date : service.calendar_dates.keySet()) { - if (endDate == null - || date.isAfter(endDate)) - endDate = date; - } - } - return endDate; - } - - public Map getTripCountPerDateOfService() { - - Map> tripsPerDate = getTripsPerDateOfService(); - Map tripCountPerDate = new HashMap<>(); - for (Map.Entry> entry : tripsPerDate.entrySet()) { - LocalDate date = entry.getKey(); - Integer count = entry.getValue().size(); - tripCountPerDate.put(date, count); - } - - return tripCountPerDate; - } - public LocalDate getStartDate() { - LocalDate startDate = null; - - if (feed.hasFeedInfo()) startDate = feed.getFeedInfo().feed_start_date; - if (startDate == null) startDate = getCalendarServiceRangeStart(); - if (startDate == null) startDate = getCalendarDateStart(); - - return startDate; - } - - public LocalDate getEndDate() { - LocalDate endDate = null; - - if (feed.hasFeedInfo()) endDate = feed.getFeedInfo().feed_end_date; - if (endDate == null) endDate = getCalendarServiceRangeEnd(); - if (endDate == null) endDate = getCalendarDateEnd(); - - return endDate; - } - - public LocalTime getStartTime (LocalDate date) { - return this.pattern.getStartTimeForTrips(getTripsForDate(date)); - } - - public LocalTime getEndTime (LocalDate date) { - return this.pattern.getEndTimeForTrips(getTripsForDate(date)); - } - - /** Get total revenue time (in seconds) for all trips on a given date. */ - public long getTotalRevenueTimeForDate (LocalDate date) { - return this.pattern.getTotalRevenueTimeForTrips(getTripsForDate(date)); - } - - public long getAverageDailyRevenueTime (int dow) { - // int value of dow from 1 (Mon) to 7 (Sun) - DayOfWeek dayOfWeek = DayOfWeek.of(dow); - List dates = feed.getDatesOfService().stream() - .filter(date -> date.getDayOfWeek().equals(dayOfWeek)) - .collect(Collectors.toList()); - - return getRevenueTimeForDates(dates) / dates.size(); - } - - public long getAverageWeekdayRevenueTime () { - List dates = feed.getDatesOfService().stream() - .filter(date -> { - int dow = date.getDayOfWeek().getValue(); - boolean isWeekday = ((dow >= DayOfWeek.MONDAY.getValue()) && (dow <= DayOfWeek.FRIDAY.getValue())); - return isWeekday; - }) - .collect(Collectors.toList()); - if (dates.size() == 0) { - return 0; - } - return getRevenueTimeForDates(dates) / dates.size(); - } - public long getRevenueTimeForDates (List dates) { - Map timePerService = new HashMap<>(); - - // First, get revenue time for each service calendar used in feed dates - // NOTE: we don't simply get revenue time for each individual date of service - // because that ends up duplicating a lot of operations if service calendars - // are reused often. - dates.stream() - .map(date -> feed.getServicesForDate(date)) - .flatMap(List::stream) - .collect(Collectors.toSet()) - .stream() - .forEach(s -> { - List trips = feed.getTripsForService(s.service_id); - long time = this.pattern.getTotalRevenueTimeForTrips(trips); - timePerService.put(s.service_id, time); - }); - - // Next, sum up service calendars by dates of service - long total = dates.stream() - .map(date -> // get sum of services per date - feed.getServicesForDate(date).stream() - .map(s -> timePerService.get(s.service_id)) - .mapToLong(time -> time) - .sum() - ) - .mapToLong(time -> time) - .sum(); - return total; - } - - public long getTotalRevenueTime () { - return getRevenueTimeForDates(feed.getDatesOfService()); - } - - /** Get total revenue distance (in meters) for all trips on a given date. */ - public double getTotalDistanceForTrips (LocalDate date) { - return this.pattern.getTotalDistanceForTrips(getTripsForDate(date)); - } - - /** in seconds */ - public int getDailyAverageHeadway (LocalDate date, LocalTime from, LocalTime to) { - - OptionalDouble avg = feed.stops.values().stream() - .map(s -> this.stop.getAverageHeadwayForStop(s.stop_id, date, from, to)) - .mapToDouble(headway -> headway) - .average(); - - return (int) avg.getAsDouble(); - } - - public double getAverageTripSpeed (LocalDate date, LocalTime from, LocalTime to) { - List trips = getTripsForDate(date); - return this.pattern.getAverageSpeedForTrips(trips, from, to); - } - public Map> getTripsPerDateOfService () { - Map> tripsPerDate = new HashMap<>(); - Map> tripsPerService = new HashMap<>(); - - LocalDate startDate = getStartDate(); - LocalDate endDate = getEndDate(); - if (startDate == null || endDate == null) { - return tripsPerDate; - } - int allDates = (int) ChronoUnit.DAYS.between(startDate, endDate.plus(1, ChronoUnit.DAYS)); - List dates = IntStream.range(0, allDates) - .mapToObj(offset -> startDate.plusDays(offset)) - .collect(Collectors.toList()); - dates.stream() - .map(date -> feed.getServicesForDate(date)) - .flatMap(List::stream) - .collect(Collectors.toSet()) - .stream() - .forEach(s -> { - List trips = feed.getTripsForService(s.service_id); - tripsPerService.put(s.service_id, trips); - }); - dates.stream() - .forEach(date -> { - List trips = feed.getServicesForDate(date).stream() - .map(s -> tripsPerService.get(s.service_id)) - .flatMap(List::stream) - .collect(Collectors.toList()); - tripsPerDate.put(date, trips); - }); - return tripsPerDate; - } - - public List getTripsForDate (LocalDate date) { - return feed.getServicesForDate(date).stream() - .map(s -> feed.getTripsForService(s.service_id)) - .flatMap(List::stream) - .collect(Collectors.toList()); - } - - public Collection getAllAgencies() { - return feed.agency.values(); - } - - /** - * Get the bounding box of this GTFS feed. - * We use a Rectangle2D rather than a Geotools envelope because GTFS is always in WGS 84. - * Note that stops do not have agencies in GTFS. - */ - public Rectangle2D getBounds () { - Rectangle2D ret = null; - - for (Stop stop : feed.stops.values()) { - - // skip over stops that don't have any stop times - if (!feed.stopCountByStopTime.containsKey(stop.stop_id)) { - continue; - } - if (ret == null) { - ret = new Rectangle2D.Double(stop.stop_lon, stop.stop_lat, 0, 0); - } - else { - ret.add(new Point2D.Double(stop.stop_lon, stop.stop_lat)); - } - } - - return ret; - } - - public AgencyStatistic getStatistic(String agencyId) { - AgencyStatistic gs = new AgencyStatistic(); - gs.setAgencyId(agencyId); - gs.setRouteCount(AgencyStats.getRouteCount(feed, agencyId)); - gs.setTripCount(AgencyStats.getTripCount(feed, agencyId)); - gs.setStopCount(AgencyStats.getStopCount(feed, agencyId)); - gs.setStopTimeCount(AgencyStats.getStopTimesCount(feed, agencyId)); - gs.setCalendarStartDate(AgencyStats.getCalendarDateStart(feed, agencyId)); - gs.setCalendarEndDate(AgencyStats.getCalendarDateEnd(feed, agencyId)); - gs.setCalendarServiceStart(AgencyStats.getCalendarServiceRangeStart(feed, agencyId)); - gs.setCalendarServiceEnd(AgencyStats.getCalendarServiceRangeEnd(feed, agencyId)); - gs.setBounds(getBounds()); - return gs; - } - - public String getStatisticAsCSV(String agencyId) { - AgencyStatistic s = getStatistic(agencyId); - return formatStatisticAsCSV(s); - } - - public static String formatStatisticAsCSV(AgencyStatistic s) { - StringBuffer buff = new StringBuffer(); - buff.append(s.getAgencyId()); - buff.append(","); - buff.append(s.getRouteCount()); - buff.append(","); - buff.append(s.getTripCount()); - buff.append(","); - buff.append(s.getStopCount()); - buff.append(","); - buff.append(s.getStopTimeCount()); - buff.append(","); - buff.append(s.getCalendarServiceStart()); - buff.append(","); - buff.append(s.getCalendarServiceEnd()); - buff.append(","); - buff.append(s.getCalendarStartDate()); - buff.append(","); - buff.append(s.getCalendarEndDate()); - return buff.toString(); - } - - public long getFrequencyCount() { - return feed.frequencies.size(); - } - - public long getShapePointCount() { - return feed.shape_points.size(); - } - - public long getFareAttributeCount() { - return feed.fares.size(); - } - - public long getFareRulesCount() { - return feed.fares.values().stream() - .mapToInt(fare -> fare.fare_rules.size()) - .sum(); - } - - public long getServiceCount() { - return feed.services.size(); - } - - public List getDatesOfService() { - return feed.getDatesOfService(); - } - - public Geometry getMergedBuffers() { - return feed.getMergedBuffers(); - } -} diff --git a/src/main/java/com/conveyal/gtfs/stats/StopStats.java b/src/main/java/com/conveyal/gtfs/stats/StopStats.java deleted file mode 100644 index 703f24c50..000000000 --- a/src/main/java/com/conveyal/gtfs/stats/StopStats.java +++ /dev/null @@ -1,281 +0,0 @@ -package com.conveyal.gtfs.stats; - -import com.conveyal.gtfs.GTFSFeed; -import com.conveyal.gtfs.model.Route; -import com.conveyal.gtfs.model.Service; -import com.conveyal.gtfs.model.StopTime; -import com.conveyal.gtfs.model.Trip; -import com.conveyal.gtfs.stats.model.TransferPerformanceSummary; -import gnu.trove.list.TIntList; -import gnu.trove.list.array.TIntArrayList; -import org.mapdb.Fun; - -import java.time.LocalDate; -import java.time.LocalTime; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.SortedSet; -import java.util.stream.Collectors; -import java.util.stream.StreamSupport; - -/** - * Created by landon on 9/2/16. - */ -public class StopStats { - - private GTFSFeed feed = null; - private FeedStats stats = null; - private RouteStats routeStats = null; - - public StopStats (GTFSFeed f, FeedStats fs) { - feed = f; - stats = fs; - routeStats = stats.route; - } - - public List getRoutes (String stop_id) { - return feed.patterns.values().stream() - .filter(p -> p.orderedStops.contains(stop_id)) - .distinct() - .map(p -> feed.routes.get(p.route_id)) - .collect(Collectors.toList()); - } - - /** - * Gets count of routes that visit a stop. - * @param stop_id - * @return count of routes for stop - */ - public int getRouteCount (String stop_id) { - return getRoutes(stop_id).size(); - } - - /** - * Gets count of trips that visit a stop for a specified date of service. - * @param stop_id - * @param date - * @return count of trips for date - */ - public int getTripCountForDate (String stop_id, LocalDate date) { - return (int) getTripsForDate(stop_id, date).size(); - } - - /** - * Get list of trips that visit a stop for a specified date of service. - * @param stop_id - * @param date - * @return list of trips for date - */ - public List getTripsForDate (String stop_id, LocalDate date) { - List tripIds = stats.getTripsForDate(date).stream() - .map(trip -> trip.trip_id) - .collect(Collectors.toList()); - - return feed.getDistinctTripsForStop(stop_id).stream() - .filter(t -> tripIds.contains(t.trip_id)) // filter by trip_id list for date - .collect(Collectors.toList()); - } - - /** - * Get the average headway, in seconds, for all trips at a stop over a time window. - * @param stop_id - * @param date - * @param from - * @param to - * @return avg. headway (in seconds) - */ - public int getAverageHeadwayForStop (String stop_id, LocalDate date, LocalTime from, LocalTime to) { - List tripsForStop = getTripsForDate(stop_id, date); - - return getStopHeadwayForTrips(stop_id, tripsForStop, from, to); - } - - /** Get the route headway for a given service date at a stop over a time window, in seconds */ - public Map getRouteHeadwaysForStop (String stop_id, LocalDate date, LocalTime from, LocalTime to) { - Map routeHeadwayMap = new HashMap<>(); - List routes = feed.patterns.values().stream() - .filter(p -> p.orderedStops.contains(stop_id)) - .map(p -> feed.routes.get(p.route_id)) - .collect(Collectors.toList()); - - for (Route route : routes) { - routeHeadwayMap.put(route.route_id, getHeadwayForStopByRoute(stop_id, route.route_id, date, from, to)); - } - return routeHeadwayMap; - } - - /** - * Get the average headway, in seconds, for a set of trips at a stop over a time window. - * @param stop_id - * @param trips - * @param from - * @param to - * @return avg. headway (in seconds) - */ - //TODO: add direction_id? - //TODO: specified stop vs. first stop - public int getStopHeadwayForTrips (String stop_id, List trips, LocalTime from, LocalTime to) { - TIntList timesAtStop = new TIntArrayList(); - Set tripIds = trips.stream() - .map(t -> t.trip_id) - .collect(Collectors.toSet()); - - List stopTimes = feed.getStopTimesForStop(stop_id).stream() - .filter(st -> tripIds.contains(st.trip_id)) - .collect(Collectors.toList()); - - for (StopTime st : stopTimes) { - - // these trips are actually running on the next day, skip them - if (st.departure_time > 86399 || st.departure_time < 0) continue; - - LocalTime timeAtStop = LocalTime.ofSecondOfDay(st.departure_time); - - if (timeAtStop.isAfter(to) || timeAtStop.isBefore(from)) { - continue; - } - - timesAtStop.add(st.departure_time); - } - timesAtStop.sort(); - - // convert to deltas - TIntList deltas = new TIntArrayList(); - - for (int i = 0; i < timesAtStop.size() - 1; i++) { - int delta = timesAtStop.get(i + 1) - timesAtStop.get(i); - - if (delta > 60) deltas.add(delta); - } - - if (deltas.isEmpty()) return -1; - - return deltas.sum() / deltas.size(); - } - - /** - * Get the average headway, in seconds, for a route at a stop over a time window. - * @param stop_id - * @param route_id - * @param date - * @param from - * @param to - * @return avg. headway (in seconds) - */ - public int getHeadwayForStopByRoute (String stop_id, String route_id, LocalDate date, LocalTime from, LocalTime to) { - - List tripsForStop = feed.getDistinctTripsForStop(stop_id).stream() - .filter(trip -> feed.trips.get(trip.trip_id).route_id.equals(route_id)) - .filter(trip -> feed.services.get(trip.service_id).activeOn(date)) - .collect(Collectors.toList()); - - return getStopHeadwayForTrips(stop_id, tripsForStop, from, to); - } - - /** - * Returns a list of transfer performance summaries (max, min, and median wait times between routes) - * for each route pair at a stop for the specified date of service. - * @param stop_id - * @param date - * @return - */ - public List getTransferPerformance (String stop_id, LocalDate date) { - List stopTimes = feed.getStopTimesForStop(stop_id); - - Map> routeStopTimeMap = new HashMap<>(); - List transferPerformanceMap = new ArrayList<>(); - // TODO: do we need to handle interpolated stop times??? - - // first stream stopTimes for stop into route -> list of stopTimes map - stopTimes.stream() - .forEach(st -> { - Trip trip = feed.trips.get(st.trip_id); - Service service = feed.services.get(trip.service_id); - // only add to map if trip is active on given date - if (service != null && service.activeOn(date)) { - Route route = feed.routes.get(trip.route_id); - - List times = new ArrayList<>(); - if (routeStopTimeMap.containsKey(route.route_id)) { - times.addAll(routeStopTimeMap.get(route.route_id)); - } - times.add(st); - routeStopTimeMap.put(route.route_id, times); - } - }); - Map, TIntList> waitTimesByRoute = new HashMap<>(); - Map, Set>> missedTransfers = new HashMap<>(); - // iterate over every entry in route -> list of stopTimes map - for (Map.Entry> entry : routeStopTimeMap.entrySet()) { - final int MISSED_TRANSFER_THRESHOLD = 60 * 10; - List currentTimes = entry.getValue(); - - String currentRoute = entry.getKey(); - - for (StopTime currentTime : currentTimes) { - if (currentTime.arrival_time > 0) { - // cycle through all other routes that stop here. - for (Map.Entry> entry2 : routeStopTimeMap.entrySet()) { - - List compareTimes = entry2.getValue(); - String compareRoute = entry2.getKey(); - Fun.Tuple2 routeKey = new Fun.Tuple2(currentRoute, compareRoute); - if (compareRoute.equals(currentRoute)) { - continue; - } - if (!waitTimesByRoute.containsKey(routeKey)) { - waitTimesByRoute.put(routeKey, new TIntArrayList()); - } - - int shortestWait = Integer.MAX_VALUE; - // compare current time against departure times for route - for (StopTime compareTime : compareTimes) { - if (compareTime.departure_time > 0) { - int waitTime = compareTime.departure_time - currentTime.arrival_time; - - // if non-negative and shortest, save for later - if (waitTime >= 0 && waitTime < shortestWait){ - shortestWait = waitTime; - } - // otherwise, check for missed near-transfer opportunities - else { - if (waitTime < 0 && waitTime * -1 <= MISSED_TRANSFER_THRESHOLD) { - Fun.Tuple2 missedTransfer = new Fun.Tuple2(compareTime, currentTime); -// missedTransfer.add(currentTime); -// missedTransfer.add(compareTime); - if (!missedTransfers.containsKey(routeKey)) { - missedTransfers.put(routeKey, new HashSet<>()); - } - missedTransfers.get(routeKey).add(missedTransfer); - } - } - } - } - // add shortestWait for currentTime to map - if (shortestWait < Integer.MAX_VALUE) - waitTimesByRoute.get(routeKey).add(shortestWait); - } - } - } - } - for (Map.Entry, TIntList> entry : waitTimesByRoute.entrySet()) { - Fun.Tuple2 routeKey = entry.getKey(); - TIntList waitTimes = entry.getValue(); - if (waitTimes.isEmpty()) { - continue; - } - int min = waitTimes.min(); - int max = waitTimes.max(); - waitTimes.sort(); - int median = waitTimes.get(waitTimes.size() / 2); - TransferPerformanceSummary routeTransferPerformance = new TransferPerformanceSummary(routeKey.a, routeKey.b, min, max, median, missedTransfers.get(routeKey)); - transferPerformanceMap.add(routeTransferPerformance); - } - - return transferPerformanceMap; - } -} diff --git a/src/test/java/com/conveyal/gtfs/GTFSFeedTest.java b/src/test/java/com/conveyal/gtfs/GTFSFeedTest.java index f7f877069..f04c4b22a 100644 --- a/src/test/java/com/conveyal/gtfs/GTFSFeedTest.java +++ b/src/test/java/com/conveyal/gtfs/GTFSFeedTest.java @@ -170,18 +170,6 @@ public void canDoRoundtripLoadAndWriteToZipFile() throws IOException { } } - /** - * Make sure the correct timezone of a stop is returned - */ - @Test - public void canGetAgencyTimeZoneForStop() { - GTFSFeed feed = GTFSFeed.fromFile(simpleGtfsZipFileName); - assertThat( - feed.getAgencyTimeZoneForStop("4u6g").getId(), - equalTo("America/Los_Angeles") - ); - } - /** * Make sure that a GTFS feed with interpolated stop times have calculated times after feed processing * @throws GTFSFeed.FirstAndLastStopsDoNotHaveTimes @@ -232,18 +220,6 @@ public void canGetInterpolatedTimes() throws GTFSFeed.FirstAndLastStopsDoNotHave } } - /** - * Make sure a list of services for a date can be calculated - */ - @Test - public void canGetServicesForDate() { - GTFSFeed feed = GTFSFeed.fromFile(simpleGtfsZipFileName); - assertThat( - feed.getServicesForDate(LocalDate.of(2017,9,17)).get(0).service_id, - equalTo("04100312-8fe1-46a5-a9f2-556f39478f57") - ); - } - /** * Make sure a spatial index of stops can be calculated */ From 15a98f570df9503c22e17f6166fd2da5db0053af Mon Sep 17 00:00:00 2001 From: Landon Reed Date: Fri, 26 Jul 2019 10:35:13 -0400 Subject: [PATCH 3/5] ci(travis): set linux dist to trusty --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 6c517751d..7149f6c53 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: java - +dist: trusty # jdk 8 not available on xenial # This library uses Java 8 features and Travis doesn't (yet) support OpenJDK 8 jdk: - oraclejdk8 From 918cce7c3d373540cbf2c98725cb02f95ee7080f Mon Sep 17 00:00:00 2001 From: Landon Reed Date: Fri, 26 Jul 2019 10:42:08 -0400 Subject: [PATCH 4/5] refactor(stats): remove unused feed statistics --- .../com/conveyal/gtfs/FrequencySummary.java | 91 ------- src/main/java/com/conveyal/gtfs/GTFSMain.java | 3 +- .../com/conveyal/gtfs/stats/AgencyStats.java | 117 --------- .../conveyal/gtfs/stats/CalendarStats.java | 40 --- .../com/conveyal/gtfs/stats/PatternStats.java | 232 ----------------- .../com/conveyal/gtfs/stats/RouteStats.java | 235 ------------------ .../gtfs/stats/model/AgencyStatistic.java | 83 ------- .../gtfs/stats/model/FeedStatistic.java | 65 ----- .../gtfs/stats/model/PatternStatistic.java | 32 --- .../gtfs/stats/model/RouteStatistic.java | 64 ----- .../gtfs/stats/model/StopStatistic.java | 26 -- .../model/TransferPerformanceSummary.java | 42 ---- .../validator/model/ValidationResult.java | 6 +- .../validator/service/StatisticsService.java | 61 ----- .../conveyal/gtfs/stats/FeedStatsTest.java | 29 --- 15 files changed, 2 insertions(+), 1124 deletions(-) delete mode 100644 src/main/java/com/conveyal/gtfs/FrequencySummary.java delete mode 100644 src/main/java/com/conveyal/gtfs/stats/AgencyStats.java delete mode 100644 src/main/java/com/conveyal/gtfs/stats/CalendarStats.java delete mode 100644 src/main/java/com/conveyal/gtfs/stats/PatternStats.java delete mode 100644 src/main/java/com/conveyal/gtfs/stats/RouteStats.java delete mode 100644 src/main/java/com/conveyal/gtfs/stats/model/AgencyStatistic.java delete mode 100644 src/main/java/com/conveyal/gtfs/stats/model/FeedStatistic.java delete mode 100644 src/main/java/com/conveyal/gtfs/stats/model/PatternStatistic.java delete mode 100644 src/main/java/com/conveyal/gtfs/stats/model/RouteStatistic.java delete mode 100644 src/main/java/com/conveyal/gtfs/stats/model/StopStatistic.java delete mode 100644 src/main/java/com/conveyal/gtfs/stats/model/TransferPerformanceSummary.java delete mode 100644 src/main/java/com/conveyal/gtfs/validator/service/StatisticsService.java delete mode 100644 src/test/java/com/conveyal/gtfs/stats/FeedStatsTest.java diff --git a/src/main/java/com/conveyal/gtfs/FrequencySummary.java b/src/main/java/com/conveyal/gtfs/FrequencySummary.java deleted file mode 100644 index a728f7fee..000000000 --- a/src/main/java/com/conveyal/gtfs/FrequencySummary.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.conveyal.gtfs; - -import com.conveyal.gtfs.model.Route; -import com.conveyal.gtfs.model.Stop; -import com.conveyal.gtfs.stats.FeedStats; -import com.conveyal.gtfs.stats.RouteStats; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.time.LocalDate; -import java.time.LocalTime; -import java.time.format.DateTimeFormatter; -import java.util.List; - -/** - * Summarize frequencies, designed for use in the KCMO transportation system. - */ -public class FrequencySummary { - private static final LocalTime[] windows = new LocalTime[] { - LocalTime.of(6, 0), - LocalTime.of(9, 0), - LocalTime.of(16, 0), - LocalTime.of(18, 0), - LocalTime.of(22, 0) - }; - - private static final LocalDate date = LocalDate.of(2016, 8, 30); - - public static void main(String... args) throws IOException { - GTFSFeed feed = GTFSFeed.fromFile(args[0]); - - FeedStats fs = new FeedStats(feed); - RouteStats stats = new RouteStats(feed, fs); - - FileWriter writer = new FileWriter(new File(args[1])); - - writer.write("Route,AM Peak Frequency,Midday Frequency,PM Peak Frequency,Evening Frequency,AM Peak Speed,Midday Speed,PM Peak Speed,Evening Speed,Trips/Day,First trip,Last trip\n"); - - for (String route_id : feed.routes.keySet()) { - for (int direction_id : new int[] { 0, 1 }) { - StringBuilder freq = new StringBuilder(); - StringBuilder speed = new StringBuilder(); - - Route r = feed.routes.get(route_id); - - freq.append(r.route_short_name); - freq.append(" "); - freq.append(r.route_long_name); - - // guess at the direction name by finding longest pattern - List stops = feed.patterns.values().stream() - .filter(p -> p.route_id.equals(route_id) && feed.trips.get(p.associatedTrips.get(0)).direction_id == direction_id) - .sorted((p1, p2) -> p1.orderedStops.size() - p2.orderedStops.size()) - .findFirst() - .get() - .orderedStops; - - Stop lastStop = feed.stops.get(stops.get(stops.size() - 1)); - - freq.append(" towards "); - freq.append(lastStop.stop_name); - - freq.append(","); - - for (int window = 0; window < windows.length - 1; window++) { - int headwaySecs = stats.getHeadwayForRouteDirection(route_id, direction_id, date, windows[window], windows[window + 1]); - freq.append(headwaySecs > 0 ? Math.round(headwaySecs / 60 ) : "-"); - freq.append(","); - - double speedMs = stats.getSpeedForRouteDirection(route_id, direction_id, date, windows[window], windows[window + 1]); - speed.append(Double.isNaN(speedMs) ? "-" : Math.round(speedMs * 3600 / 1609.0 )); - speed.append(","); - } - - speed.append(stats.getTripsPerDateOfService(route_id).get(date).stream().filter(t -> t.direction_id == direction_id).count()); - speed.append(","); - speed.append(stats.getStartTimeForRouteDirection(route_id, direction_id, date).format(DateTimeFormatter.ofPattern("K:mm a"))); - speed.append(","); - speed.append(stats.getEndTimeForRouteDirection(route_id, direction_id, date).format(DateTimeFormatter.ofPattern("K:mm a"))); - - writer.write(freq.toString()); - writer.write(speed.toString()); - writer.write("\n"); - } - } - - writer.flush(); - writer.close(); - } -} diff --git a/src/main/java/com/conveyal/gtfs/GTFSMain.java b/src/main/java/com/conveyal/gtfs/GTFSMain.java index de7665dea..8003ef96d 100644 --- a/src/main/java/com/conveyal/gtfs/GTFSMain.java +++ b/src/main/java/com/conveyal/gtfs/GTFSMain.java @@ -1,6 +1,5 @@ package com.conveyal.gtfs; -import com.conveyal.gtfs.stats.FeedStats; import com.conveyal.gtfs.util.json.JsonManager; import com.conveyal.gtfs.validator.model.ValidationResult; import org.apache.commons.cli.CommandLine; @@ -41,7 +40,7 @@ public static void main (String[] args) throws Exception { if(cmd.hasOption("validate")) { feed.validate(); JsonManager json = new JsonManager(ValidationResult.class); - ValidationResult result = new ValidationResult(arguments[0], feed, new FeedStats(feed)); + ValidationResult result = new ValidationResult(arguments[0], feed); String resultString = json.writePretty(result); File resultFile; if (arguments.length >= 2) { diff --git a/src/main/java/com/conveyal/gtfs/stats/AgencyStats.java b/src/main/java/com/conveyal/gtfs/stats/AgencyStats.java deleted file mode 100644 index 5c4d847be..000000000 --- a/src/main/java/com/conveyal/gtfs/stats/AgencyStats.java +++ /dev/null @@ -1,117 +0,0 @@ -package com.conveyal.gtfs.stats; - -import com.conveyal.gtfs.GTFSFeed; -import com.conveyal.gtfs.model.Route; -import com.conveyal.gtfs.model.Service; -import com.conveyal.gtfs.model.Stop; -import com.conveyal.gtfs.model.StopTime; -import com.conveyal.gtfs.model.Trip; - -import java.time.LocalDate; -import java.time.format.DateTimeFormatter; - -/** - * Created by landon on 9/2/16. - */ -public class AgencyStats { - private GTFSFeed feed = null; - - public static Integer getRouteCount(GTFSFeed feed, String agencyId) { - int count = 0; - for (Route route : feed.routes.values()) { - if (agencyId.equals(route.agency_id)) { - count++; - } - } - return count; - } - - public static Integer getTripCount(GTFSFeed feed, String agencyId) { - int count = 0; - for (Trip trip : feed.trips.values()) { - Route route = feed.routes.get(trip.route_id); - if (agencyId.equals(route.agency_id)) { - count++; - } - } - return count; - } - - public static Integer getStopCount(GTFSFeed feed, String agencyId) { - int count = 0; - for (Stop stop : feed.stops.values()) { -// AgencyAndId id = stop.stop_id; -// if (agencyId.equals(id.getAgencyId())) { - count++; -// } - } - return count; - } - - public static Integer getStopTimesCount(GTFSFeed feed, String agencyId) { - int count = 0; - for (StopTime stopTime : feed.stop_times.values()) { - Trip trip = feed.trips.get(stopTime.trip_id); - Route route = feed.routes.get(trip.route_id); - if (agencyId.equals(route.agency_id)) { - count++; - } - } - return count; - } - - public static LocalDate getCalendarServiceRangeStart(GTFSFeed feed, String agencyId) { - int startDate = 0; - for (Service service : feed.services.values()) { -// if (agencyId.equals(service.agency_id)) { -// if (startDate == 0 -// || service.calendar.start_date < startDate) -// startDate = service.calendar.start_date; -// } - } - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd"); - return LocalDate.parse(String.valueOf(startDate), formatter); - } - - public static LocalDate getCalendarServiceRangeEnd(GTFSFeed feed, String agencyId) { - int endDate = 0; - - for (Service service : feed.services.values()) { -// if (agencyId.equals(service.agency_id)) { -// if (endDate == 0 -// || service.calendar.end_date > endDate) -// endDate = service.calendar.end_date; -// } - } - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd"); - return LocalDate.parse(String.valueOf(endDate), formatter); - } - - public static LocalDate getCalendarDateStart(GTFSFeed feed, String agencyId) { - LocalDate startDate = null; - for (Service service : feed.services.values()) { - for (LocalDate date : service.calendar_dates.keySet()) { -// if (agencyId.equals(serviceCalendarDate.getServiceId().getAgencyId())) { - if (startDate == null - || date.isBefore(startDate)) - startDate = date; -// } - } - } - return startDate; - } - - public static LocalDate getCalendarDateEnd(GTFSFeed feed, String agencyId) { - LocalDate endDate = null; - for (Service service : feed.services.values()) { - for (LocalDate date : service.calendar_dates.keySet()) { -// if (agencyId.equals(serviceCalendarDate.getServiceId().getAgencyId())) { - if (endDate == null - || date.isAfter(endDate)) - endDate = date; -// } - } - } - return endDate; - } -} diff --git a/src/main/java/com/conveyal/gtfs/stats/CalendarStats.java b/src/main/java/com/conveyal/gtfs/stats/CalendarStats.java deleted file mode 100644 index 6a860435a..000000000 --- a/src/main/java/com/conveyal/gtfs/stats/CalendarStats.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.conveyal.gtfs.stats; - -import com.conveyal.gtfs.GTFSFeed; -import com.conveyal.gtfs.model.Service; - -import java.time.LocalDate; -import java.time.temporal.ChronoUnit; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -/** - * Created by landon on 9/2/16. - */ -public class CalendarStats { - private GTFSFeed feed = null; - private FeedStats stats = null; - -// public CalendarStats (GTFSFeed f, FeedStats fs) { -// feed = f; -// stats = fs; -// } - -// public Set getServiceIdsForDates (LocalDate from, LocalDate to) { -// long days = ChronoUnit.DAYS.between(from, to); -// -// return feed.services.values().stream() -// .filter(s -> { -// for (int i = 0; i < days; i++) { -// LocalDate date = from.plusDays(i); -// if (s.activeOn(date)) { -// return true; -// } -// } -// return false; -// }) -// .map(s -> s.service_id) -// .collect(Collectors.toSet()); -// } -} diff --git a/src/main/java/com/conveyal/gtfs/stats/PatternStats.java b/src/main/java/com/conveyal/gtfs/stats/PatternStats.java deleted file mode 100644 index 3ab89442b..000000000 --- a/src/main/java/com/conveyal/gtfs/stats/PatternStats.java +++ /dev/null @@ -1,232 +0,0 @@ -package com.conveyal.gtfs.stats; - -import com.conveyal.gtfs.GTFSFeed; -import com.conveyal.gtfs.model.Pattern; -import com.conveyal.gtfs.model.StopTime; -import com.conveyal.gtfs.model.Trip; -import gnu.trove.list.TDoubleList; -import gnu.trove.list.TIntList; -import gnu.trove.list.array.TDoubleArrayList; -import gnu.trove.list.array.TIntArrayList; -import org.mapdb.Fun; - -import java.time.LocalDate; -import java.time.LocalTime; -import java.util.Collection; -import java.util.List; -import java.util.Spliterator; -import java.util.stream.Collectors; -import java.util.stream.StreamSupport; - -/** - * Created by landon on 9/2/16. - */ -public class PatternStats { - - private GTFSFeed feed = null; - private FeedStats stats = null; - - public PatternStats (GTFSFeed f, FeedStats fs) { - feed = f; - stats = fs; - } - - /** - * Gets the pattern speed for a given pattern for a specified date and time window. - * @param pattern_id pattern ID - * @param date service date - * @param from beginning of time window - * @param to end of time window - * @return - */ - public double getPatternSpeed (String pattern_id, LocalDate date, LocalTime from, LocalTime to) { - - List trips = getTripsForDate(pattern_id, date); - - return getAverageSpeedForTrips(trips, from, to); - } - - /** - * Get average speed for set of trips that begin within the time window in meters per second. - * @param trips - * @param from - * @param to - * @return avg. speed (meters per second) - */ - public double getAverageSpeedForTrips (Collection trips, LocalTime from, LocalTime to) { - TDoubleList speeds = new TDoubleArrayList(); - - for (Trip trip : trips) { - StopTime firstStopTime = feed.stop_times.ceilingEntry(Fun.t2(trip.trip_id, null)).getValue(); - LocalTime tripBeginTime = LocalTime.ofSecondOfDay(firstStopTime.departure_time % 86399); // convert 24hr+ seconds to 0 - 86399 - - // skip trip if begin time is before or after specified time period - if (tripBeginTime.isAfter(to) || tripBeginTime.isBefore(from)) { - continue; - } - // TODO: swap straight lines for actual geometry? - double speed = feed.getTripSpeed(trip.trip_id, true); - - if (!Double.isNaN(speed)) { - speeds.add(speed); - } - } - - if (speeds.isEmpty()) return -1; - - return speeds.sum() / speeds.size(); - } - - /** - * Get earliest departure time for a set of trips. - * @param trips - * @return earliest departure time - */ - public LocalTime getStartTimeForTrips (Collection trips) { - int earliestDeparture = Integer.MAX_VALUE; - - for (Trip trip : trips) { - StopTime st = feed.getOrderedStopTimesForTrip(trip.trip_id).iterator().next(); - int dep = st.departure_time; - - // these trips begin on the next day, so we need to cast them to 0 - 86399 - if (dep > 86399) { - dep = dep % 86399; - } - - if (dep <= earliestDeparture) { - earliestDeparture = dep; - } - } - return LocalTime.ofSecondOfDay(earliestDeparture); - } - - /** - * Get last arrival time for a set of trips. - * @param trips - * @return last arrival time (if arrival occurs after midnight, time is expressed in terms of following day, e.g., 2:00 AM) - */ - public LocalTime getEndTimeForTrips (Collection trips) { - int latestArrival = Integer.MIN_VALUE; - - for (Trip trip : trips) { - StopTime st = feed.getOrderedStopTimesForTrip(trip.trip_id).iterator().next(); - - if (st.arrival_time >= latestArrival) { - latestArrival = st.arrival_time; - } - } - - // return end time as 2:00 am if last arrival occurs after midnight - return LocalTime.ofSecondOfDay(latestArrival % 86399); - } - - /** - * Get total revenue time (in seconds) for set of trips. - * @param trips - * @return total revenue time (in seconds) - */ - public long getTotalRevenueTimeForTrips (Collection trips) { - TIntList times = new TIntArrayList(); - for (Trip trip : trips) { - StopTime first; - StopTime last; - Spliterator stopTimes = feed.getOrderedStopTimesForTrip(trip.trip_id).spliterator();; - - first = StreamSupport.stream(stopTimes, false) - .findFirst() - .orElse(null); - - last = StreamSupport.stream(stopTimes, false) - .reduce((a, b) -> b) - .orElse(null); - - if (last != null && first != null) { - // revenue time should not include layovers at termini - int time = last.arrival_time - first.departure_time; - - times.add(time); - } - } - - return times.sum(); - } - - /** - * Get total revenue distance (in meters) for set of trips. - * @param trips - * @return total trip distance (in meters) - */ - public double getTotalDistanceForTrips (Collection trips) { - TDoubleList distances = new TDoubleArrayList(); - for (Trip trip : trips) { - distances.add(feed.getTripDistance(trip.trip_id, false)); - } - - return distances.sum(); - } - - /** - * Get distance for a pattern. Uses the first trip associated with the pattern. - * @param pattern_id - * @return distance (in meters) - */ - public double getPatternDistance (String pattern_id) { - Pattern pattern = feed.patterns.get(pattern_id); - - return feed.getTripDistance(pattern.associatedTrips.iterator().next(), false); - } - - /** - * Get average stop spacing for a pattern. - * @param pattern_id - * @return avg. stop spacing (in meters) - */ - public double getAverageStopSpacing (String pattern_id) { - Pattern pattern = feed.patterns.get(pattern_id); - return getPatternDistance(pattern_id) / pattern.orderedStops.size(); - } - - /** - * - * @param pattern_id pattern ID - * @param date service date - * @param from beginning of time window - * @param to end of time window - * @return - */ - public int getHeadwayForPattern (String pattern_id, LocalDate date, LocalTime from, LocalTime to) { - - List tripsForPattern = getTripsForDate(pattern_id, date); - - String commonStop = stats.route.getCommonStopForTrips(tripsForPattern); - if (commonStop == null) return -1; - - return stats.stop.getStopHeadwayForTrips(commonStop, tripsForPattern, from, to); - } - - /** - * - * @param pattern_id pattern ID - * @param date service date - * @return list of trips - */ - public long getTripCountForDate (String pattern_id, LocalDate date) { - return getTripsForDate(pattern_id, date).size(); - } - - /** - * - * @param pattern_id pattern ID - * @param date service date - * @return list of trips - */ - public List getTripsForDate (String pattern_id, LocalDate date) { - Pattern pattern = feed.patterns.get(pattern_id); - if (pattern == null) return null; - - return stats.getTripsForDate(date).stream() - .filter(trip -> pattern.associatedTrips.contains(trip.trip_id)) - .collect(Collectors.toList()); - } -} diff --git a/src/main/java/com/conveyal/gtfs/stats/RouteStats.java b/src/main/java/com/conveyal/gtfs/stats/RouteStats.java deleted file mode 100644 index 127978000..000000000 --- a/src/main/java/com/conveyal/gtfs/stats/RouteStats.java +++ /dev/null @@ -1,235 +0,0 @@ -package com.conveyal.gtfs.stats; - -import com.conveyal.gtfs.GTFSFeed; -import com.conveyal.gtfs.model.Pattern; -import com.conveyal.gtfs.model.Route; -import com.conveyal.gtfs.model.Service; -import com.conveyal.gtfs.model.Trip; -import com.conveyal.gtfs.stats.model.RouteStatistic; - -import java.time.LocalDate; -import java.time.LocalTime; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -/** - * Created by landon on 9/2/16. - */ -public class RouteStats { - private GTFSFeed feed = null; - private FeedStats stats = null; - private PatternStats patternStats = null; - private StopStats stopStats = null; - - public RouteStats (GTFSFeed f, FeedStats fs) { - feed = f; - stats = fs; - patternStats = stats.pattern; - stopStats = stats.stop; - } - - public List getStatisticForAll (LocalDate date, LocalTime from, LocalTime to) { - List stats = new ArrayList<>(); - - for (String id : feed.routes.keySet()) { - stats.add(getStatisticForRoute(id, date, from, to)); - } - return stats; - } - - public String getStatisticForAllAsCsv (LocalDate date, LocalTime from, LocalTime to) { - List stats = getStatisticForAll(date, from, to); - StringBuffer buffer = new StringBuffer(); - buffer.append(RouteStatistic.getHeaderAsCsv()); - for (RouteStatistic rs : stats) { - buffer.append(System.getProperty("line.separator")); - buffer.append(rs.asCsv()); - } - - return buffer.toString(); - } - - public String getRouteName (String route_id) { - Route route = feed.routes.get(route_id); - return route != null ? route.route_short_name + " - " + route.route_long_name : null; - } - - /** - * Get average speed on a direction of a route, in meters per second. - * @param route_id - * @param direction_id - * @param date - * @param from - * @param to - * @return avg. speed (meters per second) - */ - public double getSpeedForRouteDirection (String route_id, int direction_id, LocalDate date, LocalTime from, LocalTime to) { - List tripsForRouteDirection = getTripsForDate(route_id, date).stream() - .filter(t -> t.direction_id == direction_id) - .collect(Collectors.toList()); - - return patternStats.getAverageSpeedForTrips(tripsForRouteDirection, from, to); - } - - /** - * Get the average headway for a route direction for a specified service date and time window, in seconds. - * @param route_id - * @param direction_id - * @param date - * @param from - * @param to - * @return avg. headway in seconds - */ - public int getHeadwayForRouteDirection (String route_id, int direction_id, LocalDate date, LocalTime from, LocalTime to) { - List tripsForRouteDirection = getTripsForDate(route_id, date).stream() - .filter(t -> t.direction_id == direction_id) - .collect(Collectors.toList()); - - String commonStop = getCommonStopForTrips(tripsForRouteDirection); - if (commonStop == null) return -1; - - return stats.stop.getStopHeadwayForTrips(commonStop, tripsForRouteDirection, from, to); - } - - public String getCommonStopForTrips(List trips) { - Set commonStops = null; - - for (Trip trip : trips) { - List stops = feed.getOrderedStopListForTrip(trip.trip_id); - - if (commonStops == null) { - commonStops = new HashSet<>(stops); - } else { - commonStops.retainAll(stops); - } - } - - if (commonStops == null || commonStops.isEmpty()) return null; - - String commonStop = commonStops.iterator().next(); - return commonStop; - } - - /** - * Get earliest departure time for a given route direction on the specified date. - * @param route_id - * @param direction_id - * @param date - * @return earliest departure time - */ - public LocalTime getStartTimeForRouteDirection (String route_id, int direction_id, LocalDate date) { - - - List tripsForRouteDirection = getTripsForDate(route_id, date).stream() - .filter(t -> t.direction_id == direction_id) - .collect(Collectors.toList()); - - return patternStats.getStartTimeForTrips(tripsForRouteDirection); - } - - /** - * Get latest arrival time for a given route direction on the specified date. - * @param route_id - * @param direction_id - * @param date - * @return last arrival time - */ - public LocalTime getEndTimeForRouteDirection (String route_id, int direction_id, LocalDate date) { - List tripsForRouteDirection = getTripsForDate(route_id, date).stream() - .filter(t -> t.direction_id == direction_id) - .collect(Collectors.toList()); - - return patternStats.getEndTimeForTrips(tripsForRouteDirection); - } - - public Map getTripCountPerDateOfService(String route_id) { - - Route route = feed.routes.get(route_id); - if (route == null) return null; - - Map> tripsPerDate = getTripsPerDateOfService(route_id); - Map tripCountPerDate = new HashMap<>(); - for (Map.Entry> entry : tripsPerDate.entrySet()) { - LocalDate date = entry.getKey(); - Integer count = entry.getValue().size(); - tripCountPerDate.put(date, count); - } - - return tripCountPerDate; - } - - /** - * Returns a map of dates to list of trips for a given route. - * @param route_id - * @return mapping of trips to dates - */ - public Map> getTripsPerDateOfService(String route_id) { - Map> tripsPerDate = stats.getTripsPerDateOfService(); - for (Map.Entry> e : tripsPerDate.entrySet()) { - LocalDate date = e.getKey(); - List trips = e.getValue().stream() - .filter(t -> t.route_id.equals(route_id)) - .collect(Collectors.toList()); - tripsPerDate.put(date, trips); - } - - return tripsPerDate; - } - - /** - * Gets all trips for a given route that operate on the specified date. - * @param route_id - * @param date - * @return - */ - public List getTripsForDate (String route_id, LocalDate date) { - Route route = feed.routes.get(route_id); - if (route == null) return null; - - List trips = stats.getTripsForDate(date).stream() - .filter(trip -> route_id.equals(trip.route_id)) - .collect(Collectors.toList()); - return trips; - } - - public long getTripCountForDate (String route_id, LocalDate date) { - return getTripsForDate(route_id, date).size(); - } - - /** - * Get average stop spacing for a route. - * @param route_id - * @return avg. stop spacing (in meters) - */ - public double getAverageStopSpacing (String route_id) { - return feed.patterns.values().stream() - .filter(p -> p.route_id.equals(route_id)) - .map(p -> stats.pattern.getAverageStopSpacing(p.pattern_id)) - .mapToDouble(headway -> headway) - .average() - .getAsDouble(); - } - - public RouteStatistic getStatisticForRoute (String route_id, LocalDate date, LocalTime from, LocalTime to) { - RouteStatistic rs = new RouteStatistic(this, route_id, date, from, to); - - return rs; - } - - public String getKCMetroStatistics () { - for (Route route : feed.routes.values()) { - - } - return null; - } - - public String getStatisticsAsCsv () { - return null; - } -} diff --git a/src/main/java/com/conveyal/gtfs/stats/model/AgencyStatistic.java b/src/main/java/com/conveyal/gtfs/stats/model/AgencyStatistic.java deleted file mode 100644 index 1f9046862..000000000 --- a/src/main/java/com/conveyal/gtfs/stats/model/AgencyStatistic.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.conveyal.gtfs.stats.model; - -import java.awt.geom.Rectangle2D; -import java.io.Serializable; -import java.time.LocalDate; - -/** - * Model object representing statistics about GTFS. - * - */ -public class AgencyStatistic implements Serializable { - private String agencyId; - private Integer routeCount; - private Integer tripCount; - private Integer stopCount; - private Integer stopTimeCount; - private LocalDate calendarServiceStart; - private LocalDate calendarServiceEnd; - private LocalDate calendarStartDate; - private LocalDate calendarEndDate; - private Rectangle2D bounds; - - public String getAgencyId() { - return agencyId; - } - public void setAgencyId(String agencyId) { - this.agencyId = agencyId; - } - public Integer getRouteCount() { - return routeCount; - } - public void setRouteCount(Integer routeCount) { - this.routeCount = routeCount; - } - public Integer getTripCount() { - return tripCount; - } - public void setTripCount(Integer tripCount) { - this.tripCount = tripCount; - } - public Integer getStopCount() { - return stopCount; - } - public void setStopCount(Integer stopCount) { - this.stopCount = stopCount; - } - public Integer getStopTimeCount() { - return stopTimeCount; - } - public void setStopTimeCount(Integer stopTimeCount) { - this.stopTimeCount = stopTimeCount; - } - public LocalDate getCalendarStartDate() { - return calendarStartDate; - } - public void setCalendarStartDate(LocalDate calendarStartDate) { - this.calendarStartDate = calendarStartDate; - } - public LocalDate getCalendarEndDate() { - return calendarEndDate; - } - public void setCalendarEndDate(LocalDate calendarEndDate) { - this.calendarEndDate = calendarEndDate; - } - public LocalDate getCalendarServiceStart() { - return calendarServiceStart; - } - public void setCalendarServiceStart(LocalDate calendarServiceStart) { - this.calendarServiceStart = calendarServiceStart; - } - public LocalDate getCalendarServiceEnd() { - return calendarServiceEnd; - } - public void setCalendarServiceEnd(LocalDate calendarServiceEnd) { - this.calendarServiceEnd = calendarServiceEnd; - } - public Rectangle2D getBounds() { - return bounds; - } - public void setBounds(Rectangle2D bounds) { - this.bounds = bounds; - } -} diff --git a/src/main/java/com/conveyal/gtfs/stats/model/FeedStatistic.java b/src/main/java/com/conveyal/gtfs/stats/model/FeedStatistic.java deleted file mode 100644 index f7c987b44..000000000 --- a/src/main/java/com/conveyal/gtfs/stats/model/FeedStatistic.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.conveyal.gtfs.stats.model; - -import com.conveyal.gtfs.stats.FeedStats; -import com.vividsolutions.jts.geom.Geometry; - -import java.awt.geom.Rectangle2D; -import java.io.Serializable; -import java.time.LocalDate; -import java.time.LocalTime; -import java.util.List; -import java.util.stream.Collectors; - -/** - * Created by landon on 10/11/16. - */ -public class FeedStatistic implements Serializable { - - public String feed_id; - public int headway; - public Double avgSpeed; - public long revenueTime; - public LocalDate startDate; - public LocalDate endDate; - public long agencyCount; - public long routeCount; - public long stopCount; - public long tripCount; - public long frequencyCount; - public long stopTimeCount; - public long shapePointCount; - public long fareAttributeCount; - public long fareRuleCount; - public long serviceCount; - public List datesOfService; - public Rectangle2D bounds; - public Geometry mergedBuffers; - - public FeedStatistic (FeedStats stats, LocalDate date, LocalTime from, LocalTime to) { - feed_id = stats.feed_id; - headway = stats.getDailyAverageHeadway(date, from, to); - avgSpeed = stats.getAverageTripSpeed(date, from, to); - tripCount = stats.getTripCount(date); - revenueTime = stats.getTotalRevenueTimeForDate(date); - } - - public FeedStatistic (FeedStats stats) { - feed_id = stats.feed_id; - this.startDate = stats.getStartDate(); - this.endDate = stats.getEndDate(); - this.agencyCount = stats.getAgencyCount(); - this.routeCount = stats.getRouteCount(); - this.stopCount = stats.getStopCount(); - this.tripCount = stats.getTripCount(); - this.frequencyCount = stats.getFrequencyCount(); - this.stopTimeCount = stats.getStopTimesCount(); - this.shapePointCount = stats.getShapePointCount(); - this.fareAttributeCount = stats.getFareAttributeCount(); - this.fareRuleCount = stats.getFareRulesCount(); - this.serviceCount= stats.getServiceCount(); - this.datesOfService = stats.getDatesOfService(); - this.bounds = stats.getBounds(); - this.revenueTime = stats.getAverageWeekdayRevenueTime(); - this.mergedBuffers = stats.getMergedBuffers(); - } -} diff --git a/src/main/java/com/conveyal/gtfs/stats/model/PatternStatistic.java b/src/main/java/com/conveyal/gtfs/stats/model/PatternStatistic.java deleted file mode 100644 index 4fde536a0..000000000 --- a/src/main/java/com/conveyal/gtfs/stats/model/PatternStatistic.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.conveyal.gtfs.stats.model; - -import com.conveyal.gtfs.stats.PatternStats; - -import java.io.Serializable; -import java.time.LocalDate; -import java.time.LocalTime; - -/** - * Created by landon on 10/11/16. - */ -public class PatternStatistic implements Serializable { - - public String pattern_id; - public int headway; - public Double avgSpeed; - public long tripCount; - public double stopSpacing; -// public Double avgSpeedOffPeak; -// private LocalDate calendarServiceEnd; -// private LocalDate calendarStartDate; -// private LocalDate calendarEndDate; -// private Rectangle2D bounds; - - public PatternStatistic (PatternStats stats, String pattern_id, LocalDate date, LocalTime from, LocalTime to) { - this.pattern_id = pattern_id; - headway = stats.getHeadwayForPattern(this.pattern_id, date, from, to); - avgSpeed = stats.getPatternSpeed(this.pattern_id, date, from, to); - tripCount = stats.getTripCountForDate(this.pattern_id, date); - stopSpacing = stats.getAverageStopSpacing(this.pattern_id); - } -} diff --git a/src/main/java/com/conveyal/gtfs/stats/model/RouteStatistic.java b/src/main/java/com/conveyal/gtfs/stats/model/RouteStatistic.java deleted file mode 100644 index e29a8cc57..000000000 --- a/src/main/java/com/conveyal/gtfs/stats/model/RouteStatistic.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.conveyal.gtfs.stats.model; - -import com.conveyal.gtfs.GTFSFeed; -import com.conveyal.gtfs.stats.FeedStats; -import com.conveyal.gtfs.stats.RouteStats; - -import java.awt.geom.Rectangle2D; -import java.io.Serializable; -import java.time.LocalDate; -import java.time.LocalTime; - -/** - * Created by landon on 9/2/16. - */ -public class RouteStatistic implements Serializable { - public String route_id; - public String routeName; - public int headway; - public Double avgSpeed; - public long tripCount; - public double stopSpacing; -// public Double avgSpeedOffPeak; -// private LocalDate calendarServiceEnd; -// private LocalDate calendarStartDate; -// private LocalDate calendarEndDate; -// private Rectangle2D bounds; - - public RouteStatistic (RouteStats stats, String route_id, LocalDate date, LocalTime from, LocalTime to) { - this.route_id = route_id; - routeName = stats.getRouteName(route_id); - // TODO: add fields for inbound and outbound directions - headway = stats.getHeadwayForRouteDirection(this.route_id, 0, date, from, to); - avgSpeed = stats.getSpeedForRouteDirection(this.route_id, 0, date, from, to); - tripCount = stats.getTripCountForDate(this.route_id, date); - stopSpacing = stats.getAverageStopSpacing(this.route_id); - } - - public static String getHeaderAsCsv () { - StringBuffer buffer = new StringBuffer(); - - buffer.append("route_id"); - buffer.append(","); - buffer.append("routeName"); - buffer.append(","); - buffer.append("headway"); - buffer.append(","); - buffer.append("avgSpeed"); - - return buffer.toString(); - } - public String asCsv () { - StringBuffer buffer = new StringBuffer(); - - buffer.append(route_id); - buffer.append(","); - buffer.append(routeName); - buffer.append(","); - buffer.append(headway); - buffer.append(","); - buffer.append(avgSpeed); - - return buffer.toString(); - } -} diff --git a/src/main/java/com/conveyal/gtfs/stats/model/StopStatistic.java b/src/main/java/com/conveyal/gtfs/stats/model/StopStatistic.java deleted file mode 100644 index 85dfd2b39..000000000 --- a/src/main/java/com/conveyal/gtfs/stats/model/StopStatistic.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.conveyal.gtfs.stats.model; - -import com.conveyal.gtfs.stats.StopStats; - -import java.io.Serializable; -import java.time.LocalDate; -import java.time.LocalTime; - -/** - * Created by landon on 10/4/16. - */ -public class StopStatistic implements Serializable { - public String stop_id; - public int headway; - public int routeCount; - public int tripCount; -// public TransferPerformanceSummary transferPerformanceSummary; - - public StopStatistic (StopStats stats, String stop_id, LocalDate date, LocalTime from, LocalTime to) { - this.stop_id = stop_id; - headway = stats.getAverageHeadwayForStop(stop_id, date, from, to); - routeCount = stats.getRouteCount(stop_id); - tripCount = stats.getTripCountForDate(stop_id, date); // TODO: filter by time window? -// transferPerformanceSummary = new TransferPerformanceSummary(stats, stop_id, date); - } -} diff --git a/src/main/java/com/conveyal/gtfs/stats/model/TransferPerformanceSummary.java b/src/main/java/com/conveyal/gtfs/stats/model/TransferPerformanceSummary.java deleted file mode 100644 index f9c6f55cb..000000000 --- a/src/main/java/com/conveyal/gtfs/stats/model/TransferPerformanceSummary.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.conveyal.gtfs.stats.model; - -import com.conveyal.gtfs.model.StopTime; -import org.mapdb.Fun; - -import java.io.Serializable; -import java.util.Set; - -/** - * Created by landon on 10/4/16. - */ -public class TransferPerformanceSummary implements Serializable { - public String fromRoute; - public String toRoute; - public int bestCase; - public int worstCase; - public int typicalCase; - public Set> missedOpportunities; - - /** - * - * @param fromRoute - * @param toRoute - * @param minWaitTime - * @param maxWaitTime - * @param avgWaitTime - * @param missedTransfers - */ - public TransferPerformanceSummary (String fromRoute, String toRoute, int minWaitTime, int maxWaitTime, int avgWaitTime, Set> missedTransfers) { - this.fromRoute = fromRoute; - this.toRoute = toRoute; - bestCase = minWaitTime; - worstCase = maxWaitTime; - typicalCase = avgWaitTime; - missedOpportunities = missedTransfers; - } - - public String toString () { - return String.format("From routes %s to %s, the best case transfer time is %d seconds, worst case is %d seconds, and typical case is %d seconds. %d missed near-transfer opportunities.", fromRoute, toRoute, bestCase, worstCase, typicalCase, missedOpportunities.size()); - } - -} diff --git a/src/main/java/com/conveyal/gtfs/validator/model/ValidationResult.java b/src/main/java/com/conveyal/gtfs/validator/model/ValidationResult.java index 09e5cd202..e1427c55a 100644 --- a/src/main/java/com/conveyal/gtfs/validator/model/ValidationResult.java +++ b/src/main/java/com/conveyal/gtfs/validator/model/ValidationResult.java @@ -2,8 +2,6 @@ import com.conveyal.gtfs.GTFSFeed; import com.conveyal.gtfs.error.GTFSError; -import com.conveyal.gtfs.stats.FeedStats; -import com.conveyal.gtfs.stats.model.FeedStatistic; import java.io.Serializable; import java.util.Date; @@ -13,14 +11,12 @@ public class ValidationResult implements Serializable { public String fileName; public String validationTimestamp; - public FeedStatistic feedStatistics; public long errorCount; public NavigableSet errors; - public ValidationResult (String fileName, GTFSFeed feed, FeedStats feedStats) { + public ValidationResult (String fileName, GTFSFeed feed) { this.fileName = fileName; this.validationTimestamp = new Date().toString(); - this.feedStatistics = new FeedStatistic(feedStats); this.errorCount = feed.errors.size(); this.errors = feed.errors; } diff --git a/src/main/java/com/conveyal/gtfs/validator/service/StatisticsService.java b/src/main/java/com/conveyal/gtfs/validator/service/StatisticsService.java deleted file mode 100644 index ca21cba8c..000000000 --- a/src/main/java/com/conveyal/gtfs/validator/service/StatisticsService.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.conveyal.gtfs.validator.service; - -import com.conveyal.gtfs.stats.model.AgencyStatistic; - -import java.awt.geom.Rectangle2D; -import java.time.LocalDate; - -/** - * Provides statistics for: - * - *
  • Agencies - *
  • Routes - *
  • Trips - *
  • Stops - *
  • Stop Times - *
  • Calendar Date ranges - *
  • Calendar Service exceptions - * - * @author dev - * - */ -public interface StatisticsService { - - Integer getAgencyCount(); - - Integer getRouteCount(); - - Integer getTripCount(); - - Integer getStopCount(); - - Integer getStopTimesCount(); - - LocalDate getCalendarDateStart(); - - LocalDate getCalendarDateEnd(); - - LocalDate getCalendarServiceRangeStart(); - - LocalDate getCalendarServiceRangeEnd(); - - Integer getRouteCount(String agencyId); - - Integer getTripCount(String agencyId); - - Integer getStopCount(String agencyId); - - Integer getStopTimesCount(String agencyId); - - LocalDate getCalendarDateStart(String agencyId); - - LocalDate getCalendarDateEnd(String agencyId); - - LocalDate getCalendarServiceRangeStart(String agencyId); - - LocalDate getCalendarServiceRangeEnd(String agencyId); - - Rectangle2D getBounds(); - - AgencyStatistic getStatistic(String agencyId); -} diff --git a/src/test/java/com/conveyal/gtfs/stats/FeedStatsTest.java b/src/test/java/com/conveyal/gtfs/stats/FeedStatsTest.java deleted file mode 100644 index da30e88c2..000000000 --- a/src/test/java/com/conveyal/gtfs/stats/FeedStatsTest.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.conveyal.gtfs.stats; - -import com.conveyal.gtfs.GTFSFeed; - -import org.junit.Test; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.equalTo; - -/** - * Unit tests to verify functionality of items with the FeedStats class. - */ -public class FeedStatsTest { - - /***************************************** - * getAverageWeekdayRevenueTime - *****************************************/ - - /** - * This test makes sure that a FeedStats is able to run the getAverageWeekdayRevenueTime method - * when given an empty GTFSFeed instance. - */ - @Test - public void canCalculateWithEmptyFeed() { - GTFSFeed feed = new GTFSFeed(); - FeedStats feedStats = new FeedStats(feed); - assertThat(feedStats.getAverageWeekdayRevenueTime(), equalTo(0L)); - } -} From c5d4eba20d0e29df36dcc15598dee6de29163ca6 Mon Sep 17 00:00:00 2001 From: Landon Reed Date: Fri, 26 Jul 2019 14:13:53 -0400 Subject: [PATCH 5/5] refactor(GTFSFeed): remove commented out code BREAKING CHANGE: This PR removes a few heavyweight indexes that are no longer used. It also removes the FeedStats class/stats package. --- src/main/java/com/conveyal/gtfs/GTFSFeed.java | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/main/java/com/conveyal/gtfs/GTFSFeed.java b/src/main/java/com/conveyal/gtfs/GTFSFeed.java index b7d5572ca..1e3c52f74 100644 --- a/src/main/java/com/conveyal/gtfs/GTFSFeed.java +++ b/src/main/java/com/conveyal/gtfs/GTFSFeed.java @@ -234,15 +234,7 @@ public void toFile (String file) { throw new RuntimeException(e); } } -// public void validate (EventBus eventBus, Validator... validators) { -// if (eventBus == null) { -// -// } -// for (Validator validator : validators) { -// validator.getClass().getSimpleName(); -// validator.validate(this, false); -// } -// } + public void validate (boolean repair, Validator... validators) { long startValidation = System.currentTimeMillis(); for (Validator validator : validators) {