-
Notifications
You must be signed in to change notification settings - Fork 62
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
364 additions
and
49 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
133 changes: 133 additions & 0 deletions
133
baremaps-geoparquet/src/main/java/org/apache/baremaps/geoparquet/GeoParquetWriteSupport.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
/* | ||
* 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 com.fasterxml.jackson.core.JsonProcessingException; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import org.apache.hadoop.conf.Configuration; | ||
import org.apache.parquet.hadoop.api.WriteSupport; | ||
import org.apache.parquet.io.api.Binary; | ||
import org.apache.parquet.io.api.RecordConsumer; | ||
import org.apache.parquet.schema.*; | ||
|
||
/** | ||
* WriteSupport implementation for writing GeoParquetGroup instances to Parquet. | ||
*/ | ||
public class GeoParquetWriteSupport extends WriteSupport<GeoParquetGroup> { | ||
|
||
private RecordConsumer recordConsumer; | ||
private final MessageType schema; | ||
private final GeoParquetMetadata metadata; | ||
private final ObjectMapper objectMapper = new ObjectMapper(); | ||
|
||
/** | ||
* Constructs a new GeoParquetWriteSupport. | ||
* | ||
* @param schema the Parquet schema | ||
* @param metadata the GeoParquet metadata | ||
*/ | ||
public GeoParquetWriteSupport(MessageType schema, GeoParquetMetadata metadata) { | ||
this.schema = schema; | ||
this.metadata = metadata; | ||
} | ||
|
||
@Override | ||
public WriteContext init(Configuration configuration) { | ||
Map<String, String> extraMetadata = new HashMap<>(); | ||
// Serialize the GeoParquet metadata to JSON and add it to the file metadata | ||
String geoMetadataJson = serializeMetadata(metadata); | ||
extraMetadata.put("geo", geoMetadataJson); | ||
|
||
return new WriteContext(schema, extraMetadata); | ||
} | ||
|
||
@Override | ||
public void prepareForWrite(RecordConsumer recordConsumer) { | ||
this.recordConsumer = recordConsumer; | ||
} | ||
|
||
@Override | ||
public void write(GeoParquetGroup group) { | ||
writeGroup(group, schema); | ||
} | ||
|
||
private void writeGroup(GeoParquetGroup group, GroupType groupType) { | ||
recordConsumer.startMessage(); | ||
for (int i = 0; i < groupType.getFieldCount(); i++) { | ||
Type fieldType = groupType.getType(i); | ||
String fieldName = fieldType.getName(); | ||
int repetitionCount = group.getFieldRepetitionCount(i); | ||
if (repetitionCount == 0) { | ||
continue; // Skip if no values are present | ||
} | ||
for (int j = 0; j < repetitionCount; j++) { | ||
recordConsumer.startField(fieldName, i); | ||
if (fieldType.isPrimitive()) { | ||
Object value = group.getValue(i, j); | ||
writePrimitive(value, fieldType.asPrimitiveType()); | ||
} else { | ||
GeoParquetGroup childGroup = group.getGroup(i, j); | ||
writeGroup(childGroup, fieldType.asGroupType()); | ||
} | ||
recordConsumer.endField(fieldName, i); | ||
} | ||
} | ||
recordConsumer.endMessage(); | ||
} | ||
|
||
private void writePrimitive(Object value, PrimitiveType primitiveType) { | ||
if (value == null) { | ||
// The Parquet format does not support writing null values directly. | ||
// If the field is optional and the value is null, we simply do not write it. | ||
return; | ||
} | ||
switch (primitiveType.getPrimitiveTypeName()) { | ||
case INT32: | ||
recordConsumer.addInteger((Integer) value); | ||
break; | ||
case INT64: | ||
recordConsumer.addLong((Long) value); | ||
break; | ||
case FLOAT: | ||
recordConsumer.addFloat((Float) value); | ||
break; | ||
case DOUBLE: | ||
recordConsumer.addDouble((Double) value); | ||
break; | ||
case BOOLEAN: | ||
recordConsumer.addBoolean((Boolean) value); | ||
break; | ||
case BINARY, FIXED_LEN_BYTE_ARRAY: | ||
recordConsumer.addBinary((Binary) value); | ||
break; | ||
default: | ||
throw new GeoParquetException( | ||
"Unsupported type: " + primitiveType.getPrimitiveTypeName()); | ||
} | ||
} | ||
|
||
private String serializeMetadata(GeoParquetMetadata metadata) { | ||
try { | ||
return objectMapper.writeValueAsString(metadata); | ||
} catch (JsonProcessingException e) { | ||
throw new RuntimeException("Failed to serialize GeoParquet metadata", e); | ||
} | ||
} | ||
} |
76 changes: 76 additions & 0 deletions
76
baremaps-geoparquet/src/main/java/org/apache/baremaps/geoparquet/GeoParquetWriter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
/* | ||
* 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.io.IOException; | ||
import org.apache.hadoop.conf.Configuration; | ||
import org.apache.hadoop.fs.Path; | ||
import org.apache.parquet.column.ParquetProperties.WriterVersion; | ||
import org.apache.parquet.hadoop.ParquetWriter; | ||
import org.apache.parquet.hadoop.metadata.CompressionCodecName; | ||
import org.apache.parquet.schema.MessageType; | ||
|
||
/** | ||
* A writer for GeoParquet files that writes GeoParquetGroup instances to a Parquet file. | ||
*/ | ||
public class GeoParquetWriter implements AutoCloseable { | ||
|
||
private final ParquetWriter<GeoParquetGroup> parquetWriter; | ||
|
||
/** | ||
* Constructs a new GeoParquetWriter. | ||
* | ||
* @param outputFile the output file | ||
* @param schema the Parquet schema | ||
* @param metadata the GeoParquet metadata | ||
* @throws IOException if an I/O error occurs | ||
*/ | ||
public GeoParquetWriter(Path outputFile, MessageType schema, GeoParquetMetadata metadata) | ||
throws IOException { | ||
this.parquetWriter = new ParquetWriter<>( | ||
outputFile, | ||
new GeoParquetWriteSupport(schema, metadata), | ||
CompressionCodecName.UNCOMPRESSED, | ||
ParquetWriter.DEFAULT_BLOCK_SIZE, | ||
ParquetWriter.DEFAULT_PAGE_SIZE, | ||
ParquetWriter.DEFAULT_PAGE_SIZE, | ||
ParquetWriter.DEFAULT_IS_DICTIONARY_ENABLED, | ||
ParquetWriter.DEFAULT_IS_VALIDATING_ENABLED, | ||
WriterVersion.PARQUET_2_0, | ||
new Configuration()); | ||
Check notice Code scanning / CodeQL Deprecated method or constructor invocation Note
Invoking
ParquetWriter.ParquetWriter Error loading related location Loading |
||
} | ||
|
||
/** | ||
* Writes a GeoParquetGroup to the Parquet file. | ||
* | ||
* @param group the GeoParquetGroup to write | ||
* @throws IOException if an I/O error occurs | ||
*/ | ||
public void write(GeoParquetGroup group) throws IOException { | ||
parquetWriter.write(group); | ||
} | ||
|
||
/** | ||
* Closes the writer and releases any system resources associated with it. | ||
* | ||
* @throws IOException if an I/O error occurs | ||
*/ | ||
public void close() throws IOException { | ||
Check notice Code scanning / CodeQL Missing Override annotation Note
This method overrides
AutoCloseable.close Error loading related location Loading |
||
parquetWriter.close(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.