Exemple #1
0
        private static IPath GetSharedBoundaryProlongation(
            [NotNull] ICurve curveToReshape,
            [NotNull] IPath sharedBoundary,
            [NotNull] IPoint sourceConnectPoint,
            [NotNull] IPath reshapePath,
            double tolerance,
            [CanBeNull] out IPoint targetConnectPoint)
        {
            // try elongate the shared boundary's last segment
            ISegment sourceSegment = GetConnectSegment(sharedBoundary,
                                                       sourceConnectPoint, tolerance);

            LineEnd segmentEndToProlong = GeometryUtils.AreEqualInXY(sourceSegment.FromPoint,
                                                                     sourceConnectPoint)
                                                              ? LineEnd.From
                                                              : LineEnd.To;

            IPath result = ReshapeUtils.GetProlongation(curveToReshape, sourceSegment,
                                                        reshapePath, segmentEndToProlong,
                                                        out targetConnectPoint);

            if (result != null && segmentEndToProlong == LineEnd.From)
            {
                result.ReverseOrientation();
            }

            // TODO: The ITopoOp.Difference with the source performed in ReshapeUtils.GetProlongation might handle some
            //       difficult situations, but also prevent a solution where the source intersection is on the
            //       interiour of a segment in one polygon and on a vertex in the other. Currently this must be
            //       dealt with by the user (placing a target intersection point).

            return(result);
        }
        private static bool IsPathFullyCovered(
            [NotNull] IPath path,
            [NotNull] IPolygon insideSourcePolygon,
            [NotNull] IEnumerable <CutSubcurve> bySubCurves)
        {
            IPolyline classicCurvesPolyline = GeometryFactory.CreateEmptyPolyline(path);

            object missing = Type.Missing;

            foreach (IPath classicCurve in bySubCurves.Select(
                         cutSubcurve => cutSubcurve.Path))
            {
                ((IGeometryCollection)classicCurvesPolyline).AddGeometry(classicCurve,
                                                                         ref missing,
                                                                         ref missing);
            }

            IGeometry highLevelPath = GeometryUtils.GetHighLevelGeometry(path);

            IGeometry highLevelPathInside =
                IntersectionUtils.GetIntersectionLines(
                    (IPolyline)highLevelPath, insideSourcePolygon, true, true);

            IGeometry difference =
                ReshapeUtils.GetDifferencePolyline(
                    (IPolyline)highLevelPathInside, classicCurvesPolyline);

            // Test: Simplify required?

            return(difference.IsEmpty);
        }
        public static ShapeMsg GetOpenJawReshapeReplaceEndPoint(
            [NotNull] OpenJawReshapeLineReplacementRequest request,
            [CanBeNull] ITrackCancel trackCancel = null)
        {
            var polylineToReshape =
                (IPolyline)ProtobufGeometryUtils.FromShapeMsg(request.Feature.Shape);
            var reshapeLine =
                (IPolyline)ProtobufGeometryUtils.FromShapeMsg(request.ReshapePath);

            IPoint endPoint = null;

            if (polylineToReshape != null && reshapeLine != null)
            {
                endPoint = ReshapeUtils.GetOpenJawReshapeLineReplaceEndPoint(
                    polylineToReshape, reshapeLine, request.UseNonDefaultReshapeSide);
            }

            if (endPoint == null)
            {
                return(new ShapeMsg());
            }

            ShapeMsg result = ProtobufGeometryUtils.ToShapeMsg(endPoint);

            return(result);
        }
Exemple #4
0
        private IEnumerable <KeyValuePair <IPoint, IPoint> > CalculateSourceTargetPairs(
            [NotNull] IList <IPolycurve> sourceGeometries,
            [NotNull] IPointCollection targetIntersectionPoints)
        {
            // for all tuples -> calculate standard intersection points (possibly clip first and only use original shapes if none found?)

            if (sourceGeometries.Count <= 1)
            {
                return(new List <KeyValuePair <IPoint, IPoint> >(0));
            }

            IMultipoint sourceIntersectionPoints =
                CalculateSourceIntersections(sourceGeometries);

            // TODO: re-use SourceIntersections if selected features have not changed

            IPointCollection             unpairedSourcePoints;
            IDictionary <IPoint, IPoint> sourceTargetPairs =
                ReshapeUtils.PairByDistance((IPointCollection)sourceIntersectionPoints,
                                            targetIntersectionPoints, out unpairedSourcePoints);

            _unpairedSourceIntersectionPoints = unpairedSourcePoints;

            return(sourceTargetPairs);
        }
Exemple #5
0
        public void Cut([NotNull] IList <CutSubcurve> cutSubcurves,
                        [CanBeNull] ITrackCancel trackCancel = null)
        {
            Assert.ArgumentNotNull(cutSubcurves, nameof(cutSubcurves));
            Assert.ArgumentCondition(_featuresToCut.Count > 0, "No polygon to cut");

            if (cutSubcurves.Count == 0)
            {
                return;
            }

            // simplify the curves to connect several yellow cut subcurves into a proper path
            IGeometry geometryPrototype = _featuresToCut[0].Shape;

            IGeometryCollection simplifiedCurves =
                ReshapeUtils.GetSimplifiedReshapeCurves(
                    cutSubcurves, geometryPrototype.SpatialReference);

            if (simplifiedCurves.GeometryCount == 0)
            {
                return;
            }

            Cut((IPolyline)simplifiedCurves, trackCancel);

            if (TargetFeatures != null && ResultGeometriesByFeature.Count > 0)
            {
                InsertIntersectingVerticesInTargets(TargetFeatures,
                                                    (IGeometry)simplifiedCurves);
            }
        }
        public void CanReshapeMultipatch()
        {
            ISpatialReference lv95 = SpatialReferenceUtils.CreateSpatialReference(
                WellKnownHorizontalCS.LV95);

            IPolygon polygon = GeometryFactory.CreatePolygon(
                GeometryFactory.CreateEnvelope(2600000, 1200000, 500, 50, 20, lv95));

            IMultiPatch multiPatch = GeometryFactory.CreateMultiPatch(
                polygon);

            IPolyline cutLine = GeometryFactory.CreateLine(
                GeometryFactory.CreatePoint(2600000 - 100, 1200000),
                GeometryFactory.CreatePoint(2600000 + 100, 1200000));

            cutLine.SpatialReference = lv95;

            var reshapePath = (IPath)((IGeometryCollection)cutLine).Geometry[0];

            var reshapeInfo = new ReshapeInfo(multiPatch, reshapePath, null);

            IList <ReshapeInfo> singleReshapes;

            ReshapeUtils.ReshapeAllGeometryParts(reshapeInfo, reshapePath,
                                                 out singleReshapes);

            var reshapedRing = (IRing)((IGeometryCollection)multiPatch).Geometry[0];

            Assert.True(MathUtils.AreEqual(((IArea)reshapedRing).Area,
                                           ((IArea)polygon).Area / 2,
                                           0.1));
        }
        public void CanCutPolygonWithCorrectZ_Top4666()
        {
            // Tests the work-around for TOP-4666
            // TODO: Report ArcObjects bug to Esri Inc.
            IFeature polygonFeature = TestUtils.CreateMockFeature("PolygonTop4666.xml");

            var cutLine =
                (IPolyline)
                TestUtils.ReadGeometryFromXml(
                    TestUtils.GetGeometryTestDataPath("CutLineTop4666.xml"));

            GeometryUtils.EnsureSpatialReference(
                cutLine, polygonFeature.Shape.SpatialReference);

            var cutter = new FeatureCutter(new[] { polygonFeature });

            Stopwatch watch = Stopwatch.StartNew();

            cutter.Cut(cutLine);

            watch.Stop();

            Console.WriteLine("Cut large feature: {0}ms", watch.ElapsedMilliseconds);

            Assert.AreEqual(5, cutter.ResultGeometriesByFeature[polygonFeature].Count);

            foreach (IGeometry geometry in cutter.ResultGeometriesByFeature[
                         polygonFeature])
            {
                var polygon = (IPolygon)geometry;

                Assert.False(GeometryUtils.HasUndefinedZValues(polygon));

                GeometryUtils.Simplify(polygon);

                Assert.False(GeometryUtils.HasUndefinedZValues(polygon));

                foreach (IPoint point in GeometryUtils.GetPoints(
                             (IPointCollection)polygon))
                {
                    Assert.AreNotEqual(0, point.Z);
                }

                IPolyline resultAsPolyline = GeometryFactory.CreatePolyline(polygon);

                IPolyline zDifference =
                    ReshapeUtils.GetZOnlyDifference(resultAsPolyline, cutLine);

                // ArcObjects uses the cutLine's Z also at the intersection points.
                // Do the same in CustomIntersect?
                Assert.IsNull(zDifference);
            }
        }
        public void InsertIntersectingVerticesInTargets(
            [NotNull] IEnumerable <IFeature> targetFeatures,
            [NotNull] IPolycurve removeGeometry)
        {
            if (Result.TargetFeaturesToUpdate == null)
            {
                Result.TargetFeaturesToUpdate = new Dictionary <IFeature, IGeometry>();
            }

            ReshapeUtils.InsertIntersectingVerticesInTargets(
                targetFeatures, removeGeometry,
                Result.TargetFeaturesToUpdate);
        }
Exemple #9
0
        private void InsertIntersectingVerticesInTargets(
            [NotNull] IEnumerable <IFeature> targetFeatures,
            [NotNull] IGeometry intersectingGeometry)
        {
            if (_targetsToUpdate == null)
            {
                _targetsToUpdate = new Dictionary <IFeature, IGeometry>();
            }

            ReshapeUtils.InsertIntersectingVerticesInTargets(targetFeatures,
                                                             intersectingGeometry,
                                                             _targetsToUpdate);
        }
        public void CanCalculateDifferenceInLargeGeometry()
        {
            const int manyPointsPerPart = 123456;
            const int holes             = 3;

            IPolygon poly2a =
                CreatePunchedSquarePolygon("2a", manyPointsPerPart, holes, 1);

            GeometryUtils.Simplify(poly2a, true, true);

            IPolygon poly2b = GeometryFactory.Clone(poly2a);

            var watch = new Stopwatch();

            watch.Start();

            IPolyline line2a = GeometryFactory.CreatePolyline(poly2a);
            IPolyline line2b = GeometryFactory.CreatePolyline(poly2b);

            watch.Stop();

            Console.WriteLine(@"Created polylines in {0} ms", watch.ElapsedMilliseconds);

            watch.Reset();
            watch.Start();

            IPolyline result = ReshapeUtils.GetZOnlyDifference(line2a,
                                                               line2b);

            watch.Stop();

            Assert.IsNull(result);

            Console.WriteLine(@"Calculate Z-only difference (no changes) in {0} ms",
                              watch.ElapsedMilliseconds);

            var comparison = new GeometryComparison(line2a, line2b);

            watch.Reset();
            watch.Start();

            IDictionary <WKSPointZ, VertexIndex> differences =
                comparison.GetDifference(true);

            watch.Stop();

            Console.WriteLine(@"Calculate Difference (no changes) in {0} ms",
                              watch.ElapsedMilliseconds);

            Assert.AreEqual(0, differences.Count);
        }
Exemple #11
0
        public ReshapeResultFilter(
            [CanBeNull] List <IEnvelope> allowedExtents,
            [CanBeNull] IEnumerable <IFeature> unallowedOverlapGeometries,
            bool useMinimalTolerance)
        {
            _allowedExtents = allowedExtents;

            if (unallowedOverlapGeometries != null)
            {
                _targetUnionPoly = ReshapeUtils.CreateUnionPolygon(
                    GdbObjectUtils.GetGeometries(unallowedOverlapGeometries),
                    useMinimalTolerance);
            }
        }
Exemple #12
0
        private bool Reshape([NotNull] IGeometry geometryToReshape,
                             [NotNull] IPath reshapePath)
        {
            ReshapeInfo reshapeInfo;
            bool        reshaped = ReshapeUtils.ReshapeGeometry(geometryToReshape, reshapePath, false,
                                                                null, out reshapeInfo);

            if (reshaped)
            {
                AddToRefreshArea(reshapeInfo);
            }

            return(reshaped);
        }
        private bool TryReshape([NotNull] IPath reshapePath,
                                bool tryReshapeRingNonDefaultSide,
                                [CanBeNull] NotificationCollection notifications,
                                out IGeometry geometryToReshape)
        {
            Assert.Null(TargetFeatures,
                        "Target features are set. This method does not support target feature updates.");

            geometryToReshape = ReshapeGeometryCloneByFeature[_feature];

            var reshapeInfo = new ReshapeInfo(geometryToReshape, reshapePath,
                                              notifications)
            {
                ReshapeResultFilter =
                    GetResultFilter(tryReshapeRingNonDefaultSide),
                AllowSimplifiedReshapeSideDetermination =
                    AllowSimplifiedReshapeSideDetermination,
                AllowOpenJawReshape = AllowOpenJawReshape
            };

            IList <ReshapeInfo> reshapeInfos;
            bool reshaped = ReshapeUtils.ReshapeAllGeometryParts(reshapeInfo, reshapePath,
                                                                 out reshapeInfos);

            if (reshaped)
            {
                reshaped = AreAllReshapesAllowed(reshapeInfos, notifications);
            }

            if (reshaped)
            {
                AddToRefreshArea(reshapeInfos);

                NotificationIsWarning = reshapeInfo.NotificationIsWarning;

                if (reshapeInfo.IsOpenJawReshape)
                {
                    OpenJawReshapeOcurred         = true;
                    OpenJawIntersectionPointCount =
                        reshapeInfo.IntersectionPoints.PointCount;
                }
            }

            foreach (ReshapeInfo singleReshape in reshapeInfos)
            {
                singleReshape.Dispose();
            }

            return(reshaped);
        }
Exemple #14
0
        private static IPath GetSharedBoundaryProlongation([NotNull] ICurve curveToReshape,
                                                           [NotNull] IPath
                                                           sourceReplacementPath,
                                                           bool atSourceReplacementFromPoint,
                                                           [NotNull] IPath reshapePath,
                                                           double tolerance,
                                                           out IPoint targetConnectPoint)
        {
            IPoint sourceConnectPoint = atSourceReplacementFromPoint
                                                            ? sourceReplacementPath.FromPoint
                                                            : sourceReplacementPath.ToPoint;

            // try elongate the curveToReshape's last segment that's not part of the replacement path
            ISegment sourceSegment = GetConnectSegment(sourceReplacementPath, curveToReshape,
                                                       sourceConnectPoint, tolerance);

            IPath result = ReshapeUtils.GetProlongation(curveToReshape, sourceSegment,
                                                        reshapePath,
                                                        out targetConnectPoint);

            if (result == null)
            {
                // check if the reshape path intersects the source segment:
                IGeometry highLevelSourceSegment =
                    GeometryUtils.GetHighLevelGeometry(sourceSegment, true);

                IGeometry highLevelReshapePath = GeometryUtils.GetHighLevelGeometry(reshapePath,
                                                                                    true);

                var intersectionPoints =
                    (IPointCollection)IntersectionUtils.GetIntersectionPoints(
                        highLevelReshapePath,
                        highLevelSourceSegment, false);

                if (intersectionPoints.PointCount == 1)
                {
                    result             = CreateSinglePointPath(intersectionPoints.Point[0]);
                    targetConnectPoint = intersectionPoints.Point[0];
                }
                else
                {
                    _msg.DebugFormat(
                        "The source last shared segment has {0} intersection points with the reshape path. Currently not supported",
                        intersectionPoints.PointCount);
                }
            }

            return(result);
        }
        public StickyIntersectionConnectLineCalculator(
            [NotNull] IPolyline highLevelSketch,
            [NotNull] IPolyline individuallyReshapedPolyline,
            [NotNull] List <KeyValuePair <IPoint, IPoint> > intersectingSourceTargetPoints,
            [NotNull] Dictionary <IGeometry, IList <ReshapeInfo> > individualReshapes)
        {
            _highlevelSketchGeometry = highLevelSketch;

            _intersectingSourceTargetPoints = intersectingSourceTargetPoints;
            _individualReshapes             = individualReshapes;

            UnreshapedBoundaryPart =
                ReshapeUtils.GetDifferencePolyline(individuallyReshapedPolyline,
                                                   _highlevelSketchGeometry);
        }
Exemple #16
0
        private IPolyline GetDifferencePolylineXyz(
            [NotNull] IPolyline onPolyline,
            [NotNull] IPolyline differentFrom)
        {
            double xyTolerance = GeometryUtils.GetXyTolerance(onPolyline);

            // For the Geom-implementation, use resolution / 2 because it is based on actual Z
            // differences without snapping intermediate results to spatial reference.
            double zTolerance = UseMinimumTolerance
                                                    ? GeometryUtils.GetZResolution(differentFrom) / 2
                                                    : GeometryUtils.GetZTolerance(differentFrom);

            return(ReshapeUtils.GetDifferencePolylineXyz(
                       onPolyline, differentFrom, xyTolerance, zTolerance));
        }
Exemple #17
0
        public ReshapeResultFilter(
            [CanBeNull] List <IEnvelope> allowedExtents,
            [CanBeNull] IEnumerable <IFeature> unallowedOverlapGeometries,
            bool useMinimalTolerance)
        {
            // Set allowed extents only if there are any. Otherwise everything will be filtered.
            _allowedExtents = allowedExtents?.Count > 0 ? allowedExtents : null;

            if (unallowedOverlapGeometries != null)
            {
                _targetUnionPoly = ReshapeUtils.CreateUnionPolygon(
                    GdbObjectUtils.GetGeometries(unallowedOverlapGeometries),
                    useMinimalTolerance);
            }
        }
Exemple #18
0
        private static bool ReshapeSinglePolygonInUnion(ReshapeInfo reshapeInfo)
        {
            bool reshaped;

            if (reshapeInfo.CutReshapePath != null)
            {
                if (reshapeInfo.CutReshapePath.Path.Length > 0)
                {
                    // reshape the known polygon part with the known cut reshape path
                    reshaped = ReshapeUtils.ReshapePolygonOrMultipatch(reshapeInfo);
                }
                else
                {
                    _msg.DebugFormat(
                        "No need to reshape geometry with 0-length reshape path at {0} | {1}",
                        reshapeInfo.CutReshapePath.Path.FromPoint.X,
                        reshapeInfo.CutReshapePath.Path.FromPoint.Y);
                    reshaped = false;
                }
            }
            else
            {
                Assert.NotNull(reshapeInfo.ReshapePath,
                               "Reshape path and cut reshape path are undefined");

                // try reshape if possible (typically for union-reshapes to the inside)
                var requiredPartIndexToReshape =
                    (int)Assert.NotNull(reshapeInfo.PartIndexToReshape);

                IList <int> currentlyReshapableParts;
                reshapeInfo.IdentifyUniquePartIndexToReshape(out currentlyReshapableParts);

                if (currentlyReshapableParts.Contains(requiredPartIndexToReshape))
                {
                    // reset to make sure no other parts are reshaped here:
                    reshapeInfo.PartIndexToReshape = requiredPartIndexToReshape;
                    reshaped = ReshapeUtils.ReshapeGeometryPart(reshapeInfo.GeometryToReshape,
                                                                reshapeInfo);
                }
                else
                {
                    reshaped = false;
                }
            }

            return(reshaped);
        }
        private static ReshapeInfo Reshape(IGeometry geometryToReshape,
                                           IGeometry reshapeLine,
                                           bool tryReshapeNonDefaultSide)
        {
            var reshapePath = (IPath)((IGeometryCollection)reshapeLine).get_Geometry(0);

            var reshapeInfo = new ReshapeInfo(geometryToReshape, reshapePath, null);

            reshapeInfo.ReshapeResultFilter = new ReshapeResultFilter(tryReshapeNonDefaultSide);

            IList <int> allParts;

            reshapeInfo.IdentifyUniquePartIndexToReshape(out allParts);

            Assert.IsTrue(ReshapeUtils.ReshapePolygonOrMultipatch(reshapeInfo));

            GeometryUtils.Simplify(geometryToReshape);

            return(reshapeInfo);
        }
Exemple #20
0
        /// <summary>
        /// Determines whether the proposed reshape side and result is allowed regarding other
        /// criteria than the geometric situation. These could be determined by the current reshape
        /// options, such as allowed target overlaps or updates to the geometry outside the visible
        /// extent.
        /// This method is called after the default reshape side has been determined
        /// and the ReshapeSide property of the reshape info is set. It takes precedence over the
        /// boolean parameter useNonDefaultReshapeSide available in the reshape methods.
        /// </summary>
        /// <param name="reshapeInfo"></param>
        /// <param name="proposedSide"></param>
        /// <param name="notifications"></param>
        /// <returns></returns>
        public bool IsReshapeSideAllowed([NotNull] ReshapeInfo reshapeInfo,
                                         RingReshapeSideOfLine proposedSide,
                                         [CanBeNull] NotificationCollection notifications)
        {
            if (proposedSide == RingReshapeSideOfLine.Undefined)
            {
                // Special case, such as zig-zag
                return(true);
            }

            if (_allowedExtents != null &&
                !ChangesVisibleInAnyExtent(_allowedExtents, GetChangedSegments(
                                               reshapeInfo,
                                               proposedSide)))
            {
                NotificationUtils.Add(notifications,
                                      "Reshape side was swapped because otherwise the geometry would change outside the allowed (visible) extents. This is prevented by the option Exclude reshapes that are not completely within main map extent'.");

                return(false);
            }

            if (_targetUnionPoly != null)
            {
                IPolygon proposedResult =
                    proposedSide == RingReshapeSideOfLine.Left
                                                ? reshapeInfo.LeftReshapePolygon
                                                : reshapeInfo.RightReshapePolygon;

                if (ReshapeUtils.ResultsInOverlapWithTarget(reshapeInfo, proposedResult,
                                                            _targetUnionPoly))
                {
                    NotificationUtils.Add(notifications,
                                          "Reshape side was swapped because otherwise the result would overlap a target. This is prevented by the option 'Exclude reshape lines that result in overlaps with target features'.");
                    return(false);
                }
            }

            return(true);
        }
        private static IPolyline VerifyZOnlyDifferences(IPolyline sourcePolyline,
                                                        IPolyline targetPolyline,
                                                        int expectedResultLength,
                                                        double zTolerance = 0)
        {
            IPolyline geomOpResult = IntersectionUtils.GetZOnlyDifferenceLines(
                sourcePolyline, targetPolyline, zTolerance);

            Assert.IsNotNull(geomOpResult);
            Assert.AreEqual(expectedResultLength, Math.Round(geomOpResult.Length, 3));

            IPolyline legacyResult =
                ReshapeUtils.GetZOnlyDifferenceLegacy(sourcePolyline,
                                                      targetPolyline, zTolerance);

            Assert.IsNotNull(legacyResult);

            Assert.AreEqual(expectedResultLength, Math.Round(legacyResult.Length, 3));

            GeometryUtils.AreEqual(geomOpResult, legacyResult);

            return(geomOpResult);
        }
Exemple #22
0
        public void CanReshapeAlongMinimalTolerance()
        {
            GetOverlappingPolygons(out GdbFeature sourceFeature, out GdbFeature targetFeature);

            // Insert an extra point:
            IPoint targetAlmostIntersectPoint = GeometryFactory.CreatePoint(
                2601000.001, 1200500.0, sourceFeature.Shape.SpatialReference);

            bool pointInserted = ReshapeUtils.EnsurePointsExistInTarget(
                targetFeature.Shape,
                new[] { targetAlmostIntersectPoint }, 0.001);

            Assert.IsTrue(pointInserted);
            Assert.AreEqual(6, GeometryUtils.GetPointCount(targetFeature.Shape));

            CalculateReshapeLinesRequest calculationRequest =
                CreateCalculateReshapeLinesRequest(sourceFeature, targetFeature);

            CalculateReshapeLinesResponse calculateResponse =
                ChangeAlongServiceUtils.CalculateReshapeLines(calculationRequest, null);

            Assert.AreEqual((int)ReshapeAlongCurveUsability.CanReshape,
                            calculateResponse.ReshapeLinesUsability);
            AssertReshapeLineCount(calculateResponse.ReshapeLines, 2, 2);

            int insideLineIndex =
                GetInsideReshapeLineIndex(calculateResponse.ReshapeLines, sourceFeature.Shape);

            IPolyline insideLine =
                (IPolyline)ProtobufGeometryUtils.FromShapeMsg(
                    calculateResponse.ReshapeLines[insideLineIndex].Path);

            Assert.NotNull(insideLine);
            Assert.AreNotEqual(1000.0, (insideLine).Length);

            // NOTE: If IntersectionUtils.UseCustomIntersect = true the from point is exactly on the inserted point
            //       Otherwise it's somewhere between - so we cannot do the exact comparison
            Assert.AreNotEqual(insideLine.FromPoint.X, 2601000.0);
            Assert.AreNotEqual(insideLine.ToPoint.X, 2601000.0);

            //
            // Reshape the default side:
            ApplyReshapeLinesRequest applyRequest = new ApplyReshapeLinesRequest();

            applyRequest.ReshapeLines.Add(calculateResponse.ReshapeLines[insideLineIndex]);
            applyRequest.CalculationRequest       = calculationRequest;
            applyRequest.InsertVerticesInTarget   = false;
            applyRequest.UseNonDefaultReshapeSide = false;

            ApplyReshapeLinesResponse applyResponse =
                ChangeAlongServiceUtils.ApplyReshapeLines(applyRequest, null);

            Assert.AreEqual(1, applyResponse.ResultFeatures.Count);

            GdbObjectMsg updatedFeatureMsg = applyResponse.ResultFeatures[0].Update;
            IGeometry    updatedGeometry   = ProtobufGeometryUtils.FromShapeMsg(updatedFeatureMsg.Shape);

            Assert.IsNotNull(updatedGeometry);
            Assert.Greater(((IArea)updatedGeometry).Area, 1000.0 * 1000.0 * 3 / 4);

            // Check the new reshape line:
            AssertReshapeLineCount(applyResponse.NewReshapeLines, 1, 1);

            Assert.AreEqual((int)ReshapeAlongCurveUsability.CanReshape,
                            applyResponse.ReshapeLinesUsability);

            //
            //
            // The same using the minimum tolerance:
            //
            calculationRequest.Tolerance = 0;

            calculateResponse =
                ChangeAlongServiceUtils.CalculateReshapeLines(calculationRequest, null);

            Assert.AreEqual((int)ReshapeAlongCurveUsability.CanReshape,
                            calculateResponse.ReshapeLinesUsability);
            AssertReshapeLineCount(calculateResponse.ReshapeLines, 2, 2);

            insideLineIndex =
                GetInsideReshapeLineIndex(calculateResponse.ReshapeLines, sourceFeature.Shape);

            insideLine =
                (IPolyline)ProtobufGeometryUtils.FromShapeMsg(
                    calculateResponse.ReshapeLines[insideLineIndex].Path);

            Assert.NotNull(insideLine);
            Assert.AreEqual(1000.0, insideLine.Length, 0.000000001);

            // NOTE: If IntersectionUtils.UseCustomIntersect = true the from point is exactly on the inserted point
            //       Otherwise it's somewhere between - so we cannot do the exact comparison
            Assert.AreEqual(2601000.0, insideLine.FromPoint.X);
            Assert.AreEqual(1200500.0, insideLine.FromPoint.Y);

            //
            // Apply with minimum tolerance:
            applyRequest = new ApplyReshapeLinesRequest();

            applyRequest.ReshapeLines.Add(calculateResponse.ReshapeLines[insideLineIndex]);
            applyRequest.CalculationRequest       = calculationRequest;
            applyRequest.InsertVerticesInTarget   = false;
            applyRequest.UseNonDefaultReshapeSide = false;

            applyResponse =
                ChangeAlongServiceUtils.ApplyReshapeLines(applyRequest, null);

            Assert.AreEqual(1, applyResponse.ResultFeatures.Count);

            updatedFeatureMsg = applyResponse.ResultFeatures[0].Update;

            updatedGeometry = ProtobufGeometryUtils.FromShapeMsg(updatedFeatureMsg.Shape);

            Assert.IsNotNull(updatedGeometry);
            Assert.AreEqual(1000 * 1000 * 3 / 4, ((IArea)updatedGeometry).Area);

            // Check the new remaining reshape line (outside)
            AssertReshapeLineCount(applyResponse.NewReshapeLines, 1, 1);
            Assert.AreEqual((int)ReshapeAlongCurveUsability.CanReshape,
                            applyResponse.ReshapeLinesUsability);

            IPolyline outsideLine = (IPolyline)ProtobufGeometryUtils.FromShapeMsg(
                applyResponse.NewReshapeLines[0].Path);

            Assert.NotNull(outsideLine);
            Assert.AreEqual(3000.0, outsideLine.Length, 0.000000001);

            // NOTE: If IntersectionUtils.UseCustomIntersect = true the from point is exactly on the inserted point
            //       Otherwise it's somewhere between - so we cannot do the exact comparison
            Assert.AreEqual(2601000.0, outsideLine.ToPoint.X);
            Assert.AreEqual(1200500.0, outsideLine.ToPoint.Y);
        }
        public void CannotPerformVerticalReshapeOnFlatRing()
        {
            // Originally this geometry resulted in an endless loop because
            // IntersectionUtils.IntersectNonPlanar returned the incorrect result
            ISpatialReference lv95 = SpatialReferenceUtils.CreateSpatialReference(
                WellKnownHorizontalCS.LV95, WellKnownVerticalCS.LHN95);

            // The problem cannot be reproduced with standard resolution
            var srResolution = (ISpatialReferenceResolution)lv95;

            srResolution.set_XYResolution(true, 0.001);

            var srTolerance = (ISpatialReferenceTolerance)lv95;

            srTolerance.XYTolerance = 0.01;

            // Vertical triangle, oriented towards the south:
            var points = new WKSPointZ[6];

            points[0] = new WKSPointZ
            {
                X = 2578309.3000000007,
                Y = 1183264.3999999985,
                Z = 619.14500000000407
            };

            points[1] = new WKSPointZ
            {
                X = 2578295.6829999983,
                Y = 1183260.568,
                Z = 619.14500000000407
            };

            points[2] = new WKSPointZ
            {
                X = 2578293.9990000017,
                Y = 1183266.5500000007,
                Z = 619.14500000000407
            };

            points[3] = new WKSPointZ
            {
                X = 2578295.9070000015,
                Y = 1183267.1559999995,
                Z = 619.14500000000407
            };

            points[4] = new WKSPointZ
            {
                X = 2578307.5989999995,
                Y = 1183270.4450000003,
                Z = 619.14500000000407
            };

            points[5] = new WKSPointZ
            {
                X = 2578309.3000000007,
                Y = 1183264.3999999985,
                Z = 619.14500000000407
            };

            IRing ring = new RingClass();

            ((IGeometry)ring).SpatialReference = lv95;
            GeometryUtils.MakeZAware(ring);
            GeometryUtils.SetWKSPointZs((IPointCollection4)ring, points);

            IMultiPatch multipatch = new MultiPatchClass();

            ((IGeometry)multipatch).SpatialReference = lv95;

            GeometryUtils.MakeZAware(multipatch);
            GeometryUtils.MakeMAware(multipatch);

            GeometryUtils.MakePointIDAware(multipatch);

            GeometryFactory.AddRingToMultiPatch(ring, multipatch,
                                                esriMultiPatchRingType
                                                .esriMultiPatchOuterRing);

            var unReshaped = (IRing)((IGeometryCollection)multipatch).Geometry[0];

            IPolyline cutLine = GeometryFactory.CreateLine(
                GeometryFactory.CreatePoint(2578314.9090000018, 1183246.2400000021),
                GeometryFactory.CreatePoint(2578307.4299999997, 1183270.4310000017));

            cutLine.SpatialReference = lv95;

            //GeometryUtils.MakeZAware(cutLine);

            var reshapePath = (IPath)((IGeometryCollection)cutLine).Geometry[0];

            Assert.IsTrue(((ICurve3D)unReshaped).IsClosed3D);

            var reshapeInfo = new ReshapeInfo(multipatch, reshapePath, null);

            IList <IPath> verticalPaths;

            Assert.IsFalse(reshapeInfo.IsVerticalRingReshape(0, out verticalPaths));

            Assert.AreEqual(0, verticalPaths.Count);

            Assert.IsTrue(ReshapeUtils.ReshapeGeometry(reshapeInfo, reshapePath));

            var reshapedRing = (IRing)((IGeometryCollection)multipatch).Geometry[0];

            Assert.AreEqual(6, ((IPointCollection)reshapedRing).PointCount);

            Assert.IsTrue(((ICurve3D)reshapedRing).IsClosed3D);
        }
        public void CanReshapeVerticalRingWithMutipleReshapeLineCrossings()
        {
            ISpatialReference lv95 = SpatialReferenceUtils.CreateSpatialReference(
                WellKnownHorizontalCS.LV95);

            // Vertical triangle, oriented towards the south:
            var points = new WKSPointZ[4];

            points[0] = new WKSPointZ
            {
                X = 2600000,
                Y = 1200000,
                Z = 500
            };

            points[1] = new WKSPointZ
            {
                X = 2600100,
                Y = 1200000,
                Z = 500
            };

            points[2] = new WKSPointZ
            {
                X = 2600050,
                Y = 1200000,
                Z = 1000
            };

            points[3] = new WKSPointZ
            {
                X = 2600000,
                Y = 1200000,
                Z = 500
            };

            IRing ring = new RingClass();

            ((IGeometry)ring).SpatialReference = lv95;
            GeometryUtils.MakeZAware(ring);
            GeometryUtils.SetWKSPointZs((IPointCollection4)ring, points);

            IMultiPatch multipatch = new MultiPatchClass();

            ((IGeometry)multipatch).SpatialReference = lv95;

            GeometryUtils.MakeZAware(multipatch);
            GeometryUtils.MakeMAware(multipatch);

            GeometryUtils.MakePointIDAware(multipatch);

            GeometryFactory.AddRingToMultiPatch(ring, multipatch,
                                                esriMultiPatchRingType
                                                .esriMultiPatchOuterRing);

            var unReshaped = (IRing)((IGeometryCollection)multipatch).Geometry[0];

            IPolyline cutLine = GeometryFactory.CreateLine(
                GeometryFactory.CreatePoint(2600075, 1200000 - 100, 222),
                GeometryFactory.CreatePoint(2600075, 1200000 + 100, 222),
                GeometryFactory.CreatePoint(2600025, 1200000 + 100, 222),
                GeometryFactory.CreatePoint(2600025, 1200000 - 100, 222));

            cutLine.SpatialReference = lv95;

            GeometryUtils.MakeZAware(cutLine);

            var reshapePath = (IPath)((IGeometryCollection)cutLine).Geometry[0];

            Assert.IsTrue(((ICurve3D)unReshaped).IsClosed3D);

            var reshapeInfo = new ReshapeInfo(multipatch, reshapePath, null);

            IList <IPath> verticalPaths;

            Assert.IsTrue(reshapeInfo.IsVerticalRingReshape(0, out verticalPaths));

            Assert.AreEqual(2, verticalPaths.Count);

            // Currently it is the caller's responsability to make 2 different reshapes using the desired side...

            // We want the middle part:

            // verticalPaths[0] is the one at X=2600025
            var reshape1 = new ReshapeInfo(multipatch, verticalPaths[0], null);

            reshape1.RingReshapeSide = RingReshapeSideOfLine.Right;
            reshape1.NonPlanar       = true;

            ReshapeUtils.ReshapeGeometry(reshape1, verticalPaths[0]);

            // verticalPaths[1] is the one at X=2600075
            var reshape2 = new ReshapeInfo(multipatch, verticalPaths[1], null);

            reshape2.RingReshapeSide = RingReshapeSideOfLine.Left;
            reshape2.NonPlanar       = true;

            ReshapeUtils.ReshapeGeometry(reshape2, verticalPaths[1]);

            var reshapedRing = (IRing)((IGeometryCollection)multipatch).Geometry[0];

            Assert.AreEqual(6, ((IPointCollection)reshapedRing).PointCount);

            Assert.IsTrue(((ICurve3D)reshapedRing).IsClosed3D);

            double expectedLength = Math.Sqrt(50 * 50 + 500 * 500) * 1.0 + 50 + 2 * 250;

            Assert.AreEqual(expectedLength, ((ICurve3D)reshapedRing).Length3D, 0.001);

            var newPoints = new WKSPointZ[6];

            GeometryUtils.QueryWKSPointZs((IPointCollection4)reshapedRing, newPoints);

            Assert.IsTrue(GeometryUtils.IsSamePoint(new WKSPointZ
            {
                X = 2600025,
                Y = 1200000,
                Z = 500
            }, newPoints[0], 0, 0));

            // the new cut points
            Assert.IsTrue(GeometryUtils.IsSamePoint(new WKSPointZ
            {
                X = 2600075,
                Y = 1200000,
                Z = 500
            }, newPoints[1], 0, 0));

            Assert.IsTrue(GeometryUtils.IsSamePoint(new WKSPointZ
            {
                X = 2600075,
                Y = 1200000,
                Z = 750
            }, newPoints[2], 0, 0));

            Assert.IsTrue(GeometryUtils.IsSamePoint(new WKSPointZ
            {
                X = 2600050,
                Y = 1200000,
                Z = 1000
            }, newPoints[3], 0, 0));

            Assert.IsTrue(GeometryUtils.IsSamePoint(new WKSPointZ
            {
                X = 2600025,
                Y = 1200000,
                Z = 750
            }, newPoints[4], 0, 0));
        }
        public void CanReshapeVerticalTriangularRingInMultipatch()
        {
            ISpatialReference lv95 = SpatialReferenceUtils.CreateSpatialReference(
                WellKnownHorizontalCS.LV95);

            //IRing ring = GeometryFactory.CreateRing(
            //	GeometryFactory.CreatePath())
            var points = new WKSPointZ[4];

            points[0] = new WKSPointZ
            {
                X = 2600000,
                Y = 1200000,
                Z = 500
            };

            points[1] = new WKSPointZ
            {
                X = 2600100,
                Y = 1200000,
                Z = 500
            };

            points[2] = new WKSPointZ
            {
                X = 2600050,
                Y = 1200000,
                Z = 1000
            };

            points[3] = new WKSPointZ
            {
                X = 2600000,
                Y = 1200000,
                Z = 500
            };

            IRing ring = new RingClass();

            ((IGeometry)ring).SpatialReference = lv95;
            GeometryUtils.MakeZAware(ring);
            GeometryUtils.SetWKSPointZs((IPointCollection4)ring, points);

            IMultiPatch multipatch = new MultiPatchClass();

            ((IGeometry)multipatch).SpatialReference = lv95;

            GeometryUtils.MakeZAware(multipatch);
            GeometryUtils.MakeMAware(multipatch);

            GeometryUtils.MakePointIDAware(multipatch);

            GeometryFactory.AddRingToMultiPatch(ring, multipatch,
                                                esriMultiPatchRingType
                                                .esriMultiPatchOuterRing);

            var unReshaped = (IRing)((IGeometryCollection)multipatch).Geometry[0];

            int originalPointCount = ((IPointCollection)unReshaped).PointCount;

            IPolyline cutLine = GeometryFactory.CreateLine(
                GeometryFactory.CreatePoint(2600075, 1200000 - 100, 222),
                GeometryFactory.CreatePoint(2600075, 1200000 + 100, 222));

            cutLine.SpatialReference = lv95;

            GeometryUtils.MakeZAware(cutLine);

            var reshapePath = (IPath)((IGeometryCollection)cutLine).Geometry[0];

            Assert.IsTrue(((ICurve3D)unReshaped).IsClosed3D);

            var reshapeInfo = new ReshapeInfo(multipatch, reshapePath, null)
            {
                NonPlanar = true
            };

            IList <ReshapeInfo> singleReshapes;

            ReshapeUtils.ReshapeAllGeometryParts(reshapeInfo, reshapePath,
                                                 out singleReshapes);

            var reshapedRing = (IRing)((IGeometryCollection)multipatch).Geometry[0];

            Assert.AreEqual(originalPointCount + 1,
                            ((IPointCollection)reshapedRing).PointCount);

            Assert.IsTrue(((ICurve3D)reshapedRing).IsClosed3D);

            double expectedLength = Math.Sqrt(50 * 50 + 500 * 500) * 1.5 + 75 + 250;

            Assert.AreEqual(expectedLength, ((ICurve3D)reshapedRing).Length3D, 0.001);

            var newPoints = new WKSPointZ[5];

            GeometryUtils.QueryWKSPointZs((IPointCollection4)reshapedRing, newPoints);

            // first, fourth and last
            Assert.IsTrue(GeometryUtils.IsSamePoint(points[0], newPoints[0], 0, 0));
            Assert.IsTrue(GeometryUtils.IsSamePoint(points[2], newPoints[3], 0, 0));
            Assert.IsTrue(GeometryUtils.IsSamePoint(points[3], newPoints[4], 0, 0));

            // the new cut points
            Assert.IsTrue(GeometryUtils.IsSamePoint(new WKSPointZ
            {
                X = 2600075,
                Y = 1200000,
                Z = 500
            }, newPoints[1], 0, 0));

            Assert.IsTrue(GeometryUtils.IsSamePoint(new WKSPointZ
            {
                X = 2600075,
                Y = 1200000,
                Z = 750
            }, newPoints[2], 0, 0));

            // And now reshape right through the vertex at the top, this time reshape the left
            cutLine = GeometryFactory.CreateLine(
                GeometryFactory.CreatePoint(2600050, 1200000 - 100, 222),
                GeometryFactory.CreatePoint(2600050, 1200000 + 100, 222));
            cutLine.SpatialReference = lv95;

            GeometryUtils.MakeZAware(cutLine);

            reshapePath = (IPath)((IGeometryCollection)cutLine).Geometry[0];

            reshapeInfo = new ReshapeInfo(multipatch, reshapePath, null)
            {
                NonPlanar = true
            };

            // keep the right (small part)
            reshapeInfo.RingReshapeSide = RingReshapeSideOfLine.Right;

            ReshapeUtils.ReshapeAllGeometryParts(reshapeInfo, reshapePath,
                                                 out singleReshapes);

            reshapedRing = (IRing)((IGeometryCollection)multipatch).Geometry[0];

            Assert.AreEqual(5, ((IPointCollection)reshapedRing).PointCount);
            Assert.IsTrue(((ICurve3D)reshapedRing).IsClosed3D);

            expectedLength = Math.Sqrt(50 * 50 + 500 * 500) * 0.5 + 25 + 500 + 250;
            Assert.AreEqual(expectedLength, ((ICurve3D)reshapedRing).Length3D, 0.001);

            newPoints = new WKSPointZ[5];
            GeometryUtils.QueryWKSPointZs((IPointCollection4)reshapedRing, newPoints);

            Assert.IsTrue(GeometryUtils.IsSamePoint(new WKSPointZ
            {
                X = 2600050,
                Y = 1200000,
                Z = 500
            }, newPoints[0], 0, 0));

            Assert.IsTrue(GeometryUtils.IsSamePoint(new WKSPointZ
            {
                X = 2600075,
                Y = 1200000,
                Z = 500
            }, newPoints[1], 0, 0));

            Assert.IsTrue(GeometryUtils.IsSamePoint(new WKSPointZ
            {
                X = 2600075,
                Y = 1200000,
                Z = 750
            }, newPoints[2], 0, 0));

            Assert.IsTrue(GeometryUtils.IsSamePoint(new WKSPointZ
            {
                X = 2600050,
                Y = 1200000,
                Z = 1000
            }, newPoints[3], 0, 0));
        }
        public void CanReshapeVerticalSquareRingInMultipatch()
        {
            ISpatialReference lv95 = SpatialReferenceUtils.CreateSpatialReference(
                WellKnownHorizontalCS.LV95);

            //IRing ring = GeometryFactory.CreateRing(
            //	GeometryFactory.CreatePath())
            var points = new WKSPointZ[5];

            points[0] = new WKSPointZ
            {
                X = 2600000,
                Y = 1200000,
                Z = 500
            };

            points[1] = new WKSPointZ
            {
                X = 2600100,
                Y = 1200000,
                Z = 500
            };

            points[2] = new WKSPointZ
            {
                X = 2600100,
                Y = 1200000,
                Z = 1000
            };

            points[3] = new WKSPointZ
            {
                X = 2600000,
                Y = 1200000,
                Z = 1000
            };

            points[4] = new WKSPointZ
            {
                X = 2600000,
                Y = 1200000,
                Z = 500
            };

            IRing ring = new RingClass();

            ((IGeometry)ring).SpatialReference = lv95;
            GeometryUtils.MakeZAware(ring);
            GeometryUtils.SetWKSPointZs((IPointCollection4)ring, points);

            IMultiPatch multipatch = new MultiPatchClass();

            ((IGeometry)multipatch).SpatialReference = lv95;

            GeometryUtils.MakeZAware(multipatch);
            GeometryUtils.MakeMAware(multipatch);

            GeometryUtils.MakePointIDAware(multipatch);

            GeometryFactory.AddRingToMultiPatch(ring, multipatch,
                                                esriMultiPatchRingType
                                                .esriMultiPatchOuterRing);

            var unReshaped = (IRing)((IGeometryCollection)multipatch).Geometry[0];

            int originalPointCount = ((IPointCollection)unReshaped).PointCount;

            // Left reshape is slightly larger -> vertical reshape side is determined by size only
            IPolyline cutLine = GeometryFactory.CreateLine(
                GeometryFactory.CreatePoint(2600051, 1200000 - 100, 222),
                GeometryFactory.CreatePoint(2600051, 1200000 + 100, 222));

            cutLine.SpatialReference = lv95;

            GeometryUtils.MakeZAware(cutLine);

            var reshapePath = (IPath)((IGeometryCollection)cutLine).Geometry[0];

            Assert.IsTrue(((ICurve3D)unReshaped).IsClosed3D);

            var reshapeInfo = new ReshapeInfo(multipatch, reshapePath, null)
            {
                NonPlanar = true
            };

            IList <ReshapeInfo> singleReshapes;

            ReshapeUtils.ReshapeAllGeometryParts(reshapeInfo, reshapePath,
                                                 out singleReshapes);

            var reshapedRing = (IRing)((IGeometryCollection)multipatch).Geometry[0];

            Assert.AreEqual(originalPointCount,
                            ((IPointCollection)reshapedRing).PointCount);

            Assert.IsTrue(((ICurve3D)reshapedRing).IsClosed3D);
            Assert.AreEqual(2 * 500 + 2 * 51, ((ICurve3D)reshapedRing).Length3D);

            var newPoints = new WKSPointZ[5];

            GeometryUtils.QueryWKSPointZs((IPointCollection4)reshapedRing, newPoints);

            // first, fourth and last
            Assert.IsTrue(GeometryUtils.IsSamePoint(points[0], newPoints[0], 0, 0));
            Assert.IsTrue(GeometryUtils.IsSamePoint(points[3], newPoints[3], 0, 0));
            Assert.IsTrue(GeometryUtils.IsSamePoint(points[4], newPoints[4], 0, 0));

            // the new cut points
            Assert.IsTrue(GeometryUtils.IsSamePoint(new WKSPointZ
            {
                X = 2600051,
                Y = 1200000,
                Z = 500
            }, newPoints[1], 0, 0));

            Assert.IsTrue(GeometryUtils.IsSamePoint(new WKSPointZ
            {
                X = 2600051,
                Y = 1200000,
                Z = 1000
            }, newPoints[2], 0, 0));
        }
Exemple #27
0
        private static CutSubcurve Replace(CutSubcurve cutSubcurve1,
                                           CutSubcurve cutSubcurve2,
                                           SubcurveNode mergeNode)
        {
            IGeometryCollection mergedCollection =
                ReshapeUtils.GetSimplifiedReshapeCurves(
                    new List <CutSubcurve> {
                cutSubcurve1, cutSubcurve2
            });

            Assert.AreEqual(1, mergedCollection.GeometryCount,
                            "Unexpected number of geometries after merging adjacent subcurves");

            var newPath = (IPath)mergedCollection.get_Geometry(0);

            bool         touchAtFrom;
            SubcurveNode oldNodeAtFrom = GetNodeAt(newPath.FromPoint, cutSubcurve1,
                                                   cutSubcurve2,
                                                   out touchAtFrom);

            bool         touchAtTo;
            SubcurveNode oldNodeAtTo = GetNodeAt(newPath.ToPoint, cutSubcurve1,
                                                 cutSubcurve2,
                                                 out touchAtTo);

            if (oldNodeAtFrom.ConnectedSubcurves.Contains(cutSubcurve1))
            {
                oldNodeAtFrom.ConnectedSubcurves.Remove(cutSubcurve1);
            }

            if (oldNodeAtFrom.ConnectedSubcurves.Contains(cutSubcurve2))
            {
                oldNodeAtFrom.ConnectedSubcurves.Remove(cutSubcurve2);
            }

            if (oldNodeAtTo.ConnectedSubcurves.Contains(cutSubcurve1))
            {
                oldNodeAtTo.ConnectedSubcurves.Remove(cutSubcurve1);
            }

            if (oldNodeAtTo.ConnectedSubcurves.Contains(cutSubcurve2))
            {
                oldNodeAtTo.ConnectedSubcurves.Remove(cutSubcurve2);
            }

            var result = new CutSubcurve(newPath, touchAtFrom, touchAtTo, oldNodeAtFrom,
                                         oldNodeAtTo);

            result.Source = cutSubcurve1.Source;

            oldNodeAtFrom.ConnectedSubcurves.Add(result);
            oldNodeAtTo.ConnectedSubcurves.Add(result);

            // Old target intersection points: Add them if they were not stitch points removed after simplify:
            IPoint connectPoint = GeometryFactory.CreatePoint(mergeNode.X, mergeNode.Y,
                                                              newPath.SpatialReference);

            int partIdx;
            int?connectIndex = GeometryUtils.FindHitVertexIndex(
                newPath, connectPoint, GeometryUtils.GetXyTolerance(newPath),
                out partIdx);

            if (connectIndex != null)
            {
                result.AddExtraPotentialTargetInsertPoint(
                    ((IPointCollection)newPath).get_Point((int)connectIndex));
            }

            return(result);
        }
        public void CanCalculateDifferenceInHugeLockergestein()
        {
            string filePath = TestData.GetHugeLockergesteinPolygonPath();
            var    poly1    = (IPolygon)ReadGeometryFromXML(filePath);

            Console.WriteLine(@"{0}: {1}",
                              @"Intersection Tests with 'Huge Lockergestein'",
                              GetVertexString(poly1));

            IPolygon poly2 = GeometryFactory.Clone(poly1);

            var watch = new Stopwatch();

            watch.Start();

            IPolyline result =
                ReshapeUtils.GetZOnlyDifference(
                    GeometryFactory.CreatePolyline(poly1),
                    GeometryFactory.CreatePolyline(poly2));

            watch.Stop();

            Console.WriteLine(
                @"Calculated Z difference in huge Lockergestein (no difference) in {0} ms",
                watch.ElapsedMilliseconds);

            Assert.IsNull(result);

            // Change few points in Z
            IPoint point7 = ((IPointCollection)poly2).get_Point(7);

            point7.Z += 0.01;
            ((IPointCollection)poly2).UpdatePoint(7, point7);

            IPoint point8 = ((IPointCollection)poly2).get_Point(8);

            point8.Z += 0.01;
            ((IPointCollection)poly2).UpdatePoint(8, point8);

            watch.Reset();
            watch.Start();
            result =
                ReshapeUtils.GetZOnlyDifference(
                    GeometryFactory.CreatePolyline(poly1),
                    GeometryFactory.CreatePolyline(poly2), 0.0);

            watch.Stop();

            Console.WriteLine(
                @"Calculated Z difference in huge Lockergestein (2 different) in {0} ms",
                watch.ElapsedMilliseconds);

            Assert.IsNotNull(result);
            Assert.IsFalse(result.IsEmpty);

            double changedLength = ((ISegmentCollection)poly2).Segment[6].Length +
                                   ((ISegmentCollection)poly2).Segment[7].Length +
                                   ((ISegmentCollection)poly2).Segment[8].Length;

            Assert.AreEqual(Math.Round(changedLength, 5), Math.Round(result.Length, 5));

            GeometryUtils.MoveGeometry(poly2, 0, 0, 0.5);

            watch.Reset();
            watch.Start();
            result =
                ReshapeUtils.GetZOnlyDifference(
                    GeometryFactory.CreatePolyline(poly1),
                    GeometryFactory.CreatePolyline(poly2));

            watch.Stop();

            Console.WriteLine(
                @"Calculated Z difference in huge Lockergestein (all different) in {0} ms",
                watch.ElapsedMilliseconds);

            Assert.IsNotNull(result);
            Assert.IsFalse(result.IsEmpty);
            Assert.AreEqual(Math.Round(poly2.Length, 5), Math.Round(result.Length, 5));
        }
Exemple #29
0
        public SubcurveFilter PrepareFilter(
            [NotNull] IList <IPolyline> preprocessedSourceLines,
            [NotNull] IList <IGeometry> targetGeometries,
            bool useMinimalTolerance,
            [NotNull] ReshapeCurveFilterOptions filterOptions)
        {
            _useMinimalTolerance = useMinimalTolerance;
            _filterOptions       = filterOptions;

            ReleaseFilterObjects();

            if (filterOptions.OnlyInVisibleExtent)
            {
                Assert.NotNull(_extentProvider);
                _currentlyVisibleExtents = new List <IEnvelope>();

                // add the lens window extents
                _currentlyVisibleExtents.AddRange(
                    _extentProvider.GetVisibleLensWindowExtents());

                // plus the main map window
                _currentlyVisibleExtents.Add(_extentProvider.GetCurrentExtent());
            }

            if (filterOptions.ExcludeOutsideTolerance)
            {
                // NOTE: Buffer lines / outlines -> otherwise we miss lines for individual reshapes
                //		 and clip on extent (pre-process) before buffering to improve performance

                var sourceOutline =
                    (IPolyline)GeometryUtils.UnionGeometries(preprocessedSourceLines);

                const int logInfoPointCountThreshold = 10000;
                var       bufferNotifications        = new NotificationCollection();

                if (AdjustUtils.TryBuffer(sourceOutline,
                                          filterOptions.ExcludeTolerance,
                                          logInfoPointCountThreshold,
                                          "Calculating reshape line tolerance buffer...",
                                          bufferNotifications,
                                          out _mustBeWithinSourceBuffer))
                {
                    ExclusionOutsideSourceBufferLine =
                        GeometryFactory.CreatePolyline(
                            Assert.NotNull(_mustBeWithinSourceBuffer));
                }
                else
                {
                    _msg.WarnFormat(
                        "Unable to calculate reshape line tolerance buffer: {0}",
                        bufferNotifications.Concatenate(". "));
                }

                Marshal.ReleaseComObject(sourceOutline);
            }

            if (filterOptions.ExcludeResultingInOverlaps)
            {
                _targetUnionPoly = ReshapeUtils.CreateUnionPolygon(
                    targetGeometries, _useMinimalTolerance);
            }

            return(this);
        }