// <summary> #region ILayer Members /// <summary> /// Renders the layer /// </summary> /// <param name="g">Graphics object reference</param> /// <param name="map">Map which is rendered</param> public override void Render(Graphics g, Map map) { Bitmap bitmap = null; try { foreach (string key in _TileSetsActive) { TileSet tileSet = _TileSets[key]; tileSet.Verify(); List <Envelope> tileExtents = TileExtents.GetTileExtents(tileSet, map.Envelope, map.PixelSize); if (logger.IsDebugEnabled) { logger.DebugFormat("TileCount: {0}", tileExtents.Count); } //TODO: Retrieve several tiles at the same time asynchronously to improve performance. PDD. foreach (Envelope tileExtent in tileExtents) { if (bitmap != null) { bitmap.Dispose(); } if ((tileSet.TileCache != null) && (tileSet.TileCache.ContainsTile(tileExtent))) { bitmap = tileSet.TileCache.GetTile(tileExtent); } else { bitmap = WmsGetMap(tileExtent, tileSet); if ((tileSet.TileCache != null) && (bitmap != null)) { tileSet.TileCache.AddTile(tileExtent, bitmap); } } if (bitmap != null) { PointF destMin = Transform.WorldtoMap(tileExtent.Min(), map); PointF destMax = Transform.WorldtoMap(tileExtent.Max(), map); double minX = (int)Math.Round(destMin.X); double minY = (int)Math.Round(destMax.Y); double maxX = (int)Math.Round(destMax.X); double maxY = (int)Math.Round(destMin.Y); g.DrawImage(bitmap, new Rectangle((int)minX, (int)minY, (int)(maxX - minX), (int)(maxY - minY)), 0, 0, tileSet.Width, tileSet.Height, GraphicsUnit.Pixel, _ImageAttributes); } } } } finally { if (bitmap != null) { bitmap.Dispose(); } } }
// <summary> /// Renders the layer /// </summary> /// <param name="g">Graphics object reference</param> /// <param name="map">Map which is rendered</param> public override void Render(System.Drawing.Graphics g, Map map) { System.Drawing.Bitmap bitmap = null; try { foreach (string key in _TileSetsActive) { TileSet tileSet = _TileSets[key]; tileSet.Verify(); List <BoundingBox> tileExtents = TileExtents.GetTileExtents(tileSet, map.Envelope, map.PixelSize); //TODO: Retrieve several tiles at the same time asynchronously to improve performance. PDD. foreach (BoundingBox tileExtent in tileExtents) { if (bitmap != null) { bitmap.Dispose(); } if ((tileSet.TileCache != null) && (tileSet.TileCache.ContainsTile(tileExtent))) { bitmap = tileSet.TileCache.GetTile(tileExtent); } else { bitmap = WmsGetMap(tileExtent, tileSet); if ((tileSet.TileCache != null) && (bitmap != null)) { tileSet.TileCache.AddTile(tileExtent, bitmap); } } if (bitmap != null) { PointF destMin = SharpMap.Utilities.Transform.WorldtoMap(tileExtent.Min, map); PointF destMax = SharpMap.Utilities.Transform.WorldtoMap(tileExtent.Max, map); #region Comment on BorderBug correction // Even when tiles border to one another without any space between them there are // seams visible between the tiles in the map image. // This problem could be resolved with the solution suggested here: // http://www.codeproject.com/csharp/BorderBug.asp // The suggested correction value of 0.5f still results in seams in some cases, not so with 0.4999f. // Also it was necessary to apply Math.Round and Math.Ceiling on the destination rectangle. // PDD. #endregion float correction = 0.4999f; RectangleF srcRect = new RectangleF(0 - correction, 0 - correction, tileSet.Width, tileSet.Height); InterpolationMode tempInterpolationMode = g.InterpolationMode; g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor; //TODO: Allow custom image attributes for each TileSet. int x = (int)Math.Round(destMin.X); int y = (int)Math.Round(destMax.Y); int width = (int)Math.Round(destMax.X - x); int height = (int)Math.Round(destMin.Y - y); g.DrawImage(bitmap, new Rectangle(x, y, width, height), srcRect.Left, srcRect.Top, srcRect.Width, srcRect.Height, GraphicsUnit.Pixel, _ImageAttributes); g.InterpolationMode = tempInterpolationMode; //Put InterpolationMode back so drawing of other layers is not affected. } } } } finally { if (bitmap != null) { bitmap.Dispose(); } } }