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 SnapToLayer { 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.ObjectModel; using ThinkGeo.MapSuite.Core; using ThinkGeo.MapSuite.DesktopEdition; namespace SnapToLayer { public enum ToleranceCoordinates { World, Screen }; class SnapToLayerEditInteractiveOverlay : EditInteractiveOverlay { private PointStyle controlPointStyle; private PointStyle draggedControlPointStyle; private InMemoryFeatureLayer toSnapInMemoryFeatureLayer; private float tolerance; //private int tolerancePixel; private DistanceUnit toleranceUnit; private GeographyUnit geographyUnit; private RectangleShape currentWorldExtent; private float mapWidth; private float mapHeight; private ToleranceCoordinates toleranceType; //Property for the non dragged control point style. public PointStyle ControlPointStyle { get { return controlPointStyle; } set { controlPointStyle = value; } } //Property for the dragged control point style. public PointStyle DraggedControlPointStyle { get { return draggedControlPointStyle; } set { draggedControlPointStyle = value; } } //InMemoryFeatureLayer for the layer to be snapped to. public InMemoryFeatureLayer ToSnapInMemoryFeatureLayer { get { return toSnapInMemoryFeatureLayer; } set { toSnapInMemoryFeatureLayer = value; } } public ToleranceCoordinates ToleranceType { get { return toleranceType; } set { toleranceType = value; } } public float Tolerance { get { return tolerance; } set { tolerance = value; } } public DistanceUnit ToleranceUnit { get { return toleranceUnit; } set { toleranceUnit = value; } } //Overrides the MoveVertexCore to have the logic to check if the dragged control point is within tolerance. protected override Feature MoveVertexCore(Feature sourceFeature, PointShape sourceControlPoint, PointShape targetControlPoint) { VertexMovingEditInteractiveOverlayEventArgs vertexMovingEditInteractiveOverlayEventArgs = new VertexMovingEditInteractiveOverlayEventArgs(false, sourceFeature, new Vertex(targetControlPoint)); PointShape snapPointShape = null; if (toleranceType == ToleranceCoordinates.Screen) { snapPointShape = FindNearestSnappingPointPixel(targetControlPoint); } else { snapPointShape = FindNearestSnappingPoint(targetControlPoint); } if (snapPointShape != null) { vertexMovingEditInteractiveOverlayEventArgs.MovingVertex = new Vertex(snapPointShape); } return base.MoveVertexCore(sourceFeature, sourceControlPoint, new PointShape(vertexMovingEditInteractiveOverlayEventArgs.MovingVertex)); } //Function to find if dragged control point is within the tolerance of a vertex of layer in screen (pixels) coordinates. private PointShape FindNearestSnappingPointPixel(PointShape targetPointShape) { toSnapInMemoryFeatureLayer.Open(); Collection<Feature> toSnapInMemoryFeatures = toSnapInMemoryFeatureLayer.FeatureSource.GetFeaturesNearestTo(targetPointShape, GeographyUnit.Meter, 1, ReturningColumnsType.AllColumns); toSnapInMemoryFeatureLayer.Close(); if (toSnapInMemoryFeatures.Count == 1) { PolygonShape polygonShape = (PolygonShape)toSnapInMemoryFeatures[0].GetShape(); foreach (Vertex vertex in polygonShape.OuterRing.Vertices) { PointShape toSnapPointShape = new PointShape(vertex); float screenDistance = ExtentHelper.GetScreenDistanceBetweenTwoWorldPoints(currentWorldExtent, toSnapPointShape, targetPointShape, mapWidth, mapHeight); if (screenDistance <= tolerance) { return new PointShape(toSnapPointShape.X, toSnapPointShape.Y); } } } return null; } //Function to find if dragged control point is within the tolerance of a vertex of layer in world coordinates. private PointShape FindNearestSnappingPoint(PointShape targetPointShape) { toSnapInMemoryFeatureLayer.Open(); Collection<Feature> toSnapInMemoryFeatures = toSnapInMemoryFeatureLayer.FeatureSource.GetFeaturesNearestTo(targetPointShape, GeographyUnit.Meter, 1, ReturningColumnsType.AllColumns); toSnapInMemoryFeatureLayer.Close(); if (toSnapInMemoryFeatures.Count == 1) { PolygonShape polygonShape = (PolygonShape)toSnapInMemoryFeatures[0].GetShape(); foreach (Vertex vertex in polygonShape.OuterRing.Vertices) { PointShape toSnapPointShape = new PointShape(vertex); double Distance = toSnapPointShape.GetDistanceTo(targetPointShape, geographyUnit, toleranceUnit); if (Distance <= tolerance) { return new PointShape(toSnapPointShape.X, toSnapPointShape.Y); } } } return null; } //Overrides the DrawCore function to draw the Edit Layers, the vertices and tolerance ellipses of layer to snap to, //and the control points. protected override void DrawCore(GeoCanvas canvas) { //Sets the geography Unit used in FindNearestSnappingPoint function geographyUnit = canvas.MapUnit; currentWorldExtent = canvas.CurrentWorldExtent; mapWidth = canvas.Width; mapHeight = canvas.Height; //Draws the Edit Shapes as default. Collection<SimpleCandidate> labelsInAllLayers = new Collection<SimpleCandidate>(); EditShapesLayer.Open(); EditShapesLayer.Draw(canvas, labelsInAllLayers); canvas.Flush(); //Draw the vertices and tolerance ellipses of layer to snap to. toSnapInMemoryFeatureLayer.Open(); Collection<Feature> toSnapPoints = toSnapInMemoryFeatureLayer.FeatureSource.GetAllFeatures(ReturningColumnsType.AllColumns); toSnapInMemoryFeatureLayer.Close(); foreach (Feature feature in toSnapPoints) { PolygonShape polygonShape = (PolygonShape)feature.GetShape(); foreach (Vertex vertex in polygonShape.OuterRing.Vertices) { //Draws the vertex. PointShape pointShape = new PointShape(vertex); canvas.DrawEllipse(pointShape, 5, 5, new GeoSolidBrush(GeoColor.StandardColors.Black), DrawingLevel.LevelOne); //Draws the tolerance ellipse. if (toleranceType == ToleranceCoordinates.Screen) { ScreenPointF screenPointF = ExtentHelper.ToScreenCoordinate(canvas.CurrentWorldExtent, pointShape, canvas.Width, canvas.Height); canvas.DrawEllipse(screenPointF, tolerance * 2, tolerance * 2, new GeoPen(GeoColor.StandardColors.Black), new GeoSolidBrush(), DrawingLevel.LevelFour, 0, 0, PenBrushDrawingOrder.PenFirst); } else { EllipseShape ellipseShape = new EllipseShape(pointShape, tolerance, canvas.MapUnit, toleranceUnit); canvas.DrawArea(ellipseShape, new GeoPen(GeoColor.StandardColors.Black), DrawingLevel.LevelOne); } } } //Draws the control points. ExistingControlPointsLayer.Open(); Collection<Feature> controlPoints = ExistingControlPointsLayer.FeatureSource.GetAllFeatures(ReturningColumnsType.AllColumns); //Loops thru the control points. foreach (Feature feature in controlPoints) { //Looks at the value of "state" to draw the control point as dragged or not. if (feature.ColumnValues["state"] != "selected") { Feature[] features = new Feature[1] { feature }; controlPointStyle.Draw(features, canvas, labelsInAllLayers, labelsInAllLayers); } else { Feature[] features = new Feature[1] { feature }; draggedControlPointStyle.Draw(features, canvas, labelsInAllLayers, labelsInAllLayers); } } } } }
using System; using System.IO; using System.Windows.Forms; using ThinkGeo.MapSuite.Core; using ThinkGeo.MapSuite.DesktopEdition; namespace SnapToLayer { public partial class TestForm : Form { public TestForm() { InitializeComponent(); } private void TestForm_Load(object sender, EventArgs e) { winformsMap1.MapUnit = GeographyUnit.DecimalDegree; winformsMap1.CurrentExtent = new RectangleShape(-97.7591, 30.3126, -97.7317, 30.2964); winformsMap1.BackgroundOverlay.BackgroundBrush = new GeoSolidBrush(GeoColor.FromArgb(255, 198, 255, 255)); //Displays the World Map Kit as a background. ThinkGeo.MapSuite.DesktopEdition.WorldMapKitWmsDesktopOverlay worldMapKitDesktopOverlay = new ThinkGeo.MapSuite.DesktopEdition.WorldMapKitWmsDesktopOverlay(); winformsMap1.Overlays.Add(worldMapKitDesktopOverlay); string fileName1 = @"..\..\data\polygon.txt"; StreamReader sr1 = new StreamReader(fileName1); string fileName2 = @"..\..\data\line.txt"; StreamReader sr2 = new StreamReader(fileName2); //SnapToLayerEditInteractiveOverlay to snap dragged control point to nearest vertex of layer if within tolerance. SnapToLayerEditInteractiveOverlay snapToLayerEditInteractiveOverlay = new SnapToLayerEditInteractiveOverlay(); //inMemoryFeatureLayer used to be snapped to. InMemoryFeatureLayer polygonInMemoryFeatureLayer = new InMemoryFeatureLayer(); polygonInMemoryFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.Park1; polygonInMemoryFeatureLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; polygonInMemoryFeatureLayer.InternalFeatures.Add("Polygon", new Feature(BaseShape.CreateShapeFromWellKnownData(sr1.ReadLine()))); LayerOverlay inMemoryOverlay = new LayerOverlay(); inMemoryOverlay.Layers.Add("InMemoryFeatureLayer", polygonInMemoryFeatureLayer); winformsMap1.Overlays.Add("InMemoryOverlay", inMemoryOverlay); snapToLayerEditInteractiveOverlay.EditShapesLayer.InternalFeatures.Add("MultiLine", new Feature(BaseShape.CreateShapeFromWellKnownData(sr2.ReadLine()))); //Sets the PointStyle for the non dragged control points. snapToLayerEditInteractiveOverlay.ControlPointStyle = new PointStyle(PointSymbolType.Circle, new GeoSolidBrush(GeoColor.StandardColors.PaleGoldenrod), new GeoPen(GeoColor.StandardColors.Black), 8); //Sets the PointStyle for the dragged control points. snapToLayerEditInteractiveOverlay.DraggedControlPointStyle = new PointStyle(PointSymbolType.Circle, new GeoSolidBrush(GeoColor.StandardColors.Red), new GeoPen(GeoColor.StandardColors.Orange, 2), 10); snapToLayerEditInteractiveOverlay.ToSnapInMemoryFeatureLayer = polygonInMemoryFeatureLayer; //Example using Screen (Pixel) coordinates for tolerance. snapToLayerEditInteractiveOverlay.ToleranceType = ToleranceCoordinates.Screen; snapToLayerEditInteractiveOverlay.Tolerance = 25; //Example using World coordinates for tolerance. //snapToLayerEditInteractiveOverlay.ToleranceType = ToleranceCoordinates.World; //snapToLayerEditInteractiveOverlay.Tolerance = 150; //snapToLayerEditInteractiveOverlay.ToleranceUnit = DistanceUnit.Meter; snapToLayerEditInteractiveOverlay.CalculateAllControlPoints(); winformsMap1.EditOverlay = snapToLayerEditInteractiveOverlay; winformsMap1.Refresh(); } private void winformsMap1_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(winformsMap1.CurrentExtent, new ScreenPointF(e.X, e.Y), winformsMap1.Width, winformsMap1.Height); //Displays world coordinates. statusStrip1.Items["toolStripStatusLabelWorld"].Text = "(world) X:" + Math.Round(pointShape.X, 4) + " Y:" + Math.Round(pointShape.Y, 4); } private void btnClose_Click(object sender, EventArgs e) { this.Close(); } } }