/// <summary>
		/// Constructs an Operation object.
		/// </summary>
		/// <param name="g0"></param>
		public GeometryGraphOperation(Geometry g0) 
		{
			SetComputationPrecision( g0.PrecisionModel );

			_arg = new GeometryGraph[1];
			_arg[0] = new GeometryGraph(0, g0);;
		}
		/// <summary>
		/// Constructs an Operation object.
		/// </summary>
		/// <param name="g0"></param>
		/// <param name="g1"></param>
		public GeometryGraphOperation(Geometry g0, Geometry g1) 
		{
			SetComputationPrecision( g0.PrecisionModel );

			_arg = new GeometryGraph[2];
			_arg[0] = new GeometryGraph(0, g0);
			_arg[1] = new GeometryGraph(1, g1);
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="geomGraph"></param>
		public void Build(GeometryGraph geomGraph)
		{
			// compute nodes for intersections between previously noded edges
			ComputeIntersectionNodes( geomGraph, 0 );
			// Copy the labelling for the nodes in the parent Geometry.  These override
			// any labels determined by intersections.
			CopyNodesAndLabels( geomGraph, 0 );

			// Build EdgeEnds for all intersections.
			EdgeEndBuilder eeBuilder = new EdgeEndBuilder();
			ArrayList eeList = eeBuilder.ComputeEdgeEnds( geomGraph.Edges );
			InsertEdgeEnds( eeList );

			//Trace.WriteLine("==== NodeList ===");
			//Trace.WriteLine( _nodes.ToString() );
		} // public void Build(GeometryGraph geomGraph)
Example #4
0
		/// <summary>
		///  Find a point from the list of testCoords
		///  that is NOT a node in the edge for the list of searchCoords
		/// </summary>
		/// <param name="testCoords"></param>
		/// <param name="searchRing"></param>
		/// <param name="graph"></param>
		/// <returns>return the point found, or null if none found</returns>
		public static Coordinate FindPtNotNode(
			Coordinates testCoords,
			LinearRing searchRing,
			GeometryGraph graph)
		{
			
			// find edge corresponding to searchRing.
			Edge searchEdge = graph.FindEdge(searchRing );
			// find a point in the testCoords which is not a node of the searchRing
			EdgeIntersectionList eiList = searchEdge.EdgeIntersectionList;
			// somewhat inefficient - is there a better way? (Use a node map, for instance?)
			for (int i = 0 ; i < testCoords.Count; i++) 
			{
				Coordinate pt = testCoords[i];
				if (! eiList.IsIntersection(pt))
				{
					return pt;
				}
			}
			return null;
		}
Example #5
0
		} // private bool IsSimpleLinearGeometry( Geometry geom )

		/// <summary>
		/// For all edges, check if there are any intersections which are NOT at an endpoint.
		/// The Geometry is not simple if there are intersections not at endpoints.
		/// </summary>
		/// <param name="graph"></param>
		/// <returns></returns>
		private bool HasNonEndpointIntersection( GeometryGraph graph )
		{
			foreach ( object obj in graph.Edges )
			{
				Edge e = (Edge) obj;
				int maxSegmentIndex = e.MaximumSegmentIndex;
				foreach ( object eiObj in e.EdgeIntersectionList )
				{
					EdgeIntersection ei = (EdgeIntersection) eiObj;
					if ( !ei.IsEndPoint( maxSegmentIndex ) )
					{
						return true;
					}
				}
			} // foreach ( object obj in graph.Edges )
			return false;
		} // private bool HasNonEndpointIntersection(GeometryGraph graph)
Example #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());
			}
		}
Example #7
0
		private void CheckTooFewPoints(GeometryGraph graph)
		{
			if (graph.HasTooFewPoints()) 
			{
				_validErr = new TopologyValidationError(
					TopologyValidationError.TooFewPoints,
					graph.GetInvalidPoint());
				return;
			}
		}
Example #8
0
		/**
		 * Use a GeometryGraph to node the created edges,
		 * and create split edges between the nodes
		 */
		private ArrayList NodeEdges(ArrayList edges)
		{
			// intersect edges again to ensure they are noded correctly
			GeometryGraph graph = new GeometryGraph(0, _geomFact.PrecisionModel, 0);
			//for (Iterator i = edges.iterator(); i.hasNext(); ) 
			foreach(object obj in edges)
			{
				Edge e = (Edge) obj;
				graph.AddEdge(e);
			}
			SegmentIntersector si = graph.ComputeSelfNodes(_li);
			/*
			if (si.hasProperIntersection())
			Debug.println("proper intersection found");
			else
			Debug.println("no proper intersection found");
			*/
			ArrayList newEdges = new ArrayList();
			graph.ComputeSplitEdges(newEdges);
			return newEdges;
		}
Example #9
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;
				}
			}
		}
		} // public void ComputeIntersectionNodes( GeometryGraph geomGraph, int argIndex )

		/// <summary>
		/// Copy all nodes from an arg geometry into this graph.
		///	The node label in the arg geometry overrides any previously computed
		///	label for that argIndex.
		///	(E.g. a node may be an intersection node with
		///	a computed label of BOUNDARY,
		/// but in the original arg Geometry it is actually
		///	in the interior due to the Boundary Determination Rule)
		/// </summary>
		/// <param name="geomGraph"></param>
		/// <param name="argIndex"></param>
		public void CopyNodesAndLabels( GeometryGraph geomGraph, int argIndex )
		{
			foreach ( DictionaryEntry obj in geomGraph.Nodes ) 
			{
				Node graphNode = (Node) obj.Value;
				Node newNode = _nodes.AddNode( graphNode.GetCoordinate() );
				newNode.SetLabel( argIndex, graphNode.Label.GetLocation( argIndex ) );
				//Trace.WriteLine( _node.ToString() );
			} // foreach ( object obj in geomGraph.Nodes )
		} // public void CopyNodesAndLabels( GeometryGraph geomGraph, int argIndex )
Example #11
0
		/// <summary>
		/// Constructor.
		/// </summary>
		/// <param name="arg">Array of GeometryGraph objects.</param>
		public RelateComputer( GeometryGraph[] arg ) 
		{
			_arg = arg;
		} // public RelateComputer(GeometryGraph[] arg)
Example #12
0
		private void CheckConnectedInteriors(GeometryGraph graph)
		{
			
			ConnectedInteriorTester cit = new ConnectedInteriorTester(graph);
			if (! cit.IsInteriorsConnected())
			{
				_validErr = new TopologyValidationError(
					TopologyValidationError.DisconnectedInterior,
					cit.GetCoordinate());
			}	
		}
Example #13
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.");
		}
Example #14
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;
			}
			
		}
Example #15
0
/*
		private void SLOWCheckHolesNotNested(Polygon p)
		{
			
			for (int i = 0; i < p.GetNumInteriorRing(); i++) 
			{
				LinearRing innerHole = p.GetInteriorRingN( i );
				Coordinates innerHolePts = innerHole.GetCoordinates();
				for (int j = 0; j < p.GetNumInteriorRing(); j++) 
				{
					// don't test hole against itself!
					if (i == j) continue;

					LinearRing searchHole = p.GetInteriorRingN( j );

					// if envelopes don't overlap, holes are not nested
					if (! innerHole.GetEnvelopeInternal().Overlaps(searchHole.GetEnvelopeInternal()))
						continue;

					Coordinates searchHolePts = searchHole.GetCoordinates();
					Coordinate innerholePt = FindPtNotNode(innerHolePts, searchHole, _arg[0]);
					//Assert.isTrue(innerholePt != null, "Unable to find a hole point not a node of the search hole");
					bool inside = _cga.IsPointInPolygon(innerholePt, searchHolePts);
					if ( inside ) 
					{
						_validErr = new TopologyValidationError(
							TopologyValidationError.NestedHoles,
							innerholePt);
						return;
					}
				}
			}
		}
*/		
		/// <summary>
		///  Test that no element polygon is wholly in the interior of another element polygon.
		/// </summary>
		/// <remarks>
		///  TODO: It handles the case that one polygon is nested inside a hole of another.
		///  
		///  Preconditions:
		///  <ul>
		///  <li>shells do not partially overlap</li>
		///  <li>shells do not touch along an edge</li>
		///  <li>no duplicate rings exist</li>
		///  </ul>
		///  This routine relies on the fact that while polygon shells may touch at one or
		///  more vertices, they cannot touch at ALL vertices.
		/// </remarks>
		/// <param name="mp"></param>
		/// <param name="graph"></param>
		private void CheckShellsNotNested(MultiPolygon mp, GeometryGraph graph)
		{
			
			for (int i = 0; i < mp.GetNumGeometries(); i++) 
			{
				Polygon p = (Polygon) mp.GetGeometryN(i);
				LinearRing shell = (LinearRing) p.GetExteriorRing();
				for (int j = 0; j < mp.GetNumGeometries(); j++) 
				{
					if (i == j) continue;
					Polygon p2 = (Polygon) mp.GetGeometryN(j);
					CheckShellNotNested(shell, p2, graph);
					if (_validErr != null) return;
				}
			}
			
		}
Example #16
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());
			}
		}
Example #17
0
		} // class EndpointInfo

		/// <summary>
		/// Test that no edge intersection is the endpoint of a closed line.  To check this we
		/// compute the degree of each endpoint.  The degree of endpoints of closed lines must be
		/// exactly 2.
		/// </summary>
		/// <param name="graph">The GeometryGraph to test.</param>
		/// <returns></returns>
		private bool HasClosedEndpointIntersection( GeometryGraph graph )
		{
			SortedList endPoints = new SortedList();
			foreach ( object obj in graph.Edges )
			{
				Edge e = (Edge) obj;
				int maxSegmentIndex = e.MaximumSegmentIndex;
				bool isClosed = e.IsClosed;
				Coordinate p0 = e.GetCoordinate( 0 );
				AddEndpoint( ref endPoints, p0, isClosed );
				Coordinate p1 = e.GetCoordinate( e.NumPoints - 1 );
				AddEndpoint( ref endPoints, p1, isClosed );
			}

			foreach( DictionaryEntry entry in endPoints )
			{
				EndpointInfo eiInfo = (EndpointInfo) entry.Value;
				if ( eiInfo._isClosed && eiInfo._degree != 2)
				{
					return true;
				}
			}
			return false;
		} // private bool HasClosedEndpointIntersection( GeometryGraph graph )
Example #18
0
        /// <summary>
        /// Compute the labelling for all dirEdges in this star, as well
        ///  as the overall labelling
        /// </summary>
        /// <param name="geom"></param>
        public override void ComputeLabelling(GeometryGraph[] geom)
        {
            //Trace.WriteLine( ToString() );
            base.ComputeLabelling( geom );

            // determine the overall labelling for this DirectedEdgeStar
            // (i.e. for the node it is based at)
            _label = new Label( Location.Null );
            foreach ( object obj in Edges() )
            {
                EdgeEnd ee = (EdgeEnd)obj;
                Edge e = ee.Edge;
                Label eLabel = e.Label;
                for (int i = 0; i < 2; i++)
                {
                    int eLoc = eLabel.GetLocation(i);
                    if ( eLoc == Location.Interior || eLoc == Location.Boundary )
                    {
                        _label.SetLocation( i, Location.Interior );
                    }
                }
            } // foreach ( object obj in edges )

            //Trace.WriteLine( ToString() );
        }
Example #19
0
		} // public bool IsSimple( MultiPoint mp )

		/// <summary>
		/// Tests to see if geometry is simple.
		/// </summary>
		/// <param name="geom">Geometry to test.</param>
		/// <returns>Returns true if geometry is simple, false otherwise.</returns>
		private bool IsSimpleLinearGeometry( Geometry geom )
		{
			if( geom.IsEmpty() )
			{
				return true;
			}
			GeometryGraph graph = new GeometryGraph( 0, geom );
			LineIntersector li = new RobustLineIntersector();
			SegmentIntersector si = graph.ComputeSelfNodes( li );
			// if no self-intersection, must be simple
			if( !si.HasIntersection )
			{
				return true;
			}
			if( si.HasProperIntersection )
			{
				return false;
			}
			if( HasNonEndpointIntersection( graph ) )
			{
				return false;
			}
			if( HasClosedEndpointIntersection( graph ) )
			{
				return false;
			}
			return true;
		} // private bool IsSimpleLinearGeometry( Geometry geom )
		} // public void Build(GeometryGraph geomGraph)

		/// <summary>
		/// Insert nodes for all intersections on the edges of a Geometry.
		/// Label the created nodes the same as the edge label if they do not already have a label.
		///	This allows nodes created by either self-intersections or
		///	mutual intersections to be labelled.
		///	Endpoint nodes will already be labelled from when they were inserted.
		/// Precondition: edge intersections have been computed.
		/// </summary>
		/// <param name="geomGraph"></param>
		/// <param name="argIndex"></param>
		public void ComputeIntersectionNodes( GeometryGraph geomGraph, int argIndex )
		{
			foreach ( object obj in geomGraph.Edges ) 
			{
				Edge e = (Edge) obj;
				int eLoc = e.Label.GetLocation( argIndex );
				foreach ( object objEdgeIntersection in e.EdgeIntersectionList ) 
				{
					EdgeIntersection ei = (EdgeIntersection) objEdgeIntersection;
					RelateNode n = (RelateNode) _nodes.AddNode( ei.Coordinate );
					if ( eLoc == Location.Boundary )
					{
						n.SetLabelBoundary( argIndex );
					}
					else 
					{
						if ( n.Label.IsNull( argIndex ) )
						{
							n.SetLabel( argIndex, Location.Interior );
						} // if ( n.Label.IsNull( argIndex ) )
					}
					//Trace.WriteLine( n.ToString() );
				}
			} // foreach ( object obj in geomGraph.Edges )
		} // public void ComputeIntersectionNodes( GeometryGraph geomGraph, int argIndex )
Example #21
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="g"></param>
        /// <param name="li"></param>
        /// <param name="includeProper"></param>
        /// <returns></returns>
        public SegmentIntersector ComputeEdgeIntersections(
			GeometryGraph g,
			LineIntersector li,
			bool includeProper)
        {
            SegmentIntersector si = new SegmentIntersector( li, includeProper, true);
            si.SetBoundaryNodes( GetBoundaryNodes(), g.GetBoundaryNodes() );

            EdgeSetIntersector esi = new SimpleMCSweepLineIntersector();
            esi.ComputeIntersections( _edges, g.Edges, si );

            /*
            foreach ( object obj in g )
            {
                Edge e = (Edge) obj;
                Trace.WriteLine( e.EdgeIntersectionList.ToString() );
            }
            */
            return si;
        }
Example #22
0
		} // public EdgeEnd GetNextCW(EdgeEnd ee)


		/// <summary>
		/// 
		/// </summary>
		/// <param name="geom"></param>
		public virtual void ComputeLabelling( GeometryGraph[] geom )
		{
			
			ComputeEdgeEndLabels();
			// Propagate side labels  around the edges in the star
			// for each parent Geometry
			Trace.WriteLine( ToString() );
			PropagateSideLabels(0);
			Trace.WriteLine( ToString() );
			PropagateSideLabels(1);
			Trace.WriteLine( ToString() );

			/**
			 * If there are edges that still have null labels for a geometry
			 * this must be because there are no area edges for that geometry incident on this node.
			 * In this case, to label the edge for that geometry we must test whether the
			 * edge is in the interior of the geometry.
			 * To do this it suffices to determine whether the node for the edge is in the interior of an area.
			 * If so, the edge has location INTERIOR for the geometry.
			 * In all other cases (e.g. the node is on a line, on a point, or not on the geometry at all) the edge
			 * has the location EXTERIOR for the geometry.
			 * 
			 * Note that the edge cannot be on the BOUNDARY of the geometry, since then
			 * there would have been a parallel edge from the Geometry at this node also labelled BOUNDARY
			 * and this edge would have been labelled in the previous step.
			 * 
			 * This code causes a problem when dimensional collapses are present, since it may try and
			 * determine the location of a node where a dimensional collapse has occurred.
			 * The point should be considered to be on the EXTERIOR
			 * of the polygon, but locate() will return INTERIOR, since it is passed
			 * the original Geometry, not the collapsed version.
			 *
			 * If there are incident edges which are Line edges labelled BOUNDARY,
			 * then they must be edges resulting from dimensional collapses.
			 * In this case the other edges can be labelled EXTERIOR for this Geometry.
			 *
			 * MD 8/11/01 - NOT TRUE!  The collapsed edges may in fact be in the interior of the Geometry,
			 * which means the other edges should be labelled INTERIOR for this Geometry.
			 * Not sure how solve this...  Possibly labelling needs to be split into several phases:
			 * area label propagation, symLabel merging, then finally null label resolution.
			 */
			
			bool[] hasDimensionalCollapseEdge = new bool[]{ false, false };
			foreach ( EdgeEnd e in Edges() ) 
			{
				Label label = e.Label;

				for (int geomi = 0; geomi < 2; geomi++) 
				{
					if ( label.IsLine( geomi ) && label.GetLocation( geomi ) == Location.Boundary )
					{
						hasDimensionalCollapseEdge[geomi] = true;
					}
				} // for (int geomi = 0; geomi < 2; geomi++)
			} // foreach ( EdgeEnd e in edges )

			//Trace.WriteLine( ToString() );
			foreach ( EdgeEnd e in Edges() ) 
			{
				Label label = e.Label;
				//Trace.WriteLine( label.ToString() );
				for (int geomi = 0; geomi < 2; geomi++) 
				{
					if ( label.IsAnyNull( geomi ) )
					{
						int loc = Location.Null;
						if ( hasDimensionalCollapseEdge[geomi] ) 
						{
							loc = Location.Exterior;
						}
						else 
						{
							Coordinate p = e.Coordinate;
							loc = GetLocation( geomi, p, geom );
						}
						label.SetAllLocationsIfNull( geomi, loc );
					}
				}
				//Tract.WriteLin( e.ToString() );
			}

			//Trace.WriteLine( ToString() );

		} // public void ComputeLabelling( GeometryGraph[] geom )
		/// <summary>
		/// Initializes a new instance of the SimpleNestedRingTester class.
		/// </summary>
		public SimpleNestedRingTester(GeometryGraph graph)
		{
			this._graph = graph;
		}
Example #24
0
		private void CheckNoSelfIntersectingRings(GeometryGraph graph)
		{
			
			foreach (object obj in graph.Edges ) 
			{
				Edge e = (Edge) obj;
				CheckSelfIntersectingRing(e.EdgeIntersectionList);
				if (_validErr != null)
				{
					return;
				}
			}
		}
		///<summary>
		///  Returns the boundary, or the empty geometry if this Geometry is empty.
		///</summary>
		///<remarks>For a discussion
		///  of this function, see the OpenGIS Simple Features Specification. As stated in SFS 
		///  Section 2.1.13.1, "the boundary  of a Geometry is a set of Geometries of the next lower dimension."</remarks>
		///<returns>Returns the closure of the combinatorial boundary of this Geometry.</returns>
		public override Geometry GetBoundary()
		{
			if ( IsEmpty() ) 
			{
				return _geometryFactory.CreateGeometryCollection( null );
			}
			GeometryGraph g = new GeometryGraph(0, this);
			Coordinates pts = g.GetBoundaryPoints();
			return _geometryFactory.CreateMultiPoint(pts);
		}
		public ConnectedInteriorTester(GeometryGraph geomGraph)
		{
			this._geomGraph = geomGraph;
		}
Example #27
0
		int GetLocation(int geomIndex, Coordinate p, GeometryGraph[] geom)
		{
			// compute location only on demand
			if ( _ptInAreaLocation[ geomIndex ] == Location.Null ) 
			{
				_ptInAreaLocation[ geomIndex ] = SimplePointInAreaLocator.Locate( p, geom[geomIndex].Geometry );
			}
			return _ptInAreaLocation[geomIndex];
		}
		/// <summary>
		/// Initializes a new instance of the QuadtreeNestedRingTester class.
		/// </summary>
		public QuadtreeNestedRingTester(GeometryGraph graph)
		{
			this._graph = graph;
		}
		/// <summary>
		/// Initializes a new instance of the SweeplineNestedRingTester class.
		/// </summary>
		public SweeplineNestedRingTester(GeometryGraph graph)
		{
			this._graph = graph;
		}
Example #30
0
		private void CheckValid(MultiPolygon g)
		{
			GeometryGraph graph = new GeometryGraph(0, g);

			CheckConsistentArea(graph);
			if (_validErr != null) return;
			CheckNoSelfIntersectingRings(graph);
			if (_validErr != null) return;

			for (int i = 0; i < g.GetNumGeometries(); i++) 
			{
				Polygon p = (Polygon) g.GetGeometryN(i);
				CheckHolesInShell(p, graph);
				if (_validErr != null) return;
			}
			for (int i = 0; i < g.GetNumGeometries(); i++) 
			{
				Polygon p = (Polygon) g.GetGeometryN(i);
				CheckHolesNotNested(p, graph);
				if (_validErr != null) return;
			}
			CheckShellsNotNested(g, graph);
			if (_validErr != null) return;
			CheckConnectedInteriors(graph);
			
		}