public override void OnMouseDown(ICoordinate worldPosition, MouseEventArgs e) { if (VectorLayer == null) { return; } if (e.Button != MouseButtons.Left) { return; } isBusy = true; StartDrawing(); newNetworkFeature = GeometryFactory.CreatePoint(worldPosition); ((DataTableFeatureProvider)newNetworkFeatureLayer.DataSource).Clear(); newNetworkFeatureLayer.DataSource.Add(newNetworkFeature); snapResult = MapControl.SnapTool.ExecuteLayerSnapRules(VectorLayer, null, newNetworkFeature, worldPosition, -1); //TODO check: why is this commented out in trunk? if (snapResult != null) { newNetworkFeature.Coordinates[0].X = snapResult.Location.X; newNetworkFeature.Coordinates[0].Y = snapResult.Location.Y; } newNetworkFeatureLayer.Style = MapControl.SnapTool.Failed ? errorNetworkFeatureStyle : networkFeatureStyle; }
public virtual bool MoveTracker(TrackerFeature trackerFeature, double deltaX, double deltaY, SnapResult snapResult = null) { if (trackerFeature.Index == -1) { throw new ArgumentException("Can not find tracker; can not move."); } var handles = SelectedTrackerIndices.ToList(); if (handles.Count == 0) { return false; // Do not throw exception, can occur in special cases when moving with CTRL toggle selection } if (FallOffPolicy != null) { FallOffPolicy.Move(TargetFeature.Geometry, trackers.Select(t => t.Geometry).ToList(), handles, trackerFeature.Index, deltaX, deltaY); } else { GeometryHelper.MoveCoordinate(TargetFeature.Geometry, trackerFeature.Index, deltaX, deltaY); TargetFeature.Geometry = TargetFeature.Geometry; // fire event GeometryHelper.MoveCoordinate(trackerFeature.Geometry, 0, deltaX, deltaY); trackerFeature.Geometry = trackerFeature.Geometry; // fire event } foreach (var topologyRule in FeatureRelationEditors) { topologyRule.UpdateRelatedFeatures(SourceFeature, TargetFeature.Geometry, handles); } return true; }
/// <summary> /// /// </summary> /// <param name="sourceFeature"></param> /// <param name="sourceGeometry"></param> /// <param name="snapTargets"></param> /// <param name="worldPos"></param> /// <param name="envelope"></param> /// <param name="trackingIndex"></param> /// based of the selected tracker in the snapSource the rule can behave differently /// (only snap branches' first and last coordinate). /// <returns></returns> public virtual SnapResult Execute(IFeature sourceFeature, IFeature[] snapCandidates, ILayer[] snapLayers, IGeometry sourceGeometry, IList<IFeature> snapTargets, ICoordinate worldPos, IEnvelope envelope, int trackingIndex) { // hack preserve snapTargets functionality IList<IGeometry> snapTargetGeometries = new List<IGeometry>(); if (null != snapTargets) { for (int i = 0; i < snapTargets.Count; i++) { snapTargetGeometries.Add(snapTargets[i].Geometry); } } double minDistance = double.MaxValue; // TODO: incapsulate minDistance in ISnapResult SnapResult snapResult = null; if(snapCandidates == null || snapLayers == null) { return snapResult; } for (int i = 0; i < snapCandidates.Length; i++) { var feature = snapCandidates[i]; var layer = snapLayers[i]; if(Criteria != null && !Criteria(layer, feature)) { continue; }; IGeometry geometry = feature.Geometry; if ((null != snapTargets) && (snapTargetGeometries.IndexOf(geometry) == -1)) continue; if (SnapRole == SnapRole.None) continue; if (geometry is IPolygon) { IPolygon polygon = (IPolygon)geometry; switch (SnapRole) { case SnapRole.Free: PolygonSnapFree(ref minDistance, ref snapResult, polygon, worldPos); break; case SnapRole.AllTrackers: GeometrySnapAllTrackers(ref minDistance, ref snapResult, polygon, worldPos); break; default: //case SnapRole.FreeAtObject: PolygonSnapFreeAtObject(ref minDistance, ref snapResult, polygon, worldPos); break; } } if (geometry is ILineString) { ILineString lineString = (ILineString)geometry; switch (SnapRole) { case SnapRole.Free: LineStringSnapFree(ref minDistance, ref snapResult, lineString, worldPos); break; case SnapRole.FreeAtObject: LineStringSnapFreeAtObject(ref minDistance, ref snapResult, feature, lineString, worldPos); break; case SnapRole.TrackersNoStartNoEnd: break; case SnapRole.AllTrackers: LineStringSnapAllTrackers(ref minDistance, ref snapResult, lineString, worldPos); break; case SnapRole.Start: LineStringSnapStart(ref snapResult, lineString); break; case SnapRole.End: LineStringSnapEnd(ref snapResult, lineString); break; case SnapRole.StartEnd: LineStringSnapStartEnd(ref minDistance, ref snapResult, lineString, worldPos); break; } } else if (geometry is IPoint) { snapResult = new SnapResult(geometry.Coordinates[0], null, NewFeatureLayer, geometry, 0, 0) { Rule = this }; } snapResult.NewFeatureLayer = NewFeatureLayer; } // foreach (IGeometry geometry in snapCandidates) return snapResult; }
public void PolygonSnapFree(ref double minDistance, ref SnapResult snapResult, IPolygon polygon, ICoordinate worldPos) { for (int i = 1; i < polygon.Coordinates.Length; i++) { ICoordinate c1 = polygon.Coordinates[i - 1]; ICoordinate c2 = polygon.Coordinates[i]; double distance = GeometryHelper.LinePointDistance(c1.X, c1.Y, c2.X, c2.Y, worldPos.X, worldPos.Y); if (distance >= minDistance) continue; minDistance = distance; snapResult = new SnapResult(GeometryFactory.CreateCoordinate(worldPos.X, worldPos.Y), null, null, polygon, i - 1, i) { Rule = this }; } }
public void LineStringSnapFreeAtObject(ref double minDistance, ref SnapResult snapResult, IFeature feature, ILineString lineString, ICoordinate worldPos) { int vertexIndex; var nearestPoint = GeometryHelper.GetNearestPointAtLine(lineString, worldPos, minDistance, out vertexIndex); if (nearestPoint == null) { return; } minDistance = GeometryHelper.Distance(nearestPoint.X, nearestPoint.Y, worldPos.X, worldPos.Y); snapResult = new SnapResult(nearestPoint, feature, null, lineString, vertexIndex - 1, vertexIndex) { Rule = this }; }
private void GeometrySnapAllTrackers(ref double minDistance, ref SnapResult snapResult, IGeometry geometry, ICoordinate worldPos) { var coordinates = geometry.Coordinates; for (int i = 0; i < coordinates.Length; i++) { ICoordinate c1 = coordinates[i]; double distance = GeometryHelper.Distance(c1.X, c1.Y, worldPos.X, worldPos.Y); if (distance >= minDistance) continue; minDistance = distance; snapResult = new SnapResult(coordinates[i], null, null, geometry, i, i) {Rule = this}; } }
public void LineStringSnapAllTrackers(ref double minDistance, ref SnapResult snapResult, ILineString lineString, ICoordinate worldPos) { GeometrySnapAllTrackers(ref minDistance, ref snapResult, lineString, worldPos); }
public void LineStringSnapStart(ref SnapResult snapResult, ILineString lineString) { snapResult = new SnapResult(lineString.Coordinates[0], null, null, lineString, 0, 0) { Rule = this }; }
public void LineStringSnapEnd(ref SnapResult snapResult, ILineString lineString) { snapResult = new SnapResult(lineString.Coordinates[lineString.Coordinates.Length - 1], null, null, lineString, lineString.Coordinates.Length - 1, lineString.Coordinates.Length - 1) { Rule = this }; }
public void LineStringSnapStartEnd(ref double minDistance, ref SnapResult snapResult, ILineString lineString, ICoordinate worldPos) { ICoordinate c1 = lineString.Coordinates[0]; ICoordinate location; int snapIndexPrevious; int snapIndexNext; double distance = GeometryHelper.Distance(c1.X, c1.Y, worldPos.X, worldPos.Y); if (distance < minDistance) { location = c1; snapIndexPrevious = 0; snapIndexNext = 0; minDistance = distance; snapResult = new SnapResult(location, null, null, lineString, snapIndexPrevious, snapIndexNext) { Rule = this }; } ICoordinate c2 = lineString.Coordinates[lineString.Coordinates.Length - 1]; distance = GeometryHelper.Distance(c2.X, c2.Y, worldPos.X, worldPos.Y); if (distance >= minDistance) return; location = c2; snapIndexPrevious = lineString.Coordinates.Length - 1; snapIndexNext = lineString.Coordinates.Length - 1; snapResult = new SnapResult(location, null, null, lineString, snapIndexPrevious, snapIndexNext) { Rule = this }; }
public override void OnMouseMove(ICoordinate worldPosition, MouseEventArgs e) { if (VectorLayer == null) { return; } //to avoid listening to the mousewheel in the mean time if (!(e.Button == MouseButtons.None || e.Button == MouseButtons.Left)) { return; } StartDrawing(); foreach (var layer in Layers) { if (!isBusy) { // If the newNetworkFeatureTool is active but not actual dragging a new NetworkFeature show the snap position. IPoint point = GeometryFactory.CreatePoint(worldPosition); snapResult = MapControl.SnapTool.ExecuteLayerSnapRules(layer, null, point, worldPosition, -1); if (snapResult != null) { break; } } else { IPoint point = GeometryFactory.CreatePoint(worldPosition); snapResult = MapControl.SnapTool.ExecuteLayerSnapRules(layer, null, point, worldPosition, -1); if (snapResult != null) { newNetworkFeature.Coordinates[0].X = snapResult.Location.X; newNetworkFeature.Coordinates[0].Y = snapResult.Location.Y; newNetworkFeatureLayer.Style = networkFeatureStyle; break; } else { newNetworkFeature.Coordinates[0].X = worldPosition.X; newNetworkFeature.Coordinates[0].Y = worldPosition.Y; newNetworkFeatureLayer.Style = errorNetworkFeatureStyle; } } } DoDrawing(true); StopDrawing(); }
private void ShowSnapResult(SnapResult snapResult) { ((DataTableFeatureProvider)snapLayer.DataSource).Clear(); if (null == snapResult) return; IList<IGeometry> visibleSnaps = snapResult.VisibleSnaps; //if (null == visisbleSnaps) if (0 == visibleSnaps.Count) { List<ICoordinate> vertices = new List<ICoordinate>(); if (-1 != snapResult.SnapIndexPrevious) { vertices.Add(GeometryFactory.CreateCoordinate(snapResult.NearestTarget.Coordinates[snapResult.SnapIndexPrevious].X, snapResult.NearestTarget.Coordinates[snapResult.SnapIndexPrevious].Y)); } vertices.Add(GeometryFactory.CreateCoordinate(snapResult.Location.X, snapResult.Location.Y)); IGeometry active = GeometryFactory.CreatePoint(snapResult.Location.X, snapResult.Location.Y); if (-1 != snapResult.SnapIndexNext) { vertices.Add(GeometryFactory.CreateCoordinate(snapResult.NearestTarget.Coordinates[snapResult.SnapIndexNext].X, snapResult.NearestTarget.Coordinates[snapResult.SnapIndexNext].Y)); } if (vertices.Count > 1) { ILineString snapLineString = GeometryFactory.CreateLineString(vertices.ToArray()); ((DataTableFeatureProvider)snapLayer.DataSource).Add(snapLineString); } ((DataTableFeatureProvider)snapLayer.DataSource).Add(active); } else { foreach (var snap in visibleSnaps) { ((DataTableFeatureProvider)snapLayer.DataSource).Add(snap); } } }
/// <summary> /// Update snapping /// </summary> /// <param name="sourceLayer"></param> /// The layer of feature. /// <param name="feature"></param> /// Feature that is snapped. Feature is not always available. /// <param name="geometry"></param> /// actual geometry of the feature that is snapped. /// <param name="worldPosition"></param> /// <param name="trackerIndex"></param> public SnapResult ExecuteLayerSnapRules(ILayer sourceLayer, IFeature feature, IGeometry geometry, ICoordinate worldPosition, int trackerIndex) { var snapRules = sourceLayer.FeatureEditor.SnapRules; SnapResult = null; for (int i = 0; i < snapRules.Count; i++) { ISnapRule rule = snapRules[i]; ExecuteSnapRule(rule, feature, geometry, null, worldPosition, trackerIndex); if (null != SnapResult) break; // If snapping failed for the last rule and snapping is obligatory // any position is valid // todo add rule with SnapRole.Free? if ((!rule.Obligatory) && (i == snapRules.Count - 1)) { SnapResult = new SnapResult(worldPosition, null, sourceLayer, null, -1, -1) { Rule = rule }; } } if (0 == snapRules.Count) { SnapResult = new SnapResult(worldPosition, null, sourceLayer, null, -1, -1); } return SnapResult; }
public virtual void Stop(SnapResult snapResult) { Stop(); }
public override bool MoveTracker(TrackerFeature trackerFeature, double deltaX, double deltaY, SnapResult snapResult = null) { if (trackerFeature == AllTracker) { if (FallOffPolicy == null) { FallOffPolicy = new NoFallOffPolicy(); } var handles = TrackerIndices.ToList(); FallOffPolicy.Move(TargetFeature.Geometry, Trackers.Select(t => t.Geometry).ToList(), handles, -1, deltaX, deltaY); foreach (var topologyRule in FeatureRelationEditors) { topologyRule.UpdateRelatedFeatures(SourceFeature, TargetFeature.Geometry, handles); } return true; } return base.MoveTracker(trackerFeature, deltaX, deltaY, snapResult); }
public override void OnMouseUp(ICoordinate worldPosition, MouseEventArgs e) { if (e.Button != MouseButtons.Left) return; if (newLineGeometry.Count == 0) { return; } SnapResult snapResult = MapControl.SnapTool.ExecuteLayerSnapRules(VectorLayer, null, adding ? newLineGeometry[0] : null, worldPosition, adding ? newLineGeometry[0].Coordinates.Length - 1 : -1); ILineString lineString = (ILineString)newLineGeometry[0]; if (null == lineString) { isBusy = false; return; } if (ActualAutoCurve) { snapResult = Snap(worldPosition); if (null == snapResult) { // hack if obligatory snapping failed mimic result. This is not valid for NewNetworkFeatureTool // Think of solution within snaprule snapResult = new SnapResult(worldPosition, null, null, null, -1, -1); } if (TemporalEnd) lineString = (ILineString)GeometryHelper.SetCoordinate(lineString, lineString.Coordinates.Length - 1, snapResult.Location); else lineString = AppendCurvePoint(lineString, snapResult.Location); if (!KeepDuplicates) { lineString = RemoveDuplicatePoints(lineString); } adding = false; newLineGeometry[0] = lineString; //Flush(); SelectTool selectTool = MapControl.SelectTool; if (null != lineString && snapResult != null) { // TODO: call interactor here instead of feature provider IFeature newFeature; try { if (CloseLine) { lineString = CloseLineString(lineString); } newFeature = VectorLayer.DataSource.Add(lineString); // will add Cross Section and call ConnectCrossSectionToBranch // was adding succesfull? if (null != newFeature) { //Layer.RenderRequired = true; MapControl.SelectTool.Select(VectorLayer, newFeature); } } catch (Exception exception) { // an exception during add operation can fail; for example when adding a branch feature log.Warn(exception.Message); } } else { // do not add a linestring with zero length selectTool.Clear(); } adding = false; StopDrawing(); newLineGeometry.Clear(); isBusy = false; } else { isBusy = true; } VectorLayer.RenderRequired = true; MapControl.Refresh(); }