/// <summary> /// Creates a new memory mapped graph from existing data. /// </summary> /// <param name="vertexCount"></param> /// <param name="edgesCount"></param> /// <param name="verticesFile"></param> /// <param name="verticesCoordinatesFile"></param> /// <param name="edgesFile"></param> /// <param name="edgeDataFile"></param> /// <param name="shapesIndexFile"></param> /// <param name="shapesIndexLength"></param> /// <param name="shapesCoordinateFile"></param> /// <param name="shapesCoordinateLength"></param> /// <param name="mapFrom"></param> /// <param name="mapTo"></param> /// <param name="edgeDataSize"></param> public DirectedGraph(long vertexCount, long edgesCount, MemoryMappedFile verticesFile, MemoryMappedFile verticesCoordinatesFile, MemoryMappedFile edgesFile, MemoryMappedFile edgeDataFile, MemoryMappedFile shapesIndexFile, long shapesIndexLength, MemoryMappedFile shapesCoordinateFile, long shapesCoordinateLength, MappedHugeArray <TEdgeData, uint> .MapFrom mapFrom, MappedHugeArray <TEdgeData, uint> .MapTo mapTo, int edgeDataSize) : this( new MappedHugeArray <GeoCoordinateSimple, float>(new MemoryMappedHugeArraySingle(verticesCoordinatesFile, vertexCount * 2), 2, (array, idx, value) => { array[idx] = value.Latitude; array[idx + 1] = value.Longitude; }, (array, idx) => { return(new GeoCoordinateSimple() { Latitude = array[idx], Longitude = array[idx + 1] }); }), new MemoryMappedHugeArrayUInt32(verticesFile, vertexCount), new MemoryMappedHugeArrayUInt32(edgesFile, edgesCount), new MappedHugeArray <TEdgeData, uint>(new MemoryMappedHugeArrayUInt32(edgeDataFile, edgesCount * edgeDataSize), edgeDataSize, mapTo, mapFrom), new HugeCoordinateCollectionIndex(shapesIndexLength, new MemoryMappedHugeArrayUInt64(shapesIndexFile, shapesIndexLength), new MemoryMappedHugeArraySingle(shapesCoordinateFile, shapesCoordinateLength))) { }
/// <summary> /// Serializes this graph router data source to the given stream. /// </summary> /// <param name="stream"></param> /// <param name="edgeDataSize"></param> /// <param name="mapFrom"></param> /// <param name="mapTo"></param> /// <returns></returns> public override long Serialize(System.IO.Stream stream, int edgeDataSize, MappedHugeArray <TEdgeData, uint> .MapFrom mapFrom, MappedHugeArray <TEdgeData, uint> .MapTo mapTo) { // make room for size of graph. long position = 0; stream.Seek(8, System.IO.SeekOrigin.Begin); position = position + 8; // first serialize all graph-data. position = position + _graph.Serialize(new LimitedStream(stream), edgeDataSize, mapFrom, mapTo); // write size of graph. stream.Seek(0, System.IO.SeekOrigin.Begin); stream.Write(BitConverter.GetBytes(position), 0, 8); stream.Seek(position, System.IO.SeekOrigin.Begin); // serialize tags. var tagsSize = _tagsIndex.Serialize(new LimitedStream(stream)); position = position + tagsSize; return(position); }
/// <summary> /// Creates a new memory mapped graph using the given file. /// </summary> /// <param name="file"></param> /// <param name="estimatedSize"></param> /// <param name="mapFrom"></param> /// <param name="mapTo"></param> public DirectedGraph(MemoryMappedFile file, long estimatedSize, MappedHugeArray <TEdgeData, uint> .MapFrom mapFrom, MappedHugeArray <TEdgeData, uint> .MapTo mapTo, int edgeDataSize) : this(estimatedSize, new MappedHugeArray <GeoCoordinateSimple, float>(new MemoryMappedHugeArraySingle(file, estimatedSize * 2), 2, (array, idx, value) => { array[idx] = value.Latitude; array[idx + 1] = value.Longitude; }, (array, idx) => { return(new GeoCoordinateSimple() { Latitude = array[idx], Longitude = array[idx + 1] }); }), new MemoryMappedHugeArrayUInt32(file, estimatedSize), new MemoryMappedHugeArrayUInt32(file, estimatedSize), new MappedHugeArray <TEdgeData, uint>(new MemoryMappedHugeArrayUInt32(file, estimatedSize * edgeDataSize), edgeDataSize, mapTo, mapFrom), new HugeCoordinateCollectionIndex(file, estimatedSize)) { }
/// <summary> /// Deserializes a graph from the given stream. /// </summary> /// <param name="stream"></param> /// <param name="edgeDataSize"></param> /// <param name="mapFrom"></param> /// <param name="mapTo"></param> /// <param name="copy"></param> /// <returns></returns> public static GraphBase <TEdgeData> Deserialize(Stream stream, int edgeDataSize, MappedHugeArray <TEdgeData, uint> .MapFrom mapFrom, MappedHugeArray <TEdgeData, uint> .MapTo mapTo, bool copy) { var intBytes = new byte[4]; stream.Read(intBytes, 0, 4); var graphType = System.BitConverter.ToInt32(intBytes, 0); switch (graphType) { case 2: return(Graph <TEdgeData> .Deserialize(stream, edgeDataSize, mapFrom, mapTo, copy)); case 1: return(DirectedGraph <TEdgeData> .Deserialize(stream, edgeDataSize, mapFrom, mapTo, copy)); } throw new System.Exception(string.Format("Invalid graph type: {0}", graphType.ToInvariantString())); }
/// <summary> /// Deserializes a graph router data source from the given stream. /// </summary> /// <param name="stream"></param> /// <param name="edgeDataSize"></param> /// <param name="mapFrom"></param> /// <param name="mapTo"></param> /// <returns></returns> public new static RouterDataSource <TEdgeData> Deserialize(System.IO.Stream stream, int edgeDataSize, MappedHugeArray <TEdgeData, uint> .MapFrom mapFrom, MappedHugeArray <TEdgeData, uint> .MapTo mapTo, bool copy) { // read size of graph and start location of tags. var longBytes = new byte[8]; stream.Read(longBytes, 0, 8); var position = BitConverter.ToInt64(longBytes, 0); // deserialize graph. var graph = GraphBase <TEdgeData> .Deserialize(new CappedStream(stream, 8, position - 8), edgeDataSize, mapFrom, mapTo, copy); // deserialize tags. stream.Seek(position, System.IO.SeekOrigin.Begin); var tagsIndex = global::OsmSharp.Collections.Tags.Index.TagsIndex.Deserialize( new LimitedStream(stream)); return(new RouterDataSource <TEdgeData>(graph, tagsIndex)); }
/// <summary> /// Deserializes a graph from the given stream. /// </summary> /// <param name="stream">The stream to read from. Reading will start at position 0.</param> /// <param name="edgeDataSize">The edge data size.</param> /// <param name="mapFrom">The map from for the edge data.</param> /// <param name="mapTo">The map to for the edge data.</param> /// <param name="copy">Flag to make an in-memory copy.</param> /// <returns></returns> public new static DirectedGraph <TEdgeData> Deserialize(System.IO.Stream stream, int edgeDataSize, MappedHugeArray <TEdgeData, uint> .MapFrom mapFrom, MappedHugeArray <TEdgeData, uint> .MapTo mapTo, bool copy) { // read sizes. long position = 0; stream.Seek(4, System.IO.SeekOrigin.Begin); position = position + 4; var longBytes = new byte[8]; stream.Read(longBytes, 0, 8); position = position + 8; var vertexLength = BitConverter.ToInt64(longBytes, 0); stream.Read(longBytes, 0, 8); position = position + 8; var edgeLength = BitConverter.ToInt64(longBytes, 0); var bufferSize = 32; var cacheSize = MemoryMappedHugeArrayUInt32.DefaultCacheSize; var file = new MemoryMappedStream(new OsmSharp.IO.LimitedStream(stream)); var vertexArray = new MemoryMappedHugeArrayUInt32(file, (vertexLength + 1) * VERTEX_SIZE, (vertexLength + 1) * VERTEX_SIZE, bufferSize / 4, cacheSize * 4); position = position + ((vertexLength + 1) * VERTEX_SIZE * 4); var vertexCoordinateArray = new MappedHugeArray <GeoCoordinateSimple, float>( new MemoryMappedHugeArraySingle(file, (vertexLength + 1) * 2, (vertexLength + 1) * 2, bufferSize / 4, cacheSize * 4), 2, (array, idx, coordinate) => { array[idx] = coordinate.Latitude; array[idx + 1] = coordinate.Longitude; }, (Array, idx) => { return(new GeoCoordinateSimple() { Latitude = Array[idx], Longitude = Array[idx + 1] }); }); position = position + ((vertexLength + 1) * 2 * 4); var edgeArray = new MemoryMappedHugeArrayUInt32(file, edgeLength * EDGE_SIZE, edgeLength * EDGE_SIZE, bufferSize / 2, cacheSize * 4); position = position + (edgeLength * EDGE_SIZE * 4); var edgeDataArray = new MappedHugeArray <TEdgeData, uint>( new MemoryMappedHugeArrayUInt32(file, edgeLength * edgeDataSize, edgeLength * edgeDataSize, bufferSize * 2, cacheSize * 2), edgeDataSize, mapTo, mapFrom); position = position + (edgeLength * edgeDataSize * 4); // deserialize shapes. stream.Seek(position, System.IO.SeekOrigin.Begin); var cappedStream = new OsmSharp.IO.LimitedStream(stream); var shapes = HugeCoordinateCollectionIndex.Deserialize(cappedStream, copy); if (copy) { // copy the data. var vertexArrayCopy = new HugeArray <uint>(vertexArray.Length); vertexArrayCopy.CopyFrom(vertexArray); var vertexCoordinateArrayCopy = new HugeArray <GeoCoordinateSimple>(vertexCoordinateArray.Length); vertexCoordinateArrayCopy.CopyFrom(vertexCoordinateArray); var edgeArrayCopy = new HugeArray <uint>(edgeArray.Length); edgeArrayCopy.CopyFrom(edgeArray); var edgeDataArrayCopy = new HugeArray <TEdgeData>(edgeDataArray.Length); edgeDataArrayCopy.CopyFrom(edgeDataArray); file.Dispose(); return(new DirectedGraph <TEdgeData>(vertexCoordinateArrayCopy, vertexArrayCopy, edgeArrayCopy, edgeDataArrayCopy, shapes)); } return(new DirectedGraph <TEdgeData>(vertexCoordinateArray, vertexArray, edgeArray, edgeDataArray, shapes)); }
/// <summary> /// Serializes this graph to disk. /// </summary> /// <param name="stream">The stream to write to. Writing will start at position 0.</param> /// <param name="edgeDataSize">The edge data size.</param> /// <param name="mapFrom">The map from for the edge data.</param> /// <param name="mapTo">The map to for the edge data.</param> public override long Serialize(System.IO.Stream stream, int edgeDataSize, MappedHugeArray <TEdgeData, uint> .MapFrom mapFrom, MappedHugeArray <TEdgeData, uint> .MapTo mapTo) { long vertexCount = (_nextVertexId - 1); long edgeCount = (_nextEdgeId / EDGE_SIZE); // write vertex and edge count. long position = 0; stream.Write(BitConverter.GetBytes((int)1), 0, 4); position = position + 4; stream.Write(BitConverter.GetBytes(vertexCount), 0, 8); // write exact number of vertices. position = position + 8; stream.Write(BitConverter.GetBytes(edgeCount), 0, 8); // write exact number of edges. position = position + 8; // write in this order: vertices, vertexCoordinates, edges, edgeData, edgeShapes. using (var file = new MemoryMappedStream(new OsmSharp.IO.LimitedStream(stream))) { // write vertices (each vertex = 1 uint (4 bytes)). var vertexArray = new MemoryMappedHugeArrayUInt32(file, (vertexCount + 1) * VERTEX_SIZE, (vertexCount + 1) * VERTEX_SIZE, 1024); vertexArray.CopyFrom(_vertices, 0, 0, (vertexCount + 1) * VERTEX_SIZE); vertexArray.Dispose(); // written, get rid of it! position = position + ((vertexCount + 1) * VERTEX_SIZE * 4); // write vertex coordinates (each vertex coordinate = 2 floats (8 bytes)). var vertexCoordinateArray = new MappedHugeArray <GeoCoordinateSimple, float>( new MemoryMappedHugeArraySingle(file, (vertexCount + 1) * 2, (vertexCount + 1) * 2, 1024), 2, (array, idx, coordinate) => { array[idx] = coordinate.Latitude; array[idx + 1] = coordinate.Longitude; }, (Array, idx) => { return(new GeoCoordinateSimple() { Latitude = Array[idx], Longitude = Array[idx + 1] }); }); vertexCoordinateArray.CopyFrom(_coordinates, 0, 0, (vertexCount + 1)); vertexCoordinateArray.Dispose(); // written, get rid of it! position = position + ((vertexCount + 1) * 2 * 4); // write edges (each edge = 4 uints (16 bytes)). var edgeArray = new MemoryMappedHugeArrayUInt32(file, edgeCount * EDGE_SIZE, edgeCount * EDGE_SIZE, 1024); edgeArray.CopyFrom(_edges, edgeCount * EDGE_SIZE); edgeArray.Dispose(); // written, get rid of it! position = position + (edgeCount * EDGE_SIZE * 4); // write edge data (each edgeData = edgeDataSize units (edgeDataSize * 4 bytes)). var edgeDataArray = new MappedHugeArray <TEdgeData, uint>( new MemoryMappedHugeArrayUInt32(file, edgeCount * edgeDataSize, edgeCount * edgeDataSize, 1024), edgeDataSize, mapTo, mapFrom); edgeDataArray.CopyFrom(_edgeData, edgeCount); edgeDataArray.Dispose(); // written, get rid of it! position = position + (edgeCount * edgeDataSize * 4); } // write shapes. stream.Seek(position, System.IO.SeekOrigin.Begin); position = position + _edgeShapes.Serialize(new OsmSharp.IO.LimitedStream(stream)); return(position); }
/// <summary> /// Serializes this graph to disk. /// </summary> /// <param name="stream">The stream to write to. Writing will start at position 0.</param> /// <param name="edgeDataSize">The edge data size.</param> /// <param name="mapFrom">The map from for the edge data.</param> /// <param name="mapTo">The map to for the edge data.</param> public abstract long Serialize(Stream stream, int edgeDataSize, MappedHugeArray <TEdgeData, uint> .MapFrom mapFrom, MappedHugeArray <TEdgeData, uint> .MapTo mapTo);