예제 #1
0
        /// <summary>
        /// Tests that each hole is inside the polygon shell.
        /// This routine assumes that the holes have previously been tested
        /// to ensure that all vertices lie on the shell or inside it.
        /// A simple test of a single point in the hole can be used,
        /// provide the point is chosen such that it does not lie on the
        /// boundary of the shell.
        /// </summary>
        /// <param name="p">The polygon to be tested for hole inclusion.</param>
        /// <param name="graph">A GeometryGraph incorporating the polygon.</param>
        private void CheckHolesInShell(IPolygon p, GeometryGraph graph)
        {
            ILinearRing shell = p.Shell;

            IPointInRing pir = new McPointInRing(shell);

            for (int i = 0; i < p.NumHoles; i++)
            {
                LinearRing hole   = (LinearRing)p.GetInteriorRingN(i);
                Coordinate holePt = FindPointNotNode(hole.Coordinates, shell, graph);

                /*
                 * If no non-node hole vertex can be found, the hole must
                 * split the polygon into disconnected interiors.
                 * This will be caught by a subsequent check.
                 */
                if (holePt == null)
                {
                    return;
                }

                bool outside = !pir.IsInside(holePt);
                if (outside)
                {
                    _validErr = new TopologyValidationError(TopologyValidationErrorType.HoleOutsideShell, holePt);
                    return;
                }
            }
        }
예제 #2
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="ring"></param>
 private void CheckClosedRing(ILinearRing ring)
 {
     if (!ring.IsClosed)
     {
         _validErr = new TopologyValidationError(TopologyValidationErrorType.RingNotClosed, ring.Coordinates[0]);
     }
 }
예제 #3
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="graph"></param>
 private void CheckTooFewPoints(GeometryGraph graph)
 {
     if (graph.HasTooFewPoints)
     {
         _validErr = new TopologyValidationError(TopologyValidationErrorType.TooFewPoints, graph.InvalidPoint);
         return;
     }
 }
예제 #4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="graph"></param>
        private void CheckConnectedInteriors(GeometryGraph graph)
        {
            ConnectedInteriorTester cit = new ConnectedInteriorTester(graph);

            if (!cit.IsInteriorsConnected())
            {
                _validErr = new TopologyValidationError(TopologyValidationErrorType.DisconnectedInteriors, cit.Coordinate);
            }
        }
예제 #5
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="coords"></param>
 private void CheckInvalidCoordinates(IEnumerable <Coordinate> coords)
 {
     foreach (Coordinate c in coords)
     {
         if (!IsValidCoordinate(c))
         {
             _validErr = new TopologyValidationError(TopologyValidationErrorType.InvalidCoordinate, c);
             return;
         }
     }
 }
예제 #6
0
        /// <summary>
        /// Tests that no hole is nested inside another hole.
        /// This routine assumes that the holes are disjoint.
        /// To ensure this, holes have previously been tested
        /// to ensure that:
        /// They do not partially overlap
        /// (checked by <c>checkRelateConsistency</c>).
        /// They are not identical
        /// (checked by <c>checkRelateConsistency</c>).
        /// </summary>
        private void CheckHolesNotNested(IPolygon p, GeometryGraph graph)
        {
            QuadtreeNestedRingTester nestedTester = new QuadtreeNestedRingTester(graph);

            foreach (LinearRing innerHole in p.Holes)
            {
                nestedTester.Add(innerHole);
            }
            bool isNonNested = nestedTester.IsNonNested();

            if (!isNonNested)
            {
                _validErr = new TopologyValidationError(TopologyValidationErrorType.NestedHoles, nestedTester.NestedPoint);
            }
        }
예제 #7
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="graph"></param>
        private void CheckConsistentArea(GeometryGraph graph)
        {
            ConsistentAreaTester cat = new ConsistentAreaTester(graph);
            bool isValidArea         = cat.IsNodeConsistentArea;

            if (!isValidArea)
            {
                _validErr = new TopologyValidationError(TopologyValidationErrorType.SelfIntersection, cat.InvalidPoint);
                return;
            }
            if (cat.HasDuplicateRings)
            {
                _validErr = new TopologyValidationError(TopologyValidationErrorType.DuplicateRings, cat.InvalidPoint);
                return;
            }
        }
예제 #8
0
        /// <summary>
        /// Check if a shell is incorrectly nested within a polygon.  This is the case
        /// if the shell is inside the polygon shell, but not inside a polygon hole.
        /// (If the shell is inside a polygon hole, the nesting is valid.)
        /// The algorithm used relies on the fact that the rings must be properly contained.
        /// E.g. they cannot partially overlap (this has been previously checked by
        /// <c>CheckRelateConsistency</c>).
        /// </summary>
        private void CheckShellNotNested(LinearRing shell, Polygon p, GeometryGraph graph)
        {
            IList <Coordinate> shellPts = shell.Coordinates;
            // test if shell is inside polygon shell
            LinearRing         polyShell = (LinearRing)p.ExteriorRing;
            IList <Coordinate> polyPts   = polyShell.Coordinates;
            Coordinate         shellPt   = FindPointNotNode(shellPts, polyShell, graph);

            // if no point could be found, we can assume that the shell is outside the polygon
            if (shellPt == null)
            {
                return;
            }
            bool insidePolyShell = CgAlgorithms.IsPointInRing(shellPt, polyPts);

            if (!insidePolyShell)
            {
                return;
            }
            // if no holes, this is an error!
            if (p.NumHoles <= 0)
            {
                _validErr = new TopologyValidationError(TopologyValidationErrorType.NestedShells, shellPt);
                return;
            }

            /*
             * Check if the shell is inside one of the holes.
             * This is the case if one of the calls to checkShellInsideHole
             * returns a null coordinate.
             * Otherwise, the shell is not properly contained in a hole, which is an error.
             */
            Coordinate badNestedPt = null;

            for (int i = 0; i < p.NumHoles; i++)
            {
                LinearRing hole = (LinearRing)p.GetInteriorRingN(i);
                badNestedPt = CheckShellInsideHole(shell, hole, graph);
                if (badNestedPt == null)
                {
                    return;
                }
            }
            _validErr = new TopologyValidationError(TopologyValidationErrorType.NestedShells, badNestedPt);
        }
예제 #9
0
        /// <summary>
        /// Check that a ring does not self-intersect, except at its endpoints.
        /// Algorithm is to count the number of times each node along edge occurs.
        /// If any occur more than once, that must be a self-intersection.
        /// </summary>
        private void CheckNoSelfIntersectingRing(EdgeIntersectionList eiList)
        {
            var  nodeSet = new HashSet <Coordinate>();
            bool isFirst = true;

            foreach (EdgeIntersection ei in eiList)
            {
                if (isFirst)
                {
                    isFirst = false;
                    continue;
                }
                if (nodeSet.Contains(ei.Coordinate))
                {
                    _validErr = new TopologyValidationError(TopologyValidationErrorType.RingSelfIntersection, ei.Coordinate);
                    return;
                }
                nodeSet.Add(ei.Coordinate);
            }
        }
예제 #10
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="g"></param>
        private void CheckValid(IGeometry g)
        {
            _validErr = null;

            if (g.IsEmpty)
            {
                return;
            }
            CheckValidCoordinates(g);
            if (g is ILineString)
            {
                CheckValidLineString(g);
            }
            ILinearRing r = g as ILinearRing;

            if (r != null)
            {
                CheckValidRing(r);
            }
            IPolygon p = g as IPolygon;

            if (p != null)
            {
                CheckValidPolygon(p);
            }
            IMultiPolygon mp = g as IMultiPolygon;

            if (mp != null)
            {
                CheckValidMultipolygon(mp);
            }
            else
            {
                IGeometryCollection gc = g as IGeometryCollection;
                if (gc != null)
                {
                    CheckValidCollection(gc);
                }
            }
        }
예제 #11
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="g"></param>
        private void CheckValid(IGeometry g)
        {
            _validErr = null;

            if (g.IsEmpty) return;
            CheckValidCoordinates(g);
            if (g is ILineString)
                CheckValidLineString(g);
            ILinearRing r = g as ILinearRing;
            if (r != null) CheckValidRing(r);
            IPolygon p = g as IPolygon;
            if (p != null) CheckValidPolygon(p);
            IMultiPolygon mp = g as IMultiPolygon;
            if (mp != null) CheckValidMultipolygon(mp);
            else
            {
                IGeometryCollection gc = g as IGeometryCollection;
                if (gc != null) CheckValidCollection(gc);
            }
        }
예제 #12
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="graph"></param>
 private void CheckTooFewPoints(GeometryGraph graph)
 {
     if (graph.HasTooFewPoints)
     {
         _validErr = new TopologyValidationError(TopologyValidationErrorType.TooFewPoints, graph.InvalidPoint);
         return;
     }
 }
예제 #13
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="ring"></param>
 private void CheckClosedRing(ILinearRing ring)
 {
     if (!ring.IsClosed)
         _validErr = new TopologyValidationError(TopologyValidationErrorType.RingNotClosed, ring.Coordinates[0]);
 }
예제 #14
0
 /// <summary>
 /// Check that a ring does not self-intersect, except at its endpoints.
 /// Algorithm is to count the number of times each node along edge occurs.
 /// If any occur more than once, that must be a self-intersection.
 /// </summary>
 private void CheckNoSelfIntersectingRing(EdgeIntersectionList eiList)
 {
     ISet nodeSet = new ListSet();
     bool isFirst = true;
     foreach (EdgeIntersection ei in eiList)
     {
         if (isFirst)
         {
             isFirst = false;
             continue;
         }
         if (nodeSet.Contains(ei.Coordinate))
         {
             _validErr = new TopologyValidationError(TopologyValidationErrorType.RingSelfIntersection, ei.Coordinate);
             return;
         }
         nodeSet.Add(ei.Coordinate);
     }
 }
예제 #15
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="graph"></param>
 private void CheckConsistentArea(GeometryGraph graph)
 {
     ConsistentAreaTester cat = new ConsistentAreaTester(graph);
     bool isValidArea = cat.IsNodeConsistentArea;
     if (!isValidArea)
     {
         _validErr = new TopologyValidationError(TopologyValidationErrorType.SelfIntersection, cat.InvalidPoint);
         return;
     }
     if (cat.HasDuplicateRings)
     {
         _validErr = new TopologyValidationError(TopologyValidationErrorType.DuplicateRings, cat.InvalidPoint);
         return;
     }
 }
예제 #16
0
        /// <summary>
        /// Tests that each hole is inside the polygon shell.
        /// This routine assumes that the holes have previously been tested
        /// to ensure that all vertices lie on the shell or inside it.
        /// A simple test of a single point in the hole can be used,
        /// provide the point is chosen such that it does not lie on the
        /// boundary of the shell.
        /// </summary>
        /// <param name="p">The polygon to be tested for hole inclusion.</param>
        /// <param name="graph">A GeometryGraph incorporating the polygon.</param>
        private void CheckHolesInShell(IPolygon p, GeometryGraph graph)
        {
            ILinearRing shell = p.Shell;

            IPointInRing pir = new McPointInRing(shell);
            for (int i = 0; i < p.NumHoles; i++)
            {
                LinearRing hole = (LinearRing)p.GetInteriorRingN(i);
                Coordinate holePt = FindPointNotNode(hole.Coordinates, shell, graph);

                /*
                 * If no non-node hole vertex can be found, the hole must
                 * split the polygon into disconnected interiors.
                 * This will be caught by a subsequent check.
                 */
                if (holePt == null)
                    return;

                bool outside = !pir.IsInside(holePt);
                if (outside)
                {
                    _validErr = new TopologyValidationError(TopologyValidationErrorType.HoleOutsideShell, holePt);
                    return;
                }
            }
        }
예제 #17
0
 /// <summary>
 /// Tests that no hole is nested inside another hole.
 /// This routine assumes that the holes are disjoint.
 /// To ensure this, holes have previously been tested
 /// to ensure that:
 /// They do not partially overlap
 /// (checked by <c>checkRelateConsistency</c>).
 /// They are not identical
 /// (checked by <c>checkRelateConsistency</c>).
 /// </summary>
 private void CheckHolesNotNested(IPolygon p, GeometryGraph graph)
 {
     QuadtreeNestedRingTester nestedTester = new QuadtreeNestedRingTester(graph);
     foreach (LinearRing innerHole in p.Holes)
         nestedTester.Add(innerHole);
     bool isNonNested = nestedTester.IsNonNested();
     if (!isNonNested)
         _validErr = new TopologyValidationError(TopologyValidationErrorType.NestedHoles, nestedTester.NestedPoint);
 }
예제 #18
0
        /// <summary>
        /// Check if a shell is incorrectly nested within a polygon.  This is the case
        /// if the shell is inside the polygon shell, but not inside a polygon hole.
        /// (If the shell is inside a polygon hole, the nesting is valid.)
        /// The algorithm used relies on the fact that the rings must be properly contained.
        /// E.g. they cannot partially overlap (this has been previously checked by
        /// <c>CheckRelateConsistency</c>).
        /// </summary>
        private void CheckShellNotNested(LinearRing shell, Polygon p, GeometryGraph graph)
        {
            IList<Coordinate> shellPts = shell.Coordinates;
            // test if shell is inside polygon shell
            LinearRing polyShell = (LinearRing)p.ExteriorRing;
            IList<Coordinate> polyPts = polyShell.Coordinates;
            Coordinate shellPt = FindPointNotNode(shellPts, polyShell, graph);
            // if no point could be found, we can assume that the shell is outside the polygon
            if (shellPt == null) return;
            bool insidePolyShell = CgAlgorithms.IsPointInRing(shellPt, polyPts);
            if (!insidePolyShell) return;
            // if no holes, this is an error!
            if (p.NumHoles <= 0)
            {
                _validErr = new TopologyValidationError(TopologyValidationErrorType.NestedShells, shellPt);
                return;
            }

            /*
             * Check if the shell is inside one of the holes.
             * This is the case if one of the calls to checkShellInsideHole
             * returns a null coordinate.
             * Otherwise, the shell is not properly contained in a hole, which is an error.
             */
            Coordinate badNestedPt = null;
            for (int i = 0; i < p.NumHoles; i++)
            {
                LinearRing hole = (LinearRing)p.GetInteriorRingN(i);
                badNestedPt = CheckShellInsideHole(shell, hole, graph);
                if (badNestedPt == null) return;
            }
            _validErr = new TopologyValidationError(TopologyValidationErrorType.NestedShells, badNestedPt);
        }
예제 #19
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="graph"></param>
 private void CheckConnectedInteriors(GeometryGraph graph)
 {
     ConnectedInteriorTester cit = new ConnectedInteriorTester(graph);
     if (!cit.IsInteriorsConnected())
         _validErr = new TopologyValidationError(TopologyValidationErrorType.DisconnectedInteriors, cit.Coordinate);
 }
예제 #20
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="coords"></param>
 private void CheckInvalidCoordinates(IEnumerable<Coordinate> coords)
 {
     foreach (Coordinate c in coords)
     {
         if (!IsValidCoordinate(c))
         {
             _validErr = new TopologyValidationError(TopologyValidationErrorType.InvalidCoordinate, c);
             return;
         }
     }
 }