Exemple #1
0
        public (BusSystemData data, List <string> errors) LoadTransitData()
        {
            var connexionzPlatforms = ConnexionzClient.LoadPlatforms();
            var connexionzRoutes    = ConnexionzClient.LoadRoutes();
            var googleData          = GoogleTransitClient.LoadData();

            var routes = CreateRoutes(googleData.Routes, connexionzRoutes);
            var stops  = CreateStops(connexionzPlatforms, connexionzRoutes);

            var staticData = new BusStaticData(
                routes: routes.ToDictionary(r => r.RouteNo),
                stops: stops.ToDictionary(s => s.Id)
                );

            var platformTagsLookup = connexionzPlatforms.ToDictionary(p => p.PlatformNo, p => p.PlatformTag);
            var schedule           = CreateSchedule(googleData.Schedules, connexionzRoutes, connexionzPlatforms);

            var transitData = new BusSystemData(
                staticData,
                schedule,
                platformTagsLookup);

            var errors = ValidateTransitData(transitData);

            return(transitData, errors);
        }
Exemple #2
0
        public static List <string> ValidateTransitData(BusSystemData data)
        {
            var errors = new List <string>();

            // Validate schedule within each stop
            foreach (var kvp in data.Schedule)
            {
                var(stopId, stopRouteSchedules) = (kvp.Key, kvp.Value);
                foreach (var routeSchedule in stopRouteSchedules)
                {
                    foreach (var routeDaySchedule in routeSchedule.DaySchedules)
                    {
                        if (routeDaySchedule.Days == DaysOfWeek.None)
                        {
                            errors.Add($"Route {routeSchedule.RouteNo} at stop {stopId} has a day schedule for DaysOfWeek.None.");
                        }

                        var currentTime = TimeSpan.MinValue;
                        foreach (var nextTime in routeDaySchedule.Times)
                        {
                            if (nextTime <= currentTime)
                            {
                                errors.Add($"Route {routeSchedule.RouteNo} at stop {stopId} has an ordering discrepancy in its schedule. Arrival time {currentTime} is followed by {nextTime}");
                            }
                            currentTime = nextTime;
                        }
                    }
                }
            }

            // Validate schedule for each route
            foreach (var route in data.StaticData.Routes.Values)
            {
                var firstStopId        = route.Path[0];
                var firstStopSchedules = data.Schedule[firstStopId].FirstOrDefault(rs => rs.RouteNo == route.RouteNo);
                if (firstStopSchedules == null)
                {
                    errors.Add($"Route {route.RouteNo} has no schedule for stop ID {firstStopId}");
                    continue;
                }

                foreach (var firstStopDaySchedule in firstStopSchedules.DaySchedules)
                {
                    for (var arrivalNo = 0; arrivalNo < firstStopDaySchedule.Times.Count; arrivalNo++)
                    {
                        // get the i'th arrival for each stop in the path, ensure monotonically increasing
                        var currentArrivalTime = TimeSpan.MinValue;

                        for (var stopIdx = 0; stopIdx < route.Path.Count; stopIdx++)
                        {
                            var stopId = route.Path[stopIdx];
                            if (stopId == 0)
                            {
                                errors.Add($"Route {route.RouteNo} has a missing stop in its path at index {stopIdx}");
                                continue;
                            }
                            else if (stopId < 1000)
                            {
                                errors.Add($"Route {route.RouteNo} is using platform tag {stopId} as an ID because it has no stop ID");
                                continue;
                            }
                            else if (!data.Schedule.ContainsKey(stopId))
                            {
                                errors.Add($"Route {route.RouteNo} is using stop ID {stopId} which has no schedule");
                                continue;
                            }

                            var routeStopDayArrivalTimes = data
                                                           .Schedule[stopId]
                                                           .Single(rs => rs.RouteNo == route.RouteNo)
                                                           .DaySchedules
                                                           .Single(ds => ds.Days == firstStopDaySchedule.Days)
                                                           .Times;

                            var nextArrivalTime = routeStopDayArrivalTimes[arrivalNo];
                            if (nextArrivalTime <= currentArrivalTime)
                            {
                                Debug.Assert(stopIdx > 0);
                                errors.Add($"Route {route.RouteNo} has a schedule discrepancy across stops {route.Path[stopIdx - 1]} and {route.Path[stopIdx]}. Arrival time {currentArrivalTime} is followed by {nextArrivalTime}");
                            }

                            currentArrivalTime = nextArrivalTime;
                        }
                    }
                }
            }

            return(errors.Distinct().ToList());
        }