Beispiel #1
0
        private static void DrawWebMercatorTilesToRasterCanvas(
            SKCanvas outputCanvas,
            int width,
            int height,
            Models.Bounds boundingBox,
            IList <Models.TileDataset> sourceTiles,
            uint backgroundColor,
            int tileSize)
        {
            var zoom         = sourceTiles[0].Z;
            var tileMinX     = sourceTiles.Min(t => t.X);
            var tileMinY     = sourceTiles.Min(t => t.Y);
            var tilesCountX  = sourceTiles.Max(t => t.X) - tileMinX + 1;
            var tilesCountY  = sourceTiles.Max(t => t.Y) - tileMinY + 1;
            var canvasWidth  = tilesCountX * tileSize;
            var canvasHeight = tilesCountY * tileSize;

            var imageInfo = new SKImageInfo(
                width: canvasWidth,
                height: canvasHeight,
                colorType: SKColorType.Rgba8888,
                alphaType: SKAlphaType.Premul);

            using var surface = SKSurface.Create(imageInfo);
            using var canvas  = surface.Canvas;
            canvas.Clear(new SKColor(backgroundColor));

            // Draw all tiles
            foreach (var sourceTile in sourceTiles)
            {
                var offsetX = (sourceTile.X - tileMinX) * tileSize;
                var offsetY = (sourceTile.Y - tileMinY) * tileSize;
                using var sourceImage = SKImage.FromEncodedData(sourceTile.ImageData);
                canvas.DrawImage(sourceImage, SKRect.Create(offsetX, offsetY, tileSize, tileSize)); // Source tile scaled to dest rectangle, if needed
            }

            // Clip and scale to requested size of output image
            var geoBBox         = EntitiesConverter.MapRectangleToGeographicalBounds(boundingBox);
            var pixelOffsetX    = WebMercator.LongitudeToPixelXAtZoom(geoBBox.MinLongitude, zoom) - tileSize * tileMinX;
            var pixelOffsetY    = WebMercator.LatitudeToPixelYAtZoom(geoBBox.MaxLatitude, zoom) - tileSize * tileMinY;
            var pixelWidth      = WebMercator.LongitudeToPixelXAtZoom(geoBBox.MaxLongitude, zoom) - WebMercator.LongitudeToPixelXAtZoom(geoBBox.MinLongitude, zoom);
            var pixelHeight     = WebMercator.LatitudeToPixelYAtZoom(geoBBox.MinLatitude, zoom) - WebMercator.LatitudeToPixelYAtZoom(geoBBox.MaxLatitude, zoom);
            var sourceRectangle = SKRect.Create((float)pixelOffsetX, (float)pixelOffsetY, (float)pixelWidth, (float)pixelHeight);
            var destRectangle   = SKRect.Create(0, 0, width, height);

            using SKImage canvasImage = surface.Snapshot();
            outputCanvas.DrawImage(canvasImage, sourceRectangle, destRectangle, new SKPaint {
                FilterQuality = SKFilterQuality.High,
            });
        }