# SnapTo feature--need help

**URL:** <https://community.thinkgeo.com/t/snapto-feature-need-help/3685>\
**Category:** WPF\
**Created:** [June 30, 2014, 2:16pm UTC](https://community.thinkgeo.com/t/snapto-feature-need-help/3685 "2014-06-30T14:16:48Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Scott2](https://community.thinkgeo.com/letter_avatar_proxy/v4/letter/s/82dd89/32.png) [@Scott2](https://community.thinkgeo.com/u/Scott2)\
**Post date:** [June 30, 2014, 2:16pm UTC](https://community.thinkgeo.com/t/snapto-feature-need-help/3685/1 "2014-06-30T14:16:48Z")

</div>

Hello&nbsp;all.&nbsp;&nbsp;  
  
  
  
We&nbsp;are&nbsp;using&nbsp;the&nbsp;ThinkGeo&nbsp;WPF&nbsp;7.0&nbsp;version.  
  
  
  
I&nbsp;need&nbsp;an&nbsp;ability&nbsp;to&nbsp;snap&nbsp;to&nbsp;an&nbsp;existing&nbsp;polygon.&nbsp;&nbsp;I&nbsp;have&nbsp;seen&nbsp;the&nbsp;current&nbsp;samples.&nbsp;&nbsp;That&nbsp;doesn’t&nbsp;handle&nbsp;our&nbsp;exact&nbsp;issue.&nbsp;&nbsp;What&nbsp;we&nbsp;need&nbsp;is&nbsp;when&nbsp;the&nbsp;chooses&nbsp;to&nbsp;draw&nbsp;a&nbsp;line&nbsp;on&nbsp;the&nbsp;map,&nbsp;we&nbsp;need&nbsp;the&nbsp;cursor&nbsp;to&nbsp;snap&nbsp;to&nbsp;a&nbsp;given&nbsp;polygon.&nbsp;&nbsp;We&nbsp;have&nbsp;it&nbsp;working&nbsp;after&nbsp;the&nbsp;user&nbsp;has&nbsp;already&nbsp;added&nbsp;one&nbsp;vertex.&nbsp;&nbsp;What&nbsp;isn’t&nbsp;working&nbsp;is&nbsp;snapping&nbsp;for&nbsp;the&nbsp;first&nbsp;vertex.&nbsp;&nbsp;  
  
  
  
It&nbsp;seems&nbsp;the&nbsp;MouseMoved&nbsp;event&nbsp;of&nbsp;the&nbsp;Map.TrackOverlay&nbsp;object&nbsp;will&nbsp;not&nbsp;fire&nbsp;until&nbsp;after&nbsp;the&nbsp;shape&nbsp;has&nbsp;already&nbsp;started&nbsp;(ie:&nbsp;user&nbsp;has&nbsp;chosen&nbsp;the&nbsp;first&nbsp;vertex&nbsp;for&nbsp;the&nbsp;line).&nbsp;&nbsp;  
  
  
  
Is&nbsp;there&nbsp;a&nbsp;way&nbsp;for&nbsp;us&nbsp;to&nbsp;snap&nbsp;the&nbsp;cursor&nbsp;to&nbsp;the&nbsp;polygon&nbsp;before&nbsp;adding&nbsp;the&nbsp;first&nbsp;vertex?

---

<div class="post-metadata">

**Author:** ![Ethan](https://community.thinkgeo.com/user_avatar/community.thinkgeo.com/ethan/32/19964_2.png) [@Ethan](https://community.thinkgeo.com/u/Ethan)\
**Post date:** [July 1, 2014, 12:37am UTC](https://community.thinkgeo.com/t/snapto-feature-need-help/3685/2 "2014-07-01T00:37:34Z")

</div>

Hi&nbsp;Scott,&nbsp;  
&nbsp;&nbsp;  
&nbsp;Are&nbsp;you&nbsp;using&nbsp;Map1.TrackOverlay.MouseMoved&nbsp;event?&nbsp;I&nbsp;think&nbsp;Map1.TrackOverlay.MapMouseMove&nbsp;can&nbsp;works&nbsp;for&nbsp;you.&nbsp;  
&nbsp;&nbsp;  
&nbsp;Regards,&nbsp;  
&nbsp;&nbsp;  
&nbsp;Don

---

<div class="post-metadata">

**Author:** ![Scott2](https://community.thinkgeo.com/letter_avatar_proxy/v4/letter/s/82dd89/32.png) [@Scott2](https://community.thinkgeo.com/u/Scott2)\
**Post date:** [July 1, 2014, 6:04am UTC](https://community.thinkgeo.com/t/snapto-feature-need-help/3685/3 "2014-07-01T06:04:00Z")

</div>

Yes,&nbsp;that&nbsp;is&nbsp;the&nbsp;event&nbsp;I&nbsp;am&nbsp;using.&nbsp;&nbsp;I’ll&nbsp;try&nbsp;the&nbsp;MapMouseMove.

---

<div class="post-metadata">

**Author:** ![Scott2](https://community.thinkgeo.com/letter_avatar_proxy/v4/letter/s/82dd89/32.png) [@Scott2](https://community.thinkgeo.com/u/Scott2)\
**Post date:** [July 1, 2014, 10:08am UTC](https://community.thinkgeo.com/t/snapto-feature-need-help/3685/4 "2014-07-01T10:08:43Z")

</div>

That&nbsp;is&nbsp;the&nbsp;event&nbsp;I&nbsp;needed.&nbsp;&nbsp;Thanks.&nbsp;&nbsp;The&nbsp;issue&nbsp;I&nbsp;have&nbsp;now&nbsp;is&nbsp;that&nbsp;the&nbsp;cursor&nbsp;is&nbsp;not&nbsp;moving&nbsp;to&nbsp;what&nbsp;I&nbsp;am&nbsp;trying&nbsp;to&nbsp;move&nbsp;it&nbsp;too.&nbsp;  
  
  
  
After&nbsp;I&nbsp;get&nbsp;the&nbsp;correct&nbsp;coordinates&nbsp;I&nbsp;try&nbsp;setting&nbsp;the&nbsp;ScreenX&nbsp;&&nbsp;ScreenY&nbsp;properties&nbsp;on&nbsp;the&nbsp;InteractionArguments&nbsp;object&nbsp;of&nbsp;MapMouseMoveInteractiveOverlayEventArgs.&nbsp;&nbsp;However&nbsp;after&nbsp;I&nbsp;set&nbsp;that,&nbsp;no&nbsp;change&nbsp;appears&nbsp;to&nbsp;be&nbsp;made.&nbsp;

> `private`&nbsp;`void`&nbsp;`MouseMoved(``object`&nbsp;`sender, MapMouseMoveInteractiveOverlayEventArgs e)`  
> `        ``{`  
> `            ``try`  
> `            ``{`  
> `                ``if`&nbsp;`(Map.TrackOverlay.TrackMode == TrackMode.Circle || Map.TrackOverlay.TrackMode == TrackMode.Point)`  
> `                    ``return``;`  
> &nbsp;  
> `                ``if`&nbsp;`(!ViewModel.IsUsingTouch) CalculateDrawingDimensionsAndDisplay();`  
> `                ``if`&nbsp;`(!ViewModel.SnapOn || ViewModel.CurrentGeometryType == GeometryType.None || ViewModel.CurrentGeometryType == GeometryType.Circle) ``return``;`  
> &nbsp;  
> `                ``LayerOverlay overlay;`  
> `                ``InMemoryFeatureLayer layer;`  
> `                ``switch`&nbsp;`(ViewModel.CurrentEditor)`  
> `                ``{`  
> `                    ``case`&nbsp;`Editor.Design:`  
> `                        ``overlay = (LayerOverlay)Map.Overlays[PROPOSAL_OVERLAY];`  
> `                        ``layer = (InMemoryFeatureLayer)overlay.Layers[PROPOSAL_LAYER];`  
> `                        ``break``;`  
> `                    ``default``:`  
> `                        ``overlay = (LayerOverlay)Map.Overlays[LAYOUT_OVERLAY];`  
> `                        ``layer = (InMemoryFeatureLayer)overlay.Layers[LAYOUT_LAYER];`  
> `                        ``break``;`  
> `                ``}`  
> &nbsp;  
> `                ``layer.FeatureSource.Open();`  
> `                ``MapUtilities.SnapToFeature(e, layer.InternalFeatures, TOLERANCE, Map.MapUnit, Map);`  
> `                ``layer.FeatureSource.Close();`  
> `            ``}`  
> `            ``catch`&nbsp;`(Exception ex)`  
> `            ``{`  
> `                ``LogHost.Default.Error(ex.ToString());`  
> `            ``}`  
> `        ``}`  
> `public`&nbsp;`static`&nbsp;`void`&nbsp;`SnapToFeature(MapMouseMoveInteractiveOverlayEventArgs e, GeoCollection features, ``float`&nbsp;`tolerance, GeographyUnit mapUnit, WpfMap map)`  
> `        ``{`  
> `            ``try`  
> `            ``{`  
> `                ``var newMovedVertex = ``new`&nbsp;`Vertex();`  
> `                ``var lowestDistance = ``double``.MaxValue;`  
> &nbsp;  
> `                ``foreach`&nbsp;`(var feature ``in`&nbsp;`features)`  
> `                ``{`  
> `                    ``switch`&nbsp;`(feature.GetShape().GetWellKnownType())`  
> `                    ``{`  
> `                        ``case`&nbsp;`WellKnownType.Polygon:`  
> `                            ``FindSnapToPointOnPolygon(e, mapUnit, ``ref`&nbsp;`newMovedVertex, ``ref`&nbsp;`lowestDistance, feature.GetShape() ``as`&nbsp;`PolygonShape, map);`  
> `                            ``break``;`  
> `                    ``}`  
> `                ``}`  
> `                ``if`&nbsp;`(!(lowestDistance <= tolerance)) ``return``;`  
> &nbsp;  
> `                ``var screenCoordinate = ExtentHelper.ToScreenCoordinate(map.CurrentExtent, ``new`&nbsp;`Feature(newMovedVertex), (``float``) map.CurrentExtent.Width, (``float``) map.CurrentExtent.Height);`  
> &nbsp;  
> `                ``e.InteractionArguments.ScreenX = screenCoordinate.X;`  
> `                ``e.InteractionArguments.ScreenY = screenCoordinate.Y;`  
> `            ``}`  
> `            ``catch`&nbsp;`(Exception ex)`  
> `            ``{`  
> `                ``LogHost.Default.ErrorException(ex.ToString(), ex);`  
> `            ``}`  
> `        ``}`  
> &nbsp;  
> `private`&nbsp;`static`&nbsp;`void`&nbsp;`FindSnapToPointOnPolygon(MapMouseMoveInteractiveOverlayEventArgs e, GeographyUnit mapUnit, ``ref`&nbsp;`Vertex newMovedVertex, ``ref`&nbsp;`double`&nbsp;`lowestDistance, PolygonShape polygon, WpfMap map)`  
> `        ``{`  
> `            ``var polygonDistance = ``double``.MaxValue;`  
> `            ``var nearestPoint = ``new`&nbsp;`PointShape();`  
> `            ``for`&nbsp;`(var i = 0; i < polygon.OuterRing.Vertices.Count - 1; i++)`  
> `            ``{`  
> `                ``var line = ``new``[] { polygon.OuterRing.Vertices, polygon.OuterRing.Vertices[i + 1] };`  
> `                ``var minx = polygon.OuterRing.Vertices.X > polygon.OuterRing.Vertices[i + 1].X ? polygon.OuterRing.Vertices[i + 1].X : polygon.OuterRing.Vertices.X;`  
> `                ``var maxx = polygon.OuterRing.Vertices.X < polygon.OuterRing.Vertices[i + 1].X ? polygon.OuterRing.Vertices[i + 1].X : polygon.OuterRing.Vertices.X;`  
> `                ``var miny = polygon.OuterRing.Vertices.Y > polygon.OuterRing.Vertices[i + 1].Y ? polygon.OuterRing.Vertices[i + 1].Y : polygon.OuterRing.Vertices.Y;`  
> `                ``var maxy = polygon.OuterRing.Vertices.Y < polygon.OuterRing.Vertices[i + 1].Y ? polygon.OuterRing.Vertices[i + 1].Y : polygon.OuterRing.Vertices.Y;`  
> &nbsp;  
> `                ``var screenPointF = ``new`&nbsp;`ScreenPointF(e.InteractionArguments.ScreenX, e.InteractionArguments.ScreenY);`  
> `                ``var worldCoordinate = ExtentHelper.ToWorldCoordinate(map.CurrentExtent, screenPointF, (``float``)map.CurrentExtent.Width, (``float``)map.CurrentExtent.Height);`  
> `                ``var worldVertex = ``new`&nbsp;`Vertex(worldCoordinate);`  
> `                ``if`&nbsp;`(((!(minx < worldVertex.X)) || (!(maxx > worldVertex.X))) &&`  
> `                    ``((!(miny < worldVertex.Y)) || (!(maxy > worldVertex.Y)))) ``continue``;`  
> &nbsp;  
> `                ``var xLine = ``new`&nbsp;`LineShape(line);`  
> `                ``var newDistance = xLine.GetDistanceTo(``new`&nbsp;`PointShape(worldVertex), mapUnit, DistanceUnit.Meter);`  
> `                ``if`&nbsp;`(!(polygonDistance > newDistance)) ``continue``;`  
> &nbsp;  
> `                ``polygonDistance = newDistance;`  
> `                ``nearestPoint = xLine.GetClosestPointTo(``new`&nbsp;`PointShape(worldVertex), mapUnit);`  
> `            ``}`  
> `            ``if`&nbsp;`(!(polygonDistance < lowestDistance)) ``return``;`  
> &nbsp;  
> `            ``lowestDistance = polygonDistance;`  
> `            ``newMovedVertex = ``new`&nbsp;`Vertex(nearestPoint.X, nearestPoint.Y);`  
> `        ``}`

---

<div class="post-metadata">

**Author:** ![Ethan](https://community.thinkgeo.com/user_avatar/community.thinkgeo.com/ethan/32/19964_2.png) [@Ethan](https://community.thinkgeo.com/u/Ethan)\
**Post date:** [July 1, 2014, 10:39pm UTC](https://community.thinkgeo.com/t/snapto-feature-need-help/3685/5 "2014-07-01T22:39:37Z")

</div>

Hi&nbsp;Scott,&nbsp;&nbsp;  
&nbsp;&nbsp;  
&nbsp;Sorry&nbsp;I&nbsp;miss&nbsp;some&nbsp;information&nbsp;about&nbsp;your&nbsp;question.&nbsp;I&nbsp;think&nbsp;maybe&nbsp;the&nbsp;new&nbsp;event&nbsp;cannot&nbsp;implement&nbsp;what&nbsp;you&nbsp;want,&nbsp;because&nbsp;you&nbsp;cannot&nbsp;set&nbsp;the&nbsp;mouse&nbsp;position&nbsp;via&nbsp;it.&nbsp;  
&nbsp;&nbsp;  
&nbsp;Let&nbsp;us&nbsp;talk&nbsp;about&nbsp;this&nbsp;further,&nbsp;I&nbsp;think&nbsp;there&nbsp;are&nbsp;two&nbsp;possibilities&nbsp;about&nbsp;your&nbsp;scenario:&nbsp;  
&nbsp;&nbsp;  
&nbsp;1.&nbsp;When&nbsp;you&nbsp;move&nbsp;mouse&nbsp;close&nbsp;to&nbsp;a&nbsp;polygon,&nbsp;the&nbsp;mouse&nbsp;cursor&nbsp;snap&nbsp;to&nbsp;the&nbsp;polygon.&nbsp;  
&nbsp;&nbsp;  
&nbsp;2.&nbsp;When&nbsp;you&nbsp;move&nbsp;mouse&nbsp;close&nbsp;to&nbsp;a&nbsp;polygon,&nbsp;there&nbsp;is&nbsp;a&nbsp;point&nbsp;appear&nbsp;in&nbsp;the&nbsp;border&nbsp;of&nbsp;polygon&nbsp;for&nbsp;point&nbsp;out&nbsp;where&nbsp;can&nbsp;be&nbsp;the&nbsp;first&nbsp;snap&nbsp;point.&nbsp;  
&nbsp;&nbsp;  
&nbsp;For&nbsp;item&nbsp;1:&nbsp;&nbsp;  
&nbsp;I&nbsp;think&nbsp;you&nbsp;have&nbsp;to&nbsp;call&nbsp;windows&nbsp;API&nbsp;SetCursorPos,&nbsp;because&nbsp;our&nbsp;API&nbsp;cannot&nbsp;move&nbsp;mouse&nbsp;cursor.&nbsp;  
&nbsp;&nbsp;  
&nbsp;For&nbsp;item&nbsp;2:&nbsp;  
&nbsp;You&nbsp;can&nbsp;use&nbsp;currently&nbsp;MapMouseMove&nbsp;event&nbsp;and&nbsp;function,&nbsp;just&nbsp;need&nbsp;to&nbsp;draw&nbsp;a&nbsp;dynamic&nbsp;point&nbsp;on&nbsp;polygon&nbsp;when&nbsp;mouse&nbsp;move.&nbsp;  
&nbsp;&nbsp;  
&nbsp;After&nbsp;this&nbsp;step,&nbsp;I&nbsp;think&nbsp;the&nbsp;customer&nbsp;still&nbsp;need&nbsp;to&nbsp;click&nbsp;on&nbsp;map&nbsp;for&nbsp;make&nbsp;sure&nbsp;where&nbsp;is&nbsp;the&nbsp;first&nbsp;point.&nbsp;  
&nbsp;&nbsp;  
&nbsp;So&nbsp;now&nbsp;maybe&nbsp;you&nbsp;can&nbsp;call&nbsp;Map1.TrackOverlay.MouseClick&nbsp;to&nbsp;simulator&nbsp;click&nbsp;on&nbsp;target&nbsp;point&nbsp;and&nbsp;still&nbsp;use&nbsp;Map1.TrackOverlay.MouseMoved&nbsp;event&nbsp;for&nbsp;other&nbsp;points.&nbsp;  
&nbsp;&nbsp;  
&nbsp;Please&nbsp;let&nbsp;me&nbsp;know&nbsp;whether&nbsp;it’s&nbsp;helpful&nbsp;for&nbsp;your&nbsp;scenario?&nbsp;  
&nbsp;&nbsp;  
&nbsp;Regards,&nbsp;  
&nbsp;&nbsp;  
&nbsp;Don
