private PointShape GetSnappingPoint(Vertex originVertex, Feature affectedFeature, bool preventSameVertex = true) { PolygonShape affectedPolygon = affectedFeature.GetShape() as PolygonShape; Collection <PointShape> tmpSnappingPoints = new Collection <PointShape>(); if (editOverlay != null && snappingLayers.Count != 0) { //we only snaps to selected features when the selected features are from the EditTargetLayer IEnumerable <FeatureLayer> currentSnappingLayers = snappingLayers; if (editOverlay.SnappingLayers.Any(snappingLayer => snappingLayer == editOverlay.EditTargetLayer)) { currentSnappingLayers = currentSnappingLayers.Concat(new FeatureLayer[] { editOverlay.EditShapesLayer }); } foreach (var snappingLayer in currentSnappingLayers) { lock (snappingLayer) { if (!snappingLayer.IsOpen) { snappingLayer.Open(); } var boundingBox = MapArguments.CurrentExtent; var screenWidth = MapArguments.ActualWidth; Feature snappingFeature = null; try { SnappingAdapter calc = SnappingAdapter.Convert(snappingDistance, snappingDistanceUnit, MapArguments, originVertex); snappingFeature = snappingLayer.QueryTools. GetFeaturesWithinDistanceOf(new Feature(originVertex), MapArguments.MapUnit, calc.DistanceUnit, calc.Distance, ReturningColumnsType.NoColumns).FirstOrDefault(f => f.Id != affectedFeature.Id); } catch { } BaseShape snappingShape = null; if (snappingFeature != null && (snappingShape = snappingFeature.GetShape()) != null) { SnappingAdapter calc = SnappingAdapter.Convert(snappingDistance, snappingDistanceUnit, MapArguments, originVertex); PointShape snappingPoint = GisEditorEditInteractiveOverlay.GetSnappingPoint(snappingShape, new PointShape(originVertex), MapArguments.MapUnit, calc.Distance, calc.DistanceUnit); if (preventSameVertex && (affectedPolygon != null && !affectedPolygon.OuterRing.Vertices.Any(v => v.X == snappingPoint.X && v.Y == snappingPoint.Y))) { return(snappingPoint); } else { return(snappingPoint); } } } } } PointShape originPoint = new PointShape(originVertex); return(originPoint); }
private Vertex GetClosestVertex(List <Vertex> vertices, PointShape point) { Vertex result = vertices.FirstOrDefault(); if (vertices.Count > 0) { result = vertices.OrderBy(v => (v.X - point.X) * (v.X - point.X) + (v.Y - point.Y) * (v.Y - point.Y)).First(); } if (result != default(Vertex)) { double distanceInMeter = point.GetDistanceTo(new PointShape(result), MapArguments.MapUnit, DistanceUnit.Meter); SnappingAdapter calc = SnappingAdapter.Convert(SnappingDistance, SnappingDistanceUnit, MapArguments, point); double radiusInMeter = Conversion.ConvertMeasureUnits(calc.Distance, calc.DistanceUnit, DistanceUnit.Meter); if (distanceInMeter > radiusInMeter) { result = new Vertex(point); } } return(result); }
protected override InteractiveResult MouseMoveCore(InteractionArguments interactionArguments) { if (isShiftKeyDown) { var circle = OverlayCanvas.Children.OfType <System.Windows.Shapes.Ellipse>().FirstOrDefault(); if (circle != null) { OverlayCanvas.Children.Remove(circle); } } if (IsDirty && TrackMode != TrackMode.None) { CollectionVertices(interactionArguments); } UpdateArguments(interactionArguments); if (TrackMode != TrackMode.None && MouseDownCount < 1 && SnappingLayers.Count > 0) { lock (OverlayCanvas.Children) { Vertex currentPosition = new Vertex(interactionArguments.WorldX, interactionArguments.WorldY); var snappingCircle = OverlayCanvas.Children.OfType <System.Windows.Shapes.Ellipse>().FirstOrDefault(); if (snappingCircle == null) { snappingCircle = new System.Windows.Shapes.Ellipse(); snappingCircle.IsHitTestVisible = false; snappingCircle.HorizontalAlignment = System.Windows.HorizontalAlignment.Left; snappingCircle.VerticalAlignment = System.Windows.VerticalAlignment.Top; snappingCircle.Stroke = new SolidColorBrush(Colors.Black); snappingCircle.StrokeThickness = 1; OverlayCanvas.Children.Add(snappingCircle); } var snappingDistance = SnappingDistance; var snappingDistanceUnit = SnappingDistanceUnit; var snappingScreenPoint = ExtentHelper.ToScreenCoordinate(MapArguments.CurrentExtent, currentPosition.X, currentPosition.Y, (float)MapArguments.ActualWidth, (float)MapArguments.ActualHeight); try { SnappingAdapter calc = SnappingAdapter.Convert(snappingDistance, snappingDistanceUnit, MapArguments, currentPosition); var snappingArea = new PointShape(currentPosition.X, currentPosition.Y) .Buffer(calc.Distance, MapArguments.MapUnit, calc.DistanceUnit) .GetBoundingBox(); var snappingScreenSize = Math.Max(snappingArea.Width, snappingArea.Height) / MapArguments.CurrentResolution; snappingCircle.Width = snappingScreenSize; snappingCircle.Height = snappingScreenSize; snappingCircle.Margin = new System.Windows.Thickness(snappingScreenPoint.X - snappingScreenSize * .5, snappingScreenPoint.Y - snappingScreenSize * .5, 0, 0); } catch { } } } else { lock (OverlayCanvas.Children) { var circle = OverlayCanvas.Children.OfType <System.Windows.Shapes.Ellipse>().FirstOrDefault(); if (circle != null) { OverlayCanvas.Children.Remove(circle); } } } var interactiveResult = base.MouseMoveCore(interactionArguments); return(interactiveResult); }
protected override void OnMouseMoved(MouseMovedTrackInteractiveOverlayEventArgs e) { base.OnMouseMoved(e); var trackShape = GetTrackingShape(); if (!isShiftKeyDown && trackShape != null && (TrackMode == TrackMode.Polygon || TrackMode == TrackMode.Line) && editOverlay != null && editOverlay.SnappingLayers.Count > 0) { lock (OverlayCanvas.Children) { var snappingCircle = OverlayCanvas.Children.OfType <System.Windows.Shapes.Ellipse>().FirstOrDefault(); if (snappingCircle == null) { snappingCircle = new System.Windows.Shapes.Ellipse(); snappingCircle.IsHitTestVisible = false; snappingCircle.HorizontalAlignment = System.Windows.HorizontalAlignment.Left; snappingCircle.VerticalAlignment = System.Windows.VerticalAlignment.Top; snappingCircle.Stroke = new SolidColorBrush(Colors.Black); snappingCircle.StrokeThickness = 1; OverlayCanvas.Children.Add(snappingCircle); } var snappingDistance = editOverlay.SnappingDistance; var snappingDistanceUnit = editOverlay.SnappingDistanceUnit; var snappingScreenPoint = ExtentHelper.ToScreenCoordinate(MapArguments.CurrentExtent, e.MovedVertex.X, e.MovedVertex.Y, (float)MapArguments.ActualWidth, (float)MapArguments.ActualHeight); try { SnappingAdapter calc = SnappingAdapter.Convert(snappingDistance, snappingDistanceUnit, MapArguments, e.MovedVertex); var snappingArea = new PointShape(e.MovedVertex.X, e.MovedVertex.Y) .Buffer(calc.Distance, editOverlay.MapArguments.MapUnit, calc.DistanceUnit) .GetBoundingBox(); var snappingScreenSize = Math.Max(snappingArea.Width, snappingArea.Height) / MapArguments.CurrentResolution; snappingCircle.Width = snappingScreenSize; snappingCircle.Height = snappingScreenSize; snappingCircle.Margin = new System.Windows.Thickness(snappingScreenPoint.X - snappingScreenSize * .5, snappingScreenPoint.Y - snappingScreenSize * .5, 0, 0); } catch { } } //PointShape snappedPoint = GetSnappingPoint(e.MovedVertex, e.AffectedFeature); //if (snappedPoint != null) //{ // e.MovedVertex = new Vertex(snappedPoint); // lock (OverlayCanvas.Children) // { // var snappingCircle = OverlayCanvas.Children.OfType<System.Windows.Shapes.Ellipse>().FirstOrDefault(); // if (snappingCircle == null) // { // snappingCircle = new System.Windows.Shapes.Ellipse(); // snappingCircle.IsHitTestVisible = false; // snappingCircle.HorizontalAlignment = System.Windows.HorizontalAlignment.Left; // snappingCircle.VerticalAlignment = System.Windows.VerticalAlignment.Top; // snappingCircle.Stroke = new SolidColorBrush(Colors.Black); // snappingCircle.StrokeThickness = 1; // OverlayCanvas.Children.Add(snappingCircle); // } // var snappingDistance = editOverlay.SnappingDistance; // var snappingDistanceUnit = editOverlay.SnappingDistanceUnit; // var snappingScreenPoint = ExtentHelper.ToScreenCoordinate(MapArguments.CurrentExtent, snappedPoint, (float)MapArguments.ActualWidth, (float)MapArguments.ActualHeight); // SnappingAdapter calc = SnappingAdapter.Convert(snappingDistance, snappingDistanceUnit, MapArguments, e.MovedVertex); // var snappingArea = snappedPoint.Buffer(calc.Distance, editOverlay.MapArguments.MapUnit, calc.DistanceUnit).GetBoundingBox(); // var snappingScreenSize = Math.Max(snappingArea.Width, snappingArea.Height) / MapArguments.CurrentResolution; // snappingCircle.Width = snappingScreenSize; // snappingCircle.Height = snappingScreenSize; // snappingCircle.Margin = new System.Windows.Thickness(snappingScreenPoint.X - snappingScreenSize * .5, snappingScreenPoint.Y - snappingScreenSize * .5, 0, 0); // } //} } }