Beispiel #1
0
        /// <summary>
        /// Calculates all routes between all sources and all targets.
        /// </summary>
        /// <returns></returns>
        public static Result <Route[][]> TryCalculate(this RouterBase router, IProfileInstance profile, RouterPoint[] sources, RouterPoint[] targets)
        {
            var weightHandler = router.GetDefaultWeightHandler(profile);
            var paths         = router.TryCalculateRaw(profile, weightHandler, sources, targets);

            if (paths.IsError)
            {
                return(paths.ConvertError <Route[][]>());
            }

            var routes = new Route[paths.Value.Length][];

            for (var s = 0; s < paths.Value.Length; s++)
            {
                routes[s] = new Route[paths.Value[s].Length];
                for (var t = 0; t < paths.Value[s].Length; t++)
                {
                    var localPath = paths.Value[s][t];
                    if (localPath != null)
                    {
                        var route = router.BuildRoute(profile, weightHandler, sources[s],
                                                      targets[t], localPath);
                        if (route.IsError)
                        {
                            return(route.ConvertError <Route[][]>());
                        }
                        routes[s][t] = route.Value;
                    }
                }
            }
            return(new Result <Route[][]>(routes));
        }
Beispiel #2
0
 /// <summary>
 /// Gets the default weight handler for the given profile instance.
 /// </summary>
 public static DefaultWeightHandler GetDefaultWeightHandler(this RouterBase router, IProfileInstance profileInstance)
 {
     if (router.ProfileFactorAndSpeedCache != null && router.ProfileFactorAndSpeedCache.ContainsAll(profileInstance))
     { // use cached version and don't consult profiles anymore.
         return(new DefaultWeightHandler(router.ProfileFactorAndSpeedCache.GetGetFactor(profileInstance)));
     }
     else
     {     // use the regular function, and consult the profile continuously.
         if (router.ProfileFactorAndSpeedCache != null)
         { // when there is a cache, built it on demand.
             Itinero.Logging.Logger.Log("RouterBaseExtensions", TraceEventType.Information, "Profile {0} is not cached, building cache.",
                                        profileInstance.Profile.FullName);
             router.ProfileFactorAndSpeedCache.CalculateFor(profileInstance.Profile);
             return(new DefaultWeightHandler(router.ProfileFactorAndSpeedCache.GetGetFactor(profileInstance)));
         }
         else
         { // no cache, caching disabled.
             Itinero.Logging.Logger.Log("RouterBaseExtensions", TraceEventType.Warning, "Profile {0} is not cached, this could slow down routing significantly, consider building a profile cache.",
                                        profileInstance.Profile.FullName);
             return(new DefaultWeightHandler((p) =>
             {
                 return profileInstance.Factor(router.Db.EdgeProfiles.Get(p));
             }));
         }
     }
 }
Beispiel #3
0
        /// <summary>
        /// Resolves a location but also checks if it's connected to the rest of the network.
        /// </summary>
        public static Result <RouterPoint> TryResolveConnected(this RouterBase router, IProfileInstance profileInstance, float latitude, float longitude,
                                                               float radiusInMeter = 1000, float maxSearchDistance = Constants.SearchDistanceInMeter, bool?forward = null)
        {
            var resolver = new Algorithms.Search.ResolveAlgorithm(router.Db.Network.GeometricGraph, latitude, longitude, radiusInMeter, maxSearchDistance, (edge) =>
            {
                // create a temp resolved point in the middle of this edge.
                var tempRouterPoint    = new RouterPoint(0, 0, edge.Id, ushort.MaxValue / 2);
                var connectivityResult = router.TryCheckConnectivity(profileInstance, tempRouterPoint, radiusInMeter / 2, forward);
                if (connectivityResult.IsError)
                { // if there is an error checking connectivity, choose not report it, just don't choose this point.
                    return(false);
                }
                return(connectivityResult.Value);
            });

            resolver.Run();

            if (!resolver.HasSucceeded)
            { // something went wrong.
                return(new Result <RouterPoint>(resolver.ErrorMessage, (message) =>
                {
                    return new Itinero.Exceptions.ResolveFailedException(message);
                }));
            }
            return(new Result <RouterPoint>(resolver.Result));
        }
Beispiel #4
0
        /// <summary>
        /// Calculates all routes between all sources and all targets.
        /// </summary>
        public static Result <Route[][]> TryCalculate(this RouterBase router, Profile profile, RouterPoint[] sources, RouterPoint[] targets)
        {
            var invalidSources = new HashSet <int>();
            var invalidTargets = new HashSet <int>();
            var result         = router.TryCalculate(profile, sources, targets, invalidSources, invalidTargets).Value;

            if (invalidSources.Count > 0)
            {
                return(new Result <Route[][]>("Some sources could not be routed from. Most likely there are islands in the loaded network.", (s) =>
                {
                    throw new Exceptions.RouteNotFoundException(s);
                }));
            }
            if (invalidTargets.Count > 0)
            {
                return(new Result <Route[][]>("Some targets could not be routed to. Most likely there are islands in the loaded network.", (s) =>
                {
                    throw new Exceptions.RouteNotFoundException(s);
                }));
            }

            var routes = new Route[result.Length][];

            for (var i = 0; i < result.Length; i++)
            {
                routes[i] = new Route[result[i].Length];
                for (var j = 0; j < result[i].Length; j++)
                {
                    routes[i][j] = result[i][j];
                }
            }
            return(new Result <Route[][]>(routes));
        }
Beispiel #5
0
 /// <summary>
 /// Gets the default weight handler for the given profile.
 /// </summary>
 public static WeightHandler GetAugmentedWeightHandler(this RouterBase router, Profile profile)
 {
     if (router.ProfileFactorAndSpeedCache != null && router.ProfileFactorAndSpeedCache.ContainsAll(profile))
     { // use cached version and don't consult profiles anymore.
         return(new WeightHandler(router.ProfileFactorAndSpeedCache.GetGetFactorAndSpeed(profile)));
     }
     else
     { // use the regular function, and consult profiles continuously.
         return(new WeightHandler(profile.GetGetFactorAndSpeed(router.Db)));
     }
 }
Beispiel #6
0
 /// <summary>
 /// Returns true if all given profiles are supported.
 /// </summary>
 public static bool SupportsAll(this RouterBase router, params IProfileInstance[] profiles)
 {
     for (var i = 0; i < profiles.Length; i++)
     {
         if (!router.Db.Supports(profiles[i].Profile))
         {
             return(false);
         }
     }
     return(true);
 }
Beispiel #7
0
        /// <summary>
        /// Calculates a route the given locations;
        /// </summary>
        public static Result <Route> TryCalculate(this RouterBase router, IProfileInstance profile, RouterPoint source, RouterPoint target)
        {
            var weightHandler = router.GetDefaultWeightHandler(profile);
            var path          = router.TryCalculateRaw(profile, weightHandler, source, target);

            if (path.IsError)
            {
                return(path.ConvertError <Route>());
            }
            return(router.BuildRoute(profile, weightHandler, source, target, path.Value));
        }
Beispiel #8
0
 /// <summary>
 /// Gets the default get factor for the given profile but used the cached version whenever available.
 /// </summary>
 public static Func <ushort, Factor> GetDefaultGetFactor(this RouterBase router, Profile profile)
 {
     if (router.ProfileFactorAndSpeedCache != null && router.ProfileFactorAndSpeedCache.ContainsAll(profile))
     { // use cached version and don't consult profiles anymore.
         return(router.ProfileFactorAndSpeedCache.GetGetFactor(profile));
     }
     else
     { // use the regular function, and consult profiles continuously.
         return(profile.GetGetFactor(router.Db));
     }
 }
Beispiel #9
0
        /// <summary>
        /// Calculates all weights between all sources and all targets.
        /// </summary>
        public static Result <T[][]> TryCalculateWeight <T>(this RouterBase router, IProfileInstance profile, WeightHandler <T> weightHandler, Coordinate[] sources, Coordinate[] targets)
            where T : struct
        {
            var resolvedSources = new RouterPoint[sources.Length];

            for (var i = 0; i < sources.Length; i++)
            {
                var result = router.TryResolve(profile, sources[i]);
                if (result.IsError)
                {
                    return(new Result <T[][]>(string.Format("Source at index {0} could not be resolved: {1}",
                                                            i, result.ErrorMessage), (s) =>
                    {
                        throw new Exceptions.ResolveFailedException(s);
                    }));
                }
                resolvedSources[i] = result.Value;
            }
            var resolvedTargets = new RouterPoint[targets.Length];

            for (var i = 0; i < targets.Length; i++)
            {
                var result = router.TryResolve(profile, targets[i]);
                if (result.IsError)
                {
                    return(new Result <T[][]>(string.Format("Target at index {0} could not be resolved: {1}",
                                                            i, result.ErrorMessage), (s) =>
                    {
                        throw new Exceptions.ResolveFailedException(s);
                    }));
                }
                resolvedTargets[i] = result.Value;
            }

            var invalidSources = new HashSet <int>();
            var invalidTargets = new HashSet <int>();
            var weights        = router.TryCalculateWeight(profile, weightHandler, resolvedSources, resolvedTargets, invalidSources, invalidTargets);

            if (invalidSources.Count > 0)
            {
                return(new Result <T[][]>("Some sources could not be routed from. Most likely there are islands in the loaded network.", (s) =>
                {
                    throw new Exceptions.RouteNotFoundException(s);
                }));
            }
            if (invalidTargets.Count > 0)
            {
                return(new Result <T[][]>("Some targets could not be routed to. Most likely there are islands in the loaded network.", (s) =>
                {
                    throw new Exceptions.RouteNotFoundException(s);
                }));
            }
            return(weights);
        }
Beispiel #10
0
        /// <summary>
        /// Tries to calculate the weight between the given source and target.
        /// </summary>
        public static Result <T> TryCalculateWeight <T>(this RouterBase router, IProfileInstance profile, WeightHandler <T> weightHandler,
                                                        RouterPoint source, RouterPoint target) where T : struct
        {
            var result = router.TryCalculateRaw <T>(profile, weightHandler, source, target);

            if (result.IsError)
            {
                return(result.ConvertError <T>());
            }
            return(new Result <T>(result.Value.Weight));
        }
Beispiel #11
0
        /// <summary>
        /// Searches for the closest point on the routing network that's routable for the given profiles.
        /// </summary>
        public static RouterPoint[] Resolve(this RouterBase router, IProfileInstance profile, Coordinate[] coordinates,
                                            float searchDistanceInMeter = Constants.SearchDistanceInMeter)
        {
            var results      = router.TryResolve(profile, coordinates, searchDistanceInMeter);
            var routerPoints = new RouterPoint[results.Length];

            for (var i = 0; i < results.Length; i++)
            {
                routerPoints[i] = results[i].Value;
            }
            return(routerPoints);
        }
Beispiel #12
0
 /// <summary>
 /// Gets the default weight handler for the given profile.
 /// </summary>
 public static DefaultWeightHandler GetDefaultWeightHandler(this RouterBase router, Profile profile)
 {
     if (router.ProfileFactorAndSpeedCache != null && router.ProfileFactorAndSpeedCache.ContainsAll(profile))
     { // use cached version and don't consult profiles anymore.
         return(new DefaultWeightHandler(router.ProfileFactorAndSpeedCache.GetGetFactor(profile)));
     }
     else
     { // use the regular function, and consult profiles continuously.
         return(new DefaultWeightHandler((p) =>
         {
             return profile.Factor(router.Db.EdgeProfiles.Get(p));
         }));
     }
 }
Beispiel #13
0
        /// <summary>
        /// Calculates all weights between all locations.
        /// </summary>
        public static Result <T[][]> TryCalculateWeight <T>(this RouterBase router, IProfileInstance profile, WeightHandler <T> weightHandler, RouterPoint[] locations)
            where T : struct
        {
            var invalids = new HashSet <int>();
            var result   = router.TryCalculateWeight(profile, weightHandler, locations, locations, invalids, invalids);

            if (invalids.Count > 0)
            {
                return(new Result <T[][]>("At least one location could not be routed from/to. Most likely there are islands in the loaded network.", (s) =>
                {
                    throw new Exceptions.RouteNotFoundException(s);
                }));
            }
            return(result);
        }
Beispiel #14
0
        /// <summary>
        /// Searches for the closest points on the routing network that's routable for the given profile(s).
        /// </summary>
        public static Result <RouterPoint>[] TryResolve(this RouterBase router, IProfileInstance[] profiles, Coordinate[] coordinates,
                                                        float searchDistanceInMeter = Constants.SearchDistanceInMeter)
        {
            if (coordinates == null)
            {
                throw new ArgumentNullException("coordinate");
            }

            var result = new Result <RouterPoint> [coordinates.Length];

            for (var i = 0; i < coordinates.Length; i++)
            {
                result[i] = router.TryResolve(profiles, coordinates[i], searchDistanceInMeter);
            }
            return(result);
        }
Beispiel #15
0
        /// <summary>
        /// Calculates the weight between the two locations.
        /// </summary>
        public static Result <T> TryCalculateWeight <T>(this RouterBase router, IProfileInstance profile, WeightHandler <T> weightHandler,
                                                        float sourceLatitude, float sourceLongitude, float targetLatitude, float targetLongitude) where T : struct
        {
            var profiles    = new IProfileInstance[] { profile };
            var sourcePoint = router.TryResolve(profiles, sourceLatitude, sourceLongitude);
            var targetPoint = router.TryResolve(profiles, targetLatitude, targetLongitude);

            if (sourcePoint.IsError)
            {
                return(sourcePoint.ConvertError <T>());
            }
            if (targetPoint.IsError)
            {
                return(targetPoint.ConvertError <T>());
            }
            return(router.TryCalculateWeight(profile, weightHandler, sourcePoint.Value, targetPoint.Value));
        }
Beispiel #16
0
        /// <summary>
        /// Calculates all routes between all sources and all targets.
        /// </summary>
        public static Result <Route[]> TryCalculate(this RouterBase router, IProfileInstance profile, RouterPoint source, RouterPoint[] targets)
        {
            var result = router.TryCalculate(profile, new RouterPoint[] { source }, targets);

            if (result.IsError)
            {
                return(result.ConvertError <Route[]>());
            }

            var routes = new Route[result.Value.Length];

            for (var j = 0; j < result.Value.Length; j++)
            {
                routes[j] = result.Value[0][j];
            }
            return(new Result <Route[]>(routes));
        }
Beispiel #17
0
        /// <summary>
        /// Calculates a route between the two locations.
        /// </summary>
        public static Result <Route> TryCalculate(this RouterBase router, IProfileInstance profile,
                                                  float sourceLatitude, float sourceLongitude, float targetLatitude, float targetLongitude)
        {
            var profiles    = new IProfileInstance[] { profile };
            var sourcePoint = router.TryResolve(profiles, sourceLatitude, sourceLongitude);
            var targetPoint = router.TryResolve(profiles, targetLatitude, targetLongitude);

            if (sourcePoint.IsError)
            {
                return(sourcePoint.ConvertError <Route>());
            }
            if (targetPoint.IsError)
            {
                return(targetPoint.ConvertError <Route>());
            }
            return(router.TryCalculate(profile, sourcePoint.Value, targetPoint.Value));
        }
Beispiel #18
0
        /// <summary>
        /// Calculates a route along the given locations.
        /// </summary>
        public static Result <Route> TryCalculate(this RouterBase router, IProfileInstance profile, RouterPoint[] locations)
        {
            if (locations.Length < 2)
            {
                throw new ArgumentOutOfRangeException("Cannot calculate a routing along less than two locations.");
            }
            var route = router.TryCalculate(profile, locations[0], locations[1]);

            if (route.IsError)
            {
                return(route);
            }
            for (var i = 2; i < locations.Length; i++)
            {
                var nextRoute = router.TryCalculate(profile, locations[i - 1], locations[i]);
                if (nextRoute.IsError)
                {
                    return(nextRoute);
                }
                route = new Result <Route>(route.Value.Concatenate(nextRoute.Value));
            }
            return(route);
        }
Beispiel #19
0
        /// <summary>
        /// Calculates a route along the given locations.
        /// </summary>
        public static Result <Route> TryCalculate(this RouterBase router, Profile profile, Coordinate[] locations)
        {
            if (locations.Length < 2)
            {
                throw new ArgumentOutOfRangeException("Cannot calculate a routing along less than two locations.");
            }
            var resolved = router.TryResolve(profile, locations);
            var route    = router.TryCalculate(profile, resolved[0].Value, resolved[1].Value);

            if (route.IsError)
            {
                return(route);
            }
            for (var i = 2; i < resolved.Length; i++)
            {
                var nextRoute = router.TryCalculate(profile, resolved[i - 1].Value, resolved[i].Value);
                if (nextRoute.IsError)
                {
                    return(nextRoute);
                }
                route = new Result <Route>(route.Value.Concatenate(nextRoute.Value));
            }
            return(route);
        }
Beispiel #20
0
 /// <summary>
 /// Returns the IsAcceptable function to use in the default resolver algorithm.
 /// </summary>
 public static Func <GeometricEdge, bool> GetIsAcceptable(this RouterBase router, params Profile[] profiles)
 {
     if (router.ProfileFactorAndSpeedCache != null && router.ProfileFactorAndSpeedCache.ContainsAll(profiles))
     { // use cached version and don't consult profiles anymore.
         return(router.ProfileFactorAndSpeedCache.GetIsAcceptable(router.VerifyAllStoppable,
                                                                  profiles));
     }
     else
     {     // use the regular function, and consult profiles continuously.
         return((edge) =>
         { // check all profiles, they all need to be traversible.
           // get profile.
             float distance;
             ushort edgeProfileId;
             EdgeDataSerializer.Deserialize(edge.Data[0],
                                            out distance, out edgeProfileId);
             var edgeProfile = router.Db.EdgeProfiles.Get(edgeProfileId);
             for (var i = 0; i < profiles.Length; i++)
             {
                 // get factor from profile.
                 if (profiles[i].Factor(edgeProfile).Value <= 0)
                 { // cannot be traversed by this profile.
                     return false;
                 }
                 if (router.VerifyAllStoppable)
                 {     // verify stoppable.
                     if (!profiles[i].CanStopOn(edgeProfile))
                     { // this profile cannot stop on this edge.
                         return false;
                     }
                 }
             }
             return true;
         });
     }
 }
Beispiel #21
0
 /// <summary>
 /// Searches for the closest point on the routing network that's routable for the given profiles.
 /// </summary>
 public static Result <RouterPoint> TryResolve(this RouterBase router, IProfileInstance[] profiles, Coordinate coordinate,
                                               float searchDistanceInMeter = Constants.SearchDistanceInMeter)
 {
     return(router.TryResolve(profiles, coordinate.Latitude, coordinate.Longitude,
                              searchDistanceInMeter));
 }
Beispiel #22
0
 /// <summary>
 /// Calculates all weights between all given locations.
 /// </summary>
 public static Result <T[][]> TryCalculateWeight <T>(this RouterBase router, WeightHandler <T> weightHandler, IProfileInstance profile, Coordinate[] locations)
     where T : struct
 {
     return(router.TryCalculateWeight(profile, weightHandler, locations, locations));
 }
Beispiel #23
0
 /// <summary>
 /// Searches for the closest point on the routing network that's routable for the given profiles.
 /// </summary>
 public static RouterPoint Resolve(this RouterBase router, IProfileInstance profile, Coordinate coordinate,
                                   float searchDistanceInMeter = Constants.SearchDistanceInMeter)
 {
     return(router.TryResolve(profile, coordinate, searchDistanceInMeter).Value);
 }
Beispiel #24
0
 /// <summary>
 /// Calculates the weight between the two locations.
 /// </summary>
 public static Result <float> TryCalculateWeight(this RouterBase router, IProfileInstance profile, Coordinate source, Coordinate target)
 {
     return(router.TryCalculateWeight(profile, profile.DefaultWeightHandler(router), source, target));
 }
Beispiel #25
0
 /// <summary>
 /// Calculates the weight between the two locations.
 /// </summary>
 public static Result <T> TryCalculateWeight <T>(this RouterBase router, IProfileInstance profile, WeightHandler <T> weightHandler, Coordinate source, Coordinate target)
     where T : struct
 {
     return(router.TryCalculateWeight(profile, weightHandler, source.Latitude, source.Longitude, target.Latitude, target.Longitude));
 }
Beispiel #26
0
 /// <summary>
 /// Calculates a route between the two locations.
 /// </summary>
 public static Result <Route> TryCalculate(this RouterBase router, IProfileInstance profile, Coordinate source,
                                           Coordinate target)
 {
     return(router.TryCalculate(profile, source.Latitude, source.Longitude, target.Latitude, target.Longitude));
 }
Beispiel #27
0
 /// <summary>
 /// Searches for the closest point on the routing network that's routable for the given profiles.
 /// </summary>
 public static RouterPoint Resolve(this RouterBase router, IProfileInstance[] profiles, Coordinate coordinate,
                                   Func <RoutingEdge, bool> isBetter,
                                   float searchDistanceInMeter = Constants.SearchDistanceInMeter)
 {
     return(router.TryResolve(profiles, coordinate, isBetter, searchDistanceInMeter).Value);
 }
Beispiel #28
0
 /// <summary>
 /// Calculates a route along the given locations.
 /// </summary>
 public static Route Calculate(this RouterBase router, IProfileInstance profile, Coordinate[] locations)
 {
     return(router.TryCalculate(profile, locations).Value);
 }
Beispiel #29
0
 /// <summary>
 /// Calculates a route between the two locations.
 /// </summary>
 public static Route Calculate(this RouterBase router, IProfileInstance profile, Coordinate source, Coordinate target)
 {
     return(router.TryCalculate(profile, source, target).Value);
 }
Beispiel #30
0
 /// <summary>
 /// Resolves a location but also checks if it's connected to the rest of the network.
 /// </summary>
 public static RouterPoint ResolveConnected(this RouterBase router, IProfileInstance profileInstance, float latitude, float longitude, float radiusInMeter = 1000,
                                            float maxSearchDistance = Constants.SearchDistanceInMeter)
 {
     return(router.TryResolveConnected(profileInstance, latitude, longitude, radiusInMeter, maxSearchDistance).Value);
 }