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