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.ObjectModel; using ThinkGeo.MapSuite.Core; namespace LatLongGraticule { //this class inherits from AdornmentLayer. class GraticuleAdornmentLayer : AdornmentLayer { private enum LineType { Meridian, Parallel }; private Collection<double> intervals = new Collection<double>(); int graticuleDensity; private GeoColor graticuleColor; //Structure used for labeling the meridians and parallels at the desired location on the map in screen coordinates. private struct GraticuleLabel { public string label; public ScreenPointF location; public GraticuleLabel(string Label, ScreenPointF Location) { this.label = Label; this.location = Location; } } public GraticuleAdornmentLayer() { //This property gives the approximate density of lines that the map will have. this.graticuleDensity = 10; //The color of the lines this.graticuleColor = GeoColor.FromArgb(255, GeoColor.StandardColors.LightBlue); //Sets all the intervals in degree to be displayed. SetDefaultIntervals(); } //The intervals need to be added from the smallest to the largest. private void SetDefaultIntervals() { intervals.Add(0.0005); intervals.Add(0.001); intervals.Add(0.002); intervals.Add(0.005); intervals.Add(0.01); intervals.Add(0.02); intervals.Add(0.05); intervals.Add(0.1); intervals.Add(0.2); intervals.Add(0.5); intervals.Add(1); intervals.Add(2); intervals.Add(5); intervals.Add(10); intervals.Add(20); intervals.Add(40); intervals.Add(50); } protected override void DrawCore(GeoCanvas canvas, Collection<SimpleCandidate> labelsInAllLayers) { RectangleShape currentExtent = canvas.CurrentWorldExtent; double currentMinX = currentExtent.UpperLeftPoint.X; double currentMaxX = currentExtent.UpperRightPoint.X; double currentMaxY = currentExtent.UpperLeftPoint.Y; double currentMinY = currentExtent.LowerLeftPoint.Y; //Gets the increment according to the current extent of the map and the graticule density set //by the GrsaticuleDensity property double increment; increment = GetIncrement(currentExtent.Width, graticuleDensity); //Collections of GraticuleLabel for labeling the different lines. Collection<GraticuleLabel> meridianGraticuleLabels = new Collection<GraticuleLabel>(); Collection<GraticuleLabel> parallelGraticuleLabels = new Collection<GraticuleLabel>(); //Loop for displaying the meridians (lines of common longitude). double x = 0; for (x = CeilingNumber(currentExtent.UpperLeftPoint.X, increment); x <= currentExtent.UpperRightPoint.X; x += increment) { LineShape lineShapeMeridian = new LineShape(); lineShapeMeridian.Vertices.Add(new Vertex(x, currentMaxY)); lineShapeMeridian.Vertices.Add(new Vertex(x, currentMinY)); canvas.DrawLine(lineShapeMeridian, new GeoPen(graticuleColor,0.5F), DrawingLevel.LevelFour); //Gets the label and screen position of each meridian. ScreenPointF meridianLabelPosition = ExtentHelper.ToScreenCoordinate(canvas.CurrentWorldExtent,x,currentMaxY,canvas.Width,canvas.Height); meridianGraticuleLabels.Add(new GraticuleLabel(FormatLatLong(x,LineType.Meridian,increment), meridianLabelPosition)); } //Loop for displaying the parallels (lines of common latitude). double y = 0; for (y = CeilingNumber(currentExtent.LowerLeftPoint.Y, increment); y <= currentExtent.UpperRightPoint.Y; y += increment) { LineShape lineShapeParallel = new LineShape(); lineShapeParallel.Vertices.Add(new Vertex(currentMaxX, y)); lineShapeParallel.Vertices.Add(new Vertex(currentMinX, y)); canvas.DrawLine(lineShapeParallel, new GeoPen(graticuleColor, 0.5F), DrawingLevel.LevelFour); //Gets the label and screen position of each parallel. ScreenPointF parallelLabelPosition = ExtentHelper.ToScreenCoordinate(canvas.CurrentWorldExtent, currentMinX, y, canvas.Width, canvas.Height); parallelGraticuleLabels.Add(new GraticuleLabel(FormatLatLong(y,LineType.Parallel,increment), parallelLabelPosition)); } //Loop for displaying the label for the meridians. foreach (GraticuleLabel meridianGraticuleLabel in meridianGraticuleLabels) { Collection<ScreenPointF> locations = new Collection<ScreenPointF>(); locations.Add(new ScreenPointF(meridianGraticuleLabel.location.X, meridianGraticuleLabel.location.Y + 6)); canvas.DrawText(meridianGraticuleLabel.label, new GeoFont("Arial", 10), new GeoSolidBrush(GeoColor.StandardColors.Navy), new GeoPen(GeoColor.StandardColors.White, 2), locations, DrawingLevel.LevelFour, 8, 0, 0); } //Loop for displaying the label for the parallels. foreach (GraticuleLabel parallelGraticuleLabel in parallelGraticuleLabels) { Collection< ScreenPointF> locations = new Collection<ScreenPointF>(); locations.Add(new ScreenPointF(parallelGraticuleLabel.location.X,parallelGraticuleLabel.location.Y)); canvas.DrawText(parallelGraticuleLabel.label, new GeoFont("Arial", 10), new GeoSolidBrush(GeoColor.StandardColors.Navy), new GeoPen(GeoColor.StandardColors.White,2), locations, DrawingLevel.LevelFour, 8, 0, 90); } } //Formats the decimal degree value into Degree Minute and Seconds according to the increment. It also looks //if the longitude is East or West and the latitude North or South. private string FormatLatLong(double value, LineType lineType, double increment) { string result = ""; try { if (increment >= 1) { result = DecimalDegreesHelper.GetDegreesMinutesSecondsStringFromDecimalDegree(Math.Abs(value)); result = result.Substring(0, result.Length - 9); } else if (increment >= 0.1) { result = DecimalDegreesHelper.GetDegreesMinutesSecondsStringFromDecimalDegree(Math.Abs(value)); result = result.Substring(0, result.Length - 5); } else if (increment >= 0.01) { result = DecimalDegreesHelper.GetDegreesMinutesSecondsStringFromDecimalDegree(Math.Abs(value)); } else { result = DecimalDegreesHelper.GetDegreesMinutesSecondsStringFromDecimalDegree(Math.Abs(value), 2); } if (lineType == LineType.Meridian) { if (value > 0) result = result + " E"; else if (value < 0) result = result + " W"; } if (lineType == LineType.Parallel) { if (value > 0) result = result + " N"; else if (value < 0) result = result + " S"; } } catch { result = "N/A"; } finally {} return result; } //Function used for determining the degree value to use according to the interval. private double CeilingNumber(double Number, double Interval) { double result = 0; double IEEERemainder = Math.IEEERemainder(Number, Interval); if (IEEERemainder > 0) result = (Number - IEEERemainder) + Interval; else if (IEEERemainder < 0) result = Number + Math.Abs(IEEERemainder); else result = Number; return result; } //Gets the increment to used according to the with of the current extent and the graticule density. private double GetIncrement(double CurrentExtentWidth, double Divisor) { double result = 0; double rawInterval = CurrentExtentWidth / Divisor; int i = 0; foreach (double interval in intervals) { if (rawInterval < intervals[i]) { result = intervals[i]; break; } i++; } if (result == 0) result = intervals[intervals.Count|- 1]; return result; } } }
using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; namespace LatLongGraticule { 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.Windows.Forms; using ThinkGeo.MapSuite.Core; using ThinkGeo.MapSuite.DesktopEdition; namespace LatLongGraticule { public partial class TestForm : Form { public TestForm() { InitializeComponent(); } private void TestForm_Load(object sender, EventArgs e) { // Set the full extent and the background color winformsMap1.CurrentExtent = new RectangleShape(-120, 25, 20, -30); winformsMap1.BackgroundOverlay.BackgroundBrush = new GeoSolidBrush(GeoColor.FromArgb(255, 198, 255, 255)); // Add the static layers to the MapEngine ShapeFileFeatureLayer 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); LayerOverlay overLayer = new LayerOverlay(); overLayer.Layers.Add(worldLayer); winformsMap1.Overlays.Add("Overlay", overLayer); //Add the GraticuleAdormentLayer to the Adornment Layers of the MapEngine GraticuleAdornmentLayer graticuleAdornmentLayer = new GraticuleAdornmentLayer(); winformsMap1.AdornmentOverlay.Layers.Add("graticule", graticuleAdornmentLayer); winformsMap1.Refresh(); } //Displays the world coordinates for the mouse pointer in decimal degrees and Degrees Minutes Seconds form. private void winformsMap1_MouseMove(object sender, MouseEventArgs e) { PointShape worldPointShape = ExtentHelper.ToWorldCoordinate(winformsMap1.CurrentExtent, new ScreenPointF(e.X, e.Y), winformsMap1.Width, winformsMap1.Height); try { lblLongitudeDMS.Text = DecimalDegreesHelper.GetDegreesMinutesSecondsStringFromDecimalDegree(worldPointShape.X); lblLatitudeDMS.Text = DecimalDegreesHelper.GetDegreesMinutesSecondsStringFromDecimalDegree(worldPointShape.Y); lblLongitude.Text = System.Convert.ToString(worldPointShape.X); lblLatitude.Text = System.Convert.ToString(worldPointShape.Y); } catch { lblLongitudeDMS.Text = "N/A"; lblLatitudeDMS.Text = "N/A"; lblLongitude.Text = "N/A"; lblLatitude.Text = "N/A"; } finally { } } private void btnClose_Click(object sender, EventArgs e) { this.Close(); } } }