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.Windows.Forms; namespace ScalingTextStyleForPolygon { 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.Collections.Generic; using System.Collections.ObjectModel; using ThinkGeo.MapSuite.Core; namespace ScalingTextStyleForPolygon { class ScalingTextStyle : TextStyle { private GeographyUnit mapUnit; private double maximumScale; private double minimumScale; private float maximumLabelSize; private float minimumLabelSize; public ScalingTextStyle() : this(GeographyUnit.DecimalDegree, string.Empty, double.MaxValue, 0, 8, 16) { } public ScalingTextStyle(GeographyUnit MapUnit, string TextColumnName, double MaximumScale, double MinimumScale, float MaximumLabelSize, float MinimumLabelSize) { this.mapUnit = MapUnit; this.TextColumnName = TextColumnName; this.maximumScale = MaximumScale; this.minimumScale = MinimumScale; this.maximumLabelSize = MaximumLabelSize; this.minimumLabelSize = MinimumLabelSize; } // This is the map unit to determine the scale. public GeographyUnit MapUnit { get { return mapUnit; } set { mapUnit = value; } } // The maximum scale will be the largest scale used to calculate the size of the label. // If the scale gets larger than the maximum, then we compute the scaling based on // this number instead. This means that after this scale, the size of the label will not get // any smaller no matter how much more you zoom out. public double MaximumScale { get { return maximumScale; } set { maximumScale = value; } } // The minimum scale will be the smallest scale used to calculate the size of the label. // If the scale gets smaller than the minimum, then we compute the scaling based on // this number instead. This means that after this scale, the size of the label will not get // any larger no matter how much more you zoom in. public double MinimumScale { get { return minimumScale; } set { minimumScale = value; } } // The MaximumSize is the size of the label at MinimumScale and lower. public float MaximumLabelSize { get { return maximumLabelSize; } set { maximumLabelSize = value; } } // The MinimumSize is the size of the label at MaximumScale and higher. public float MinimumLabelSize { get { return minimumLabelSize; } set { minimumLabelSize = value; } } protected override void DrawCore(IEnumerable<Feature> features, GeoCanvas canvas, System.Collections.ObjectModel.Collection<SimpleCandidate> labelsInThisLayer, System.Collections.ObjectModel.Collection<SimpleCandidate> labelsInAllLayers) { // Loop through all of the features being passed in to draw. foreach (Feature feature in features) { Collection<LabelingCandidate> labelingCandidates = GetLabelingCandidates(feature, canvas); foreach (LabelingCandidate labelingCandidate in labelingCandidates) { // Let's make sure the features being passed in are Polygon or multi polygons WellKnownType shapeWellKnownType = feature.GetWellKnownType(); if (shapeWellKnownType == WellKnownType.Polygon || shapeWellKnownType == WellKnownType.Multipolygon) { double currentScale = ExtentHelper.GetScale(canvas.CurrentWorldExtent, canvas.Width, mapUnit); // Enforce the minimum and maximum scale properties if (currentScale > maximumScale) { currentScale = maximumScale; } if (currentScale < minimumScale) { currentScale = minimumScale; } // Calculate the size of the label based on the scale. //If the scale is between minimum scale and maximum scale, the size of the label will be calculated according //to the maximum scale/minimum scale ratio. //For example: //Minimum Scale:100,000 //Maximum Scale:200,000 //Minimum Size:9 //Maximum Size:16 //If the scale is 150,000 (mid value between 100,000 and 200,000), the size of the image will be //13 (mid value between 9 and 16). float labelSize = (float)(maximumLabelSize - ((currentScale - minimumScale) * (maximumLabelSize - minimumLabelSize)) / (maximumScale - minimumScale)); string Text = feature.ColumnValues[TextColumnName]; // Call the canvas method to draw the label scaled. //Gets the MultipolygonShape for the feature MultipolygonShape multipolygonShape = new MultipolygonShape(feature.GetWellKnownBinary()); //Loops thru each of the Polygon to be labeled if no overlapping occurs. foreach (PolygonShape polygonShape in multipolygonShape.Polygons) { if (CheckOverlapping(labelingCandidate, canvas, labelsInThisLayer, labelsInAllLayers) == false) { //Finds the center of the bouding bos of the polygon. PointShape pointShape = polygonShape.GetBoundingBox().GetCenterPoint(); //Convert from world coordinate to screen coordinate the location of the feature. ScreenPointF textScreenPoint = ExtentHelper.ToScreenCoordinate(canvas.CurrentWorldExtent, pointShape, canvas.Width, canvas.Height); //Use DrawText method of canvas to label according to the values previously set. canvas.DrawText(Text, new GeoFont("Arial", labelSize), this.TextSolidBrush, //new GeoSolidBrush(GeoColor.StandardColors.Black), null, new ScreenPointF[] { textScreenPoint }, DrawingLevel.LevelFour, this.XOffsetInPixel, this.YOffsetInPixel - labelSize, (float)this.RotationAngle); } SimpleCandidate simpleCandidate = new SimpleCandidate(labelingCandidate.OriginalText, labelingCandidate.ScreenArea); if (labelsInAllLayers != null) { labelsInAllLayers.Add(simpleCandidate); } if (labelsInThisLayer != null) { labelsInThisLayer.Add(simpleCandidate); } } } } } } protected override System.Collections.ObjectModel.Collection<string> GetRequiredColumnNamesCore() { // Here we grab the column from the textStyle and then add // the required columns to make sure we pull back the column // that we need for labeling. Collection<string> columns = new Collection<string>(); if (!columns.Contains(TextColumnName)) { columns.Add(TextColumnName); } return columns; } } }
using System; using System.Collections.ObjectModel; using System.Drawing; using System.Windows.Forms; using ThinkGeo.MapSuite.Core; namespace ScalingTextStyleForPolygon { public partial class TestForm : Form { private MapEngine mapEngine = new MapEngine(); private Bitmap bitmap = null; public TestForm() { InitializeComponent(); } private void TestForm_Load(object sender, EventArgs e) { // Sets the full extent and the background color mapEngine.CurrentExtent = ExtentHelper.GetDrawingExtent(new RectangleShape(63.78,33.33,115.11,3.57), Map.Width, Map.Height); mapEngine.BackgroundFillBrush = new GeoSolidBrush(GeoColor.GeographicColors.ShallowOcean); // Adds the static layers to the MapEngine ShapeFileFeatureLayer worldLayer = new ShapeFileFeatureLayer(@"..\..\Data\Countries02.shp", ShapeFileReadWriteMode.ReadOnly); worldLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Clear(); worldLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add (new AreaStyle(new GeoPen(GeoColor.StandardColors.Black), new GeoSolidBrush(GeoColor.StandardColors.LightPink))); //Adds the ScalingTextStyle to countries to have the country name displayed at a font size proportional to the scale. ScalingTextStyle scalingTextStyle = new ScalingTextStyle(GeographyUnit.DecimalDegree, "CNTRY_NAME", 31000000, 3000000, 18, 8); scalingTextStyle.TextSolidBrush = new GeoSolidBrush(GeoColor.StandardColors.Brown); scalingTextStyle.DuplicateRule = LabelDuplicateRule.NoDuplicateLabels; worldLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(scalingTextStyle); worldLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; mapEngine.StaticLayers.Add("WorldLayer", worldLayer); DrawImage(); } private void DrawImage() { if (bitmap != null) { bitmap.Dispose(); } bitmap = new Bitmap(Map.Width, Map.Height); mapEngine.OpenAllLayers(); mapEngine.DrawStaticLayers(bitmap, GeographyUnit.DecimalDegree); mapEngine.DrawDynamicLayers(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(); } private void Map_MouseMove(object sender, MouseEventArgs e) { //Displays the X and Y in screen coordinates. statusStrip1.Items["toolStripStatusLabelScreen"].Text = "X:" + e.X + " Y:" + e.Y; //Gets the PointShape in world coordinates from screen coordinates. PointShape pointShape = ExtentHelper.ToWorldCoordinate(mapEngine.CurrentExtent, new ScreenPointF(e.X, e.Y), Map.Width, Map.Height); //Displays world coordinates. statusStrip1.Items["toolStripStatusLabelWorld"].Text = "(world) X:" + Math.Round(pointShape.X, 4) + " Y:" + Math.Round(pointShape.Y, 4); } } }