public void TestSparseRemoval1()
        {
            // use one edge definition everywhere.
            var edge = new Edge();
            edge.Forward = true;
            edge.Tags = 1;

            var graph = new Graph<Edge>();
            uint vertex1 = graph.AddVertex(0, 0);
            uint vertex2 = graph.AddVertex(1, 1);
            uint vertex3 = graph.AddVertex(2, 2);

            graph.AddEdge(vertex1, vertex2, edge, null);
            graph.AddEdge(vertex2, vertex1, edge, null);
            graph.AddEdge(vertex2, vertex3, edge, null);
            graph.AddEdge(vertex3, vertex2, edge, null);

            // execute pre-processor.
            var preProcessor = new GraphSimplificationPreprocessor(graph);
            preProcessor.Start();

            // test resulting graph.
            Assert.AreEqual(2, graph.VertexCount);
            Assert.AreEqual(1, graph.GetEdges(1).ToKeyValuePairs().Length);
            Assert.AreEqual(2, graph.GetEdges(1).ToKeyValuePairs()[0].Key);
            Assert.AreEqual(1, graph.GetEdges(2).ToKeyValuePairs().Length);
            Assert.AreEqual(1, graph.GetEdges(2).ToKeyValuePairs()[0].Key);
        }
        public void TestSparseRemoval2()
        {
            // use one edge definition everywhere.
            var edge = new Edge();
            edge.Forward = true;
            edge.Tags = 1;

            var graph = new Graph<Edge>();
            uint vertex1 = graph.AddVertex(0, 0);
            uint vertex2 = graph.AddVertex(1, 1);
            uint vertex3 = graph.AddVertex(2, 2);
            uint vertex4 = graph.AddVertex(3, 3);
            uint vertex5 = graph.AddVertex(4, 4);
            uint vertex6 = graph.AddVertex(5, 5);

            graph.AddEdge(vertex1, vertex2, edge, null); // 1 <-> 2
            graph.AddEdge(vertex2, vertex1, edge, null); // 1 <-> 2
            graph.AddEdge(vertex2, vertex3, edge, null); // 2 <-> 3
            graph.AddEdge(vertex3, vertex2, edge, null); // 2 <-> 3
            graph.AddEdge(vertex3, vertex4, edge, null); // 3 <-> 4
            graph.AddEdge(vertex4, vertex3, edge, null); // 3 <-> 4
            graph.AddEdge(vertex4, vertex5, edge, null); // 4 <-> 5
            graph.AddEdge(vertex5, vertex4, edge, null); // 4 <-> 5
            graph.AddEdge(vertex3, vertex6, edge, null); // 3 <-> 6
            graph.AddEdge(vertex6, vertex3, edge, null); // 3 <-> 6

            // execute pre-processor.
            var preProcessor = new GraphSimplificationPreprocessor(graph);
            preProcessor.Start();

            // test resulting graph.
            Assert.AreEqual(4, graph.VertexCount);

            Assert.AreEqual(1, graph.GetEdges(1).ToKeyValuePairs().Length);
            Assert.AreEqual(2, graph.GetEdges(1).ToKeyValuePairs()[0].Key);

            Assert.AreEqual(3, graph.GetEdges(2).ToKeyValuePairs().Length);
            Assert.IsTrue(graph.GetEdges(2).ToKeyValuePairs().Any(x => x.Key == 1));
            Assert.IsTrue(graph.GetEdges(2).ToKeyValuePairs().Any(x => x.Key == 3));
            Assert.IsTrue(graph.GetEdges(2).ToKeyValuePairs().Any(x => x.Key == 4));

            Assert.AreEqual(1, graph.GetEdges(3).ToKeyValuePairs().Length);
            Assert.AreEqual(2, graph.GetEdges(3).ToKeyValuePairs()[0].Key);

            Assert.AreEqual(1, graph.GetEdges(4).ToKeyValuePairs().Length);
            Assert.AreEqual(2, graph.GetEdges(4).ToKeyValuePairs()[0].Key);
        }
        public void RoutingRegressionTest11ResolvingReverse()
        {
            // build a graph to encode from.
            var tags = new TagsIndex();
            var graphDataSource = new RouterDataSource<Edge>(new Graph<Edge>(), tags);
            var vertex1 = graphDataSource.AddVertex(51.05849821468899f, 3.7240000000000000f);
            var vertex2 = graphDataSource.AddVertex(51.05849821468899f, 3.7254400000000000f);
            var vertex3 = graphDataSource.AddVertex(51.05849821468899f, 3.7225627899169926f);
            var edgeData = new Edge() // all edges are identical.
            {
                Distance = 100,
                Forward = true,
                Tags = tags.Add(new TagsCollection(
                    Tag.Create("highway", "tertiary"),
                    Tag.Create("oneway", "yes")))
            };
            var shape1 = new CoordinateArrayCollection<OsmSharp.Math.Geo.Simple.GeoCoordinateSimple>(
                new OsmSharp.Math.Geo.Simple.GeoCoordinateSimple[] {
                    new OsmSharp.Math.Geo.Simple.GeoCoordinateSimple()
                    {
                        Latitude = 1,
                        Longitude = 1
                    },
                    new OsmSharp.Math.Geo.Simple.GeoCoordinateSimple()
                    {
                        Latitude = 2,
                        Longitude = 2
                    }
                });
            var shape2 = new CoordinateArrayCollection<OsmSharp.Math.Geo.Simple.GeoCoordinateSimple>(
                new OsmSharp.Math.Geo.Simple.GeoCoordinateSimple[] {
                    new OsmSharp.Math.Geo.Simple.GeoCoordinateSimple()
                    {
                        Latitude = 3,
                        Longitude = 3
                    },
                    new OsmSharp.Math.Geo.Simple.GeoCoordinateSimple()
                    {
                        Latitude = 4,
                        Longitude = 4
                    }
                });
            graphDataSource.AddEdge(vertex1, vertex2, edgeData, shape1);
            graphDataSource.AddEdge(vertex3, vertex1, edgeData, shape2);

            var edges =  new List<Edge<Edge>>(graphDataSource.GetEdges(1));
            Assert.AreEqual(2, edges.Count);
            foreach(var edge in edges)
            {
                if (edge.Neighbour == 2)
                {
                    Assert.AreEqual(true, edge.EdgeData.Forward);
                }
                else if(edge.Neighbour == 3)
                {
                    Assert.AreEqual(false, edge.EdgeData.Forward);
                }
            }

            edges = new List<Edge<Edge>>(graphDataSource.GetEdges(2));
            Assert.AreEqual(1, edges.Count);
            Assert.AreEqual(false, edges[0].EdgeData.Forward);

            edges = new List<Edge<Edge>>(graphDataSource.GetEdges(3));
            Assert.AreEqual(1, edges.Count);
            Assert.AreEqual(true, edges[0].EdgeData.Forward);
        }
        public void RoutingRegressionTest10ResolvingReverse()
        {
            // build a graph to encode from.
            var tags = new TagsIndex();
            var graphDataSource = new RouterDataSource<Edge>(new Graph<Edge>(), tags);
            var vertex1 = graphDataSource.AddVertex(51.05849821468899f, 3.7240000000000000f);
            var vertex2 = graphDataSource.AddVertex(51.05849821468899f, 3.7254400000000000f);
            var vertex3 = graphDataSource.AddVertex(51.05849821468899f, 3.7225627899169926f);
            var edge = new Edge() // all edges are identical.
            {
                Distance = 100,
                Forward = true,
                Tags = tags.Add(new TagsCollection(
                    Tag.Create("highway", "tertiary"),
                    Tag.Create("oneway", "yes")))
            };
            var shape1 = new CoordinateArrayCollection<OsmSharp.Math.Geo.Simple.GeoCoordinateSimple>(
                new OsmSharp.Math.Geo.Simple.GeoCoordinateSimple[] {
                    new OsmSharp.Math.Geo.Simple.GeoCoordinateSimple()
                    {
                        Latitude = 1,
                        Longitude = 1
                    },
                    new OsmSharp.Math.Geo.Simple.GeoCoordinateSimple()
                    {
                        Latitude = 2,
                        Longitude = 2
                    }
                });
            var shape2 = new CoordinateArrayCollection<OsmSharp.Math.Geo.Simple.GeoCoordinateSimple>(
                new OsmSharp.Math.Geo.Simple.GeoCoordinateSimple[] {
                    new OsmSharp.Math.Geo.Simple.GeoCoordinateSimple()
                    {
                        Latitude = 3,
                        Longitude = 3
                    },
                    new OsmSharp.Math.Geo.Simple.GeoCoordinateSimple()
                    {
                        Latitude = 4,
                        Longitude = 4
                    }
                });
            graphDataSource.AddEdge(vertex1, vertex2, edge, shape1);
            graphDataSource.AddEdge(vertex3, vertex1, edge, shape2);

            // {RectF:[(3,71326552867889,51,048498214689),(3,73326552867889,51,068498214689)]}
            var edges =  graphDataSource.GetEdges(new GeoCoordinateBox(
                new GeoCoordinate(51.068498214689, 3.73326552867889),
                new GeoCoordinate(51.048498214689, 3.71326552867889)));

            while (edges.MoveNext())
            {
                if (edges.Vertex1 == 1 &&
                    edges.Vertex2 == 2)
                {
                    Assert.IsTrue(edges.EdgeData.Forward);
                    var shapes = edges.Intermediates.ToSimpleArray();
                    Assert.AreEqual(2, shapes.Length);
                    Assert.AreEqual(1, shapes[0].Latitude);
                    Assert.AreEqual(1, shapes[0].Longitude);
                    Assert.AreEqual(2, shapes[1].Latitude);
                    Assert.AreEqual(2, shapes[1].Longitude);
                }
                else if (edges.Vertex1 == 2 &&
                    edges.Vertex2 == 1)
                {
                    Assert.IsFalse(edges.EdgeData.Forward);
                    var shapes = edges.Intermediates.ToSimpleArray();
                    Assert.AreEqual(2, shapes.Length);
                    Assert.AreEqual(2, shapes[0].Latitude);
                    Assert.AreEqual(2, shapes[0].Longitude);
                    Assert.AreEqual(1, shapes[1].Latitude);
                    Assert.AreEqual(1, shapes[1].Longitude);
                }
                if (edges.Vertex1 == 1 &&
                    edges.Vertex2 == 3)
                {
                    Assert.IsFalse(edges.EdgeData.Forward);
                    var shapes = edges.Intermediates.ToSimpleArray();
                    Assert.AreEqual(2, shapes.Length);
                    Assert.AreEqual(4, shapes[0].Latitude);
                    Assert.AreEqual(4, shapes[0].Longitude);
                    Assert.AreEqual(3, shapes[1].Latitude);
                    Assert.AreEqual(3, shapes[1].Longitude);
                }
                else if (edges.Vertex1 == 3 &&
                    edges.Vertex2 == 1)
                {
                    Assert.IsTrue(edges.EdgeData.Forward);
                    var shapes = edges.Intermediates.ToSimpleArray();
                    Assert.AreEqual(2, shapes.Length);
                    Assert.AreEqual(3, shapes[0].Latitude);
                    Assert.AreEqual(3, shapes[0].Longitude);
                    Assert.AreEqual(4, shapes[1].Latitude);
                    Assert.AreEqual(4, shapes[1].Longitude);
                }
            }
        }
        public void RoutingRegressionTest9ResolvingReverse()
        {
            // build a graph to encode from.
            var tags = new TagsIndex();
            var graphDataSource = new RouterDataSource<Edge>(new Graph<Edge>(), tags);
            var vertex1 = graphDataSource.AddVertex(51.05849821468899f, 3.7240000000000000f);
            var vertex2 = graphDataSource.AddVertex(51.05849821468899f, 3.7254400000000000f);
            var vertex3 = graphDataSource.AddVertex(51.05849821468899f, 3.7225627899169926f);
            var edge = new Edge() // all edges are identical.
            {
                Distance = 100,
                Forward = true,
                Tags = tags.Add(new TagsCollection(
                    Tag.Create("highway", "tertiary"),
                    Tag.Create("oneway", "yes")))
            };
            graphDataSource.AddEdge(vertex1, vertex2, edge, null);
            graphDataSource.AddEdge(vertex3, vertex1, edge, null);

            // {RectF:[(3,71326552867889,51,048498214689),(3,73326552867889,51,068498214689)]}
            var edges =  graphDataSource.GetEdges(new GeoCoordinateBox(
                new GeoCoordinate(51.068498214689, 3.73326552867889),
                new GeoCoordinate(51.048498214689, 3.71326552867889)));

            while(edges.MoveNext())
            {
                if(edges.Vertex1 == 1 &&
                    edges.Vertex2 == 2)
                {
                    Assert.IsTrue(edges.EdgeData.Forward);
                }
                else if(edges.Vertex1 == 2 &&
                    edges.Vertex2 == 1)
                {
                    Assert.IsFalse(edges.EdgeData.Forward);
                }
                if (edges.Vertex1 == 1 &&
                    edges.Vertex2 == 3)
                {
                    Assert.IsFalse(edges.EdgeData.Forward);
                }
                else if (edges.Vertex1 == 3 &&
                    edges.Vertex2 == 1)
                {
                    Assert.IsTrue(edges.EdgeData.Forward);
                }
            }
        }
        public void TestSparseRemoval1Routing()
        {
            // use one edge definition everywhere.
            var tagsIndex = new TagsIndex();
            var tags = new TagsCollection(new Tag("highway","residential"));
            var edge = new Edge();
            edge.Forward = true;
            edge.Tags = tagsIndex.Add(tags);

            var graph = new Graph<Edge>();
            uint vertex1 = graph.AddVertex(51.267797f, 4.8013623f);
            uint vertex2 = graph.AddVertex(51.267702f, 4.8013396f);
            uint vertex3 = graph.AddVertex(51.267592f, 4.8013024f);

            graph.AddEdge(vertex1, vertex2, edge, null);
            graph.AddEdge(vertex2, vertex3, edge, null);
            graph.AddEdge(vertex3, vertex2, edge, null);

            // save vertex coordinates for later use.
            float latitude, longitude;
            graph.GetVertex(vertex1, out latitude, out longitude);
            var vertex1Coordinate = new GeoCoordinate(latitude, longitude);
            graph.GetVertex(vertex2, out latitude, out longitude);
            var vertex2Coordinate = new GeoCoordinate(latitude, longitude);
            graph.GetVertex(vertex3, out latitude, out longitude);
            var vertex3Coordinate = new GeoCoordinate(latitude, longitude);

            // execute pre-processor.
            var preProcessor = new GraphSimplificationPreprocessor(graph);
            preProcessor.Start();

            // create router.
            var source = new RouterDataSource<Edge>(
                graph, tagsIndex);
            var router = Router.CreateFrom(source, new OsmRoutingInterpreter());

            // test some basic routing requests.
            // 1 -> 3: 1 -> 2 -> 3.
            var resolved1 = router.Resolve(Vehicle.Car, vertex1Coordinate);
            var resolved3 = router.Resolve(Vehicle.Car, vertex3Coordinate);
            var route = router.Calculate(Vehicle.Car, resolved1, resolved3);
            
            // verify the simple route result.
            Assert.IsNotNull(route);
            Assert.AreEqual(3, route.Segments.Length);
            Assert.AreEqual(vertex1Coordinate.Latitude, route.Segments[0].Latitude);
            Assert.AreEqual(vertex1Coordinate.Longitude, route.Segments[0].Longitude);
            Assert.AreEqual(vertex2Coordinate.Latitude, route.Segments[1].Latitude);
            Assert.AreEqual(vertex2Coordinate.Longitude, route.Segments[1].Longitude);
            Assert.AreEqual(vertex3Coordinate.Latitude, route.Segments[2].Latitude);
            Assert.AreEqual(vertex3Coordinate.Longitude, route.Segments[2].Longitude);

            // 1 -> 2: 1 -> 2.
            router = Router.CreateFrom(source, new OsmRoutingInterpreter());
            resolved1 = router.Resolve(Vehicle.Car, vertex1Coordinate);
            var resolved2 = router.Resolve(Vehicle.Car, vertex2Coordinate);
            route = router.Calculate(Vehicle.Car, resolved1, resolved2);

            // verify the simple route result.
            Assert.IsNotNull(route);
            Assert.AreEqual(2, route.Segments.Length);
            Assert.AreEqual(vertex1Coordinate.Latitude, route.Segments[0].Latitude);
            Assert.AreEqual(vertex1Coordinate.Longitude, route.Segments[0].Longitude);
            Assert.AreEqual(vertex2Coordinate.Latitude, route.Segments[1].Latitude);
            Assert.AreEqual(vertex2Coordinate.Longitude, route.Segments[1].Longitude);
        }