/** * Add the given line to the graph * * @param wrappedLine is MasonGeometry wrapping a JTS line * @note Some code copied from JTS PolygonizeGraph.addEdge() and hacked to fit */ private void addLineString(MasonGeometry wrappedLine) { LineString line = (LineString) wrappedLine.geometry; if (line.isEmpty()) { return; } Coordinate[] linePts = CoordinateArrays.removeRepeatedPoints(line.getCoordinates()); if (linePts.length < 2) { return; } Coordinate startPt = linePts[0]; Coordinate endPt = linePts[linePts.length - 1]; Node nStart = getNode(startPt); // nodes added as necessary side-effect Node nEnd = getNode(endPt); GeomPlanarGraphEdge edge = new GeomPlanarGraphEdge(line); GeomPlanarGraphDirectedEdge de0 = new GeomPlanarGraphDirectedEdge(nStart, nEnd, linePts[1], true); GeomPlanarGraphDirectedEdge de1 = new GeomPlanarGraphDirectedEdge(nEnd, nStart, linePts[linePts.length - 2], false); edge.setDirectedEdges(de0, de1); edge.setAttributes(wrappedLine.getAttributes()); add(edge); }
/** * Find the innermost enclosing shell EdgeRing containing the argument EdgeRing, if any. The * innermost enclosing ring is the <i>smallest</i> enclosing ring. The algorithm used depends on * the fact that: <br> * ring A contains ring B iff envelope(ring A) contains envelope(ring B) <br> * This routine is only safe to use if the chosen point of the hole is known to be properly * contained in a shell (which is guaranteed to be the case if the hole does not touch its shell) * * @return containing EdgeRing, if there is one or null if no containing EdgeRing is found */ public static EdgeRing findEdgeRingContaining(EdgeRing testEr, List shellList) { LinearRing testRing = testEr.getRing(); Envelope testEnv = testRing.getEnvelopeInternal(); Coordinate testPt = testRing.getCoordinateN(0); EdgeRing minShell = null; Envelope minShellEnv = null; for (Iterator it = shellList.iterator(); it.hasNext(); ) { EdgeRing tryShell = (EdgeRing) it.next(); LinearRing tryShellRing = tryShell.getRing(); Envelope tryShellEnv = tryShellRing.getEnvelopeInternal(); // the hole envelope cannot equal the shell envelope // (also guards against testing rings against themselves) if (tryShellEnv.equals(testEnv)) continue; // hole must be contained in shell if (!tryShellEnv.contains(testEnv)) continue; testPt = CoordinateArrays.ptNotInList(testRing.getCoordinates(), tryShellRing.getCoordinates()); boolean isContained = false; if (CGAlgorithms.isPointInRing(testPt, tryShellRing.getCoordinates())) isContained = true; // check if this new containing ring is smaller than the current minimum ring if (isContained) { if (minShell == null || minShellEnv.contains(tryShellEnv)) { minShell = tryShell; minShellEnv = minShell.getRing().getEnvelopeInternal(); } } } return minShell; }