Skip to content

Commit

Permalink
Add data schema and table for geoparquet
Browse files Browse the repository at this point in the history
  • Loading branch information
bchapuis committed May 28, 2024
1 parent 455dccc commit 91e3263
Show file tree
Hide file tree
Showing 16 changed files with 451 additions and 23 deletions.
4 changes: 4 additions & 0 deletions baremaps-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ limitations under the License.
<groupId>org.apache.baremaps</groupId>
<artifactId>baremaps-data</artifactId>
</dependency>
<dependency>
<groupId>org.apache.baremaps</groupId>
<artifactId>baremaps-geoparquet</artifactId>
</dependency>
<dependency>
<groupId>org.apache.baremaps</groupId>
<artifactId>baremaps-maplibre</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collection;
import java.util.List;
import org.apache.baremaps.data.schema.DataSchema;
import org.apache.baremaps.data.schema.DataTable;
import org.apache.baremaps.data.schema.DataTableException;
Expand All @@ -40,7 +40,7 @@ public FlatGeoBufDataSchema(Path directory) {
* {@inheritDoc}
*/
@Override
public Collection<String> list() throws DataTableException {
public List<String> list() throws DataTableException {
try (var files = Files.list(directory)) {
return files
.filter(file -> file.toString().toLowerCase().endsWith(".fgb"))
Expand All @@ -67,7 +67,12 @@ public DataTable get(String name) throws DataTableException {
public void add(DataTable table) throws DataTableException {
var filename = table.rowType().name();
filename = filename.endsWith(".fgb") ? filename : filename + ".fgb";
var path = directory.resolve(filename);
add(filename, table);
}

@Override
public void add(String name, DataTable table) throws DataTableException {
var path = directory.resolve(name);
try {
Files.deleteIfExists(path);
Files.createFile(path);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@


import java.nio.file.Path;
import java.util.Collection;
import java.util.List;
import mil.nga.geopackage.GeoPackage;
import mil.nga.geopackage.GeoPackageManager;
import org.apache.baremaps.data.schema.DataSchema;
Expand Down Expand Up @@ -54,7 +54,7 @@ public void close() throws Exception {
* {@inheritDoc}
*/
@Override
public Collection<String> list() throws DataTableException {
public List<String> list() throws DataTableException {
return geoPackage.getFeatureTables();
}

Expand All @@ -70,7 +70,12 @@ public DataTable get(String name) throws DataTableException {
* {@inheritDoc}
*/
@Override
public void add(DataTable value) throws DataTableException {
public void add(DataTable table) throws DataTableException {
throw new UnsupportedOperationException();
}

@Override
public void add(String name, DataTable table) throws DataTableException {
throw new UnsupportedOperationException();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* 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.storage.geoparquet;


import java.net.URI;
import java.util.List;
import org.apache.baremaps.data.schema.DataSchema;
import org.apache.baremaps.data.schema.DataTable;
import org.apache.baremaps.data.schema.DataTableException;

/**
* A schema corresponding to a GeoPackage database.
*/
public class GeoParquetDataSchema implements DataSchema, AutoCloseable {

private final URI uri;

public GeoParquetDataSchema(URI uri) {
this.uri = uri;
}

@Override
public void close() throws Exception {

}

@Override
public List<String> list() throws DataTableException {
return List.of(uri.toString());
}

@Override
public DataTable get(String name) throws DataTableException {
if (!uri.toString().equals(name)) {
throw new DataTableException("Table not found");
}
return new GeoParquetTable(uri);
}

@Override
public void add(DataTable table) throws DataTableException {
throw new UnsupportedOperationException();
}

@Override
public void add(String name, DataTable table) throws DataTableException {
throw new UnsupportedOperationException();
}

@Override
public void remove(String name) throws DataTableException {
throw new UnsupportedOperationException();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* 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.storage.geoparquet;

import java.net.URI;
import java.util.Iterator;
import java.util.Spliterator;
import java.util.stream.Stream;
import org.apache.baremaps.data.schema.*;
import org.apache.baremaps.geoparquet.GeoParquetReader;
import org.apache.baremaps.geoparquet.data.GeoParquetGroup.Schema;

public class GeoParquetTable implements DataTable {

private final URI path;

private DataRowType rowType;

public GeoParquetTable(URI path) {
this.path = path;
}

@Override
public long size() {
return Long.MAX_VALUE;
}

@Override
public Iterator<DataRow> iterator() {
return parallelStream().iterator();
}

public Spliterator<DataRow> spliterator() {

Check notice

Code scanning / CodeQL

Missing Override annotation Note

This method overrides
DataCollection.spliterator
; it is advisable to add an Override annotation.
return parallelStream().spliterator();
}

@Override
public Stream<DataRow> stream() {
return parallelStream().sequential();
}

@Override
public Stream<DataRow> parallelStream() {
try {
return new GeoParquetReader(path).read().map(group -> new DataRowImpl(
GeoParquetTypeConversion.asDataRowType(path.toString(), group.getSchema()),
GeoParquetTypeConversion.asDataRow(group)));
} catch (Exception e) {
throw new RuntimeException(e);
}
}

@Override
public void clear() {

}

@Override
public DataRowType rowType() {
if (rowType == null) {
try {
GeoParquetReader reader = new GeoParquetReader(path);
Schema schema = reader.getGeoParquetSchema();
rowType = GeoParquetTypeConversion.asDataRowType(path.toString(), schema);
return rowType;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return rowType;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* 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.storage.geoparquet;

import java.util.ArrayList;
import java.util.List;
import org.apache.baremaps.data.schema.DataColumn;
import org.apache.baremaps.data.schema.DataColumn.Type;
import org.apache.baremaps.data.schema.DataColumnImpl;
import org.apache.baremaps.data.schema.DataRowType;
import org.apache.baremaps.data.schema.DataRowTypeImpl;
import org.apache.baremaps.geoparquet.data.GeoParquetGroup;
import org.apache.baremaps.geoparquet.data.GeoParquetGroup.Field;
import org.apache.baremaps.geoparquet.data.GeoParquetGroup.Schema;

public class GeoParquetTypeConversion {

public static DataRowType asDataRowType(String table, Schema schema) {
List<DataColumn> fields = schema.fields().stream()
.map(field -> (DataColumn) new DataColumnImpl(field.name(), asDataRowType(field.type())))
.toList();
return new DataRowTypeImpl(table, fields);
}

public static Type asDataRowType(GeoParquetGroup.Type type) {
return switch (type) {
case BINARY -> Type.BYTE_ARRAY;
case BOOLEAN -> Type.BOOLEAN;
case INTEGER -> Type.INTEGER;
case INT96 -> Type.LONG;
case LONG -> Type.LONG;
case FLOAT -> Type.FLOAT;
case DOUBLE -> Type.DOUBLE;
case STRING -> Type.STRING;
case GEOMETRY -> Type.GEOMETRY;
case GROUP -> null;
};
}

public static List<Object> asDataRow(GeoParquetGroup group) {
List<Object> values = new ArrayList<>();
Schema schema = group.getSchema();
List<Field> fields = schema.fields();
for (int i = 0; i < fields.size(); i++) {
Field field = fields.get(i);
field.type();
switch (field.type()) {
case BINARY -> values.add(group.getBinaryValue(i).getBytes());
case BOOLEAN -> values.add(group.getBooleanValue(i));
case INTEGER -> values.add(group.getIntegerValue(i));
case INT96 -> values.add(group.getLongValue(i));
case LONG -> values.add(group.getLongValue(i));
case FLOAT -> values.add(group.getFloatValue(i));
case DOUBLE -> values.add(group.getDoubleValue(i));
case STRING -> values.add(group.getStringValue(i));
case GEOMETRY -> values.add(group.getGeometryValue(i));
case GROUP -> values.add(null); // TODO: values.add(asDataRow(group.getGroupValue(i)));
}
}
return values;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import de.bytefish.pgbulkinsert.pgsql.handlers.*;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
Expand All @@ -42,6 +41,7 @@
*/
public class PostgresDataSchema implements DataSchema {

public static final String REGEX = "[^a-zA-Z0-9]";
private static final Logger logger = LoggerFactory.getLogger(PostgresDataSchema.class);

private static final String[] TYPES = new String[] {"TABLE", "VIEW"};
Expand All @@ -61,7 +61,7 @@ public PostgresDataSchema(DataSource dataSource) {
* {@inheritDoc}
*/
@Override
public Collection<String> list() throws DataTableException {
public List<String> list() throws DataTableException {
DatabaseMetadata metadata = new DatabaseMetadata(dataSource);
return metadata.getTableMetaData(null, "public", null, TYPES).stream()
.map(table -> table.table().tableName())
Expand All @@ -74,7 +74,8 @@ public Collection<String> list() throws DataTableException {
@Override
public DataTable get(String name) throws DataTableException {
var databaseMetadata = new DatabaseMetadata(dataSource);
var tableMetadata = databaseMetadata.getTableMetaData(null, null, name, TYPES)
var postgresName = name.replaceAll(REGEX, "_").toLowerCase();
var tableMetadata = databaseMetadata.getTableMetaData(null, null, postgresName, TYPES)
.stream().findFirst();
if (tableMetadata.isEmpty()) {
throw new DataTableException("Table " + name + " does not exist.");
Expand All @@ -88,14 +89,21 @@ public DataTable get(String name) throws DataTableException {
*/
@Override
public void add(DataTable table) {
var name = table.rowType().name().replaceAll(REGEX, "_").toLowerCase();
add(name, table);
}

/**
* {@inheritDoc}
*/
@Override
public void add(String name, DataTable table) {
try (var connection = dataSource.getConnection()) {
var regex = "[^a-zA-Z0-9]";
var name = table.rowType().name().replaceAll(regex, "_").toLowerCase();
var mapping = new HashMap<String, String>();
var properties = new ArrayList<DataColumn>();
for (DataColumn column : table.rowType().columns()) {
if (PostgresTypeConversion.typeToName.containsKey(column.type())) {
var columnName = column.name().replaceAll(regex, "_").toLowerCase();
var columnName = column.name().replaceAll(REGEX, "_").toLowerCase();
mapping.put(columnName, column.name());
properties.add(new DataColumnImpl(columnName, column.type()));
}
Expand Down
Loading

0 comments on commit 91e3263

Please sign in to comment.