Esempio n. 1
0
 /// <summary>
 /// Creates a new weight-matrix algorithm.
 /// </summary>
 public WeightMatrixAlgorithm(RouterBase router, IProfileInstance profile, WeightHandler <T> weightHandler, IMassResolvingAlgorithm massResolver)
 {
     _router        = router;
     _profile       = profile;
     _weightHandler = weightHandler;
     _massResolver  = massResolver;
 }
Esempio n. 2
0
        /// <summary>
        /// Creates a new weight-matrix algorithm.
        /// </summary>
        public DirectedWeightMatrixAlgorithm(RouterBase router, IProfileInstance profile, WeightHandler <T> weightHandler, IMassResolvingAlgorithm massResolver, T?max = null)
        {
            _router        = router;
            _profile       = profile;
            _weightHandler = weightHandler;
            _massResolver  = massResolver;

            ContractedDb contractedDb;

            if (!router.Db.TryGetContracted(profile.Profile, out contractedDb))
            {
                throw new NotSupportedException(
                          "Contraction-based many-to-many calculates are not supported in the given router db for the given profile.");
            }
            if (!contractedDb.HasEdgeBasedGraph)
            {
                throw new NotSupportedException(
                          "Contraction-based edge-based many-to-many calculates are not supported in the given router db for the given profile.");
            }
            _graph = contractedDb.EdgeBasedGraph;
            weightHandler.CheckCanUse(contractedDb);
            if (max.HasValue)
            {
                _max = max.Value;
            }
            else
            {
                _max = weightHandler.Infinite;
            }

            _buckets = new Dictionary <uint, Dictionary <int, LinkedEdgePath <T> > >();
        }
Esempio n. 3
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));
        }
        /// <summary>
        /// Gets the get factor function for the given profile.
        /// </summary>
        public Func <ushort, FactorAndSpeed> GetGetFactorAndSpeed(IProfileInstance profileInstance)
        {
            if (!this.ContainsAll(profileInstance))
            {
                throw new ArgumentException("Given profile not supported.");
            }

            var cachedFactors = _edgeProfileFactors[profileInstance.Profile.FullName];

            if (profileInstance.Constraints != null)
            {
                return((p) =>
                {
                    var cachedFactor = cachedFactors[p];
                    if (profileInstance.IsConstrained(cachedFactor.Constraints))
                    {
                        return FactorAndSpeed.NoFactor;
                    }
                    return cachedFactor;
                });
            }
            return((p) =>
            {
                return cachedFactors[p];
            });
        }
        /// <summary>
        /// Gets the get factor function for the given profile.
        /// </summary>
        public Func <ushort, Factor> GetGetFactor(IProfileInstance profileInstance)
        {
            if (!_edgeProfileFactors.TryGetValue(profileInstance.Profile.FullName, out var cache))
            {
                throw new ArgumentException("Given profile not supported.");
            }
            var cachedFactors = cache;

            if (profileInstance.Constraints != null)
            {
                return((p) =>
                {
                    var cachedFactor = cachedFactors[p];
                    if (profileInstance.IsConstrained(cachedFactor.Constraints))
                    {
                        return Factor.NoFactor;
                    }
                    return cachedFactor.ToFactor();
                });
            }
            return((p) =>
            {
                return cachedFactors[p].ToFactor();
            });
        }
Esempio n. 6
0
 /// <summary>
 /// Gets a function that gets a factor and speed for an edge with the given attributes.
 /// </summary>
 public static Func <ushort, FactorAndSpeed> GetGetFactorAndSpeed(this IProfileInstance profileInstance, RouterDb routerDb)
 {
     return((profileId) =>
     {
         var profile = routerDb.EdgeProfiles.Get(profileId);
         return profileInstance.FactorAndSpeed(profile);
     });
 }
Esempio n. 7
0
        /// <summary>
        /// Returns the default weight handler but calculates a profile cache first.
        /// </summary>
        public static DefaultWeightHandler DefaultWeightHandlerCached(this IProfileInstance profile, RouterDb routerDb)
        {
            // prebuild profile factor cache.
            var profileCache = new ProfileFactorAndSpeedCache(routerDb);

            profileCache.CalculateFor(profile.Profile);

            return(new Weights.DefaultWeightHandler(profileCache.GetGetFactor(profile)));
        }
Esempio n. 8
0
        /// <summary>
        /// Gets a the factor and speed for an edge with the given attributes.
        /// </summary>
        public static FactorAndSpeed FactorAndSpeed(this IProfileInstance profileInstance, IAttributeCollection attributes)
        {
            var factorAndSpeed = profileInstance.Profile.FactorAndSpeed(attributes);

            if (profileInstance.IsConstrained(factorAndSpeed.Constraints))
            {
                return(Profiles.FactorAndSpeed.NoFactor);
            }
            return(factorAndSpeed);
        }
Esempio n. 9
0
        /// <summary>
        /// Builds a route.
        /// </summary>
        public override sealed Result <Route> BuildRoute <T>(IProfileInstance profileInstance, WeightHandler <T> weightHandler, RouterPoint source, RouterPoint target, EdgePath <T> path)
        {
            if (this.CustomRouteBuilder != null)
            { // there is a custom route builder.
                return(this.CustomRouteBuilder.TryBuild(_db, profileInstance.Profile, source, target, path));
            }

            // use the default.
            return(CompleteRouteBuilder.TryBuild(_db, profileInstance.Profile, source, target, path));
        }
Esempio n. 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));
        }
Esempio n. 11
0
        public override Result <Route> BuildRoute <T>(IProfileInstance profile, WeightHandler <T> weightHandler, RouterPoint source, RouterPoint target, EdgePath <T> path)
        {
            var route = new Route();

            route.Shape = new Coordinate[]
            {
                source.Location(),
                    target.Location()
            };
            return(new Result <Route>(route));
        }
Esempio n. 12
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);
        }
Esempio n. 13
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));
        }
Esempio n. 14
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);
        }
Esempio n. 15
0
        /// <summary>
        /// Checks if the given point is connected to the rest of the network. Use this to detect points on routing islands.
        /// </summary>
        /// <param name="radius">The radius metric, that can be a distance, time or custom metric.</param>
        /// <returns></returns>
        public sealed override Result <bool> TryCheckConnectivity(IProfileInstance profileInstance, RouterPoint point, float radius, bool?forward = null)
        {
            try
            {
                if (!_db.Supports(profileInstance.Profile))
                {
                    return(new Result <bool>("Routing profile is not supported.", (message) =>
                    {
                        return new Exception(message);
                    }));
                }

                // get the weight handler.
                var weightHandler = this.GetDefaultWeightHandler(profileInstance);

                var checkForward  = forward == null || forward.Value;
                var checkBackward = forward == null || !forward.Value;

                if (checkForward)
                { // build and run forward dykstra search.
                    var dykstra = new Dykstra(_db.Network.GeometricGraph.Graph, weightHandler, null,
                                              point.ToEdgePaths(_db, weightHandler, true), radius, false);
                    dykstra.Run();
                    if (!dykstra.HasSucceeded ||
                        !dykstra.MaxReached)
                    { // something went wrong or max not reached.
                        return(new Result <bool>(false));
                    }
                }


                if (checkBackward)
                { // build and run backward dykstra search.
                    var dykstra = new Dykstra(_db.Network.GeometricGraph.Graph, weightHandler, null,
                                              point.ToEdgePaths(_db, weightHandler, false), radius, true);
                    dykstra.Run();
                    if (!dykstra.HasSucceeded ||
                        !dykstra.MaxReached)
                    { // something went wrong or max not reached.
                        return(new Result <bool>(false));
                    }
                }
                return(new Result <bool>(true));
            }
            catch (Exception ex)
            {
                return(new Result <bool>(ex.Message, (m) => ex));
            }
        }
Esempio n. 16
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);
        }
Esempio n. 17
0
        /// <summary>
        /// Checks the given edge values against the contraints in the profile.
        /// </summary>
        public static bool IsConstrained(this IProfileInstance profileInstance, float[] edgeValues)
        {
            if (profileInstance.Constraints == null)
            {
                return(false);
            }

            if (profileInstance.Profile.ConstrainedVariables == null)
            {
                return(false);
            }

            if (edgeValues == null)
            {
                return(false);
            }

            for (var i = 0; i < profileInstance.Profile.ConstrainedVariables.Length && i < profileInstance.Constraints.Length; i++)
            {
                var constraint = profileInstance.Profile.ConstrainedVariables[i];
                if (constraint == null)
                {
                    continue;
                }
                var profileValue = profileInstance.Constraints[i];
                if (profileValue == constraint.DefaultValue)
                {
                    continue;
                }
                var edgeValue = edgeValues[i];
                if (edgeValue == constraint.DefaultValue)
                {
                    continue;
                }

                if (constraint.IsMax && profileValue > edgeValue)
                { // the constraint is a maximum and the profile value is larger than the edge value.
                    // the edge value for example maxweight 1.5T but vehicle weight is 2T.
                    return(true);
                }
                else if (!constraint.IsMax && profileValue < edgeValue)
                { // the constraint is a minimum and the profile value is smaller than the edge value.
                    return(true);
                }
            }

            return(false);
        }
Esempio n. 18
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 profile, 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(profile, coordinates[i], searchDistanceInMeter);
            }
            return(result);
        }
Esempio n. 19
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));
        }
Esempio n. 20
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));
        }
Esempio n. 21
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));
        }
Esempio n. 22
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);
        }
Esempio n. 23
0
        public override Result <T[][]> TryCalculateWeight <T>(IProfileInstance profile, WeightHandler <T> weightHandler,
                                                              RouterPoint[] sources, RouterPoint[] targets, ISet <int> invalidSources, ISet <int> invalidTargets, RoutingSettings <T> settings)
        {
            var weights = new T[sources.Length][];

            for (var s = 0; s < sources.Length; s++)
            {
                weights[s] = new T[targets.Length];
                for (var t = 0; t < sources.Length; t++)
                {
                    weights[s][t] = weightHandler.Calculate(0, Coordinate.DistanceEstimateInMeter(
                                                                new Coordinate(sources[s].Latitude, sources[s].Longitude),
                                                                new Coordinate(targets[t].Latitude, targets[t].Longitude)));
                }
            }

            foreach (var invalid in _invalidSet)
            {
                invalidSources.Add(invalid);
                invalidTargets.Add(invalid);
            }

            return(new Result <T[][]>(weights));
        }
Esempio n. 24
0
        /// <summary>
        /// Checks if the given point is connected to the rest of the network. Use this to detect points on routing islands.
        /// </summary>
        /// <returns></returns>
        public sealed override Result <bool> TryCheckConnectivity(IProfileInstance profileInstance, RouterPoint point, float radiusInMeters)
        {
            if (!_db.Supports(profileInstance.Profile))
            {
                return(new Result <bool>("Routing profile is not supported.", (message) =>
                {
                    return new Exception(message);
                }));
            }

            // get the weight handler.
            var weightHandler = this.GetDefaultWeightHandler(profileInstance);

            // build and run dykstra search.
            var dykstra = new Dykstra(_db.Network.GeometricGraph.Graph, weightHandler, null,
                                      point.ToEdgePaths(_db, weightHandler, true), radiusInMeters, false);

            dykstra.Run();
            if (!dykstra.HasSucceeded)
            { // something went wrong.
                return(new Result <bool>(false));
            }
            return(new Result <bool>(dykstra.MaxReached));
        }
Esempio n. 25
0
 /// <summary>
 /// Gets a the factor for an edge with the given attributes.
 /// </summary>
 public static Factor Factor(this IProfileInstance profileInstance, IAttributeCollection attributes)
 {
     return(profileInstance.FactorAndSpeed(attributes).ToFactor());
 }
Esempio n. 26
0
 /// <summary>
 /// Builds a route based on a raw path.
 /// </summary>
 public abstract Result <Route> BuildRoute <T>(IProfileInstance profile, WeightHandler <T> weightHandler, RouterPoint source, RouterPoint target, EdgePath <T> path) where T : struct;
Esempio n. 27
0
 /// <summary>
 /// Calculates all weights between all sources and all targets.
 /// </summary>
 /// <returns></returns>
 public abstract Result <T[][]> TryCalculateWeight <T>(IProfileInstance profile, WeightHandler <T> weightHandler, RouterPoint[] sources, RouterPoint[] targets,
                                                       ISet <int> invalidSources, ISet <int> invalidTargets, RoutingSettings <T> settings = null) where T : struct;
Esempio n. 28
0
 /// <summary>
 /// Calculates all routes between all sources and all targets.
 /// </summary>
 /// <returns></returns>
 public abstract Result <EdgePath <T>[][]> TryCalculateRaw <T>(IProfileInstance profile, WeightHandler <T> weightHandler, RouterPoint[] sources, RouterPoint[] targets,
                                                               RoutingSettings <T> settings = null) where T : struct;
Esempio n. 29
0
 /// <summary>
 /// Calculates a route between the two directed edges. The route starts in the direction of the edge and ends with an arrive in the direction of the target edge.
 /// </summary>
 /// <returns></returns>
 public abstract Result <EdgePath <T> > TryCalculateRaw <T>(IProfileInstance profile, WeightHandler <T> weightHandler, long sourceDirectedEdge, long targetDirectedEdge,
                                                            RoutingSettings <T> settings = null) where T : struct;
Esempio n. 30
0
 /// <summary>
 /// Checks if the given point is connected to the rest of the network. Use this to detect points on routing islands.
 /// </summary>
 /// <param name="radius">The radius metric, that can be a distance, time or custom metric.</param>
 /// <returns></returns>
 public abstract Result <bool> TryCheckConnectivity(IProfileInstance profile, RouterPoint point, float radius, bool?forward = null);