You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@baremaps.apache.org by bc...@apache.org on 2023/06/21 15:02:05 UTC
[incubator-baremaps] branch calcite updated: Add support for spatial types
This is an automated email from the ASF dual-hosted git repository.
bchapuis pushed a commit to branch calcite
in repository https://gitbox.apache.org/repos/asf/incubator-baremaps.git
The following commit(s) were added to refs/heads/calcite by this push:
new 7cdfc88f Add support for spatial types
7cdfc88f is described below
commit 7cdfc88f20142ec349ec185326c35105d36a3cc5
Author: Bertil Chapuis <bc...@gmail.com>
AuthorDate: Wed Jun 21 17:01:58 2023 +0200
Add support for spatial types
---
.../java/org/apache/baremaps/calcite/Calcite.java | 109 ++++++++++++++-------
.../baremaps/collection/DataCollectionAdapter.java | 2 -
.../collection/store/AbstractDataTable.java | 3 +-
.../store/DataTableGeometryTransformer.java | 6 +-
.../baremaps/workflow/tasks/ImportGeoPackage.java | 2 +-
.../baremaps/workflow/tasks/ImportShapefile.java | 2 +-
6 files changed, 84 insertions(+), 40 deletions(-)
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/calcite/Calcite.java b/baremaps-core/src/main/java/org/apache/baremaps/calcite/Calcite.java
index 7c4b5958..8b8d2f61 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/calcite/Calcite.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/calcite/Calcite.java
@@ -12,6 +12,7 @@
package org.apache.baremaps.calcite;
+import com.google.common.collect.ImmutableList;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
@@ -29,49 +30,59 @@ import org.apache.calcite.jdbc.CalciteConnection;
import org.apache.calcite.jdbc.JavaTypeFactoryImpl;
import org.apache.calcite.linq4j.Enumerable;
import org.apache.calcite.linq4j.Linq4j;
+import org.apache.calcite.model.ModelHandler;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.RelDataTypeFactory;
+import org.apache.calcite.runtime.SpatialTypeFunctions;
+import org.apache.calcite.runtime.SpatialTypeFunctions.Accum;
+import org.apache.calcite.runtime.SpatialTypeFunctions.Collect;
+import org.apache.calcite.runtime.SpatialTypeFunctions.Union;
import org.apache.calcite.schema.ScannableTable;
import org.apache.calcite.schema.SchemaPlus;
import org.apache.calcite.schema.impl.AbstractTable;
+import org.apache.calcite.schema.impl.AggregateFunctionImpl;
+import org.apache.calcite.sql.fun.SqlSpatialTypeFunctions;
import org.apache.calcite.sql.type.SqlTypeName;
+import org.locationtech.jts.geom.*;
public class Calcite {
- private static final DataSchema PLAYER_DATA_SCHEMA = new DataSchemaImpl("player", List.of(
+ private static final GeometryFactory GEOMETRY_FACTORY = new GeometryFactory();
+
+ private static final DataSchema CITY_SCHEMA = new DataSchemaImpl("country", List.of(
new DataColumnImpl("id", Integer.class),
new DataColumnImpl("name", String.class),
- new DataColumnImpl("level", Integer.class)));
+ new DataColumnImpl("geometry", Geometry.class)));
- private static final DataTable PLAYER_DATA_TABLE = new DataTableImpl(
- PLAYER_DATA_SCHEMA,
- new IndexedDataList<>(new AppendOnlyBuffer<>(new RowDataType(PLAYER_DATA_SCHEMA))));
+ private static final DataTable CITY_TABLE = new DataTableImpl(
+ CITY_SCHEMA,
+ new IndexedDataList<>(new AppendOnlyBuffer<>(new RowDataType(CITY_SCHEMA))));
static {
- PLAYER_DATA_TABLE.add(new DataRowImpl(PLAYER_DATA_TABLE.schema(), List.of(1, "Wizard", 5)));
- PLAYER_DATA_TABLE.add(new DataRowImpl(PLAYER_DATA_TABLE.schema(), List.of(2, "Hunter", 7)));
+ CITY_TABLE.add(new DataRowImpl(CITY_TABLE.schema(),
+ List.of(1, "Paris", GEOMETRY_FACTORY.createPoint(new Coordinate(2.3522, 48.8566)))));
+ CITY_TABLE.add(new DataRowImpl(CITY_TABLE.schema(),
+ List.of(2, "New York", GEOMETRY_FACTORY.createPoint(new Coordinate(-74.0060, 40.7128)))));
}
- private static final DataSchema EQUIPMENT_DATA_SCHEMA = new DataSchemaImpl("equipment", List.of(
- new DataColumnImpl("id", Integer.class),
- new DataColumnImpl("name", String.class),
- new DataColumnImpl("damage", Integer.class),
- new DataColumnImpl("player_id", Integer.class)));
+ private static final DataSchema POPULATION_SCHEMA = new DataSchemaImpl("population", List.of(
+ new DataColumnImpl("country_id", Integer.class),
+ new DataColumnImpl("population", Integer.class)));
- private static final DataTable EQUIPMENT_DATA_TABLE = new DataTableImpl(
- EQUIPMENT_DATA_SCHEMA,
- new IndexedDataList<>(new AppendOnlyBuffer<>(new RowDataType(EQUIPMENT_DATA_SCHEMA))));
+ private static final DataTable POPULATION_TABLE = new DataTableImpl(
+ POPULATION_SCHEMA,
+ new IndexedDataList<>(new AppendOnlyBuffer<>(new RowDataType(POPULATION_SCHEMA))));
static {
- EQUIPMENT_DATA_TABLE
- .add(new DataRowImpl(EQUIPMENT_DATA_TABLE.schema(), List.of(1, "fireball", 7, 1)));
- EQUIPMENT_DATA_TABLE
- .add(new DataRowImpl(EQUIPMENT_DATA_TABLE.schema(), List.of(2, "rifle", 4, 2)));
+ POPULATION_TABLE
+ .add(new DataRowImpl(POPULATION_TABLE.schema(), List.of(1, 2_161_000)));
+ POPULATION_TABLE
+ .add(new DataRowImpl(POPULATION_TABLE.schema(), List.of(2, 8_336_000)));
}
public static void main(String[] args) throws SQLException {
Properties info = new Properties();
- info.setProperty("lex", "JAVA");
+ info.setProperty("lex", "MYSQL");
Connection connection = DriverManager.getConnection("jdbc:calcite:", info);
CalciteConnection calciteConnection =
@@ -79,21 +90,29 @@ public class Calcite {
SchemaPlus rootSchema = calciteConnection.getRootSchema();
- ListTable playerTable = new ListTable(PLAYER_DATA_TABLE);
- rootSchema.add("player", playerTable);
+ final ImmutableList<String> emptyPath = ImmutableList.of();
+ ModelHandler.addFunctions(rootSchema, null, emptyPath,
+ SpatialTypeFunctions.class.getName(), "*", true);
+ ModelHandler.addFunctions(rootSchema, null, emptyPath,
+ SqlSpatialTypeFunctions.class.getName(), "*", true);
+
+ rootSchema.add("ST_UNION", AggregateFunctionImpl.create(Union.class));
+ rootSchema.add("ST_ACCUM", AggregateFunctionImpl.create(Accum.class));
+ rootSchema.add("ST_COLLECT", AggregateFunctionImpl.create(Collect.class));
- ListTable equipmentTable = new ListTable(EQUIPMENT_DATA_TABLE);
- rootSchema.add("equipment", equipmentTable);
+ ListTable cityTable = new ListTable(CITY_TABLE);
+ rootSchema.add("country", cityTable);
+
+ ListTable populationTable = new ListTable(POPULATION_TABLE);
+ rootSchema.add("population", populationTable);
String sql =
- "SELECT player.name, equipment.name FROM player INNER JOIN equipment ON player.id = equipment.player_id ";
+ "SELECT name, ST_Buffer(geometry, 10), population FROM country INNER JOIN population ON country.id = population.country_id";
ResultSet resultSet = connection.createStatement().executeQuery(sql);
- StringBuilder b = new StringBuilder();
while (resultSet.next()) {
- b.append(resultSet.getString(1)).append(" attacks with ");
- b.append(resultSet.getString(2)).append(" !\n");
+ System.out.println(
+ resultSet.getString(1) + ", " + resultSet.getObject(2) + ", " + resultSet.getInt(3));
}
- System.out.println(b);
resultSet.close();
}
@@ -126,12 +145,36 @@ public class Calcite {
}
private RelDataType toSqlType(Class type) {
- if (type.equals(Integer.class)) {
- return new JavaTypeFactoryImpl().createSqlType(SqlTypeName.INTEGER);
- } else if (type.equals(String.class)) {
+ if (type.equals(String.class)) {
return new JavaTypeFactoryImpl().createSqlType(SqlTypeName.VARCHAR);
+ } else if (type.equals(Boolean.class)) {
+ return new JavaTypeFactoryImpl().createSqlType(SqlTypeName.BOOLEAN);
+ } else if (type.equals(Short.class)) {
+ return new JavaTypeFactoryImpl().createSqlType(SqlTypeName.SMALLINT);
+ } else if (type.equals(Integer.class)) {
+ return new JavaTypeFactoryImpl().createSqlType(SqlTypeName.INTEGER);
+ } else if (type.equals(Float.class)) {
+ return new JavaTypeFactoryImpl().createSqlType(SqlTypeName.FLOAT);
+ } else if (type.equals(Double.class)) {
+ return new JavaTypeFactoryImpl().createSqlType(SqlTypeName.DOUBLE);
+ } else if (type.equals(Geometry.class)) {
+ return new JavaTypeFactoryImpl().createSqlType(SqlTypeName.GEOMETRY);
+ } else if (type.equals(Point.class)) {
+ return new JavaTypeFactoryImpl().createSqlType(SqlTypeName.GEOMETRY);
+ } else if (type.equals(LineString.class)) {
+ return new JavaTypeFactoryImpl().createSqlType(SqlTypeName.GEOMETRY);
+ } else if (type.equals(Polygon.class)) {
+ return new JavaTypeFactoryImpl().createSqlType(SqlTypeName.GEOMETRY);
+ } else if (type.equals(MultiPoint.class)) {
+ return new JavaTypeFactoryImpl().createSqlType(SqlTypeName.GEOMETRY);
+ } else if (type.equals(MultiLineString.class)) {
+ return new JavaTypeFactoryImpl().createSqlType(SqlTypeName.GEOMETRY);
+ } else if (type.equals(MultiPolygon.class)) {
+ return new JavaTypeFactoryImpl().createSqlType(SqlTypeName.GEOMETRY);
+ } else if (type.equals(GeometryCollection.class)) {
+ return new JavaTypeFactoryImpl().createSqlType(SqlTypeName.GEOMETRY);
} else {
- throw new IllegalArgumentException();
+ throw new IllegalArgumentException("Unsupported type " + type);
}
}
}
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/collection/DataCollectionAdapter.java b/baremaps-core/src/main/java/org/apache/baremaps/collection/DataCollectionAdapter.java
index a58a5a64..8c41e461 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/collection/DataCollectionAdapter.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/collection/DataCollectionAdapter.java
@@ -15,8 +15,6 @@ package org.apache.baremaps.collection;
import java.util.Iterator;
import java.util.function.Function;
-import org.apache.baremaps.collection.AbstractDataCollection;
-import org.apache.baremaps.collection.DataCollection;
/**
* A decorator for a table that transforms the geometries of the rows.
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/collection/store/AbstractDataTable.java b/baremaps-core/src/main/java/org/apache/baremaps/collection/store/AbstractDataTable.java
index 9f3cec73..7ff8702a 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/collection/store/AbstractDataTable.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/collection/store/AbstractDataTable.java
@@ -17,6 +17,7 @@ import org.apache.baremaps.collection.AbstractDataCollection;
/**
* A table is a collection of rows respecting a schema.
*/
-public abstract class AbstractDataTable extends AbstractDataCollection<DataRow> implements DataTable {
+public abstract class AbstractDataTable extends AbstractDataCollection<DataRow>
+ implements DataTable {
}
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/collection/store/DataTableGeometryTransformer.java b/baremaps-core/src/main/java/org/apache/baremaps/collection/store/DataTableGeometryTransformer.java
index 9642628b..ca607794 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/collection/store/DataTableGeometryTransformer.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/collection/store/DataTableGeometryTransformer.java
@@ -17,7 +17,8 @@ import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.util.GeometryTransformer;
/**
- * A transformer that applies a {@code GeometryTransformer} to the geometries of a {@code DataTable}.
+ * A transformer that applies a {@code GeometryTransformer} to the geometries of a
+ * {@code DataTable}.
*/
public class DataTableGeometryTransformer implements Function<DataRow, DataRow> {
@@ -31,7 +32,8 @@ public class DataTableGeometryTransformer implements Function<DataRow, DataRow>
* @param dataTable the table to transform
* @param geometryTransformer the geometry transformer
*/
- public DataTableGeometryTransformer(DataTable dataTable, GeometryTransformer geometryTransformer) {
+ public DataTableGeometryTransformer(DataTable dataTable,
+ GeometryTransformer geometryTransformer) {
this.dataTable = dataTable;
this.geometryTransformer = geometryTransformer;
}
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/ImportGeoPackage.java b/baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/ImportGeoPackage.java
index 34d5c380..38cc4e2f 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/ImportGeoPackage.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/ImportGeoPackage.java
@@ -13,8 +13,8 @@
package org.apache.baremaps.workflow.tasks;
import java.nio.file.Path;
-import org.apache.baremaps.collection.store.DataTableGeometryTransformer;
import org.apache.baremaps.collection.store.DataTableAdapter;
+import org.apache.baremaps.collection.store.DataTableGeometryTransformer;
import org.apache.baremaps.storage.geopackage.GeoPackageDataStore;
import org.apache.baremaps.storage.postgres.PostgresDataStore;
import org.apache.baremaps.utils.ProjectionTransformer;
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/ImportShapefile.java b/baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/ImportShapefile.java
index 90c05afd..4d52a785 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/ImportShapefile.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/ImportShapefile.java
@@ -13,8 +13,8 @@
package org.apache.baremaps.workflow.tasks;
import java.nio.file.Path;
-import org.apache.baremaps.collection.store.DataTableGeometryTransformer;
import org.apache.baremaps.collection.store.DataTableAdapter;
+import org.apache.baremaps.collection.store.DataTableGeometryTransformer;
import org.apache.baremaps.storage.postgres.PostgresDataStore;
import org.apache.baremaps.storage.shapefile.ShapefileDataTable;
import org.apache.baremaps.utils.ProjectionTransformer;