/// <summary> /// Check that there is no ring which self-intersects (except of course at its endpoints). /// This is required by OGC topology rules (but not by other models /// such as ESRI SDE, which allow inverted shells and exverted holes). /// </summary> /// <param name="graph"></param> private void CheckNoSelfIntersectingRings(GeometryGraph graph) { for (IEnumerator i = graph.GetEdgeEnumerator(); i.MoveNext();) { Edge e = (Edge)i.Current; CheckNoSelfIntersectingRing(e.EdgeIntersectionList); if (validErr != null) { return; } } }
/// <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> private bool HasNonEndpointIntersection(GeometryGraph graph) { for (IEnumerator i = graph.GetEdgeEnumerator(); i.MoveNext();) { Edge e = (Edge)i.Current; int maxSegmentIndex = e.MaximumSegmentIndex; for (IEnumerator eiIt = e.EdgeIntersectionList.GetEnumerator(); eiIt.MoveNext();) { EdgeIntersection ei = (EdgeIntersection)eiIt.Current; if (!ei.IsEndPoint(maxSegmentIndex)) { return(true); } } } return(false); }
/// <summary> /// /// </summary> /// <param name="geomGraph"></param> public virtual 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(); IList eeList = eeBuilder.ComputeEdgeEnds(geomGraph.GetEdgeEnumerator()); InsertEdgeEnds(eeList); }
/// <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 virtual void ComputeIntersectionNodes(GeometryGraph geomGraph, int argIndex) { for (IEnumerator edgeIt = geomGraph.GetEdgeEnumerator(); edgeIt.MoveNext();) { Edge e = (Edge)edgeIt.Current; Locations eLoc = e.Label.GetLocation(argIndex); for (IEnumerator eiIt = e.EdgeIntersectionList.GetEnumerator(); eiIt.MoveNext();) { EdgeIntersection ei = (EdgeIntersection)eiIt.Current; RelateNode n = (RelateNode)nodes.AddNode(ei.Coordinate); if (eLoc == Locations.Boundary) { n.SetLabelBoundary(argIndex); } else if (n.Label.IsNull(argIndex)) { n.SetLabel(argIndex, Locations.Interior); } } } }
/// <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"></param> private bool HasClosedEndpointIntersection(GeometryGraph graph) { IDictionary endPoints = new SortedList(); for (IEnumerator i = graph.GetEdgeEnumerator(); i.MoveNext();) { Edge e = (Edge)i.Current; bool isClosed = e.IsClosed; ICoordinate p0 = e.GetCoordinate(0); AddEndpoint(endPoints, p0, isClosed); ICoordinate p1 = e.GetCoordinate(e.NumPoints - 1); AddEndpoint(endPoints, p1, isClosed); } for (IEnumerator i = endPoints.Values.GetEnumerator(); i.MoveNext();) { EndpointInfo eiInfo = (EndpointInfo)i.Current; if (eiInfo.IsClosed && eiInfo.Degree != 2) { return(true); } } return(false); }