/* Generates predicted joruney times based on historic average and real time measurements */ func getPredictedJourneyTime(stopPoints []string) (time.Duration, error) { adjacentStops := make(map[string]map[string]bool) for i := 0; i < len(stopPoints)-1; i++ { fromStop := stopPoints[i] toStop := stopPoints[i+1] fromStopMap, fromStopExists := adjacentStops[fromStop] if !fromStopExists { fromStopMap = make(map[string]bool) } fromStopMap[toStop] = true adjacentStops[fromStop] = fromStopMap } currentEstimates, _, _, _, _, err := selectdb.SelectCurrentEstimates(adjacentStops) if err != nil { return 0, err } counterInit := time.Time{} counter := counterInit for _, details := range currentEstimates { for _, duration := range details { counter = counter.Add(duration) } } return counter.Sub(counterInit), nil }
/* Returns our prediction of how long it takes (mixed/historic/real time) for a given line to travel from a stop to another */ func updateBusPrediction(line, bound string, intermediateStopsOrdered []string, departureTime time.Time) (time.Duration, time.Duration, time.Duration, map[string]map[string]time.Duration, error) { intermediateStops := make(map[string]map[string]bool) for i := 0; i < len(intermediateStopsOrdered)-1; i++ { fromStop := intermediateStopsOrdered[i] toStop := intermediateStopsOrdered[i+1] intermediateStops[fromStop] = map[string]bool{ toStop: true, } } /* Short circut if departure time is found to be recent, and use current_estimates instead */ if departureTime.Before(time.Now().Add(time.Hour)) { logger.GetLogger().Info("Case 1") _, historicEstimates, realTimeEstimates, expectedLastingTimes, delayCounts, err := selectdb.SelectCurrentEstimates(intermediateStops) prediction := time.Duration(0) historicPrediction := time.Duration(0) realTimePrediction := time.Duration(0) predictionAdjacentStops := make(map[string]map[string]time.Duration) for i := 0; i < len(intermediateStopsOrdered)-1; i++ { fromStop := intermediateStopsOrdered[i] toStop := intermediateStopsOrdered[i+1] expectedLastingTime := expectedLastingTimes[fromStop][toStop] delayCount := delayCounts[fromStop][toStop] var estimate time.Duration if delayCount >= 3 || time.Now().Add(expectedLastingTime).After(departureTime.Add(prediction)) { estimate = realTimeEstimates[fromStop][toStop] } else { estimate = historicEstimates[fromStop][toStop] } prediction += estimate historicPrediction += historicEstimates[fromStop][toStop] realTimePrediction += realTimeEstimates[fromStop][toStop] predictionAdjacentStops[fromStop] = map[string]time.Duration{ toStop: estimate, } } return prediction, historicPrediction, realTimePrediction, predictionAdjacentStops, err } else { logger.GetLogger().Info("Case 2") estimates2, historicEstimates2, realTimeEstimates2, err := performanceeval.PredictJourneyWithMixedData(performanceeval.DefaultMethod(), line, bound, intermediateStops, intermediateStopsOrdered, departureTime) if err != nil { return 0, 0, 0, nil, err } /* Convert data structures */ estimates := castEstimates(estimates2) historicEstimates := castEstimates(historicEstimates2) realTimeEstimates := castEstimates(realTimeEstimates2) prediction := time.Duration(0) historicPrediction := time.Duration(0) realTimePrediction := time.Duration(0) predictionAdjacentStops := make(map[string]map[string]time.Duration) for i := 0; i < len(intermediateStopsOrdered)-1; i++ { fromStop := intermediateStopsOrdered[i] toStop := intermediateStopsOrdered[i+1] historicPrediction += historicEstimates[fromStop][toStop] realTimePrediction += realTimeEstimates[fromStop][toStop] prediction += estimates[fromStop][toStop] predictionAdjacentStops[fromStop] = map[string]time.Duration{ toStop: estimates[fromStop][toStop], } } return prediction, historicPrediction, realTimePrediction, predictionAdjacentStops, err } }
/* Get durations, historic and real time for all routes map (line => (bound => ("duration" => duration "historicDuration" => historic duration "realTimeDuration" => real time duration))) */ func getRouteDurations(lineBounds map[string]map[string]bool) map[string]map[string]map[string]time.Duration { allLineStopPoints := selectdb.SelectMultipleLineStopPoints(lineBounds) adjacentStops := extractAdjacentStops(allLineStopPoints) currentEstimates, currentHistoricEstimates, currentRealTimeEstimates, _, delayCounts, _ := selectdb.SelectCurrentEstimates(adjacentStops) routeDurations := make(map[string]map[string]map[string]time.Duration) for line, lineDetails := range lineBounds { for bound, _ := range lineDetails { duration, historicDuration, realTimeDuration, err := getRouteDuration(line, bound, allLineStopPoints[line][bound], currentEstimates, currentHistoricEstimates, currentRealTimeEstimates, delayCounts) if err != nil { logger.GetLogger().Error("Failed to get route duartion for line %v (%v): %v", line, bound, err.Error()) continue } _, exists := routeDurations[line] if !exists { routeDurations[line] = make(map[string]map[string]time.Duration) } routeDurations[line][bound] = map[string]time.Duration{ "duration": duration, "historicDuration": historicDuration, "realTimeDuration": realTimeDuration, } } } return routeDurations }