assignHolesToShells method

List<List<LinearRing>> assignHolesToShells(
  1. List<LinearRing> shells,
  2. List<LinearRing> holes
)

Implementation

List<List<LinearRing>> assignHolesToShells(
    final List<LinearRing> shells, final List<LinearRing> holes) {
  List<List<LinearRing>> holesForShells = [];
  for (int i = 0; i < shells.length; i++) {
    holesForShells.add([]);
  }

  // find homes
  for (int i = 0; i < holes.length; i++) {
    LinearRing testRing = holes[i];
    LinearRing? minShell;
    Envelope? minEnv;
    Envelope testEnv = testRing.getEnvelopeInternal();
    Coordinate testPt = testRing.getCoordinateN(0);
    LinearRing tryRing;

    for (int j = 0; j < shells.length; j++) {
      tryRing = shells[j];

      Envelope tryEnv = tryRing.getEnvelopeInternal();
      if (minShell != null) {
        minEnv = minShell.getEnvelopeInternal();
      }

      bool isContained = false;
      List<Coordinate> coordList = tryRing.getCoordinates();

      if (tryEnv.containsEnvelope(testEnv) &&
          (RayCrossingCounter.locatePointInRingList(testPt, coordList) != 2 ||
              (pointInList(testPt, coordList)))) {
        isContained = true;
      }

      // check if this new containing ring is smaller than the current
      // minimum ring
      if (isContained) {
        if ((minShell == null) || minEnv!.containsEnvelope(tryEnv)) {
          minShell = tryRing;
        }
      }
    }

    if (minShell == null) {
      // now reverse this bad "hole" and turn it into a shell
      shells.add(testRing);
      holesForShells.add([]);
    } else {
      holesForShells[shells.indexOf(minShell)].add(testRing);
    }
  }

  return holesForShells;
}