示例#1
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);
 }
示例#2
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(TopologyValidationErrors.NestedHoles, nestedTester.NestedPoint);        
 }
示例#3
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(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.NumHoles; i++)
            {
                LinearRing hole = (LinearRing)p.GetInteriorRingN(i);
                badNestedPt = CheckShellInsideHole(shell, hole, graph);
                if (badNestedPt == null) return;
            }
            _validErr = new TopologyValidationError(TopologyValidationErrors.NestedShells, badNestedPt);
        }
示例#4
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(TopologyValidationErrors.RingSelfIntersection, ei.Coordinate);
             return;
         }
         nodeSet.Add(ei.Coordinate);
     }
 }
示例#5
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(TopologyValidationErrors.HoleOutsideShell, holePt);
                    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>
 /// 
 /// </summary>
 /// <param name="graph"></param>
 private void CheckTooFewPoints(GeometryGraph graph)
 {
     if (graph.HasTooFewPoints)
     {
         _validErr = new TopologyValidationError(TopologyValidationErrors.TooFewPoints, graph.InvalidPoint);
         return;
     }
 }
示例#8
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="ring"></param>
 private void CheckClosedRing(ILinearRing ring)
 {
     if (!ring.IsClosed)
         _validErr = new TopologyValidationError(TopologyValidationErrors.RingNotClosed, ring.Coordinates[0]);
 }
示例#9
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="coords"></param>
 private void CheckInvalidCoordinates(IEnumerable<Coordinate> coords)
 {
     foreach(Coordinate c in coords)
     {
         if (!IsValidCoordinate(c))
         {
             _validErr = new TopologyValidationError(TopologyValidationErrors.InvalidCoordinate, c);
             return;
         }
     }
 }
示例#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);
            }
           
        }