Beispiel #1
0
        private static double calculatePriority(Tile tile, MapPosition mapPosition, int tileSize)
        {
            double tileLatitude  = MercatorProjection.TileYToLatitude(tile.TileY, tile.ZoomLevel);
            double tileLongitude = MercatorProjection.TileXToLongitude(tile.TileX, tile.ZoomLevel);

            int    halfTileSize = tileSize / 2;
            long   mapSize      = MercatorProjection.GetMapSize(mapPosition.ZoomLevel, tileSize);
            double tilePixelX   = MercatorProjection.LongitudeToPixelX(tileLongitude, mapSize) + halfTileSize;
            double tilePixelY   = MercatorProjection.LatitudeToPixelY(tileLatitude, mapSize) + halfTileSize;

            LatLong latLong   = mapPosition.LatLong;
            double  mapPixelX = MercatorProjection.LongitudeToPixelX(latLong.Longitude, mapSize);
            double  mapPixelY = MercatorProjection.LatitudeToPixelY(latLong.Latitude, mapSize);

            double diffPixel = Math.Sqrt(Math.Pow(tilePixelX - mapPixelX, 2) + Math.Pow(tilePixelY - mapPixelY, 2));
            int    diffZoom  = Math.Abs(tile.ZoomLevel - mapPosition.ZoomLevel);

            return(diffPixel + PENALTY_PER_ZOOM_LEVEL * tileSize * diffZoom);
        }
Beispiel #2
0
        public virtual void WithDataTest()
        {
            MapFile mapFile = new MapFile(EmbeddedResourceLoader.Load("Resources.WithData.output.map", this.GetType()));

            MapFileInfo mapFileInfo = mapFile.MapFileInfo;

            Assert.True(mapFileInfo.DebugFile);

            for (sbyte zoomLevel = ZOOM_LEVEL_MIN; zoomLevel <= ZOOM_LEVEL_MAX; ++zoomLevel)
            {
                Point poi = new Point(0.04, 0.04);

                int tileX = MercatorProjection.LongitudeToTileX(0.04, zoomLevel);
                int tileY = MercatorProjection.LatitudeToTileY(0.04, zoomLevel);

                Tile tile = new Tile(tileX, tileY, zoomLevel);

                double lonMin = MercatorProjection.TileXToLongitude(tileX, zoomLevel);
                double lonMax = MercatorProjection.TileXToLongitude(tileX + 1, zoomLevel);
                double latMin = MercatorProjection.TileYToLatitude(tileY + 1, zoomLevel);
                double latMax = MercatorProjection.TileYToLatitude(tileY, zoomLevel);

                //tile.Index = new TileIndex(tileX, tileY, zoomLevel.ToString());
                //tile.Extent = new Extent(lonMin, latMin, lonMax, latMax);

                MapReadResult mapReadResult = mapFile.ReadMapData(tile);

                Assert.AreEqual(1, mapReadResult.PointOfInterests.Count);
                Assert.AreEqual(1, mapReadResult.Ways.Count);

                CheckPointOfInterest(mapReadResult.PointOfInterests[0]);
                CheckWay(mapReadResult.Ways[0]);
            }

            mapFile.Close();
        }
        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);
        }