checkShellNotNested method

void checkShellNotNested(
  1. LinearRing shell,
  2. Polygon p,
  3. GeometryGraph graph
)

Check if a shell is incorrectly nested within a polygon. This is the case if the shell is inside the polygon shell, but not inside a polygon hole. (If the shell is inside a polygon hole, the nesting is valid.)

The algorithm used relies on the fact that the rings must be properly contained. E.g. they cannot partially overlap (this has been previously checked by checkRelateConsistency )

Implementation

void checkShellNotNested(LinearRing shell, Polygon p, GeometryGraph graph) {
  List<Coordinate> shellPts = shell.getCoordinates();
  // test if shell is inside polygon shell
  LinearRing polyShell = p.getExteriorRing();
  if (polyShell.isEmpty()) return;
  List<Coordinate> polyPts = polyShell.getCoordinates();
  Coordinate? shellPt = findPtNotNode(shellPts, polyShell, graph);
  // if no point could be found, we can assume that the shell is outside the polygon
  if (shellPt == null) return;
  bool insidePolyShell = PointLocation.isInRing(shellPt, polyPts);
  if (!insidePolyShell) return;

  // if no holes, this is an error!
  if (p.getNumInteriorRing() <= 0) {
    validErr = new TopologyValidationError.withCoordinate(
        TopologyValidationError.NESTED_SHELLS, shellPt);
    return;
  }

  /**
   * Check if the shell is inside one of the holes.
   * This is the case if one of the calls to checkShellInsideHole
   * returns a null coordinate.
   * Otherwise, the shell is not properly contained in a hole, which is an error.
   */
  Coordinate? badNestedPt = null;
  for (int i = 0; i < p.getNumInteriorRing(); i++) {
    LinearRing hole = p.getInteriorRingN(i);
    badNestedPt = checkShellInsideHole(shell, hole, graph);
    if (badNestedPt == null) return;
  }
  validErr = new TopologyValidationError.withCoordinate(
      TopologyValidationError.NESTED_SHELLS, badNestedPt);
}