ThinkGeo.com    |     Documentation    |     Premium Support

Snapping help needed

Hi Guys,


I need a liitle help on snapping, I am almost there but just missing something.


Using the EditOverlay_MapMouseUp, I have the vertex that was moved, I have the point to snap the vertex to in map coordinates.  How do you move the vertex to the snapped point and then update the ControlPoints and the underlying data.


Been playing with this for hours now, the help contradicts itself, I can't find the MoveVertex call and am getting very frustrated, a half decent example would help!


Regards


John


 



John,


I have created a sample to show how to extend EditOverlay and make it can snapped select a vertex.


Please let me know if you have questions


Thanks


James



1500-SnappingEdit.zip (11.6 KB)

Hi James,


Thanks for that, not quite what I was expecting.


The objective of 'snapping' whilst editing would be to 'snap' or move a control point to the position of a point from another layer.


The source below shows a partially implemented soloution, we are just missing the 'update' bit.


 


using System; using System.Collections.ObjectModel; using System.Drawing; using System.Windows.Forms; using ThinkGeo.MapSuite.Core; using ThinkGeo.MapSuite.DesktopEdition; namespace SnappingEdit { public partial class Form1 : Form { private InMemoryFeatureLayer _snappingLines; private InMemoryFeatureLayer _snappingPoints; private LayerOverlay _staticOverlay; private InteractionArguments _args; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { winformsMap1.MapUnit = GeographyUnit.Meter; winformsMap1.CurrentExtent = new RectangleShape(0, 1000000, 1000000, 0); winformsMap1.BackgroundOverlay.BackgroundBrush = new GeoSolidBrush(GeoColor.StandardColors.White); _editor = winformsMap1.EditOverlay = _editor; _snappingLines = new InMemoryFeatureLayer(); _snappingLines.InternalFeatures.Add("Line", new Feature(BaseShape.CreateShapeFromWellKnownData( "LINESTRING(600000 600000, 700000 700000,750000 600000, 800000 700000, 850000 600000,950000 800000)"))); _snappingLines.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = LineStyles.Equator1; _snappingLines.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; _staticOverlay = new LayerOverlay(); _staticOverlay.Layers.Add(_snappingLines); _snappingPoints = new InMemoryFeatureLayer(); _snappingPoints.InternalFeatures.Add(new Feature(BaseShape.CreateShapeFromWellKnownData( "POINT(600000 600000)"))); _snappingPoints.InternalFeatures.Add(new Feature(BaseShape.CreateShapeFromWellKnownData( "POINT(700000 700000)"))); _snappingPoints.InternalFeatures.Add(new Feature(BaseShape.CreateShapeFromWellKnownData( "POINT(750000 600000)"))); _snappingPoints.InternalFeatures.Add(new Feature(BaseShape.CreateShapeFromWellKnownData( "POINT(800000 700000)"))); _snappingPoints.InternalFeatures.Add(new Feature(BaseShape.CreateShapeFromWellKnownData( "POINT(850000 600000)"))); _snappingPoints.InternalFeatures.Add(new Feature(BaseShape.CreateShapeFromWellKnownData( "POINT(950000 800000)"))); _snappingPoints.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = PointStyles.City3; _snappingPoints.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; _staticOverlay.Layers.Add(_snappingPoints); winformsMap1.Overlays.Add(_staticOverlay); _editor.EditShapesLayer.InternalFeatures.Add("Line", new Feature(BaseShape.CreateShapeFromWellKnownData( "LINESTRING(800000 800000, 900000 900000,1000000 1000000)"))); _editor.CanAddVertex = false; _editor.CanDrag = false; _editor.CanRemoveVertex = false; _editor.CanResize = false; _editor.CanRotate = false; _editor.CalculateAllControlPoints(); _editor.MapMouseMove += _editor_MapMouseMove; _editor.VertexMoving += _editor_VertexMoving; winformsMap1.Refresh(); } void _editor_mapmousemove(object sender, mapmousemoveinteractiveoverlayeventargs e) { _args = e.interactionarguments; } private PointShape FindNearestSnappingPoint(PointShape aPos) { Int32 tolerance = (Int32)(winformsMap1.CurrentScale / 200); Collection<feature> wpts = _snappingPoints.QueryTools.GetFeaturesNearestTo(aPos, GeographyUnit.Meter, 1, ReturningColumnsType.NoColumns); int aDist = (int)aPos.GetDistanceTo(wpts[0].GetShape(), GeographyUnit.Meter, DistanceUnit.Meter); if (aDist < tolerance) return (PointShape)wpts[0].GetShape(); return null; } // The objective here is to allow any of the edited control points to 'snap' to any of the points in _snappingPoints void _editor_VertexMoving(object sender, VertexMovingEditInteractiveOverlayEventArgs e) { // Only do snapping if the shift key is used if(ModifierKeys == Keys.Shift) { // Find a point from the _snappingPoints layer that will be the target to snap to _snapToPoint = FindNearestSnappingPoint(new PointShape(_args.WorldX,_args.WorldY)); if (_snapToPoint != null) { // Here we know that we want to snap (move) the control point that is being dragged to the position of _snapPoint and update // the controlpoint position, the underrlying data and the mouse position } } } } } 


Hope this helps to explain the problem


John



Today, we posted a new project in the Code Community that shows how to have the mouse pointer snapping to the nearest vertex for dragging it. It is not exactly what you are waiting for but early next week, we will work on an InteractiveOverlay for snapping vertices within a tolerance based on another layer as your expections are. Thank you. 
  
 code.thinkgeo.com/projects/show/snappingtovertex 


John,


I have updated your code and now is what you exactly want.


Begin,



If you press the shift key and drag, it will snap to a point from another layer,



Please let me know if you have questions.


Thanks


James



1503-SnapALayer.zip (11.3 KB)

Hi James,


That's perfect, just what I was looking for.


John


 



John, 
  
 It’s awesome you got it. 
  
 James

Hello, 
  
 I integrated the above code in my project and it is not working with the 
 e.MovingVertex=New Vertex(_snapToPoint)  
 but it works with 
 e.TargetVertex=New Vertex(_snapToPoint)   
 while in the provided solution above it works fine without changing anything. 
  
 Can you please explain the difference between MovingVertex and TargetVertex because it is not very clear in the documentation? 
  
 Regards, 
  
 Arber

Hello Arber, 
  
 “MovingVertex” and “TargetVertex” are all in “MoveVertexCore”. The “TargetVertex” means a target point when the vertex was moved, but the “MovingVertex” was sent to user codes and the user can modify “MovingVertex” when the VertexMoving event was raised. 
  
 Regards, 
  
 Gary