/// <summary> /// Limited reshape curve calculation without support for multiple-sources-as-union, adjust and preview-calculation /// </summary> /// <param name="sourceFeatures"></param> /// <param name="targetFeatures"></param> /// <param name="visibleExtent"></param> /// <param name="useMinimalTolerance"></param> /// <param name="bufferOptions"></param> /// <param name="filterOptions"></param> /// <param name="resultSubcurves"></param> /// <param name="trackCancel"></param> /// <returns></returns> public static ReshapeAlongCurveUsability CalculateReshapeCurves( [NotNull] IList <IFeature> sourceFeatures, [NotNull] IList <IFeature> targetFeatures, [CanBeNull] IEnvelope visibleExtent, bool useMinimalTolerance, TargetBufferOptions bufferOptions, ReshapeCurveFilterOptions filterOptions, IList <CutSubcurve> resultSubcurves, [CanBeNull] ITrackCancel trackCancel) { Assert.ArgumentCondition(sourceFeatures.Count > 0, "No selected features"); IEnvelope clipExtent = GetClipExtent(visibleExtent, bufferOptions.BufferTarget ? bufferOptions.BufferDistance : 0); ISubcurveCalculator curveCalculator = new ReshapableSubcurveCalculator(); curveCalculator.SubcurveFilter = new SubcurveFilter(new StaticExtentProvider(visibleExtent)); IGeometry targetGeometry = BuildTargetGeometry(targetFeatures, clipExtent); string reasonForEmptyTargetLine; IPolyline targetLine = PrepareTargetLine( sourceFeatures, targetGeometry, clipExtent, bufferOptions, out reasonForEmptyTargetLine, trackCancel); if (targetLine == null || targetLine.IsEmpty) { return(ReshapeAlongCurveUsability.NoTarget); } PrepareSubcurveCalculator(curveCalculator, sourceFeatures, targetFeatures, useMinimalTolerance, filterOptions, clipExtent); ReshapeAlongCurveUsability result; if (sourceFeatures.Count == 1) { result = RecalculateReshapableSubcurves( sourceFeatures[0], targetLine, curveCalculator, resultSubcurves, trackCancel); } else { result = AddAdditionalSingleGeometryReshapeCurves( sourceFeatures, targetLine, null, curveCalculator, resultSubcurves, trackCancel); } // TODO: Adjust lines, Difference areas return(result); }
private static IPolyline BufferTargetLine([NotNull] IPolyline targetLine, [NotNull] TargetBufferOptions options, [CanBeNull] IEnvelope envelopeScope, [CanBeNull] NotificationCollection bufferNotifications, [CanBeNull] ITrackCancel trackCancel) { Assert.ArgumentNotNull(targetLine, nameof(targetLine)); Assert.ArgumentCondition(!targetLine.IsEmpty, "BufferTargetLine: Target line is empty."); IPolyline result = null; IPolygon targetBuffer; if (AdjustUtils.TryBuffer(targetLine, options.BufferDistance, options.LogInfoPointThreshold, "Buffering target geometry...", bufferNotifications, out targetBuffer)) { Assert.NotNull(targetBuffer, "targetBuffer"); if (trackCancel != null && !trackCancel.Continue()) { return(targetLine); } if (options.EnforceMinimumBufferSegmentLength) { // TODO: removing short segments is slow if many adjacent segments // need to be removed. if (trackCancel != null && !trackCancel.Continue()) { return(targetLine); } if (((IPointCollection)targetLine).PointCount > options.LogInfoPointThreshold) { _msg.Info("Removing short segments from buffer..."); } EnforceMinimumSegmentLength(targetBuffer, options.BufferMinimumSegmentLength, envelopeScope); } result = GeometryFactory.CreatePolyline(targetBuffer); Marshal.ReleaseComObject(targetBuffer); } return(result); }
public static IPolyline PrepareTargetLine( [NotNull] IList <IFeature> selectedFeatures, [NotNull] IGeometry targetGeometry, [CanBeNull] IEnvelope clipExtent, [NotNull] TargetBufferOptions bufferOptions, out string reasonForNullOrEmpty, [CanBeNull] ITrackCancel trackCancel) { IGeometry target = targetGeometry; // Ensure target's SR already here ISpatialReference sr = GetShapeSpatialReference(selectedFeatures[0]); if (GeometryUtils.EnsureSpatialReference(target, sr)) { _msg.Debug("Target geometry needed projection."); } reasonForNullOrEmpty = null; IPolyline targetLine = GetPreprocessedGeometryForExtent(target, clipExtent); if (targetLine.IsEmpty) { reasonForNullOrEmpty = "Reshape-along-target is outside main window extent."; return(targetLine); } if (trackCancel != null && !trackCancel.Continue()) { reasonForNullOrEmpty = "Cancelled"; return(null); } if (bufferOptions.BufferTarget) { var bufferNotifications = new NotificationCollection(); targetLine = BufferTargetLine(targetLine, bufferOptions, clipExtent, bufferNotifications, trackCancel); if (targetLine == null) { reasonForNullOrEmpty = $"Unable to buffer target geometry: {bufferNotifications.Concatenate(". ")}"; } } return(targetLine); }
/// <summary> /// Cut curve calculation. /// </summary> /// <param name="sourceFeatures"></param> /// <param name="targetFeatures"></param> /// <param name="visibleExtent"></param> /// <param name="tolerance"></param> /// <param name="bufferOptions"></param> /// <param name="filterOptions"></param> /// <param name="resultSubcurves"></param> /// <param name="trackCancel"></param> /// <returns></returns> public static ReshapeAlongCurveUsability CalculateCutCurves( [NotNull] IList <IFeature> sourceFeatures, [NotNull] IList <IFeature> targetFeatures, [CanBeNull] IEnvelope visibleExtent, double tolerance, TargetBufferOptions bufferOptions, ReshapeCurveFilterOptions filterOptions, IList <CutSubcurve> resultSubcurves, [CanBeNull] ITrackCancel trackCancel = null) { ISubcurveCalculator curveCalculator = new CutPolygonSubcurveCalculator(); return(CalculateChangeAlongCurves(sourceFeatures, targetFeatures, visibleExtent, tolerance, bufferOptions, filterOptions, resultSubcurves, curveCalculator, trackCancel)); }
/// <summary> /// Limited reshape curve calculation without support for multiple-sources-as-union, /// adjust and preview-calculation. /// </summary> /// <param name="sourceFeatures"></param> /// <param name="targetFeatures"></param> /// <param name="visibleExtent"></param> /// <param name="tolerance"></param> /// <param name="bufferOptions"></param> /// <param name="filterOptions"></param> /// <param name="resultSubcurves"></param> /// <param name="curveCalculator"></param> /// <param name="trackCancel"></param> /// <returns></returns> public static ReshapeAlongCurveUsability CalculateChangeAlongCurves( [NotNull] IList <IFeature> sourceFeatures, [NotNull] IList <IFeature> targetFeatures, [CanBeNull] IEnvelope visibleExtent, double tolerance, [NotNull] TargetBufferOptions bufferOptions, [NotNull] ReshapeCurveFilterOptions filterOptions, IList <CutSubcurve> resultSubcurves, [NotNull] ISubcurveCalculator curveCalculator, [CanBeNull] ITrackCancel trackCancel = null) { Assert.ArgumentCondition( sourceFeatures.All( f => curveCalculator.CanUseSourceGeometryType( DatasetUtils.GetShapeType(f.Class))), "Source feature list contains invalid geometry type(s)"); Assert.ArgumentCondition(targetFeatures.All(CanUseAsTargetFeature), "Target feature list contains invalid features"); if (sourceFeatures.Count == 0) { return(ReshapeAlongCurveUsability.NoSource); } if (targetFeatures.Count == 0) { return(ReshapeAlongCurveUsability.NoTarget); } visibleExtent = visibleExtent ?? UnionExtents(sourceFeatures, targetFeatures); // TODO: Actual tolerance that can be specified (using double for forward compatibility) bool useMinimalTolerance = MathUtils.AreEqual(0, tolerance); IEnvelope clipExtent = GetClipExtent(visibleExtent, bufferOptions.BufferTarget ? bufferOptions.BufferDistance : 0); curveCalculator.SubcurveFilter = new SubcurveFilter(new StaticExtentProvider(visibleExtent)); IGeometry targetGeometry = BuildTargetGeometry(targetFeatures, clipExtent); IPolyline targetLine = PrepareTargetLine( sourceFeatures, targetGeometry, clipExtent, bufferOptions, out string _, trackCancel); if (targetLine == null || targetLine.IsEmpty) { return(ReshapeAlongCurveUsability.NoTarget); } PrepareSubcurveCalculator(curveCalculator, sourceFeatures, targetFeatures, useMinimalTolerance, filterOptions, clipExtent); ReshapeAlongCurveUsability result; if (sourceFeatures.Count == 1) { result = RecalculateReshapableSubcurves( sourceFeatures[0], targetLine, curveCalculator, resultSubcurves, trackCancel); } else { result = AddAdditionalSingleGeometryReshapeCurves( sourceFeatures, targetLine, null, curveCalculator, resultSubcurves, trackCancel); } // TODO: Adjust lines, Difference areas return(result); }