ThinkGeo Cloud
ThinkGeo UI Controls
ThinkGeo Open Source
Help and Support
External Resources
ThinkGeo Cloud
ThinkGeo UI Controls
ThinkGeo Open Source
Help and Support
External Resources
using System; using System.Collections.Generic; using System.Linq; using System.Text; using ThinkGeo.MapSuite.Core; namespace DoughnutPointStyle { class DonutPointStyle : PointStyle { // A default constructor that just calls the main constructor. public DonutPointStyle() : this(0, 0, new GeoSolidBrush(), new GeoPen(GeoColor.SimpleColors.Transparent), 10) { } // A constructor with fewer parameters that calls the main constructor. public DonutPointStyle(float outerRadius, float innerRadius, GeoBrush fillBrush) : this(outerRadius, innerRadius, fillBrush, new GeoPen(GeoColor.SimpleColors.Transparent), 10) { } // A constructor with fewer parameters that calls the main constructor. public DonutPointStyle(float outerRadius, float innerRadius, GeoBrush fillBrush, GeoPen outerPen) : this(outerRadius, innerRadius, fillBrush, outerPen, 10) { } // The main constructor, it allows you to set all of the options available. public DonutPointStyle(float outerRadius, float innerRadius, GeoBrush fillBrush, GeoPen outerPen, int vertexCountInQuarter) : base() { this.OuterRadius = outerRadius; this.InnerRadius = innerRadius; this.FillBrush = fillBrush; this.OuterPen = outerPen; this.VertexCountInQuarter = vertexCountInQuarter; } // This is the outer radius of the donut in screen coordinate. public float OuterRadius { get; set; } // This is the inner radius of the donut in screen coordinate. public float InnerRadius { get; set; } // This is the brush used to fill the donut. public GeoBrush FillBrush { get; set; } // This is the pen for the rim of the donut. public GeoPen OuterPen { get; set; } // This specifies how many vertices will make up a quarter of a circle in a donut. public int VertexCountInQuarter { get; set; } // This is the method we need to override. protected override void DrawCore(System.Collections.Generic.IEnumerable<Feature> features, GeoCanvas canvas, System.Collections.ObjectModel.Collection<SimpleCandidate> labelsInThisLayer, System.Collections.ObjectModel.Collection<SimpleCandidate> labelsInAllLayers) { foreach (Feature feature in features) { ScreenPointF screenPointF = ExtentHelper.ToScreenCoordinate(canvas.CurrentWorldExtent, feature, canvas.Width, canvas.Height); IEnumerable<ScreenPointF[]> screenPointFs = GetVerticesForADonut(screenPointF, OuterRadius, InnerRadius, VertexCountInQuarter); canvas.DrawArea(screenPointFs, OuterPen, FillBrush, DrawingLevel.LevelFour, this.XOffsetInPixel, this.YOffsetInPixel, PenBrushDrawingOrder.BrushFirst); } } // This method gets the vertices of a donut, which is composed of two circles. private IEnumerable<ScreenPointF[]> GetVerticesForADonut(ScreenPointF center, float outerRadius, float innerRadius, int vertexCountInQuarter) { List<ScreenPointF> outerScreenPointFs = GetVerticesForACircle(center, outerRadius, vertexCountInQuarter); List<ScreenPointF> innerScreenPointFs = GetVerticesForACircle(center, innerRadius, vertexCountInQuarter); outerScreenPointFs.Reverse(); return new ScreenPointF[][] { outerScreenPointFs.ToArray(), innerScreenPointFs.ToArray() }; } // This method gets the vertices of a circle. private List<ScreenPointF> GetVerticesForACircle(ScreenPointF center, float radius, int vertexCountInQuarter) { double deltaDegree = (double)90 / (vertexCountInQuarter + 1); List<ScreenPointF> screenPointFs = new List<ScreenPointF>(); // +X screenPointFs.Add(new ScreenPointF(center.X + radius, center.Y)); // Phase I for (double currentDegree = deltaDegree; currentDegree < 90; currentDegree += deltaDegree) { float x = (float)Math.Cos(currentDegree / 180 * Math.PI) * radius + center.X; float y = (float)Math.Sin(currentDegree / 180 * Math.PI) * radius + center.Y; screenPointFs.Add(new ScreenPointF(x, y)); } // +Y screenPointFs.Add(new ScreenPointF(center.X, center.Y + radius)); // Phase II for (int i = vertexCountInQuarter; i > 0; i--) { screenPointFs.Add(new ScreenPointF(2 * center.X - screenPointFs[i].X, screenPointFs[i].Y)); } // -X screenPointFs.Add(new ScreenPointF(center.X - radius, center.Y)); // Phase III for (int i = 1; i <= vertexCountInQuarter; i++) { screenPointFs.Add(new ScreenPointF(2 * center.X - screenPointFs[i].X, 2 * center.Y - screenPointFs[i].Y)); } // -Y screenPointFs.Add(new ScreenPointF(center.X, center.Y - radius)); // Phase IV for (int i = vertexCountInQuarter; i > 0; i--) { screenPointFs.Add(new ScreenPointF(screenPointFs[i].X, 2 * center.Y - screenPointFs[i].Y)); } // +X screenPointFs.Add(new ScreenPointF(center.X + radius, center.Y)); return screenPointFs; } } }
using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; namespace DoughnutPointStyle { static class Program { /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new TestForm()); } } }
using System; using System.Drawing; using System.Windows.Forms; using ThinkGeo.MapSuite.Core; namespace DoughnutPointStyle { public partial class TestForm : Form { private MapEngine mapEngine = new MapEngine(); private Bitmap bitmap = null; private ShapeFileFeatureLayer worldLayer = null; public TestForm() { InitializeComponent(); } private void TestForm_Load(object sender, EventArgs e) { // Set the full extent and the background color mapEngine.CurrentExtent = ExtentHelper.GetDrawingExtent(new RectangleShape(-180.0, 83.0, 180.0, -90.0), Map.Width, Map.Height); mapEngine.BackgroundFillBrush = new GeoSolidBrush(GeoColor.GeographicColors.ShallowOcean); // Add the worldLayer to the MapEngine worldLayer = new ShapeFileFeatureLayer(@"..\..\Data\Countries02.shp", ShapeFileReadWriteMode.ReadOnly); worldLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.County1; worldLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; mapEngine.StaticLayers.Add("WorldLayer", worldLayer); // Add the capitalLayer to the MapEngine ShapeFileFeatureLayer capitalLayer = new ShapeFileFeatureLayer(@"..\..\Data\worldcapitals.shp", ShapeFileReadWriteMode.ReadOnly); DonutPointStyle donutPointStyle = new DonutPointStyle(6,3, new GeoSolidBrush(GeoColor.SimpleColors.Green), new GeoPen(GeoColor.SimpleColors.Black,1)); capitalLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(donutPointStyle); capitalLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; mapEngine.StaticLayers.Add("CapitalLayer", capitalLayer); DrawImage(); } private void DrawImage() { if (bitmap != null) { bitmap.Dispose(); } bitmap = new Bitmap(Map.Width, Map.Height); 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.GetDrawingExtent(new RectangleShape(-180.0, 83.0, 180.0, -90.0), Map.Width, Map.Height); 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 btnClose_Click(object sender, EventArgs e) { this.Close(); } } }