/// <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); } } }
/// <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); } } }
/// <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); } } } } } }