in baremaps-core/src/main/java/org/apache/baremaps/storage/flatgeobuf/FlatGeoBufDataTable.java [151:218]
public void write(Collection<DataRow> features) throws IOException {
try (
var channel = FileChannel.open(file, StandardOpenOption.CREATE, StandardOpenOption.WRITE);
var outputStream = Channels.newOutputStream(channel)) {
outputStream.write(Constants.MAGIC_BYTES);
var bufferBuilder = new FlatBufferBuilder();
var headerMeta = new HeaderMeta();
headerMeta.geometryType = GeometryType.Unknown;
headerMeta.indexNodeSize = 16;
headerMeta.srid = 3857;
headerMeta.featuresCount =
features instanceof AbstractDataCollection<DataRow>c ? c.sizeAsLong() : features.size();
headerMeta.name = rowType.name();
headerMeta.columns = FlatGeoBufTypeConversion.asColumns(rowType.columns());
HeaderMeta.write(headerMeta, outputStream, bufferBuilder);
var indexSize =
(int) PackedRTree.calcSize((int) headerMeta.featuresCount, headerMeta.indexNodeSize);
for (int i = 0; i < indexSize; i++) {
outputStream.write(0);
}
var iterator = features.iterator();
while (iterator.hasNext()) {
var featureBuilder = new FlatBufferBuilder(4096);
var row = iterator.next();
var propertiesBuffer = ByteBuffer.allocate(1 << 20).order(ByteOrder.LITTLE_ENDIAN);
var properties = row.values().stream()
.filter(v -> !(v instanceof Geometry))
.toList();
for (int i = 0; i < properties.size(); i++) {
var column = headerMeta.columns.get(i);
var value = properties.get(i);
propertiesBuffer.putShort((short) i);
FlatGeoBufTypeConversion.writeValue(propertiesBuffer, column, value);
}
if (propertiesBuffer.position() > 0) {
propertiesBuffer.flip();
}
var propertiesOffset = org.wololo.flatgeobuf.generated.Feature
.createPropertiesVector(featureBuilder, propertiesBuffer);
var geometry = row.values().stream()
.filter(v -> v instanceof Geometry)
.map(Geometry.class::cast)
.findFirst();
var geometryOffset = geometry.isPresent()
? GeometryConversions.serialize(featureBuilder, geometry.get(), headerMeta.geometryType)
: 0;
var featureOffset =
org.wololo.flatgeobuf.generated.Feature.createFeature(featureBuilder, geometryOffset,
propertiesOffset, 0);
featureBuilder.finishSizePrefixed(featureOffset);
ByteBuffer data = featureBuilder.dataBuffer();
while (data.hasRemaining()) {
channel.write(data);
}
}
}
}