This is an automated email from the ASF dual-hosted git repository. bchapuis pushed a commit to branch flatgeobuf in repository https://gitbox.apache.org/repos/asf/incubator-baremaps.git
commit 9cfaf568433a1bf5306189b08ba2709c8de2b32c Author: Bertil Chapuis <[email protected]> AuthorDate: Tue Jun 18 14:25:37 2024 +0200 Improve implementation --- .../src/main/{resources => }/fbs/feature.fbs | 0 .../src/main/{resources => }/fbs/header.fbs | 0 .../baremaps/flatgeobuf/BoundedInputStream.java | 74 ---------- .../org/apache/baremaps/flatgeobuf/Constants.java | 37 ----- .../org/apache/baremaps/flatgeobuf/FlatGeoBuf.java | 128 +++------------- .../{FlatGeoBuf.java => FlatGeoBufMapper.java} | 163 +++++++-------------- .../baremaps/flatgeobuf/FlatGeoBufReader.java | 121 ++++++++------- .../baremaps/flatgeobuf/GeometryConversions.java | 2 +- .../apache/baremaps/flatgeobuf/FlatGeoBufTest.java | 38 +++-- 9 files changed, 165 insertions(+), 398 deletions(-) diff --git a/baremaps-flatgeobuf/src/main/resources/fbs/feature.fbs b/baremaps-flatgeobuf/src/main/fbs/feature.fbs similarity index 100% rename from baremaps-flatgeobuf/src/main/resources/fbs/feature.fbs rename to baremaps-flatgeobuf/src/main/fbs/feature.fbs diff --git a/baremaps-flatgeobuf/src/main/resources/fbs/header.fbs b/baremaps-flatgeobuf/src/main/fbs/header.fbs similarity index 100% rename from baremaps-flatgeobuf/src/main/resources/fbs/header.fbs rename to baremaps-flatgeobuf/src/main/fbs/header.fbs diff --git a/baremaps-flatgeobuf/src/main/java/org/apache/baremaps/flatgeobuf/BoundedInputStream.java b/baremaps-flatgeobuf/src/main/java/org/apache/baremaps/flatgeobuf/BoundedInputStream.java deleted file mode 100644 index 38b91bf5..00000000 --- a/baremaps-flatgeobuf/src/main/java/org/apache/baremaps/flatgeobuf/BoundedInputStream.java +++ /dev/null @@ -1,74 +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.flatgeobuf; - -import java.io.IOException; -import java.io.InputStream; - -public class BoundedInputStream extends InputStream { - private final InputStream in; - private long remaining; - - public BoundedInputStream(InputStream in, long size) { - this.in = in; - this.remaining = size; - } - - @Override - public int read() throws IOException { - if (remaining == 0) { - return -1; - } - int result = in.read(); - if (result != -1) { - remaining--; - } - return result; - } - - @Override - public int read(byte[] b, int off, int len) throws IOException { - if (remaining == 0) { - return -1; - } - int toRead = (int) Math.min(len, remaining); - int result = in.read(b, off, toRead); - if (result != -1) { - remaining -= result; - } - return result; - } - - @Override - public long skip(long n) throws IOException { - long toSkip = Math.min(n, remaining); - long skipped = in.skip(toSkip); - remaining -= skipped; - return skipped; - } - - @Override - public int available() throws IOException { - return (int) Math.min(in.available(), remaining); - } - - @Override - public void close() throws IOException { - in.close(); - } -} diff --git a/baremaps-flatgeobuf/src/main/java/org/apache/baremaps/flatgeobuf/Constants.java b/baremaps-flatgeobuf/src/main/java/org/apache/baremaps/flatgeobuf/Constants.java deleted file mode 100644 index 1a15e1b7..00000000 --- a/baremaps-flatgeobuf/src/main/java/org/apache/baremaps/flatgeobuf/Constants.java +++ /dev/null @@ -1,37 +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.flatgeobuf; - -import java.nio.ByteBuffer; - -public class Constants { - - public static final byte[] MAGIC_BYTES = - new byte[] {0x66, 0x67, 0x62, 0x03, 0x66, 0x67, 0x62, 0x00}; - - public static boolean isFlatgeobuf(ByteBuffer bb) { - return bb.get() == MAGIC_BYTES[0] && - bb.get() == MAGIC_BYTES[1] && - bb.get() == MAGIC_BYTES[2] && - bb.get() == MAGIC_BYTES[3] && - bb.get() == MAGIC_BYTES[4] && - bb.get() == MAGIC_BYTES[5] && - bb.get() == MAGIC_BYTES[6] && - bb.get() == MAGIC_BYTES[7]; - } -} diff --git a/baremaps-flatgeobuf/src/main/java/org/apache/baremaps/flatgeobuf/FlatGeoBuf.java b/baremaps-flatgeobuf/src/main/java/org/apache/baremaps/flatgeobuf/FlatGeoBuf.java index 0a07db14..1712b321 100644 --- a/baremaps-flatgeobuf/src/main/java/org/apache/baremaps/flatgeobuf/FlatGeoBuf.java +++ b/baremaps-flatgeobuf/src/main/java/org/apache/baremaps/flatgeobuf/FlatGeoBuf.java @@ -18,20 +18,30 @@ package org.apache.baremaps.flatgeobuf; import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; import java.util.List; -import java.util.stream.IntStream; -import org.apache.baremaps.flatgeobuf.FlatGeoBuf.Header.Feature; import org.locationtech.jts.geom.Geometry; public class FlatGeoBuf { - private FlatGeoBuf() { + public static final byte[] MAGIC_BYTES = + new byte[] {0x66, 0x67, 0x62, 0x03, 0x66, 0x67, 0x62, 0x00}; + + private FlatGeoBuf() { // Prevent instantiation } - // Geometry type enumeration + public static boolean isFlatgeobuf(ByteBuffer bb) { + return bb.get() == MAGIC_BYTES[0] && + bb.get() == MAGIC_BYTES[1] && + bb.get() == MAGIC_BYTES[2] && + bb.get() == MAGIC_BYTES[3] && + bb.get() == MAGIC_BYTES[4] && + bb.get() == MAGIC_BYTES[5] && + bb.get() == MAGIC_BYTES[6] && + bb.get() == MAGIC_BYTES[7]; + } + + // Geometry type enumeration public enum GeometryType { UNKNOWN(0), POINT(1), @@ -122,110 +132,10 @@ public class FlatGeoBuf { public Header { indexNodeSize = indexNodeSize == 0 ? 16 : indexNodeSize; } - - public record Feature( - Geometry geometry, - List<Object> properties) { - } - } - - public static Header asHeaderRecord(org.apache.baremaps.flatgeobuf.generated.Header header) { - return new Header( - header.name(), - new double[] { - header.envelope(0), - header.envelope(1), - header.envelope(2), - header.envelope(3) - }, - GeometryType.values()[header.geometryType()], - header.hasZ(), - header.hasM(), - header.hasT(), - header.hasTm(), - IntStream.range(0, header.columnsLength()) - .mapToObj(header::columns) - .map(column -> new Column( - column.name(), - ColumnType.values()[column.type()], - column.title(), - column.description(), - column.width(), - column.precision(), - column.scale(), - column.nullable(), - column.unique(), - column.primaryKey(), - column.metadata())) - .toList(), - header.featuresCount(), - header.indexNodeSize(), - new Crs( - header.crs().org(), - header.crs().code(), - header.crs().name(), - header.crs().description(), - header.crs().wkt(), - header.crs().codeString()), - header.title(), - header.description(), - header.metadata()); - } - - public static Feature asFeatureRecord(org.apache.baremaps.flatgeobuf.generated.Header header, - org.apache.baremaps.flatgeobuf.generated.Feature feature) { - var values = new ArrayList<>(); - if (feature.propertiesLength() > 0) { - var propertiesBuffer = feature.propertiesAsByteBuffer(); - while (propertiesBuffer.hasRemaining()) { - var columnPosition = propertiesBuffer.getShort(); - var columnType = header.columns(columnPosition); - var columnValue = readValue(propertiesBuffer, columnType); - values.add(columnValue); - } - } - return new Feature( - GeometryConversions.readGeometry(feature.geometry(), header.geometryType()), - values); - } - - private static Object readValue(ByteBuffer buffer, - org.apache.baremaps.flatgeobuf.generated.Column column) { - return switch (ColumnType.values()[column.type()]) { - case BYTE -> buffer.get(); - case UBYTE -> buffer.get(); - case BOOL -> buffer.get() == 1; - case SHORT -> buffer.getShort(); - case USHORT -> buffer.getShort(); - case INT -> buffer.getInt(); - case UINT -> buffer.getInt(); - case LONG -> buffer.getLong(); - case ULONG -> buffer.getLong(); - case FLOAT -> buffer.getFloat(); - case DOUBLE -> buffer.getDouble(); - case STRING -> readString(buffer); - case JSON -> readJson(buffer); - case DATETIME -> readDateTime(buffer); - case BINARY -> readBinary(buffer); - }; - } - - private static Object readString(ByteBuffer buffer) { - var length = buffer.getInt(); - var bytes = new byte[length]; - buffer.get(bytes); - return new String(bytes, StandardCharsets.UTF_8); - } - - private static Object readJson(ByteBuffer buffer) { - throw new UnsupportedOperationException(); - } - - private static Object readDateTime(ByteBuffer buffer) { - throw new UnsupportedOperationException(); } - private static Object readBinary(ByteBuffer buffer) { - throw new UnsupportedOperationException(); + public record Feature( + Geometry geometry, + List<Object> properties) { } } diff --git a/baremaps-flatgeobuf/src/main/java/org/apache/baremaps/flatgeobuf/FlatGeoBuf.java b/baremaps-flatgeobuf/src/main/java/org/apache/baremaps/flatgeobuf/FlatGeoBufMapper.java similarity index 60% copy from baremaps-flatgeobuf/src/main/java/org/apache/baremaps/flatgeobuf/FlatGeoBuf.java copy to baremaps-flatgeobuf/src/main/java/org/apache/baremaps/flatgeobuf/FlatGeoBufMapper.java index 0a07db14..81165398 100644 --- a/baremaps-flatgeobuf/src/main/java/org/apache/baremaps/flatgeobuf/FlatGeoBuf.java +++ b/baremaps-flatgeobuf/src/main/java/org/apache/baremaps/flatgeobuf/FlatGeoBufMapper.java @@ -14,123 +14,67 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.apache.baremaps.flatgeobuf; +import com.google.flatbuffers.FlatBufferBuilder; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.ArrayList; -import java.util.List; import java.util.stream.IntStream; -import org.apache.baremaps.flatgeobuf.FlatGeoBuf.Header.Feature; -import org.locationtech.jts.geom.Geometry; +import org.apache.baremaps.flatgeobuf.generated.Column; +import org.apache.baremaps.flatgeobuf.generated.Feature; +import org.apache.baremaps.flatgeobuf.generated.Header; -public class FlatGeoBuf { +public class FlatGeoBufMapper { - private FlatGeoBuf() { + private FlatGeoBufMapper() { // Prevent instantiation } - // Geometry type enumeration - public enum GeometryType { - UNKNOWN(0), - POINT(1), - LINESTRING(2), - POLYGON(3), - MULTIPOINT(4), - MULTILINESTRING(5), - MULTIPOLYGON(6), - GEOMETRYCOLLECTION(7), - CIRCULARSTRING(8), - COMPOUNDCURVE(9), - CURVEPOLYGON(10), - MULTICURVE(11), - MULTISURFACE(12), - CURVE(13), - SURFACE(14), - POLYHEDRALSURFACE(15), - TIN(16), - TRIANGLE(17); - - private final int value; - - GeometryType(int value) { - this.value = value; + public static Header asHeaderFlatGeoBuf(FlatGeoBuf.Header header) { + var builder = new FlatBufferBuilder(); + int[] columnsArray = header.columns().stream().mapToInt(c -> { + int nameOffset = builder.createString(c.name()); + int type = c.type().ordinal(); + return org.apache.baremaps.flatgeobuf.generated.Column.createColumn( + builder, nameOffset, type, 0, 0, c.width(), c.precision(), c.scale(), c.nullable(), + c.unique(), + c.primaryKey(), 0); + }).toArray(); + int columnsOffset = + org.apache.baremaps.flatgeobuf.generated.Header.createColumnsVector(builder, columnsArray); + + int nameOffset = 0; + if (header.name() != null) { + nameOffset = builder.createString(header.name()); } - - public int getValue() { - return value; - } - } - - public enum ColumnType { - BYTE, - UBYTE, - BOOL, - SHORT, - USHORT, - INT, - UINT, - LONG, - ULONG, - FLOAT, - DOUBLE, - STRING, - JSON, - DATETIME, - BINARY - } - - public record Column( - String name, - ColumnType type, - String title, - String description, - int width, - int precision, - int scale, - boolean nullable, - boolean unique, - boolean primaryKey, - String metadata) { - } - - public record Crs( - String org, - int code, - String name, - String description, - String wkt, - String codeString) { - } - - public record Header( - String name, - double[] envelope, - GeometryType geometryType, - boolean hasZ, - boolean hasM, - boolean hasT, - boolean hasTM, - List<Column> columns, - long featuresCount, - int indexNodeSize, - Crs crs, - String title, - String description, - String metadata) { - public Header { - indexNodeSize = indexNodeSize == 0 ? 16 : indexNodeSize; + int crsOffset = 0; + if (header.crs().code() != 0) { + org.apache.baremaps.flatgeobuf.generated.Crs.startCrs(builder); + org.apache.baremaps.flatgeobuf.generated.Crs.addCode(builder, header.crs().code()); + crsOffset = org.apache.baremaps.flatgeobuf.generated.Crs.endCrs(builder); } - - public record Feature( - Geometry geometry, - List<Object> properties) { + int envelopeOffset = 0; + if (header.envelope() != null) { + envelopeOffset = Header.createEnvelopeVector(builder, header.envelope()); } + Header.startHeader(builder); + Header.addGeometryType(builder, header.geometryType().getValue()); + Header.addIndexNodeSize(builder, header.indexNodeSize()); + Header.addColumns(builder, columnsOffset); + Header.addEnvelope(builder, envelopeOffset); + Header.addName(builder, nameOffset); + Header.addCrs(builder, crsOffset); + Header.addFeaturesCount(builder, header.featuresCount()); + int offset = Header.endHeader(builder); + + builder.finishSizePrefixed(offset); + + return Header.getRootAsHeader(builder.dataBuffer()); } - public static Header asHeaderRecord(org.apache.baremaps.flatgeobuf.generated.Header header) { - return new Header( + public static FlatGeoBuf.Header asHeaderRecord(Header header) { + return new FlatGeoBuf.Header( header.name(), new double[] { header.envelope(0), @@ -138,16 +82,16 @@ public class FlatGeoBuf { header.envelope(2), header.envelope(3) }, - GeometryType.values()[header.geometryType()], + FlatGeoBuf.GeometryType.values()[header.geometryType()], header.hasZ(), header.hasM(), header.hasT(), header.hasTm(), IntStream.range(0, header.columnsLength()) .mapToObj(header::columns) - .map(column -> new Column( + .map(column -> new FlatGeoBuf.Column( column.name(), - ColumnType.values()[column.type()], + FlatGeoBuf.ColumnType.values()[column.type()], column.title(), column.description(), column.width(), @@ -160,7 +104,7 @@ public class FlatGeoBuf { .toList(), header.featuresCount(), header.indexNodeSize(), - new Crs( + new FlatGeoBuf.Crs( header.crs().org(), header.crs().code(), header.crs().name(), @@ -172,8 +116,7 @@ public class FlatGeoBuf { header.metadata()); } - public static Feature asFeatureRecord(org.apache.baremaps.flatgeobuf.generated.Header header, - org.apache.baremaps.flatgeobuf.generated.Feature feature) { + public static FlatGeoBuf.Feature asFeatureRecord(Header header, Feature feature) { var values = new ArrayList<>(); if (feature.propertiesLength() > 0) { var propertiesBuffer = feature.propertiesAsByteBuffer(); @@ -184,14 +127,14 @@ public class FlatGeoBuf { values.add(columnValue); } } - return new Feature( + return new FlatGeoBuf.Feature( GeometryConversions.readGeometry(feature.geometry(), header.geometryType()), values); } private static Object readValue(ByteBuffer buffer, - org.apache.baremaps.flatgeobuf.generated.Column column) { - return switch (ColumnType.values()[column.type()]) { + Column column) { + return switch (FlatGeoBuf.ColumnType.values()[column.type()]) { case BYTE -> buffer.get(); case UBYTE -> buffer.get(); case BOOL -> buffer.get() == 1; diff --git a/baremaps-flatgeobuf/src/main/java/org/apache/baremaps/flatgeobuf/FlatGeoBufReader.java b/baremaps-flatgeobuf/src/main/java/org/apache/baremaps/flatgeobuf/FlatGeoBufReader.java index f59b9397..2b62cf3f 100644 --- a/baremaps-flatgeobuf/src/main/java/org/apache/baremaps/flatgeobuf/FlatGeoBufReader.java +++ b/baremaps-flatgeobuf/src/main/java/org/apache/baremaps/flatgeobuf/FlatGeoBufReader.java @@ -19,6 +19,7 @@ package org.apache.baremaps.flatgeobuf; import java.io.IOException; import java.io.InputStream; +import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.channels.Channels; @@ -34,7 +35,7 @@ public class FlatGeoBufReader { // Check if the file is a flatgeobuf ByteBuffer buffer = BufferUtil.createByteBuffer(12, ByteOrder.LITTLE_ENDIAN); BufferUtil.readBytes(channel, buffer, 12); - if (!Constants.isFlatgeobuf(buffer)) { + if (!FlatGeoBuf.isFlatgeobuf(buffer)) { throw new IOException("This is not a flatgeobuf!"); } @@ -54,7 +55,6 @@ public class FlatGeoBufReader { public static ByteBuffer readIndexAsBuffer(ReadableByteChannel channel, Header header) throws IOException { long indexSize = PackedRTree.calcSize(header.featuresCount(), header.indexNodeSize()); - if (indexSize > 1L << 31) { throw new IOException("Index size is greater than 2GB!"); } @@ -71,61 +71,68 @@ public class FlatGeoBufReader { public static Feature readFeature(ReadableByteChannel channel, ByteBuffer buffer) throws IOException { - ByteBuffer newBuffer = BufferUtil.readBytes(channel, buffer, 4); - int featureSize = newBuffer.getInt(); - newBuffer = BufferUtil.readBytes(channel, buffer, featureSize); - Feature feature = Feature.getRootAsFeature(newBuffer); - buffer.position(buffer.position() + featureSize); - return feature; + try { + ByteBuffer newBuffer = BufferUtil.readBytes(channel, buffer, 4); + int featureSize = newBuffer.getInt(); + newBuffer = BufferUtil.readBytes(channel, buffer, featureSize); + Feature feature = Feature.getRootAsFeature(newBuffer); + buffer.position(buffer.position() + featureSize); + return feature; + } catch (IOException | BufferUnderflowException e) { + throw new IOException("Error reading feature", e); + } } - // var geometryBuffer = feature.geometry(); - // var geometry = GeometryConversions.readGeometry(geometryBuffer, geometryBuffer.type()); - // var properties = new ArrayList<>(); - // if (feature.propertiesLength() > 0) { - // var propertiesBuffer = feature.propertiesAsByteBuffer(); - // while (propertiesBuffer.hasRemaining()) { - // var type = propertiesBuffer.getShort(); - // var column = header.columns.get(type); - // var value = readColumnValue(propertiesBuffer, column); - // properties.add(value); - // } - // } - // } - // - // public static Object readColumnValue(ByteBuffer buffer, ColumnMeta column) { - // return switch (column.type()) { - // case ColumnType.Byte -> buffer.get(); - // case ColumnType.Bool -> buffer.get() == 1; - // case ColumnType.Short -> buffer.getShort(); - // case ColumnType.Int -> buffer.getInt(); - // case ColumnType.Long -> buffer.getLong(); - // case ColumnType.Float -> buffer.getFloat(); - // case ColumnType.Double -> buffer.getDouble(); - // case ColumnType.String -> readColumnString(buffer); - // case ColumnType.Json -> readColumnJson(buffer); - // case ColumnType.DateTime -> readColumnDateTime(buffer); - // case ColumnType.Binary -> readColumnBinary(buffer); - // default -> null; - // }; - // } - // - // public static Object readColumnString(ByteBuffer buffer) { - // var length = buffer.getInt(); - // var bytes = new byte[length]; - // buffer.get(bytes); - // return new String(bytes, StandardCharsets.UTF_8); - // } - // - // public static Object readColumnJson(ByteBuffer buffer) { - // throw new UnsupportedOperationException(); - // } - // - // public static Object readColumnDateTime(ByteBuffer buffer) { - // throw new UnsupportedOperationException(); - // } - // - // public static Object readColumnBinary(ByteBuffer buffer) { - // throw new UnsupportedOperationException(); - // } + private static class BoundedInputStream extends InputStream { + private final InputStream in; + private long remaining; + + private BoundedInputStream(InputStream in, long size) { + this.in = in; + this.remaining = size; + } + + @Override + public int read() throws IOException { + if (remaining == 0) { + return -1; + } + int result = in.read(); + if (result != -1) { + remaining--; + } + return result; + } + + @Override + public int read(byte[] b, int off, int len) throws IOException { + if (remaining == 0) { + return -1; + } + int toRead = (int) Math.min(len, remaining); + int result = in.read(b, off, toRead); + if (result != -1) { + remaining -= result; + } + return result; + } + + @Override + public long skip(long n) throws IOException { + long toSkip = Math.min(n, remaining); + long skipped = in.skip(toSkip); + remaining -= skipped; + return skipped; + } + + @Override + public int available() throws IOException { + return (int) Math.min(in.available(), remaining); + } + + @Override + public void close() throws IOException { + in.close(); + } + } } diff --git a/baremaps-flatgeobuf/src/main/java/org/apache/baremaps/flatgeobuf/GeometryConversions.java b/baremaps-flatgeobuf/src/main/java/org/apache/baremaps/flatgeobuf/GeometryConversions.java index 359b9e79..7d6efeab 100644 --- a/baremaps-flatgeobuf/src/main/java/org/apache/baremaps/flatgeobuf/GeometryConversions.java +++ b/baremaps-flatgeobuf/src/main/java/org/apache/baremaps/flatgeobuf/GeometryConversions.java @@ -31,7 +31,7 @@ public class GeometryConversions { public static GeometryOffsets writeGeometryPart( FlatBufferBuilder builder, org.locationtech.jts.geom.Geometry geometry, - int geometryType) throws IOException { + int geometryType) { GeometryOffsets go = new GeometryOffsets(); diff --git a/baremaps-flatgeobuf/src/test/java/org/apache/baremaps/flatgeobuf/FlatGeoBufTest.java b/baremaps-flatgeobuf/src/test/java/org/apache/baremaps/flatgeobuf/FlatGeoBufTest.java index 03401dd5..cbcb949d 100644 --- a/baremaps-flatgeobuf/src/test/java/org/apache/baremaps/flatgeobuf/FlatGeoBufTest.java +++ b/baremaps-flatgeobuf/src/test/java/org/apache/baremaps/flatgeobuf/FlatGeoBufTest.java @@ -17,14 +17,15 @@ package org.apache.baremaps.flatgeobuf; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.*; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.channels.FileChannel; import java.nio.file.StandardOpenOption; +import java.util.ArrayList; +import java.util.List; import org.apache.baremaps.flatgeobuf.generated.Feature; import org.apache.baremaps.flatgeobuf.generated.Header; import org.apache.baremaps.testing.TestFiles; @@ -52,25 +53,42 @@ public class FlatGeoBufTest { assertNotNull(header); assertEquals(179, header.featuresCount()); + FlatGeoBuf.Header headerRecord = FlatGeoBufMapper.asHeaderRecord(header); + assertNotNull(headerRecord); + assertEquals(179, headerRecord.featuresCount()); + // Read the index FlatGeoBufReader.skipIndex(channel, header); // Read the first feature ByteBuffer buffer = BufferUtil.createByteBuffer(1 << 16, ByteOrder.LITTLE_ENDIAN); + List<FlatGeoBuf.Feature> featureList = new ArrayList<>(); for (int i = 0; i < header.featuresCount(); i++) { Feature feature = FlatGeoBufReader.readFeature(channel, buffer); - - System.out.println(FlatGeoBuf.asFeatureRecord(header, feature)); - + featureList.add(FlatGeoBufMapper.asFeatureRecord(header, feature)); assertNotNull(feature); } - } - } + // Check the first feature + FlatGeoBuf.Feature firstFeature = featureList.get(0); + assertNotNull(firstFeature); + assertEquals(2, firstFeature.properties().size()); + assertEquals("ATA", firstFeature.properties().get(0)); + assertEquals("Antarctica", firstFeature.properties().get(1)); + assertNotNull(firstFeature.geometry()); + assertEquals(658, firstFeature.geometry().getNumPoints()); + + // Check the last feature + FlatGeoBuf.Feature lastFeature = featureList.get(178); + assertNotNull(lastFeature); + assertEquals(2, lastFeature.properties().size()); + assertEquals("FLK", lastFeature.properties().get(0)); + assertEquals("Falkland Islands", lastFeature.properties().get(1)); + assertNotNull(lastFeature.geometry()); + assertEquals(10, lastFeature.geometry().getNumPoints()); - public static void main(String... args) { - System.out.println(Long.MAX_VALUE); - System.out.println(Long.MAX_VALUE >> 32); + assertThrows(IOException.class, () -> FlatGeoBufReader.readFeature(channel, buffer)); + } } }
