private EnumSet<Direction> sliceWorldCopy(List<List<CoordinateSequence>> groups, int xOffset)
    throws GeometryException {
    EnumSet<Direction> overflow = EnumSet.noneOf(Direction.class);
    for (List<CoordinateSequence> group : groups) {
      Map<TileCoord, List<CoordinateSequence>> inProgressShapes = new HashMap<>();
      for (int i = 0; i < group.size(); i++) {
        CoordinateSequence segment = group.get(i);
        boolean isOuterRing = i == 0;
        /*
         * Step 1 in the striped clipping algorithm: slice the geometry into vertical slices representing each "x" tile
         * coordinate:
         * x=0 1 2 3 4 ...
         *  | | | | | |
         *  |-|-| | | |
         *  | | |\| | |
         *  | | | |-|-|
         *  | | | | | |
         */
        IntObjectMap<List<MutableCoordinateSequence>> xSlices = sliceX(segment);
        for (IntObjectCursor<List<MutableCoordinateSequence>> xCursor : xSlices) {
          int x = xCursor.key + xOffset;
          // skip processing content past the edge of the world, but return that we saw it
          if (x >= maxTilesAtThisZoom) {
            overflow.add(Direction.RIGHT);
          } else if (x < 0) {
            overflow.add(Direction.LEFT);
          } else {
            /*
             * Step 2 in the striped clipping algorithm: split each vertical column x slice into horizontal slices
             * representing the row for each Y coordinate.
             */
            for (CoordinateSequence stripeSegment : xCursor.value) {
              // sliceY only stores content for rings of a polygon, need to store the
              // filled tiles that it spanned separately
              IntRangeSet filledYRange = sliceY(stripeSegment, x, isOuterRing, inProgressShapes);
              if (area && filledYRange != null) {
                if (isOuterRing) {
                  addFilledRange(x, filledYRange);
                } else {
                  removeFilledRange(x, filledYRange);
                }
              }
            }
          }
        }
      }
      addShapeToResults(inProgressShapes);
    }

    return overflow;
  }
Slices a geometry into tiles and stores in member fields for a single "copy" of the world.
<p>
Instead of handling content outside -180 to 180 degrees longitude, return {@link Direction#LEFT} or
{@link Direction#RIGHT} to indicate whether this method should be called again with a different {@code xOffset} to
process wrapped content.

@param groups  the geometry
@param xOffset offset to apply to each X coordinate (-2^z handles content that wraps too far east and 2^z handles
               content that wraps too far west)
@return {@link Direction#LEFT} if there is more content to the west and {@link Direction#RIGHT} if there is more
        content to the east.
@throws GeometryException for a polygon that is invalid in a way that interferes with clipping
planetiler-core/src/main/java/com/onthegomap/planetiler/render/TiledGeometry.java