/// <summary> /// Checks connectivity of all given points and returns only those that are valid. /// </summary> /// <param name="router"></param> /// <param name="vehicle"></param> /// <param name="resolvedPoints"></param> /// <param name="weight"></param> /// <returns></returns> public static RouterPoint[] CheckConnectivityAndRemoveInvalid( this Router router, Vehicle vehicle, RouterPoint[] resolvedPoints, float weight) { var connectedPoints = new List <RouterPoint>(); for (int idx = 0; idx < resolvedPoints.Length; idx++) { RouterPoint resolvedPoint = resolvedPoints[idx]; if (resolvedPoint != null && router.CheckConnectivity(vehicle, resolvedPoint, weight)) { // the point is connected. connectedPoints.Add(resolvedPoint); } } return(connectedPoints.ToArray()); }
/// <summary> /// Calculates the TSP. /// </summary> /// <param name="dataStream"></param> /// <param name="csvStream"></param> /// <param name="pbf"></param> /// <param name="vehicleEnum"></param> /// <returns></returns> private OsmSharpRoute CalculateTSP(Stream dataStream, Stream csvStream, bool pbf, VehicleEnum vehicleEnum) { // create the router. var interpreter = new OsmRoutingInterpreter(); var tagsIndex = new OsmTagsIndex(); // do the data processing. var osmData = new DynamicGraphRouterDataSource<PreProcessedEdge>(tagsIndex); var targetData = new PreProcessedDataGraphProcessingTarget( osmData, interpreter, osmData.TagsIndex, vehicleEnum); var dataProcessorSource = new XmlDataProcessorSource(dataStream); var sorter = new DataProcessorFilterSort(); sorter.RegisterSource(dataProcessorSource); targetData.RegisterSource(sorter); targetData.Pull(); IRouter<RouterPoint> router = new Router<PreProcessedEdge>(osmData, interpreter, new DykstraRoutingPreProcessed(osmData.TagsIndex)); // read the source files. const int latitudeIdx = 2; const int longitudeIdx = 3; string[][] pointStrings = OsmSharp.Tools.DelimitedFiles.DelimitedFileHandler.ReadDelimitedFileFromStream( csvStream, DelimiterType.DotCommaSeperated); var points = new List<RouterPoint>(); int cnt = 10; foreach (string[] line in pointStrings) { if (points.Count >= cnt) { break; } var latitudeString = (string)line[latitudeIdx]; var longitudeString = (string)line[longitudeIdx]; //string route_ud = (string)line[1]; double longitude = 0; double latitude = 0; if (double.TryParse(longitudeString, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out longitude) && double.TryParse(latitudeString, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out latitude)) { var point = new GeoCoordinate(latitude, longitude); RouterPoint resolved = router.Resolve(VehicleEnum.Car, point); if (resolved != null && router.CheckConnectivity(VehicleEnum.Car, resolved, 100)) { points.Add(resolved); } } } var tspSolver = new RouterTSPWrapper<RouterPoint, RouterTSP>( new RouterTSPAEXGenetic(), router, interpreter); return tspSolver.CalculateTSP(vehicleEnum, points.ToArray()); }
/// <summary> /// Calculates the TSP. /// </summary> /// <param name="operation">The operation request.</param> /// <param name="router">The router.</param> /// <param name="matcher">Contains an algorithm to match points to the route network.</param> /// <param name="open">Flag indicating the type of TSP problem, open or not.</param> /// <returns></returns> private RoutingResponse DoTSP( RoutingOperation operation, Router<SimpleWeighedEdge> router, IEdgeMatcher matcher, bool open) { // create the response. var response = new RoutingResponse(); // resolve the points and do the routing. var hooksPerRouterPoints = new Dictionary<RouterPoint, List<RoutingHook>>(); var routerPoints = new List<RouterPoint>(); var unroutableHooks = new List<RoutingHook>(); // save the unroutable hooks. for (int idx = 0; idx < operation.Hooks.Length; idx++) { // routing hook tags. IDictionary<string, string> tags = operation.Hooks[idx].Tags.ConvertToDictionary(); // resolve the point. RouterPoint routerPoint = router.Resolve(operation.Vehicle, new GeoCoordinate( operation.Hooks[idx].Latitude, operation.Hooks[idx].Longitude), matcher, tags); // check the result. if (routerPoint == null) { // this hook is not routable. unroutableHooks.Add(operation.Hooks[idx]); } else { // a point to hook on was found! List<RoutingHook> hooksAtPoint; if (!hooksPerRouterPoints.TryGetValue(routerPoint, out hooksAtPoint)) { // the router point does not exist yet. // check if the router point is routable. if (router.CheckConnectivity(operation.Vehicle, routerPoint, 200)) {// the point is routable. // create the hooks list at this point. hooksAtPoint = new List<RoutingHook>(); hooksPerRouterPoints.Add(routerPoint, hooksAtPoint); // add the new router point to the list. routerPoint.Tags.Add(new KeyValuePair<string, string>("id", routerPoints.Count.ToString( System.Globalization.CultureInfo.InvariantCulture))); routerPoints.Add(routerPoint); // add the hook. hooksAtPoint.Add(operation.Hooks[idx]); } else {// this hook is not routable. unroutableHooks.Add(operation.Hooks[idx]); } } else { // add the hook. hooksAtPoint.Add(operation.Hooks[idx]); } } } // add the unroutable hooks. response.UnroutableHooks = unroutableHooks.ToArray(); // calculate all the weights. double[][] weights = router.CalculateManyToManyWeight(operation.Vehicle, routerPoints.ToArray(), routerPoints.ToArray()); // calculate the TSP. var tspSolver = new RouterTSPAEXGenetic(300, 100); IRoute tspRoute = tspSolver.CalculateTSP(weights, routerPoints.Select(x => x.Location).ToArray(), 0, !open); // calculate the actual route. OsmSharpRoute route = null; foreach (Edge edge in tspRoute.Edges()) { // calculate the actual edge-route. OsmSharpRoute edgeRoute = router.Calculate(operation.Vehicle, routerPoints[edge.From], routerPoints[edge.To]); // add the routing hook tags. List<RoutingHook> fromHooks = hooksPerRouterPoints[routerPoints[edge.From]]; edgeRoute.Entries[0].Points = new RoutePoint[fromHooks.Count]; for (int hookIdx = 0; hookIdx < fromHooks.Count; hookIdx++) { var hookPoint = new RoutePoint { Latitude = fromHooks[hookIdx].Latitude, Longitude = fromHooks[hookIdx].Longitude, Tags = fromHooks[hookIdx].Tags.ConvertToList().ConvertFrom() }; edgeRoute.Entries[0].Points[hookIdx] = hookPoint; } List<RoutingHook> toHooks = hooksPerRouterPoints[routerPoints[edge.To]]; edgeRoute.Entries[edgeRoute.Entries.Length - 1].Points = new RoutePoint[toHooks.Count]; for (int hookIdx = 0; hookIdx < toHooks.Count; hookIdx++) { var hookPoint = new RoutePoint { Latitude = toHooks[hookIdx].Latitude, Longitude = toHooks[hookIdx].Longitude, Tags = toHooks[hookIdx].Tags.ConvertToList().ConvertFrom() }; edgeRoute.Entries[edgeRoute.Entries.Length - 1].Points[hookIdx] = hookPoint; } // concatenate routes. if (route == null) { route = edgeRoute; } else { route = OsmSharpRoute.Concatenate(route, edgeRoute); } } response.Route = route; // set the response as successfull. response.Status = OsmSharpServiceResponseStatusEnum.Success; return response; }
/// <summary> /// Calculates the route from the source to the closest point. /// </summary> /// <param name="operation">The operation request.</param> /// <param name="router">The router.</param> /// <param name="matcher">Contains an algorithm to match points to the route network.</param> /// <returns></returns> private RoutingResponse DoToClosest( RoutingOperation operation, Router<SimpleWeighedEdge> router, IEdgeMatcher matcher) { // create the response. var response = new RoutingResponse(); // resolve the points and do the routing. var hooksPerRouterPoints = new Dictionary<RouterPoint, List<RoutingHook>>(); var routerPoints = new List<RouterPoint>(); var unroutableHooks = new List<RoutingHook>(); // save the unroutable hooks. for (int idx = 0; idx < operation.Hooks.Length; idx++) { // routing hook tags. IDictionary<string, string> tags = operation.Hooks[idx].Tags.ConvertToDictionary(); // resolve the point. RouterPoint routerPoint = router.Resolve(operation.Vehicle, new GeoCoordinate( operation.Hooks[idx].Latitude, operation.Hooks[idx].Longitude), matcher, tags); // check the result. if (routerPoint == null) { // this hook is not routable. if (idx == 0) { // the first point has to be valid! throw new Exception("Cannot resolve source point of a CalculateToClosest() operation."); } unroutableHooks.Add(operation.Hooks[idx]); } else { // a point to hook on was found! List<RoutingHook> hooksAtPoint; if (!hooksPerRouterPoints.TryGetValue(routerPoint, out hooksAtPoint)) { // the router point does not exist yet. // check if the router point is routable. if (router.CheckConnectivity(operation.Vehicle, routerPoint, 200)) {// the point is routable. // create the hooks list at this point. hooksAtPoint = new List<RoutingHook>(); hooksPerRouterPoints.Add(routerPoint, hooksAtPoint); // add the new router point to the list. routerPoint.Tags.Add(new KeyValuePair<string, string>("id", routerPoints.Count.ToString( System.Globalization.CultureInfo.InvariantCulture))); routerPoint.Tags.Add(new KeyValuePair<string, string>("idx", idx.ToString( System.Globalization.CultureInfo.InvariantCulture))); routerPoints.Add(routerPoint); // add the hook. hooksAtPoint.Add(operation.Hooks[idx]); } else {// this hook is not routable. if (idx == 0) { // the first point has to be valid! throw new Exception("Cannot resolve source point of a CalculateToClosest() operation."); } unroutableHooks.Add(operation.Hooks[idx]); } } else { // add the hook. hooksAtPoint.Add(operation.Hooks[idx]); } } } // add the unroutable hooks. response.UnroutableHooks = unroutableHooks.ToArray(); // extract the first point. RouterPoint first = routerPoints[0]; routerPoints.RemoveAt(0); // calculate all the weights. OsmSharpRoute route = router.CalculateToClosest(operation.Vehicle, first, routerPoints.ToArray()); if (route != null) { // add the routerpoint tags. string idxClosestString = route.Entries[route.Entries.Length - 1].Points[0].Tags[1].Value; int idxClosest = int.Parse(idxClosestString); // get the closest point. RoutingHook pointClosest = operation.Hooks[idxClosest]; // get the routerpoint. RoutePoint routePoint = route.Entries[route.Entries.Length - 1].Points[0]; // add the closest point tags. routePoint.Latitude = pointClosest.Latitude; routePoint.Longitude = pointClosest.Longitude; List<KeyValuePair<string, string>> tags = pointClosest.Tags.ConvertToList(); tags.Add(new KeyValuePair<string, string>("id", pointClosest.Id.ToString())); // add the id-tag. routePoint.Tags = tags.ConvertFrom(); response.Route = route; // set the response as successfull. response.Status = OsmSharpServiceResponseStatusEnum.Success; } return response; }
/// <summary> /// Calculates a regular route. /// </summary> /// <param name="operation">The operation request.</param> /// <param name="router">The router.</param> /// <param name="matcher">Contains an algorithm to match points to the route network.</param> /// <returns></returns> private RoutingResponse DoRegular( RoutingOperation operation, Router<SimpleWeighedEdge> router, IEdgeMatcher matcher) { // create the response. var response = new RoutingResponse(); OsmSharpRoute route = null; RouterPoint previous = null; var unroutableHooks = new List<RoutingHook>(); // keep a list of unroutable hooks. for (int idx = 0; idx < operation.Hooks.Length - 1; idx++) { // resolve the next point. RouterPoint next = router.Resolve(operation.Vehicle, new GeoCoordinate(operation.Hooks[idx].Latitude, operation.Hooks[idx].Longitude), matcher, operation.Hooks[idx].Tags.ConvertToDictionary()); // check the routability. if (next != null && router.CheckConnectivity(operation.Vehicle, next, 200)) { // the next point is routable. if (previous != null) { // calculate the next part of the route. OsmSharpRoute routePart = router.Calculate(operation.Vehicle, previous, next); // concatenate the route part. if (route == null) { route = routePart; } else { route = OsmSharpRoute.Concatenate(route, routePart); } } // set the next to the previous. previous = next; } else { // add the hook to the unroutable hooks list. unroutableHooks.Add(operation.Hooks[idx]); } } // add the unroutable hooks. response.UnroutableHooks = unroutableHooks.ToArray(); // set the response route. response.Route = route; // report succes! response.Status = OsmSharpServiceResponseStatusEnum.Success; response.StatusMessage = string.Empty; return response; }
/// <summary> /// Calculates a matrix of weights between all given points. /// </summary> /// <param name="operation">The operation request.</param> /// <param name="router">The router.</param> /// <param name="matcher">Contains an algorithm to match points to the route network.</param> /// <returns></returns> private RoutingResponse DoManyToMany( RoutingOperation operation, Router<SimpleWeighedEdge> router, IEdgeMatcher matcher) { // create the response. var response = new RoutingResponse(); // resolve the points and do the routing. var routerPoints = new List<RouterPoint>(); var unroutableHooks = new List<RoutingHook>(); // save the unroutable hooks. for (int idx = 0; idx < operation.Hooks.Length; idx++) { // routing hook tags. IDictionary<string, string> tags = operation.Hooks[idx].Tags.ConvertToDictionary(); // resolve the point. RouterPoint routerPoint = router.Resolve(operation.Vehicle, new GeoCoordinate( operation.Hooks[idx].Latitude, operation.Hooks[idx].Longitude), matcher, tags); // check the result. if (routerPoint == null) { // this hook is not routable. unroutableHooks.Add(operation.Hooks[idx]); } else { // a point to hook on was found! // check if the router point is routable. if (router.CheckConnectivity(operation.Vehicle, routerPoint, 200)) { // the point is routable. // add the new router point to the list. routerPoint.Tags.Add(new KeyValuePair<string, string>("id", routerPoints.Count.ToString( System.Globalization.CultureInfo.InvariantCulture))); routerPoints.Add(routerPoint); } else { // this hook is not routable. unroutableHooks.Add(operation.Hooks[idx]); } } } // add the unroutable hooks. response.UnroutableHooks = unroutableHooks.ToArray(); // calculate and fill the response. response.Weights = router.CalculateManyToManyWeight(operation.Vehicle, routerPoints.ToArray(), routerPoints.ToArray()); // report succes! response.Status = OsmSharpServiceResponseStatusEnum.Success; response.StatusMessage = string.Empty; return response; }