예제 #1
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;
  }
예제 #2
0
 private void findRightmostEdgeAtVertex() {
   /**
    * The rightmost point is an interior vertex, so it has a segment on either side of it. If these
    * segments are both above or below the rightmost point, we need to determine their relative
    * orientation to decide which is rightmost.
    */
   Coordinate[] pts = minDe.getEdge().getCoordinates();
   Assert.isTrue(
       minIndex > 0 && minIndex < pts.length,
       "rightmost point expected to be interior vertex of edge");
   Coordinate pPrev = pts[minIndex - 1];
   Coordinate pNext = pts[minIndex + 1];
   int orientation = CGAlgorithms.computeOrientation(minCoord, pNext, pPrev);
   boolean usePrev = false;
   // both segments are below min point
   if (pPrev.y < minCoord.y
       && pNext.y < minCoord.y
       && orientation == CGAlgorithms.COUNTERCLOCKWISE) {
     usePrev = true;
   } else if (pPrev.y > minCoord.y
       && pNext.y > minCoord.y
       && orientation == CGAlgorithms.CLOCKWISE) {
     usePrev = true;
   }
   // if both segments are on the same side, do nothing - either is safe
   // to select as a rightmost segment
   if (usePrev) {
     minIndex = minIndex - 1;
   }
 }
예제 #3
0
 /**
  * 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());
 }