User Tools

Site Tools


serviceseditionsample_usinggraphicsgeocanvas_cs_120911.zip

ServicesEditionSample UsingGraphicsGeoCanvas CS 120911.zip

GraphicsGeoCanvas.cs

 using System;  
 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Text;  
 using System.Collections.ObjectModel;  
 using System.Drawing.Imaging;  
 using System.Drawing;  
 using System.Drawing.Drawing2D;  
 using System.IO;  
 using System.Reflection;  
 
 namespace ThinkGeo.MapSuite.Core  
 {  
     [Serializable]  
     public class GraphicsGeoCanvas : GeoCanvas  
     {  
         [Obfuscation(Exclude|= true)]  
         private Dictionary<DrawingLevel, Collection<Dictionary<string, object>>> featuresOrderByLevel;  
         [Obfuscation(Exclude|= true)]  
         private Dictionary<long, Font> fontCache;  
         [Obfuscation(Exclude|= true)]  
         private Dictionary<long, Brush> brushCache;  
         [Obfuscation(Exclude|= true)]  
         private Dictionary<long, Pen> penCache;  
         [Obfuscation(Exclude|= true)]  
         private Graphics graphics;  
         [Obfuscation(Exclude|= true)]  
         private const float standardDpi = 96f;  
         [Obfuscation(Exclude|= true)]  
         private bool isMeasured;  
 
         public GraphicsGeoCanvas()  
         {  
             featuresOrderByLevel = new Dictionary<DrawingLevel, Collection<Dictionary<string, object>>>();  
         }  
 
         public void BeginDrawing(object nativeImage, float width, float height, RectangleShape worldExtent, GeographyUnit drawingMapUnit)  
         {  
             IsDrawing = true;  
             this.Width = width;  
             this.Height = height;  
 
             base.BeginDrawing(nativeImage, worldExtent, drawingMapUnit);  
         }  
 
         protected override void BeginDrawingCore(object nativeImage, RectangleShape worldExtent, GeographyUnit drawingMapUnit)  
         {  
             if (Width <= 0 || Height <= 0)  
             {  
                 throw new InvalidOperationException("GraphicsGeoCanvas' Width and Height are not set, please call the overload BeginDrawing(object nativeImage, float width, float height, RectangleShape worldExtent, GeographyUnit drawingMapUnit) and pass in the graphics' width and height");  
             }  
             graphics = (Graphics)nativeImage;  
 
             CurrentWorldExtent = ExtentHelper.GetDrawingExtent(worldExtent, Width, Height);  
         }  
 
         protected override void EndDrawingCore()  
         {  
             DrawImage();  
 
             //g.DrawRectangle(new Pen(Color.Red), new Rectangle(0,0,(int)Width, (int)Height));  
 
             if (graphics != null)  
             {  
                 graphics.Flush();  
                 graphics.Dispose();  
                 graphics = null;  
             }  
 
             ClearCache();  
         }  
 
         private void DrawImage()  
         {  
             if (featuresOrderByLevel.ContainsKey(DrawingLevel.LevelOne)) { DrawLevel(featuresOrderByLevel[DrawingLevel.LevelOne]); }  
             if (featuresOrderByLevel.ContainsKey(DrawingLevel.LevelTwo)) { DrawLevel(featuresOrderByLevel[DrawingLevel.LevelTwo]); }  
             if (featuresOrderByLevel.ContainsKey(DrawingLevel.LevelThree)) { DrawLevel(featuresOrderByLevel[DrawingLevel.LevelThree]); }  
             if (featuresOrderByLevel.ContainsKey(DrawingLevel.LevelFour)) { DrawLevel(featuresOrderByLevel[DrawingLevel.LevelFour]); }  
 
             if (isMeasured)  
             {  
                 if (featuresOrderByLevel.ContainsKey(DrawingLevel.LabelLevel))  
                 {  
                     DrawLevel(featuresOrderByLevel[DrawingLevel.LabelLevel]);  
                 }  
             }  
         }  
 
         private void DrawLevel(Collection<Dictionary<string, object>> drawingItems)  
         {  
             foreach (Dictionary<string, object> item in drawingItems)  
             {  
                 switch (item["method"].ToString())  
                 {  
                     case "DrawAreaCache":  
                         DrawAreaCache((IEnumerable<ScreenPointF[]>)item["screenPoints"], (GeoPen)item["outlinePen"], (GeoBrush)item["fillBrush"], (float)item["xOffset"], (float)item["yOffset"], (PenBrushDrawingOrder)item["penBrushDrawingOrder"]);  
                         break;  
                     case "DrawLineCache":  
                         DrawLineCache((IEnumerable<ScreenPointF>)item["screenPoints"], (GeoPen)item["linePen"], (float)item["xOffset"], (float)item["yOffset"]);  
                         break;  
                     case "DrawTextCache":  
                         DrawTextCache((string)item["text"], (GeoFont)item["font"], (GeoBrush)item["fillBrush"], (GeoPen)item["haloPen"], (IEnumerable<ScreenPointF>)item["textPathInScreen"], (float)item["xOffset"], (float)item["yOffset"], (float)item["rotateAngle"]);  
                         break;  
                     case "DrawEllipseCache":  
                         DrawEllipseCache((ScreenPointF)item["screenPoint"], (float)item["width"], (float)item["height"], (GeoPen)item["outlinePen"], (GeoBrush)item["fillBrush"], (float)item["xOffset"], (float)item["yOffset"], (PenBrushDrawingOrder)item["penBrushDrawingOrder"]);  
                         break;  
                     case "DrawScreenImageWithoutScalingCache":  
                         DrawScreenImageWithoutScalingCache((GeoImage)item["image"], (float)item["centerXInScreen"], (float)item["centerYInScreen"], (float)item["xOffset"], (float)item["yOffset"], (float)item["rotateAngle"]);  
                         break;  
                     case "DrawScreenImageCache":  
                         DrawScreenImageCache((GeoImage)item["image"], (float)item["centerXInScreen"], (float)item["centerYInScreen"], (float)item["widthInScreen"], (float)item["heightInScreen"], (float)item["xOffset"], (float)item["yOffset"], (float)item["rotateAngle"]);  
                         break;  
                     default: break;  
                 }  
             }  
         }  
 
         private void DrawEllipseCache(ScreenPointF screenPoint, float width, float height, GeoPen outlinePen, GeoBrush fillBrush, float xOffset, float yOffset, PenBrushDrawingOrder penBrushDrawingOrder)  
         {  
             float screenX = (float)screenPoint.X - width * 0.5f + xOffset;  
             float screenY = (float)screenPoint.Y - height * 0.5f + yOffset;  
 
             if (penBrushDrawingOrder == PenBrushDrawingOrder.BrushFirst)  
             {  
                 if (fillBrush != null) { graphics.FillEllipse(GetGdiPlusBrushFromGeoBrush(fillBrush, new ScreenPointF[] { screenPoint }), screenX, screenY, width, height); }  
                 if (outlinePen != null) { graphics.DrawEllipse(GetGdiPlusPenFromGeoPen(outlinePen), screenX, screenY, width, height); }  
             }  
             else  
             {  
                 if (outlinePen != null) { graphics.DrawEllipse(GetGdiPlusPenFromGeoPen(outlinePen), screenX, screenY, width, height); }  
                 if (fillBrush != null) { graphics.FillEllipse(GetGdiPlusBrushFromGeoBrush(fillBrush, new ScreenPointF[] { screenPoint }), screenX, screenY, width, height); }  
             }  
         }  
 
         private void ClearCache()  
         {  
             featuresOrderByLevel.Clear();  
 
             if (brushCache != null) { brushCache.Clear(); }  
             if (penCache != null) { penCache.Clear(); }  
             if (fontCache != null) { fontCache.Clear(); }  
         }  
 
         protected override void DrawLineCore(IEnumerable<ScreenPointF> screenPoints, GeoPen linePen, DrawingLevel drawingLevel, float xOffset, float yOffset)  
         {  
             //Validators.CheckParameterIsNotNull(screenPoints, "screenPoints");  
             //Validators.CheckParameterIsNotNull(linePen, "outlinePen");  
             //Validators.CheckDrawingLevelIsValid(drawingLevel, "drawingLevel");  
             //Validators.CheckGeoCanvasIsInDrawing(IsDrawing);  
 
             if (!featuresOrderByLevel.ContainsKey(drawingLevel))  
             {  
                 featuresOrderByLevel.Add(drawingLevel, new Collection<Dictionary<string, object>>());  
             }  
 
             Dictionary<string, object> parameters = new Dictionary<string, object>();  
             parameters.Add("screenPoints", screenPoints);  
             parameters.Add("linePen", linePen);  
             parameters.Add("xOffset", xOffset);  
             parameters.Add("yOffset", yOffset);  
             parameters.Add("method", "DrawLineCache");  
 
             featuresOrderByLevel[drawingLevel].Add(parameters);  
         }  
 
         private void DrawLineCache(IEnumerable<ScreenPointF> screenPoints, GeoPen linePen, float xOffset, float yOffset)  
         {  
             List<PointF> points = new List<PointF>();  
 
             int previousX = int.MaxValue;  
             int previousY = int.MaxValue;  
 
             foreach (ScreenPointF point in screenPoints)  
             {  
                 float x = (point.X + xOffset);  
                 float y = (point.Y + yOffset);  
                 int screenX = (int)x;  
                 int screenY = (int)y;  
 
                 if (screenX < -1E+8)  
                 {  
                     screenX = (int)-1E+8;  
                 }  
 
                 if (screenX > 1E+8)  
                 {  
                     screenX = (int)1E+8;  
                 }  
 
                 if (screenY < -1E+8f)  
                 {  
                     screenY = (int)-1E+8;  
                 }  
 
                 if (screenY > 1E+8f)  
                 {  
                     screenY = (int)1E+8f;  
                 }  
 
                 if (previousX != screenX || previousY != screenY)  
                 {  
                     previousX = screenX;  
                     previousY = screenY;  
                     points.Add(new PointF(x, y));  
                 }  
             }  
 
             if (points.Count == 1)  
             {  
                 points.Add(new PointF(points[0].X + 0.1f, points[0].Y));  
             }  
 
             if (points.Count > 1)  
             {  
                 graphics.DrawLines(GetGdiPlusPenFromGeoPen(linePen), points.ToArray());  
             }  
         }  
 
         protected override void DrawAreaCore(IEnumerable<ScreenPointF[]> screenPoints, GeoPen outlinePen, GeoBrush fillBrush, DrawingLevel drawingLevel, float xOffset, float yOffset, PenBrushDrawingOrder penBrushDrawingOrder)  
         {  
             //Validators.CheckParameterIsNotNull(screenPoints, "screenPoints");  
             //Validators.CheckParameterIsNotBothNull(outlinePen, fillBrush, "outlinePen", "fillBrush");  
             //Validators.CheckDrawingLevelIsValid(drawingLevel, "drawingLevel");  
             //Validators.CheckGeoCanvasIsInDrawing(IsDrawing);  
 
             if (!featuresOrderByLevel.ContainsKey(drawingLevel))  
             {  
                 featuresOrderByLevel.Add(drawingLevel, new Collection<Dictionary<string, object>>());  
             }  
 
             Dictionary<string, object> parameters = new Dictionary<string, object>();  
             parameters.Add("screenPoints", screenPoints);  
             parameters.Add("outlinePen", outlinePen);  
             parameters.Add("fillBrush", fillBrush);  
             parameters.Add("xOffset", xOffset);  
             parameters.Add("yOffset", yOffset);  
             parameters.Add("penBrushDrawingOrder", penBrushDrawingOrder);  
             parameters.Add("method", "DrawAreaCache");  
 
             featuresOrderByLevel[drawingLevel].Add(parameters);  
         }  
 
         private void DrawAreaCache(IEnumerable<ScreenPointF[]> screenPoints, GeoPen outlinePen, GeoBrush fillBrush, float xOffset, float yOffset, PenBrushDrawingOrder penBrushDrawingOrder)  
         {  
             DrawAreaForNotHighSpeed(screenPoints, outlinePen, fillBrush, xOffset, yOffset, penBrushDrawingOrder);  
         }  
 
         private void DrawAreaForNotHighSpeed(IEnumerable<ScreenPointF[]> screenPoints, GeoPen outlinePen, GeoBrush fillBrush, float xOffset, float yOffset, PenBrushDrawingOrder penBrushDrawingOrder)  
         {  
             List<PointF[]> ringsCollection = new List<PointF[]>();  
             //ScreenPointF[] cachePoints = null;  
             Collection<ScreenPointF> cachePoints = new Collection<ScreenPointF>();  
 
             foreach (ScreenPointF[] rings in screenPoints)  
             {  
                 //if (cachePoints == null) { cachePoints = rings; }  
                 foreach (ScreenPointF pointF in rings)  
                 {  
                     cachePoints.Add(pointF);  
                 }  
 
                 PointF[] points = new PointF[rings.Length];  
                 int previousX = int.MaxValue;  
                 int previousY = int.MaxValue;  
                 int tempCount = 0;  
                 for (int i = 0; i < rings.Length; i++)  
                 {  
                     ScreenPointF point = rings[i];  
                     float screenX = (float)(point.X + xOffset);  
                     float screenY = (float)(point.Y + yOffset);  
                     if (previousX != (int)screenX || previousY != (int)screenY)  
                     {  
                         previousX = (int)screenX;  
                         previousY = (int)screenY;  
                         points[tempCount] = new PointF(screenX, screenY);  
                         tempCount++;  
                     }  
                 }  
                 if (tempCount <= 2) { continue; }  
                 if (tempCount != rings.Length)  
                 {  
                     Array.Resize<PointF>(ref points, tempCount);  
                 }  
                 ringsCollection.Add(points);  
             }  
 
             int count = ringsCollection.Count;  
 
             if (count == 1)  
             {  
 
                 if (penBrushDrawingOrder == PenBrushDrawingOrder.BrushFirst)  
                 {  
                     if (fillBrush != null) { graphics.FillPolygon(GetGdiPlusBrushFromGeoBrush(fillBrush, cachePoints), ringsCollection[0]); }  
                     if (outlinePen != null) { graphics.DrawPolygon(GetGdiPlusPenFromGeoPen(outlinePen), ringsCollection[0]); }  
                 }  
                 else  
                 {  
                     if (outlinePen != null) { graphics.DrawPolygon(GetGdiPlusPenFromGeoPen(outlinePen), ringsCollection[0]); }  
                     if (fillBrush != null) { graphics.FillPolygon(GetGdiPlusBrushFromGeoBrush(fillBrush, cachePoints), ringsCollection[0]); }  
                 }  
             }  
             else if (count != 0)  
             {  
                 GraphicsPath graphicsPath = null;  
 
                 try  
                 {  
                     graphicsPath = new GraphicsPath();  
                     graphicsPath.FillMode = FillMode.Winding;  
                     foreach (PointF[] points in ringsCollection)  
                     {  
                         graphicsPath.AddPolygon(points);  
                     }  
 
                     if (penBrushDrawingOrder == PenBrushDrawingOrder.BrushFirst)  
                     {  
                         if (fillBrush != null) { graphics.FillPath(GetGdiPlusBrushFromGeoBrush(fillBrush, cachePoints), graphicsPath); }  
                         if (outlinePen != null) { graphics.DrawPath(GetGdiPlusPenFromGeoPen(outlinePen), graphicsPath); }  
                     }  
                     else  
                     {  
                         if (outlinePen != null) { graphics.DrawPath(GetGdiPlusPenFromGeoPen(outlinePen), graphicsPath); }  
                         if (fillBrush != null) { graphics.FillPath(GetGdiPlusBrushFromGeoBrush(fillBrush, cachePoints), graphicsPath); }  
                     }  
                 }  
                 finally  
                 {  
                     if (graphicsPath != null) { graphicsPath.Dispose(); }  
                 }  
             }  
         }  
 
         private Pen GetGdiPlusPenFromGeoPen(GeoPen pen)  
         {  
             if (pen == null) { return null; }  
 
             if (penCache == null) { penCache = new Dictionary<long, Pen>(); }  
 
             if (penCache.ContainsKey(pen.Id))  
             {  
                 return penCache[pen.Id];  
             }  
 
             Pen resultPen = new Pen(GetGDIPlusColorFromGeoColor(pen.Color));  
             resultPen.Width = pen.Width * (Dpi / standardDpi);  
             resultPen.Brush = GetGdiPlusBrushFromGeoBrush(pen.Brush, null);  
             resultPen.Color = GetGDIPlusColorFromGeoColor(pen.Color);  
             resultPen.DashCap = GetDashCapFromGeoDashCap(pen.DashCap);  
             resultPen.LineJoin = GetLineJoinFromDrawingLingJoin(pen.LineJoin);  
             resultPen.MiterLimit = pen.MiterLimit;  
             resultPen.StartCap = GetLineCapFromDrawingLineCap(pen.StartCap);  
             resultPen.EndCap = GetLineCapFromDrawingLineCap(pen.EndCap);  
 
             if (pen.DashPattern != null && pen.DashPattern.Count > 0)  
             {  
                 float[] dashPattern = new float[pen.DashPattern.Count];  
                 for (int i = 0; i < dashPattern.Length; i++)  
                 {  
                     dashPattern[i] = pen.DashPattern[i];  
                 }  
 
                 resultPen.DashPattern = dashPattern;  
             }  
 
             penCache.Add(pen.Id, resultPen);  
 
             return resultPen;  
         }  
 
         private static LineCap GetLineCapFromDrawingLineCap(DrawingLineCap lineCap)  
         {  
             LineCap returnLineCap = LineCap.Round;  
 
             switch (lineCap)  
             {  
                 case DrawingLineCap.Round:  
                     returnLineCap = LineCap.Round;  
                     break;  
                 case DrawingLineCap.AnchorMask:  
                     returnLineCap = LineCap.AnchorMask;  
                     break;  
                 case DrawingLineCap.ArrowAnchor:  
                     returnLineCap = LineCap.ArrowAnchor;  
                     break;  
                 case DrawingLineCap.Custom:  
                     returnLineCap = LineCap.Custom;  
                     break;  
                 case DrawingLineCap.DiamondAnchor:  
                     returnLineCap = LineCap.DiamondAnchor;  
                     break;  
                 case DrawingLineCap.Flat:  
                     returnLineCap = LineCap.Flat;  
                     break;  
                 case DrawingLineCap.NoAnchor:  
                     returnLineCap = LineCap.NoAnchor;  
                     break;  
                 case DrawingLineCap.RoundAnchor:  
                     returnLineCap = LineCap.RoundAnchor;  
                     break;  
                 case DrawingLineCap.Square:  
                     returnLineCap = LineCap.Square;  
                     break;  
                 case DrawingLineCap.SquareAnchor:  
                     returnLineCap = LineCap.SquareAnchor;  
                     break;  
                 case DrawingLineCap.Triangle:  
                     returnLineCap = LineCap.Triangle;  
                     break;  
                 default:  
                     throw new ArgumentOutOfRangeException("lineCap", "The value for the enumeration is not one of the valid values.");  
             }  
 
             return returnLineCap;  
         }  
 
         private static LineJoin GetLineJoinFromDrawingLingJoin(DrawingLineJoin lineJoin)  
         {  
             LineJoin returnLineJoin = LineJoin.Miter;  
 
             switch (lineJoin)  
             {  
                 case DrawingLineJoin.Bevel:  
                     returnLineJoin = LineJoin.Bevel;  
                     break;  
                 case DrawingLineJoin.Miter:  
                     returnLineJoin = LineJoin.Miter;  
                     break;  
                 case DrawingLineJoin.MiterClipped:  
                     returnLineJoin = LineJoin.MiterClipped;  
                     break;  
                 case DrawingLineJoin.Round:  
                     returnLineJoin = LineJoin.Round;  
                     break;  
                 default:  
                     throw new ArgumentOutOfRangeException("lineJoin", "The value for the enumeration is not one of the valid values.");  
             }  
 
             return returnLineJoin;  
         }  
 
         private static DashCap GetDashCapFromGeoDashCap(GeoDashCap dashCap)  
         {  
             DashCap returnDashCap = DashCap.Flat;  
 
             switch (dashCap)  
             {  
                 case GeoDashCap.Flat:  
                     returnDashCap = DashCap.Flat;  
                     break;  
                 case GeoDashCap.Round:  
                     returnDashCap = DashCap.Round;  
                     break;  
                 case GeoDashCap.Triangle:  
                     returnDashCap = DashCap.Triangle;  
                     break;  
                 default:  
                     throw new ArgumentOutOfRangeException("dashCap", "The value for the enumeration is not one of the valid values.");  
             }  
 
             return returnDashCap;  
         }  
 
         private Brush GetGdiPlusBrushFromGeoBrush(GeoBrush brush, IEnumerable<ScreenPointF> areaPointsCache)  
         {  
             if (brush == null) { return null; }  
 
             Brush resultBrush = null;  
             GeoLinearGradientBrush geoLinearGradientBrush = brush as GeoLinearGradientBrush;  
 
             if (geoLinearGradientBrush != null)  
             {  
                 if (areaPointsCache != null)  
                 {  
                     float minX = float.MaxValue;  
                     float maxX = float.MinValue;  
                     float minY = float.MaxValue;  
                     float maxY = float.MinValue;  
 
                     //for (int i = 0; i < areaPointsCache.Length; i++)  
                     //{  
                     foreach (ScreenPointF pointF in areaPointsCache)  
                     {  
                         //ScreenPointF pointF = areaPointsCache[i];  
                         if (minX > pointF.X) { minX = pointF.X; }  
                         if (maxX < pointF.X) { maxX = pointF.X; }  
                         if (minY > pointF.Y) { minY = pointF.Y; }  
                         if (maxY < pointF.Y) { maxY = pointF.Y; }  
                     }  
                     float width = maxX - minX;  
                     float height = maxY - minY;  
                     if (width == 0) { width = 1; }  
                     if (height == 0) { height = 1; }  
 
                     resultBrush = GetGdiBrushFromGeoLinearGradientBrush(geoLinearGradientBrush, new RectangleF(minX, minY, width, height));  
                 }  
                 else  
                 {  
                     resultBrush = GetGdiBrushFromGeoLinearGradientBrush(geoLinearGradientBrush, new RectangleF(0, 0, Width, Height));  
                 }  
             }  
             else  
             {  
                 if (brushCache == null) { brushCache = new Dictionary<long, Brush>(); }  
 
                 if (brushCache.ContainsKey(brush.Id))  
                 {  
                     return brushCache[brush.Id];  
                 }  
                 string typeName = brush.GetType().Name;  
 
                 switch (typeName)  
                 {  
                     case "GeoSolidBrush":  
                         GeoSolidBrush geoSolidBrush = brush as GeoSolidBrush;  
                         if (geoSolidBrush != null)  
                         {  
                             resultBrush = GetGdiBrushFromGeoSolidBrush(geoSolidBrush);  
                         }  
                         break;  
 
                     case "GeoLinearGradientBrush":  
 
                         break;  
 
                     case "GeoHatchBrush":  
                         GeoHatchBrush geoHatchBrush = brush as GeoHatchBrush;  
                         if (geoHatchBrush != null)  
                         {  
                             resultBrush = GetGdiBrushFromGeoHatchBrush(geoHatchBrush);  
                         }  
                         break;  
 
                     case "GeoTextureBrush":  
                         GeoTextureBrush geoTextureBrush = brush as GeoTextureBrush;  
                         if (geoTextureBrush != null)  
                         {  
                             resultBrush = GetGdiBrushFromGeoTextureBrush(geoTextureBrush);  
                         }  
                         break;  
 
                     default: break;  
                 }  
 
                 brushCache.Add(brush.Id, resultBrush);  
             }  
 
             return resultBrush;  
         }  
 
         private static Brush GetGdiBrushFromGeoTextureBrush(GeoTextureBrush brush)  
         {  
             if (brush == null) { return null; }  
 
             DrawingRectangleF drawingRectangleF = brush.DrawingRectangleF;  
             float upperLeftX = drawingRectangleF.CenterX - drawingRectangleF.Width / 2;  
             float upperLeftY = drawingRectangleF.CenterY - drawingRectangleF.Width / 2;  
 
             Image image = Image.FromStream(brush.GeoImage.GetImageStream(new GdiPlusGeoCanvas()));  
             RectangleF rectangleF = new RectangleF(upperLeftX, upperLeftY, drawingRectangleF.Width, drawingRectangleF.Height);  
 
             TextureBrush resultBrush;  
             if (rectangleF.Width == 0)  
             {  
                 resultBrush = new TextureBrush(image);  
             }  
             else  
             {  
                 resultBrush = new TextureBrush(image, GetWrapModeFromGeoWrapMode(brush.GeoWrapMode), rectangleF);  
             }  
             return resultBrush;  
         }  
 
         private static Brush GetGdiBrushFromGeoHatchBrush(GeoHatchBrush brush)  
         {  
             if (brush == null) { return null; }  
 
             Color foregroundColor = GetGDIPlusColorFromGeoColor(brush.ForegroundColor);  
             Color backgroundColor = GetGDIPlusColorFromGeoColor(brush.BackgroundColor);  
             HatchStyle hatchStyle = GetHatchStyleFromGeoHatchStyle(brush.HatchStyle);  
 
             return new HatchBrush(hatchStyle, foregroundColor, backgroundColor);  
         }  
 
         private static HatchStyle GetHatchStyleFromGeoHatchStyle(GeoHatchStyle hatchStyle)  
         {  
             switch (hatchStyle)  
             {  
                 case GeoHatchStyle.Horizontal: return HatchStyle.Horizontal;  
                 case GeoHatchStyle.Vertical: return HatchStyle.Vertical;  
                 case GeoHatchStyle.ForwardDiagonal: return HatchStyle.ForwardDiagonal;  
                 case GeoHatchStyle.BackwardDiagonal: return HatchStyle.BackwardDiagonal;  
                 case GeoHatchStyle.LargeGrid: return HatchStyle.LargeGrid;  
                 case GeoHatchStyle.DiagonalCross: return HatchStyle.DiagonalCross;  
                 case GeoHatchStyle.Percent05: return HatchStyle.Percent05;  
                 case GeoHatchStyle.Percent10: return HatchStyle.Percent10;  
                 case GeoHatchStyle.Percent20: return HatchStyle.Percent20;  
                 case GeoHatchStyle.Percent25: return HatchStyle.Percent25;  
                 case GeoHatchStyle.Percent30: return HatchStyle.Percent30;  
                 case GeoHatchStyle.Percent40: return HatchStyle.Percent40;  
                 case GeoHatchStyle.Percent50: return HatchStyle.Percent50;  
                 case GeoHatchStyle.Percent60: return HatchStyle.Percent60;  
                 case GeoHatchStyle.Percent70: return HatchStyle.Percent70;  
                 case GeoHatchStyle.Percent75: return HatchStyle.Percent75;  
                 case GeoHatchStyle.Percent80: return HatchStyle.Percent80;  
                 case GeoHatchStyle.Percent90: return HatchStyle.Percent90;  
                 case GeoHatchStyle.LightDownwardDiagonal: return HatchStyle.LightDownwardDiagonal;  
                 case GeoHatchStyle.LightUpwardDiagonal: return HatchStyle.LightUpwardDiagonal;  
                 case GeoHatchStyle.DarkDownwardDiagonal: return HatchStyle.DarkDownwardDiagonal;  
                 case GeoHatchStyle.DarkUpwardDiagonal: return HatchStyle.DarkUpwardDiagonal;  
                 case GeoHatchStyle.WideDownwardDiagonal: return HatchStyle.WideDownwardDiagonal;  
                 case GeoHatchStyle.WideUpwardDiagonal: return HatchStyle.WideUpwardDiagonal;  
                 case GeoHatchStyle.LightVertical: return HatchStyle.LightVertical;  
                 case GeoHatchStyle.LightHorizontal: return HatchStyle.LightHorizontal;  
                 case GeoHatchStyle.NarrowVertical: return HatchStyle.NarrowVertical;  
                 case GeoHatchStyle.NarrowHorizontal: return HatchStyle.NarrowHorizontal;  
                 case GeoHatchStyle.DarkVertical: return HatchStyle.DarkVertical;  
                 case GeoHatchStyle.DarkHorizontal: return HatchStyle.DarkHorizontal;  
                 case GeoHatchStyle.DashedDownwardDiagonal: return HatchStyle.DashedDownwardDiagonal;  
                 case GeoHatchStyle.DashedUpwardDiagonal: return HatchStyle.DashedUpwardDiagonal;  
                 case GeoHatchStyle.DashedHorizontal: return HatchStyle.DashedHorizontal;  
                 case GeoHatchStyle.DashedVertical: return HatchStyle.DashedVertical;  
                 case GeoHatchStyle.SmallConfetti: return HatchStyle.SmallConfetti;  
                 case GeoHatchStyle.LargeConfetti: return HatchStyle.LargeConfetti;  
                 case GeoHatchStyle.ZigZag: return HatchStyle.ZigZag;  
                 case GeoHatchStyle.Wave: return HatchStyle.Wave;  
                 case GeoHatchStyle.DiagonalBrick: return HatchStyle.DiagonalBrick;  
                 case GeoHatchStyle.HorizontalBrick: return HatchStyle.HorizontalBrick;  
                 case GeoHatchStyle.Weave: return HatchStyle.Weave;  
                 case GeoHatchStyle.Plaid: return HatchStyle.Plaid;  
                 case GeoHatchStyle.Divot: return HatchStyle.Divot;  
                 case GeoHatchStyle.DottedGrid: return HatchStyle.DottedGrid;  
                 case GeoHatchStyle.DottedDiamond: return HatchStyle.DottedDiamond;  
                 case GeoHatchStyle.Shingle: return HatchStyle.Shingle;  
                 case GeoHatchStyle.Trellis: return HatchStyle.Trellis;  
                 case GeoHatchStyle.Sphere: return HatchStyle.Sphere;  
                 case GeoHatchStyle.SmallGrid: return HatchStyle.SmallGrid;  
                 case GeoHatchStyle.SmallCheckerBoard: return HatchStyle.SmallCheckerBoard;  
                 case GeoHatchStyle.LargeCheckerBoard: return HatchStyle.LargeCheckerBoard;  
                 case GeoHatchStyle.OutlinedDiamond: return HatchStyle.OutlinedDiamond;  
                 case GeoHatchStyle.SolidDiamond: return HatchStyle.SolidDiamond;  
                 case GeoHatchStyle.Min: return HatchStyle.Min;  
                 case GeoHatchStyle.Max: return HatchStyle.Max;  
                 case GeoHatchStyle.Cross: return HatchStyle.Cross;  
                 default:  
                     throw new ArgumentOutOfRangeException("hatchStyle", "The value for the enumeration is not one of the valid values.");  
             }  
         }  
 
         private static Brush GetGdiBrushFromGeoSolidBrush(GeoSolidBrush brush)  
         {  
             Color color = GetGDIPlusColorFromGeoColor(brush.Color);  
             return new SolidBrush(color);  
         }  
 
         private static Brush GetGdiBrushFromGeoLinearGradientBrush(GeoLinearGradientBrush brush, RectangleF rectangle)  
         {  
             if (brush == null) { return null; }  
 
             LinearGradientBrush resultBrush = null;  
 
             Color color1 = GetGDIPlusColorFromGeoColor(brush.StartColor);  
             Color color2 = GetGDIPlusColorFromGeoColor(brush.EndColor);  
 
             resultBrush = new LinearGradientBrush(rectangle, color1, color2, brush.DirectionAngle);  
             resultBrush.WrapMode = GetWrapModeFromGeoWrapMode(brush.WrapMode);  
 
             return resultBrush;  
         }  
 
         private static Color GetGDIPlusColorFromGeoColor(GeoColor color)  
         {  
             return Color.FromArgb(color.AlphaComponent, color.RedComponent, color.GreenComponent, color.BlueComponent);  
         }  
 
         private static WrapMode GetWrapModeFromGeoWrapMode(GeoWrapMode geoWrapMode)  
         {  
             WrapMode wrapMode = WrapMode.Tile;  
 
             switch (geoWrapMode)  
             {  
                 case GeoWrapMode.Clamp:  
                     wrapMode = WrapMode.Clamp;  
                     break;  
                 case GeoWrapMode.Tile:  
                     wrapMode = WrapMode.Tile;  
                     break;  
                 case GeoWrapMode.TileFlipX:  
                     wrapMode = WrapMode.TileFlipX;  
                     break;  
                 case GeoWrapMode.TileFlipXY:  
                     wrapMode = WrapMode.TileFlipXY;  
                     break;  
                 case GeoWrapMode.TileFlipY:  
                     wrapMode = WrapMode.TileFlipY;  
                     break;  
                 default:  
                     throw new ArgumentOutOfRangeException("geoWrapMode");  
             }  
 
             return wrapMode;  
         }  
 
         protected override void DrawEllipseCore(ScreenPointF screenPoint, float width, float height, GeoPen outlinePen, GeoBrush fillBrush, DrawingLevel drawingLevel, float xOffset, float yOffset, PenBrushDrawingOrder penBrushDrawingOrder)  
         {  
             //Validators.CheckParameterIsNotBothNull(outlinePen, fillBrush, "outlinePen", "fillBrush");  
             //Validators.CheckGeoCanvasIsInDrawing(IsDrawing);  
             //Validators.CheckDrawingLevelIsValid(drawingLevel, "drawingLevel");  
 
             if (!featuresOrderByLevel.ContainsKey(drawingLevel))  
             {  
                 featuresOrderByLevel.Add(drawingLevel, new Collection<Dictionary<string, object>>());  
             }  
 
             Dictionary<string, object> parameters = new Dictionary<string, object>();  
             parameters.Add("screenPoint", screenPoint);  
             parameters.Add("width", width);  
             parameters.Add("height", height);  
             parameters.Add("outlinePen", outlinePen);  
             parameters.Add("fillBrush", fillBrush);  
             parameters.Add("xOffset", xOffset);  
             parameters.Add("yOffset", yOffset);  
             parameters.Add("penBrushDrawingOrder", penBrushDrawingOrder);  
             parameters.Add("method", "DrawEllipseCache");  
 
             featuresOrderByLevel[drawingLevel].Add(parameters);  
         }  
 
         private float ToPrinterDpiPixel(float pixel)  
         {  
             return pixel * Dpi / standardDpi;  
         }  
 
         private void DrawScreenImageWithoutScalingCache(GeoImage image, float centerXInScreen, float centerYInScreen, float xOffset, float yOffset, float rotateAngle)  
         {  
             Bitmap bitmap = new Bitmap(image.GetImageStream(this));  
             float imageWidth = ToPrinterDpiPixel((float)(bitmap.Width));  
             float imageHeight = ToPrinterDpiPixel((float)(bitmap.Height));  
 
             float screenX = ToPrinterDpiPixel(centerXInScreen);  
             float screenY = ToPrinterDpiPixel(centerYInScreen);  
 
             screenX += -imageWidth / 2 + xOffset;  
             screenY += -imageHeight / 2 + yOffset;  
 
             if (rotateAngle == 0)  
             {  
                 try  
                 {  
                     bitmap.SetResolution(standardDpi, standardDpi);  
                     graphics.DrawImage(bitmap, screenX, screenY);  
                 }  
                 finally  
                 {  
                     if (bitmap != null) { bitmap.Dispose(); }  
                 }  
             }  
             else  
             {  
                 float upperLeftPointX = -imageWidth * 0.5f;  
                 float upperLeftPointY = imageHeight * 0.5f;  
                 double rotateRadient = rotateAngle * Math.PI / 180;  
                 double baseRadient = Math.PI - Math.Atan(imageHeight / imageWidth);  
                 double radius = Math.Sqrt(imageWidth * imageWidth + imageHeight * imageHeight) * 0.5;  
                 double newRadient = baseRadient + rotateRadient;  
                 double newPointX = radius * Math.Cos(newRadient);  
                 double newPointY = radius * Math.Sin(newRadient);  
                 double xOffsetInScreen = newPointX - upperLeftPointX;  
                 double yOffsetInScreen = -(newPointY - upperLeftPointY);  
                 screenX += (float)xOffsetInScreen;  
                 screenY += (float)yOffsetInScreen;  
 
                 try  
                 {  
                     bitmap = new Bitmap(image.GetImageStream(this));  
 
                     graphics.TranslateTransform(screenX, screenY);  
                     graphics.RotateTransform(-rotateAngle);  
 
                     bitmap.SetResolution(standardDpi, standardDpi);  
                     graphics.DrawImage(bitmap, 0, 0);  
 
                     graphics.RotateTransform(rotateAngle);  
                     graphics.TranslateTransform(-screenX, -screenY);  
                 }  
                 finally  
                 {  
                     if (bitmap != null) { bitmap.Dispose(); }  
                 }  
             }  
         }  
 
         protected override void DrawScreenImageWithoutScalingCore(GeoImage image, float centerXInScreen, float centerYInScreen, DrawingLevel drawingLevel, float xOffset, float yOffset, float rotateAngle)  
         {  
             //Validators.CheckParameterIsNotNull(image, "image");  
 
             if (!featuresOrderByLevel.ContainsKey(drawingLevel))  
             {  
                 featuresOrderByLevel.Add(drawingLevel, new Collection<Dictionary<string, object>>());  
             }  
 
             Dictionary<string, object> parameters = new Dictionary<string, object>();  
 
             byte[] buffer = new byte[image.GetImageStream(this).Length];  
             image.GetImageStream(this).Read(buffer, 0, buffer.Length);  
             GeoImage imageCopy = new GeoImage(new MemoryStream(buffer));  
 
             parameters.Add("image", imageCopy);  
             parameters.Add("centerXInScreen", centerXInScreen);  
             parameters.Add("centerYInScreen", centerYInScreen);  
             parameters.Add("xOffset", xOffset);  
             parameters.Add("yOffset", yOffset);  
             parameters.Add("rotateAngle", rotateAngle);  
             parameters.Add("method", "DrawScreenImageWithoutScalingCache");  
 
             featuresOrderByLevel[drawingLevel].Add(parameters);  
         }  
 
         private void DrawScreenImageCache(GeoImage image, float centerXInScreen, float centerYInScreen, float widthInScreen, float heightInScreen, float xOffset, float yOffset, float rotateAngle)  
         {  
             Bitmap bitmap = new Bitmap(image.GetImageStream(this));  
             float imageWidth = widthInScreen;  
             float imageHeight = heightInScreen;  
 
             float screenX = ToPrinterDpiPixel(centerXInScreen);  
             float screenY = ToPrinterDpiPixel(centerYInScreen);  
 
             screenX += -imageWidth / 2 + xOffset;  
             screenY += -imageHeight / 2 + yOffset;  
 
             if (rotateAngle == 0)  
             {  
                 try  
                 {  
                     bitmap.SetResolution(standardDpi, standardDpi);  
                     graphics.DrawImage(bitmap, screenX, screenY, imageWidth, imageHeight);  
                 }  
                 finally  
                 {  
                     if (bitmap != null) { bitmap.Dispose(); }  
                 }  
             }  
             else  
             {  
                 float upperLeftPointX = -imageWidth * 0.5f;  
                 float upperLeftPointY = imageHeight * 0.5f;  
                 double rotateRadient = rotateAngle * Math.PI / 180;  
                 double baseRadient = Math.PI - Math.Atan(imageHeight / imageWidth);  
                 double radius = Math.Sqrt(imageWidth * imageWidth + imageHeight * imageHeight) * 0.5;  
                 double newRadient = baseRadient + rotateRadient;  
                 double newPointX = radius * Math.Cos(newRadient);  
                 double newPointY = radius * Math.Sin(newRadient);  
                 double xOffsetInScreen = newPointX - upperLeftPointX;  
                 double yOffsetInScreen = -(newPointY - upperLeftPointY);  
                 screenX += (float)xOffsetInScreen;  
                 screenY += (float)yOffsetInScreen;  
 
                 try  
                 {  
                     bitmap = new Bitmap(image.GetImageStream(this));  
 
                     graphics.TranslateTransform(screenX, screenY);  
                     graphics.RotateTransform(-rotateAngle);  
 
                     bitmap.SetResolution(standardDpi, standardDpi);  
                     graphics.DrawImage(bitmap, 0, 0);  
 
                     graphics.RotateTransform(rotateAngle);  
                     graphics.TranslateTransform(-screenX, -screenY);  
                 }  
                 finally  
                 {  
                     if (bitmap != null) { bitmap.Dispose(); }  
                 }  
             }  
         }  
 
         protected override void DrawScreenImageCore(GeoImage image, float centerXInScreen, float centerYInScreen, float widthInScreen, float heightInScreen, DrawingLevel drawingLevel, float xOffset, float yOffset, float rotateAngle)  
         {  
             //Validators.CheckParameterIsNotNull(image, "image");  
 
             if (!featuresOrderByLevel.ContainsKey(drawingLevel))  
             {  
                 featuresOrderByLevel.Add(drawingLevel, new Collection<Dictionary<string, object>>());  
             }  
 
             Dictionary<string, object> parameters = new Dictionary<string, object>();  
 
             byte[] buffer = new byte[image.GetImageStream(this).Length];  
             image.GetImageStream(this).Read(buffer, 0, buffer.Length);  
             GeoImage imageCopy = new GeoImage(new MemoryStream(buffer));  
 
             parameters.Add("image", imageCopy);  
             parameters.Add("centerXInScreen", centerXInScreen);  
             parameters.Add("centerYInScreen", centerYInScreen);  
             parameters.Add("widthInScreen", widthInScreen);  
             parameters.Add("heightInScreen", heightInScreen);  
             parameters.Add("xOffset", xOffset);  
             parameters.Add("yOffset", yOffset);  
             parameters.Add("rotateAngle", rotateAngle);  
             parameters.Add("method", "DrawScreenImageCache");  
 
             featuresOrderByLevel[drawingLevel].Add(parameters);  
         }  
 
         protected override void DrawTextCore(string text, GeoFont font, GeoBrush fillBrush, GeoPen haloPen, IEnumerable<ScreenPointF> textPathInScreen, DrawingLevel drawingLevel, float xOffset, float yOffset, float rotateAngle)  
         {  
             //Validators.CheckParameterIsNotNull(fillBrush, "fillBrush");  
             //Validators.CheckParameterIsNotNull(font, "font");  
             //Validators.CheckParameterIsNotNull(text, "text");  
             //Validators.CheckDrawingLevelIsValid(drawingLevel, "drawingLevel");  
             //Validators.CheckParameterIsNotNullOrEmpty(text, "text");  
             //Validators.CheckGeoCanvasIsInDrawing(IsDrawing);  
             //Validators.CheckParameterIsNotNull(textPathInScreen, "textPathInScreen");  
 
             if (!featuresOrderByLevel.ContainsKey(drawingLevel))  
             {  
                 featuresOrderByLevel.Add(drawingLevel, new Collection<Dictionary<string, object>>());  
             }  
 
             Dictionary<string, object> parameters = new Dictionary<string, object>();  
             parameters.Add("text", text);  
             parameters.Add("font", font);  
             parameters.Add("fillBrush", fillBrush);  
             parameters.Add("haloPen", haloPen);  
             parameters.Add("textPathInScreen", textPathInScreen);  
             parameters.Add("rotateAngle", rotateAngle);  
             parameters.Add("xOffset", xOffset);  
             parameters.Add("yOffset", yOffset);  
             parameters.Add("method", "DrawTextCache");  
 
             featuresOrderByLevel[drawingLevel].Add(parameters);  
 
             isMeasured = true;  
         }  
 
         private void DrawTextCache(string text, GeoFont font, GeoBrush fillBrush, GeoPen haloPen, IEnumerable<ScreenPointF> textPathInScreen, float xOffset, float yOffset, float rotateAngle)  
         {  
             Font gdiFont = GetGdiPlusFontFromGeoFont(font);  
 
             CompositingMode mode = graphics.CompositingMode;  
             graphics.CompositingMode = CompositingMode.SourceOver;  
 
             DrawingRectangleF rectangle = MeasureText(text, font);  
 
             double width = rectangle.Width;  
             double height = rectangle.Height;  
 
             double rotateRadient = 0;  
             double xOffsetRotated = 0;  
             double yOffsetRotated = 0;  
 
             if (rotateAngle != 0)  
             {  
                 double upperLeftX = -width * 0.5;  
                 double upperLeftY = height * 0.5;  
 
                 double radius = Math.Sqrt(width * width + height * height) * 0.5;  
 
                 rotateRadient = rotateAngle * Math.PI / 180;  
 
                 double newRadient = rotateRadient - Math.Atan(height / width) + Math.PI;  
 
                 xOffsetRotated = radius * Math.Cos(newRadient) - upperLeftX;  
                 yOffsetRotated = -(radius * Math.Sin(newRadient) - upperLeftY);  
             }  
 
             foreach (ScreenPointF point in textPathInScreen)  
             {  
                 ScreenPointF pointForLabel = new ScreenPointF((float)(point.X - width * 0.5), (float)(point.Y - height * 0.5));  
 
                 if (rotateAngle == 0)  
                 {  
                     float dpixOffset = xOffset * (Dpi / standardDpi);  
                     float dpiyOffset = yOffset * (Dpi / standardDpi);  
 
                     DrawString(graphics, text, gdiFont, fillBrush, haloPen, new PointF(pointForLabel.X + dpixOffset, pointForLabel.Y + dpiyOffset), width, height);  
                 }  
                 else  
                 {  
                     float newPointX = (float)(pointForLabel.X + (xOffset * (Dpi / standardDpi)) + xOffsetRotated);  
                     float newPointY = (float)(pointForLabel.Y + (yOffset * (Dpi / standardDpi)) + yOffsetRotated);  
 
                     graphics.TranslateTransform(newPointX, newPointY);  
                     graphics.RotateTransform((float)-rotateAngle);  
 
                     DrawString(graphics, text, gdiFont, fillBrush, haloPen, new PointF(0, 0), width, height);  
 
                     graphics.RotateTransform((float)rotateAngle);  
                     graphics.TranslateTransform(-newPointX, -newPointY);  
                 }  
             }  
 
             graphics.CompositingMode = mode;  
         }  
 
         private void DrawString(Graphics graphics, string text, Font font, GeoBrush fillBrush, GeoPen haloPen, PointF position, double width, double height)  
         {  
             Brush brush = GetGdiPlusBrushFromGeoBrush(fillBrush, new ScreenPointF[] { new ScreenPointF(position.X, position.Y), new ScreenPointF(position.X + (float)width, position.Y + (float)height) });  
             Pen pen = GetGdiPlusPenFromGeoPen(haloPen);  
 
             if (haloPen == null || haloPen.Brush == null || haloPen.Color.AlphaComponent == 0)  
             {  
                 graphics.DrawString(text, font, brush, position, StringFormat.GenericTypographic);  
             }  
             else  
             {  
                 SmoothingMode tempSmoothingMode = graphics.SmoothingMode;  
                 GraphicsPath path = null;  
                 float xOffset = 0;  
                 float yOffset = 0;  
 
                 try  
                 {  
                     path = new GraphicsPath();  
                     float fontSize = font.Size * Dpi / standardDpi;  
                     path.AddString(text, font.FontFamily, (int)font.Style, fontSize * 1.3f, position, StringFormat.GenericTypographic);  
 
                     RectangleF bound = path.GetBounds();  
                     float boundWidth = bound.Width;  
                     float boundHeight = bound.Height;  
 
                     xOffset = (float)((width - boundWidth) * 0.5);  
                     yOffset = (float)((height - boundHeight) * 0.3);  
 
                     graphics.SmoothingMode = SmoothingMode.AntiAlias;  
 
                     graphics.TranslateTransform(xOffset, yOffset);  
 
                     graphics.DrawPath(pen, path);  
                     graphics.FillPath(brush, path);  
                 }  
                 finally  
                 {  
                     if (path != null) { path.Dispose(); }  
 
                     graphics.SmoothingMode = tempSmoothingMode;  
                     graphics.TranslateTransform(-xOffset, -yOffset);  
                 }  
             }  
         }  
 
         private Font GetGdiPlusFontFromGeoFont(GeoFont font)  
         {  
             if (font == null) { return null; }  
 
             if (fontCache == null) { fontCache = new Dictionary<long, Font>(); }  
 
             if (fontCache.ContainsKey(font.Id))  
             {  
                 return fontCache[font.Id];  
             }  
 
             FontStyle gdiplusFontStyle = GetFontStyleFromDrawingFontStyle(font.Style);  
 
             Font resultFont = new Font(font.FontName, font.Size, gdiplusFontStyle);  
 
             fontCache.Add(font.Id, resultFont);  
 
             return resultFont;  
         }  
 
         private static FontStyle GetFontStyleFromDrawingFontStyle(DrawingFontStyles style)  
         {  
             FontStyle returnFontStyle = FontStyle.Regular;  
 
             int value = (int)style;  
 
             if (value < 1 || value > (int)(DrawingFontStyles.Regular |  
                                            DrawingFontStyles.Bold |  
                                            DrawingFontStyles.Italic |  
                                            DrawingFontStyles.Underline |  
                                            DrawingFontStyles.Strikeout))  
             {  
                 throw new ArgumentOutOfRangeException("style", "The value for the enumeration is not one of the valid values.");  
             }  
 
             if ((style & DrawingFontStyles.Bold) != 0) { returnFontStyle = returnFontStyle | FontStyle.Bold; }  
             if ((style & DrawingFontStyles.Italic) != 0) { returnFontStyle = returnFontStyle | FontStyle.Italic; }  
             if ((style & DrawingFontStyles.Underline) != 0) { returnFontStyle = returnFontStyle | FontStyle.Underline; }  
             if ((style & DrawingFontStyles.Strikeout) != 0) { returnFontStyle = returnFontStyle | FontStyle.Strikeout; }  
 
             return returnFontStyle;  
         }  
 
         protected override DrawingRectangleF MeasureTextCore(string text, GeoFont font)  
         {  
             //Validators.CheckParameterIsNotNull(text, "text");  
 
             Bitmap bitmap = null;  
             Graphics graphics = null;  
 
             SizeF size;  
 
             try  
             {  
                 bitmap = new Bitmap(1, 1);  
                 bitmap.SetResolution(Dpi, Dpi);  
 
                 graphics = Graphics.FromImage(bitmap);  
 
                 size = graphics.MeasureString(text, GetGdiPlusFontFromGeoFont(font), new PointF(), StringFormat.GenericTypographic);  
                 if (size.Width == 0 && size.Height != 0 && text.Length != 0)  
                 {  
                     size.Width = 1;  
                 }  
             }  
             finally  
             {  
                 if (graphics != null) { graphics.Dispose(); }  
                 if (bitmap != null) { bitmap.Dispose(); }  
             }  
 
             return new DrawingRectangleF(size.Width / 2, size.Height / 2, size.Width, size.Height);  
         }  
 
         protected override object ToNativeImageCore(GeoImage image)  
         {  
             //Validators.CheckParameterIsNotNull(image, "image");  
 
             Bitmap bitmap = null;  
             lock (image)  
             {  
                 Stream imageStream = image.GetImageStream(this);  
                 bitmap = new Bitmap(imageStream);  
             }  
             return bitmap;  
         }  
 
         protected override GeoImage ToGeoImageCore(object nativeImage)  
         {  
             Metafile file = nativeImage as Metafile;  
             if (file != null)  
             {  
                 MemoryStream stream = new MemoryStream();  
                 file.Save(stream, ImageFormat.Png);  
                 stream.Seek(0, SeekOrigin.Begin);  
                 return new GeoImage(stream);  
             }  
             throw new ArgumentException("The parameter you supplied may not be null.", "nativeImage");  
         }  
 
         protected override float GetCanvasWidthCore(object nativeImage)  
         {  
             return Width;  
         }  
 
         protected override float GetCanvasHeightCore(object nativeImage)  
         {  
             return Height;  
         }  
 
         public override Stream GetStreamFromGeoImage(GeoImage image)  
         {  
             //Validators.CheckParameterIsNotNull(image, "image");  
 
             if (String.IsNullOrEmpty(image.PathFilename) || !File.Exists(image.PathFilename))  
             {  
                 if (Width > 0 && Height > 0)  
                 {  
                     Bitmap tmpBitmap = new Bitmap((int)Width, (int)Height);  
                     MemoryStream memoryStream = new MemoryStream();  
                     tmpBitmap.Save(memoryStream, ImageFormat.Png);  
                     tmpBitmap.Dispose();  
                     tmpBitmap = null;  
                     return memoryStream;  
                 }  
                 return null;  
             }  
 
             MemoryStream imageStream = null;  
             Bitmap bitmap = null;  
 
             try  
             {  
                 imageStream = new MemoryStream();  
                 bitmap = new Bitmap(image.PathFilename);  
 
                 image.CanvasImageFormat = bitmap.RawFormat.Guid;  
                 bitmap.Save(imageStream, ImageFormat.Png);  
                 imageStream.Seek(0, SeekOrigin.Begin);  
             }  
             finally  
             {  
                 if (bitmap != null) { bitmap.Dispose(); }  
             }  
 
             return imageStream;  
         }  
 
         protected override void FlushCore()  
         {  
             graphics.Flush();  
         }  
     }  
 }  
 

Sample.cs

 using System;  
 using System;  
 using System.Drawing;  
 using System.Windows.Forms;  
 using ThinkGeo.MapSuite.Core;  
 using System.Drawing.Imaging;  
 using System.Reflection;  
 using System.IO;  
 
 public partial class Sample : Form  
 {  
     private MapEngine mapEngine;  
     private Bitmap bitmap;  
 
     public Sample()  
     {  
         InitializeComponent();  
     }  
 
     private void DisplayASimpleMap_Load(object sender, EventArgs e)  
     {  
         bitmap = new Bitmap(map.Width, map.Height);  
         mapEngine = new MapEngine();  
 
         mapEngine.ShowLogo = true;  
         mapEngine.BackgroundFillBrush = new GeoSolidBrush(GeoColor.GeographicColors.ShallowOcean);  
         string filePath = @"..\..\Data\Countries02.shp";  
 
         ShapeFileFeatureLayer countryLayer = new ShapeFileFeatureLayer(filePath);  
         countryLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.Country1;  
         countryLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle = TextStyles.Country1("CNTRY_NAME");  
         countryLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;  
 
         countryLayer.Open();  
         RectangleShape extent = countryLayer.GetBoundingBox();  
         countryLayer.Close();  
 
         mapEngine.StaticLayers.Add("countryLayer", countryLayer);  
         mapEngine.CurrentExtent = extent;  
 
         DrawImage();  
     }  
 
     private void DrawImage()  
     {  
         mapEngine.OpenAllLayers();  
         mapEngine.DrawStaticLayers(bitmap, GeographyUnit.DecimalDegree);  
         mapEngine.CloseAllLayers();  
 
         map.Image = bitmap;  
     }  
 
     private void ToolBar_ButtonClick(object sender, ToolBarButtonClickEventArgs e)  
     {  
         switch (e.Button.Tag.ToString())  
         {  
             case "Zoom In":  
                 mapEngine.CurrentExtent.ScaleDown(50);  
                 break;  
             case "Zoom Out":  
                 mapEngine.CurrentExtent.ScaleUp(50);  
                 break;  
             case "Full Extent":  
                 mapEngine.CurrentExtent = ExtentHelper.SnapToZoomLevel(new RectangleShape(-139.2, 92.4, 120.9, -93.2), GeographyUnit.DecimalDegree, map.Width, map.Height, new ZoomLevelSet());  
                 break;  
             case "Pan Left":  
                 mapEngine.CurrentExtent = ExtentHelper.Pan(mapEngine.CurrentExtent, PanDirection.Left, 20);  
                 break;  
             case "Pan Right":  
                 mapEngine.CurrentExtent = ExtentHelper.Pan(mapEngine.CurrentExtent, PanDirection.Right, 20);  
                 break;  
             case "Pan Up":  
                 mapEngine.CurrentExtent = ExtentHelper.Pan(mapEngine.CurrentExtent, PanDirection.Up, 20);  
                 break;  
             case "Pan Down":  
                 mapEngine.CurrentExtent = ExtentHelper.Pan(mapEngine.CurrentExtent, PanDirection.Down, 20);  
                 break;  
             default:  
                 break;  
         }  
         DrawImage();  
     }  
 
     private void map_ClientSizeChanged(object sender, EventArgs e)  
     {  
         if (map.Width > bitmap.Width || map.Height > bitmap.Height)  
         {  
             bitmap = new Bitmap(map.Width, map.Height);  
             double scale = new ZoomLevelSet().GetZoomLevel(mapEngine.CurrentExtent, map.Width, GeographyUnit.DecimalDegree).Scale;  
             mapEngine.CurrentExtent = ExtentHelper.SnapToZoomLevel((RectangleShape)mapEngine.CurrentExtent.CloneDeep(), GeographyUnit.DecimalDegree, map.Width, map.Height, new ZoomLevelSet());  
             mapEngine.CurrentExtent = ExtentHelper.ZoomToScale(scale, mapEngine.CurrentExtent, GeographyUnit.DecimalDegree, map.Width, map.Height);  
             DrawImage();  
         }  
     }  
 
     private void btnOneFeature_Click(object sender, EventArgs e)  
     {  
         float canvasWidth = 0;  
         float canvasHeight = 0;  
         string metaFileName = String.Empty;  
         Button btn = sender as Button;  
 
         canvasWidth = 4000;  
         canvasHeight = 4000;  
         metaFileName = @"result.emf";  
 
         ShapeFileFeatureLayer countryLayer = mapEngine.StaticLayers["countryLayer"] as ShapeFileFeatureLayer;  
 
         if (null != countryLayer)  
         {  
             Metafile metaFile = new Metafile(metaFileName, Graphics.FromImage(new Bitmap(1, 1)).GetHdc());  
             GraphicsGeoCanvas graphicGeoCanvas = new GraphicsGeoCanvas();  
             Graphics graphic = Graphics.FromImage(metaFile);  
 
 
             countryLayer.Open();  
             graphicGeoCanvas.BeginDrawing(graphic, canvasWidth, canvasHeight, mapEngine.CurrentExtent, GeographyUnit.DecimalDegree);  
             countryLayer.Draw(graphicGeoCanvas, new System.Collections.ObjectModel.Collection<SimpleCandidate>());  
             graphicGeoCanvas.EndDrawing();  
             countryLayer.Close();  
             metaFile.Dispose();  
         }  
 
         MessageBox.Show(String.Format("The map has been saved as EMF to {0}
{1}", Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), metaFileName));  
     }  
 }  
 
serviceseditionsample_usinggraphicsgeocanvas_cs_120911.zip.txt · Last modified: 2015/09/09 03:30 by admin