Пример #1
0
        /// <summary>
        /// Creates a new CH edge data source.
        /// </summary>
        public CHEdgeDataDataSource(Stream stream, CHEdgeDataDataSourceSerializer serializer,
                                    int startOfRegions, CHVertexRegionIndex regionIndex, int zoom,
                                    int startOfBlocks, CHBlockIndex blockIndex, uint blockSize,
                                    ITagsCollectionIndexReadonly tagsIndex)
        {
            _stream     = stream;
            _serializer = serializer;

            this.InitializeRegions(startOfRegions, regionIndex, zoom);
            this.InitializeBlocks(startOfBlocks, blockIndex, blockSize);

            _blocks    = new LRUCache <uint, CHBlock>(1000);
            _regions   = new LRUCache <ulong, CHVertexRegion>(1000);
            _tagsIndex = tagsIndex;
        }
Пример #2
0
 /// <summary>
 /// Initializes the blocks stuff.
 /// </summary>
 /// <param name="startOfBlocks"></param>
 /// <param name="blocksIndex"></param>
 /// <param name="blockSize"></param>
 private void InitializeBlocks(int startOfBlocks, CHBlockIndex blocksIndex, uint blockSize)
 {
     _startOfBlocks = startOfBlocks;
     _blocksIndex   = blocksIndex;
     _blockSize     = blockSize;
 }
Пример #3
0
        /// <summary>
        /// Does the v2 serialization.
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="graph"></param>
        /// <returns></returns>
        protected override void DoSerialize(LimitedStream stream,
                                            DynamicGraphRouterDataSource <CHEdgeData> graph)
        {
            // sort the graph.
            IDynamicGraph <CHEdgeData> sortedGraph = this.SortGraph(graph);

            // create the regions.
            SortedDictionary <ulong, List <uint> > regions = new SortedDictionary <ulong, List <uint> >();

            for (uint newVertexId = 1; newVertexId < sortedGraph.VertexCount + 1; newVertexId++)
            {
                // add to the CHRegions.
                float latitude, longitude;
                sortedGraph.GetVertex(newVertexId, out latitude, out longitude);
                Tile tile = Tile.CreateAroundLocation(new GeoCoordinate(
                                                          latitude, longitude), _regionZoom);
                List <uint> regionVertices;
                if (!regions.TryGetValue(tile.Id, out regionVertices))
                {
                    regionVertices = new List <uint>();
                    regions.Add(tile.Id, regionVertices);
                }
                regionVertices.Add(newVertexId);
            }

            // serialize the sorted graph.
            // [START_OF_BLOCKS][START_OF_TAGS][[SIZE_OF_REGION_INDEX][REGION_INDEX][REGIONS]][[SIZE_OF_BLOCK_INDEX][BLOCK_INDEX][BLOCKS]][TAGS]
            // STRART_OF_BLOCKS:        4bytes
            // START_OF_STAGS:          4bytes

            // SIZE_OF_REGION_INDEX:    4bytes
            // REGION_INDEX:            see SIZE_OF_REGION_INDEX
            // REGIONS:                 see START_OF_BLOCKS - 4bytes

            // SIZE_OF_BLOCK_INDEX:     4bytes
            // BLOCK_INDEX:             see SIZE_OF_BLOCK_INDEX.
            // BLOCKS:                  from START_OF_BLOCKS + 4bytes + SIZE_OF_BLOCKS_INDEX until END.

            // serialize regions and build their index.
            CHVertexRegionIndex chRegionIndex = new CHVertexRegionIndex();

            chRegionIndex.LocationIndex = new int[regions.Count];
            chRegionIndex.RegionIds     = new ulong[regions.Count];
            var memoryStream = new MemoryStream();
            int regionIdx    = 0;

            foreach (KeyValuePair <ulong, List <uint> > region in regions)
            {
                // serialize.
                CHVertexRegion chRegion = new CHVertexRegion();
                chRegion.Vertices = region.Value.ToArray();
                _runtimeTypeModel.Serialize(memoryStream, chRegion);

                // set index.
                chRegionIndex.LocationIndex[regionIdx] = (int)memoryStream.Position;
                chRegionIndex.RegionIds[regionIdx]     = region.Key;
                regionIdx++;
            }
            stream.Seek(12, SeekOrigin.Begin);                  // move to beginning of [REGION_INDEX]
            _runtimeTypeModel.Serialize(stream, chRegionIndex); // write region index.
            int sizeRegionIndex = (int)(stream.Position - 12);  // now at beginning of [REGIONS]

            memoryStream.Seek(0, SeekOrigin.Begin);
            memoryStream.WriteTo(stream);             // write regions.
            memoryStream.Dispose();
            int startOfBlocks = (int)stream.Position; // now at beginning of [SIZE_OF_BLOCK_INDEX]

            // serialize the blocks and build their index.
            memoryStream = new MemoryStream();
            List <int> blockLocations = new List <int>();
            uint       vertexId       = 1;

            while (vertexId < sortedGraph.VertexCount)
            {
                uint            blockId       = vertexId;
                List <CHArc>    blockArcs     = new List <CHArc>();
                List <CHVertex> blockVertices = new List <CHVertex>();
                while (vertexId < blockId + _blockVertexSize &&
                       vertexId < sortedGraph.VertexCount + 1)
                { // create this block.
                    CHVertex chVertex = new CHVertex();
                    float    latitude, longitude;
                    sortedGraph.GetVertex(vertexId, out latitude, out longitude);
                    chVertex.Latitude  = latitude;
                    chVertex.Longitude = longitude;
                    chVertex.ArcIndex  = (ushort)(blockArcs.Count);
                    foreach (KeyValuePair <uint, CHEdgeData> sortedArc in sortedGraph.GetArcs(vertexId))
                    {
                        CHArc chArc = new CHArc();
                        chArc.TargetId   = sortedArc.Key;
                        chArc.ShortcutId = sortedArc.Value.ContractedVertexId;
                        chArc.Weight     = sortedArc.Value.Weight;
                        chArc.Direction  = sortedArc.Value.Direction;
                        chArc.TagsId     = sortedArc.Value.Tags;
                        blockArcs.Add(chArc);
                    }
                    chVertex.ArcCount = (ushort)(blockArcs.Count - chVertex.ArcIndex);
                    blockVertices.Add(chVertex);

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

                // create block.
                CHBlock block = new CHBlock();
                block.Arcs     = blockArcs.ToArray();
                block.Vertices = blockVertices.ToArray(); // TODO: get rid of the list and create an array to begin with.

                // write blocks.
                MemoryStream blockStream = new MemoryStream();
                _runtimeTypeModel.Serialize(blockStream, block);
                byte[] compressed = GZipStream.CompressBuffer(blockStream.ToArray());
                blockStream.Dispose();

                memoryStream.Write(compressed, 0, compressed.Length);
                blockLocations.Add((int)memoryStream.Position);
            }
            CHBlockIndex blockIndex = new CHBlockIndex();

            blockIndex.LocationIndex = blockLocations.ToArray();

            stream.Seek(startOfBlocks + 4, SeekOrigin.Begin);                  // move to beginning of [BLOCK_INDEX]
            _runtimeTypeModel.Serialize(stream, blockIndex);                   // write region index.
            int sizeBlockIndex = (int)(stream.Position - (startOfBlocks + 4)); // now at beginning of [BLOCKS]

            memoryStream.Seek(0, SeekOrigin.Begin);
            memoryStream.WriteTo(stream); // write blocks.
            memoryStream.Dispose();

            // write tags after blocks.
            int tagsPosition = (int)stream.Position;

            TagIndexSerializer.SerializeBlocks(stream, graph.TagsIndex, 100);

            stream.Seek(startOfBlocks, SeekOrigin.Begin);              // move to [SIZE_OF_BLOCK_INDEX]
            stream.Write(BitConverter.GetBytes(sizeBlockIndex), 0, 4); // write start position of blocks. Now at [SIZE_OF_REGION_INDEX]

            // write index.
            stream.Seek(0, SeekOrigin.Begin);                           // move to beginning
            stream.Write(BitConverter.GetBytes(startOfBlocks), 0, 4);   // write start position of blocks. Now at [SIZE_OF_REGION_INDEX]
            stream.Write(BitConverter.GetBytes(tagsPosition), 0, 4);
            stream.Write(BitConverter.GetBytes(sizeRegionIndex), 0, 4); // write size of region index.
            stream.Flush();
        }