public static ReshapeAlongCurveUsability AddAdditionalSingleGeometryReshapeCurves( [NotNull] IList <IFeature> sourceFeatures, [NotNull] IPolyline targetPolyline, [CanBeNull] IPolyline unionLine, ISubcurveCalculator subcurveCalculator, IList <CutSubcurve> resultSubcurves, [CanBeNull] ITrackCancel trackCancel) { var result = ReshapeAlongCurveUsability.Undefined; IEnumerable <CutSubcurve> allSingleGeoReshapeCurves = GetIndividualGeometriesReshapeCurves(sourceFeatures, targetPolyline, subcurveCalculator); // where there are single and union reshape curves show the user only those reshape // curves that reshape the union otherwise it can get confusing and several reshape // lines overlap which cannot be seen. foreach (CutSubcurve singleGeometryReshapeCurve in allSingleGeoReshapeCurves) { if (trackCancel != null && !trackCancel.Continue()) { return(ReshapeAlongCurveUsability.Undefined); } // do not add those curves that are on the current union boundary // TODO: if all (reshapable) curves are filtered out due to intersection with source union: // consider still adding them to avoid confusion (the target is not visible) or generally // add a fill symbol for all target features. if (unionLine != null) { IGeometry highLevelSubcurve = GeometryUtils.GetHighLevelGeometry( singleGeometryReshapeCurve.Path, true); if (HasLinearIntersections(unionLine, highLevelSubcurve)) { continue; } } if (singleGeometryReshapeCurve.CanReshape) { result = ReshapeAlongCurveUsability.CanReshape; } resultSubcurves.Add(singleGeometryReshapeCurve); } if (result == ReshapeAlongCurveUsability.Undefined) { result = resultSubcurves.Count == 0 ? ReshapeAlongCurveUsability.NoReshapeCurves : ReshapeAlongCurveUsability .InsufficientOrAmbiguousReshapeCurves; } return(result); }
public static void PrepareSubcurveCalculator( ISubcurveCalculator subCurveCalculator, [NotNull] IList <IFeature> sourceFeatures, [NotNull] IList <IFeature> targetFeatures, bool useMinimalTolerance, ReshapeCurveFilterOptions filterOptions, [CanBeNull] IEnvelope clipExtent) { Assert.ArgumentNotNull(subCurveCalculator, nameof(subCurveCalculator)); subCurveCalculator.Prepare(sourceFeatures, targetFeatures, clipExtent, useMinimalTolerance, filterOptions); }
public static ReshapeAlongCurveUsability RecalculateReshapableSubcurves( [NotNull] IFeature sourceFeature, [NotNull] IPolyline targetPolyline, ISubcurveCalculator curveCalculator, IList <CutSubcurve> resultSubcurves, [CanBeNull] ITrackCancel trackCancel) { ReshapeAlongCurveUsability result; IGeometry editGeometry = sourceFeature.Shape; try { if (trackCancel != null && !trackCancel.Continue()) { return(ReshapeAlongCurveUsability.Undefined); } result = curveCalculator.CalculateSubcurves( editGeometry, targetPolyline, resultSubcurves, trackCancel); foreach (CutSubcurve reshapeSubcurve in resultSubcurves) { reshapeSubcurve.Source = new GdbObjectReference(sourceFeature); } if (trackCancel != null && !trackCancel.Continue()) { return(ReshapeAlongCurveUsability.Undefined); } } finally { Marshal.ReleaseComObject(editGeometry); } return(result); }
private static IEnumerable <CutSubcurve> GetIndividualGeometriesReshapeCurves( [NotNull] IList <IFeature> sourceFeatures, [NotNull] IPolyline targetPolyline, [NotNull] ISubcurveCalculator subcurveCalculator) { var result = new List <CutSubcurve>(); _msg.DebugFormat( "GetIndividualGeometriesReshapeCurves: calculating curves for {0} geometries..", sourceFeatures.Count); foreach (IFeature sourceFeature in sourceFeatures) { IGeometry sourceGeometry = sourceFeature.Shape; var individualResultList = new List <CutSubcurve>(); ReshapeAlongCurveUsability individualResult = subcurveCalculator.CalculateSubcurves( sourceGeometry, targetPolyline, individualResultList, null); foreach (CutSubcurve subcurve in individualResultList) { subcurve.Source = new GdbObjectReference(sourceFeature); } result.AddRange(individualResultList); _msg.VerboseDebugFormat( "Individual geometry's subcurve calculation result: {0}", individualResult); Marshal.ReleaseComObject(sourceGeometry); } return(result); }
/// <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); }
public CutPolygonSubcurveCalculator() { _standardSubcurveCalculator = new ReshapableSubcurveCalculator(); }