This is an automated email from the ASF dual-hosted git repository.

bchapuis pushed a commit to branch geoparquet-filtering-and-simplification
in repository https://gitbox.apache.org/repos/asf/incubator-baremaps.git

commit cc5d9fed21aa713e2118743505b98fb2ba5796f7
Author: Bertil Chapuis <[email protected]>
AuthorDate: Tue Oct 8 17:05:07 2024 +0200

    Merge GeoParquetGroup interface and implementation
---
 .../baremaps/geoparquet/GeoParquetGroup.java       | 745 +++++++++++++++----
 .../geoparquet/GeoParquetGroupConverter.java       |   8 +-
 .../geoparquet/GeoParquetGroupFactory.java         |   4 +-
 .../baremaps/geoparquet/GeoParquetGroupImpl.java   | 825 ---------------------
 .../GeoParquetGroupRecordMaterializer.java         |   2 +-
 5 files changed, 614 insertions(+), 970 deletions(-)

diff --git 
a/baremaps-geoparquet/src/main/java/org/apache/baremaps/geoparquet/GeoParquetGroup.java
 
b/baremaps-geoparquet/src/main/java/org/apache/baremaps/geoparquet/GeoParquetGroup.java
index 419b9f19..a03ec28a 100644
--- 
a/baremaps-geoparquet/src/main/java/org/apache/baremaps/geoparquet/GeoParquetGroup.java
+++ 
b/baremaps-geoparquet/src/main/java/org/apache/baremaps/geoparquet/GeoParquetGroup.java
@@ -17,241 +17,708 @@
 
 package org.apache.baremaps.geoparquet;
 
+import java.util.ArrayList;
 import java.util.List;
 import org.apache.parquet.io.api.Binary;
+import org.apache.parquet.io.api.RecordConsumer;
 import org.apache.parquet.schema.GroupType;
 import org.locationtech.jts.geom.Envelope;
 import org.locationtech.jts.geom.Geometry;
+import org.locationtech.jts.io.ParseException;
+import org.locationtech.jts.io.WKBReader;
+import org.locationtech.jts.io.WKBWriter;
 
-/**
- * A group of fields in a GeoParquet file.
- * 
- */
-public interface GeoParquetGroup {
+public class GeoParquetGroup {
 
-  /**
-   * Returns the Parquet schema of the group.
-   *
-   * @return the Parquet schema
-   */
-  GroupType getParquetSchema();
+  private final GroupType schema;
 
-  /**
-   * Returns the GeoParquet schema of the group built upon the Parquet schema 
and the GeoParquet
-   * metadata.
-   *
-   * @return the GeoParquet schema
-   */
-  Schema getGeoParquetSchema();
+  private final GeoParquetMetadata metadata;
 
-  /**
-   * Returns the GeoParquet metadata of the group.
-   *
-   * @return the Parquet metadata
-   */
-  GeoParquetMetadata getGeoParquetMetadata();
+  private final Schema geoParquetSchema;
 
-  /**
-   * Creates a new empty group in the group at the specified field index.
-   *
-   * @param fieldIndex the field index
-   * @return the new group
-   */
-  GeoParquetGroup createGroup(int fieldIndex);
+  private final List<?>[] data;
+
+  public GeoParquetGroup(
+      GroupType schema,
+      GeoParquetMetadata metadata,
+      Schema geoParquetSchema) {
+    this.schema = schema;
+    this.metadata = metadata;
+    this.geoParquetSchema = geoParquetSchema;
+    this.data = new List[schema.getFields().size()];
+    for (int i = 0; i < schema.getFieldCount(); i++) {
+      this.data[i] = new ArrayList<>();
+    }
+  }
+
+  public GeoParquetGroup addGroup(int fieldIndex) {
+    GeoParquetGroup group = createGroup(fieldIndex);
+    add(fieldIndex, group);
+    return group;
+  }
+
+  public GeoParquetGroup addGroup(String field) {
+    return addGroup(getParquetSchema().getFieldIndex(field));
+  }
+
+  public GeoParquetGroup getGroup(int fieldIndex, int index) {
+    return (GeoParquetGroup) getValue(fieldIndex, index);
+  }
+
+  public GeoParquetGroup getGroup(String field, int index) {
+    return getGroup(getParquetSchema().getFieldIndex(field), index);
+  }
+
+  public int getFieldRepetitionCount(int fieldIndex) {
+    List<?> list = data[fieldIndex];
+    return list == null ? 0 : list.size();
+  }
+
+  public String getValueToString(int fieldIndex, int index) {
+    return String.valueOf(getValue(fieldIndex, index));
+  }
+
+  public String getString(int fieldIndex, int index) {
+    return ((BinaryValue) getValue(fieldIndex, index)).getString();
+  }
+
+  public int getInteger(int fieldIndex, int index) {
+    return ((IntegerValue) getValue(fieldIndex, index)).getInteger();
+  }
+
+  public long getLong(int fieldIndex, int index) {
+    return ((LongValue) getValue(fieldIndex, index)).getLong();
+  }
+
+  public double getDouble(int fieldIndex, int index) {
+    return ((DoubleValue) getValue(fieldIndex, index)).getDouble();
+  }
+
+  public float getFloat(int fieldIndex, int index) {
+    return ((FloatValue) getValue(fieldIndex, index)).getFloat();
+  }
+
+  public boolean getBoolean(int fieldIndex, int index) {
+    return ((BooleanValue) getValue(fieldIndex, index)).getBoolean();
+  }
+
+  public Binary getBinary(int fieldIndex, int index) {
+    return ((BinaryValue) getValue(fieldIndex, index)).getBinary();
+  }
+
+  public Binary getInt96(int fieldIndex, int index) {
+    return ((Int96Value) getValue(fieldIndex, index)).getInt96();
+  }
+
+  public Geometry getGeometry(int fieldIndex, int index) {
+    byte[] bytes = ((BinaryValue) getValue(fieldIndex, 
index)).getBinary().getBytes();
+    try {
+      return new WKBReader().read(bytes);
+    } catch (ParseException e) {
+      throw new GeoParquetException("WKBReader failed to parse", e);
+    }
+  }
+
+  private Object getValue(int fieldIndex, int index) {
+    List<?> list = getObjects(fieldIndex);
+    try {
+      return list.get(index);
+    } catch (IndexOutOfBoundsException e) {
+      String elementText = String.format(" element number %d ", index);
+      throw createGeoParquetException(fieldIndex, elementText);
+    }
+  }
+
+  private List<?> getObjects(int fieldIndex) {
+    List<?> list;
+    if (fieldIndex < 0 || fieldIndex >= data.length) {
+      throw createGeoParquetException(fieldIndex, "");
+    }
+    list = data[fieldIndex];
+    return list;
+  }
+
+  private GeoParquetException createGeoParquetException(int fieldIndex, String 
elementText) {
+    String msg = String.format("Not found %d (%s)%s in group%n%s", fieldIndex,
+        schema.getFieldName(fieldIndex), elementText, this);
+    return new GeoParquetException(msg);
+  }
+
+  private void add(int fieldIndex, Primitive value) {
+    org.apache.parquet.schema.Type type = schema.getType(fieldIndex);
+    List list = getObjects(fieldIndex);
+    if (!type.isRepetition(org.apache.parquet.schema.Type.Repetition.REPEATED)
+        && !list.isEmpty()) {
+      throw new IllegalStateException("field " + fieldIndex + " (" + 
type.getName()
+          + ") can not have more than one value: " + list);
+    }
+    list.add(value);
+  }
+
+  public void add(int fieldIndex, int value) {
+    add(fieldIndex, new IntegerValue(value));
+  }
+
+  public void add(int fieldIndex, long value) {
+    add(fieldIndex, new LongValue(value));
+  }
+
+  public void add(int fieldIndex, String value) {
+    add(fieldIndex, new BinaryValue(Binary.fromString(value)));
+  }
+
+  public void add(int fieldIndex, boolean value) {
+    add(fieldIndex, new BooleanValue(value));
+  }
+
+  public void add(int fieldIndex, Binary value) {
+    switch 
(getParquetSchema().getType(fieldIndex).asPrimitiveType().getPrimitiveTypeName())
 {
+      case BINARY, FIXED_LEN_BYTE_ARRAY:
+        add(fieldIndex, new BinaryValue(value));
+        break;
+      case INT96:
+        add(fieldIndex, new Int96Value(value));
+        break;
+      default:
+        throw new UnsupportedOperationException(
+            getParquetSchema().asPrimitiveType().getName() + " not supported 
for Binary");
+    }
+  }
+
+  public void add(int fieldIndex, float value) {
+    add(fieldIndex, new FloatValue(value));
+  }
+
+  public void add(int fieldIndex, double value) {
+    add(fieldIndex, new DoubleValue(value));
+  }
+
+  public void add(int fieldIndex, GeoParquetGroup value) {
+    List list = data[fieldIndex];
+    list.add(value);
+  }
+
+  public void add(int fieldIndex, Geometry geometry) {
+    byte[] bytes = new WKBWriter().write(geometry);
+    add(fieldIndex, Binary.fromConstantByteArray(bytes));
+  }
+
+  public void add(String field, int value) {
+    add(getParquetSchema().getFieldIndex(field), value);
+  }
+
+  public void add(String field, long value) {
+    add(getParquetSchema().getFieldIndex(field), value);
+  }
+
+  public void add(String field, float value) {
+    add(getParquetSchema().getFieldIndex(field), value);
+  }
+
+  public void add(String field, double value) {
+    add(getParquetSchema().getFieldIndex(field), value);
+  }
+
+  public void add(String field, String value) {
+    add(getParquetSchema().getFieldIndex(field), value);
+  }
+
+  public void add(String field, boolean value) {
+    add(getParquetSchema().getFieldIndex(field), value);
+  }
+
+  public void add(String field, Binary value) {
+    add(getParquetSchema().getFieldIndex(field), value);
+  }
+
+  public void add(String field, GeoParquetGroup value) {
+    add(getParquetSchema().getFieldIndex(field), value);
+  }
+
+  public void add(String field, Geometry geometry) {
+    byte[] bytes = new WKBWriter().write(geometry);
+    add(getParquetSchema().getFieldIndex(field), 
Binary.fromConstantByteArray(bytes));
+  }
+
+  public void writeValue(int field, int index, RecordConsumer recordConsumer) {
+    ((Primitive) getValue(field, index)).writeValue(recordConsumer);
+  }
+
+  public String toString() {
+    return toString("");
+  }
+
+  public String toString(String indent) {
+    StringBuilder builder = new StringBuilder();
+    appendToString(builder, indent);
+    return builder.toString();
+  }
+
+  private void appendToString(StringBuilder builder, String indent) {
+    int i = 0;
+    for (org.apache.parquet.schema.Type field : schema.getFields()) {
+      String name = field.getName();
+      List<?> values = data[i];
+      ++i;
+      if (values != null && !values.isEmpty()) {
+        for (Object value : values) {
+          builder.append(indent).append(name);
+          if (value == null) {
+            builder.append(": NULL\n");
+          } else if (value instanceof GeoParquetGroup geoParquetGroup) {
+            builder.append('\n');
+            geoParquetGroup.appendToString(builder, indent + "  ");
+          } else {
+            builder.append(": ").append(value).append('\n');
+          }
+        }
+      }
+    }
+  }
+
+  public List<Primitive> getValues(int fieldIndex) {
+    return (List<Primitive>) data[fieldIndex];
+  }
+
+  private List<GeoParquetGroup> getGroups(int fieldIndex) {
+    return (List<GeoParquetGroup>) data[fieldIndex];
+  }
+
+  public Schema getGeoParquetSchema() {
+    return geoParquetSchema;
+  }
 
-  List<Primitive> getValues(int fieldIndex);
+  public GroupType getParquetSchema() {
+    return schema;
+  }
 
-  Binary getBinaryValue(int fieldIndex);
+  public GeoParquetMetadata getGeoParquetMetadata() {
+    return metadata;
+  }
 
-  List<Binary> getBinaryValues(int fieldIndex);
+  public GeoParquetGroup createGroup(int fieldIndex) {
+    if (geoParquetSchema.fields().get(fieldIndex) instanceof EnvelopeField 
envelopeField) {
+      return new GeoParquetGroup(schema.getType(fieldIndex).asGroupType(), 
metadata,
+          envelopeField.schema());
+    }
 
-  Boolean getBooleanValue(int fieldIndex);
+    if (geoParquetSchema.fields().get(fieldIndex) instanceof GroupField 
groupField) {
+      return new GeoParquetGroup(schema.getType(fieldIndex).asGroupType(), 
metadata,
+          groupField.schema());
+    }
 
-  List<Boolean> getBooleanValues(int fieldIndex);
+    GroupField field = ((GroupField) 
geoParquetSchema.fields().get(fieldIndex));
+    return new GeoParquetGroup(
+        schema.getType(fieldIndex).asGroupType(),
+        metadata,
+        field.schema());
+  }
 
-  Double getDoubleValue(int fieldIndex);
+  public Binary getBinaryValue(int fieldIndex) {
+    return getBinaryValues(fieldIndex).get(0);
+  }
 
-  List<Double> getDoubleValues(int fieldIndex);
+  public List<Binary> getBinaryValues(int fieldIndex) {
+    return getValues(fieldIndex).stream().map(Primitive::getBinary).toList();
+  }
 
-  Float getFloatValue(int fieldIndex);
+  public Boolean getBooleanValue(int fieldIndex) {
+    return getBooleanValues(fieldIndex).get(0);
+  }
 
-  List<Float> getFloatValues(int fieldIndex);
+  public List<Boolean> getBooleanValues(int fieldIndex) {
+    return getValues(fieldIndex).stream().map(Primitive::getBoolean).toList();
+  }
 
-  Integer getIntegerValue(int fieldIndex);
+  public Double getDoubleValue(int fieldIndex) {
+    return getDoubleValues(fieldIndex).get(0);
+  }
 
-  List<Integer> getIntegerValues(int fieldIndex);
+  public List<Double> getDoubleValues(int fieldIndex) {
+    return getValues(fieldIndex).stream().map(Primitive::getDouble).toList();
+  }
 
-  Binary getInt96Value(int fieldIndex);
+  public Float getFloatValue(int fieldIndex) {
+    return getFloatValues(fieldIndex).get(0);
+  }
 
-  List<Binary> getInt96Values(int fieldIndex);
+  public List<Float> getFloatValues(int fieldIndex) {
+    return getValues(fieldIndex).stream().map(Primitive::getFloat).toList();
+  }
 
-  Binary getNanoTimeValue(int fieldIndex);
+  public Integer getIntegerValue(int fieldIndex) {
+    return getIntegerValues(fieldIndex).get(0);
+  }
 
-  List<Binary> getNanoTimeValues(int fieldIndex);
+  public List<Integer> getIntegerValues(int fieldIndex) {
+    return getValues(fieldIndex).stream().map(Primitive::getInteger).toList();
+  }
 
-  Long getLongValue(int fieldIndex);
+  public Binary getInt96Value(int fieldIndex) {
+    return getBinaryValues(fieldIndex).get(0);
+  }
 
-  List<Long> getLongValues(int fieldIndex);
+  public List<Binary> getInt96Values(int fieldIndex) {
+    return getValues(fieldIndex).stream().map(Primitive::getBinary).toList();
+  }
 
-  String getStringValue(int fieldIndex);
+  public Binary getNanoTimeValue(int fieldIndex) {
+    return getBinaryValues(fieldIndex).get(0);
+  }
 
-  List<String> getStringValues(int fieldIndex);
+  public List<Binary> getNanoTimeValues(int fieldIndex) {
+    return getValues(fieldIndex).stream().map(Primitive::getBinary).toList();
+  }
 
-  Geometry getGeometryValue(int fieldIndex);
+  public Long getLongValue(int fieldIndex) {
+    return getLongValues(fieldIndex).get(0);
+  }
 
-  List<Geometry> getGeometryValues(int fieldIndex);
+  public List<Long> getLongValues(int fieldIndex) {
+    return getValues(fieldIndex).stream().map(Primitive::getLong).toList();
+  }
 
-  Envelope getEnvelopeValue(int fieldIndex);
+  public String getStringValue(int fieldIndex) {
+    return getStringValues(fieldIndex).get(0);
+  }
 
-  List<Envelope> getEnvelopeValues(int fieldIndex);
+  public List<String> getStringValues(int fieldIndex) {
+    return getValues(fieldIndex).stream().map(Primitive::getString).toList();
+  }
 
-  GeoParquetGroup getGroupValue(int fieldIndex);
+  public Geometry getGeometryValue(int fieldIndex) {
+    return getGeometryValues(fieldIndex).get(0);
+  }
 
-  List<GeoParquetGroup> getGroupValues(int fieldIndex);
+  public List<Geometry> getGeometryValues(int fieldIndex) {
+    List<Geometry> geometries = new ArrayList<>();
+    for (Binary binary : getBinaryValues(fieldIndex)) {
+      try {
+        geometries.add(new WKBReader().read(binary.getBytes()));
+      } catch (ParseException e) {
+        throw new GeoParquetException("WKBReader failed to parse.", e);
+      }
+    }
+    return geometries;
+  }
 
-  Binary getBinaryValue(String fieldName);
+  public Envelope getEnvelopeValue(int fieldIndex) {
+    return getEnvelopeValues(fieldIndex).get(0);
+  }
 
-  List<Binary> getBinaryValues(String fieldName);
+  public List<Envelope> getEnvelopeValues(int fieldIndex) {
+    return getGroupValues(fieldIndex).stream().map(group -> {
+      double xMin = 
group.getGeoParquetSchema().fields().get(0).type().equals(Type.FLOAT)
+          ? (double) group.getFloatValue(0)
+          : group.getDoubleValue(0);
+      double yMin = 
group.getGeoParquetSchema().fields().get(1).type().equals(Type.FLOAT)
+          ? (double) group.getFloatValue(1)
+          : group.getDoubleValue(1);
+      double xMax = 
group.getGeoParquetSchema().fields().get(2).type().equals(Type.FLOAT)
+          ? (double) group.getFloatValue(2)
+          : group.getDoubleValue(2);
+      double yMax = 
group.getGeoParquetSchema().fields().get(0).type().equals(Type.FLOAT)
+          ? (double) group.getFloatValue(3)
+          : group.getDoubleValue(3);
+      return new Envelope(xMin, xMax, yMin, yMax);
+    }).toList();
+  }
 
-  Boolean getBooleanValue(String fieldName);
+  public GeoParquetGroup getGroupValue(int fieldIndex) {
+    return getGroupValues(fieldIndex).get(0);
+  }
 
-  List<Boolean> getBooleanValues(String fieldName);
+  public List<GeoParquetGroup> getGroupValues(int fieldIndex) {
+    return getGroups(fieldIndex);
+  }
 
-  Double getDoubleValue(String fieldName);
+  public Binary getBinaryValue(String fieldName) {
+    return getBinaryValues(fieldName).get(0);
+  }
 
-  List<Double> getDoubleValues(String fieldName);
+  public List<Binary> getBinaryValues(String fieldName) {
+    return getBinaryValues(schema.getFieldIndex(fieldName));
+  }
 
-  Float getFloatValue(String fieldName);
+  public Boolean getBooleanValue(String fieldName) {
+    return getBooleanValues(fieldName).get(0);
+  }
 
-  List<Float> getFloatValues(String fieldName);
+  public List<Boolean> getBooleanValues(String fieldName) {
+    return getBooleanValues(schema.getFieldIndex(fieldName));
+  }
 
-  Integer getIntegerValue(String fieldName);
+  public Double getDoubleValue(String fieldName) {
+    return getDoubleValues(fieldName).get(0);
+  }
 
-  List<Integer> getIntegerValues(String fieldName);
+  public List<Double> getDoubleValues(String fieldName) {
+    return getDoubleValues(schema.getFieldIndex(fieldName));
+  }
 
-  Binary getInt96Value(String fieldName);
+  public Float getFloatValue(String fieldName) {
+    return getFloatValues(fieldName).get(0);
+  }
 
-  List<Binary> getInt96Values(String fieldName);
+  public List<Float> getFloatValues(String fieldName) {
+    return getFloatValues(schema.getFieldIndex(fieldName));
+  }
 
-  Binary getNanoTimeValue(String fieldName);
+  public Integer getIntegerValue(String fieldName) {
+    return getIntegerValues(fieldName).get(0);
+  }
 
-  List<Binary> getNanoTimeValues(String fieldName);
+  public List<Integer> getIntegerValues(String fieldName) {
+    return getIntegerValues(schema.getFieldIndex(fieldName));
+  }
 
-  Long getLongValue(String fieldName);
+  public Binary getInt96Value(String fieldName) {
+    return getBinaryValues(fieldName).get(0);
+  }
 
-  List<Long> getLongValues(String fieldName);
+  public List<Binary> getInt96Values(String fieldName) {
+    return getBinaryValues(schema.getFieldIndex(fieldName));
+  }
 
-  String getStringValue(String fieldName);
+  public Binary getNanoTimeValue(String fieldName) {
+    return getBinaryValues(fieldName).get(0);
+  }
 
-  List<String> getStringValues(String fieldName);
+  public List<Binary> getNanoTimeValues(String fieldName) {
+    return getBinaryValues(schema.getFieldIndex(fieldName));
+  }
 
-  Geometry getGeometryValue(String fieldName);
+  public Long getLongValue(String fieldName) {
+    return getLongValues(fieldName).get(0);
+  }
 
-  List<Geometry> getGeometryValues(String fieldName);
+  public List<Long> getLongValues(String fieldName) {
+    return getLongValues(schema.getFieldIndex(fieldName));
+  }
+
+  public String getStringValue(String fieldName) {
+    return getStringValues(fieldName).get(0);
+  }
+
+  public List<String> getStringValues(String fieldName) {
+    return getStringValues(schema.getFieldIndex(fieldName));
+  }
+
+  public Geometry getGeometryValue(String fieldName) {
+    return getGeometryValues(fieldName).get(0);
+  }
+
+  public List<Geometry> getGeometryValues(String fieldName) {
+    return getGeometryValues(schema.getFieldIndex(fieldName));
+  }
 
-  Envelope getEnvelopeValue(String fieldName);
+  public Envelope getEnvelopeValue(String fieldName) {
+    return getEnvelopeValues(fieldName).get(0);
+  }
 
-  List<Envelope> getEnvelopeValues(String fieldName);
+  public List<Envelope> getEnvelopeValues(String fieldName) {
+    return getEnvelopeValues(schema.getFieldIndex(fieldName));
+  }
 
-  GeoParquetGroup getGroupValue(String fieldName);
+  public GeoParquetGroup getGroupValue(String fieldName) {
+    return getGroupValues(fieldName).get(0);
+  }
 
-  List<GeoParquetGroup> getGroupValues(String fieldName);
+  public List<GeoParquetGroup> getGroupValues(String fieldName) {
+    return getGroupValues(schema.getFieldIndex(fieldName));
+  }
 
-  void setBinaryValue(int fieldIndex, Binary binaryValue);
+  public void setBinaryValue(int fieldIndex, Binary binaryValue) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setBinaryValues(int fieldIndex, List<Binary> binaryValues);
+  public void setBinaryValues(int fieldIndex, List<Binary> binaryValues) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setBooleanValue(int fieldIndex, Boolean booleanValue);
+  public void setBooleanValue(int fieldIndex, Boolean booleanValue) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setBooleanValues(int fieldIndex, List<Boolean> booleanValues);
+  public void setBooleanValues(int fieldIndex, List<Boolean> booleanValues) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setDoubleValue(int fieldIndex, Double doubleValue);
+  public void setDoubleValue(int fieldIndex, Double doubleValue) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setDoubleValues(int fieldIndex, List<Double> doubleValues);
+  public void setDoubleValues(int fieldIndex, List<Double> doubleValues) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setFloatValue(int fieldIndex, Float floatValue);
+  public void setFloatValue(int fieldIndex, Float floatValue) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setFloatValues(int fieldIndex, List<Float> floatValues);
+  public void setFloatValues(int fieldIndex, List<Float> floatValues) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setIntegerValue(int fieldIndex, Integer integerValue);
+  public void setIntegerValue(int fieldIndex, Integer integerValue) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setIntegerValues(int fieldIndex, List<Integer> integerValues);
+  public void setIntegerValues(int fieldIndex, List<Integer> integerValues) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setInt96Value(int fieldIndex, Binary int96Value);
+  public void setInt96Value(int fieldIndex, Binary int96Value) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setInt96Values(int fieldIndex, List<Binary> int96Values);
+  public void setInt96Values(int fieldIndex, List<Binary> int96Values) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setNanoTimeValue(int fieldIndex, Binary nanoTimeValue);
+  public void setNanoTimeValue(int fieldIndex, Binary nanoTimeValue) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setNanoTimeValues(int fieldIndex, List<Binary> nanoTimeValues);
+  public void setNanoTimeValues(int fieldIndex, List<Binary> nanoTimeValues) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setLongValue(int fieldIndex, Long longValue);
+  public void setLongValue(int fieldIndex, Long longValue) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setLongValues(int fieldIndex, List<Long> longValues);
+  public void setLongValues(int fieldIndex, List<Long> longValues) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setStringValue(int fieldIndex, String stringValue);
+  public void setStringValue(int fieldIndex, String stringValue) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setStringValues(int fieldIndex, List<String> stringValues);
+  public void setStringValues(int fieldIndex, List<String> stringValues) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setGeometryValue(int fieldIndex, Geometry geometryValue);
+  public void setGeometryValue(int fieldIndex, Geometry geometryValue) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setGeometryValues(int fieldIndex, List<Geometry> geometryValues);
+  public void setGeometryValues(int fieldIndex, List<Geometry> geometryValues) 
{
+    throw new UnsupportedOperationException();
+  }
 
-  void setEnvelopeValue(int fieldIndex, Envelope envelopeValue);
+  public void setEnvelopeValue(int fieldIndex, Envelope envelopeValue) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setEnvelopeValues(int fieldIndex, List<Envelope> envelopeValues);
+  public void setEnvelopeValues(int fieldIndex, List<Envelope> envelopeValues) 
{
+    throw new UnsupportedOperationException();
+  }
 
-  void setGroupValue(int fieldIndex, GeoParquetGroup groupValue);
+  public void setGroupValue(int fieldIndex, GeoParquetGroup groupValue) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setGroupValues(int fieldIndex, List<GeoParquetGroup> groupValues);
+  public void setGroupValues(int fieldIndex, List<GeoParquetGroup> 
groupValues) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setBinaryValue(String fieldName, Binary binaryValue);
+  public void setBinaryValue(String fieldName, Binary binaryValue) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setBinaryValues(String fieldName, List<Binary> binaryValues);
+  public void setBinaryValues(String fieldName, List<Binary> binaryValues) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setBooleanValue(String fieldName, Boolean booleanValue);
+  public void setBooleanValue(String fieldName, Boolean booleanValue) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setBooleanValues(String fieldName, List<Boolean> booleanValues);
+  public void setBooleanValues(String fieldName, List<Boolean> booleanValues) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setDoubleValue(String fieldName, Double doubleValue);
+  public void setDoubleValue(String fieldName, Double doubleValue) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setDoubleValues(String fieldName, List<Double> doubleValues);
+  public void setDoubleValues(String fieldName, List<Double> doubleValues) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setFloatValue(String fieldName, Float floatValue);
+  public void setFloatValue(String fieldName, Float floatValue) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setFloatValues(String fieldName, List<Float> floatValues);
+  public void setFloatValues(String fieldName, List<Float> floatValues) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setIntegerValue(String fieldName, Integer integerValue);
+  public void setIntegerValue(String fieldName, Integer integerValue) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setIntegerValues(String fieldName, List<Integer> integerValues);
+  public void setIntegerValues(String fieldName, List<Integer> integerValues) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setInt96Value(String fieldName, Binary int96Value);
+  public void setInt96Value(String fieldName, Binary int96Value) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setInt96Values(String fieldName, List<Binary> int96Values);
+  public void setInt96Values(String fieldName, List<Binary> int96Values) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setNanoTimeValue(String fieldName, Binary nanoTimeValue);
+  public void setNanoTimeValue(String fieldName, Binary nanoTimeValue) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setNanoTimeValues(String fieldName, List<Binary> nanoTimeValues);
+  public void setNanoTimeValues(String fieldName, List<Binary> nanoTimeValues) 
{
+    throw new UnsupportedOperationException();
+  }
 
-  void setLongValue(String fieldName, Long longValue);
+  public void setLongValue(String fieldName, Long longValue) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setLongValues(String fieldName, List<Long> longValues);
+  public void setLongValues(String fieldName, List<Long> longValues) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setStringValue(String fieldName, String stringValue);
+  public void setStringValue(String fieldName, String stringValue) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setStringValues(String fieldName, List<String> stringValues);
+  public void setStringValues(String fieldName, List<String> stringValues) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setGeometryValue(String fieldName, Geometry geometryValue);
+  public void setGeometryValue(String fieldName, Geometry geometryValue) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setGeometryValues(String fieldName, List<Geometry> geometryValues);
+  public void setGeometryValues(String fieldName, List<Geometry> 
geometryValues) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setEnvelopeValue(String fieldName, Envelope envelopeValue);
+  public void setEnvelopeValue(String fieldName, Envelope envelopeValue) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setEnvelopeValues(String fieldName, List<Envelope> envelopeValues);
+  public void setEnvelopeValues(String fieldName, List<Envelope> 
envelopeValues) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setGroupValue(String fieldName, GeoParquetGroup groupValue);
+  public void setGroupValue(String fieldName, GeoParquetGroup groupValue) {
+    throw new UnsupportedOperationException();
+  }
 
-  void setGroupValues(String fieldName, List<GeoParquetGroup> groupValues);
+  public void setGroupValues(String fieldName, List<GeoParquetGroup> 
groupValues) {
+    throw new UnsupportedOperationException();
+  }
 
   /**
    * A GeoParquet schema that describes the fields of a group and can easily 
be introspected.
@@ -259,7 +726,7 @@ public interface GeoParquetGroup {
    * @param name
    * @param fields the fields of the schema
    */
-  record Schema(String name, List<Field> fields) {
+  public record Schema(String name, List<Field> fields) {
 
   }
 
@@ -269,13 +736,13 @@ public interface GeoParquetGroup {
    * Sealed interfaces were introduced in Java 17 and can be used with pattern 
matching since Java
    * 21.
    */
-  sealed
+  sealed public
   interface Field {
-    String name();
+     String name();
 
-    Type type();
+     Type type();
 
-    Cardinality cardinality();
+     Cardinality cardinality();
   }
 
   record BinaryField(String name, Cardinality cardinality) implements Field {
@@ -353,12 +820,12 @@ public interface GeoParquetGroup {
   record EnvelopeField(String name, Cardinality cardinality, Schema schema) 
implements Field {
 
     @Override
-        public Type type() {
-        return Type.ENVELOPE;
-        }
+    public Type type() {
+      return Type.ENVELOPE;
+    }
   }
 
-  record GroupField(String name, Cardinality cardinality, Schema schema) 
implements Field {
+  public record GroupField(String name, Cardinality cardinality, Schema 
schema) implements Field {
 
     @Override
     public Type type() {
@@ -369,7 +836,7 @@ public interface GeoParquetGroup {
   /**
    * The type of a GeoParquet field.
    */
-  enum Type {
+  public enum Type {
     BINARY,
     BOOLEAN,
     DOUBLE,
@@ -386,7 +853,7 @@ public interface GeoParquetGroup {
   /**
    * The cardinality of a GeoParquet field.
    */
-  enum Cardinality {
+  public enum Cardinality {
     REQUIRED,
     OPTIONAL,
     REPEATED
diff --git 
a/baremaps-geoparquet/src/main/java/org/apache/baremaps/geoparquet/GeoParquetGroupConverter.java
 
b/baremaps-geoparquet/src/main/java/org/apache/baremaps/geoparquet/GeoParquetGroupConverter.java
index 5257b9ea..d5c06724 100644
--- 
a/baremaps-geoparquet/src/main/java/org/apache/baremaps/geoparquet/GeoParquetGroupConverter.java
+++ 
b/baremaps-geoparquet/src/main/java/org/apache/baremaps/geoparquet/GeoParquetGroupConverter.java
@@ -26,10 +26,12 @@ class GeoParquetGroupConverter extends GroupConverter {
 
   private final GeoParquetGroupConverter parent;
   private final int index;
-  protected GeoParquetGroupImpl current;
+  protected GeoParquetGroup current;
   private final Converter[] converters;
 
-  GeoParquetGroupConverter(GeoParquetGroupConverter parent, int index,
+  GeoParquetGroupConverter(
+      GeoParquetGroupConverter parent,
+      int index,
       GroupType schema) {
     this.parent = parent;
     this.index = index;
@@ -62,7 +64,7 @@ class GeoParquetGroupConverter extends GroupConverter {
     current = null;
   }
 
-  public GeoParquetGroupImpl getCurrentRecord() {
+  public GeoParquetGroup getCurrentRecord() {
     return current;
   }
 }
diff --git 
a/baremaps-geoparquet/src/main/java/org/apache/baremaps/geoparquet/GeoParquetGroupFactory.java
 
b/baremaps-geoparquet/src/main/java/org/apache/baremaps/geoparquet/GeoParquetGroupFactory.java
index bcea6b8b..2b093226 100644
--- 
a/baremaps-geoparquet/src/main/java/org/apache/baremaps/geoparquet/GeoParquetGroupFactory.java
+++ 
b/baremaps-geoparquet/src/main/java/org/apache/baremaps/geoparquet/GeoParquetGroupFactory.java
@@ -94,8 +94,8 @@ class GeoParquetGroupFactory {
     return new GeoParquetGroup.Schema(schema.getName(), fields);
   }
 
-  public GeoParquetGroupImpl newGroup() {
-    return new GeoParquetGroupImpl(schema, metadata, geoParquetSchema);
+  public GeoParquetGroup newGroup() {
+    return new GeoParquetGroup(schema, metadata, geoParquetSchema);
   }
 
 }
diff --git 
a/baremaps-geoparquet/src/main/java/org/apache/baremaps/geoparquet/GeoParquetGroupImpl.java
 
b/baremaps-geoparquet/src/main/java/org/apache/baremaps/geoparquet/GeoParquetGroupImpl.java
deleted file mode 100644
index b9a6a607..00000000
--- 
a/baremaps-geoparquet/src/main/java/org/apache/baremaps/geoparquet/GeoParquetGroupImpl.java
+++ /dev/null
@@ -1,825 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.baremaps.geoparquet;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.apache.parquet.io.api.Binary;
-import org.apache.parquet.io.api.RecordConsumer;
-import org.apache.parquet.schema.GroupType;
-import org.locationtech.jts.geom.Envelope;
-import org.locationtech.jts.geom.Geometry;
-import org.locationtech.jts.io.ParseException;
-import org.locationtech.jts.io.WKBReader;
-import org.locationtech.jts.io.WKBWriter;
-
-class GeoParquetGroupImpl implements GeoParquetGroup {
-
-  private final GroupType schema;
-
-  private final GeoParquetMetadata metadata;
-
-  private final Schema geoParquetSchema;
-
-  private final List<?>[] data;
-
-  public GeoParquetGroupImpl(
-      GroupType schema,
-      GeoParquetMetadata metadata,
-      Schema geoParquetSchema) {
-    this.schema = schema;
-    this.metadata = metadata;
-    this.geoParquetSchema = geoParquetSchema;
-    this.data = new List[schema.getFields().size()];
-    for (int i = 0; i < schema.getFieldCount(); i++) {
-      this.data[i] = new ArrayList<>();
-    }
-  }
-
-  public GeoParquetGroupImpl addGroup(int fieldIndex) {
-    GeoParquetGroupImpl group = createGroup(fieldIndex);
-    add(fieldIndex, group);
-    return group;
-  }
-
-  public GeoParquetGroupImpl addGroup(String field) {
-    return addGroup(getParquetSchema().getFieldIndex(field));
-  }
-
-  public GeoParquetGroupImpl getGroup(int fieldIndex, int index) {
-    return (GeoParquetGroupImpl) getValue(fieldIndex, index);
-  }
-
-  public GeoParquetGroupImpl getGroup(String field, int index) {
-    return getGroup(getParquetSchema().getFieldIndex(field), index);
-  }
-
-  public int getFieldRepetitionCount(int fieldIndex) {
-    List<?> list = data[fieldIndex];
-    return list == null ? 0 : list.size();
-  }
-
-  public String getValueToString(int fieldIndex, int index) {
-    return String.valueOf(getValue(fieldIndex, index));
-  }
-
-  public String getString(int fieldIndex, int index) {
-    return ((BinaryValue) getValue(fieldIndex, index)).getString();
-  }
-
-  public int getInteger(int fieldIndex, int index) {
-    return ((IntegerValue) getValue(fieldIndex, index)).getInteger();
-  }
-
-  public long getLong(int fieldIndex, int index) {
-    return ((LongValue) getValue(fieldIndex, index)).getLong();
-  }
-
-  public double getDouble(int fieldIndex, int index) {
-    return ((DoubleValue) getValue(fieldIndex, index)).getDouble();
-  }
-
-  public float getFloat(int fieldIndex, int index) {
-    return ((FloatValue) getValue(fieldIndex, index)).getFloat();
-  }
-
-  public boolean getBoolean(int fieldIndex, int index) {
-    return ((BooleanValue) getValue(fieldIndex, index)).getBoolean();
-  }
-
-  public Binary getBinary(int fieldIndex, int index) {
-    return ((BinaryValue) getValue(fieldIndex, index)).getBinary();
-  }
-
-  public Binary getInt96(int fieldIndex, int index) {
-    return ((Int96Value) getValue(fieldIndex, index)).getInt96();
-  }
-
-  public Geometry getGeometry(int fieldIndex, int index) {
-    byte[] bytes = ((BinaryValue) getValue(fieldIndex, 
index)).getBinary().getBytes();
-    try {
-      return new WKBReader().read(bytes);
-    } catch (ParseException e) {
-      throw new GeoParquetException("WKBReader failed to parse", e);
-    }
-  }
-
-  private Object getValue(int fieldIndex, int index) {
-    List<?> list = getObjects(fieldIndex);
-    try {
-      return list.get(index);
-    } catch (IndexOutOfBoundsException e) {
-      String elementText = String.format(" element number %d ", index);
-      throw createGeoParquetException(fieldIndex, elementText);
-    }
-  }
-
-  private List<?> getObjects(int fieldIndex) {
-    List<?> list;
-    if (fieldIndex < 0 || fieldIndex >= data.length) {
-      throw createGeoParquetException(fieldIndex, "");
-    }
-    list = data[fieldIndex];
-    return list;
-  }
-
-  private GeoParquetException createGeoParquetException(int fieldIndex, String 
elementText) {
-    String msg = String.format("Not found %d (%s)%s in group%n%s", fieldIndex,
-        schema.getFieldName(fieldIndex), elementText, this);
-    return new GeoParquetException(msg);
-  }
-
-  private void add(int fieldIndex, Primitive value) {
-    org.apache.parquet.schema.Type type = schema.getType(fieldIndex);
-    List list = getObjects(fieldIndex);
-    if (!type.isRepetition(org.apache.parquet.schema.Type.Repetition.REPEATED)
-        && !list.isEmpty()) {
-      throw new IllegalStateException("field " + fieldIndex + " (" + 
type.getName()
-          + ") can not have more than one value: " + list);
-    }
-    list.add(value);
-  }
-
-  public void add(int fieldIndex, int value) {
-    add(fieldIndex, new IntegerValue(value));
-  }
-
-  public void add(int fieldIndex, long value) {
-    add(fieldIndex, new LongValue(value));
-  }
-
-  public void add(int fieldIndex, String value) {
-    add(fieldIndex, new BinaryValue(Binary.fromString(value)));
-  }
-
-  public void add(int fieldIndex, boolean value) {
-    add(fieldIndex, new BooleanValue(value));
-  }
-
-  public void add(int fieldIndex, Binary value) {
-    switch 
(getParquetSchema().getType(fieldIndex).asPrimitiveType().getPrimitiveTypeName())
 {
-      case BINARY, FIXED_LEN_BYTE_ARRAY:
-        add(fieldIndex, new BinaryValue(value));
-        break;
-      case INT96:
-        add(fieldIndex, new Int96Value(value));
-        break;
-      default:
-        throw new UnsupportedOperationException(
-            getParquetSchema().asPrimitiveType().getName() + " not supported 
for Binary");
-    }
-  }
-
-  public void add(int fieldIndex, float value) {
-    add(fieldIndex, new FloatValue(value));
-  }
-
-  public void add(int fieldIndex, double value) {
-    add(fieldIndex, new DoubleValue(value));
-  }
-
-  public void add(int fieldIndex, GeoParquetGroupImpl value) {
-    List list = data[fieldIndex];
-    list.add(value);
-  }
-
-  public void add(int fieldIndex, Geometry geometry) {
-    byte[] bytes = new WKBWriter().write(geometry);
-    add(fieldIndex, Binary.fromConstantByteArray(bytes));
-  }
-
-  public void add(String field, int value) {
-    add(getParquetSchema().getFieldIndex(field), value);
-  }
-
-  public void add(String field, long value) {
-    add(getParquetSchema().getFieldIndex(field), value);
-  }
-
-  public void add(String field, float value) {
-    add(getParquetSchema().getFieldIndex(field), value);
-  }
-
-  public void add(String field, double value) {
-    add(getParquetSchema().getFieldIndex(field), value);
-  }
-
-  public void add(String field, String value) {
-    add(getParquetSchema().getFieldIndex(field), value);
-  }
-
-  public void add(String field, boolean value) {
-    add(getParquetSchema().getFieldIndex(field), value);
-  }
-
-  public void add(String field, Binary value) {
-    add(getParquetSchema().getFieldIndex(field), value);
-  }
-
-  public void add(String field, GeoParquetGroupImpl value) {
-    add(getParquetSchema().getFieldIndex(field), value);
-  }
-
-  public void add(String field, Geometry geometry) {
-    byte[] bytes = new WKBWriter().write(geometry);
-    add(getParquetSchema().getFieldIndex(field), 
Binary.fromConstantByteArray(bytes));
-  }
-
-  public void writeValue(int field, int index, RecordConsumer recordConsumer) {
-    ((Primitive) getValue(field, index)).writeValue(recordConsumer);
-  }
-
-  @Override
-  public String toString() {
-    return toString("");
-  }
-
-  public String toString(String indent) {
-    StringBuilder builder = new StringBuilder();
-    appendToString(builder, indent);
-    return builder.toString();
-  }
-
-  private void appendToString(StringBuilder builder, String indent) {
-    int i = 0;
-    for (org.apache.parquet.schema.Type field : schema.getFields()) {
-      String name = field.getName();
-      List<?> values = data[i];
-      ++i;
-      if (values != null && !values.isEmpty()) {
-        for (Object value : values) {
-          builder.append(indent).append(name);
-          if (value == null) {
-            builder.append(": NULL\n");
-          } else if (value instanceof GeoParquetGroupImpl geoParquetGroupImpl) 
{
-            builder.append('\n');
-            geoParquetGroupImpl.appendToString(builder, indent + "  ");
-          } else {
-            builder.append(": ").append(value).append('\n');
-          }
-        }
-      }
-    }
-  }
-
-  @Override
-  public List<Primitive> getValues(int fieldIndex) {
-    return (List<Primitive>) data[fieldIndex];
-  }
-
-  private List<GeoParquetGroup> getGroups(int fieldIndex) {
-    return (List<GeoParquetGroup>) data[fieldIndex];
-  }
-
-  @Override
-  public Schema getGeoParquetSchema() {
-    return geoParquetSchema;
-  }
-
-  @Override
-  public GroupType getParquetSchema() {
-    return schema;
-  }
-
-  @Override
-  public GeoParquetMetadata getGeoParquetMetadata() {
-    return metadata;
-  }
-
-  @Override
-  public GeoParquetGroupImpl createGroup(int fieldIndex) {
-    if (geoParquetSchema.fields().get(fieldIndex) instanceof EnvelopeField 
envelopeField) {
-      return new GeoParquetGroupImpl(schema.getType(fieldIndex).asGroupType(), 
metadata,
-          envelopeField.schema());
-    }
-
-    if (geoParquetSchema.fields().get(fieldIndex) instanceof GroupField 
groupField) {
-      return new GeoParquetGroupImpl(schema.getType(fieldIndex).asGroupType(), 
metadata,
-          groupField.schema());
-    }
-
-    GroupField field = ((GroupField) 
geoParquetSchema.fields().get(fieldIndex));
-    return new GeoParquetGroupImpl(
-        schema.getType(fieldIndex).asGroupType(),
-        metadata,
-        field.schema());
-  }
-
-  @Override
-  public Binary getBinaryValue(int fieldIndex) {
-    return getBinaryValues(fieldIndex).get(0);
-  }
-
-  @Override
-  public List<Binary> getBinaryValues(int fieldIndex) {
-    return getValues(fieldIndex).stream().map(Primitive::getBinary).toList();
-  }
-
-  @Override
-  public Boolean getBooleanValue(int fieldIndex) {
-    return getBooleanValues(fieldIndex).get(0);
-  }
-
-  @Override
-  public List<Boolean> getBooleanValues(int fieldIndex) {
-    return getValues(fieldIndex).stream().map(Primitive::getBoolean).toList();
-  }
-
-  @Override
-  public Double getDoubleValue(int fieldIndex) {
-    return getDoubleValues(fieldIndex).get(0);
-  }
-
-  @Override
-  public List<Double> getDoubleValues(int fieldIndex) {
-    return getValues(fieldIndex).stream().map(Primitive::getDouble).toList();
-  }
-
-  @Override
-  public Float getFloatValue(int fieldIndex) {
-    return getFloatValues(fieldIndex).get(0);
-  }
-
-  @Override
-  public List<Float> getFloatValues(int fieldIndex) {
-    return getValues(fieldIndex).stream().map(Primitive::getFloat).toList();
-  }
-
-  @Override
-  public Integer getIntegerValue(int fieldIndex) {
-    return getIntegerValues(fieldIndex).get(0);
-  }
-
-  @Override
-  public List<Integer> getIntegerValues(int fieldIndex) {
-    return getValues(fieldIndex).stream().map(Primitive::getInteger).toList();
-  }
-
-  @Override
-  public Binary getInt96Value(int fieldIndex) {
-    return getBinaryValues(fieldIndex).get(0);
-  }
-
-  @Override
-  public List<Binary> getInt96Values(int fieldIndex) {
-    return getValues(fieldIndex).stream().map(Primitive::getBinary).toList();
-  }
-
-  @Override
-  public Binary getNanoTimeValue(int fieldIndex) {
-    return getBinaryValues(fieldIndex).get(0);
-  }
-
-  @Override
-  public List<Binary> getNanoTimeValues(int fieldIndex) {
-    return getValues(fieldIndex).stream().map(Primitive::getBinary).toList();
-  }
-
-  @Override
-  public Long getLongValue(int fieldIndex) {
-    return getLongValues(fieldIndex).get(0);
-  }
-
-  @Override
-  public List<Long> getLongValues(int fieldIndex) {
-    return getValues(fieldIndex).stream().map(Primitive::getLong).toList();
-  }
-
-  @Override
-  public String getStringValue(int fieldIndex) {
-    return getStringValues(fieldIndex).get(0);
-  }
-
-  @Override
-  public List<String> getStringValues(int fieldIndex) {
-    return getValues(fieldIndex).stream().map(Primitive::getString).toList();
-  }
-
-  @Override
-  public Geometry getGeometryValue(int fieldIndex) {
-    return getGeometryValues(fieldIndex).get(0);
-  }
-
-  @Override
-  public List<Geometry> getGeometryValues(int fieldIndex) {
-    List<Geometry> geometries = new ArrayList<>();
-    for (Binary binary : getBinaryValues(fieldIndex)) {
-      try {
-        geometries.add(new WKBReader().read(binary.getBytes()));
-      } catch (ParseException e) {
-        throw new GeoParquetException("WKBReader failed to parse.", e);
-      }
-    }
-    return geometries;
-  }
-
-  @Override
-  public Envelope getEnvelopeValue(int fieldIndex) {
-    return getEnvelopeValues(fieldIndex).get(0);
-  }
-
-  @Override
-  public List<Envelope> getEnvelopeValues(int fieldIndex) {
-    return getGroupValues(fieldIndex).stream().map(group -> {
-      double xMin = 
group.getGeoParquetSchema().fields().get(0).type().equals(Type.FLOAT)
-          ? (double) group.getFloatValue(0)
-          : group.getDoubleValue(0);
-      double yMin = 
group.getGeoParquetSchema().fields().get(1).type().equals(Type.FLOAT)
-          ? (double) group.getFloatValue(1)
-          : group.getDoubleValue(1);
-      double xMax = 
group.getGeoParquetSchema().fields().get(2).type().equals(Type.FLOAT)
-          ? (double) group.getFloatValue(2)
-          : group.getDoubleValue(2);
-      double yMax = 
group.getGeoParquetSchema().fields().get(0).type().equals(Type.FLOAT)
-          ? (double) group.getFloatValue(3)
-          : group.getDoubleValue(3);
-      return new Envelope(xMin, xMax, yMin, yMax);
-    }).toList();
-  }
-
-  @Override
-  public GeoParquetGroup getGroupValue(int fieldIndex) {
-    return getGroupValues(fieldIndex).get(0);
-  }
-
-  @Override
-  public List<GeoParquetGroup> getGroupValues(int fieldIndex) {
-    return getGroups(fieldIndex);
-  }
-
-  @Override
-  public Binary getBinaryValue(String fieldName) {
-    return getBinaryValues(fieldName).get(0);
-  }
-
-  @Override
-  public List<Binary> getBinaryValues(String fieldName) {
-    return getBinaryValues(schema.getFieldIndex(fieldName));
-  }
-
-  @Override
-  public Boolean getBooleanValue(String fieldName) {
-    return getBooleanValues(fieldName).get(0);
-  }
-
-  @Override
-  public List<Boolean> getBooleanValues(String fieldName) {
-    return getBooleanValues(schema.getFieldIndex(fieldName));
-  }
-
-  @Override
-  public Double getDoubleValue(String fieldName) {
-    return getDoubleValues(fieldName).get(0);
-  }
-
-  @Override
-  public List<Double> getDoubleValues(String fieldName) {
-    return getDoubleValues(schema.getFieldIndex(fieldName));
-  }
-
-  @Override
-  public Float getFloatValue(String fieldName) {
-    return getFloatValues(fieldName).get(0);
-  }
-
-  @Override
-  public List<Float> getFloatValues(String fieldName) {
-    return getFloatValues(schema.getFieldIndex(fieldName));
-  }
-
-  @Override
-  public Integer getIntegerValue(String fieldName) {
-    return getIntegerValues(fieldName).get(0);
-  }
-
-  @Override
-  public List<Integer> getIntegerValues(String fieldName) {
-    return getIntegerValues(schema.getFieldIndex(fieldName));
-  }
-
-  @Override
-  public Binary getInt96Value(String fieldName) {
-    return getBinaryValues(fieldName).get(0);
-  }
-
-  @Override
-  public List<Binary> getInt96Values(String fieldName) {
-    return getBinaryValues(schema.getFieldIndex(fieldName));
-  }
-
-  @Override
-  public Binary getNanoTimeValue(String fieldName) {
-    return getBinaryValues(fieldName).get(0);
-  }
-
-  @Override
-  public List<Binary> getNanoTimeValues(String fieldName) {
-    return getBinaryValues(schema.getFieldIndex(fieldName));
-  }
-
-  @Override
-  public Long getLongValue(String fieldName) {
-    return getLongValues(fieldName).get(0);
-  }
-
-  @Override
-  public List<Long> getLongValues(String fieldName) {
-    return getLongValues(schema.getFieldIndex(fieldName));
-  }
-
-  @Override
-  public String getStringValue(String fieldName) {
-    return getStringValues(fieldName).get(0);
-  }
-
-  @Override
-  public List<String> getStringValues(String fieldName) {
-    return getStringValues(schema.getFieldIndex(fieldName));
-  }
-
-  @Override
-  public Geometry getGeometryValue(String fieldName) {
-    return getGeometryValues(fieldName).get(0);
-  }
-
-  @Override
-  public List<Geometry> getGeometryValues(String fieldName) {
-    return getGeometryValues(schema.getFieldIndex(fieldName));
-  }
-
-  @Override
-  public Envelope getEnvelopeValue(String fieldName) {
-    return getEnvelopeValues(fieldName).get(0);
-  }
-
-  @Override
-  public List<Envelope> getEnvelopeValues(String fieldName) {
-    return getEnvelopeValues(schema.getFieldIndex(fieldName));
-  }
-
-  @Override
-  public GeoParquetGroup getGroupValue(String fieldName) {
-    return getGroupValues(fieldName).get(0);
-  }
-
-  @Override
-  public List<GeoParquetGroup> getGroupValues(String fieldName) {
-    return getGroupValues(schema.getFieldIndex(fieldName));
-  }
-
-  @Override
-  public void setBinaryValue(int fieldIndex, Binary binaryValue) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setBinaryValues(int fieldIndex, List<Binary> binaryValues) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setBooleanValue(int fieldIndex, Boolean booleanValue) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setBooleanValues(int fieldIndex, List<Boolean> booleanValues) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setDoubleValue(int fieldIndex, Double doubleValue) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setDoubleValues(int fieldIndex, List<Double> doubleValues) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setFloatValue(int fieldIndex, Float floatValue) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setFloatValues(int fieldIndex, List<Float> floatValues) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setIntegerValue(int fieldIndex, Integer integerValue) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setIntegerValues(int fieldIndex, List<Integer> integerValues) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setInt96Value(int fieldIndex, Binary int96Value) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setInt96Values(int fieldIndex, List<Binary> int96Values) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setNanoTimeValue(int fieldIndex, Binary nanoTimeValue) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setNanoTimeValues(int fieldIndex, List<Binary> nanoTimeValues) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setLongValue(int fieldIndex, Long longValue) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setLongValues(int fieldIndex, List<Long> longValues) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setStringValue(int fieldIndex, String stringValue) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setStringValues(int fieldIndex, List<String> stringValues) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setGeometryValue(int fieldIndex, Geometry geometryValue) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setGeometryValues(int fieldIndex, List<Geometry> geometryValues) 
{
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setEnvelopeValue(int fieldIndex, Envelope envelopeValue) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setEnvelopeValues(int fieldIndex, List<Envelope> envelopeValues) 
{
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setGroupValue(int fieldIndex, GeoParquetGroup groupValue) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setGroupValues(int fieldIndex, List<GeoParquetGroup> 
groupValues) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setBinaryValue(String fieldName, Binary binaryValue) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setBinaryValues(String fieldName, List<Binary> binaryValues) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setBooleanValue(String fieldName, Boolean booleanValue) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setBooleanValues(String fieldName, List<Boolean> booleanValues) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setDoubleValue(String fieldName, Double doubleValue) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setDoubleValues(String fieldName, List<Double> doubleValues) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setFloatValue(String fieldName, Float floatValue) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setFloatValues(String fieldName, List<Float> floatValues) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setIntegerValue(String fieldName, Integer integerValue) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setIntegerValues(String fieldName, List<Integer> integerValues) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setInt96Value(String fieldName, Binary int96Value) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setInt96Values(String fieldName, List<Binary> int96Values) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setNanoTimeValue(String fieldName, Binary nanoTimeValue) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setNanoTimeValues(String fieldName, List<Binary> nanoTimeValues) 
{
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setLongValue(String fieldName, Long longValue) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setLongValues(String fieldName, List<Long> longValues) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setStringValue(String fieldName, String stringValue) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setStringValues(String fieldName, List<String> stringValues) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setGeometryValue(String fieldName, Geometry geometryValue) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setGeometryValues(String fieldName, List<Geometry> 
geometryValues) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setEnvelopeValue(String fieldName, Envelope envelopeValue) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setEnvelopeValues(String fieldName, List<Envelope> 
envelopeValues) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setGroupValue(String fieldName, GeoParquetGroup groupValue) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setGroupValues(String fieldName, List<GeoParquetGroup> 
groupValues) {
-    throw new UnsupportedOperationException();
-  }
-
-}
diff --git 
a/baremaps-geoparquet/src/main/java/org/apache/baremaps/geoparquet/GeoParquetGroupRecordMaterializer.java
 
b/baremaps-geoparquet/src/main/java/org/apache/baremaps/geoparquet/GeoParquetGroupRecordMaterializer.java
index 4583ace8..64c2d339 100644
--- 
a/baremaps-geoparquet/src/main/java/org/apache/baremaps/geoparquet/GeoParquetGroupRecordMaterializer.java
+++ 
b/baremaps-geoparquet/src/main/java/org/apache/baremaps/geoparquet/GeoParquetGroupRecordMaterializer.java
@@ -58,7 +58,7 @@ class GeoParquetGroupRecordMaterializer extends 
RecordMaterializer<GeoParquetGro
   }
 
   @Override
-  public GeoParquetGroupImpl getCurrentRecord() {
+  public GeoParquetGroup getCurrentRecord() {
     return root.getCurrentRecord();
   }
 

Reply via email to