Beispiel #1
0
        /// <summary>
        /// Serializes the vertices
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="graph"></param>
        protected virtual void SerializeVertices(LimitedStream stream, DynamicGraphRouterDataSource <TEdgeData> graph)
        {
            RuntimeTypeModel typeModel = RuntimeTypeModel.Create();

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

            int   blockSize = 1000;
            var   vertices = new SerializableVertex[blockSize];
            uint  vertex = 1;
            float latitude, longitude;

            while (vertex <= graph.VertexCount)
            {
                // adjust array size if needed.
                if (vertices.Length > graph.VertexCount - vertex)
                { // shrink array.
                    vertices = new SerializableVertex[graph.VertexCount - vertex + 1];
                }

                // build block.
                for (uint idx = 0; idx < vertices.Length; idx++)
                {
                    uint current = vertex + idx;
                    if (vertex <= graph.VertexCount && graph.GetVertex(current, out latitude, out longitude))
                    {     // vertex in the graph.
                        if (vertices[idx] == null)
                        { // make sure there is a vertex.
                            vertices[idx] = new SerializableVertex();
                        }
                        vertices[idx].Latitude  = latitude;
                        vertices[idx].Longitude = longitude;
                    }
                    else
                    { // vertex not in the graph.
                        throw new Exception("Cannot serialize non-existing vertices!");
                    }
                }

                // serialize.
                typeModel.SerializeWithSize(stream, vertices);

                // move to the next vertex.
                vertex = (uint)(vertex + blockSize);
            }
        }
        public void RoutingSerializationV2DataSourceTest()
        {
            const string embeddedString = "OsmSharp.Test.Unittests.test_network.osm";

            // create the tags index.
            var tagsIndex = new SimpleTagsIndex();

            // creates a new interpreter.
            var interpreter = new OsmRoutingInterpreter();

            // do the data processing.
            var original =
                new DynamicGraphRouterDataSource <LiveEdge>(tagsIndex);
            var targetData = new LiveGraphOsmStreamTarget(
                original, interpreter, tagsIndex);
            var dataProcessorSource = new XmlOsmStreamSource(
                Assembly.GetExecutingAssembly().GetManifestResourceStream(embeddedString));

            targetData.RegisterSource(dataProcessorSource);
            targetData.Pull();

            // store some lat/lons.
            var verticesLocations = new List <GeoCoordinate>();

            for (uint vertex = 1; vertex <= 5; vertex++)
            {
                float latitude, longitude;
                if (original.GetVertex(vertex, out latitude, out longitude))
                {
                    verticesLocations.Add(
                        new GeoCoordinate(latitude, longitude));
                }
            }

            // create serializer.
            var routingSerializer = new V2RoutingDataSourceLiveEdgeSerializer(false);

            // serialize/deserialize.
            IBasicRouterDataSource <LiveEdge> deserializedVersion;

            byte[] byteArray;
            using (var stream = new MemoryStream())
            {
                try
                {
                    routingSerializer.Serialize(stream, original);
                    byteArray = stream.ToArray();
                }
                catch (Exception)
                {
                    if (Debugger.IsAttached)
                    {
                        Debugger.Break();
                    }
                    throw;
                }
            }
            using (var stream = new MemoryStream(byteArray))
            {
                try
                {
                    deserializedVersion = routingSerializer.Deserialize(stream, false);
                }
                catch (Exception)
                {
                    if (Debugger.IsAttached)
                    {
                        Debugger.Break();
                    }
                    throw;
                }
            }

            //Assert.AreEqual(original.VertexCount, deserializedVersion.VertexCount);
            Assert.AreEqual(original.TagsIndex.Get(0), deserializedVersion.TagsIndex.Get(0));

            for (uint vertex = 1; vertex <= 5; vertex++)
            {
                float latitude, longitude;
                if (deserializedVersion.GetVertex(vertex, out latitude, out longitude))
                {
                    Assert.AreEqual(verticesLocations[(int)vertex - 1].Latitude, latitude, 0.000001);
                    Assert.AreEqual(verticesLocations[(int)vertex - 1].Longitude, longitude, 0.000001);
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// Does the v1 serialization.
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="graph"></param>
        /// <returns></returns>
        protected override void DoSerialize(LimitedStream stream,
                                            DynamicGraphRouterDataSource <LiveEdge> 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, LiveEdge>[] arcs = graph.GetArcs(vertex);

                    // serialize the arcs.
                    if (arcs != null && arcs.Length > 0)
                    {
                        var serializableGraphArcs = new SerializableGraphArcs();
                        serializableGraphArcs.DestinationId = new uint[arcs.Length];
                        serializableGraphArcs.Forward       = new bool[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, LiveEdge> 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;

                                // 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 RoutingSerializationV2DataSourceTest()
        {
            const string embeddedString = "OsmSharp.Test.Unittests.test_network.osm";

            // create the tags index.
            var tagsIndex = new SimpleTagsIndex();

            // creates a new interpreter.
            var interpreter = new OsmRoutingInterpreter();

            // do the data processing.
            var original =
                new DynamicGraphRouterDataSource<LiveEdge>(tagsIndex);
            var targetData = new LiveGraphOsmStreamTarget(
                original, interpreter, tagsIndex);
            var dataProcessorSource = new XmlOsmStreamSource(
                Assembly.GetExecutingAssembly().GetManifestResourceStream(embeddedString));
            targetData.RegisterSource(dataProcessorSource);
            targetData.Pull();

            // store some lat/lons.
            var verticesLocations = new List<GeoCoordinate>();
            for (uint vertex = 1; vertex <= 5; vertex++)
            {
                float latitude, longitude;
                if(original.GetVertex(vertex, out latitude, out longitude))
                {
                    verticesLocations.Add(
                        new GeoCoordinate(latitude, longitude));
                }
            }

            // create serializer.
            var routingSerializer = new V2RoutingDataSourceLiveEdgeSerializer(false);

            // serialize/deserialize.
            IBasicRouterDataSource<LiveEdge> deserializedVersion;
            byte[] byteArray;
            using (var stream = new MemoryStream())
            {
                try
                {
                    routingSerializer.Serialize(stream, original);
                    byteArray = stream.ToArray();
                }
                catch (Exception)
                {
                    if (Debugger.IsAttached)
                    {
                        Debugger.Break();
                    }
                    throw;
                }
            }
            using (var stream = new MemoryStream(byteArray))
            {
                try
                {
                    deserializedVersion = routingSerializer.Deserialize(stream, false);
                }
                catch (Exception)
                {
                    if (Debugger.IsAttached)
                    {
                        Debugger.Break();
                    }
                    throw;
                }
            }

            //Assert.AreEqual(original.VertexCount, deserializedVersion.VertexCount);
            Assert.AreEqual(original.TagsIndex.Get(0), deserializedVersion.TagsIndex.Get(0));

            for (uint vertex = 1; vertex <= 5; vertex++)
            {
                float latitude, longitude;
                if (deserializedVersion.GetVertex(vertex, out latitude, out longitude))
                {
                    Assert.AreEqual(verticesLocations[(int)vertex - 1].Latitude, latitude, 0.000001);
                    Assert.AreEqual(verticesLocations[(int)vertex - 1].Longitude, longitude, 0.000001);
                }
            }
        }
Beispiel #5
0
        /// <summary>
        /// Called right after the contraction.
        /// </summary>
        /// <param name="vertex"></param>
        /// <param name="edges"></param>
        void pre_processor_OnAfterContractionEvent(uint vertex, KeyValuePair <uint, CHEdgeData>[] edges)
        {
            // create a new CHRouter
            var router = new CHRouter();

            // calculate all the routes between the neighbours of the contracted vertex.
            foreach (KeyValuePair <uint, CHEdgeData> from in edges)
            {
                // initialize the from-list.
                var fromList = new PathSegmentVisitList();
                fromList.UpdateVertex(new PathSegment <long>(from.Key));

                // initalize the from dictionary.
                Dictionary <uint, PathSegment <long> > fromDic = _pathsBeforeContraction[from.Key];
                foreach (KeyValuePair <uint, CHEdgeData> to in edges)
                {
                    // initialize the to-list.
                    var toList = new PathSegmentVisitList();
                    toList.UpdateVertex(new PathSegment <long>(to.Key));

                    // calculate the route.
                    PathSegment <long> route = router.Calculate(_data, _interpreter, OsmSharp.Routing.Vehicle.Car, fromList, toList, double.MaxValue, null);
                    if ((fromDic[to.Key] == null && route != null) ||
                        (fromDic[to.Key] != null && route == null) ||
                        ((fromDic[to.Key] != null && route != null) && fromDic[to.Key] != route))
                    { // the route match!
                        Assert.Fail("Routes are different before/after contraction!");
                    }
                }
            }

            if (_referenceRouter != null)
            { // do crazy verification!
                Router chRouter = Router.CreateCHFrom(_data, router, new OsmRoutingInterpreter());

                // loop over all nodes and resolve their locations.
                var resolvedReference = new RouterPoint[_data.VertexCount - 1];
                var resolved          = new RouterPoint[_data.VertexCount - 1];
                for (uint idx = 1; idx < _data.VertexCount; idx++)
                { // resolve each vertex.
                    float latitude, longitude;
                    if (_data.GetVertex(idx, out latitude, out longitude))
                    {
                        resolvedReference[idx - 1] = _referenceRouter.Resolve(Vehicle.Car, new GeoCoordinate(latitude, longitude));
                        resolved[idx - 1]          = chRouter.Resolve(Vehicle.Car, new GeoCoordinate(latitude, longitude));
                    }

                    Assert.IsNotNull(resolvedReference[idx - 1]);
                    Assert.IsNotNull(resolved[idx - 1]);

                    Assert.AreEqual(resolvedReference[idx - 1].Location.Latitude,
                                    resolved[idx - 1].Location.Latitude, 0.0001);
                    Assert.AreEqual(resolvedReference[idx - 1].Location.Longitude,
                                    resolved[idx - 1].Location.Longitude, 0.0001);
                }

                // limit tests to a fixed number.
                int maxTestCount   = 100;
                int testEveryOther = (resolved.Length * resolved.Length) / maxTestCount;
                testEveryOther = System.Math.Max(testEveryOther, 1);

                // check all the routes having the same weight(s).
                for (int fromIdx = 0; fromIdx < resolved.Length; fromIdx++)
                {
                    for (int toIdx = 0; toIdx < resolved.Length; toIdx++)
                    {
                        int testNumber = fromIdx * resolved.Length + toIdx;
                        if (testNumber % testEveryOther == 0)
                        {
                            Route referenceRoute = _referenceRouter.Calculate(Vehicle.Car,
                                                                              resolvedReference[fromIdx], resolvedReference[toIdx]);
                            Route route = chRouter.Calculate(Vehicle.Car,
                                                             resolved[fromIdx], resolved[toIdx]);

                            if (referenceRoute != null)
                            {
                                Assert.IsNotNull(referenceRoute);
                                Assert.IsNotNull(route);
                                this.CompareRoutes(referenceRoute, route);
                            }
                        }
                    }
                }
            }
        }