Beispiel #1
0
        /// <summary>
        /// Serializes all edges.
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="graph"></param>
        protected override void SerializeEdges(LimitedStream stream, DynamicGraphRouterDataSource <LiveEdge> graph)
        {
            var typeModel = RuntimeTypeModel.Create();

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

            int blockSize = 1000;
            var arcsQueue = new List <SerializableEdge>(blockSize);

            uint vertex = 0;

            while (vertex < graph.VertexCount)
            { // keep looping and serialize all vertices.
                var arcs = graph.GetEdges(vertex);
                if (arcs != null)
                { // serialize the arcs, but serialize them only once.
                    // choose only those arcs that start at a vertex smaller than the target.
                    for (int idx = 0; idx < arcs.Length; idx++)
                    {
                        if (arcs[idx].Key > vertex)
                        {
                            GeoCoordinateSimple[] coordinates;
                            if (!graph.GetEdgeShape(vertex, arcs[idx].Key, out coordinates))
                            {
                                coordinates = null;
                            }
                            arcsQueue.Add(new SerializableEdge()
                            {
                                Distance    = arcs[idx].Value.Distance,
                                FromId      = vertex,
                                ToId        = arcs[idx].Key,
                                Value       = arcs[idx].Value.Value,
                                Coordinates = coordinates
                            });

                            if (arcsQueue.Count == blockSize)
                            { // execute serialization.
                                typeModel.SerializeWithSize(stream, arcsQueue.ToArray());
                                arcsQueue.Clear();
                            }
                        }
                    }

                    // serialize.
                    vertex++;
                }
            }

            if (arcsQueue.Count > 0)
            { // execute serialization.
                typeModel.SerializeWithSize(stream, arcsQueue.ToArray());
                arcsQueue.Clear();
            }
        }
Beispiel #2
0
        /// <summary>
        /// Serializes all edges.
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="graph"></param>
        protected override void SerializeEdges(LimitedStream stream, DynamicGraphRouterDataSource <CHEdgeData> graph)
        {
            var typeModel = RuntimeTypeModel.Create();

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

            int blockSize = 1000;
            var arcsQueue = new List <SerializableEdge>(blockSize);

            uint vertex = 0;

            while (vertex < graph.VertexCount)
            { // keep looping and serialize all vertices.
                var arcs = graph.GetEdges(vertex);
                if (arcs != null)
                { // serialize the arcs, but serialize them only once.
                    // choose only those arcs that start at a vertex smaller than the target.
                    for (int idx = 0; idx < arcs.Length; idx++)
                    {
                        if (arcs[idx].Key > vertex)
                        {
                            arcsQueue.Add(new SerializableEdge()
                            {
                                FromId             = vertex,
                                ToId               = arcs[idx].Key,
                                ContractedVertexId = arcs[idx].Value.ContractedVertexId,
                                Direction          = arcs[idx].Value.Direction,
                                Tags               = arcs[idx].Value.Tags,
                                Weight             = arcs[idx].Value.Weight
                            });

                            if (arcsQueue.Count == blockSize)
                            { // execute serialization.
                                typeModel.SerializeWithSize(stream, arcsQueue.ToArray());
                                arcsQueue.Clear();
                            }
                        }
                    }

                    // serialize.
                    vertex++;
                }
            }

            if (arcsQueue.Count > 0)
            { // execute serialization.
                typeModel.SerializeWithSize(stream, arcsQueue.ToArray());
                arcsQueue.Clear();
            }
        }
        public void RoutingRegressionTest9ResolvingReverse()
        {
            // 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")))
            };

            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);
                }
            }
        }
        /// <summary>
        /// Serializes all edges.
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="graph"></param>
        protected override void SerializeEdges(LimitedStream stream, DynamicGraphRouterDataSource <LiveEdge> graph)
        {
            var typeModel = RuntimeTypeModel.Create();

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

            int blockSize = 10000;
            var arcsQueue = new List <SerializableEdge>(blockSize);

            uint vertex = 0;

            while (vertex < graph.VertexCount)
            { // keep looping and serialize all vertices.
                var edges = graph.GetEdges(vertex);
                // serialize the arcs, but serialize them only once.
                // choose only those arcs that start at a vertex smaller than the target.
                foreach (var edge in edges)
                {
                    if (edge.Neighbour > vertex)
                    {
                        arcsQueue.Add(new SerializableEdge()
                        {
                            Distance    = edge.EdgeData.Distance,
                            FromId      = vertex,
                            ToId        = edge.Neighbour,
                            Value       = edge.EdgeData.Value,
                            Coordinates = edge.Intermediates.ToSimpleArray()
                        });

                        if (arcsQueue.Count == blockSize)
                        { // execute serialization.
                            typeModel.SerializeWithSize(stream, arcsQueue.ToArray());
                            arcsQueue.Clear();
                        }
                    }
                }

                // move to next vertex.
                vertex++;
            }

            if (arcsQueue.Count > 0)
            { // execute serialization.
                typeModel.SerializeWithSize(stream, arcsQueue.ToArray());
                arcsQueue.Clear();
            }
        }
        /// <summary>
        /// Serializes all edges.
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="graph"></param>
        protected override void SerializeEdges(LimitedStream stream, DynamicGraphRouterDataSource <CHEdgeData> graph)
        {
            var typeModel = RuntimeTypeModel.Create();

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

            int blockSize = 1000;
            var arcsQueue = new List <SerializableEdge>(blockSize);

            uint vertex = 0;

            while (vertex < graph.VertexCount)
            { // keep looping and serialize all vertices.
                var arcs = graph.GetEdges(vertex).ToList();
                if (arcs != null)
                { // serialize the arcs, but serialize them only once.
                    // choose only those arcs that start at a vertex smaller than the target.
                    for (int idx = 0; idx < arcs.Count; idx++)
                    {
                        arcsQueue.Add(new SerializableEdge()
                        {
                            FromId      = vertex,
                            ToId        = arcs[idx].Neighbour,
                            Meta        = arcs[idx].EdgeData.Meta,
                            Value       = arcs[idx].EdgeData.Value,
                            Weight      = arcs[idx].EdgeData.Weight,
                            Coordinates = arcs[idx].Intermediates.ToSimpleArray()
                        });

                        if (arcsQueue.Count == blockSize)
                        { // execute serialization.
                            typeModel.SerializeWithSize(stream, arcsQueue.ToArray());
                            arcsQueue.Clear();
                        }
                    }

                    // serialize.
                    vertex++;
                }
            }

            if (arcsQueue.Count > 0)
            { // execute serialization.
                typeModel.SerializeWithSize(stream, arcsQueue.ToArray());
                arcsQueue.Clear();
            }
        }
        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 RoutingRegressionTest9ResolvingReverse()
        {
            // 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")))
            };
            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 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);
        }
        /// <summary>
        /// Does the v1 serialization.
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="graph"></param>
        /// <returns></returns>
        protected override void DoSerialize(LimitedStream stream,
                                            DynamicGraphRouterDataSource <CHEdgeData> graph)
        {
            // create an index per tile.
            var dataPerTile = new Dictionary <Tile, UnserializedTileData>();

            for (uint vertex = 1; vertex < graph.VertexCount + 1; vertex++)
            { // loop over all vertices and serialize all into the correct tile.
                float latitude, longitude;
                if (graph.GetVertex(vertex, out latitude, out longitude))
                { // the vertex was found.
                    // build the correct tile.
                    Tile tile = Tile.CreateAroundLocation(new GeoCoordinate(latitude, longitude), Zoom);
                    UnserializedTileData serializableGraphTile;
                    if (!dataPerTile.TryGetValue(tile, out serializableGraphTile))
                    { // create the new tile.
                        serializableGraphTile             = new UnserializedTileData();
                        serializableGraphTile.Ids         = new List <uint>();
                        serializableGraphTile.Latitude    = new List <ushort>();
                        serializableGraphTile.Longitude   = new List <ushort>();
                        serializableGraphTile.StringTable = new Dictionary <string, int>();
                        serializableGraphTile.Arcs        = new List <SerializableGraphArcs>();

                        dataPerTile.Add(tile, serializableGraphTile);
                    }

                    // create short latitude/longitude.
                    serializableGraphTile.Ids.Add(vertex);
                    serializableGraphTile.Latitude.Add((ushort)(((tile.TopLeft.Latitude - latitude)
                                                                 / tile.Box.DeltaLat) * ushort.MaxValue));
                    serializableGraphTile.Longitude.Add((ushort)(((longitude - tile.TopLeft.Longitude)
                                                                  / tile.Box.DeltaLon) * ushort.MaxValue));

                    // get the arcs.
                    KeyValuePair <uint, CHEdgeData>[] arcs = graph.GetEdges(vertex);

                    // serialize the arcs.
                    var serializableGraphArcs = new SerializableGraphArcs();
                    if (arcs != null && arcs.Length > 0)
                    {
                        serializableGraphArcs.DestinationId = new uint[arcs.Length];
                        serializableGraphArcs.Forward       = new bool[arcs.Length];
                        serializableGraphArcs.Backward      = new bool[arcs.Length];
                        serializableGraphArcs.Weight        = new float[arcs.Length];
                        serializableGraphArcs.TileX         = new int[arcs.Length];
                        serializableGraphArcs.TileY         = new int[arcs.Length];
                        serializableGraphArcs.Tags          = new SerializableTags[arcs.Length];

                        for (int idx = 0; idx < arcs.Length; idx++)
                        {
                            KeyValuePair <uint, CHEdgeData> arc = arcs[idx];
                            // get destination tile.
                            if (graph.GetVertex(arc.Key, out latitude, out longitude))
                            { // the destionation was found.
                                Tile destinationTile = Tile.CreateAroundLocation(
                                    new GeoCoordinate(latitude, longitude), Zoom);
                                serializableGraphArcs.DestinationId[idx] = arc.Key;
                                serializableGraphArcs.TileX[idx]         = destinationTile.X;
                                serializableGraphArcs.TileY[idx]         = destinationTile.Y;
                                serializableGraphArcs.Forward[idx]       = arc.Value.Forward;
                                serializableGraphArcs.Backward[idx]      = arc.Value.Backward;
                                serializableGraphArcs.Weight[idx]        = arc.Value.Weight;

                                // get the tags.
                                TagsCollectionBase tagsCollection =
                                    graph.TagsIndex.Get(arc.Value.Tags);
                                if (tagsCollection != null)
                                {
                                    serializableGraphArcs.Tags[idx]        = new SerializableTags();
                                    serializableGraphArcs.Tags[idx].Keys   = new int[tagsCollection.Count];
                                    serializableGraphArcs.Tags[idx].Values = new int[tagsCollection.Count];
                                    int tagsIndex = 0;
                                    foreach (var tag in tagsCollection)
                                    {
                                        int key;
                                        if (!serializableGraphTile.StringTable.TryGetValue(
                                                tag.Key, out key))
                                        { // string not yet in string table.
                                            key = serializableGraphTile.StringTable.Count;
                                            serializableGraphTile.StringTable.Add(tag.Key,
                                                                                  key);
                                        }
                                        int value;
                                        if (!serializableGraphTile.StringTable.TryGetValue(
                                                tag.Value, out value))
                                        { // string not yet in string table.
                                            value = serializableGraphTile.StringTable.Count;
                                            serializableGraphTile.StringTable.Add(tag.Value,
                                                                                  value);
                                        }
                                        serializableGraphArcs.Tags[idx].Keys[tagsIndex]   = key;
                                        serializableGraphArcs.Tags[idx].Values[tagsIndex] = value;
                                        tagsIndex++;
                                    }
                                }
                            }
                        }
                    }
                    serializableGraphTile.Arcs.Add(serializableGraphArcs);
                }
            }

            // LAYOUT OF V2: {HEADER}{compressionflag(1byte)}{#tiles(4byte)}{tilesMetaEnd(8byte)}{tiles-meta-data-xxxxxxx}{tiles-data}
            // {HEADER} : already written before this method.
            // {#tiles(4byte)} : the number of tiles in this file (calculate the offset of the {tiles-data}
            //                   section using (TileMetaSize * dataPerTile.Count + 4 + 8)
            // {tilesMetaEnd(8byte)} : the end of the meta tiles.
            // {tiles-meta-data-xxxxxxx} : the serialized tile metadata.
            // {tiles-data} : the actual tile data.

            // calculate the space needed for the tile offset.
            const long tileMetaOffset = 1 + 4 + 8;
            long       tileOffset     = TileMetaSize * dataPerTile.Count +
                                        tileMetaOffset; // all tile metadata + a tile count + tags offset.

            // build the tile metadata while writing the tile data.
            stream.Seek(tileOffset, SeekOrigin.Begin);
            var metas = new SerializableGraphTileMetas();

            metas.Length = new int[dataPerTile.Count];
            metas.Offset = new long[dataPerTile.Count];
            metas.TileX  = new int[dataPerTile.Count];
            metas.TileY  = new int[dataPerTile.Count];
            int metasIndex = 0;

            foreach (var unserializedTileData in dataPerTile)
            {
                // create the tile meta.
                metas.TileX[metasIndex]  = unserializedTileData.Key.X;
                metas.TileY[metasIndex]  = unserializedTileData.Key.Y;
                metas.Offset[metasIndex] = stream.Position;

                // create the tile.
                var serializableGraphTile = new SerializableGraphTile();
                serializableGraphTile.Arcs        = unserializedTileData.Value.Arcs.ToArray();
                serializableGraphTile.Ids         = unserializedTileData.Value.Ids.ToArray();
                serializableGraphTile.Latitude    = unserializedTileData.Value.Latitude.ToArray();
                serializableGraphTile.Longitude   = unserializedTileData.Value.Longitude.ToArray();
                serializableGraphTile.StringTable = new string[unserializedTileData.Value.StringTable.Count];
                foreach (var stringEntry in unserializedTileData.Value.StringTable)
                {
                    serializableGraphTile.StringTable[stringEntry.Value] =
                        stringEntry.Key;
                }

                // serialize the tile.
                if (!_compress)
                { // compresses the file.
                    _runtimeTypeModel.Serialize(stream, serializableGraphTile);
                }
                else
                { // first compress the data, then write.
                    var uncompressed = new MemoryStream();
                    _runtimeTypeModel.Serialize(uncompressed, serializableGraphTile);
                    var uncompressedBuffer = uncompressed.ToArray();

                    byte[] compressed = GZipStream.CompressBuffer(uncompressedBuffer);
                    stream.Write(compressed, 0, compressed.Length);
                }

                // calculate the length of the data that was just serialized.
                metas.Length[metasIndex] = (int)(stream.Position - metas.Offset[metasIndex]);

                metasIndex++;
            }

            // serialize all tile meta data.
            stream.Seek(tileMetaOffset, SeekOrigin.Begin);
            _runtimeTypeModel.Serialize(stream, metas);
            long tileMetaEnd = stream.Position; // save the meta and.

            // save all the offsets.
            stream.Seek(0, SeekOrigin.Begin);
            byte[] compressionFlag = new[] { (byte)(_compress ? 1 : 0) };
            stream.Write(compressionFlag, 0, 1);
            byte[] tileCountBytes = BitConverter.GetBytes(metas.TileX.Length);
            stream.Write(tileCountBytes, 0, tileCountBytes.Length);     // 4 bytes
            byte[] tileMetaEndBytes = BitConverter.GetBytes(tileMetaEnd);
            stream.Write(tileMetaEndBytes, 0, tileMetaEndBytes.Length); // 8 bytes

            stream.Flush();
        }
        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);
                }
            }
        }