/** * Find and mark L edges which are "covered" by the result area (if any). * L edges at nodes which also have A edges can be checked by checking * their depth at that node. * L edges at nodes which do not have A edges can be checked by doing a * point-in-polygon test with the previously computed result areas. */ private void findCoveredLineEdges() { // first set covered for all L edges at nodes which have A edges too for (Object o1 : op.getGraph().getNodes()) { Node node = (Node) o1; //node.print(System.out); ((DirectedEdgeStar) node.getEdges()).findCoveredLineEdges(); } /** * For all L edges which weren't handled by the above, * use a point-in-poly test to determine whether they are covered */ for (Object o : op.getGraph().getEdgeEnds()) { DirectedEdge de = (DirectedEdge) o; Edge e = de.getEdge(); if (de.isLineEdge() && !e.isCoveredSet()) { boolean isCovered = this.op.isCoveredByA(de.getCoordinate()); e.setCovered(isCovered); } } }
/** * Incomplete nodes are nodes whose labels are incomplete. * (e.g. the location for one Geometry is null). * These are either isolated nodes, * or nodes which have edges from only a single Geometry incident on them. * <p> * Isolated nodes are found because nodes in one graph which don't intersect * nodes in the other are not completely labelled by the initial process * of adding nodes to the nodeList. * To complete the labelling we need to check for nodes that lie in the * interior of edges, and in the interior of areas. * <p> * When each node labelling is completed, the labelling of the incident * edges is updated, to complete their labelling as well. */ private void labelIncompleteNodes() { int nodeCount = 0; for (Object o : graph.getNodes()) { Node n = (Node) o; Label label = n.getLabel(); if (n.isIsolated()) { nodeCount++; if (label.isNull(0)) { this.labelIncompleteNode(n, 0); } else { this.labelIncompleteNode(n, 1); } } // now update the labelling for the DirectedEdges incident on this node ((DirectedEdgeStar) n.getEdges()).updateLabelling(label); //n.print(System.out); } /* int nPoly0 = arg[0].getGeometry().getNumGeometries(); int nPoly1 = arg[1].getGeometry().getNumGeometries(); System.out.println("# isolated nodes= " + nodeCount + " # poly[0] = " + nPoly0 + " # poly[1] = " + nPoly1); */ }
/** * Tests whether the result geometry is consistent * * @throws TopologyException if inconsistent topology is found */ public void check(int opCode) { for (Iterator nodeit = this.graph.getNodeIterator(); nodeit.hasNext(); ) { Node node = (Node) nodeit.next(); this.testLinkResultDirectedEdges((DirectedEdgeStar) node.getEdges(), opCode); } }
private List getPotentialResultAreaEdges(DirectedEdgeStar deStar, int opCode) { //print(System.out); List resultAreaEdgeList = new ArrayList(); for (Iterator it = deStar.iterator(); it.hasNext(); ) { DirectedEdge de = (DirectedEdge) it.next(); if (this.isPotentialResultAreaEdge(de, opCode) || this.isPotentialResultAreaEdge(de.getSym(), opCode)) { resultAreaEdgeList.add(de); } } return resultAreaEdgeList; }
/** * For all nodes in this EdgeRing, * link the DirectedEdges at the node to form minimalEdgeRings */ public void linkDirectedEdgesForMinimalEdgeRings() { DirectedEdge de = this.startDe; do { Node node = de.getNode(); ((DirectedEdgeStar) node.getEdges()).linkMinimalDirectedEdges(this); de = de.getNext(); } while (de != this.startDe); }
/** * For nodes which have edges from only one Geometry incident on them, * the previous step will have left their dirEdges with no labelling for the other * Geometry. However, the sym dirEdge may have a labelling for the other * Geometry, so merge the two labels. */ private void mergeSymLabels() { for (Object o : graph.getNodes()) { Node node = (Node) o; ((DirectedEdgeStar) node.getEdges()).mergeSymLabels(); //node.print(System.out); } }
private void updateNodeLabelling() { // update the labels for nodes // The label for a node is updated from the edges incident on it // (Note that a node may have already been labelled // because it is a point in one of the input geometries) for (Object o : graph.getNodes()) { Node node = (Node) o; Label lbl = ((DirectedEdgeStar) node.getEdges()).getLabel(); node.getLabel().merge(lbl); } }
private void findRightmostEdgeAtNode() { Node node = this.minDe.getNode(); DirectedEdgeStar star = (DirectedEdgeStar) node.getEdges(); this.minDe = star.getRightmostEdge(); // the DirectedEdge returned by the previous call is not // necessarily in the forward direction. Use the sym edge if it isn't. if (!this.minDe.isForward()) { this.minDe = this.minDe.getSym(); this.minIndex = this.minDe.getEdge().getCoordinates().length - 1; } }
/** * For all nodes in this EdgeRing, * link the DirectedEdges at the node to form minimalEdgeRings */ public void linkDirectedEdgesForMinimalEdgeRings() { DirectedEdge de = startDe; do { Node node = de.getNode(); ((DirectedEdgeStar) node.getEdges()).linkMinimalDirectedEdges(this); de = de.getNext(); } while (de != startDe); }
private void testLinkResultDirectedEdges(DirectedEdgeStar deStar, int opCode) { // make sure edges are copied to resultAreaEdges list List ringEdges = this.getPotentialResultAreaEdges(deStar, opCode); // find first area edge (if any) to start linking at DirectedEdge firstOut = null; DirectedEdge incoming = null; int state = this.SCANNING_FOR_INCOMING; // link edges in CCW order for (Object ringEdge : ringEdges) { DirectedEdge nextOut = (DirectedEdge) ringEdge; DirectedEdge nextIn = nextOut.getSym(); // skip de's that we're not interested in if (!nextOut.getLabel().isArea()) { continue; } // record first outgoing edge, in order to link the last incoming edge if (firstOut == null && this.isPotentialResultAreaEdge(nextOut, opCode)) { firstOut = nextOut; } // assert: sym.isInResult() == false, since pairs of dirEdges should have been removed already switch (state) { case SCANNING_FOR_INCOMING: if (!this.isPotentialResultAreaEdge(nextIn, opCode)) { continue; } incoming = nextIn; state = this.LINKING_TO_OUTGOING; break; case LINKING_TO_OUTGOING: if (!this.isPotentialResultAreaEdge(nextOut, opCode)) { continue; } //incoming.setNext(nextOut); state = this.SCANNING_FOR_INCOMING; break; } } //Debug.print(this); if (state == this.LINKING_TO_OUTGOING) { //Debug.print(firstOut == null, this); if (firstOut == null) { throw new TopologyException("no outgoing dirEdge found", deStar.getCoordinate()); } } }
@Override public Node createNode(Coordinate coord) { return new Node(coord, new DirectedEdgeStar()); }
public Node createNode(Coordinate coord) { return new Node(coord, new DirectedEdgeStar()); }