using System.Collections; using GeoAPI.Geometries; using GisSharpBlog.NetTopologySuite.Algorithm; using GisSharpBlog.NetTopologySuite.Geometries; using GisSharpBlog.NetTopologySuite.GeometriesGraph; using GisSharpBlog.NetTopologySuite.Index.Quadtree; using GisSharpBlog.NetTopologySuite.Utilities; namespace GisSharpBlog.NetTopologySuite.Operation.Valid { /// /// Tests whether any of a set of LinearRings are /// nested inside another ring in the set, using a Quadtree /// index to speed up the comparisons. /// public class QuadtreeNestedRingTester { private GeometryGraph graph; // used to find non-node vertices private IList rings = new ArrayList(); private IEnvelope totalEnv = new Envelope(); private Quadtree quadtree; private ICoordinate nestedPt; /// /// /// /// public QuadtreeNestedRingTester(GeometryGraph graph) { this.graph = graph; } /// /// /// public ICoordinate NestedPoint { get { return nestedPt; } } /// /// /// /// public void Add(ILinearRing ring) { rings.Add(ring); totalEnv.ExpandToInclude(ring.EnvelopeInternal); } /// /// /// /// public bool IsNonNested() { BuildQuadtree(); for (int i = 0; i < rings.Count; i++) { ILinearRing innerRing = (ILinearRing) rings[i]; ICoordinate[] innerRingPts = innerRing.Coordinates; IList results = quadtree.Query(innerRing.EnvelopeInternal); for (int j = 0; j < results.Count; j++) { ILinearRing searchRing = (ILinearRing) results[j]; ICoordinate[] searchRingPts = searchRing.Coordinates; if (innerRing == searchRing) continue; if (!innerRing.EnvelopeInternal.Intersects(searchRing.EnvelopeInternal)) continue; ICoordinate innerRingPt = IsValidOp.FindPointNotNode(innerRingPts, searchRing, graph); Assert.IsTrue(innerRingPt != null, "Unable to find a ring point not a node of the search ring"); bool isInside = CGAlgorithms.IsPointInRing(innerRingPt, searchRingPts); if (isInside) { nestedPt = innerRingPt; return false; } } } return true; } /// /// /// private void BuildQuadtree() { quadtree = new Quadtree(); for (int i = 0; i < rings.Count; i++) { ILinearRing ring = (ILinearRing) rings[i]; Envelope env = (Envelope) ring.EnvelopeInternal; quadtree.Insert(env, ring); } } } }