private void DrawParentTileBitmap(ICanvas canvas, Point point, Tile tile) { Tile cachedParentTile = GetCachedParentTile(tile, 4); if (cachedParentTile != null) { IBitmap bitmap = this.tileCache.GetImmediately(CreateJob(cachedParentTile)); if (bitmap != null) { int tileSize = this.displayModel.TileSize; long translateX = tile.GetShiftX(cachedParentTile) * tileSize; long translateY = tile.GetShiftY(cachedParentTile) * tileSize; sbyte zoomLevelDiff = (sbyte)(tile.ZoomLevel - cachedParentTile.ZoomLevel); float scaleFactor = (float)Math.Pow(2, zoomLevelDiff); int x = (int)Math.Round(point.X); int y = (int)Math.Round(point.Y); this.matrix.Reset(); this.matrix.Translate(x - translateX, y - translateY); this.matrix.Scale(scaleFactor, scaleFactor); canvas.SetClip(x, y, this.displayModel.TileSize, this.displayModel.TileSize); canvas.DrawBitmap(bitmap, this.matrix); canvas.ResetClip(); bitmap.DecrementRefCount(); } } }
public override void Draw(BoundingBox boundingBox, sbyte zoomLevel, ICanvas canvas, Point topLeftPoint) { IList <TilePosition> tilePositions = LayerUtil.GetTilePositions(boundingBox, zoomLevel, topLeftPoint, this.displayModel.TileSize); // In a rotation situation it is possible that drawParentTileBitmap sets the // clipping bounds to portrait, while the device is just being rotated into // landscape: the result is a partially painted screen that only goes away // after zooming (which has the effect of resetting the clip bounds if drawParentTileBitmap // is called again). // Always resetting the clip bounds here seems to avoid the problem, // I assume that this is a pretty cheap operation, otherwise it would be better // to hook this into the onConfigurationChanged call chain. canvas.ResetClip(); if (!isTransparent) { canvas.FillColor(this.displayModel.BackgroundColor); } ISet <Job> jobs = new HashSet <Job>(); foreach (TilePosition tilePosition in tilePositions) { jobs.Add(CreateJob(tilePosition.Tile)); } this.tileCache.WorkingSet = jobs; for (int i = tilePositions.Count - 1; i >= 0; --i) { TilePosition tilePosition = tilePositions[i]; Point point = tilePosition.Point; Tile tile = tilePosition.Tile; T job = CreateJob(tile); ITileBitmap bitmap = this.tileCache.GetImmediately(job); if (bitmap == null) { if (this.hasJobQueue && !this.tileCache.ContainsKey(job)) { this.jobQueue.Add(job); } DrawParentTileBitmap(canvas, point, tile); } else { if (IsTileStale(tile, bitmap) && this.hasJobQueue && !this.tileCache.ContainsKey(job)) { this.jobQueue.Add(job); } RetrieveLabelsOnly(job); canvas.DrawBitmap(bitmap, (int)Math.Round(point.X), (int)Math.Round(point.Y)); bitmap.DecrementRefCount(); } } if (this.hasJobQueue) { this.jobQueue.NotifyWorkers(); } }