/// <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);
        }
Exemplo n.º 2
0
        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);
        }
Exemplo n.º 3
0
        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);
        }
Exemplo n.º 4
0
        /// <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));
        }
Exemplo n.º 5
0
        /// <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);
        }