/// <summary> /// Creates a crack point calculator that selects also existing vertices as crack points. /// To calculate protected points shared with non-generalized geometries the intersection /// option IncludeLinearIntersectionAllPoints should be used. /// To calculate protected points shared with geometries that also should be generalized /// the intersection option IncludeLinearIntersectionEndpoints should be used /// </summary> /// <param name="intersectionOption"></param> /// <returns></returns> public static CrackPointCalculator CreateProtectedPointsCalculator( IntersectionPointOptions intersectionOption = IntersectionPointOptions.IncludeLinearIntersectionAllPoints) { double?snapTolerance = null; // NOTE: do not set the minimum segment length here because a non-null value // means that crack points should be excluded if they are too close to the // next vertex -> make this more explicit by new property on VertexInfo double? minimumSegmentLength = null; const bool addCrackPointsAlsoOnExistingVertices = true; // distinguish between selected protecting features (only protect start/end points) // and un-selected protecting features (protect every intersecting vertex) var crackPointCalculator = new CrackPointCalculator( snapTolerance, minimumSegmentLength, addCrackPointsAlsoOnExistingVertices, false, intersectionOption, null); return(crackPointCalculator); }
public void AddCrackPoints([NotNull] IFeature targetFeature, [NotNull] CrackPointCalculator crackPointCalculator) { // TODO: consider moving this to CrackUtils Stopwatch watch = _msg.DebugStartTiming("Calculating intersection points between {0} and {1}", GdbObjectUtils.ToString(Feature), GdbObjectUtils.ToString(targetFeature)); IPointCollection intersectionPoints = null; try { IGeometry targetGeometry = targetFeature.ShapeCopy; IGeometry originalGeometry = Feature.Shape; IPolyline clippedSource = OriginalClippedPolyline; GeometryUtils.EnsureSpatialReference(targetGeometry, clippedSource.SpatialReference); crackPointCalculator.SetDataResolution(Feature); IGeometry intersectionTarget; intersectionPoints = crackPointCalculator.GetIntersectionPoints( clippedSource, targetGeometry, out intersectionTarget); // TODO: if the target has a vertex closish (wrt tolerance) to the actual intersection point // the intersection point is somewhere in between. Consider snapping intersection points // to target vertices (this might be the start of clustering!) or use minimal tolerance! AddIntersectionPoints(intersectionPoints); IList <CrackPoint> crackPoints = crackPointCalculator.DetermineCrackPoints( intersectionPoints, originalGeometry, clippedSource, intersectionTarget); // TODO: rename to AddNonCrackablePoints / sort out whether drawing can happen straight from List<CrackPoint> AddCrackPoints(crackPoints); if (intersectionTarget != null && intersectionTarget != targetGeometry) { Marshal.ReleaseComObject(intersectionTarget); } Marshal.ReleaseComObject(targetGeometry); } catch (Exception e) { string message = $"Error calculationg crack points with target feature {RowFormat.Format(targetFeature)}: {e.Message}"; _msg.Debug(message, e); if (crackPointCalculator.ContinueOnException) { crackPointCalculator.FailedOperations.Add(Feature.OID, message); } else { throw; } } _msg.DebugStopTiming(watch, "Calculated and processed {0} intersection points", intersectionPoints?.PointCount); }