/// <summary>
        /// Deserializes all edges.
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="size"></param>
        /// <param name="graph"></param>
        protected override void DeserializeEdges(LimitedStream stream, long size, DynamicGraphRouterDataSource <LiveEdge> graph)
        {
            var typeModel = RuntimeTypeModel.Create();

            typeModel.Add(typeof(SerializableEdge), true);
            typeModel.Add(typeof(GeoCoordinateSimple), true);

            long position = stream.Position;

            while (stream.Position < position + size)
            { // keep looping until the appropriate number of bytes have been read.
                var serializableEdges = typeModel.DeserializeWithSize(stream, null, typeof(SerializableEdge[])) as SerializableEdge[];
                for (int idx = 0; idx < serializableEdges.Length; idx++)
                {
                    ICoordinateCollection coordinateCollection = null;
                    if (serializableEdges[idx].Coordinates != null)
                    {
                        coordinateCollection = new CoordinateArrayCollection <GeoCoordinateSimple>(serializableEdges[idx].Coordinates);
                    }
                    graph.AddEdge(serializableEdges[idx].FromId, serializableEdges[idx].ToId,
                                  new LiveEdge()
                    {
                        Distance = serializableEdges[idx].Distance,
                        Value    = serializableEdges[idx].Value
                    }, coordinateCollection);
                }
            }
        }
Example #2
0
        /// <summary>
        /// Returns true if the given vertex has the given neighbour.
        /// </summary>
        /// <param name="vertex1"></param>
        /// <param name="vertex2"></param>
        /// <param name="shape"></param>
        /// <returns></returns>
        public bool GetEdgeShape(uint vertex1, uint vertex2, out ICoordinateCollection shape)
        {
            Tile tile;

            if (_tilesPerVertex.TryGetValue(vertex1, out tile))
            {
                // load missing tile if needed.
                this.LoadMissingTile(tile);
                _tilesPerVertex.Remove(vertex1);
            }

            // get the arcs and return.
            if (_vertices.Length > vertex1)
            {
                var vertex = _vertices[(int)vertex1];
                if (vertex != null &&
                    vertex.Arcs != null)
                {
                    for (int idx = 0; idx < vertex.Arcs.Length; idx++)
                    {
                        if (vertex.Arcs[idx].Item1 == vertex2)
                        {
                            shape = null;
                            if (vertex.Arcs[idx].Item3 != null)
                            {
                                shape = new CoordinateArrayCollection <GeoCoordinateSimple>(vertex.Arcs[idx].Item3);
                            }
                            return(true);
                        }
                    }
                }
            }
            shape = null;
            return(false);
        }
Example #3
0
        /// <summary>
        /// Gets the shape for the arc in from the given vertex and at the given index.
        /// </summary>
        /// <param name="vertexId">The vertex id.</param>
        /// <param name="arcIdx">The index of the arc.</param>
        /// <param name="shape">The shape.</param>
        /// <returns>True if there was a shape.</returns>
        private bool GetShapeForArc(uint vertexId, uint arcIdx, out ICoordinateCollection shape)
        {
            var vertex         = _vertices[(int)vertexId];
            var arcCoordinates = vertex.Arcs[arcIdx];

            shape = null;
            if (arcCoordinates.Item3 != null)
            {
                shape = new CoordinateArrayCollection <GeoCoordinateSimple>(arcCoordinates.Item3);
            }
            return(true);
        }
        public void TestTrim()
        {
            OsmSharp.Math.Random.StaticRandomGenerator.Set(116542346);

            var box = new GeoCoordinateBox(
                new GeoCoordinate(90, 180),
                new GeoCoordinate(-90, -180));
            var size = 100;
            var maxCollectionSize   = 4;
            var referenceDictionary = new Dictionary <long, ICoordinateCollection>();
            var coordinates         = new HugeCoordinateCollectionIndex(400);

            for (int idx = 0; idx < size; idx++)
            {
                var currentSize      = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(maxCollectionSize) + 1;
                var coordinatesArray = new GeoCoordinate[currentSize];
                while (currentSize > 0)
                {
                    coordinatesArray[currentSize - 1] = box.GenerateRandomIn(OsmSharp.Math.Random.StaticRandomGenerator.Get());
                    currentSize--;
                }
                var coordinatesCollection = new CoordinateArrayCollection <GeoCoordinate>(coordinatesArray);
                referenceDictionary[idx] = coordinatesCollection;
                coordinates[idx]         = coordinatesCollection;
            }

            // execute the trim.
            coordinates.Trim();

            // check result.
            for (int idx = 0; idx < size; idx++)
            {
                var referenceCollection = referenceDictionary[idx];
                var collection          = coordinates[idx];

                referenceCollection.Reset();
                collection.Reset();

                while (referenceCollection.MoveNext())
                {
                    Assert.IsTrue(collection.MoveNext());
                    Assert.AreEqual(referenceCollection.Latitude, collection.Latitude);
                    Assert.AreEqual(referenceCollection.Longitude, collection.Longitude);
                }
                Assert.IsFalse(collection.MoveNext());
            }
        }
        /// <summary>
        /// Gets the shape for the arc in the given block and at the given index.
        /// </summary>
        /// <param name="blockId">The index of the block to search.</param>
        /// <param name="arcIdx">The index of the arc in the block.</param>
        /// <param name="shape">The shape.</param>
        /// <returns>True if there was a shape.</returns>
        private bool GetShapeForArc(uint blockId, uint arcIdx, out ICoordinateCollection shape)
        {
            CHBlockCoordinates blockCoordinates;

            if (!_blockShapes.TryGet(blockId, out blockCoordinates))
            { // damn block not cached!
                blockCoordinates = this.DeserializeShape(blockId);
                if (blockCoordinates == null)
                { // oops even now the block is not found!
                    shape = null;
                    return(false);
                }
                _blockShapes.Add(blockId, blockCoordinates);
            }
            var arcCoordinates = blockCoordinates.Arcs[arcIdx];

            shape = null;
            if (arcCoordinates.Coordinates != null)
            {
                shape = new CoordinateArrayCollection <GeoCoordinateSimple>(arcCoordinates.Coordinates);
            }
            return(true);
        }
        public void TestSwitch()
        {
            OsmSharp.Math.Random.StaticRandomGenerator.Set(116542346);

            var box = new GeoCoordinateBox(
                new GeoCoordinate(90, 180),
                new GeoCoordinate(-90, -180));
            var size = 100;
            var maxCollectionSize   = 4;
            var referenceDictionary = new Dictionary <long, ICoordinateCollection>();
            var coordinates         = new HugeCoordinateCollectionIndex(400);

            for (int idx = 0; idx < size; idx++)
            {
                var currentSize      = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(maxCollectionSize) + 1;
                var coordinatesArray = new GeoCoordinate[currentSize];
                while (currentSize > 0)
                {
                    coordinatesArray[currentSize - 1] = box.GenerateRandomIn(OsmSharp.Math.Random.StaticRandomGenerator.Get());
                    currentSize--;
                }
                var coordinatesCollection = new CoordinateArrayCollection <GeoCoordinate>(coordinatesArray);
                referenceDictionary[idx] = coordinatesCollection;
                coordinates[idx]         = coordinatesCollection;
            }

            // generate a sequence of two id's and switch.
            for (var i = 0; i < 20; i++)
            {
                var id1 = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(size);
                var id2 = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(size - 1);
                if (id1 <= id2)
                {
                    id2++;
                }

                var temp = referenceDictionary[id1];
                referenceDictionary[id1] = referenceDictionary[id2];
                referenceDictionary[id2] = temp;

                coordinates.Switch(id1, id2);
            }

            // check result.
            for (int idx = 0; idx < size; idx++)
            {
                var referenceCollection = referenceDictionary[idx];
                var collection          = coordinates[idx];

                referenceCollection.Reset();
                collection.Reset();

                while (referenceCollection.MoveNext())
                {
                    Assert.IsTrue(collection.MoveNext());
                    Assert.AreEqual(referenceCollection.Latitude, collection.Latitude);
                    Assert.AreEqual(referenceCollection.Longitude, collection.Longitude);
                }
                Assert.IsFalse(collection.MoveNext());
            }
        }
        public void TestSerialize()
        {
            OsmSharp.Math.Random.StaticRandomGenerator.Set(116542346);

            var box = new GeoCoordinateBox(
                new GeoCoordinate(90, 180),
                new GeoCoordinate(-90, -180));
            var size = 5;
            var maxCollectionSize   = 4;
            var referenceDictionary = new Dictionary <long, ICoordinateCollection>();
            var coordinates         = new HugeCoordinateCollectionIndex(100);

            for (int idx = 0; idx < size; idx++)
            {
                var currentSize      = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(maxCollectionSize) + 1;
                var coordinatesArray = new GeoCoordinate[currentSize];
                while (currentSize > 0)
                {
                    coordinatesArray[currentSize - 1] = box.GenerateRandomIn(OsmSharp.Math.Random.StaticRandomGenerator.Get());
                    currentSize--;
                }
                var coordinatesCollection = new CoordinateArrayCollection <GeoCoordinate>(coordinatesArray);
                referenceDictionary[idx] = coordinatesCollection;
                coordinates[idx]         = coordinatesCollection;
            }

            coordinates.Trim();
            coordinates.Compress();

            byte[] data = null;
            using (var stream = new MemoryStream())
            {
                long length = coordinates.Serialize(stream);
                data = stream.ToArray();

                Assert.AreEqual(168, length);
                Assert.AreEqual(data.Length, length);
            }

            var result = HugeCoordinateCollectionIndex.Deserialize(new MemoryStream(data));

            // check result.
            for (int idx = 0; idx < size; idx++)
            {
                var referenceCollection = referenceDictionary[idx];
                var collection          = result[idx];

                referenceCollection.Reset();
                collection.Reset();

                while (referenceCollection.MoveNext())
                {
                    Assert.IsTrue(collection.MoveNext());
                    Assert.AreEqual(referenceCollection.Latitude, collection.Latitude);
                    Assert.AreEqual(referenceCollection.Longitude, collection.Longitude);
                }
                Assert.IsFalse(collection.MoveNext());
            }

            result = HugeCoordinateCollectionIndex.Deserialize(new MemoryStream(data), true);

            // check result.
            for (int idx = 0; idx < size; idx++)
            {
                var referenceCollection = referenceDictionary[idx];
                var collection          = result[idx];

                referenceCollection.Reset();
                collection.Reset();

                while (referenceCollection.MoveNext())
                {
                    Assert.IsTrue(collection.MoveNext());
                    Assert.AreEqual(referenceCollection.Latitude, collection.Latitude);
                    Assert.AreEqual(referenceCollection.Longitude, collection.Longitude);
                }
                Assert.IsFalse(collection.MoveNext());
            }
        }
        /// <summary>
        /// Adds an edge.
        /// </summary>
        /// <param name="forward"></param>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <param name="tags"></param>
        /// <param name="intermediates"></param>
        protected virtual void AddRoadEdge(TagsCollectionBase tags, uint from, uint to, List <GeoCoordinateSimple> intermediates)
        {
            float         latitude;
            float         longitude;
            GeoCoordinate fromCoordinate = null;

            if (_graph.GetVertex(from, out latitude, out longitude))
            { //
                fromCoordinate = new GeoCoordinate(latitude, longitude);
            }
            GeoCoordinate toCoordinate = null;

            if (_graph.GetVertex(to, out latitude, out longitude))
            { //
                toCoordinate = new GeoCoordinate(latitude, longitude);
            }

            if (fromCoordinate != null && toCoordinate != null)
            { // calculate the edge data.
                TEdgeData             existingData;
                ICoordinateCollection forwardShape;
                if (this.GetEdge(_graph, from, to, out existingData, out forwardShape))
                {     // oeps, an edge already exists!
                    if (intermediates != null && intermediates.Count > 0)
                    { // add one of the intermediates as new vertex.
                        uint newVertex;
                        if (forwardShape != null && forwardShape.Count > 0)
                        { // the other edge also has a shape, make sure to also split it.
                            var existingIntermediates = new List <GeoCoordinateSimple>(forwardShape.ToSimpleArray());
                            newVertex = _graph.AddVertex(existingIntermediates[0].Latitude, existingIntermediates[0].Longitude);

                            // add edge before.
                            var beforeEdgeData = this.CalculateEdgeData(_interpreter.EdgeInterpreter, _tagsIndex, tags, true,
                                                                        fromCoordinate, new GeoCoordinate(existingIntermediates[0].Latitude, existingIntermediates[0].Longitude), null);
                            _graph.AddEdge(from, newVertex, beforeEdgeData, null);
                            if (_graph.IsDirected)
                            { // also the need to add the reverse edge.
                                beforeEdgeData = (TEdgeData)beforeEdgeData.Reverse();
                                _graph.AddEdge(newVertex, from, beforeEdgeData, null);
                            }

                            // add edge after.
                            var afterIntermediates = existingIntermediates.GetRange(1, existingIntermediates.Count - 1);
                            var afterEdgeData      = this.CalculateEdgeData(_interpreter.EdgeInterpreter, _tagsIndex, tags, true,
                                                                            new GeoCoordinate(existingIntermediates[0].Latitude, existingIntermediates[0].Longitude), toCoordinate, afterIntermediates);
                            _graph.AddEdge(newVertex, to, afterEdgeData, new CoordinateArrayCollection <GeoCoordinateSimple>(afterIntermediates.ToArray()));
                            if (_graph.IsDirected)
                            { // also the need to add the reverse edge.
                                afterIntermediates.Reverse();
                                afterEdgeData = (TEdgeData)afterEdgeData.Reverse();
                                _graph.AddEdge(to, newVertex, afterEdgeData, new CoordinateArrayCollection <GeoCoordinateSimple>(afterIntermediates.ToArray()));
                            }

                            // remove original edge.
                            _graph.RemoveEdge(from, to, existingData);
                            if (_graph.IsDirected && _graph.CanHaveDuplicates)
                            { // also remove opposite edges.
                                _graph.RemoveEdge(to, from, (TEdgeData)existingData.Reverse());
                            }
                        }

                        newVertex = _graph.AddVertex(intermediates[0].Latitude, intermediates[0].Longitude);
                        var newEdgeData = this.CalculateEdgeData(_interpreter.EdgeInterpreter, _tagsIndex, tags, true,
                                                                 fromCoordinate, new GeoCoordinate(intermediates[0].Latitude, intermediates[0].Longitude), null);
                        _graph.AddEdge(from, newVertex, newEdgeData, null);
                        if (_graph.IsDirected)
                        { // also the need to add the reverse edge.
                            newEdgeData = (TEdgeData)newEdgeData.Reverse();
                            _graph.AddEdge(newVertex, from, newEdgeData, null);
                        }

                        from           = newVertex;
                        fromCoordinate = new GeoCoordinate(intermediates[0].Latitude, intermediates[0].Longitude);
                        intermediates  = intermediates.GetRange(1, intermediates.Count - 1);
                    }
                    else
                    {     // hmm, no intermediates, the other edge should have them.
                        if (forwardShape != null && forwardShape.Count > 0)
                        { // there is a shape, add one of the intermediates as a new vertex.
                            var existingIntermediates = new List <GeoCoordinateSimple>(forwardShape.ToSimpleArray());
                            var newVertex             = _graph.AddVertex(existingIntermediates[0].Latitude, existingIntermediates[0].Longitude);

                            // add edge before.
                            var beforeEdgeData = this.CalculateEdgeData(_interpreter.EdgeInterpreter, _tagsIndex, tags, true,
                                                                        fromCoordinate, new GeoCoordinate(existingIntermediates[0].Latitude, existingIntermediates[0].Longitude), null);
                            _graph.AddEdge(from, newVertex, beforeEdgeData, null);
                            if (_graph.IsDirected)
                            { // also the need to add the reverse edge.
                                beforeEdgeData = (TEdgeData)beforeEdgeData.Reverse();
                                _graph.AddEdge(newVertex, from, beforeEdgeData, null);
                            }

                            // add edge after.
                            var afterIntermediates = existingIntermediates.GetRange(1, existingIntermediates.Count - 1);
                            var afterEdgeData      = this.CalculateEdgeData(_interpreter.EdgeInterpreter, _tagsIndex, tags, true,
                                                                            new GeoCoordinate(existingIntermediates[0].Latitude, existingIntermediates[0].Longitude), toCoordinate, afterIntermediates);
                            _graph.AddEdge(newVertex, to, afterEdgeData, new CoordinateArrayCollection <GeoCoordinateSimple>(afterIntermediates.ToArray()));
                            if (_graph.IsDirected)
                            { // also the need to add the reverse edge.
                                afterIntermediates.Reverse();
                                afterEdgeData = (TEdgeData)afterEdgeData.Reverse();
                                _graph.AddEdge(to, newVertex, afterEdgeData, new CoordinateArrayCollection <GeoCoordinateSimple>(afterIntermediates.ToArray()));
                            }

                            if (_graph.CanHaveDuplicates)
                            { // make sure to remove the existing edge if graph allows duplicates.
                                _graph.RemoveEdge(from, to);
                                if (_graph.IsDirected)
                                { // also remove the reverse.
                                    _graph.RemoveEdge(to, from);
                                }
                            }
                        }
                        else
                        {
                            // do nothing just overwrite what is there, probably a bug in OSM, two overlapping ways, sharing nodes.
                        }
                    }

                    // edge was there already but was removed,split or needs to be replaced.
                    var edgeData = this.CalculateEdgeData(_interpreter.EdgeInterpreter, _tagsIndex, tags, true,
                                                          fromCoordinate, toCoordinate, intermediates);
                    _graph.AddEdge(from, to, edgeData, new CoordinateArrayCollection <GeoCoordinateSimple>(intermediates.ToArray()));
                    if (_graph.IsDirected)
                    { // also the need to add the reverse edge.
                        intermediates.Reverse();
                        edgeData = (TEdgeData)edgeData.Reverse();
                        _graph.AddEdge(to, from, edgeData, new CoordinateArrayCollection <GeoCoordinateSimple>(intermediates.ToArray()));
                    }
                }
                else
                { // edge is not there yet, just add it.
                    ICoordinateCollection intermediatesCollection = null;
                    if (intermediates != null)
                    {
                        intermediatesCollection = new CoordinateArrayCollection <GeoCoordinateSimple>(intermediates.ToArray());
                    }

                    // add new edge.
                    var edgeData = this.CalculateEdgeData(_interpreter.EdgeInterpreter, _tagsIndex, tags, true,
                                                          fromCoordinate, toCoordinate, intermediates);
                    _graph.AddEdge(from, to, edgeData, intermediatesCollection);
                    if (_graph.IsDirected)
                    { // also the need to add the reverse edge.
                        if (intermediates != null)
                        {
                            intermediates.Reverse();
                            intermediatesCollection = new CoordinateArrayCollection <GeoCoordinateSimple>(intermediates.ToArray());
                        }
                        edgeData = (TEdgeData)edgeData.Reverse();
                        _graph.AddEdge(to, from, edgeData, intermediatesCollection);
                    }
                }
            }
        }
        public void TestResize()
        {
            OsmSharp.Math.Random.StaticRandomGenerator.Set(116542346);

            var box = new GeoCoordinateBox(
                new GeoCoordinate(90, 180),
                new GeoCoordinate(-90, -180));
            var size = 100;
            var maxCollectionSize = 4;
            var referenceDictionary = new Dictionary<long, ICoordinateCollection>();
            var coordinates = new HugeCoordinateCollectionIndex(400);
            for (int idx = 0; idx < size; idx++)
            {
                var currentSize = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(maxCollectionSize) + 1;
                var coordinatesArray = new GeoCoordinate[currentSize];
                while (currentSize > 0)
                {
                    coordinatesArray[currentSize - 1] = box.GenerateRandomIn(OsmSharp.Math.Random.StaticRandomGenerator.Get());
                    currentSize--;
                }
                var coordinatesCollection = new CoordinateArrayCollection<GeoCoordinate>(coordinatesArray);
                referenceDictionary[idx] = coordinatesCollection;
                coordinates[idx] = coordinatesCollection;
            }

            // check result.
            for (int idx = 0; idx < size; idx++)
            {
                var referenceCollection = referenceDictionary[idx];
                var collection = coordinates[idx];

                referenceCollection.Reset();
                collection.Reset();

                while (referenceCollection.MoveNext())
                {
                    Assert.IsTrue(collection.MoveNext());
                    Assert.AreEqual(referenceCollection.Latitude, collection.Latitude);
                    Assert.AreEqual(referenceCollection.Longitude, collection.Longitude);
                }
                Assert.IsFalse(collection.MoveNext());
            }

            // change size and check result.
            var newSize = 75;
            coordinates.Resize(newSize);

            // check result.
            Assert.AreEqual(75, coordinates.LengthIndex);
            for (var idx = 0; idx < newSize; idx++)
            {
                var referenceCollection = referenceDictionary[idx];
                var collection = coordinates[idx];

                referenceCollection.Reset();
                collection.Reset();

                while (referenceCollection.MoveNext())
                {
                    Assert.IsTrue(collection.MoveNext());
                    Assert.AreEqual(referenceCollection.Latitude, collection.Latitude);
                    Assert.AreEqual(referenceCollection.Longitude, collection.Longitude);
                }
                Assert.IsFalse(collection.MoveNext());
            }
        }
        public void TestSmall()
        {
            OsmSharp.Math.Random.StaticRandomGenerator.Set(116542346);

            var box = new GeoCoordinateBox(
                new GeoCoordinate(90, 180),
                new GeoCoordinate(-90, -180));
            var size = 100;
            var maxCollectionSize = 4;
            var referenceDictionary = new Dictionary<long, ICoordinateCollection>();
            var coordinates = new HugeCoordinateCollectionIndex(400);
            for(int idx = 0; idx < size; idx++)
            {
                var currentSize = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(maxCollectionSize) + 1;
                var coordinatesArray = new GeoCoordinate[currentSize];
                while(currentSize > 0)
                {
                    coordinatesArray[currentSize - 1] =  box.GenerateRandomIn(OsmSharp.Math.Random.StaticRandomGenerator.Get());
                    currentSize--;
                }
                var coordinatesCollection = new CoordinateArrayCollection<GeoCoordinate>(coordinatesArray);
                referenceDictionary[idx] = coordinatesCollection;
                coordinates[idx] = coordinatesCollection;
            }

            // check result.
            for (int idx = 0; idx < size; idx++)
            {
                var referenceCollection = referenceDictionary[idx];
                var collection = coordinates[idx];

                referenceCollection.Reset();
                collection.Reset();

                while(referenceCollection.MoveNext())
                {
                    Assert.IsTrue(collection.MoveNext());
                    Assert.AreEqual(referenceCollection.Latitude, collection.Latitude);
                    Assert.AreEqual(referenceCollection.Longitude, collection.Longitude);
                }
                Assert.IsFalse(collection.MoveNext());
            }

            // generate new randoms.
            for (int idx = 0; idx < size; idx++)
            {
                var currentSize = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(maxCollectionSize) + 1;
                var coordinatesArray = new GeoCoordinate[currentSize];
                while (currentSize > 0)
                {
                    coordinatesArray[currentSize - 1] = box.GenerateRandomIn(OsmSharp.Math.Random.StaticRandomGenerator.Get());
                    currentSize--;
                }
                var coordinatesCollection = new CoordinateArrayCollection<GeoCoordinate>(coordinatesArray);
                referenceDictionary[idx] = coordinatesCollection;
                coordinates[idx] = coordinatesCollection;

                var referenceCollection = referenceDictionary[idx];
                var collection = coordinates[idx];

                referenceCollection.Reset();
                collection.Reset();

                while (referenceCollection.MoveNext())
                {
                    Assert.IsTrue(collection.MoveNext());
                    Assert.AreEqual(referenceCollection.Latitude, collection.Latitude);
                    Assert.AreEqual(referenceCollection.Longitude, collection.Longitude);
                }
                Assert.IsFalse(collection.MoveNext());
            }

            // check again.
            for (int idx = 0; idx < size; idx++)
            {
                var referenceCollection = referenceDictionary[idx];
                var collection = coordinates[idx];

                referenceCollection.Reset();
                collection.Reset();

                while (referenceCollection.MoveNext())
                {
                    Assert.IsTrue(collection.MoveNext());
                    Assert.AreEqual(referenceCollection.Latitude, collection.Latitude);
                    Assert.AreEqual(referenceCollection.Longitude, collection.Longitude);
                }
                Assert.IsFalse(collection.MoveNext());
            }

            // randomly remove stuff.
            for (int idx = 0; idx < size; idx++)
            {
                if(OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(2) > 1)
                {
                    referenceDictionary[idx] = null;
                    coordinates[idx] = null;
                }
            }

            // check again.
            for (int idx = 0; idx < size; idx++)
            {
                var referenceCollection = referenceDictionary[idx];
                var collection = coordinates[idx];

                if (referenceCollection == null)
                {
                    Assert.IsNull(collection);
                }
                else
                {
                    referenceCollection.Reset();
                    collection.Reset();

                    while (referenceCollection.MoveNext())
                    {
                        Assert.IsTrue(collection.MoveNext());
                        Assert.AreEqual(referenceCollection.Latitude, collection.Latitude);
                        Assert.AreEqual(referenceCollection.Longitude, collection.Longitude);
                    }
                    Assert.IsFalse(collection.MoveNext());
                }
            }

            // generate new randoms.
            for (int idx = 0; idx < size; idx++)
            {
                var currentSize = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(maxCollectionSize) + 1;
                var coordinatesArray = new GeoCoordinate[currentSize];
                while (currentSize > 0)
                {
                    coordinatesArray[currentSize - 1] = box.GenerateRandomIn(OsmSharp.Math.Random.StaticRandomGenerator.Get());
                    currentSize--;
                }
                var coordinatesCollection = new CoordinateArrayCollection<GeoCoordinate>(coordinatesArray);
                referenceDictionary[idx] = coordinatesCollection;
                coordinates[idx] = coordinatesCollection;

                var referenceCollection = referenceDictionary[idx];
                var collection = coordinates[idx];

                referenceCollection.Reset();
                collection.Reset();

                while (referenceCollection.MoveNext())
                {
                    Assert.IsTrue(collection.MoveNext());
                    Assert.AreEqual(referenceCollection.Latitude, collection.Latitude);
                    Assert.AreEqual(referenceCollection.Longitude, collection.Longitude);
                }
                Assert.IsFalse(collection.MoveNext());
            }

            // check again.
            for (int idx = 0; idx < size; idx++)
            {
                var referenceCollection = referenceDictionary[idx];
                var collection = coordinates[idx];

                referenceCollection.Reset();
                collection.Reset();

                while (referenceCollection.MoveNext())
                {
                    Assert.IsTrue(collection.MoveNext());
                    Assert.AreEqual(referenceCollection.Latitude, collection.Latitude);
                    Assert.AreEqual(referenceCollection.Longitude, collection.Longitude);
                }
                Assert.IsFalse(collection.MoveNext());
            }
        }
        public void TestSerialize()
        {
            OsmSharp.Math.Random.StaticRandomGenerator.Set(116542346);

            var box = new GeoCoordinateBox(
                new GeoCoordinate(90, 180),
                new GeoCoordinate(-90, -180));
            var size = 5;
            var maxCollectionSize = 4;
            var referenceDictionary = new Dictionary<long, ICoordinateCollection>();
            var coordinates = new HugeCoordinateCollectionIndex(100);
            for (int idx = 0; idx < size; idx++)
            {
                var currentSize = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(maxCollectionSize) + 1;
                var coordinatesArray = new GeoCoordinate[currentSize];
                while (currentSize > 0)
                {
                    coordinatesArray[currentSize - 1] = box.GenerateRandomIn(OsmSharp.Math.Random.StaticRandomGenerator.Get());
                    currentSize--;
                }
                var coordinatesCollection = new CoordinateArrayCollection<GeoCoordinate>(coordinatesArray);
                referenceDictionary[idx] = coordinatesCollection;
                coordinates[idx] = coordinatesCollection;
            }

            coordinates.Trim();
            coordinates.Compress();

            byte[] data = null;
            using(var stream = new MemoryStream())
            {
                long length = coordinates.Serialize(stream);
                data = stream.ToArray();

                Assert.AreEqual(168, length);
                Assert.AreEqual(data.Length, length);
            }

            var result = HugeCoordinateCollectionIndex.Deserialize(new MemoryStream(data));

            // check result.
            for (int idx = 0; idx < size; idx++)
            {
                var referenceCollection = referenceDictionary[idx];
                var collection = result[idx];

                referenceCollection.Reset();
                collection.Reset();

                while (referenceCollection.MoveNext())
                {
                    Assert.IsTrue(collection.MoveNext());
                    Assert.AreEqual(referenceCollection.Latitude, collection.Latitude);
                    Assert.AreEqual(referenceCollection.Longitude, collection.Longitude);
                }
                Assert.IsFalse(collection.MoveNext());
            }

            result = HugeCoordinateCollectionIndex.Deserialize(new MemoryStream(data), true);

            // check result.
            for (int idx = 0; idx < size; idx++)
            {
                var referenceCollection = referenceDictionary[idx];
                var collection = result[idx];

                referenceCollection.Reset();
                collection.Reset();

                while (referenceCollection.MoveNext())
                {
                    Assert.IsTrue(collection.MoveNext());
                    Assert.AreEqual(referenceCollection.Latitude, collection.Latitude);
                    Assert.AreEqual(referenceCollection.Longitude, collection.Longitude);
                }
                Assert.IsFalse(collection.MoveNext());
            }
        }
Example #12
0
        public void TestHugeCoordinateCollectionIndexSmall()
        {
            OsmSharp.Math.Random.StaticRandomGenerator.Set(116542346);

            var box = new GeoCoordinateBox(
                new GeoCoordinate(90, 180),
                new GeoCoordinate(-90, -180));
            var size = 100;
            var maxCollectionSize   = 4;
            var referenceDictionary = new Dictionary <long, ICoordinateCollection>();
            var coordinates         = new HugeCoordinateCollectionIndex(400);

            for (int idx = 0; idx < size; idx++)
            {
                var currentSize      = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(maxCollectionSize) + 1;
                var coordinatesArray = new GeoCoordinate[currentSize];
                while (currentSize > 0)
                {
                    coordinatesArray[currentSize - 1] = box.GenerateRandomIn(OsmSharp.Math.Random.StaticRandomGenerator.Get());
                    currentSize--;
                }
                var coordinatesCollection = new CoordinateArrayCollection <GeoCoordinate>(coordinatesArray);
                referenceDictionary[idx] = coordinatesCollection;
                coordinates[idx]         = coordinatesCollection;
            }

            // check result.
            for (int idx = 0; idx < size; idx++)
            {
                var referenceCollection = referenceDictionary[idx];
                var collection          = coordinates[idx];

                referenceCollection.Reset();
                collection.Reset();

                while (referenceCollection.MoveNext())
                {
                    Assert.IsTrue(collection.MoveNext());
                    Assert.AreEqual(referenceCollection.Latitude, collection.Latitude);
                    Assert.AreEqual(referenceCollection.Longitude, collection.Longitude);
                }
                Assert.IsFalse(collection.MoveNext());
            }

            // generate new randoms.
            for (int idx = 0; idx < size; idx++)
            {
                var currentSize      = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(maxCollectionSize) + 1;
                var coordinatesArray = new GeoCoordinate[currentSize];
                while (currentSize > 0)
                {
                    coordinatesArray[currentSize - 1] = box.GenerateRandomIn(OsmSharp.Math.Random.StaticRandomGenerator.Get());
                    currentSize--;
                }
                var coordinatesCollection = new CoordinateArrayCollection <GeoCoordinate>(coordinatesArray);
                referenceDictionary[idx] = coordinatesCollection;
                coordinates[idx]         = coordinatesCollection;

                var referenceCollection = referenceDictionary[idx];
                var collection          = coordinates[idx];

                referenceCollection.Reset();
                collection.Reset();

                while (referenceCollection.MoveNext())
                {
                    Assert.IsTrue(collection.MoveNext());
                    Assert.AreEqual(referenceCollection.Latitude, collection.Latitude);
                    Assert.AreEqual(referenceCollection.Longitude, collection.Longitude);
                }
                Assert.IsFalse(collection.MoveNext());
            }

            // check again.
            for (int idx = 0; idx < size; idx++)
            {
                var referenceCollection = referenceDictionary[idx];
                var collection          = coordinates[idx];

                referenceCollection.Reset();
                collection.Reset();

                while (referenceCollection.MoveNext())
                {
                    Assert.IsTrue(collection.MoveNext());
                    Assert.AreEqual(referenceCollection.Latitude, collection.Latitude);
                    Assert.AreEqual(referenceCollection.Longitude, collection.Longitude);
                }
                Assert.IsFalse(collection.MoveNext());
            }

            // randomly remove stuff.
            for (int idx = 0; idx < size; idx++)
            {
                if (OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(2) > 1)
                {
                    referenceDictionary[idx] = null;
                    coordinates[idx]         = null;
                }
            }

            // check again.
            for (int idx = 0; idx < size; idx++)
            {
                var referenceCollection = referenceDictionary[idx];
                var collection          = coordinates[idx];

                if (referenceCollection == null)
                {
                    Assert.IsNull(collection);
                }
                else
                {
                    referenceCollection.Reset();
                    collection.Reset();

                    while (referenceCollection.MoveNext())
                    {
                        Assert.IsTrue(collection.MoveNext());
                        Assert.AreEqual(referenceCollection.Latitude, collection.Latitude);
                        Assert.AreEqual(referenceCollection.Longitude, collection.Longitude);
                    }
                    Assert.IsFalse(collection.MoveNext());
                }
            }

            // generate new randoms.
            for (int idx = 0; idx < size; idx++)
            {
                var currentSize      = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(maxCollectionSize) + 1;
                var coordinatesArray = new GeoCoordinate[currentSize];
                while (currentSize > 0)
                {
                    coordinatesArray[currentSize - 1] = box.GenerateRandomIn(OsmSharp.Math.Random.StaticRandomGenerator.Get());
                    currentSize--;
                }
                var coordinatesCollection = new CoordinateArrayCollection <GeoCoordinate>(coordinatesArray);
                referenceDictionary[idx] = coordinatesCollection;
                coordinates[idx]         = coordinatesCollection;

                var referenceCollection = referenceDictionary[idx];
                var collection          = coordinates[idx];

                referenceCollection.Reset();
                collection.Reset();

                while (referenceCollection.MoveNext())
                {
                    Assert.IsTrue(collection.MoveNext());
                    Assert.AreEqual(referenceCollection.Latitude, collection.Latitude);
                    Assert.AreEqual(referenceCollection.Longitude, collection.Longitude);
                }
                Assert.IsFalse(collection.MoveNext());
            }

            // check again.
            for (int idx = 0; idx < size; idx++)
            {
                var referenceCollection = referenceDictionary[idx];
                var collection          = coordinates[idx];

                referenceCollection.Reset();
                collection.Reset();

                while (referenceCollection.MoveNext())
                {
                    Assert.IsTrue(collection.MoveNext());
                    Assert.AreEqual(referenceCollection.Latitude, collection.Latitude);
                    Assert.AreEqual(referenceCollection.Longitude, collection.Longitude);
                }
                Assert.IsFalse(collection.MoveNext());
            }
        }
        public void RoutingRegressionTest11ResolvingReverse()
        {
            // build a graph to encode from.
            var tags            = new TagsTableCollectionIndex();
            var graphDataSource = new DynamicGraphRouterDataSource <LiveEdge>(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 LiveEdge() // 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 <LiveEdge> >(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 <LiveEdge> >(graphDataSource.GetEdges(2));
            Assert.AreEqual(1, edges.Count);
            Assert.AreEqual(false, edges[0].EdgeData.Forward);

            edges = new List <Edge <LiveEdge> >(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 TagsTableCollectionIndex();
            var graphDataSource = new DynamicGraphRouterDataSource <LiveEdge>(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 LiveEdge() // 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);
                }
            }
        }
        /// <summary>
        /// Loads the edge between the given vertices.
        /// </summary>
        /// <param name="vertex1"></param>
        /// <param name="vertex2"></param>
        /// <param name="shape"></param>
        /// <returns></returns>
        private bool LoadArcShape(uint vertex1, uint vertex2, out ICoordinateCollection shape)
        {
            uint blockId = CHBlock.CalculateId(vertex1, _blockSize);
            CHBlockCoordinates blockCoordinates;

            if (!_blockShapes.TryGet(blockId, out blockCoordinates))
            { // damn block not cached!
                blockCoordinates = this.DeserializeShape(blockId);
                if (blockCoordinates == null)
                { // oops even now the block is not found!
                    shape = null;
                    return(false);
                }
                _blockShapes.Add(blockId, blockCoordinates);
            }
            CHBlock block;

            if (!_blocks.TryGet(blockId, out block))
            { // damn block not cached!
                block = this.DeserializeBlock(blockId);
                if (block == null)
                { // oops even now the block is not found!
                    shape = null;
                    return(false);
                }
                _blocks.Add(blockId, block);
            }
            uint blockIdx = vertex1 - blockId;

            if (block.Vertices != null &&
                blockIdx < block.Vertices.Length)
            { // block is found and the vertex is there!
                for (int arcIdx = block.Vertices[blockIdx].ArcIndex;
                     arcIdx < block.Vertices[blockIdx].ArcIndex + block.Vertices[blockIdx].ArcCount; arcIdx++)
                { // loop over all arcs.
                    var chArc = block.Arcs[arcIdx];
                    if (chArc.TargetId == vertex2)
                    {
                        var arcCoordinates = blockCoordinates.Arcs[arcIdx];
                        shape = null;
                        if (arcCoordinates.Coordinates != null)
                        {
                            shape = new CoordinateArrayCollection <GeoCoordinateSimple>(arcCoordinates.Coordinates);
                        }
                        return(true);
                    }
                }
            }
            blockId = CHBlock.CalculateId(vertex2, _blockSize);
            if (!_blocks.TryGet(blockId, out block))
            { // damn block not cached!
                block = this.DeserializeBlock(blockId);
                if (block == null)
                { // oops even now the block is not found!
                    shape = null;
                    return(false);
                }
                _blocks.Add(blockId, block);
            }
            if (!_blockShapes.TryGet(blockId, out blockCoordinates))
            { // damn block not cached!
                blockCoordinates = this.DeserializeShape(blockId);
                if (blockCoordinates == null)
                { // oops even now the block is not found!
                    shape = null;
                    return(false);
                }
                _blockShapes.Add(blockId, blockCoordinates);
            }
            blockIdx = vertex2 - blockId;
            if (block.Vertices != null &&
                blockIdx < block.Vertices.Length)
            { // block is found and the vertex is there!
                for (int arcIdx = block.Vertices[blockIdx].ArcIndex;
                     arcIdx < block.Vertices[blockIdx].ArcIndex + block.Vertices[blockIdx].ArcCount; arcIdx++)
                { // loop over all arcs.
                    var chArc = block.Arcs[arcIdx];
                    if (chArc.TargetId == vertex1)
                    {
                        var arcCoordinates = blockCoordinates.Arcs[arcIdx];
                        shape = null;
                        if (arcCoordinates.Coordinates != null)
                        {
                            shape = new CoordinateArrayCollection <GeoCoordinateSimple>(arcCoordinates.Coordinates);
                        }
                        return(true);
                    }
                }
            }
            shape = null;
            return(false);
        }
        public void RoutingRegressionTest11ResolvingReverse()
        {
            // build a graph to encode from.
            var tags = new TagsTableCollectionIndex();
            var graphDataSource = new DynamicGraphRouterDataSource<LiveEdge>(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 LiveEdge() // 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<LiveEdge>>(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<LiveEdge>>(graphDataSource.GetEdges(2));
            Assert.AreEqual(1, edges.Count);
            Assert.AreEqual(false, edges[0].EdgeData.Forward);

            edges = new List<Edge<LiveEdge>>(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 TagsTableCollectionIndex();
            var graphDataSource = new DynamicGraphRouterDataSource<LiveEdge>(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 LiveEdge() // 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 TestSwitch()
        {
            OsmSharp.Math.Random.StaticRandomGenerator.Set(116542346);

            var box = new GeoCoordinateBox(
                new GeoCoordinate(90, 180),
                new GeoCoordinate(-90, -180));
            var size = 100;
            var maxCollectionSize = 4;
            var referenceDictionary = new Dictionary<long, ICoordinateCollection>();
            var coordinates = new HugeCoordinateCollectionIndex(400);
            for (int idx = 0; idx < size; idx++)
            {
                var currentSize = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(maxCollectionSize) + 1;
                var coordinatesArray = new GeoCoordinate[currentSize];
                while (currentSize > 0)
                {
                    coordinatesArray[currentSize - 1] = box.GenerateRandomIn(OsmSharp.Math.Random.StaticRandomGenerator.Get());
                    currentSize--;
                }
                var coordinatesCollection = new CoordinateArrayCollection<GeoCoordinate>(coordinatesArray);
                referenceDictionary[idx] = coordinatesCollection;
                coordinates[idx] = coordinatesCollection;
            }

            // generate a sequence of two id's and switch.
            for(var i = 0; i < 20; i++)
            {
                var id1 = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(size);
                var id2 = OsmSharp.Math.Random.StaticRandomGenerator.Get().Generate(size - 1);
                if (id1 <= id2) { id2++; }

                var temp = referenceDictionary[id1];
                referenceDictionary[id1] = referenceDictionary[id2];
                referenceDictionary[id2] = temp;

                coordinates.Switch(id1, id2);
            }

            // check result.
            for (int idx = 0; idx < size; idx++)
            {
                var referenceCollection = referenceDictionary[idx];
                var collection = coordinates[idx];

                referenceCollection.Reset();
                collection.Reset();

                while (referenceCollection.MoveNext())
                {
                    Assert.IsTrue(collection.MoveNext());
                    Assert.AreEqual(referenceCollection.Latitude, collection.Latitude);
                    Assert.AreEqual(referenceCollection.Longitude, collection.Longitude);
                }
                Assert.IsFalse(collection.MoveNext());
            }
        }