/// <summary> /// Create an image for this layer by stitching together tile images. /// </summary> /// <param name="oLayerBoundingBox"> /// The bounding box for the layer. Tiles outside this bounding box will not be drawn. /// </param> /// <param name="oViewBoundingBox"> /// The bounding box of the view. The resulting image will be scaled and /// cropped to fill this view. /// </param> /// <returns>The raw data of the composed image.</returns> public byte[] GetCompositeImage(BoundingBox oLayerBoundingBox, BoundingBox oViewBoundingBox) { if (!oLayerBoundingBox.Intersects(oViewBoundingBox)) return BlankImageBytes(); BoundingBox visibleDataBounds = oLayerBoundingBox.IntersectWith(oViewBoundingBox); //bool moreDataComing = false; TileSet oRequiredTiles = new TileSet(visibleDataBounds, TileSet.GetLevel(oViewBoundingBox)); TileSet oServiceTiles = oRequiredTiles; // --- Keep going to lower-levelled tiles until we can service the request --- System.Diagnostics.Debug.WriteLine("Requesting composite image at level " + oServiceTiles.Level); while (oServiceTiles.Level > 0 && !oServiceTiles.IsCached(this, oLayerBoundingBox)) { oRequiredTiles = oServiceTiles; oServiceTiles = new TileSet(visibleDataBounds, oServiceTiles.Level - 1); //moreDataComing = true; System.Diagnostics.Debug.WriteLine("Decrementing level to " + oServiceTiles.Level); } // --- Queue up the other images for the request --- if (!oRequiredTiles.IsCached(this, oLayerBoundingBox)) { DownloadSet oRequiredDownloads = new DownloadSet(this, oRequiredTiles, oLayerBoundingBox); oRequiredDownloads.DownloadAsync(new EventHandler(oRequiredDownloads_DownloadComplete)); } // --- Compose image tiles to master tile --- Bitmap composite = ComposeImageFromTileCache(oServiceTiles); BoundingBox compositeBounds = oServiceTiles.Bounds; double degreesPerPixel = TileInfo.GetTileSize(oServiceTiles.Level) / TileInfo.TileSizePixels; // --- Render the image for the tile level requested --- Bitmap result = new Bitmap((int)((oViewBoundingBox.MaxX - oViewBoundingBox.MinX) / degreesPerPixel), (int)((oViewBoundingBox.MaxY - oViewBoundingBox.MinY) / degreesPerPixel)); BoundingBox resultBounds = new BoundingBox(oViewBoundingBox); using (Graphics g = Graphics.FromImage(result)) { g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; g.DrawImage(composite, new PointF((float)((compositeBounds.MinX - resultBounds.MinX) / degreesPerPixel), (float)((resultBounds.MaxY - compositeBounds.MaxY) / degreesPerPixel))); //if (moreDataComing) // g.FillRectangle(new System.Drawing.Drawing2D.HatchBrush(System.Drawing.Drawing2D.HatchStyle.Percent05, Color.Green, Color.Transparent), 0, 0, result.Width, result.Height); } result.Save("C:/documents and settings/chrismac/desktop/sent.png", System.Drawing.Imaging.ImageFormat.Png); MemoryStream buffer = new MemoryStream(); result.Save(buffer, System.Drawing.Imaging.ImageFormat.Png); return buffer.ToArray(); }