Пример #1
0
        /// <summary>
        /// Tries to calculate an earliest arrival route from stop1 to stop2.
        /// </summary>
        public override Result <Route> TryEarliestArrival(DateTime departureTime,
                                                          RouterPoint sourcePoint, Profile sourceProfile, RouterPoint targetPoint, Profile targetProfile,
                                                          EarliestArrivalSettings settings)
        {
            // get the get factor function.
            var sourceGetFactor = _router.GetDefaultGetFactor(sourceProfile);
            var targetGetFactor = _router.GetDefaultGetFactor(targetProfile);

            // create the profile search.
            var tripEnumerator = _db.TransitDb.GetTripsEnumerator();
            var transfersDb    = _db.TransitDb.GetTransfersDb(_transferProfile);
            var profileSearch  = new ProfileSearch(_db.TransitDb, departureTime, transfersDb, _db.TransitDb.GetIsTripPossibleFunc());

            // search for sources.
            var departureTimeSeconds = (uint)(departureTime - departureTime.Date).TotalSeconds;
            var sourceSearch         = new ClosestStopsSearch(_db, sourceProfile, sourceGetFactor, sourcePoint,
                                                              settings.MaxSecondsSource, false);

            sourceSearch.StopFound = (s, t) =>
            {
                profileSearch.SetSourceStop(s, departureTimeSeconds + (uint)t);
                return(false);
            };

            // search for targets.
            var targetSearch = new ClosestStopsSearch(_db, targetProfile, targetGetFactor, targetPoint,
                                                      settings.MaxSecondsTarget, true);

            targetSearch.StopFound = (s, t) =>
            {
                profileSearch.SetTargetStop(s, (uint)t);
                return(false);
            };

            // create bidirectional helper if possible.
            SearchHelper helper = null;
            BidirectionalSearchHelper bidirectionalHelper = null;

            if (sourceProfile.Name == targetProfile.Name)
            { // profiles are the same.
                bidirectionalHelper = new BidirectionalSearchHelper(
                    sourceSearch.Search, targetSearch.Search);
                targetSearch.WasEdgeFound = bidirectionalHelper.TargetWasFound;
            }
            else
            { // profiles are different but the source can still reach the destination.
                helper = new SearchHelper(_router.Db, sourceSearch.Search, sourceProfile, targetPoint);
                sourceSearch.WasEdgeFound = helper.SourceWasFound;
            }

            // run source search.
            sourceSearch.Run();
            if (!sourceSearch.HasRun ||
                !sourceSearch.HasSucceeded)
            {
                return(new Result <Route>("Searching for source stops failed."));
            }

            // run target search.
            targetSearch.Run();
            if (!targetSearch.HasRun ||
                !targetSearch.HasSucceeded)
            {
                return(new Result <Route>("Searching for target stops failed."));
            }

            // run actual profile search.
            profileSearch.Run();
            if (!profileSearch.HasRun ||
                !profileSearch.HasSucceeded)
            {
                return(new Result <Route>("No route found."));
            }

            // build routes.
            var profileSearchRouteBuilder = new ProfileSearchRouteBuilder(profileSearch);

            profileSearchRouteBuilder.Run();
            if (!profileSearchRouteBuilder.HasRun ||
                !profileSearchRouteBuilder.HasSucceeded)
            {
                return(new Result <Route>(string.Format("Route could not be built: {0}.", profileSearchRouteBuilder.ErrorMessage)));
            }

            var sourceWeight  = sourceSearch.GetWeight(profileSearchRouteBuilder.Stops[0]);
            var targetWeight  = targetSearch.GetWeight(profileSearchRouteBuilder.Stops[profileSearchRouteBuilder.Stops.Count - 1]);
            var transitWeight = sourceWeight + profileSearchRouteBuilder.Duration + targetWeight;

            if (bidirectionalHelper != null &&
                bidirectionalHelper.HasSucceeded)
            { // there is a direct route to the target.
                if (transitWeight > bidirectionalHelper.BestWeight)
                {
                    if (!this.PreferTransit || bidirectionalHelper.BestWeight < this.PreferTransitThreshold)
                    { // transit it not preferred or belof threshold.
                        var path = bidirectionalHelper.GetPath();
                        return(new Result <Route>(
                                   CompleteRouteBuilder.Build(_router.Db, sourceProfile, sourcePoint, targetPoint, path)));
                    }
                }
            }
            else if (helper != null &&
                     helper.HasSucceeded)
            { // there is a direct route to the target.
                if (transitWeight > helper.BestWeight)
                {
                    if (!this.PreferTransit || bidirectionalHelper.BestWeight < this.PreferTransitThreshold)
                    { // transit it not preferred or belof threshold.
                        var path = helper.GetPath();
                        return(new Result <Route>(
                                   CompleteRouteBuilder.Build(_router.Db, sourceProfile, sourcePoint, targetPoint, path)));
                    }
                }
            }

            // build source/target routes.
            var sourceRoute = sourceSearch.GetRoute(profileSearchRouteBuilder.Stops[0]);
            var targetRoute = targetSearch.GetRoute(profileSearchRouteBuilder.Stops[profileSearchRouteBuilder.Stops.Count - 1]);

            // concatenate it all.
            var route = sourceRoute.Concatenate(profileSearchRouteBuilder.Route);

            route = route.Concatenate(targetRoute);

            return(new Result <Route>(route));
        }
Пример #2
0
 /// <summary>
 /// Tries to calculate an earliest arrival route from stop1 to stop2.
 /// </summary>
 public abstract Result <Route> TryEarliestArrival(DateTime departureTime,
                                                   RouterPoint sourcePoint, Profile sourceProfile, RouterPoint targetPoint, Profile targetProfile,
                                                   EarliestArrivalSettings settings);