checkHolesInShell method

void checkHolesInShell(
  1. Polygon p,
  2. GeometryGraph graph
)

Tests that each hole is inside the polygon shell. This routine assumes that the holes have previously been tested to ensure that all vertices lie on the shell or on the same side of it (i.e. that the hole rings do not cross the shell ring). In other words, this test is only correct if the ConsistentArea test is passed first. Given this, a simple point-in-polygon test of a single point in the hole can be used, provided the point is chosen such that it does not lie on the shell.

@param p the polygon to be tested for hole inclusion @param graph a GeometryGraph incorporating the polygon

Implementation

void checkHolesInShell(Polygon p, GeometryGraph graph) {
  LinearRing shell = p.getExteriorRing();
  bool isShellEmpty = shell.isEmpty();
  //PointInRing pir = new SimplePointInRing(shell);
  //PointInRing pir = new SIRtreePointInRing(shell);
  //PointInRing pir = new MCPointInRing(shell);
  PointOnGeometryLocator pir = new IndexedPointInAreaLocator(shell);

  for (int i = 0; i < p.getNumInteriorRing(); i++) {
    LinearRing hole = p.getInteriorRingN(i);
    Coordinate? holePt = null;
    if (hole.isEmpty()) continue;
    holePt = findPtNotNode(hole.getCoordinates(), shell, graph);
    /**
     * If no non-node hole vertex can be found, the hole must
     * split the polygon into disconnected interiors.
     * This will be caught by a subsequent check.
     */
    if (holePt == null) return;

    bool outside = isShellEmpty || (Location.EXTERIOR == pir.locate(holePt));
    if (outside) {
      validErr = new TopologyValidationError.withCoordinate(
          TopologyValidationError.HOLE_OUTSIDE_SHELL, holePt);
      return;
    }
  }
}