protected Geometry decodePolygon()

in baremaps-core/src/main/java/org/apache/baremaps/vectortile/VectorTileDecoder.java [310:394]


  protected Geometry decodePolygon(List<Integer> encoding) {
    List<Polygon> polygons = new ArrayList<>();
    Optional<LinearRing> shell = Optional.empty();
    List<LinearRing> holes = new ArrayList<>();
    List<Coordinate> coordinates = new ArrayList<>();

    // Iterate over the commands and parameters
    int i = 0;
    while (i < encoding.size()) {
      int value = encoding.get(i);
      int command = command(value);
      int count = count(value);

      // Accumulate the coordinates
      if (command == MOVE_TO || command == LINE_TO) {

        // Increment the index to the first parameter
        i++;

        int length = count * 2;
        for (int j = 0; j < length; j += 2) {
          // Decode the parameters and move the cursor
          cx += parameter(encoding.get(i + j));
          cy += parameter(encoding.get(i + j + 1));

          // Start a new linear ring
          if (command == MOVE_TO) {
            coordinates.clear();
            coordinates.add(new Coordinate(cx, cy));
          }

          // Add the coordinate to the current linear ring
          else if (command == LINE_TO) {
            coordinates.add(new Coordinate(cx, cy));
          }
        }

        // Increment the index to the next command
        i += length;
      }

      // Assemble the linear rings
      if (command == CLOSE_PATH) {
        coordinates.add(coordinates.get(0));
        LinearRing linearRing =
            GEOMETRY_FACTORY.createLinearRing(coordinates.toArray(new Coordinate[0]));
        boolean isShell = isClockWise(linearRing);

        // Build the previous polygon
        if (isShell && shell.isPresent()) {
          polygons
              .add(GEOMETRY_FACTORY.createPolygon(shell.get(), holes.toArray(new LinearRing[0])));
          holes.clear();
        }

        // Add the linear ring to the appropriate variable
        if (isShell) {
          shell = Optional.of(linearRing);
        } else {
          holes.add(linearRing);
        }

        // Reset the coordinates
        coordinates.clear();

        // Increment the index to the next command
        i++;
      }
    }

    // Build the last polygon
    if (shell.isPresent()) {
      polygons.add(GEOMETRY_FACTORY.createPolygon(shell.get(), holes.toArray(new LinearRing[0])));
      holes.clear();
    }

    // Build the final geometry
    if (polygons.size() == 1) {
      return polygons.get(0);
    } else if (polygons.size() > 1) {
      return GEOMETRY_FACTORY.createMultiPolygon(polygons.toArray(new Polygon[0]));
    } else {
      throw new IllegalStateException("No polygons found.");
    }
  }