예제 #1
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>
        /// <param name="eiList"></param>
        private void CheckSelfIntersectingRing(EdgeIntersectionList eiList)
        {
            //Set nodeSet = new TreeSet(); awc  don't need sorted list, just a hashtable
            Hashtable nodeSet = new Hashtable();
            bool      isFirst = true;

            //for (Iterator i = eiList.iterator(); i.hasNext(); )
            foreach (EdgeIntersection ei in eiList)
            {
                //EdgeIntersection ei = (EdgeIntersection) i.next();
                if (isFirst)
                {
                    isFirst = false;
                    continue;
                }
                if (nodeSet.Contains(ei.Coordinate))
                {
                    _validErr = new TopologyValidationError(
                        TopologyValidationError.RingSelfIntersection,
                        ei.Coordinate);
                    return;
                }
                else
                {
                    //TODO: awc - should probably use hashcode
                    nodeSet.Add(ei.Coordinate, ei.Coordinate);
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Test 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">Graph a GeometryGraph incorporating the polygon.</param>
        private void CheckHolesInShell(Polygon p, GeometryGraph graph)
        {
            LinearRing  shell    = (LinearRing)p.GetExteriorRing();
            Coordinates shellPts = shell.GetCoordinates();

            //PointInRing pir = new SimplePointInRing(shell);
            //PointInRing pir = new SIRtreePointInRing(shell);
            IPointInRing pir = new MCPointInRing(shell);

            for (int i = 0; i < p.GetNumInteriorRing(); i++)
            {
                LinearRing hole   = (LinearRing)p.GetInteriorRingN(i);
                Coordinate holePt = FindPtNotNode(hole.GetCoordinates(), shell, graph);
                if (holePt == null)
                {
                    throw new InvalidOperationException("Unable to find a hole point not a vertex of the shell.");
                }

                bool outside = !pir.IsInside(holePt);
                if (outside)
                {
                    _validErr = new TopologyValidationError(
                        TopologyValidationError.HoleOutsideShell,
                        holePt);
                    return;
                }
            }
        }
예제 #3
0
        /// <summary>
        /// This routine Checks to see if a shell is properly contained in a hole.
        /// </summary>
        /// <param name="shell"></param>
        /// <param name="hole"></param>
        /// <param name="graph"></param>
        private void CheckShellInsideHole(LinearRing shell, LinearRing hole, GeometryGraph graph)
        {
            Coordinates shellPts = shell.GetCoordinates();
            Coordinates holePts  = hole.GetCoordinates();
            // TODO: improve performance of this - by sorting pointlists for instance?
            Coordinate shellPt = FindPtNotNode(shellPts, hole, graph);

            // if point is on shell but not hole, Check that the shell is inside the hole
            if (shellPt != null)
            {
                bool insideHole = _cga.IsPointInRing(shellPt, holePts);
                if (!insideHole)
                {
                    _validErr = new TopologyValidationError(
                        TopologyValidationError.NestedShells,
                        shellPt);
                }
                return;
            }
            Coordinate holePt = FindPtNotNode(holePts, shell, graph);

            // if point is on hole but not shell, Check that the hole is outside the shell
            if (holePt != null)
            {
                bool insideShell = _cga.IsPointInRing(holePt, shellPts);
                if (insideShell)
                {
                    _validErr = new TopologyValidationError(
                        TopologyValidationError.NestedShells,
                        holePt);
                }
                return;
            }
            throw new InvalidOperationException("Points in shell and hole appear to be equal.");
        }
예제 #4
0
 private void CheckTooFewPoints(GeometryGraph graph)
 {
     if (graph.HasTooFewPoints())
     {
         _validErr = new TopologyValidationError(
             TopologyValidationError.TooFewPoints,
             graph.GetInvalidPoint());
         return;
     }
 }
예제 #5
0
        private void CheckConnectedInteriors(GeometryGraph graph)
        {
            ConnectedInteriorTester cit = new ConnectedInteriorTester(graph);

            if (!cit.IsInteriorsConnected())
            {
                _validErr = new TopologyValidationError(
                    TopologyValidationError.DisconnectedInterior,
                    cit.GetCoordinate());
            }
        }
예제 #6
0
        private void CheckConsistentArea(GeometryGraph graph)
        {
            ConsistentAreaTester cat = new ConsistentAreaTester(graph);

            bool isValidArea = cat.IsNodeConsistentArea();

            if (!isValidArea)
            {
                _validErr = new TopologyValidationError(
                    TopologyValidationError.SelfIntersection,
                    cat.GetInvalidPoint());
                return;
            }
            if (cat.HasDuplicateRings())
            {
                _validErr = new TopologyValidationError(
                    TopologyValidationError.DuplicateRings,
                    cat.GetInvalidPoint());
            }
        }
예제 #7
0
 private void CheckValid(Geometry g)
 {
     if (_isChecked)
     {
         return;
     }
     _validErr = null;
     if (g.IsEmpty())
     {
         return;
     }
     if (g is Point)
     {
         return;
     }
     else if (g is MultiPoint)
     {
         return;
     }
     // LineString also handles LinearRings
     else if (g is LineString)
     {
         CheckValid((LineString)g);
     }
     else if (g is Polygon)
     {
         CheckValid((Polygon)g);
     }
     else if (g is MultiPolygon)
     {
         CheckValid((MultiPolygon)g);
     }
     else if (g is GeometryCollection)
     {
         CheckValid((GeometryCollection)g);
     }
     else
     {
         throw new NotSupportedException(g.GetType().Name);
     }
 }
예제 #8
0
        /// <summary>
        /// Tests that no hole is nested inside another hole.
        /// </summary>
        /// <remarks>
        /// This routine assumes that the holes are disjoint.
        /// To ensure this, holes have previously been tested
        /// to ensure that:
        /// <ul>
        /// <li>they do not partially overlap
        /// (Checked by CheckRelateConsistency)</li>
        /// <li>they are not identical
        /// (Checked by CheckRelateConsistency)</li>
        /// <li>they do not touch at a vertex
        /// (Checked by ????)</li>
        /// </ul>
        /// </remarks>
        /// <param name="p"></param>
        /// <param name="graph"></param>
        private void CheckHolesNotNested(Polygon p, GeometryGraph graph)
        {
            QuadtreeNestedRingTester nestedTester = new QuadtreeNestedRingTester(graph);

            //SimpleNestedRingTester nestedTester = new SimpleNestedRingTester(_arg[0]);
            //SweeplineNestedRingTester nestedTester = new SweeplineNestedRingTester(_arg[0]);

            for (int i = 0; i < p.GetNumInteriorRing(); i++)
            {
                LinearRing innerHole = p.GetInteriorRingN(i);
                nestedTester.Add(innerHole);
            }
            bool isNonNested = nestedTester.IsNonNested();

            if (!isNonNested)
            {
                _validErr = new TopologyValidationError(
                    TopologyValidationError.NestedHoles,
                    nestedTester.GetNestedPoint());
            }
        }
예제 #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
        /// CheckRelateConsistency
        /// </summary>
        /// <param name="shell"></param>
        /// <param name="p"></param>
        /// <param name="graph"></param>
        private void CheckShellNotNested(LinearRing shell, Polygon p, GeometryGraph graph)
        {
            Coordinates shellPts = shell.GetCoordinates();
            // test if shell is inside polygon shell
            LinearRing  polyShell = (LinearRing)p.GetExteriorRing();
            Coordinates polyPts   = polyShell.GetCoordinates();
            Coordinate  shellPt   = FindPtNotNode(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 = _cga.IsPointInRing(shellPt, polyPts);

            if (!insidePolyShell)
            {
                return;
            }

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

            for (int i = 0; i < p.GetNumInteriorRing(); i++)
            {
                LinearRing hole = p.GetInteriorRingN(i);
                CheckShellInsideHole(shell, hole, graph);
                if (_validErr != null)
                {
                    return;
                }
            }
        }
예제 #10
0
		private void CheckValid(Geometry g)
		{
			
			if (_isChecked)
			{
				return;
			}
			_validErr = null;
			if ( g.IsEmpty() )
			{
					return;
			}
			if (g is Point)   
			{
				return;
			}
			else if (g is MultiPoint)
			{
				return;
			}
				// LineString also handles LinearRings
			else if (g is LineString) 
			{
				CheckValid( (LineString) g);
			}
			else if (g is Polygon)    
			{
				CheckValid( (Polygon) g);
			}
			else if (g is MultiPolygon) 
			{
				CheckValid( (MultiPolygon) g);
			}
			else if (g is GeometryCollection)
			{
				CheckValid( (GeometryCollection) g);
			}
			else  throw new NotSupportedException(g.GetType().Name);

		}
예제 #11
0
		private void CheckConsistentArea(GeometryGraph graph)
		{
			
			ConsistentAreaTester cat = new ConsistentAreaTester(graph);
			
			bool isValidArea = cat.IsNodeConsistentArea();
			if (! isValidArea) 
			{
				_validErr = new TopologyValidationError(
					TopologyValidationError.SelfIntersection,
					cat.GetInvalidPoint());
				return;
			}
			if (cat.HasDuplicateRings()) 
			{
				_validErr = new TopologyValidationError(
					TopologyValidationError.DuplicateRings,
					cat.GetInvalidPoint());
			}
		}
예제 #12
0
		/// <summary>
		/// Test 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">Graph a GeometryGraph incorporating the polygon.</param>
		private void CheckHolesInShell(Polygon p, GeometryGraph graph)
		{
			LinearRing shell = (LinearRing) p.GetExteriorRing();
			Coordinates shellPts = shell.GetCoordinates();

			//PointInRing pir = new SimplePointInRing(shell);
			//PointInRing pir = new SIRtreePointInRing(shell);
			IPointInRing pir = new MCPointInRing(shell);

			for (int i = 0; i < p.GetNumInteriorRing(); i++) 
			{

				LinearRing hole = (LinearRing) p.GetInteriorRingN(i);
				Coordinate holePt = FindPtNotNode(hole.GetCoordinates(), shell, graph);
				if (holePt == null)
				{
					throw new InvalidOperationException("Unable to find a hole point not a vertex of the shell.");
				}

				bool outside = ! pir.IsInside(holePt);
				if ( outside ) 
				{
					_validErr = new TopologyValidationError(
						TopologyValidationError.HoleOutsideShell,
						holePt);
					return;
				}
			}
		}
예제 #13
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>
		/// <param name="eiList"></param>
		private void CheckSelfIntersectingRing(EdgeIntersectionList eiList)
		{
			
			//Set nodeSet = new TreeSet(); awc  don't need sorted list, just a hashtable
			Hashtable nodeSet = new Hashtable();
			bool isFirst = true;
			//for (Iterator i = eiList.iterator(); i.hasNext(); ) 
			foreach(EdgeIntersection ei in eiList)
			{
				//EdgeIntersection ei = (EdgeIntersection) i.next();
				if (isFirst) 
				{
					isFirst = false;
					continue;
				}
				if (nodeSet.Contains(ei.Coordinate)) 
				{
					_validErr = new TopologyValidationError(
						TopologyValidationError.RingSelfIntersection,
						ei.Coordinate);
					return;
				}
				else 
				{
					//TODO: awc - should probably use hashcode
					nodeSet.Add(ei.Coordinate, ei.Coordinate);
				}
			}
		}
예제 #14
0
		/// <summary>
		/// Tests that no hole is nested inside another hole.
		/// </summary>
		/// <remarks>
		/// This routine assumes that the holes are disjoint.
		/// To ensure this, holes have previously been tested
		/// to ensure that:
		/// <ul>
		/// <li>they do not partially overlap
		/// (Checked by CheckRelateConsistency)</li>
		/// <li>they are not identical
		/// (Checked by CheckRelateConsistency)</li>
		/// <li>they do not touch at a vertex
		/// (Checked by ????)</li>
		/// </ul>
		/// </remarks>
		/// <param name="p"></param>
		/// <param name="graph"></param>
		private void CheckHolesNotNested(Polygon p, GeometryGraph graph)
		{
			
			QuadtreeNestedRingTester nestedTester = new QuadtreeNestedRingTester(graph);
			//SimpleNestedRingTester nestedTester = new SimpleNestedRingTester(_arg[0]);
			//SweeplineNestedRingTester nestedTester = new SweeplineNestedRingTester(_arg[0]);

			for (int i = 0; i < p.GetNumInteriorRing(); i++) 
			{
				LinearRing innerHole = p.GetInteriorRingN( i );
				nestedTester.Add(innerHole);
			}
			bool isNonNested = nestedTester.IsNonNested();
			if ( ! isNonNested ) 
			{
				_validErr = new TopologyValidationError(
					TopologyValidationError.NestedHoles,
					nestedTester.GetNestedPoint());
			}
		}
예제 #15
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
		/// CheckRelateConsistency
		/// </summary>
		/// <param name="shell"></param>
		/// <param name="p"></param>
		/// <param name="graph"></param>
		private void CheckShellNotNested(LinearRing shell, Polygon p, GeometryGraph graph)
		{
			
			Coordinates shellPts = shell.GetCoordinates();
			// test if shell is inside polygon shell
			LinearRing polyShell =  (LinearRing) p.GetExteriorRing();
			Coordinates polyPts = polyShell.GetCoordinates();
			Coordinate shellPt = FindPtNotNode(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 = _cga.IsPointInRing(shellPt, polyPts);
			if (! insidePolyShell) return;

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

			for (int i = 0; i < p.GetNumInteriorRing(); i++) 
			{
				LinearRing hole = p.GetInteriorRingN( i );
				CheckShellInsideHole(shell, hole, graph);
				if (_validErr != null) return;
			}
			
		}
예제 #16
0
		private void CheckTooFewPoints(GeometryGraph graph)
		{
			if (graph.HasTooFewPoints()) 
			{
				_validErr = new TopologyValidationError(
					TopologyValidationError.TooFewPoints,
					graph.GetInvalidPoint());
				return;
			}
		}
예제 #17
0
		private void CheckConnectedInteriors(GeometryGraph graph)
		{
			
			ConnectedInteriorTester cit = new ConnectedInteriorTester(graph);
			if (! cit.IsInteriorsConnected())
			{
				_validErr = new TopologyValidationError(
					TopologyValidationError.DisconnectedInterior,
					cit.GetCoordinate());
			}	
		}
예제 #18
0
		/// <summary>
		/// This routine Checks to see if a shell is properly contained in a hole.
		/// </summary>
		/// <param name="shell"></param>
		/// <param name="hole"></param>
		/// <param name="graph"></param>
		private void CheckShellInsideHole(LinearRing shell, LinearRing hole, GeometryGraph graph)
		{
			
			Coordinates shellPts = shell.GetCoordinates();
			Coordinates holePts = hole.GetCoordinates();
			// TODO: improve performance of this - by sorting pointlists for instance?
			Coordinate shellPt = FindPtNotNode(shellPts, hole, graph);
			// if point is on shell but not hole, Check that the shell is inside the hole
			if (shellPt != null) 
			{
				bool insideHole = _cga.IsPointInRing(shellPt, holePts);
				if (! insideHole)
					_validErr = new TopologyValidationError(
						TopologyValidationError.NestedShells,
						shellPt);
				return;
			}
			Coordinate holePt = FindPtNotNode(holePts, shell, graph);
			// if point is on hole but not shell, Check that the hole is outside the shell
			if (holePt != null) 
			{
				bool insideShell = _cga.IsPointInRing(holePt, shellPts);
				if (insideShell) 
				{
					_validErr = new TopologyValidationError(
						TopologyValidationError.NestedShells,
						holePt);
				}
				return;
			}
			throw new InvalidOperationException("Points in shell and hole appear to be equal.");
		}