public override MultiLinestring Clone() { var result = new RingGroup(ExteriorRing.Clone(), InteriorRings.Select(i => i.Clone())) { Id = Id }; return(result); }
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); }
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); }
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); }
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); }
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); }