public static IList <esriSegmentInfo> CalculateShortSegments( [NotNull] FeatureVertexInfo forFeatureVertexInfo, bool use2DLengthOnly, [CanBeNull] IGeometry perimeter) { _msg.VerboseDebugFormat("Getting short segments for {0}", GdbObjectUtils.ToString(forFeatureVertexInfo.Feature)); var minimumSegmentLength = (double)Assert.NotNull(forFeatureVertexInfo.MinimumSegmentLength); IList <esriSegmentInfo> shortSegments = GetShortSegments( forFeatureVertexInfo.Feature, perimeter, minimumSegmentLength, use2DLengthOnly); IList <esriSegmentInfo> protectedSegments = GetProtectedSegments( shortSegments, forFeatureVertexInfo.CrackPointCollection); IList <esriSegmentInfo> removableSegments = shortSegments.Where(shortSegment => !protectedSegments.Contains(shortSegment)) .ToList(); forFeatureVertexInfo.ShortSegments = removableSegments; forFeatureVertexInfo.NonRemovableShortSegments = protectedSegments; return(removableSegments); }
/// <summary> /// Removes the shorts segments of the specified featureVertexInfo unless they are protected /// by the specified featureVertexInfo's CrackPoints. The minimum of the featureVertexInfo must /// be set. /// </summary> /// <param name="fromPolycurve"></param> /// <param name="featureVertexInfo"></param> /// <param name="use2DLengthOnly"></param> /// <param name="inPerimeter"></param> /// <returns></returns> private static void RemoveShortSegments( [NotNull] IPolycurve fromPolycurve, [NotNull] FeatureVertexInfo featureVertexInfo, bool use2DLengthOnly, [CanBeNull] IGeometry inPerimeter) { Assert.ArgumentNotNull(fromPolycurve, nameof(fromPolycurve)); Assert.ArgumentNotNull(featureVertexInfo, nameof(featureVertexInfo)); Assert.ArgumentCondition(featureVertexInfo.ShortSegments != null, "featureVertexInfo's ShortSegments is null"); Assert.ArgumentCondition(featureVertexInfo.MinimumSegmentLength != null, "featureVertexInfo's MinimumSegmentLength is null"); var notifications = new NotificationCollection(); Assert.NotNull(featureVertexInfo.MinimumSegmentLength, "Minimum segment length not set."); var minimumSegmentLength = (double)featureVertexInfo.MinimumSegmentLength; IList <esriSegmentInfo> shortSegments = featureVertexInfo.ShortSegments; SegmentReplacementUtils.RemoveShortSegments(fromPolycurve, shortSegments, minimumSegmentLength, use2DLengthOnly, featureVertexInfo.CrackPointCollection, inPerimeter, notifications); if (notifications.Count > 0) { _msg.WarnFormat("Feature {0}: {1}", GdbObjectUtils.ToString(featureVertexInfo.Feature), notifications.Concatenate(" ")); } }
private static int DeleteShortSegments( [NotNull] IPolycurve fromPolycurve, [NotNull] FeatureVertexInfo vertexInfo, bool use2DLengthOnly, [CanBeNull] IGeometry inPerimeter) { IList <esriSegmentInfo> shortSegmentInfos = vertexInfo.ShortSegments; Assert.NotNull(shortSegmentInfos); _msg.DebugFormat("Deleting {0} short segments from {1}", shortSegmentInfos.Count, GdbObjectUtils.ToString(vertexInfo.Feature)); Assert.NotNull(vertexInfo.MinimumSegmentLength, "Minimum segment length not set."); //double minimumSegmentLength = (double)vertexInfo.MinimumSegmentLength; var fromSegmentCollection = (ISegmentCollection)fromPolycurve; int originalSegmentCount = fromSegmentCollection.SegmentCount; RemoveShortSegments(fromPolycurve, vertexInfo, use2DLengthOnly, inPerimeter); fromSegmentCollection.SegmentsChanged(); //// re-consider cost vs. information need: //int remainingCount = GetShortSegments( // fromPolycurve, inPerimeter, minimumSegmentLength, use2DLengthOnly).Count; int deletedSegmentsCount = originalSegmentCount - fromSegmentCollection.SegmentCount; return(deletedSegmentsCount); }
private static IPointCollection RemoveProtectedPoints( [NotNull] IPointCollection fromWeededPoints, [CanBeNull] FeatureVertexInfo featureVertexInfo) { if (featureVertexInfo == null || featureVertexInfo.CrackPointCollection == null) { return(null); } // TODO: the removedPoints are missing the protected points due to shared segments // -> also get weed points on the start/end point of shared segments/paths IPointCollection protectedPoints = featureVertexInfo.CrackPointCollection; IPointCollection removedPoints = CrackUtils.RemovePoints(fromWeededPoints, protectedPoints); //// TODO: Also remove those weed points that would change an adjacent segment on which there is //// a crack point (i.e. one without pre-existing vertex) //double searchTolerance = GeometryUtils.GetXyTolerance(featureVertexInfo.OriginalClippedPolyline); //foreach (IPoint point in GeometryUtils.GetPoints(fromWeededPoints)) //{ // int partIndex; // int segmentIndex = SegmentReplacementUtils.GetSegmentIndex( // featureVertexInfo.OriginalClippedPolyline, point, // searchTolerance, // out partIndex, true); // //IGeometry highLevelSegment = GeometryUtils.GetHighLevelGeometry(SegmentReplacementUtils.GetSegment(featureVertexInfo.OriginalClippedPolyline), true) // //if (GeometryUtils.Disjoint()) //} return(removedPoints); }
private static IPolycurve GetOriginalGeometry( [NotNull] IFeature feature, [CanBeNull] FeatureVertexInfo featureVertexInfo) { bool isPolygon = feature.Shape.GeometryType == esriGeometryType.esriGeometryPolygon; if (featureVertexInfo == null) { return(GeometryFactory.CreatePolyline(feature.Shape)); } featureVertexInfo.SimplifyCrackPoints(); if (_msg.IsVerboseDebugEnabled) { _msg.VerboseDebugFormat( "Cutting input geometry with protected points. Generalization Info: {0}", featureVertexInfo.ToString(true)); } IPolyline originalGeometry = featureVertexInfo.OriginalClippedPolyline; if (featureVertexInfo.CrackPointCollection == null || featureVertexInfo.CrackPointCollection.PointCount == 0) { return(originalGeometry); } // TODO: consider consolidating points equal in XY: get average Z (or Z from non-editable feature) // to really make coincident! IPointCollection protectedPoints = featureVertexInfo.CrackPointCollection; IGeometryCollection splittedResult = null; foreach (IPath path in GeometryUtils.GetPaths(originalGeometry)) { bool splitHappenedAtFrom; double cutOffDistance = GeometryUtils.GetXyTolerance(originalGeometry); const bool projectPointsOntoPathToSplit = true; IGeometryCollection splittedPaths = GeometryUtils.SplitPath( path, protectedPoints, projectPointsOntoPathToSplit, cutOffDistance, out splitHappenedAtFrom); if (isPolygon && path.IsClosed && !splitHappenedAtFrom && splittedPaths.GeometryCount > 1) { MergeLastWithFirstPart(splittedPaths); } if (splittedResult == null) { splittedResult = splittedPaths; } else { splittedResult.AddGeometryCollection(splittedPaths); } } if (_msg.IsVerboseDebugEnabled) { _msg.VerboseDebugFormat("Original feature {0} splitted by protected points: {1}", GdbObjectUtils.ToString(feature), GeometryUtils.ToString((IGeometry)splittedResult)); } return(splittedResult as IPolycurve); }
public FeatureVertexInfo Clone([CanBeNull] IGeometry subSelectionPerimeter) { var result = new FeatureVertexInfo(Feature, _perimeter, SnapTolerance, MinimumSegmentLength); if (CrackPoints != null) { result.CrackPoints = new List <CrackPoint>(); foreach (CrackPoint crackPoint in CrackPoints) { if (subSelectionPerimeter == null || GeometryUtils.Contains(subSelectionPerimeter, crackPoint.Point)) { result.CrackPoints.Add(crackPoint); } } } if (IntersectionPoints != null) { result.IntersectionPoints = GetFilteredPoints(IntersectionPoints, subSelectionPerimeter); } if (CrackPointCollection != null) { result.CrackPointCollection = GetFilteredPoints(CrackPointCollection, subSelectionPerimeter); } if (PointsToDelete != null) { result.PointsToDelete = GetFilteredPoints(PointsToDelete, subSelectionPerimeter); } if (NonCrackablePoints != null) { result.NonCrackablePoints = GetFilteredPoints(NonCrackablePoints, subSelectionPerimeter); } if (NonDeletablePoints != null) { result.NonDeletablePoints = GetFilteredPoints(NonDeletablePoints, subSelectionPerimeter); } if (ShortSegments != null) { result.ShortSegments = ShortSegmentsUtils.GetFilteredSegments(ShortSegments, subSelectionPerimeter, true); } if (NonRemovableShortSegments != null) { result.NonRemovableShortSegments = ShortSegmentsUtils.GetFilteredSegments(NonRemovableShortSegments, subSelectionPerimeter, true); } return(result); }