Exemple #1
0
        /// <summary>
        /// Reads all map data for the area covered by the given tile at the tile zoom level.
        /// </summary>
        /// <param name="tile">
        ///            defines area and zoom level of read map data. </param>
        /// <returns> the read map data. </returns>
        public override MapReadResult ReadMapData(Tile tile)
        {
            lock (this)
            {
                try
                {
                    QueryParameters queryParameters = new QueryParameters();
                    queryParameters.queryZoomLevel = this.mapFileHeader.GetQueryZoomLevel(tile.ZoomLevel);

                    // get and check the sub-file for the query zoom level
                    SubFileParameter subFileParameter = this.mapFileHeader.GetSubFileParameter(queryParameters.queryZoomLevel);
                    if (subFileParameter == null)
                    {
                        LOGGER.Warn("no sub-file for zoom level: " + queryParameters.queryZoomLevel);
                        return(null);
                    }

                    queryParameters.CalculateBaseTiles(tile, subFileParameter);
                    queryParameters.CalculateBlocks(subFileParameter);

                    // we enlarge the bounding box for the tile slightly in order to retain any data that
                    // lies right on the border, some of this data needs to be drawn as the graphics will
                    // overlap onto this tile.
                    return(ProcessBlocks(queryParameters, subFileParameter, tile.BoundingBox));
                }
                catch (IOException e)
                {
                    LOGGER.Log(LogLevel.Fatal, e.Message, e);
                    return(null);
                }
            }
        }
        /// <summary>
        /// Reads all map data for the area covered by the given tile at the tile zoom level.
        /// </summary>
        /// <param name="tile">
        ///            defines area and zoom level of read map data. </param>
        /// <returns> the read map data. </returns>
        public MapReadResult ReadMapData(TileInfo tileInfo)
        {
            lock (sync)
            {
                try
                {
                    QueryParameters queryParameters = new QueryParameters();
                    queryParameters.queryZoomLevel = this.mapFileHeader.GetQueryZoomLevel(sbyte.Parse(tileInfo.Index.Level));

                    // get and check the sub-file for the query zoom level
                    SubFileParameter subFileParameter = this.mapFileHeader.GetSubFileParameter(queryParameters.queryZoomLevel);
                    if (subFileParameter == null)
                    {
                        Logger.Log(LogLevel.Warning, "no sub-file for zoom level: " + queryParameters.queryZoomLevel);
                        return(null);
                    }

                    queryParameters.CalculateBaseTiles(tileInfo, subFileParameter);
                    queryParameters.CalculateBlocks(subFileParameter);

                    // we enlarge the bounding box for the tile slightly in order to retain any data that
                    // lies right on the border, some of this data needs to be drawn as the graphics will
                    // overlap onto this tile.
                    return(ProcessBlocks(queryParameters, subFileParameter, tileInfo.Extent.ToBoundingBox()));
                }
                catch (IOException e)
                {
                    Logger.Log(LogLevel.Error, e.Message, e);
                    return(null);
                }
            }
        }
Exemple #3
0
 public virtual void CalculateBaseTiles(Tile tile, SubFileParameter subFileParameter)
 {
     if (tile.ZoomLevel < subFileParameter.BaseZoomLevel)
     {
         // calculate the XY numbers of the upper left and lower right sub-tiles
         int zoomLevelDifference = subFileParameter.BaseZoomLevel - tile.ZoomLevel;
         this.fromBaseTileX  = tile.TileX << zoomLevelDifference;
         this.fromBaseTileY  = tile.TileY << zoomLevelDifference;
         this.toBaseTileX    = this.fromBaseTileX + (1 << zoomLevelDifference) - 1;
         this.toBaseTileY    = this.fromBaseTileY + (1 << zoomLevelDifference) - 1;
         this.useTileBitmask = false;
     }
     else if (tile.ZoomLevel > subFileParameter.BaseZoomLevel)
     {
         // calculate the XY numbers of the parent base tile
         int zoomLevelDifference = tile.ZoomLevel - subFileParameter.BaseZoomLevel;
         this.fromBaseTileX    = (int)((uint)tile.TileX >> zoomLevelDifference);
         this.fromBaseTileY    = (int)((uint)tile.TileY >> zoomLevelDifference);
         this.toBaseTileX      = this.fromBaseTileX;
         this.toBaseTileY      = this.fromBaseTileY;
         this.useTileBitmask   = true;
         this.queryTileBitmask = QueryCalculations.CalculateTileBitmask(tile, zoomLevelDifference);
     }
     else
     {
         // use the tile XY numbers of the requested tile
         this.fromBaseTileX  = tile.TileX;
         this.fromBaseTileY  = tile.TileY;
         this.toBaseTileX    = this.fromBaseTileX;
         this.toBaseTileY    = this.fromBaseTileY;
         this.useTileBitmask = false;
     }
 }
Exemple #4
0
        private void ReadSubFileParameters(ReadBuffer readBuffer, long fileSize, MapFileInfoBuilder mapFileInfoBuilder)
        {
            sbyte numberOfSubFiles = readBuffer.ReadByte();

            mapFileInfoBuilder.numberOfSubFiles = numberOfSubFiles;

            var tempSubFileParameters = new SubFileParameter[numberOfSubFiles];

            zoomLevelMinimum = sbyte.MaxValue;
            zoomLevelMaximum = sbyte.MinValue;

            for (sbyte currentSubFile = 0; currentSubFile < numberOfSubFiles; ++currentSubFile)
            {
                var subFileParameterBuilder = new SubFileParameterBuilder();

                sbyte baseZoomLevel = readBuffer.ReadByte();
                subFileParameterBuilder.BaseZoomLevel = baseZoomLevel;

                sbyte zoomLevelMin = readBuffer.ReadByte();
                subFileParameterBuilder.ZoomLevelMin = zoomLevelMin;

                sbyte zoomLevelMax = readBuffer.ReadByte();
                subFileParameterBuilder.ZoomLevelMax = zoomLevelMax;

                long startAddress = readBuffer.ReadLong();
                subFileParameterBuilder.StartAddress = startAddress;

                long indexStartAddress = startAddress;
                subFileParameterBuilder.IndexStartAddress = indexStartAddress;

                long subFileSize = readBuffer.ReadLong();
                subFileParameterBuilder.SubFileSize = subFileSize;

                subFileParameterBuilder.BoundingBox = mapFileInfoBuilder.boundingBox;

                tempSubFileParameters[currentSubFile] = subFileParameterBuilder.Build();

                if (zoomLevelMinimum > tempSubFileParameters[currentSubFile].ZoomLevelMin)
                {
                    zoomLevelMinimum = tempSubFileParameters[currentSubFile].ZoomLevelMin;
                    mapFileInfoBuilder.zoomLevelMin = zoomLevelMinimum;
                }
                if (zoomLevelMaximum < tempSubFileParameters[currentSubFile].ZoomLevelMax)
                {
                    zoomLevelMaximum = tempSubFileParameters[currentSubFile].ZoomLevelMax;
                    mapFileInfoBuilder.zoomLevelMax = zoomLevelMaximum;
                }
            }

            subFileParameters = new SubFileParameter[zoomLevelMaximum + 1];
            for (int currentMapFile = 0; currentMapFile < numberOfSubFiles; ++currentMapFile)
            {
                var subFileParameter = tempSubFileParameters[currentMapFile];
                for (sbyte zoomLevel = subFileParameter.ZoomLevelMin; zoomLevel <= subFileParameter.ZoomLevelMax; ++zoomLevel)
                {
                    subFileParameters[zoomLevel] = subFileParameter;
                }
            }
        }
Exemple #5
0
 public static void calculateBlocks(QueryParameters queryParameters, SubFileParameter subFileParameter)
 {
     // calculate the blocks in the file which need to be read
     queryParameters.fromBlockX = Math.Max(queryParameters.fromBaseTileX - subFileParameter.BoundaryTileLeft, 0);
     queryParameters.fromBlockY = Math.Max(queryParameters.fromBaseTileY - subFileParameter.BoundaryTileTop, 0);
     queryParameters.toBlockX   = Math.Min(queryParameters.toBaseTileX - subFileParameter.BoundaryTileLeft, subFileParameter.BlocksWidth - 1);
     queryParameters.toBlockY   = Math.Min(queryParameters.toBaseTileY - subFileParameter.BoundaryTileTop, subFileParameter.BlocksHeight - 1);
 }
Exemple #6
0
 public virtual void CalculateBlocks(SubFileParameter subFileParameter)
 {
     // calculate the blocks in the file which need to be read
     this.fromBlockX = Math.Max(this.fromBaseTileX - subFileParameter.BoundaryTileLeft, 0);
     this.fromBlockY = Math.Max(this.fromBaseTileY - subFileParameter.BoundaryTileTop, 0);
     this.toBlockX   = Math.Min(this.toBaseTileX - subFileParameter.BoundaryTileLeft, subFileParameter.BlocksWidth - 1);
     this.toBlockY   = Math.Min(this.toBaseTileY - subFileParameter.BoundaryTileTop, subFileParameter.BlocksHeight - 1);
 }
        private PoiWayBundle ProcessBlock(QueryParameters queryParameters, SubFileParameter subFileParameter, BoundingBox boundingBox, double tileLatitude, double tileLongitude, ReadBuffer readBuffer)
        {
            if (!ProcessBlockSignature(readBuffer))
            {
                return(null);
            }

            int[][] zoomTable            = ReadZoomTable(subFileParameter, readBuffer);
            int     zoomTableRow         = queryParameters.queryZoomLevel - subFileParameter.ZoomLevelMin;
            int     poisOnQueryZoomLevel = zoomTable[zoomTableRow][0];
            int     waysOnQueryZoomLevel = zoomTable[zoomTableRow][1];

            // get the relative offset to the first stored way in the block
            int firstWayOffset = readBuffer.ReadUnsignedInt();

            if (firstWayOffset < 0)
            {
                Logger.Log(LogLevel.Warning, INVALID_FIRST_WAY_OFFSET + firstWayOffset);
                return(null);
            }

            // add the current buffer position to the relative first way offset
            firstWayOffset += readBuffer.BufferPosition;
            if (firstWayOffset > readBuffer.BufferSize)
            {
                Logger.Log(LogLevel.Warning, INVALID_FIRST_WAY_OFFSET + firstWayOffset);
                return(null);
            }

            bool filterRequired = queryParameters.queryZoomLevel > subFileParameter.BaseZoomLevel;

            IList <PointOfInterest> pois = ProcessPOIs(tileLatitude, tileLongitude, poisOnQueryZoomLevel, boundingBox, filterRequired, readBuffer);

            if (pois == null)
            {
                return(null);
            }

            // finished reading POIs, check if the current buffer position is valid
            if (readBuffer.BufferPosition > firstWayOffset)
            {
                Logger.Log(LogLevel.Warning, "invalid buffer position: " + readBuffer.BufferPosition);
                return(null);
            }

            // move the pointer to the first way
            readBuffer.BufferPosition = firstWayOffset;

            IList <Way> ways = ProcessWays(queryParameters, waysOnQueryZoomLevel, boundingBox, filterRequired, tileLatitude, tileLongitude, readBuffer);

            if (ways == null)
            {
                return(null);
            }

            return(new PoiWayBundle(pois, ways));
        }
Exemple #8
0
        private NodeWayBundle ProcessBlock(QueryParameters queryParameters, SubFileParameter subFileParameter)
        {
            if (!processBlockSignature())
            {
                return(null);
            }

            ZoomTable zoomTable = readZoomTable(subFileParameter);

            if (zoomTable == null)
            {
                return(null);
            }
            int zoomTableRow          = queryParameters.queryZoomLevel - subFileParameter.ZoomLevelMin;
            int nodesOnQueryZoomLevel = zoomTable[zoomTableRow].NodesCount;
            int waysOnQueryZoomLevel  = zoomTable[zoomTableRow].WaysCount;

            // get the relative offset to the first stored way in the block
            long firstWayOffset = this.readBuffer.ReadUnsignedInt();

            if (firstWayOffset < 0)
            {
                return(null);
            }

            // add the current buffer position to the relative first way offset
            firstWayOffset += this.readBuffer.Position;
            if (firstWayOffset > this.readBuffer.Length)
            {
                return(null);
            }

            List <Node> nodes = processNodes(nodesOnQueryZoomLevel);

            if (nodes == null)
            {
                return(null);
            }

            // finished reading nodes, check if the current buffer position is valid
            if (this.readBuffer.Position > firstWayOffset)
            {
                return(null);
            }

            // move the pointer to the first way
            this.readBuffer.Position = firstWayOffset;

            List <Way> ways = processWays(queryParameters, waysOnQueryZoomLevel);

            if (ways == null)
            {
                return(null);
            }

            return(new NodeWayBundle(this.tile, nodes, ways));
        }
Exemple #9
0
        /// <summary>
        /// Returns the index entry of a block in the given map file. If the required index entry is not cached, it will be
        /// read from the map file index and put in the cache.
        /// </summary>
        /// <param name="subFileParameter">
        ///            the parameters of the map file for which the index entry is needed. </param>
        /// <param name="blockNumber">
        ///            the number of the block in the map file. </param>
        /// <returns> the index entry. </returns>
        /// <exception cref="IOException">
        ///             if an I/O error occurs during reading. </exception>
        internal virtual long GetIndexEntry(SubFileParameter subFileParameter, long blockNumber)
        {
            // check if the block number is out of bounds
            if (blockNumber >= subFileParameter.NumberOfBlocks)
            {
                throw new IOException("invalid block number: " + blockNumber);
            }

            // calculate the index block number
            long indexBlockNumber = blockNumber / INDEX_ENTRIES_PER_BLOCK;

            // create the cache entry key for this request
            IndexCacheEntryKey indexCacheEntryKey = new IndexCacheEntryKey(subFileParameter, indexBlockNumber);

            // check for cached index block
            byte[] indexBlock = this.map.Get(indexCacheEntryKey);
            if (indexBlock == null)
            {
                // cache miss, seek to the correct index block in the file and read it
                long indexBlockPosition = subFileParameter.IndexStartAddress + indexBlockNumber * SIZE_OF_INDEX_BLOCK;

                int remainingIndexSize = (int)(subFileParameter.IndexEndAddress - indexBlockPosition);
                int indexBlockSize     = Math.Min(SIZE_OF_INDEX_BLOCK, remainingIndexSize);
                indexBlock = new byte[indexBlockSize];

                lock (sync)
                {
                    this.randomAccessFile.Seek(indexBlockPosition, SeekOrigin.Begin);
                    if (this.randomAccessFile.Read(indexBlock, 0, indexBlockSize) != indexBlockSize)
                    {
                        throw new IOException("could not read index block with size: " + indexBlockSize);
                    }
                }

                // put the index block in the map
                this.map.Add(indexCacheEntryKey, indexBlock);
            }

            // calculate the address of the index entry inside the index block
            long indexEntryInBlock   = blockNumber % INDEX_ENTRIES_PER_BLOCK;
            int  addressInIndexBlock = (int)(indexEntryInBlock * SubFileParameter.BYTES_PER_INDEX_ENTRY);

            // return the real index entry
            return(Deserializer.GetFiveBytesLong((sbyte[])(Array)indexBlock, addressInIndexBlock));
        }
Exemple #10
0
        /**
         * Returns the index entry of a block in the given map file. If the required index entry is not cached, it will be
         * read from the map file index and put in the cache.
         *
         * @param subFileParameter
         *            the parameters of the map file for which the index entry is needed.
         * @param blockNumber
         *            the number of the block in the map file.
         * @return the index entry.
         * @throws IOException
         *             if an I/O error occurs during reading.
         */
        public long getIndexEntry(SubFileParameter subFileParameter, long blockNumber)
        {
            // check if the block number is out of bounds
            if (blockNumber >= subFileParameter.NumberOfBlocks)
            {
                throw new IOException("invalid block number: " + blockNumber);
            }

            // calculate the index block number
            long indexBlockNumber = blockNumber / INDEX_ENTRIES_PER_BLOCK;

            // create the cache entry key for this request
            IndexCacheEntryKey indexCacheEntryKey = new IndexCacheEntryKey(subFileParameter, indexBlockNumber);

            // check for cached index block
            byte[] indexBlock;
            if (!this.map.TryGetValue(indexCacheEntryKey, out indexBlock))
            {
                // cache miss, seek to the correct index block in the file and read it
                long indexBlockPosition = subFileParameter.IndexStartAddress + indexBlockNumber * SIZE_OF_INDEX_BLOCK;

                int remainingIndexSize = (int)(subFileParameter.IndexEndAddress - indexBlockPosition);
                int indexBlockSize     = Math.Min(SIZE_OF_INDEX_BLOCK, remainingIndexSize);
                indexBlock = new byte[indexBlockSize];

                this.Stream.Seek(indexBlockPosition, SeekOrigin.Begin);
                if (this.Stream.Read(indexBlock, 0, indexBlockSize) != indexBlockSize)
                {
                    throw new IOException("could not read index block with size: " + indexBlockSize);
                }

                // put the index block in the map
                this.map.Add(indexCacheEntryKey, indexBlock);
            }

            // calculate the address of the index entry inside the index block
            long indexEntryInBlock   = blockNumber % INDEX_ENTRIES_PER_BLOCK;
            int  addressInIndexBlock = (int)(indexEntryInBlock * SubFileParameter.BytesPerIndexEntry);

            // return the real index entry
            return(Deserializer.GetLong(indexBlock, addressInIndexBlock, SubFileParameter.BytesPerIndexEntry));
        }
Exemple #11
0
        private int[][] ReadZoomTable(SubFileParameter subFileParameter)
        {
            int rows = subFileParameter.ZoomLevelMax - subFileParameter.ZoomLevelMin + 1;

//JAVA TO C# CONVERTER NOTE: The following call to the 'RectangularArrays' helper class reproduces the rectangular array initialization that is automatic in Java:
//ORIGINAL LINE: int[][] zoomTable = new int[rows][2];
            int[][] zoomTable = RectangularArrays.ReturnRectangularIntArray(rows, 2);

            int cumulatedNumberOfPois = 0;
            int cumulatedNumberOfWays = 0;

            for (int row = 0; row < rows; ++row)
            {
                cumulatedNumberOfPois += this.readBuffer.ReadUnsignedInt();
                cumulatedNumberOfWays += this.readBuffer.ReadUnsignedInt();

                zoomTable[row][0] = cumulatedNumberOfPois;
                zoomTable[row][1] = cumulatedNumberOfWays;
            }

            return(zoomTable);
        }
Exemple #12
0
        /**
         * Reads all map data for the area covered by the given tile at the tile zoom level.
         *
         * @param tile
         *            defines area and zoom level of read map data.
         * @return the read map data.
         */
        public IMapReadResult ReadMapData(Tile tile)
        {
            try {
                prepareExecution();
                QueryParameters queryParameters = new QueryParameters();
                queryParameters.queryZoomLevel = this.mapFileHeader.getQueryZoomLevel(tile.ZoomFactor);

                // get and check the sub-file for the query zoom level
                SubFileParameter subFileParameter = this.mapFileHeader.getSubFileParameter(queryParameters.queryZoomLevel);
                if (subFileParameter == null)
                {
                    return(null);
                }

                QueryCalculations.calculateBaseTiles(queryParameters, tile, subFileParameter);
                QueryCalculations.calculateBlocks(queryParameters, subFileParameter);

                return(processBlocks(queryParameters, subFileParameter));
            } catch (IOException e) {
                return(null);
            }
        }
Exemple #13
0
        private ZoomTable readZoomTable(SubFileParameter subFileParameter)
        {
            int       rows      = subFileParameter.ZoomLevelMax - subFileParameter.ZoomLevelMin + 1;
            ZoomTable zoomTable = new ZoomTable(rows);

            int cumulatedNumberOfnodes = 0;
            int cumulatedNumberOfWays  = 0;

            for (int row = 0; row < rows; ++row)
            {
                cumulatedNumberOfnodes += this.readBuffer.ReadUnsignedInt();
                cumulatedNumberOfWays  += this.readBuffer.ReadUnsignedInt();

                if (cumulatedNumberOfnodes < 0 || cumulatedNumberOfnodes > MAXIMUM_ZOOM_TABLE_OBJECTS)
                {
                    System.Diagnostics.Debug.WriteLine("invalid cumulated number of nodes in row " + row + ' ' + cumulatedNumberOfnodes);
                    if (this.mapFileHeader.MapFileInfo.DebugFile)
                    {
                        System.Diagnostics.Debug.WriteLine(DEBUG_SIGNATURE_BLOCK + this.signatureBlock);
                    }
                    return(null);
                }
                else if (cumulatedNumberOfWays < 0 || cumulatedNumberOfWays > MAXIMUM_ZOOM_TABLE_OBJECTS)
                {
                    System.Diagnostics.Debug.WriteLine("invalid cumulated number of ways in row " + row + ' ' + cumulatedNumberOfWays);
                    if (this.mapFileHeader.MapFileInfo.DebugFile)
                    {
                        System.Diagnostics.Debug.WriteLine(DEBUG_SIGNATURE_BLOCK + this.signatureBlock);
                    }
                    return(null);
                }

                zoomTable[row] = new ZoomTable.ZoomTableEntry(cumulatedNumberOfnodes, cumulatedNumberOfWays);
            }

            return(zoomTable);
        }
        private int[][] ReadZoomTable(SubFileParameter subFileParameter, ReadBuffer readBuffer)
        {
            int rows = subFileParameter.ZoomLevelMax - subFileParameter.ZoomLevelMin + 1;

            int[][] zoomTable = new int[rows][];
            for (int array1 = 0; array1 < rows; array1++)
            {
                zoomTable[array1] = new int[2];
            }

            int cumulatedNumberOfPois = 0;
            int cumulatedNumberOfWays = 0;

            for (int row = 0; row < rows; ++row)
            {
                cumulatedNumberOfPois += readBuffer.ReadUnsignedInt();
                cumulatedNumberOfWays += readBuffer.ReadUnsignedInt();

                zoomTable[row][0] = cumulatedNumberOfPois;
                zoomTable[row][1] = cumulatedNumberOfWays;
            }

            return(zoomTable);
        }
        private void ReadSubFileParameters(ReadBuffer readBuffer, long fileSize, MapFileInfoBuilder mapFileInfoBuilder)
        {
            // get and check the number of sub-files (1 byte)
            sbyte numberOfSubFiles = readBuffer.ReadByte();

            if (numberOfSubFiles < 1)
            {
                throw new MapFileException("invalid number of sub-files: " + numberOfSubFiles);
            }
            mapFileInfoBuilder.numberOfSubFiles = numberOfSubFiles;

            SubFileParameter[] tempSubFileParameters = new SubFileParameter[numberOfSubFiles];
            this.zoomLevelMinimum = sbyte.MaxValue;
            this.zoomLevelMaximum = sbyte.MinValue;

            // get and check the information for each sub-file
            for (sbyte currentSubFile = 0; currentSubFile < numberOfSubFiles; ++currentSubFile)
            {
                SubFileParameterBuilder subFileParameterBuilder = new SubFileParameterBuilder();

                // get and check the base zoom level (1 byte)
                sbyte baseZoomLevel = readBuffer.ReadByte();
                if (baseZoomLevel < 0 || baseZoomLevel > BASE_ZOOM_LEVEL_MAX)
                {
                    throw new MapFileException("invalid base zoom level: " + baseZoomLevel);
                }
                subFileParameterBuilder.BaseZoomLevel = baseZoomLevel;

                // get and check the minimum zoom level (1 byte)
                sbyte zoomLevelMin = readBuffer.ReadByte();
                if (zoomLevelMin < 0 || zoomLevelMin > 22)
                {
                    throw new MapFileException("invalid minimum zoom level: " + zoomLevelMin);
                }
                subFileParameterBuilder.ZoomLevelMin = zoomLevelMin;

                // get and check the maximum zoom level (1 byte)
                sbyte zoomLevelMax = readBuffer.ReadByte();
                if (zoomLevelMax < 0 || zoomLevelMax > 22)
                {
                    throw new MapFileException("invalid maximum zoom level: " + zoomLevelMax);
                }
                subFileParameterBuilder.ZoomLevelMax = zoomLevelMax;

                // check for valid zoom level range
                if (zoomLevelMin > zoomLevelMax)
                {
                    throw new MapFileException("invalid zoom level range: " + zoomLevelMin + SPACE + zoomLevelMax);
                }

                // get and check the start address of the sub-file (8 bytes)
                long startAddress = readBuffer.ReadLong();
                if (startAddress < HEADER_SIZE_MIN || startAddress >= fileSize)
                {
                    throw new MapFileException("invalid start address: " + startAddress);
                }
                subFileParameterBuilder.StartAddress = startAddress;

                long indexStartAddress = startAddress;
                if (mapFileInfoBuilder.optionalFields.IsDebugFile)
                {
                    // the sub-file has an index signature before the index
                    indexStartAddress += SIGNATURE_LENGTH_INDEX;
                }
                subFileParameterBuilder.IndexStartAddress = indexStartAddress;

                // get and check the size of the sub-file (8 bytes)
                long subFileSize = readBuffer.ReadLong();
                if (subFileSize < 1)
                {
                    throw new MapFileException("invalid sub-file size: " + subFileSize);
                }
                subFileParameterBuilder.SubFileSize = subFileSize;

                subFileParameterBuilder.BoundingBox = mapFileInfoBuilder.boundingBox;

                // add the current sub-file to the list of sub-files
                tempSubFileParameters[currentSubFile] = subFileParameterBuilder.Build();


                // update the global minimum and maximum zoom level information
                if (this.zoomLevelMinimum > tempSubFileParameters[currentSubFile].ZoomLevelMin)
                {
                    this.zoomLevelMinimum           = tempSubFileParameters[currentSubFile].ZoomLevelMin;
                    mapFileInfoBuilder.zoomLevelMin = this.zoomLevelMinimum;
                }
                if (this.zoomLevelMaximum < tempSubFileParameters[currentSubFile].ZoomLevelMax)
                {
                    this.zoomLevelMaximum           = tempSubFileParameters[currentSubFile].ZoomLevelMax;
                    mapFileInfoBuilder.zoomLevelMax = this.zoomLevelMaximum;
                }
            }

            // create and fill the lookup table for the sub-files
            this.subFileParameters = new SubFileParameter[this.zoomLevelMaximum + 1];
            for (int currentMapFile = 0; currentMapFile < numberOfSubFiles; ++currentMapFile)
            {
                SubFileParameter subFileParameter = tempSubFileParameters[currentMapFile];
                for (sbyte zoomLevel = subFileParameter.ZoomLevelMin; zoomLevel <= subFileParameter.ZoomLevelMax; ++zoomLevel)
                {
                    this.subFileParameters[zoomLevel] = subFileParameter;
                }
            }
        }
 /// <summary>
 /// Creates an immutable key to be stored in a map.
 /// </summary>
 /// <param name="subFileParameter">
 ///            the parameters of the map file. </param>
 /// <param name="indexBlockNumber">
 ///            the number of the index block. </param>
 internal IndexCacheEntryKey(SubFileParameter subFileParameter, long indexBlockNumber)
 {
     this.subFileParameter = subFileParameter;
     this.indexBlockNumber = indexBlockNumber;
     this.hashCodeValue    = CalculateHashCode();
 }
Exemple #17
0
        private MapReadResult processBlocks(QueryParameters queryParameters, SubFileParameter subFileParameter)
        {
            bool queryIsWater       = true;
            bool queryReadWaterInfo = false;

            MapReadResultBuilder mapReadResultBuilder = new MapReadResultBuilder();

            // read and process all blocks from top to bottom and from left to right
            for (long row = queryParameters.fromBlockY; row <= queryParameters.toBlockY; ++row)
            {
                for (long column = queryParameters.fromBlockX; column <= queryParameters.toBlockX; ++column)
                {
                    // calculate the actual block number of the needed block in the file
                    long blockNumber = row * subFileParameter.BlocksWidth + column;

                    // get the current index entry
                    long currentBlockIndexEntry = this.databaseIndexCache.getIndexEntry(subFileParameter, blockNumber);

                    // check if the current query would still return a water tile
                    if (queryIsWater)
                    {
                        // check the water flag of the current block in its index entry
                        queryIsWater      &= (currentBlockIndexEntry & BITMASK_INDEX_WATER) != 0;
                        queryReadWaterInfo = true;
                    }

                    // get and check the current block pointer
                    long currentBlockpointer = currentBlockIndexEntry & BITMASK_INDEX_OFFSET;
                    if (currentBlockpointer < 1 || currentBlockpointer > subFileParameter.SubFileSize)
                    {
                        System.Diagnostics.Debug.WriteLine("invalid current block pointer: " + currentBlockpointer);
                        System.Diagnostics.Debug.WriteLine("subFileSize: " + subFileParameter.SubFileSize);
                        return(null);
                    }

                    long nextBlockpointer;
                    // check if the current block is the last block in the file
                    if (blockNumber + 1 == subFileParameter.NumberOfBlocks)
                    {
                        // set the next block pointer to the end of the file
                        nextBlockpointer = subFileParameter.SubFileSize;
                    }
                    else
                    {
                        // get and check the next block pointer
                        nextBlockpointer = this.databaseIndexCache.getIndexEntry(subFileParameter, blockNumber + 1)
                                           & BITMASK_INDEX_OFFSET;
                        if (nextBlockpointer > subFileParameter.SubFileSize)
                        {
                            System.Diagnostics.Debug.WriteLine("invalid next block pointer: " + nextBlockpointer);
                            System.Diagnostics.Debug.WriteLine("sub-file size: " + subFileParameter.SubFileSize);
                            return(null);
                        }
                    }

                    // calculate the size of the current block
                    int currentBlockSize = (int)(nextBlockpointer - currentBlockpointer);
                    if (currentBlockSize < 0)
                    {
                        System.Diagnostics.Debug.WriteLine("current block size must not be negative: " + currentBlockSize);
                        return(null);
                    }
                    else if (currentBlockSize == 0)
                    {
                        // the current block is empty, continue with the next block
                        continue;
                    }
                    else if (currentBlockSize > BufferStream.MAXIMUM_BUFFER_SIZE)
                    {
                        // the current block is too large, continue with the next block
                        System.Diagnostics.Debug.WriteLine("current block size too large: " + currentBlockSize);
                        continue;
                    }
                    else if (currentBlockpointer + currentBlockSize > this.fileSize)
                    {
                        System.Diagnostics.Debug.WriteLine("current block largher than file size: " + currentBlockSize);
                        return(null);
                    }

                    // seek to the current block in the map file
                    this.inputFile.Seek(subFileParameter.StartAddress + currentBlockpointer, SeekOrigin.Begin);

                    // read the current block into the buffer
                    if (!this.readBuffer.ReadFromFile(currentBlockSize))
                    {
                        // skip the current block
                        System.Diagnostics.Debug.WriteLine("reading current block has failed: " + currentBlockSize);
                        return(null);
                    }

                    // calculate the top-left coordinates of the underlying tile
                    this.tile = new Tile(
                        subFileParameter.BoundaryTileLeft + column,
                        subFileParameter.BoundaryTileTop + row,
                        subFileParameter.BaseZoomLevel,
                        Projection.TileSize
                        );
                    this.tilePosition = Projection.MappointToGeoPoint(tile.MapPoint1);

                    try {
                        NodeWayBundle nodeWayBundle = ProcessBlock(queryParameters, subFileParameter);
                        mapReadResultBuilder.Add(nodeWayBundle);
                    } catch (IndexOutOfRangeException e) {
                        System.Diagnostics.Debug.WriteLine(e.Message);
                    }
                }
            }

            // the query is finished, was the water flag set for all blocks?
            if (queryIsWater && queryReadWaterInfo)
            {
                mapReadResultBuilder.isWater = true;
            }

            return(mapReadResultBuilder.build());
        }
        private MapReadResult ProcessBlocks(QueryParameters queryParameters, SubFileParameter subFileParameter, BoundingBox boundingBox)
        {
            bool queryIsWater       = true;
            bool queryReadWaterInfo = false;

            MapReadResult mapFileReadResult = new MapReadResult();

            // read and process all blocks from top to bottom and from left to right
            for (long row = queryParameters.fromBlockY; row <= queryParameters.toBlockY; ++row)
            {
                for (long column = queryParameters.fromBlockX; column <= queryParameters.toBlockX; ++column)
                {
                    // calculate the actual block number of the needed block in the file
                    long blockNumber = row * subFileParameter.BlocksWidth + column;

                    // get the current index entry
                    long currentBlockIndexEntry = this.databaseIndexCache.GetIndexEntry(subFileParameter, blockNumber);

                    // check if the current query would still return a water tile
                    if (queryIsWater)
                    {
                        // check the water flag of the current block in its index entry
                        queryIsWater      &= (currentBlockIndexEntry & BITMASK_INDEX_WATER) != 0;
                        queryReadWaterInfo = true;
                    }

                    // get and check the current block pointer
                    long currentBlockPointer = currentBlockIndexEntry & BITMASK_INDEX_OFFSET;
                    if (currentBlockPointer < 1 || currentBlockPointer > subFileParameter.SubFileSize)
                    {
                        Logger.Log(LogLevel.Warning, "invalid current block pointer: " + currentBlockPointer);
                        Logger.Log(LogLevel.Warning, "subFileSize: " + subFileParameter.SubFileSize);
                        return(null);
                    }

                    long nextBlockPointer;
                    // check if the current block is the last block in the file
                    if (blockNumber + 1 == subFileParameter.NumberOfBlocks)
                    {
                        // set the next block pointer to the end of the file
                        nextBlockPointer = subFileParameter.SubFileSize;
                    }
                    else
                    {
                        // get and check the next block pointer
                        nextBlockPointer = this.databaseIndexCache.GetIndexEntry(subFileParameter, blockNumber + 1) & BITMASK_INDEX_OFFSET;
                        if (nextBlockPointer > subFileParameter.SubFileSize)
                        {
                            Logger.Log(LogLevel.Warning, "invalid next block pointer: " + nextBlockPointer);
                            Logger.Log(LogLevel.Warning, "sub-file size: " + subFileParameter.SubFileSize);
                            return(null);
                        }
                    }

                    // calculate the size of the current block
                    int currentBlockSize = (int)(nextBlockPointer - currentBlockPointer);
                    if (currentBlockSize < 0)
                    {
                        Logger.Log(LogLevel.Warning, "current block size must not be negative: " + currentBlockSize);
                        return(null);
                    }
                    else if (currentBlockSize == 0)
                    {
                        // the current block is empty, continue with the next block
                        continue;
                    }
                    else if (currentBlockSize > ReadBuffer.MaximumBufferSize)
                    {
                        // the current block is too large, continue with the next block
                        Logger.Log(LogLevel.Warning, "current block size too large: " + currentBlockSize);
                        continue;
                    }
                    else if (currentBlockPointer + currentBlockSize > this.fileSize)
                    {
                        Logger.Log(LogLevel.Warning, "current block largher than file size: " + currentBlockSize);
                        return(null);
                    }

                    // read the current block into the buffer
                    ReadBuffer readBuffer = new ReadBuffer(inputStream);
                    if (!readBuffer.ReadFromStream(subFileParameter.StartAddress + currentBlockPointer, currentBlockSize))
                    {
                        // skip the current block
                        Logger.Log(LogLevel.Warning, "reading current block has failed: " + currentBlockSize);
                        return(null);
                    }

                    // calculate the top-left coordinates of the underlying tile
                    double tileLatitude  = MercatorProjection.TileYToLatitude(subFileParameter.BoundaryTileTop + row, subFileParameter.BaseZoomLevel);
                    double tileLongitude = MercatorProjection.TileXToLongitude(subFileParameter.BoundaryTileLeft + column, subFileParameter.BaseZoomLevel);

                    try
                    {
                        PoiWayBundle poiWayBundle = ProcessBlock(queryParameters, subFileParameter, boundingBox, tileLatitude, tileLongitude, readBuffer);
                        if (poiWayBundle != null)
                        {
                            mapFileReadResult.Add(poiWayBundle);
                        }
                    }
                    catch (System.IndexOutOfRangeException e)
                    {
                        Logger.Log(LogLevel.Error, e.Message, e);
                    }
                }
            }

            // the query is finished, was the water flag set for all blocks?
            if (queryIsWater && queryReadWaterInfo)
            {
                // Deprecate water tiles rendering
                // mapFileReadResult.IsWater = true;
            }

            return(mapFileReadResult);
        }
Exemple #19
0
 public static void calculateBaseTiles(QueryParameters queryParameters, Tile tile, SubFileParameter subFileParameter)
 {
     if (tile.ZoomFactor < subFileParameter.BaseZoomLevel)
     {
         // calculate the XY numbers of the upper left and lower right sub-tiles
         int zoomLevelDifference = subFileParameter.BaseZoomLevel - tile.ZoomFactor;
         queryParameters.fromBaseTileX  = tile.TileX << zoomLevelDifference;
         queryParameters.fromBaseTileY  = tile.TileY << zoomLevelDifference;
         queryParameters.toBaseTileX    = queryParameters.fromBaseTileX + (1 << zoomLevelDifference) - 1;
         queryParameters.toBaseTileY    = queryParameters.fromBaseTileY + (1 << zoomLevelDifference) - 1;
         queryParameters.useTileBitmask = false;
     }
     else if (tile.ZoomFactor > subFileParameter.BaseZoomLevel)
     {
         // calculate the XY numbers of the parent base tile
         int zoomLevelDifference = tile.ZoomFactor - subFileParameter.BaseZoomLevel;
         queryParameters.fromBaseTileX    = tile.TileX >> zoomLevelDifference;
         queryParameters.fromBaseTileY    = tile.TileY >> zoomLevelDifference;
         queryParameters.toBaseTileX      = queryParameters.fromBaseTileX;
         queryParameters.toBaseTileY      = queryParameters.fromBaseTileY;
         queryParameters.useTileBitmask   = true;
         queryParameters.queryTileBitmask = calculateTileBitmask(tile, zoomLevelDifference);
     }
     else
     {
         // use the tile XY numbers of the requested tile
         queryParameters.fromBaseTileX  = tile.TileX;
         queryParameters.fromBaseTileY  = tile.TileY;
         queryParameters.toBaseTileX    = queryParameters.fromBaseTileX;
         queryParameters.toBaseTileY    = queryParameters.fromBaseTileY;
         queryParameters.useTileBitmask = false;
     }
 }