Beispiel #1
0
        protected void AddToRefreshArea(ReshapeInfo reshapeInfo)
        {
            AddToRefreshArea(reshapeInfo.ReshapePath);

            // using replaced segments is an important optimization, especially for large polygons
            AddToRefreshArea(reshapeInfo.ReplacedSegments ?? reshapeInfo.GeometryToReshape);
        }
Beispiel #2
0
        public void CanValidateReshapeLine()
        {
            ISpatialReference sr = SpatialReferenceUtils.CreateSpatialReference(
                WellKnownHorizontalCS.LV95, WellKnownVerticalCS.LHN95);

            IPath reshapePath = GeometryFactory.CreatePath(
                GeometryFactory.CreatePoint(2600000.12, 1200000.12, sr),
                GeometryFactory.CreatePoint(2600000.121, 1200000.121, sr));

            IPolyline polyline = GeometryFactory.CreatePolyline(2600000, 1200000, 2600001,
                                                                1200001);
            var reshapeInfo = new ReshapeInfo(polyline, reshapePath, null);

            // It says it's closed but it's just a bit short
            Assert.IsTrue(reshapePath.IsClosed);
            Assert.IsFalse(reshapeInfo.ValidateReshapePath());

            // even with 3 points:
            WKSPoint middlePoint;

            middlePoint.X = 2600000.1205;
            middlePoint.Y = 1200000.1205;
            ((IPointCollection)reshapePath).InsertWKSPoints(1, 1, middlePoint);

            reshapeInfo = new ReshapeInfo(polyline, reshapePath, null);

            Assert.IsTrue(reshapePath.IsClosed);
            Assert.IsFalse(reshapeInfo.ValidateReshapePath());
        }
        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));
        }
Beispiel #4
0
        public void CanDeterminePolygonReshapeSideInsideOnlySeveralParts()
        {
            ISpatialReference spatialReference = SpatialReferenceUtils.CreateSpatialReference(
                WellKnownHorizontalCS.LV95, WellKnownVerticalCS.LHN95);

            IGeometry geometryToReshape =
                GeometryFactory.CreatePolygon(100, 100, 200, 200, spatialReference);

            IGeometry reshapeLine =
                GeometryFactory.CreatePolyline(spatialReference,
                                               GeometryFactory.CreatePoint(100, 200),
                                               GeometryFactory.CreatePoint(150, 100),
                                               GeometryFactory.CreatePoint(200, 200));

            ReshapeInfo reshapeInfo = Reshape(GeometryFactory.Clone(geometryToReshape),
                                              reshapeLine, false);

            ExpectResult(reshapeInfo, RingReshapeSideOfLine.Left, 5000, 1, 1);

            const bool useNonDefaultSide = true;

            reshapeInfo = Reshape(GeometryFactory.Clone(geometryToReshape),
                                  reshapeLine, useNonDefaultSide);

            ExpectResult(reshapeInfo, RingReshapeSideOfLine.Right, 5000, 2, 2);
        }
Beispiel #5
0
        public void CanDeterminePolygonReshapeSideInsideAndOutsideOnePartWithBoundaryLoop()
        {
            //     _
            //    / \
            //   /   \
            //--/--\--\-----
            //      \__\
            // The original polygon is below the horizontal dashed-line: ---

            ISpatialReference spatialReference = SpatialReferenceUtils.CreateSpatialReference(
                WellKnownHorizontalCS.LV95, WellKnownVerticalCS.LHN95);

            IGeometry geometryToReshape =
                GeometryFactory.CreatePolygon(100, 100, 200, 200, spatialReference);

            IGeometry reshapeLine =
                GeometryFactory.CreatePolyline(spatialReference,
                                               GeometryFactory.CreatePoint(125, 200),
                                               GeometryFactory.CreatePoint(125, 250),
                                               GeometryFactory.CreatePoint(175, 250),
                                               GeometryFactory.CreatePoint(175, 150),
                                               GeometryFactory.CreatePoint(150, 150),
                                               GeometryFactory.CreatePoint(150, 200));

            // plus one quarter minus 50 * 25 = 12500 - 1250 = 11250
            ReshapeInfo reshapeInfo = Reshape(GeometryFactory.Clone(geometryToReshape),
                                              reshapeLine, false);

            ExpectResult(reshapeInfo, RingReshapeSideOfLine.Right, 11250, 1, 1);

            // has boundary loop:
            MakeInnerRing(reshapeInfo.GeometryToReshape);
            GeometryUtils.Simplify(reshapeInfo.GeometryToReshape);
            Assert.AreEqual(3,
                            ((IGeometryCollection)reshapeInfo.GeometryToReshape).GeometryCount);
            Assert.AreEqual(2, ((IPolygon)reshapeInfo.GeometryToReshape).ExteriorRingCount);

            const bool useNonDefaultSide = true;

            reshapeInfo = Reshape(GeometryFactory.Clone(geometryToReshape),
                                  reshapeLine, useNonDefaultSide);

            // non-boundary loop variant:
            ExpectResult(reshapeInfo, RingReshapeSideOfLine.Left, 3750, 1, 1);

            MakeInnerRing(reshapeInfo.GeometryToReshape);
            GeometryUtils.Simplify(reshapeInfo.GeometryToReshape);
            Assert.AreEqual(2,
                            ((IGeometryCollection)reshapeInfo.GeometryToReshape).GeometryCount);
            Assert.AreEqual(1, ((IPolygon)reshapeInfo.GeometryToReshape).ExteriorRingCount);
        }
        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);
        }
Beispiel #7
0
        public bool IsResultAllowed(ReshapeInfo reshapeInfo,
                                    NotificationCollection notifications)
        {
            if (_allowedExtents != null &&
                !ChangesVisibleInAnyExtent(
                    _allowedExtents, GetChangedSegments(
                        reshapeInfo, reshapeInfo.RingReshapeSide)))
            {
                NotificationUtils.Add(notifications,
                                      "Some of the updated segments are outside the visible extent. The reshape is not allowed due to the option 'Exclude reshapes that are not completely within main map extent'");
                return(false);
            }

            return(true);
        }
Beispiel #8
0
        public MultiReshapeConnectLineCalculator(IGeometry originalUnion,
                                                 IGeometry geometryPartToReshape,
                                                 ReshapeInfo unionReshapeInfo,
                                                 double maxProlongationLengthFactor)
            : base(GeometryFactory.CreatePolyline(originalUnion))
        {
            _originalUnion               = originalUnion;
            _geometryPartToReshape       = geometryPartToReshape;
            _unionReshapeInfo            = unionReshapeInfo;
            _maxProlongationLengthFactor = maxProlongationLengthFactor;

            _tolerance = GeometryUtils.GetXyTolerance(originalUnion);

            Notifications         = new NotificationCollection();
            FallbackNotifications = new NotificationCollection();
        }
Beispiel #9
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);
        }
Beispiel #10
0
        private static void ExpectResult(ReshapeInfo reshapeInfo,
                                         RingReshapeSideOfLine reshapeSide, double area,
                                         int ringCount, int exteriorRingCount)
        {
            Assert.AreEqual(reshapeSide, reshapeInfo.RingReshapeSide);

            Assert.AreEqual(Math.Round(area, 2),
                            Math.Round(((IArea)reshapeInfo.GeometryToReshape).Area, 2),
                            "Wrong result area.");

            Assert.AreEqual(ringCount,
                            ((IGeometryCollection)reshapeInfo.GeometryToReshape).GeometryCount,
                            "Wrong number of rings in result.");
            Assert.AreEqual(exteriorRingCount,
                            ((IPolygon)reshapeInfo.GeometryToReshape).ExteriorRingCount,
                            "Wrong number of exterior rings in result.");
        }
Beispiel #11
0
        public void CanDeterminePolygonReshapeSideInsideOnlySeveralParts_OnIsland()
        {
            // currently implemented solution: always return single part result
            ISpatialReference spatialReference = SpatialReferenceUtils.CreateSpatialReference(
                WellKnownHorizontalCS.LV95, WellKnownVerticalCS.LHN95);

            IGeometry geometryToReshape =
                GeometryFactory.CreatePolygon(100, 100, 200, 200, spatialReference);

            MakeInnerRing(geometryToReshape);

            IGeometry reshapeLine =
                GeometryFactory.CreatePolyline(spatialReference,
                                               GeometryFactory.CreatePoint(100, 200),
                                               GeometryFactory.CreatePoint(150, 100),
                                               GeometryFactory.CreatePoint(200, 200));

            ReshapeInfo reshapeInfo = Reshape(GeometryFactory.Clone(geometryToReshape),
                                              reshapeLine, false);

            ExpectResult(reshapeInfo, RingReshapeSideOfLine.Right, 1000000 - 5000, 2, 1);

            // and the inner ring is single part, without boundary loop
            IRing    innerRing     = GetInnerRing(reshapeInfo);
            IPolygon innerRingPoly = GeometryFactory.CreatePolygon(innerRing, spatialReference);

            GeometryUtils.Simplify(innerRingPoly);

            Assert.AreEqual(1, ((IGeometryCollection)innerRingPoly).GeometryCount);

            const bool useNonDefaultSide = true;

            reshapeInfo = Reshape(GeometryFactory.Clone(geometryToReshape),
                                  reshapeLine, useNonDefaultSide);

            ExpectResult(reshapeInfo, RingReshapeSideOfLine.Left, 1000000 - 5000, 2, 1);

            // now the inner ring is single part but has a boundary loop
            innerRing     = GetInnerRing(reshapeInfo);
            innerRingPoly = GeometryFactory.CreatePolygon(innerRing, spatialReference);
            GeometryUtils.Simplify(innerRingPoly);

            Assert.AreEqual(2, ((IGeometryCollection)innerRingPoly).GeometryCount);
        }
Beispiel #12
0
        public void CanDeterminePolygonReshapeSideOutsideOnlyCuttingOffIsland_OnIsland()
        {
            // The below situation is an island ring, being reshaped to the outside of the island (i.e. into the actual polygon)
            //   ________
            //  /  _____ |
            // /__/ h  / |
            //---------------
            // The original polygon is below the reshape line (dashed-line ---)

            ISpatialReference spatialReference = SpatialReferenceUtils.CreateSpatialReference(
                WellKnownHorizontalCS.LV95, WellKnownVerticalCS.LHN95);

            IGeometry geometryToReshape =
                GeometryFactory.CreatePolygon(100, 100, 200, 200, spatialReference);

            MakeInnerRing(geometryToReshape);

            IGeometry reshapeLine =
                GeometryFactory.CreatePolyline(spatialReference,
                                               GeometryFactory.CreatePoint(200, 200),
                                               GeometryFactory.CreatePoint(200, 250),
                                               GeometryFactory.CreatePoint(125, 250),
                                               GeometryFactory.CreatePoint(125, 200),
                                               GeometryFactory.CreatePoint(150, 200),
                                               GeometryFactory.CreatePoint(150, 225),
                                               GeometryFactory.CreatePoint(175, 225),
                                               GeometryFactory.CreatePoint(175, 200));

            // plus 50 * 75 minus 25 * 25 = 3750 - 625 = 13125
            ReshapeInfo reshapeInfo = Reshape(GeometryFactory.Clone(geometryToReshape),
                                              reshapeLine, false);

            ExpectResult(reshapeInfo, RingReshapeSideOfLine.Right, 1000000 - 13125, 3, 2);

            const bool useNonDefaultSide = true;

            reshapeInfo = Reshape(GeometryFactory.Clone(geometryToReshape),
                                  reshapeLine, useNonDefaultSide);

            // not allowing non-default
            ExpectResult(reshapeInfo, RingReshapeSideOfLine.Right, 1000000 - 13125, 3, 2);
        }
Beispiel #13
0
        private bool ApplyReshapePath(IGeometry geometryToReshape, IPath reshapePath,
                                      NotificationCollection notifications,
                                      [CanBeNull] CutSubcurve cutSubcurve,
                                      IDictionary <IGeometry, NotificationCollection>
                                      reshapedGeometries)
        {
            var reshapeInfo =
                new ReshapeInfo(geometryToReshape, reshapePath,
                                notifications)
            {
                PartIndexToReshape = 0,                         // TODO
                CutReshapePath     = cutSubcurve
            };

            // TODO: make ReshapeSingleGeometryInUnion not depend on unionReshapeInfo and use the same general workflow?

            bool reshaped = ReshapeSinglePolygonInUnion(reshapeInfo);

            if (reshaped)
            {
                // to avoid incorrect relational operator results in for the next path on target
                ((ISegmentCollection)geometryToReshape).SegmentsChanged();

                AddToRefreshArea(reshapeInfo);
            }

            // move adding notfications to caller?
            if (reshaped && !reshapedGeometries.ContainsKey(reshapeInfo.GeometryToReshape))
            {
                reshapedGeometries.Add(reshapeInfo.GeometryToReshape, reshapeInfo.Notifications);
            }
            else
            {
                if (reshapeInfo.Notifications != null)
                {
                    NotificationUtils.Add(notifications,
                                          reshapeInfo.Notifications.Concatenate(" "));
                }
            }

            return(reshaped);
        }
Beispiel #14
0
        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);
        }
Beispiel #15
0
        public void CanReshapeNonLinearGeometry()
        {
            ISpatialReference spatialReference = SpatialReferenceUtils.CreateSpatialReference(
                WellKnownHorizontalCS.LV95, WellKnownVerticalCS.LHN95);

            IPoint    centerPoint       = GeometryFactory.CreatePoint(150, 150);
            IGeometry geometryToReshape =
                GeometryFactory.CreateCircleArcPolygon(centerPoint, 50, false);

            geometryToReshape.SpatialReference = spatialReference;

            double circleArea = ((IArea)geometryToReshape).Area;

            IGeometry reshapeLine =
                GeometryFactory.CreatePolyline(spatialReference,
                                               GeometryFactory.CreatePoint(175, 100),
                                               GeometryFactory.CreatePoint(175, 200));

            ReshapeInfo reshapeInfo = Reshape(GeometryFactory.Clone(geometryToReshape),
                                              reshapeLine, false);

            CutSubcurve cutReshapePath = reshapeInfo.CutReshapePath;

            Assert.NotNull(cutReshapePath);

            // s = 2* sqrt(r^2-(r-h)^2) = 2 * sqrt(2rh-h^2)
            Assert.AreEqual(86.60, Math.Round(cutReshapePath.Path.Length, 2));

            const double area = 6318.5222074138192;

            ExpectResult(reshapeInfo, RingReshapeSideOfLine.Left, area, 1, 1);

            const bool useNonDefaultSide = true;

            reshapeInfo = Reshape(GeometryFactory.Clone(geometryToReshape),
                                  reshapeLine, useNonDefaultSide);

            double otherSide = circleArea - area;

            ExpectResult(reshapeInfo, RingReshapeSideOfLine.Right, otherSide, 1, 1);
        }
Beispiel #16
0
        private static IPath GetChangedSegments(ReshapeInfo reshapeInfo,
                                                RingReshapeSideOfLine proposedSide)
        {
            IPath replacedSegments;

            if (reshapeInfo.ReplacedSegments == null)
            {
                var   ringToReshape  = (IRing)reshapeInfo.GetGeometryPartToReshape();
                IPath cutReshapePath = Assert.NotNull(reshapeInfo.CutReshapePath).Path;

                replacedSegments = SegmentReplacementUtils.GetSegmentsToReplace(
                    ringToReshape, cutReshapePath.FromPoint, cutReshapePath.ToPoint,
                    proposedSide);
            }
            else
            {
                replacedSegments = reshapeInfo.ReplacedSegments;
            }

            return(replacedSegments);
        }
Beispiel #17
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);
        }
Beispiel #18
0
        public void CanDeterminePolygonReshapeSideInsideAndOutsideOnePartWithCutBack()
        {
            //   _                   _
            //  / \                 / \
            //--\--\-----/--        \  \-----/
            //   \      /      ->    \      /
            //    \____/              \____/

            ISpatialReference spatialReference = SpatialReferenceUtils.CreateSpatialReference(
                WellKnownHorizontalCS.LV95, WellKnownVerticalCS.LHN95);

            IGeometry geometryToReshape =
                GeometryFactory.CreatePolygon(100, 100, 200, 200, spatialReference);

            IGeometry reshapeLine =
                GeometryFactory.CreatePolyline(spatialReference,
                                               GeometryFactory.CreatePoint(125, 200),
                                               GeometryFactory.CreatePoint(125, 150),
                                               GeometryFactory.CreatePoint(175, 150),
                                               GeometryFactory.CreatePoint(175, 250),
                                               GeometryFactory.CreatePoint(150, 250),
                                               GeometryFactory.CreatePoint(150, 200));

            // one quarter plus 50 * 25 = 3750
            ReshapeInfo reshapeInfo = Reshape(GeometryFactory.Clone(geometryToReshape),
                                              reshapeLine, false);

            ExpectResult(reshapeInfo, RingReshapeSideOfLine.Left, 3750, 1, 1);

            const bool useNonDefaultSide = true;

            reshapeInfo = Reshape(GeometryFactory.Clone(geometryToReshape),
                                  reshapeLine, useNonDefaultSide);

            // standard inside-outside, not allowing non-default
            ExpectResult(reshapeInfo, RingReshapeSideOfLine.Left, 3750, 1, 1);
        }
Beispiel #19
0
        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);
        }
Beispiel #20
0
        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));
        }
Beispiel #21
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));
        }
Beispiel #22
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));
        }
Beispiel #23
0
 private static IRing GetInnerRing(ReshapeInfo reshapeInfo)
 {
     return
         (GeometryUtils.GetParts((IGeometryCollection)reshapeInfo.GeometryToReshape).Cast
          <IRing>().FirstOrDefault(ring => !ring.IsExterior));
 }