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.Configuration; using System.Data; using System.Linq; using System.Windows; namespace SnapToLayer2 { /// <summary> /// Interaction logic for App.xaml /// </summary> public partial class App : Application { } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Collections.ObjectModel; using ThinkGeo.MapSuite.Core; using ThinkGeo.MapSuite.WpfDesktopEdition; namespace SnapToLayer2 { public enum ToleranceCoordinates { World, Screen }; class SnapToLayerEditInteractiveOverlay : EditInteractiveOverlay { private PointStyle controlPointStyle; private PointStyle draggedControlPointStyle; private InMemoryFeatureLayer toSnapInMemoryFeatureLayer; private float tolerance; 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; } } protected override Feature MoveVertexCore(Feature sourceFeature, PointShape sourceControlPoint, PointShape targetControlPoint) { PointShape snapPointShape = null; if (toleranceType == ToleranceCoordinates.Screen) { snapPointShape = FindNearestSnappingPointPixel(targetControlPoint); } else { snapPointShape = FindNearestSnappingPoint(targetControlPoint); } return base.MoveVertexCore(sourceFeature, sourceControlPoint, snapPointShape ?? targetControlPoint); } //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) { MultipolygonShape multipolygonShape = (MultipolygonShape)toSnapInMemoryFeatures[0].GetShape(); foreach (PolygonShape polygonShape in multipolygonShape.Polygons) { 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; } protected override void DrawTileCore(GeoCanvas geoCanvas) { //Sets the geography Unit used in FindNearestSnappingPoint function geographyUnit = geoCanvas.MapUnit; currentWorldExtent = geoCanvas.CurrentWorldExtent; mapWidth = geoCanvas.Width; mapHeight = geoCanvas.Height; //Draws the Edit Shapes as default. Collection<SimpleCandidate> labelsInAllLayers = new Collection<SimpleCandidate>(); EditShapesLayer.Open(); EditShapesLayer.Draw(geoCanvas, labelsInAllLayers); geoCanvas.Flush(); //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, geoCanvas, labelsInAllLayers, labelsInAllLayers); } else { Feature[] features = new Feature[1] { feature }; draggedControlPointStyle.Draw(features, geoCanvas, labelsInAllLayers, labelsInAllLayers); } } } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Shapes; using System.Collections.ObjectModel; using ThinkGeo.MapSuite.Core; using ThinkGeo.MapSuite.WpfDesktopEdition; namespace SnapToLayer2 { /// <summary> /// Interaction logic for TestWindow.xaml /// </summary> public partial class TestWindow : Window { public TestWindow() { InitializeComponent(); } private void Window_Loaded(object sender, RoutedEventArgs e) { //Sets the correct map unit and the extent of the map. wpfMap1.MapUnit = GeographyUnit.Feet; wpfMap1.CurrentExtent = new RectangleShape(2468268,7111899,2469766,7110811); BackgroundOverlay backGroundOverlay = new BackgroundOverlay(); backGroundOverlay.BackgroundBrush = new GeoSolidBrush(GeoColor.StandardColors.LightGoldenrodYellow); wpfMap1.BackgroundOverlay = backGroundOverlay; //Backgrounbd layer for streets. ShapeFileFeatureLayer shapefileFeatureLayer1 = new ShapeFileFeatureLayer(@"../../Data/Streets.shp"); shapefileFeatureLayer1.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = LineStyles.LocalRoad3; shapefileFeatureLayer1.ZoomLevelSet.ZoomLevel01.DefaultTextStyle = TextStyles.LocalRoad3("ROAD_NAME"); shapefileFeatureLayer1.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; LayerOverlay layerOverlay = new LayerOverlay(); layerOverlay.Layers.Add("Streets", shapefileFeatureLayer1); wpfMap1.Overlays.Add(layerOverlay); //inMemoryFeatureLayer used to be snapped to. InMemoryFeatureLayer polygonInMemoryFeatureLayer = new InMemoryFeatureLayer(); polygonInMemoryFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.Park1; polygonInMemoryFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = PointStyles.CreateSimpleCircleStyle (GeoColor.StandardColors.Transparent, 25, GeoColor.StandardColors.Black); polygonInMemoryFeatureLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; InMemoryFeatureLayer pointInMemoryFeatureLayer = new InMemoryFeatureLayer(); TolerancePointStyle tolerancePointStyle = new TolerancePointStyle(); tolerancePointStyle.Tolerance = 25; tolerancePointStyle.ToleranceType = ToleranceCoordinates.Screen; pointInMemoryFeatureLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(tolerancePointStyle); pointInMemoryFeatureLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; ShapeFileFeatureSource shapeFileFeatureSource = new ShapeFileFeatureSource(@"..\..\data\Parks.shp"); shapeFileFeatureSource.Open(); Collection<Feature> features = shapeFileFeatureSource.GetAllFeatures(ReturningColumnsType.NoColumns); foreach (Feature feature in features) { polygonInMemoryFeatureLayer.InternalFeatures.Add(feature); MultipolygonShape multipolygonShape = (MultipolygonShape)feature.GetShape(); foreach (PolygonShape polygonShape in multipolygonShape.Polygons) { foreach (Vertex vertex in polygonShape.OuterRing.Vertices) { pointInMemoryFeatureLayer.InternalFeatures.Add(new Feature(new PointShape(vertex))); } } } shapeFileFeatureSource.Close(); LayerOverlay inMemoryOverlay = new LayerOverlay(); inMemoryOverlay.Layers.Add("InMemoryFeatureLayer", polygonInMemoryFeatureLayer); inMemoryOverlay.Layers.Add("PointInMemoryFeatureLayer", pointInMemoryFeatureLayer); wpfMap1.Overlays.Add("InMemoryOverlay", inMemoryOverlay); //SnapToLayerEditInteractiveOverlay to snap dragged control point to nearest vertex of layer if within tolerance. SnapToLayerEditInteractiveOverlay snapToLayerEditInteractiveOverlay = new SnapToLayerEditInteractiveOverlay(); LineShape lineShape = new LineShape(); lineShape.Vertices.Add(new Vertex(2468665, 7111734)); lineShape.Vertices.Add(new Vertex(2468560, 7111376)); lineShape.Vertices.Add(new Vertex(2468569, 7110947)); snapToLayerEditInteractiveOverlay.EditShapesLayer.InternalFeatures.Add("MultiLine", new Feature(lineShape)); //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(); wpfMap1.EditOverlay = snapToLayerEditInteractiveOverlay; wpfMap1.TrackOverlay.TrackMode = TrackMode.None; wpfMap1.Refresh(); } private void wpfMap1_MouseMove(object sender, MouseEventArgs e) { //Gets the PointShape in world coordinates from screen coordinates. Point point = e.MouseDevice.GetPosition(null); ScreenPointF screenPointF = new ScreenPointF((float)point.X, (float)point.Y); PointShape pointShape = ExtentHelper.ToWorldCoordinate(wpfMap1.CurrentExtent, screenPointF, (float)wpfMap1.Width, (float)wpfMap1.Height); textBox1.Text = "X: " + Math.Round(pointShape.X,2) + " Y: " + Math.Round(pointShape.Y,2); } } }
using System.Collections.Generic; using System.Drawing; using ThinkGeo.MapSuite.Core; using ThinkGeo.MapSuite.WpfDesktopEdition; namespace SnapToLayer2 { class TolerancePointStyle : PointStyle { private float tolerance; private DistanceUnit toleranceUnit; private ToleranceCoordinates toleranceType; 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; } } protected override void DrawCore(IEnumerable<Feature> features, GeoCanvas canvas, System.Collections.ObjectModel.Collection<SimpleCandidate> labelsInThisLayer, System.Collections.ObjectModel.Collection<SimpleCandidate> labelsInAllLayers) { foreach (Feature feature in features) { //Draws the vertex. PointShape pointShape = (PointShape)feature.GetShape(); 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); } } } } }