Beispiel #1
0
        public override MultiLinestring Clone()
        {
            var result = new RingGroup(ExteriorRing.Clone(),
                                       InteriorRings.Select(i => i.Clone()))
            {
                Id = Id
            };

            return(result);
        }
Beispiel #2
0
        public static bool InteriorIntersectXY([NotNull] RingGroup poly1,
                                               [NotNull] RingGroup poly2,
                                               double tolerance)
        {
            bool disjoint;
            bool touchXY = TouchesXY(poly1, poly2, tolerance, out disjoint);

            if (disjoint)
            {
                return(false);
            }

            return(!touchXY);
        }
Beispiel #3
0
        private bool TryCutCookie <T>(Linestring cutRing, T origPolygon, out T updatedOriginal,
                                      out RingGroup innerResult,
                                      bool allowEmptyResults = false) where T : MultiLinestring
        {
            updatedOriginal = null;

            if (TryCutCookie(origPolygon, cutRing, _subcurveNavigator.Tolerance, out innerResult,
                             allowEmptyResults))
            {
                updatedOriginal = origPolygon;
                return(true);
            }

            return(false);
        }
Beispiel #4
0
        private bool TryCutCookie <T>(Linestring cutRing,
                                      IList <T> origPolygons,
                                      out T updatedOriginal,
                                      out RingGroup innerResult) where T : MultiLinestring
        {
            updatedOriginal = null;
            innerResult     = null;

            foreach (T origPolygon in origPolygons.ToList())
            {
                if (TryCutCookie(cutRing, origPolygon, out updatedOriginal, out innerResult))
                {
                    return(true);
                }
            }

            return(false);
        }
Beispiel #5
0
        public static bool TouchesXY([NotNull] RingGroup poly1,
                                     [NotNull] RingGroup poly2,
                                     double tolerance,
                                     out bool disjoint)
        {
            bool exteriorRingsTouch =
                TouchesXY(poly1.ExteriorRing, poly2.ExteriorRing, tolerance, out disjoint);

            if (disjoint || exteriorRingsTouch)
            {
                return(exteriorRingsTouch);
            }

            if (poly1.InteriorRingCount == 0 && poly2.InteriorRingCount == 0)
            {
                return(false);
            }

            // Check if the outer ring touches an inner ring from the inside (assuming proper orientation -> from the outside)
            // and is disjoint from all other inner rings
            if (TouchesXY(poly1.ExteriorRing, poly2.InteriorRings, tolerance, out disjoint))
            {
                return(true);
            }

            if (disjoint)
            {
                return(false);
            }

            if (TouchesXY(poly2.ExteriorRing, poly1.InteriorRings, tolerance, out disjoint))
            {
                return(true);
            }

            return(false);
        }
Beispiel #6
0
        private static bool TryCutCookie <T>([NotNull] T polygon,
                                             [NotNull] Linestring cookieCutter,
                                             double tolerance,
                                             out RingGroup resultCookie,
                                             bool allowEmptyResults = false)
            where T : MultiLinestring
        {
            resultCookie = null;

            if (!GeomRelationUtils.PolycurveContainsXY(
                    polygon, cookieCutter, tolerance))
            {
                return(false);
            }

            // Remove pre-existing interior rings that are completely within cookie cutter
            List <Linestring> containedExistingIslands =
                RemoveContainedExistingIslands(polygon, cookieCutter, tolerance);

            Linestring interiorRing = cookieCutter.Clone();

            Assert.True(interiorRing.IsClosed, "Interior ring is not closed");

            interiorRing.TryOrientAnticlockwise();

            IntersectionPoint3D outerRingIntersection;
            bool ringsAreEqual;
            int  parentRingIdx = GetContainingRingIndex(
                polygon, interiorRing, tolerance, out ringsAreEqual, out outerRingIntersection);

            Assert.False(parentRingIdx < 0, "No parent ring found");

            Linestring containingRing = polygon.GetLinestring(parentRingIdx);

            if (containingRing.ClockwiseOriented == false)
            {
                // The cutter is completely within an existing island -> ignore (keep existing ring)
                return(false);
            }

            if (ringsAreEqual)
            {
                // The cutter is equal to the found ring. Positive rings cancel each other out:
                if (!allowEmptyResults)
                {
                    return(false);
                }

                polygon.RemoveLinestring(containingRing);
            }
            else if (outerRingIntersection == null)
            {
                // The cutter is completely within an existing outer ring -> add as island
                polygon.AddLinestring(interiorRing);
            }
            else
            {
                // create boundary loop:
                polygon.RemoveLinestring(containingRing);

                Linestring withBoundaryLoop = CreateWithBoundaryLoop(containingRing, interiorRing,
                                                                     outerRingIntersection,
                                                                     tolerance);

                polygon.InsertLinestring(parentRingIdx, withBoundaryLoop);
            }

            resultCookie = RingGroup.CreateProperlyOriented(cookieCutter.Clone());

            foreach (Linestring unusedCutRing in containedExistingIslands)
            {
                RingGroup cookieInCookie;
                Assert.True(TryCutCookie(resultCookie, unusedCutRing, tolerance,
                                         out cookieInCookie),
                            "Inner ring in cookie cutter cannot be cut from result cookie");
            }

            return(true);
        }