/// <summary> /// Builds a raw router to compare against. /// </summary> /// <returns></returns> public IRouter<RouterPoint> BuildDykstraRouter(IBasicRouterDataSource<PreProcessedEdge> data, IRoutingInterpreter interpreter, IBasicRouter<PreProcessedEdge> basic_router) { // initialize the router. return new Router<PreProcessedEdge>( data, interpreter, basic_router); }
/// <summary> /// Builds a router. /// </summary> /// <returns></returns> public override Router BuildRouter(IBasicRouterDataSource <LiveEdge> data, IOsmRoutingInterpreter interpreter, IBasicRouter <LiveEdge> basicRouter) { // initialize the router. return(Router.CreateLiveFrom(data, basicRouter, interpreter)); }
/// <summary> /// Test if routes from a resolved node to itself is correctly calculated. /// /// Regression Test: Routing to self with a resolved node returns a route to the nearest real node and back. /// </summary> protected void DoTestResolveBetweenRouteToSelf() { var interpreter = new OsmRoutingInterpreter(); IBasicRouterDataSource <TEdgeData> data = this.BuildData(interpreter, "OsmSharp.Test.Unittests.test_network.osm"); IBasicRouter <TEdgeData> basicRouter = this.BuildBasicRouter(data); Router router = this.BuildRouter(data, interpreter, basicRouter); // first test a non-between node. RouterPoint resolved = router.Resolve(Vehicle.Car, new GeoCoordinate(51.0576193, 3.7191801)); Route route = router.Calculate(Vehicle.Car, resolved, resolved); Assert.AreEqual(1, route.Entries.Length); Assert.AreEqual(0, route.TotalDistance); Assert.AreEqual(0, route.TotalTime); resolved = router.Resolve(Vehicle.Car, new GeoCoordinate(51.0578761, 3.7193972)); //,-103, -4, -8 route = router.Calculate(Vehicle.Car, resolved, resolved); Assert.AreEqual(1, route.Entries.Length); Assert.AreEqual(0, route.TotalDistance); Assert.AreEqual(0, route.TotalTime); resolved = router.Resolve(Vehicle.Car, new GeoCoordinate(51.0576510, 3.7194124)); //,-104, -14, -12 route = router.Calculate(Vehicle.Car, resolved, resolved); Assert.AreEqual(1, route.Entries.Length); Assert.AreEqual(0, route.TotalDistance); Assert.AreEqual(0, route.TotalTime); resolved = router.Resolve(Vehicle.Car, new GeoCoordinate(51.0576829, 3.7196791)); //,-105, -12, -10 route = router.Calculate(Vehicle.Car, resolved, resolved); Assert.AreEqual(1, route.Entries.Length); Assert.AreEqual(0, route.TotalDistance); Assert.AreEqual(0, route.TotalTime); }
/// <summary> /// Tests that a router preserves tags that are located on ways/arcs in the route. /// </summary> protected void DoTestArcTags() { var interpreter = new OsmRoutingInterpreter(); IBasicRouterDataSource <TEdgeData> data = this.BuildData(interpreter, "OsmSharp.Test.Unittests.test_network.osm"); IBasicRouter <TEdgeData> basicRouter = this.BuildBasicRouter(data); Router router = this.BuildRouter( data, interpreter, basicRouter); RouterPoint source = router.Resolve(Vehicle.Car, new GeoCoordinate(51.0578532, 3.7192229)); source.Tags.Add(new KeyValuePair <string, string>("name", "source")); RouterPoint target = router.Resolve(Vehicle.Car, new GeoCoordinate(51.0576193, 3.7191801)); target.Tags.Add(new KeyValuePair <string, string>("name", "target")); Route route = router.Calculate(Vehicle.Car, source, target); Assert.IsNotNull(route); Assert.AreEqual(5, route.Entries.Length); Assert.AreEqual("highway", route.Entries[1].Tags[0].Key); Assert.AreEqual("residential", route.Entries[1].Tags[0].Value); Assert.AreEqual("highway", route.Entries[2].Tags[0].Key); Assert.AreEqual("residential", route.Entries[2].Tags[0].Value); Assert.AreEqual("highway", route.Entries[3].Tags[0].Key); Assert.AreEqual("residential", route.Entries[3].Tags[0].Value); }
/// <summary> /// Test if routes between resolved nodes are correctly calculated. /// /// 20----x----21----x----16 /// </summary> protected void DoTestResolveCase1() { // initialize data. var interpreter = new OsmRoutingInterpreter(); IBasicRouterDataSource <TEdgeData> data = this.BuildData(interpreter, "OsmSharp.Test.Unittests.test_network.osm"); var vertex20 = new GeoCoordinate(51.0578532, 3.7192229); var vertex21 = new GeoCoordinate(51.0578518, 3.7195654); var vertex16 = new GeoCoordinate(51.0577299, 3.719745); PointF2D point = vertex20 + ((vertex21 - vertex20) * 0.5); var vertex2021 = new GeoCoordinate(point[1], point[0]); point = vertex21 + ((vertex16 - vertex21) * 0.5); var vertex2116 = new GeoCoordinate(point[1], point[0]); // calculate route. IRoutingAlgorithm <TEdgeData> basicRouter = this.BuildBasicRouter(data); Router router = this.BuildRouter(data, interpreter, basicRouter); Route route = router.Calculate(Vehicle.Car, router.Resolve(Vehicle.Car, vertex2021), router.Resolve(Vehicle.Car, vertex2116)); Assert.AreEqual(3, route.Segments.Length); Assert.AreEqual(vertex2021.Latitude, route.Segments[0].Latitude, 0.0001); Assert.AreEqual(vertex2021.Longitude, route.Segments[0].Longitude, 0.0001); Assert.AreEqual(vertex21.Latitude, route.Segments[1].Latitude, 0.0001); Assert.AreEqual(vertex21.Longitude, route.Segments[1].Longitude, 0.0001); Assert.AreEqual(vertex2116.Latitude, route.Segments[2].Latitude, 0.0001); Assert.AreEqual(vertex2116.Longitude, route.Segments[2].Longitude, 0.0001); }
/// <summary> /// Tests if the many-to-many weights are the same as the point-to-point weights. /// </summary> protected void DoTestManyToMany1() { var interpreter = new OsmRoutingInterpreter(); IBasicRouterDataSource <EdgeData> data = this.BuildData(interpreter); IBasicRouter <EdgeData> basicRouter = this.BuildBasicRouter(data); Router router = this.BuildRouter( data, interpreter, basicRouter); var resolvedPoints = new RouterPoint[3]; resolvedPoints[0] = router.Resolve(Vehicle.Car, new GeoCoordinate(51.0578532, 3.7192229)); resolvedPoints[1] = router.Resolve(Vehicle.Car, new GeoCoordinate(51.0576193, 3.7191801)); resolvedPoints[2] = router.Resolve(Vehicle.Car, new GeoCoordinate(51.0581001, 3.7200612)); double[][] weights = router.CalculateManyToManyWeight(Vehicle.Car, resolvedPoints, resolvedPoints); for (int x = 0; x < weights.Length; x++) { for (int y = 0; y < weights.Length; y++) { double manyToMany = weights[x][y]; double pointToPoint = router.CalculateWeight(Vehicle.Car, resolvedPoints[x], resolvedPoints[y]); Assert.AreEqual(pointToPoint, manyToMany); } } }
public static void Initialize() { var routingSerializer = new CHEdgeDataDataSourceSerializer(); _graph = routingSerializer.Deserialize( Assembly.GetExecutingAssembly().GetManifestResourceStream(@"Android.Routing.Offline.kempen-big.osm.pbf.contracted.mobile.routing")); }
/// <summary> /// Tests one route. /// </summary> /// <param name="embeddedName"></param> /// <param name="contract"></param> /// <param name="from"></param> /// <param name="to"></param> protected void TestCompareOne(string embeddedName, bool contract, GeoCoordinate from, GeoCoordinate to) { // build the routing settings. IOsmRoutingInterpreter interpreter = new OsmSharp.Routing.Osm.Interpreter.OsmRoutingInterpreter(); // get the osm data source. IBasicRouterDataSource <LiveEdge> data = this.BuildDykstraDataSource(interpreter, embeddedName); // build the reference router.; Router referenceRouter = this.BuildDykstraRouter( this.BuildDykstraDataSource(interpreter, embeddedName), interpreter, new DykstraRoutingLive()); // build the router to be tested. Router router = this.BuildRouter(interpreter, embeddedName, contract); RouterPoint referenceResolvedFrom = referenceRouter.Resolve(Vehicle.Car, from); RouterPoint referenceResolvedTo = referenceRouter.Resolve(Vehicle.Car, to); RouterPoint resolvedFrom = router.Resolve(Vehicle.Car, from); RouterPoint resolvedTo = router.Resolve(Vehicle.Car, to); Route referenceRoute = referenceRouter.Calculate(Vehicle.Car, referenceResolvedFrom, referenceResolvedTo); Route route = router.Calculate(Vehicle.Car, resolvedFrom, resolvedTo); this.CompareRoutes(referenceRoute, route); }
/// <summary> /// Does the actual testing. /// </summary> /// <param name="embeddedString"></param> private void DoRoutingSerializationV2CHRoutingV2ComparisonTest(string embeddedString) { // creates a new interpreter. var interpreter = new OsmRoutingInterpreter(); // do the data processing. var original = CHEdgeGraphOsmStreamTarget.Preprocess(new XmlOsmStreamSource( Assembly.GetExecutingAssembly().GetManifestResourceStream(embeddedString)), interpreter, Vehicle.Car); // create serializer. var routingSerializer = new OsmSharp.Routing.CH.Serialization.Sorted.CHEdgeDataDataSourceSerializer(); // serialize/deserialize. TagsCollectionBase metaData = new TagsCollection(); metaData.Add("some_key", "some_value"); byte[] byteArray; using (var stream = new MemoryStream()) { try { routingSerializer.Serialize(stream, original, metaData); byteArray = stream.ToArray(); } catch (Exception) { if (Debugger.IsAttached) { Debugger.Break(); } throw; } } IBasicRouterDataSource <CHEdgeData> deserializedVersion = routingSerializer.Deserialize(new MemoryStream(byteArray), out metaData); Assert.AreEqual(original.TagsIndex.Get(0), deserializedVersion.TagsIndex.Get(0)); Assert.IsTrue(deserializedVersion.SupportsProfile(Vehicle.Car)); Assert.IsFalse(deserializedVersion.SupportsProfile(Vehicle.Bicycle)); // create reference router. original = CHEdgeGraphOsmStreamTarget.Preprocess(new XmlOsmStreamSource( Assembly.GetExecutingAssembly() .GetManifestResourceStream(embeddedString)), interpreter, Vehicle.Car); var basicRouterOriginal = new CHRouter(); Router referenceRouter = Router.CreateCHFrom( original, basicRouterOriginal, interpreter); // try to do some routing on the deserialized version. var basicRouter = new CHRouter(); Router router = Router.CreateCHFrom( deserializedVersion, basicRouter, interpreter); this.TestCompareAll(original, referenceRouter, router); }
/// <summary> /// Returns true if the given vertex has a witness calculator. /// </summary> /// <param name="graph"></param> /// <param name="from"></param> /// <param name="to"></param> /// <param name="via"></param> /// <param name="weight"></param> /// <param name="max_settles"></param> /// <returns></returns> public bool Exists(IBasicRouterDataSource <CHEdgeData> graph, uint from, uint to, uint via, float weight, int max_settles) { if (this.CalculateWeight(graph, from, to, via, weight, max_settles) <= weight) { // do verification. return(true); } return(false); }
/// <summary> /// Creates a router using live interpreted edges. /// </summary> /// <param name="data">The data to route on.</param> /// <param name="interpreter">The routing interpreter.</param> /// <returns></returns> public static Router CreateLiveFrom(IBasicRouterDataSource <LiveEdge> data, IRoutingInterpreter interpreter) { // creates the live edge router. var liveEdgeRouter = new TypedRouterLiveEdge( data, interpreter, new DykstraRoutingLive()); return(new Router(liveEdgeRouter)); // create the actual router. }
///// <summary> ///// Adds a new scene layer with the given primitives source as it's source. ///// </summary> ///// <param name="scene"></param> ///// <returns></returns> //public LayerScene AddLayerScene(IScene2DPrimitivesSource scene) //{ // LayerScene layerScene = new LayerScene(scene); // this.AddLayer(layerScene); // return layerScene; //} /// <summary> /// Adds a graph layer with the given data and style. /// </summary> /// <param name="dataSource"></param> /// <param name="styleInterpreter"></param> /// <returns></returns> public LayerDynamicGraphLiveEdge AddLayerGraph(IBasicRouterDataSource <LiveEdge> dataSource, StyleInterpreter styleInterpreter) { LayerDynamicGraphLiveEdge layerGraph = new LayerDynamicGraphLiveEdge(dataSource, styleInterpreter); this.AddLayer(layerGraph); return(layerGraph); }
/// <summary> /// Creates a basic router datasource. /// </summary> /// <param name="datasource"></param> public BasicRouterDataSource(IBasicRouterDataSource <TEdge> datasource) { _datasource = datasource; _newEdges = new List <KeyValuePair <long, KeyValuePair <long, Tuple <TEdge, ICoordinateCollection> > > >(); _removedArcs = new HashSet <Arc>(); _newVertices = new Dictionary <long, GeoCoordinate>(); }
public void RoutingSerializationV2CHRoutingComparisonTest() { const string embeddedString = "OsmSharp.Test.Unittests.test_network_real1.osm"; // creates a new interpreter. var interpreter = new OsmRoutingInterpreter(); // do the data processing. var original = CHEdgeGraphOsmStreamTarget.Preprocess(new XmlOsmStreamSource( Assembly.GetExecutingAssembly() .GetManifestResourceStream(embeddedString)), interpreter, Vehicle.Car); // create serializer. var routingSerializer = new OsmSharp.Routing.CH.Serialization.Sorted.CHEdgeDataDataSourceSerializer(true); // serialize/deserialize. byte[] byteArray; using (var stream = new MemoryStream()) { try { routingSerializer.Serialize(stream, original); byteArray = stream.ToArray(); } catch (Exception) { if (Debugger.IsAttached) { Debugger.Break(); } throw; } } IBasicRouterDataSource <CHEdgeData> deserializedVersion = routingSerializer.Deserialize(new MemoryStream(byteArray)); Assert.AreEqual(original.TagsIndex.Get(0), deserializedVersion.TagsIndex.Get(0)); // create reference router. original = CHEdgeGraphOsmStreamTarget.Preprocess(new XmlOsmStreamSource( Assembly.GetExecutingAssembly() .GetManifestResourceStream(embeddedString)), interpreter, Vehicle.Car); var basicRouterOriginal = new CHRouter(); Router referenceRouter = Router.CreateCHFrom( original, basicRouterOriginal, interpreter); // try to do some routing on the deserialized version. var basicRouter = new CHRouter(); Router router = Router.CreateCHFrom( deserializedVersion, basicRouter, interpreter); //this.TestCompareAll(original, referenceRouter, router); }
/// <summary> /// Creates a new OSM data layer. /// </summary> /// <param name="dataSource"></param> /// <param name="styleInterpreter"></param> public LayerDynamicGraphLiveEdge(IBasicRouterDataSource <LiveEdge> dataSource, StyleInterpreter styleInterpreter) { _dataSource = dataSource; _styleInterpreter = styleInterpreter; _scene = new Scene2D(new OsmSharp.Math.Geo.Projections.WebMercator(), 16); _interpretedObjects = new Dictionary <int, HashSet <ArcId> >(); }
/// <summary> /// Creates a router using live interpreted edges. /// </summary> /// <param name="data">The data to route on.</param> /// <param name="basicRouter">A custom routing implementation.</param> /// <param name="interpreter">The routing interpreter.</param> /// <returns></returns> public static Router CreateCHFrom(IBasicRouterDataSource <CHEdgeData> data, IBasicRouter <CHEdgeData> basicRouter, IRoutingInterpreter interpreter) { // creates the live edge router. var liveEdgeRouter = new TypedRouterCHEdge( data, interpreter, basicRouter); return(new Router(liveEdgeRouter)); // create the actual router. }
/// <summary> /// Creates a new OSM data layer. /// </summary> /// <param name="dataSource"></param> /// <param name="styleInterpreter"></param> public LayerDynamicGraphLiveEdge(IBasicRouterDataSource<LiveEdge> dataSource, StyleInterpreter styleInterpreter) { _dataSource = dataSource; _styleInterpreter = styleInterpreter; _scene = new Scene2D(new OsmSharp.Math.Geo.Projections.WebMercator(), 16); _interpretedObjects = new Dictionary<int, HashSet<ArcId>>(); }
/// <summary> /// Compares all routes against the reference router. /// </summary> public void TestCompareAll(string embeddedName) { // build the routing settings. IRoutingInterpreter interpreter = new OsmSharp.Routing.Osm.Interpreter.OsmRoutingInterpreter(); // get the osm data source. IBasicRouterDataSource <LiveEdge> data = this.BuildDykstraDataSource(interpreter, embeddedName); // build the reference router.; Router referenceRouter = this.BuildDykstraRouter( this.BuildDykstraDataSource(interpreter, embeddedName), interpreter, new DykstraRoutingLive(data.TagsIndex)); // build the router to be tested. Router router = this.BuildRouter(interpreter, embeddedName); // loop over all nodes and resolve their locations. var resolvedReference = new RouterPoint[data.VertexCount - 1]; var resolved = new RouterPoint[data.VertexCount - 1]; for (uint idx = 1; idx < data.VertexCount; idx++) { // resolve each vertex. float latitude, longitude; if (data.GetVertex(idx, out latitude, out longitude)) { resolvedReference[idx - 1] = referenceRouter.Resolve(Vehicle.Car, new GeoCoordinate(latitude, longitude)); resolved[idx - 1] = router.Resolve(Vehicle.Car, new GeoCoordinate(latitude, longitude)); } Assert.IsNotNull(resolvedReference[idx - 1]); Assert.IsNotNull(resolved[idx - 1]); Assert.AreEqual(resolvedReference[idx - 1].Location.Latitude, resolved[idx - 1].Location.Latitude, 0.0001); Assert.AreEqual(resolvedReference[idx - 1].Location.Longitude, resolved[idx - 1].Location.Longitude, 0.0001); } // check all the routes having the same weight(s). for (int fromIdx = 0; fromIdx < resolved.Length; fromIdx++) { for (int toIdx = 0; toIdx < resolved.Length; toIdx++) { OsmSharpRoute referenceRoute = referenceRouter.Calculate(Vehicle.Car, resolvedReference[fromIdx], resolvedReference[toIdx]); OsmSharpRoute route = router.Calculate(Vehicle.Car, resolved[fromIdx], resolved[toIdx]); Assert.IsNotNull(referenceRoute); Assert.IsNotNull(route); Assert.AreEqual(referenceRoute.TotalDistance, route.TotalDistance, 0.0001); // TODO: meta data is missing in some CH routing; see issue //Assert.AreEqual(reference_route.TotalTime, route.TotalTime, 0.0001); } } }
/// <summary> /// Returns true if the given vertex has a witness calculator. /// </summary> /// <param name="graph"></param> /// <param name="from"></param> /// <param name="to"></param> /// <param name="maxWeight"></param> /// <param name="maxSettles"></param> /// <returns></returns> public bool Exists(IBasicRouterDataSource<CHEdgeData> graph, uint from, uint to, float maxWeight, int maxSettles) { var tos = new List<uint>(1); tos.Add(to); var tosWeights = new List<float>(1); tosWeights.Add(maxWeight); var exists = new bool[1]; this.Exists(graph, from, tos, tosWeights, maxSettles, ref exists); return exists[0]; }
/// <summary> /// Creates a new OSM data layer. /// </summary> /// <param name="dataSource"></param> /// <param name="styleInterpreter"></param> public LayerDynamicGraphLiveEdge(IBasicRouterDataSource <LiveEdge> dataSource, StyleInterpreter styleInterpreter) { _dataSource = dataSource; _styleInterpreter = styleInterpreter; this.Scene = new Scene2DSimple(); _interpretedObjects = new Dictionary <int, HashSet <ArcId> >(); this.Cache = false; }
/// <summary> /// Creates a new OSM data layer. /// </summary> /// <param name="dataSource"></param> /// <param name="styleInterpreter"></param> public LayerDynamicGraphLiveEdge(IBasicRouterDataSource<LiveEdge> dataSource, StyleInterpreter styleInterpreter) { _dataSource = dataSource; _styleInterpreter = styleInterpreter; this.Scene = new Scene2DSimple(); _interpretedObjects = new Dictionary<int, HashSet<ArcId>>(); this.Cache = false; }
/// <summary> /// Calculates a shortest path between the source vertex and any of the targets and returns the shortest. /// </summary> /// <param name="graph"></param> /// <param name="interpreter"></param> /// <param name="vehicle"></param> /// <param name="from"></param> /// <param name="targets"></param> /// <param name="max"></param> /// <returns></returns> public PathSegment <long> CalculateToClosest(IBasicRouterDataSource <LiveEdge> graph, IRoutingInterpreter interpreter, Vehicle vehicle, PathSegmentVisitList from, PathSegmentVisitList[] targets, double max) { PathSegment <long>[] result = this.DoCalculation(graph, interpreter, vehicle, from, targets, max, false, false); if (result != null && result.Length == 1) { return(result[0]); } return(null); }
/// <summary> /// Tests the the given router class by comparing calculated routes agains a given reference router. /// </summary> /// <param name="data"></param> /// <param name="referenceRouter"></param> /// <param name="router"></param> protected void TestCompareAll <TEdgeData>(IBasicRouterDataSource <TEdgeData> data, Router referenceRouter, Router router) where TEdgeData : IGraphEdgeData { // loop over all nodes and resolve their locations. var resolvedReference = new RouterPoint[data.VertexCount - 1]; var resolved = new RouterPoint[data.VertexCount - 1]; for (uint idx = 1; idx < data.VertexCount; idx++) { // resolve each vertex. float latitude, longitude; if (data.GetVertex(idx, out latitude, out longitude)) { resolvedReference[idx - 1] = referenceRouter.Resolve(Vehicle.Car, new GeoCoordinate(latitude, longitude), true); resolved[idx - 1] = router.Resolve(Vehicle.Car, new GeoCoordinate(latitude, longitude), true); } // reference and resolved have to exist. Assert.IsNotNull(resolvedReference[idx - 1]); Assert.IsNotNull(resolved[idx - 1]); // reference and resolved cannot be more than 10cm apart. Assert.AreEqual(0, resolvedReference[idx - 1].Location.DistanceReal( resolved[idx - 1].Location).Value, 0.1, "Reference and resolved are more than 10cm apart."); } // limit tests to a fixed number. int maxTestCount = 100; int testEveryOther = (resolved.Length * resolved.Length) / maxTestCount; testEveryOther = System.Math.Max(testEveryOther, 1); // check all the routes having the same weight(s). for (int fromIdx = 0; fromIdx < resolved.Length; fromIdx++) { for (int toIdx = 0; toIdx < resolved.Length; toIdx++) { int testNumber = fromIdx * resolved.Length + toIdx; if (testNumber % testEveryOther == 0) { var referenceRoute = referenceRouter.Calculate(Vehicle.Car, resolvedReference[fromIdx], resolvedReference[toIdx]); var route = router.Calculate(Vehicle.Car, resolved[fromIdx], resolved[toIdx]); if (referenceRoute != null) { Assert.IsNotNull(referenceRoute); Assert.IsNotNull(route); this.CompareRoutes(referenceRoute, route); } } } } }
/// <summary> /// Calculates the shortest path from all sources to all targets. /// </summary> /// <param name="graph"></param> /// <param name="interpreter"></param> /// <param name="vehicle"></param> /// <param name="sources"></param> /// <param name="targets"></param> /// <param name="maxSearch"></param> /// <returns></returns> public PathSegment <long>[][] CalculateManyToMany(IBasicRouterDataSource <LiveEdge> graph, IRoutingInterpreter interpreter, Vehicle vehicle, PathSegmentVisitList[] sources, PathSegmentVisitList[] targets, double maxSearch) { var results = new PathSegment <long> [sources.Length][]; for (int sourceIdx = 0; sourceIdx < sources.Length; sourceIdx++) { results[sourceIdx] = this.DoCalculation(graph, interpreter, vehicle, sources[sourceIdx], targets, maxSearch, false, false); } return(results); }
/// <summary> /// Calculates the shortest path from the given vertex to the given vertex given the weights in the graph. /// </summary> /// <param name="vehicle"></param> /// <param name="from"></param> /// <param name="to"></param> /// <param name="graph"></param> /// <param name="interpreter"></param> /// <param name="max"></param> /// <returns></returns> public double CalculateWeight(IBasicRouterDataSource <LiveEdge> graph, IRoutingInterpreter interpreter, Vehicle vehicle, PathSegmentVisitList from, PathSegmentVisitList to, double max) { PathSegment <long> closest = this.CalculateToClosest(graph, interpreter, vehicle, from, new PathSegmentVisitList[] { to }, max); if (closest != null) { return(closest.Weight); } return(double.MaxValue); }
/// <summary> /// Returns true if the given vertex has a witness calculator. /// </summary> /// <param name="graph"></param> /// <param name="from"></param> /// <param name="to"></param> /// <param name="via"></param> /// <param name="weight"></param> /// <param name="max_settles"></param> /// <returns></returns> public bool Exists(IBasicRouterDataSource<CHEdgeData> graph, uint from, uint to, uint via, float weight, int max_settles) { if (this.CalculateWeight(graph, from, to, via, weight, max_settles) <= weight) { // do verification. //CHRouter router = new CHRouter(_data); //if (!(router.CalculateWeight(from, to, via, weight, max_settles) <= weight)) //{ // //throw new Exception(); //} return true; } return false; }
/// <summary> /// Calculates the shortest path from the given vertex to the given vertex given the weights in the graph. /// </summary> /// <param name="graph"></param> /// <param name="from"></param> /// <param name="to"></param> /// <param name="interpreter"></param> /// <param name="vehicle"></param> /// <returns></returns> public PathSegment <long> Calculate(IBasicRouterDataSource <LiveEdge> graph, IRoutingInterpreter interpreter, Vehicle vehicle, uint from, uint to) { var source = new PathSegmentVisitList(); source.UpdateVertex(new PathSegment <long>(from)); var target = new PathSegmentVisitList(); target.UpdateVertex(new PathSegment <long>(to)); // do the basic CH calculations. return(this.Calculate(graph, interpreter, vehicle, source, target, float.MaxValue, null)); }
/// <summary> /// Returns true if the given vertex has a witness calculator. /// </summary> /// <param name="graph"></param> /// <param name="from"></param> /// <param name="to"></param> /// <param name="via"></param> /// <param name="weight"></param> /// <param name="max_settles"></param> /// <returns></returns> public bool Exists(IBasicRouterDataSource <CHEdgeData> graph, uint from, uint to, uint via, float weight, int max_settles) { if (this.CalculateWeight(graph, from, to, via, weight, max_settles) <= weight) { // do verification. //CHRouter router = new CHRouter(_data); //if (!(router.CalculateWeight(from, to, via, weight, max_settles) <= weight)) //{ // //throw new Exception(); //} return(true); } return(false); }
/// <summary> /// Calculates all routes from a given sources to all given targets. /// </summary> /// <param name="graph"></param> /// <param name="interpreter"></param> /// <param name="vehicle"></param> /// <param name="sources"></param> /// <param name="targets"></param> /// <param name="max"></param> /// <returns></returns> public double[][] CalculateManyToManyWeight(IBasicRouterDataSource <LiveEdge> graph, IRoutingInterpreter interpreter, Vehicle vehicle, PathSegmentVisitList[] sources, PathSegmentVisitList[] targets, double max) { var results = new double[sources.Length][]; for (int idx = 0; idx < sources.Length; idx++) { results[idx] = this.CalculateOneToManyWeight(graph, interpreter, vehicle, sources[idx], targets, max); OsmSharp.Logging.Log.TraceEvent("DykstraRoutingLive", System.Diagnostics.TraceEventType.Information, "Calculating weights... {0}%", (int)(((float)idx / (float)sources.Length) * 100)); } return(results); }
/// <summary> /// Calculates all points that are at or close to the given weight. /// </summary> /// <param name="graph"></param> /// <param name="interpreter"></param> /// <param name="vehicle"></param> /// <param name="source"></param> /// <param name="weight"></param> /// <param name="forward"></param> /// <returns></returns> public HashSet <long> CalculateRange(IBasicRouterDataSource <LiveEdge> graph, IRoutingInterpreter interpreter, Vehicle vehicle, PathSegmentVisitList source, double weight, bool forward) { PathSegment <long>[] result = this.DoCalculation(graph, interpreter, vehicle, source, new PathSegmentVisitList[0], weight, false, true, forward); var resultVertices = new HashSet <long>(); for (int idx = 0; idx < result.Length; idx++) { resultVertices.Add(result[idx].VertexId); } return(resultVertices); }
/// <summary> /// Tests that a router actually finds the shortest route. /// </summary> protected void DoTestShortestResolved1() { var interpreter = new OsmRoutingInterpreter(); IBasicRouterDataSource <TEdgeData> data = this.BuildData(interpreter, "OsmSharp.Test.Unittests.test_network.osm"); IBasicRouter <TEdgeData> basicRouter = this.BuildBasicRouter(data); Router router = this.BuildRouter( data, interpreter, basicRouter); RouterPoint source = router.Resolve(Vehicle.Car, new GeoCoordinate(51.0578153, 3.7193937)); RouterPoint target = router.Resolve(Vehicle.Car, new GeoCoordinate(51.0582408, 3.7194636)); Route route = router.Calculate(Vehicle.Car, source, target); Assert.IsNotNull(route); Assert.AreEqual(10, route.Entries.Length); }
/// <summary> /// Tests that a router actually finds the shortest route. /// </summary> protected void DoTestShortest2() { var interpreter = new OsmRoutingInterpreter(); IBasicRouterDataSource <TEdgeData> data = this.BuildData(interpreter, "OsmSharp.Test.Unittests.test_network.osm"); IBasicRouter <TEdgeData> basicRouter = this.BuildBasicRouter(data); Router router = this.BuildRouter( data, interpreter, basicRouter); RouterPoint source = router.Resolve(Vehicle.Car, new GeoCoordinate(51.0579235, 3.7199811)); RouterPoint target = router.Resolve(Vehicle.Car, new GeoCoordinate(51.0578532, 3.7192229)); Route route = router.Calculate(Vehicle.Car, source, target); Assert.IsNotNull(route); Assert.AreEqual(6, route.Segments.Length); }
/// <summary> /// Tests that a router actually finds the shortest route. /// </summary> protected void DoTestShortest5() { var interpreter = new OsmRoutingInterpreter(); IBasicRouterDataSource <TEdgeData> data = this.BuildData(interpreter, "OsmSharp.Test.Unittests.test_network.osm"); IRoutingAlgorithm <TEdgeData> basic_router = this.BuildBasicRouter(data); Router router = this.BuildRouter( data, interpreter, basic_router); RouterPoint source = router.Resolve(Vehicle.Car, new GeoCoordinate(51.0576193, 3.7191801)); RouterPoint target = router.Resolve(Vehicle.Car, new GeoCoordinate(51.0581001, 3.7200612)); Route route = router.Calculate(Vehicle.Car, source, target); Assert.IsNotNull(route); Assert.AreEqual(7, route.Segments.Length); }
/// <summary> /// Tests that a router actually finds the shortest route. /// </summary> protected void DoTestShortestResolved2() { var interpreter = new OsmRoutingInterpreter(); IBasicRouterDataSource <TEdgeData> data = this.BuildData(interpreter, "OsmSharp.Test.Unittests.test_network.osm"); IRoutingAlgorithm <TEdgeData> basicRouter = this.BuildBasicRouter(data); Router router = this.BuildRouter( data, interpreter, basicRouter); RouterPoint source = router.Resolve(Vehicle.Car, new GeoCoordinate(51.0581843, 3.7201209)); // between 2 - 3 RouterPoint target = router.Resolve(Vehicle.Car, new GeoCoordinate(51.0581484, 3.7194957)); // between 9 - 8 Route route = router.Calculate(Vehicle.Car, source, target); Assert.IsNotNull(route); Assert.AreEqual(5, route.Segments.Length); }
/// <summary> /// Returns true if the search can move beyond the given weight. /// </summary> /// <param name="graph"></param> /// <param name="interpreter"></param> /// <param name="vehicle"></param> /// <param name="source"></param> /// <param name="weight"></param> /// <returns></returns> public bool CheckConnectivity(IBasicRouterDataSource <LiveEdge> graph, IRoutingInterpreter interpreter, Vehicle vehicle, PathSegmentVisitList source, double weight) { HashSet <long> range = this.CalculateRange(graph, interpreter, vehicle, source, weight, true); if (range.Count > 0) { range = this.CalculateRange(graph, interpreter, vehicle, source, weight, false); if (range.Count > 0) { return(true); } } return(false); }
/// <summary> /// Creates a router using live interpreted edges. /// </summary> /// <param name="data">The data to route on.</param> /// <param name="basicRouter">A custom routing implementation.</param> /// <param name="interpreter">The routing interpreter.</param> /// <returns></returns> public static Router CreateLiveFrom(IBasicRouterDataSource<LiveEdge> data, IRoutingAlgorithm<LiveEdge> basicRouter, IRoutingInterpreter interpreter) { // creates the live edge router. var liveEdgeRouter = new TypedRouterLiveEdge( data, interpreter, basicRouter); return new Router(liveEdgeRouter); // create the actual router. }
/// <summary> /// Creates a router using live interpreted edges. /// </summary> /// <param name="data">The data to route on.</param> /// <param name="interpreter">The routing interpreter.</param> /// <returns></returns> public static Router CreateLiveFrom(IBasicRouterDataSource<LiveEdge> data, IRoutingInterpreter interpreter) { // creates the live edge router. var liveEdgeRouter = new TypedRouterLiveEdge( data, interpreter, new DykstraRoutingLive(data.TagsIndex)); return new Router(liveEdgeRouter); // create the actual router. }
/// <summary> /// Creates a router using live interpreted edges. /// </summary> /// <param name="data">The data to route on.</param> /// <param name="basicRouter">A custom routing implementation.</param> /// <param name="interpreter">The routing interpreter.</param> /// <returns></returns> public static Router CreateCHFrom(IBasicRouterDataSource<CHEdgeData> data, IBasicRouter<CHEdgeData> basicRouter, IRoutingInterpreter interpreter) { // creates the live edge router. var liveEdgeRouter = new TypedRouterCHEdge( data, interpreter, basicRouter); return new Router(liveEdgeRouter); // create the actual router. }
/// <summary> /// Calculates witnesses from on source to multiple targets at once. /// </summary> /// <param name="graph"></param> /// <param name="from"></param> /// <param name="tos"></param> /// <param name="tosWeights"></param> /// <param name="maxSettles"></param> /// <param name="exists"></param> public void Exists(IBasicRouterDataSource<CHEdgeData> graph, uint from, List<uint> tos, List<float> tosWeights, int maxSettles, ref bool[] exists) { int maxHops = _hopLimit; if (maxHops == 1) { this.ExistsOneHop(graph, from, tos, tosWeights, maxSettles, ref exists); return; } // creates the settled list. var settled = new HashSet<uint>(); var toSet = new HashSet<uint>(); float maxWeight = 0; for(int idx = 0; idx < tos.Count; idx++) { if(!exists[idx]) { toSet.Add(tos[idx]); if(maxWeight < tosWeights[idx]) { maxWeight = tosWeights[idx]; } } } // creates the priorty queue. var heap = _reusableHeap; heap.Clear(); heap.Push(new SettledVertex(from, 0, 0), 0); // keep looping until the queue is empty or the target is found! while (heap.Count > 0) { // pop the first customer. var current = heap.Pop(); if (!settled.Contains(current.VertexId)) { // the current vertex has net been settled. settled.Add(current.VertexId); // settled the vertex. // check if this is a to. if(toSet.Contains(current.VertexId)) { int index = tos.IndexOf(current.VertexId); exists[index] = current.Weight < tosWeights[index]; toSet.Remove(current.VertexId); if(toSet.Count == 0) { break; } } if (settled.Count >= maxSettles) { // do not continue searching. break; } // get the neighbours. var neighbours = graph.GetEdges(current.VertexId); while (neighbours.MoveNext()) { if (!settled.Contains(neighbours.Neighbour)) { if (neighbours.isInverted) { var invertedEdgeData = neighbours.InvertedEdgeData; if (invertedEdgeData.Backward && !invertedEdgeData.ToHigher && !invertedEdgeData.ToLower) { var neighbour = new SettledVertex(neighbours.Neighbour, invertedEdgeData.BackwardWeight + current.Weight, current.Hops + 1); if (neighbour.Weight < maxWeight && neighbour.Hops < maxHops) { heap.Push(neighbour, neighbour.Weight); //if (toSet.Contains(neighbours.Neighbour)) // check early for witnesses. //{ // this neighbour has been found and it already represents a witness even if not shortest. // int index = tos.IndexOf(neighbours.Neighbour); // if (neighbour.Weight < tosWeights[index] || // heap.Peek().VertexId == neighbours.Neighbour) // { // ok, witness already found. // exists[index] = current.Weight < tosWeights[index]; // toSet.Remove(neighbours.Neighbour); // if (toSet.Count == 0) // { // break; // } // } //} } } } else { var edgeData = neighbours.EdgeData; if (edgeData.Forward && !edgeData.ToHigher && !edgeData.ToLower) { var neighbour = new SettledVertex(neighbours.Neighbour, edgeData.ForwardWeight + current.Weight, current.Hops + 1); if (neighbour.Weight < maxWeight && neighbour.Hops < maxHops) { heap.Push(neighbour, neighbour.Weight); //if (toSet.Contains(neighbours.Neighbour)) // check early for witnesses. //{ // this neighbour has been found and it already represents a witness even if not shortest. // int index = tos.IndexOf(neighbours.Neighbour); // if (neighbour.Weight < tosWeights[index] || // heap.Peek().VertexId == neighbours.Neighbour) // { // ok, witness already found. // exists[index] = current.Weight < tosWeights[index]; // toSet.Remove(neighbours.Neighbour); // if (toSet.Count == 0) // { // break; // } // } //} } } } } } } } }
/// <summary> /// Returns true if the given vertex has a witness calculator. /// </summary> /// <param name="graph"></param> /// <param name="from"></param> /// <param name="to"></param> /// <param name="via"></param> /// <param name="weight"></param> /// <param name="max_settles"></param> /// <returns></returns> public bool Exists(IBasicRouterDataSource<CHEdgeData> graph, uint from, uint to, uint via, float weight, int max_settles) { return _router.CalculateWeight(graph, from, to, via, weight, max_settles) <= weight; }
/// <summary> /// Calculates witnesses from one source to multiple targets at once but using only one hop. /// </summary> /// <param name="graph"></param> /// <param name="from"></param> /// <param name="tos"></param> /// <param name="tosWeights"></param> /// <param name="maxSettles"></param> /// <param name="exists"></param> private void ExistsOneHop(IBasicRouterDataSource<CHEdgeData> graph, uint from, List<uint> tos, List<float> tosWeights, int maxSettles, ref bool[] exists) { var toSet = new HashSet<uint>(); float maxWeight = 0; for (int idx = 0; idx < tos.Count; idx++) { if (!exists[idx]) { toSet.Add(tos[idx]); if (maxWeight < tosWeights[idx]) { maxWeight = tosWeights[idx]; } } } var neighbours = graph.GetEdges(from); while(neighbours.MoveNext()) { if(toSet.Contains(neighbours.Neighbour)) { // ok, this is a to-edge. int index = tos.IndexOf(neighbours.Neighbour); toSet.Remove(neighbours.Neighbour); if(neighbours.isInverted) { if (!neighbours.InvertedEdgeData.ToHigher && neighbours.InvertedEdgeData.Backward && neighbours.InvertedEdgeData.BackwardWeight < tosWeights[index]) { exists[index] = true; } } else { if (!neighbours.EdgeData.ToLower && neighbours.EdgeData.Forward && neighbours.EdgeData.ForwardWeight < tosWeights[index]) { exists[index] = true; } } if(toSet.Count == 0) { break; } } } }
///// <summary> ///// Adds a new scene layer with the given primitives source as it's source. ///// </summary> ///// <param name="scene"></param> ///// <returns></returns> //public LayerScene AddLayerScene(IScene2DPrimitivesSource scene) //{ // LayerScene layerScene = new LayerScene(scene); // this.AddLayer(layerScene); // return layerScene; //} /// <summary> /// Adds a graph layer with the given data and style. /// </summary> /// <param name="dataSource"></param> /// <param name="styleInterpreter"></param> /// <returns></returns> public LayerDynamicGraphLiveEdge AddLayerGraph(IBasicRouterDataSource<LiveEdge> dataSource, StyleInterpreter styleInterpreter) { LayerDynamicGraphLiveEdge layerGraph = new LayerDynamicGraphLiveEdge(dataSource, styleInterpreter); this.AddLayer(layerGraph); return layerGraph; }
/// <summary> /// Builds a raw router to compare against. /// </summary> /// <returns></returns> public Router BuildDykstraRouter(IBasicRouterDataSource<LiveEdge> data, IRoutingInterpreter interpreter, IBasicRouter<LiveEdge> basicRouter) { // initialize the router. return Router.CreateLiveFrom(data, basicRouter, interpreter); }
/// <summary> /// Implements a very simple dykstra version. /// </summary> /// <param name="graph"></param> /// <param name="from"></param> /// <param name="to"></param> /// <param name="via"></param> /// <param name="max_weight"></param> /// <param name="max_settles"></param> /// <returns></returns> private float CalculateWeight(IBasicRouterDataSource<CHEdgeData> graph, uint from, uint to, uint via, float max_weight, int max_settles) { int max_hops = 5; float weight = float.MaxValue; // creates the settled list. HashSet<uint> settled = new HashSet<uint>(); settled.Add(via); // creates the priorty queue. BinairyHeap<SettledVertex> heap = new BinairyHeap<SettledVertex>(); heap.Push(new SettledVertex(from, 0, 0), 0); // keep looping until the queue is empty or the target is found! while (heap.Count > 0) { // pop the first customer. SettledVertex current = heap.Pop(); if (!settled.Contains(current.VertexId)) { // the current vertex has net been settled. settled.Add(current.VertexId); // settled the vertex. // test stop conditions. if (current.VertexId == to) { // target is found! return current.Weight; } // test the hop count. if (current.Hops < max_hops) { // the neighbours will only increase hops! if (settled.Count >= max_settles) { // do not continue searching. return float.MaxValue; } // get the neighbours. KeyValuePair<uint, CHEdgeData>[] neighbours = graph.GetArcs(current.VertexId); for (int idx = 0; idx < neighbours.Length; idx++) { if (neighbours[idx].Value.Forward && (neighbours[idx].Key == to || !settled.Contains(neighbours[idx].Key))) { SettledVertex neighbour = new SettledVertex(neighbours[idx].Key, neighbours[idx].Value.Weight + current.Weight, current.Hops + 1); if (neighbour.Weight < max_weight) { if (neighbours[idx].Key == to) { return neighbour.Weight; } heap.Push(neighbour, neighbour.Weight); } } } } } } return weight; }