/** reverses the order of points in lr (is CW -> CCW or CCW->CW) */ LinearRing reverseRing(LinearRing lr) { int numPoints = lr.getNumPoints(); Coordinate[] newCoords = new Coordinate[numPoints]; for (int t = 0; t < numPoints; t++) { newCoords[t] = lr.getCoordinateN(numPoints - t - 1); } return new LinearRing(newCoords, new PrecisionModel(), 0); }
/** * 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; }
/** * Transforms a LinearRing. The transformation of a LinearRing may result in a coordinate sequence * which does not form a structurally valid ring (i.e. a degnerate ring of 3 or fewer points). In * this case a LineString is returned. Subclasses may wish to override this method and check for * this situation (e.g. a subclass may choose to eliminate degenerate linear rings) * * @param geom the ring to simplify * @param parent the parent geometry * @return a LinearRing if the transformation resulted in a structurally valid ring * @return a LineString if the transformation caused the LinearRing to collapse to 3 or fewer * points */ protected Geometry transformLinearRing(LinearRing geom, Geometry parent) { CoordinateSequence seq = transformCoordinates(geom.getCoordinateSequence(), geom); if (seq == null) return factory.createLinearRing((CoordinateSequence) null); int seqSize = seq.size(); // ensure a valid LinearRing if (seqSize > 0 && seqSize < 4 && !preserveType) return factory.createLineString(seq); return factory.createLinearRing(seq); }
/** * Tests if the {@link LinearRing} ring formed by this edge ring is topologically valid. * * @return true if the ring is valid */ public boolean isValid() { getCoordinates(); if (ringPts.length <= 3) return false; getRing(); return ring.isValid(); }
/** * Tests whether this ring is a hole. Due to the way the edges in the polyongization graph are * linked, a ring is a hole if it is oriented counter-clockwise. * * @return <code>true</code> if this ring is a hole */ public boolean isHole() { LinearRing ring = getRing(); return CGAlgorithms.isCCW(ring.getCoordinates()); }