/// <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 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)); })); } } }
/// <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)); }
/// <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)); }
/// <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))); } }
/// <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); }
/// <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)); }
/// <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)); } }
/// <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); }
/// <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)); }
/// <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); }
/// <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)); })); } }
/// <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); }
/// <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); }
/// <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)); }
/// <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)); }
/// <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)); }
/// <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); }
/// <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); }
/// <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; }); } }
/// <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)); }
/// <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)); }
/// <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); }
/// <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)); }
/// <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)); }
/// <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)); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }