示例#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.NumInteriorRings; i++)
            {
                ILinearRing hole   = p.Holes[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(TopologyValidationErrors.HoleOutsideShell, holePt);
                    return;
                }
            }
        }
示例#2
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="ring"></param>
 private void CheckClosedRing(ILinearRing ring)
 {
     if (!ring.IsClosed)
     {
         validErr = new TopologyValidationError(TopologyValidationErrors.RingNotClosed,
                                                ring.GetCoordinateN(0));
     }
 }
示例#3
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="graph"></param>
 private void CheckTooFewPoints(GeometryGraph graph)
 {
     if (graph.HasTooFewPoints)
     {
         validErr = new TopologyValidationError(TopologyValidationErrors.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(TopologyValidationErrors.DisconnectedInteriors,
                                                       cit.Coordinate);
            }
        }
示例#5
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="coords"></param>
 private void CheckInvalidCoordinates(Coordinate[] coords)
 {
     foreach (Coordinate c in coords)
     {
         if (!IsValidCoordinate(c))
         {
             validErr = new TopologyValidationError(TopologyValidationErrors.InvalidCoordinate, c);
             return;
         }
     }
 }
示例#6
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(TopologyValidationErrors.SelfIntersection, cat.InvalidPoint);
                return;
            }
            if (cat.HasDuplicateRings)
            {
                validErr = new TopologyValidationError(TopologyValidationErrors.DuplicateRings, cat.InvalidPoint);
                return;
            }
        }
示例#7
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)
        {
            var nestedTester = new IndexedNestedRingTester(graph);

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

            if (!isNonNested)
            {
                validErr = new TopologyValidationError(TopologyValidationErrors.NestedHoles,
                                                       nestedTester.NestedPoint);
            }
        }
示例#8
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="g"></param>
        private void CheckValid(IGeometry g)
        {
            if (isChecked)
            {
                return;
            }

            validErr = null;

            if (g.IsEmpty)
            {
                return;
            }

            if (g is IPoint)
            {
                CheckValid((IPoint)g);
            }
            else if (g is IMultiPoint)
            {
                CheckValid((IMultiPoint)g);
            }
            else if (g is ILinearRing) // LineString also handles LinearRings
            {
                CheckValid((ILinearRing)g);
            }
            else if (g is ILineString)
            {
                CheckValid((ILineString)g);
            }
            else if (g is IPolygon)
            {
                CheckValid((IPolygon)g);
            }
            else if (g is IMultiPolygon)
            {
                CheckValid((IMultiPolygon)g);
            }
            else if (g is IGeometryCollection)
            {
                CheckValid((IGeometryCollection)g);
            }
            else
            {
                throw new NotSupportedException(g.GetType().FullName);
            }
        }
示例#9
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(ILinearRing shell, IPolygon p, GeometryGraph graph)
        {
            Coordinate[] shellPts = shell.Coordinates;
            // test if shell is inside polygon shell
            ILinearRing polyShell = p.Shell;

            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.NumInteriorRings <= 0)
            {
                validErr = new TopologyValidationError(TopologyValidationErrors.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.NumInteriorRings; i++)
            {
                ILinearRing hole = p.Holes[i];
                badNestedPt = CheckShellInsideHole(shell, hole, graph);
                if (badNestedPt == null)
                {
                    return;
                }
            }
            validErr = new TopologyValidationError(TopologyValidationErrors.NestedShells, badNestedPt);
        }
示例#10
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)
        {
            Set <Coordinate> nodeSet = new Set <Coordinate>();
            bool             isFirst = true;

            foreach (EdgeIntersection ei in eiList)
            {
                if (isFirst)
                {
                    isFirst = false;
                    continue;
                }
                if (nodeSet.Contains(ei.Coordinate))
                {
                    validErr = new TopologyValidationError(TopologyValidationErrors.RingSelfIntersection, ei.Coordinate);
                    return;
                }
                else
                {
                    nodeSet.Add(ei.Coordinate);
                }
            }
        }
示例#11
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="g"></param>
        private void CheckValid(IGeometry g)
        {
            if(isChecked) 
                return;
            
            validErr = null;

            if (g.IsEmpty) return;            
            
            if (g is IPoint) 
                CheckValid((IPoint) g);            
            else if (g is IMultiPoint) 
                CheckValid((IMultiPoint) g);
            else if (g is ILinearRing) // LineString also handles LinearRings
                CheckValid((ILinearRing) g);
            else if (g is ILineString) 
                CheckValid((ILineString) g);
            else if (g is IPolygon) 
                CheckValid((IPolygon) g);
            else if (g is IMultiPolygon) 
                CheckValid((IMultiPolygon) g);
            else if (g is IGeometryCollection)
                CheckValid((IGeometryCollection) g);
            else throw new NotSupportedException(g.GetType().FullName);
        }
示例#12
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="ring"></param>
 private void CheckClosedRing(ILinearRing ring)
 {
     if (!ring.IsClosed)
         validErr = new TopologyValidationError(TopologyValidationErrors.RingNotClosed, 
             ring.GetCoordinateN(0));
 }
示例#13
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="graph"></param>
 private void CheckTooFewPoints(GeometryGraph graph)
 {
     if (graph.HasTooFewPoints)
     {
         validErr = new TopologyValidationError(TopologyValidationErrors.TooFewPoints,
             graph.InvalidPoint);
         return;
     }
 }
示例#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)
 {
     Set<Coordinate> nodeSet = new Set<Coordinate>();    
     bool isFirst = true;
     foreach(EdgeIntersection ei in eiList)
     {                
         if (isFirst)
         {
             isFirst = false;
             continue;
         }
         if (nodeSet.Contains(ei.Coordinate))
         {
             validErr = new TopologyValidationError(TopologyValidationErrors.RingSelfIntersection, ei.Coordinate);
             return;
         }
         else 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(TopologyValidationErrors.SelfIntersection, cat.InvalidPoint);
         return;
     }
     if (cat.HasDuplicateRings)
     {
         validErr = new TopologyValidationError(TopologyValidationErrors.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.NumInteriorRings; i++)
            {
                ILinearRing hole = p.Holes[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(TopologyValidationErrors.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)
 {
     var nestedTester = new IndexedNestedRingTester(graph);
     foreach (ILinearRing innerHole in p.Holes)
         nestedTester.Add(innerHole);
     bool isNonNested = nestedTester.IsNonNested();
     if (!isNonNested)
         validErr = new TopologyValidationError(TopologyValidationErrors.NestedHoles, 
             nestedTester.NestedPoint);        
 }
示例#18
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="coords"></param>
 private void CheckInvalidCoordinates(Coordinate[] coords)
 {
     foreach (Coordinate c in coords)
     {
         if (!IsValidCoordinate(c))
         {
             validErr = new TopologyValidationError(TopologyValidationErrors.InvalidCoordinate, c);
             return;
         }
     }
 }
示例#19
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="graph"></param>
 private void CheckConnectedInteriors(GeometryGraph graph)
 {
     ConnectedInteriorTester cit = new ConnectedInteriorTester(graph);
     if (!cit.IsInteriorsConnected())
         validErr = new TopologyValidationError(TopologyValidationErrors.DisconnectedInteriors,
             cit.Coordinate);
 }
示例#20
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(ILinearRing shell, IPolygon p, GeometryGraph graph)
        {
            Coordinate[] shellPts = shell.Coordinates;
            // test if shell is inside polygon shell
            ILinearRing polyShell = p.Shell;
            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.NumInteriorRings <= 0)
            {
                validErr = new TopologyValidationError(TopologyValidationErrors.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.NumInteriorRings; i++)
            {
                ILinearRing hole = p.Holes[i];
                badNestedPt = CheckShellInsideHole(shell, hole, graph);
                if (badNestedPt == null) return;
            }
            validErr = new TopologyValidationError(TopologyValidationErrors.NestedShells, badNestedPt);
        }