private FilterPredicate createEnvelopeFilter()

in baremaps-geoparquet/src/main/java/org/apache/baremaps/geoparquet/GeoParquetSpliterator.java [163:223]


  private FilterPredicate createEnvelopeFilter(MessageType schema, Envelope envelope) {
    // Check whether the envelope is null or the world
    if (envelope == null
        || envelope.isNull()
        || envelope.equals(new Envelope(-180, 180, -90, 90))) {
      return null;
    }

    // Check whether the schema has a bbox field
    Type type = schema.getType("bbox");
    if (type == null) {
      return null;
    }

    // Check whether the bbox has the xmin, ymin, xmax, ymax fields
    GroupType bbox = type.asGroupType();
    if (bbox.getFieldCount() != 4
        || !bbox.containsField("xmin")
        || !bbox.containsField("ymin")
        || !bbox.containsField("xmax")
        || !bbox.containsField("ymax")) {
      return null;
    }

    // Check whether all fields are primitive types
    List<Type> types = bbox.getFields();
    if (types.stream().anyMatch(t -> !t.isPrimitive())) {
      return null;
    }

    // Check whether all fields are of the same type
    List<PrimitiveTypeName> typeNames = types.stream()
        .map(t -> t.asPrimitiveType().getPrimitiveTypeName())
        .toList();
    PrimitiveTypeName typeName = typeNames.get(0);
    if (!typeNames.stream().allMatch(typeName::equals)) {
      return null;
    }

    // Check whether the type is a float or a double
    if (typeName != PrimitiveTypeName.DOUBLE && typeName != PrimitiveTypeName.FLOAT) {
      return null;
    }

    // Initialize the filter predicate creator for the given type
    BiFunction<String, Number, FilterPredicate> filterPredicateCreator =
        (column, value) -> switch (typeName) {
        case DOUBLE -> FilterApi.gtEq(FilterApi.doubleColumn(column), value.doubleValue());
        case FLOAT -> FilterApi.gtEq(FilterApi.floatColumn(column), value.floatValue());
        default -> throw new IllegalStateException("Unexpected value: " + typeName);
        };

    // Create the filter predicate
    return FilterApi.and(
        FilterApi.and(
            filterPredicateCreator.apply("bbox.xmin", envelope.getMinX()),
            filterPredicateCreator.apply("bbox.xmax", envelope.getMaxX())),
        FilterApi.and(
            filterPredicateCreator.apply("bbox.ymin", envelope.getMinY()),
            filterPredicateCreator.apply("bbox.ymax", envelope.getMaxY())));
  }