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/02/26 19:48:16 UTC
[incubator-baremaps] 01/02: Replace feature by dataframe
This is an automated email from the ASF dual-hosted git repository.
bchapuis pushed a commit to branch 590-flatgeobuf
in repository https://gitbox.apache.org/repos/asf/incubator-baremaps.git
commit 7ead5ad4a15c72dacf6c757c60a8ddab74c32de7
Author: Bertil Chapuis <bc...@gmail.com>
AuthorDate: Sat Feb 25 14:59:05 2023 +0100
Replace feature by dataframe
---
.../AbstractDataCollection.java} | 25 ++-
.../baremaps/collection/AppendOnlyBuffer.java | 2 +-
.../apache/baremaps/collection/DataCollection.java | 13 +-
.../collection/DataCollectionException.java | 8 +-
.../org/apache/baremaps/collection/DataList.java | 2 +-
.../AbstractDataFrame.java} | 10 +-
.../Resource.java => dataframe/Column.java} | 6 +-
.../Aggregate.java => dataframe/ColumnImpl.java} | 5 +-
.../FeatureSet.java => dataframe/DataFrame.java} | 10 +-
.../DataFrameException.java} | 22 +--
.../DataFrameImpl.java} | 25 +--
.../DataStore.java} | 13 +-
.../FeatureSet.java => dataframe/DataType.java} | 10 +-
.../DataTypeImpl.java} | 17 +-
.../ReadableAggregate.java => dataframe/Row.java} | 13 +-
.../org/apache/baremaps/dataframe/RowImpl.java | 40 ++++
.../org/apache/baremaps/feature/FeatureImpl.java | 55 ------
.../apache/baremaps/feature/FeatureTypeImpl.java | 51 ------
.../baremaps/feature/ReadableFeatureSet.java | 24 ---
.../baremaps/feature/ReadableFeatureStream.java | 37 ----
.../apache/baremaps/feature/WritableAggregate.java | 25 ---
.../baremaps/feature/WritableFeatureSet.java | 24 ---
.../baremaps/mvt/expression/Expressions.java | 110 +++++------
.../storage/DataFrameProjectionTransform.java | 63 +++++++
.../storage/FeatureSetProjectionTransform.java | 58 ------
.../storage/flatgeobuf/FeatureIterator.java | 21 +--
.../storage/flatgeobuf/FlatGeoBufFeatureSet.java | 202 ++++++++++-----------
...FeatureConversions.java => RowConversions.java} | 77 ++++----
.../storage/geopackage/GeoPackageDatabase.java | 39 +++-
.../storage/geopackage/GeoPackageTable.java | 62 +++----
.../{PostgresTable.java => PostgresDataFrame.java} | 31 ++--
.../storage/postgres/PostgresDatabase.java | 143 ++++++++-------
.../storage/shapefile/ShapefileDataFrame.java | 102 +++++++++++
.../storage/shapefile/ShapefileDirectory.java | 40 +++-
.../storage/shapefile/ShapefileFeatureSet.java | 92 ----------
.../shapefile/internal/DbaseByteReader.java | 8 +-
.../shapefile/internal/InputFeatureStream.java | 24 +--
.../shapefile/internal/ShapefileByteReader.java | 40 ++--
.../shapefile/internal/ShapefileReader.java | 10 +-
.../org/apache/baremaps/workflow/tasks/Entity.java | 36 ++--
.../baremaps/workflow/tasks/ImportGeoPackage.java | 13 +-
.../baremaps/workflow/tasks/ImportShapefile.java | 8 +-
.../workflow/tasks/TransformEntityCollection.java | 55 ++++--
.../org/apache/baremaps/mvt/ExpressionsTest.java | 28 +--
.../flatgeobuf/FlatGeoBufFeatureSetTest.java | 7 +-
45 files changed, 797 insertions(+), 909 deletions(-)
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/feature/Feature.java b/baremaps-core/src/main/java/org/apache/baremaps/collection/AbstractDataCollection.java
similarity index 55%
rename from baremaps-core/src/main/java/org/apache/baremaps/feature/Feature.java
rename to baremaps-core/src/main/java/org/apache/baremaps/collection/AbstractDataCollection.java
index 93e6d8db..0b0d41a4 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/feature/Feature.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/collection/AbstractDataCollection.java
@@ -10,20 +10,27 @@
* the License.
*/
-package org.apache.baremaps.feature;
+package org.apache.baremaps.collection;
-import java.util.Map;
+import java.util.AbstractCollection;
-public interface Feature {
-
- FeatureType getType();
-
- void setProperty(String name, Object value);
+/**
+ * An abstract collection of data elements that can hold a large number of elements.
+ *
+ * @param <E> The type of the data.
+ */
+public abstract class AbstractDataCollection<E> extends AbstractCollection<E>
+ implements DataCollection<E> {
- Object getProperty(String name);
- Map<String, Object> getProperties();
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int size() {
+ return (int) Math.min(sizeAsLong(), Integer.MAX_VALUE);
+ }
}
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/collection/AppendOnlyBuffer.java b/baremaps-core/src/main/java/org/apache/baremaps/collection/AppendOnlyBuffer.java
index 1e582daa..e46d9a95 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/collection/AppendOnlyBuffer.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/collection/AppendOnlyBuffer.java
@@ -31,7 +31,7 @@ import org.apache.baremaps.collection.type.DataType;
*
* @param <E> The type of the data.
*/
-public class AppendOnlyBuffer<E> extends DataCollection<E> {
+public class AppendOnlyBuffer<E> extends AbstractDataCollection<E> {
private final DataType<E> dataType;
private final Memory memory;
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/collection/DataCollection.java b/baremaps-core/src/main/java/org/apache/baremaps/collection/DataCollection.java
index 8a9d9831..394af1ae 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/collection/DataCollection.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/collection/DataCollection.java
@@ -12,16 +12,9 @@
package org.apache.baremaps.collection;
+import java.util.Collection;
-
-import java.util.AbstractCollection;
-
-/**
- * A abstract collection of data elements that can hold a large number of elements.
- *
- * @param <E> The type of the data.
- */
-public abstract class DataCollection<E> extends AbstractCollection<E> {
+public interface DataCollection<E> extends Collection<E> {
/**
* Returns the number of values stored in the data store.
@@ -31,7 +24,7 @@ public abstract class DataCollection<E> extends AbstractCollection<E> {
public abstract long sizeAsLong();
/** {@inheritDoc} */
- public int size() {
+ default int size() {
return (int) Math.min(sizeAsLong(), Integer.MAX_VALUE);
}
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/collection/DataCollectionException.java b/baremaps-core/src/main/java/org/apache/baremaps/collection/DataCollectionException.java
index c2613527..d19d4e2c 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/collection/DataCollectionException.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/collection/DataCollectionException.java
@@ -14,11 +14,11 @@ package org.apache.baremaps.collection;
/** Signals that an exception occurred in a store. */
public class DataCollectionException extends RuntimeException {
- /** Constructs a {@code BlobStoreException} with {@code null} as its error detail message. */
+ /** Constructs a {@code DataCollectionException} with {@code null} as its error detail message. */
public DataCollectionException() {}
/**
- * Constructs an {@code StoreException} with the specified detail message.
+ * Constructs an {@code DataCollectionException} with the specified detail message.
*
* @param message the message
*/
@@ -27,7 +27,7 @@ public class DataCollectionException extends RuntimeException {
}
/**
- * Constructs a {@code StoreException} with the specified cause.
+ * Constructs a {@code DataCollectionException} with the specified cause.
*
* @param cause the cause
*/
@@ -36,7 +36,7 @@ public class DataCollectionException extends RuntimeException {
}
/**
- * Constructs a {@code StoreException} with the specified detail message and cause.
+ * Constructs a {@code DataCollectionException} with the specified detail message and cause.
*
* @param message the message
* @param cause the cause
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/collection/DataList.java b/baremaps-core/src/main/java/org/apache/baremaps/collection/DataList.java
index a0c1aff7..98c732fc 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/collection/DataList.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/collection/DataList.java
@@ -22,7 +22,7 @@ import java.util.NoSuchElementException;
*
* @param <E> The type of the data.
*/
-public abstract class DataList<E> extends DataCollection<E> {
+public abstract class DataList<E> extends AbstractDataCollection<E> {
/**
* Appends a value to the list and returns its index.
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/feature/FeatureSet.java b/baremaps-core/src/main/java/org/apache/baremaps/dataframe/AbstractDataFrame.java
similarity index 73%
copy from baremaps-core/src/main/java/org/apache/baremaps/feature/FeatureSet.java
copy to baremaps-core/src/main/java/org/apache/baremaps/dataframe/AbstractDataFrame.java
index 2dcc4534..8a0349a4 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/feature/FeatureSet.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/dataframe/AbstractDataFrame.java
@@ -10,14 +10,10 @@
* the License.
*/
-package org.apache.baremaps.feature;
+package org.apache.baremaps.dataframe;
+import org.apache.baremaps.collection.AbstractDataCollection;
-
-import java.io.IOException;
-
-public interface FeatureSet extends Resource {
-
- FeatureType getType() throws IOException;
+public abstract class AbstractDataFrame extends AbstractDataCollection<Row> implements DataFrame {
}
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/feature/Resource.java b/baremaps-core/src/main/java/org/apache/baremaps/dataframe/Column.java
similarity index 85%
rename from baremaps-core/src/main/java/org/apache/baremaps/feature/Resource.java
rename to baremaps-core/src/main/java/org/apache/baremaps/dataframe/Column.java
index a9686585..174d86ad 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/feature/Resource.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/dataframe/Column.java
@@ -10,10 +10,12 @@
* the License.
*/
-package org.apache.baremaps.feature;
+package org.apache.baremaps.dataframe;
+public interface Column {
+ String name();
-public interface Resource {
+ Class type();
}
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/feature/Aggregate.java b/baremaps-core/src/main/java/org/apache/baremaps/dataframe/ColumnImpl.java
similarity index 83%
rename from baremaps-core/src/main/java/org/apache/baremaps/feature/Aggregate.java
rename to baremaps-core/src/main/java/org/apache/baremaps/dataframe/ColumnImpl.java
index a13eb326..ad3928c7 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/feature/Aggregate.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/dataframe/ColumnImpl.java
@@ -10,7 +10,8 @@
* the License.
*/
-package org.apache.baremaps.feature;
+package org.apache.baremaps.dataframe;
+
+public record ColumnImpl(String name, Class type) implements Column {
-public interface Aggregate extends Resource {
}
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/feature/FeatureSet.java b/baremaps-core/src/main/java/org/apache/baremaps/dataframe/DataFrame.java
similarity index 76%
copy from baremaps-core/src/main/java/org/apache/baremaps/feature/FeatureSet.java
copy to baremaps-core/src/main/java/org/apache/baremaps/dataframe/DataFrame.java
index 2dcc4534..3efccf11 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/feature/FeatureSet.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/dataframe/DataFrame.java
@@ -10,14 +10,12 @@
* the License.
*/
-package org.apache.baremaps.feature;
+package org.apache.baremaps.dataframe;
+import org.apache.baremaps.collection.DataCollection;
+public interface DataFrame extends DataCollection<Row> {
-import java.io.IOException;
-
-public interface FeatureSet extends Resource {
-
- FeatureType getType() throws IOException;
+ DataType dataType();
}
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/collection/DataCollectionException.java b/baremaps-core/src/main/java/org/apache/baremaps/dataframe/DataFrameException.java
similarity index 55%
copy from baremaps-core/src/main/java/org/apache/baremaps/collection/DataCollectionException.java
copy to baremaps-core/src/main/java/org/apache/baremaps/dataframe/DataFrameException.java
index c2613527..1a2e746b 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/collection/DataCollectionException.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/dataframe/DataFrameException.java
@@ -10,38 +10,38 @@
* the License.
*/
-package org.apache.baremaps.collection;
+package org.apache.baremaps.dataframe;
-/** Signals that an exception occurred in a store. */
-public class DataCollectionException extends RuntimeException {
- /** Constructs a {@code BlobStoreException} with {@code null} as its error detail message. */
- public DataCollectionException() {}
+/** Signals that an exception occurred in a data frame. */
+public class DataFrameException extends RuntimeException {
+ /** Constructs a {@code DataFrameException} with {@code null} as its error detail message. */
+ public DataFrameException() {}
/**
- * Constructs an {@code StoreException} with the specified detail message.
+ * Constructs an {@code DataFrameException} with the specified detail message.
*
* @param message the message
*/
- public DataCollectionException(String message) {
+ public DataFrameException(String message) {
super(message);
}
/**
- * Constructs a {@code StoreException} with the specified cause.
+ * Constructs a {@code DataFrameException} with the specified cause.
*
* @param cause the cause
*/
- public DataCollectionException(Throwable cause) {
+ public DataFrameException(Throwable cause) {
super(cause);
}
/**
- * Constructs a {@code StoreException} with the specified detail message and cause.
+ * Constructs a {@code DataFrameException} with the specified detail message and cause.
*
* @param message the message
* @param cause the cause
*/
- public DataCollectionException(String message, Throwable cause) {
+ public DataFrameException(String message, Throwable cause) {
super(message, cause);
}
}
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/feature/PropertyType.java b/baremaps-core/src/main/java/org/apache/baremaps/dataframe/DataFrameImpl.java
similarity index 60%
rename from baremaps-core/src/main/java/org/apache/baremaps/feature/PropertyType.java
rename to baremaps-core/src/main/java/org/apache/baremaps/dataframe/DataFrameImpl.java
index 634657c4..4b0ffd27 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/feature/PropertyType.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/dataframe/DataFrameImpl.java
@@ -10,24 +10,25 @@
* the License.
*/
-package org.apache.baremaps.feature;
+package org.apache.baremaps.dataframe;
-public class PropertyType<T> {
+import java.util.ArrayList;
- private final String name;
- private final Class<T> type;
+public class DataFrameImpl extends ArrayList<Row> implements DataFrame {
- public PropertyType(String name, Class<T> type) {
- this.name = name;
- this.type = type;
- }
+ private final DataType dataType;
- public String getName() {
- return name;
+ public DataFrameImpl(DataType dataType) {
+ this.dataType = dataType;
}
- public Class<T> getType() {
- return type;
+ @Override
+ public long sizeAsLong() {
+ return size();
}
+ @Override
+ public DataType dataType() {
+ return dataType;
+ }
}
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/feature/FeatureCollection.java b/baremaps-core/src/main/java/org/apache/baremaps/dataframe/DataStore.java
similarity index 67%
rename from baremaps-core/src/main/java/org/apache/baremaps/feature/FeatureCollection.java
rename to baremaps-core/src/main/java/org/apache/baremaps/dataframe/DataStore.java
index 5a4d8eba..ce89b957 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/feature/FeatureCollection.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/dataframe/DataStore.java
@@ -10,15 +10,18 @@
* the License.
*/
-package org.apache.baremaps.feature;
+package org.apache.baremaps.dataframe;
+import java.util.Collection;
+public interface DataStore {
-import java.io.IOException;
-import java.util.Collection;
+ Collection<DataFrame> list() throws DataFrameException;
+
+ DataFrame get(String name) throws DataFrameException;
-public interface FeatureCollection extends Collection<Feature> {
+ void add(DataFrame value) throws DataFrameException;
- FeatureType getType() throws IOException;
+ void remove(String name) throws DataFrameException;
}
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/feature/FeatureSet.java b/baremaps-core/src/main/java/org/apache/baremaps/dataframe/DataType.java
similarity index 78%
rename from baremaps-core/src/main/java/org/apache/baremaps/feature/FeatureSet.java
rename to baremaps-core/src/main/java/org/apache/baremaps/dataframe/DataType.java
index 2dcc4534..29352566 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/feature/FeatureSet.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/dataframe/DataType.java
@@ -10,14 +10,16 @@
* the License.
*/
-package org.apache.baremaps.feature;
+package org.apache.baremaps.dataframe;
+import java.util.List;
+public interface DataType {
-import java.io.IOException;
+ String name();
-public interface FeatureSet extends Resource {
+ List<Column> columns();
- FeatureType getType() throws IOException;
+ Row newInstance();
}
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/feature/FeatureType.java b/baremaps-core/src/main/java/org/apache/baremaps/dataframe/DataTypeImpl.java
similarity index 66%
rename from baremaps-core/src/main/java/org/apache/baremaps/feature/FeatureType.java
rename to baremaps-core/src/main/java/org/apache/baremaps/dataframe/DataTypeImpl.java
index 52c07fe0..ee362fd2 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/feature/FeatureType.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/dataframe/DataTypeImpl.java
@@ -10,16 +10,15 @@
* the License.
*/
-package org.apache.baremaps.feature;
+package org.apache.baremaps.dataframe;
-import java.util.Map;
+import java.util.ArrayList;
+import java.util.List;
-public interface FeatureType {
- String getName();
+public record DataTypeImpl(String name, List<Column> columns) implements DataType {
- Map<String, PropertyType> getPropertyTypes();
-
- PropertyType getPropertyType(String name);
-
- Feature newInstance();
+ @Override
+ public Row newInstance() {
+ return new RowImpl(this, new ArrayList(columns.size()));
+ }
}
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/feature/ReadableAggregate.java b/baremaps-core/src/main/java/org/apache/baremaps/dataframe/Row.java
similarity index 73%
rename from baremaps-core/src/main/java/org/apache/baremaps/feature/ReadableAggregate.java
rename to baremaps-core/src/main/java/org/apache/baremaps/dataframe/Row.java
index 2493c211..8b291119 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/feature/ReadableAggregate.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/dataframe/Row.java
@@ -10,15 +10,18 @@
* the License.
*/
-package org.apache.baremaps.feature;
+package org.apache.baremaps.dataframe;
+import java.util.List;
+public interface Row {
-import java.io.IOException;
-import java.util.stream.Stream;
+ DataType dataType();
-public interface ReadableAggregate extends Aggregate {
+ List<Object> values();
- Stream<Resource> read() throws IOException;
+ Object get(String name);
+
+ void set(String name, Object value);
}
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/dataframe/RowImpl.java b/baremaps-core/src/main/java/org/apache/baremaps/dataframe/RowImpl.java
new file mode 100644
index 00000000..027b383e
--- /dev/null
+++ b/baremaps-core/src/main/java/org/apache/baremaps/dataframe/RowImpl.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed 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.dataframe;
+
+import java.util.List;
+
+public record RowImpl(DataType dataType, List values) implements Row {
+
+ @Override
+ public Object get(String name) {
+ for (int i = 0; i < dataType().columns().size(); i++) {
+ if (dataType().columns().get(i).name().equals(name)) {
+ return values.get(i);
+ }
+ }
+ throw new IllegalArgumentException("Column " + name + " not found.");
+ }
+
+ @Override
+ public void set(String name, Object value) {
+ for (int i = 0; i < dataType().columns().size(); i++) {
+ if (dataType().columns().get(i).name().equals(name)) {
+ values.set(i, value);
+ return;
+ }
+ }
+ throw new IllegalArgumentException("Column " + name + " not found.");
+ }
+
+}
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/feature/FeatureImpl.java b/baremaps-core/src/main/java/org/apache/baremaps/feature/FeatureImpl.java
deleted file mode 100644
index 8e0fc0c2..00000000
--- a/baremaps-core/src/main/java/org/apache/baremaps/feature/FeatureImpl.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Licensed 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.feature;
-
-
-
-import com.google.common.collect.ImmutableMap;
-import java.util.HashMap;
-import java.util.Map;
-
-public final class FeatureImpl implements Feature {
-
- private FeatureType type;
-
- private Map<String, Object> properties;
-
- public FeatureImpl(FeatureType type) {
- this(type, new HashMap<>());
- }
-
- public FeatureImpl(FeatureType type, Map<String, Object> properties) {
- this.type = type;
- this.properties = properties;
- }
-
- @Override
- public FeatureType getType() {
- return type;
- }
-
- @Override
- public void setProperty(String name, Object value) {
- properties.put(name, value);
- }
-
- @Override
- public Object getProperty(String name) {
- return properties.get(name);
- }
-
- public Map<String, Object> getProperties() {
- return ImmutableMap.copyOf(properties);
- }
-
-}
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/feature/FeatureTypeImpl.java b/baremaps-core/src/main/java/org/apache/baremaps/feature/FeatureTypeImpl.java
deleted file mode 100644
index 1cda4086..00000000
--- a/baremaps-core/src/main/java/org/apache/baremaps/feature/FeatureTypeImpl.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Licensed 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.feature;
-
-
-
-import com.google.common.collect.ImmutableMap;
-import java.util.Map;
-
-public class FeatureTypeImpl implements FeatureType {
-
- private final String name;
-
- private final Map<String, PropertyType> propertyTypes;
-
- public FeatureTypeImpl(String name, Map<String, PropertyType> propertyTypes) {
- this.name = name;
- this.propertyTypes = propertyTypes;
- }
-
- @Override
- public String getName() {
- return name;
- }
-
- @Override
- public Map<String, PropertyType> getPropertyTypes() {
- return ImmutableMap.copyOf(propertyTypes);
- }
-
- @Override
- public PropertyType getPropertyType(String name) {
- return propertyTypes.get(name);
- }
-
- @Override
- public Feature newInstance() {
- return new FeatureImpl(this);
- }
-
-}
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/feature/ReadableFeatureSet.java b/baremaps-core/src/main/java/org/apache/baremaps/feature/ReadableFeatureSet.java
deleted file mode 100644
index 8fa615b4..00000000
--- a/baremaps-core/src/main/java/org/apache/baremaps/feature/ReadableFeatureSet.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Licensed 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.feature;
-
-
-
-import java.io.IOException;
-import java.util.stream.Stream;
-
-public interface ReadableFeatureSet extends FeatureSet {
-
- Stream<? extends Feature> read() throws IOException;
-
-}
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/feature/ReadableFeatureStream.java b/baremaps-core/src/main/java/org/apache/baremaps/feature/ReadableFeatureStream.java
deleted file mode 100644
index e1969fae..00000000
--- a/baremaps-core/src/main/java/org/apache/baremaps/feature/ReadableFeatureStream.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Licensed 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.feature;
-
-import java.util.stream.Stream;
-
-public class ReadableFeatureStream implements ReadableFeatureSet {
-
- private final FeatureType featureType;
-
- private final Stream<? extends Feature> stream;
-
- public ReadableFeatureStream(FeatureType featureType, Stream<? extends Feature> stream) {
- this.featureType = featureType;
- this.stream = stream;
- }
-
- @Override
- public FeatureType getType() {
- return featureType;
- }
-
- @Override
- public Stream<? extends Feature> read() {
- return stream;
- }
-}
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/feature/WritableAggregate.java b/baremaps-core/src/main/java/org/apache/baremaps/feature/WritableAggregate.java
deleted file mode 100644
index 87d300c4..00000000
--- a/baremaps-core/src/main/java/org/apache/baremaps/feature/WritableAggregate.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Licensed 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.feature;
-
-
-
-import java.io.IOException;
-
-public interface WritableAggregate extends Aggregate {
-
- void write(Resource resource) throws IOException;
-
- void remove(Resource resource) throws IOException;
-
-}
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/feature/WritableFeatureSet.java b/baremaps-core/src/main/java/org/apache/baremaps/feature/WritableFeatureSet.java
deleted file mode 100644
index a7541ef4..00000000
--- a/baremaps-core/src/main/java/org/apache/baremaps/feature/WritableFeatureSet.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Licensed 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.feature;
-
-
-
-import java.io.IOException;
-import java.util.stream.Stream;
-
-public interface WritableFeatureSet extends FeatureSet {
-
- void write(Stream<Feature> features) throws IOException;
-
-}
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/mvt/expression/Expressions.java b/baremaps-core/src/main/java/org/apache/baremaps/mvt/expression/Expressions.java
index f421dd77..1cd7d3fc 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/mvt/expression/Expressions.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/mvt/expression/Expressions.java
@@ -32,7 +32,7 @@ import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
-import org.apache.baremaps.feature.Feature;
+import org.apache.baremaps.dataframe.Row;
import org.locationtech.jts.geom.*;
public interface Expressions {
@@ -41,7 +41,7 @@ public interface Expressions {
String name();
- T evaluate(Feature feature);
+ T evaluate(Row feature);
}
@@ -53,7 +53,7 @@ public interface Expressions {
}
@Override
- public Object evaluate(Feature feature) {
+ public Object evaluate(Row row) {
return value;
}
}
@@ -66,8 +66,8 @@ public interface Expressions {
}
@Override
- public Object evaluate(Feature feature) {
- Object value = expression.evaluate(feature);
+ public Object evaluate(Row row) {
+ Object value = expression.evaluate(row);
if (value instanceof List list && index >= 0 && index < list.size()) {
return list.get(index);
}
@@ -83,8 +83,8 @@ public interface Expressions {
}
@Override
- public Object evaluate(Feature feature) {
- return feature.getProperty(property);
+ public Object evaluate(Row row) {
+ return row.get(property);
}
}
@@ -96,8 +96,8 @@ public interface Expressions {
}
@Override
- public Boolean evaluate(Feature feature) {
- return feature.getProperty(property) != null;
+ public Boolean evaluate(Row row) {
+ return row.get(property) != null;
}
}
@@ -109,8 +109,8 @@ public interface Expressions {
}
@Override
- public Boolean evaluate(Feature feature) {
- var expressionValue = expression.evaluate(feature);
+ public Boolean evaluate(Row row) {
+ var expressionValue = expression.evaluate(row);
if (expressionValue instanceof List list) {
return list.contains(value);
} else if (expressionValue instanceof String string) {
@@ -129,8 +129,8 @@ public interface Expressions {
}
@Override
- public Integer evaluate(Feature feature) {
- var expressionValue = expression.evaluate(feature);
+ public Integer evaluate(Row row) {
+ var expressionValue = expression.evaluate(row);
if (expressionValue instanceof List list) {
return list.indexOf(value);
} else if (expressionValue instanceof String string) {
@@ -149,8 +149,8 @@ public interface Expressions {
}
@Override
- public Integer evaluate(Feature feature) {
- Object value = expression.evaluate(feature);
+ public Integer evaluate(Row row) {
+ Object value = expression.evaluate(row);
if (value instanceof String string) {
return string.length();
} else if (value instanceof List list) {
@@ -173,14 +173,14 @@ public interface Expressions {
}
@Override
- public Object evaluate(Feature feature) {
- Object value = expression.evaluate(feature);
- var startIndex = (Integer) start.evaluate(feature);
+ public Object evaluate(Row row) {
+ Object value = expression.evaluate(row);
+ var startIndex = (Integer) start.evaluate(row);
if (value instanceof String string) {
- var endIndex = end == null ? string.length() : (Integer) end.evaluate(feature);
+ var endIndex = end == null ? string.length() : (Integer) end.evaluate(row);
return string.substring(startIndex, endIndex);
} else if (value instanceof List list) {
- var endIndex = end == null ? list.size() : (Integer) end.evaluate(feature);
+ var endIndex = end == null ? list.size() : (Integer) end.evaluate(row);
return list.subList(startIndex, endIndex);
} else {
return List.of();
@@ -196,8 +196,8 @@ public interface Expressions {
}
@Override
- public Object evaluate(Feature feature) {
- return !(boolean) expression.evaluate(feature);
+ public Object evaluate(Row row) {
+ return !(boolean) expression.evaluate(row);
}
}
@@ -209,8 +209,8 @@ public interface Expressions {
}
@Override
- public Object evaluate(Feature feature) {
- return new Not(new Equal(left, right)).evaluate(feature);
+ public Object evaluate(Row row) {
+ return new Not(new Equal(left, right)).evaluate(row);
}
}
@@ -222,8 +222,8 @@ public interface Expressions {
}
@Override
- public Boolean evaluate(Feature feature) {
- return (double) left.evaluate(feature) < (double) right.evaluate(feature);
+ public Boolean evaluate(Row row) {
+ return (double) left.evaluate(row) < (double) right.evaluate(row);
}
}
@@ -235,8 +235,8 @@ public interface Expressions {
}
@Override
- public Object evaluate(Feature feature) {
- return (double) left.evaluate(feature) <= (double) right.evaluate(feature);
+ public Object evaluate(Row row) {
+ return (double) left.evaluate(row) <= (double) right.evaluate(row);
}
}
@@ -248,8 +248,8 @@ public interface Expressions {
}
@Override
- public Object evaluate(Feature feature) {
- return left.evaluate(feature).equals(right.evaluate(feature));
+ public Object evaluate(Row row) {
+ return left.evaluate(row).equals(right.evaluate(row));
}
}
@@ -261,8 +261,8 @@ public interface Expressions {
}
@Override
- public Boolean evaluate(Feature feature) {
- return (double) left.evaluate(feature) > (double) right.evaluate(feature);
+ public Boolean evaluate(Row row) {
+ return (double) left.evaluate(row) > (double) right.evaluate(row);
}
}
@@ -274,8 +274,8 @@ public interface Expressions {
}
@Override
- public Boolean evaluate(Feature feature) {
- return (double) left.evaluate(feature) >= (double) right.evaluate(feature);
+ public Boolean evaluate(Row row) {
+ return (double) left.evaluate(row) >= (double) right.evaluate(row);
}
}
@@ -287,8 +287,8 @@ public interface Expressions {
}
@Override
- public Object evaluate(Feature feature) {
- return expressions.stream().allMatch(expression -> (boolean) expression.evaluate(feature));
+ public Object evaluate(Row row) {
+ return expressions.stream().allMatch(expression -> (boolean) expression.evaluate(row));
}
}
@@ -300,8 +300,8 @@ public interface Expressions {
}
@Override
- public Object evaluate(Feature feature) {
- return expressions.stream().anyMatch(expression -> (boolean) expression.evaluate(feature));
+ public Object evaluate(Row row) {
+ return expressions.stream().anyMatch(expression -> (boolean) expression.evaluate(row));
}
}
@@ -313,11 +313,11 @@ public interface Expressions {
}
@Override
- public Object evaluate(Feature feature) {
- if ((boolean) condition.evaluate(feature)) {
- return then.evaluate(feature);
+ public Object evaluate(Row row) {
+ if ((boolean) condition.evaluate(row)) {
+ return then.evaluate(row);
} else {
- return otherwise.evaluate(feature);
+ return otherwise.evaluate(row);
}
}
}
@@ -330,9 +330,9 @@ public interface Expressions {
}
@Override
- public Object evaluate(Feature feature) {
+ public Object evaluate(Row row) {
for (Expression expression : expressions) {
- Object value = expression.evaluate(feature);
+ Object value = expression.evaluate(row);
if (value != null) {
return value;
}
@@ -350,20 +350,20 @@ public interface Expressions {
}
@Override
- public Object evaluate(Feature feature) {
+ public Object evaluate(Row row) {
if (cases.size() % 2 != 0) {
throw new IllegalArgumentException(
"match expression must have an even number of arguments");
}
- var inputValue = input.evaluate(feature);
+ var inputValue = input.evaluate(row);
for (int i = 0; i < cases.size(); i += 2) {
Expression condition = cases.get(i);
Expression then = cases.get(i + 1);
- if (inputValue.equals(condition.evaluate(feature))) {
- return then.evaluate(feature);
+ if (inputValue.equals(condition.evaluate(row))) {
+ return then.evaluate(row);
}
}
- return fallback.evaluate(feature);
+ return fallback.evaluate(row);
}
}
@@ -375,7 +375,7 @@ public interface Expressions {
}
@Override
- public Object evaluate(Feature feature) {
+ public Object evaluate(Row row) {
throw new UnsupportedOperationException("within expression is not supported");
}
}
@@ -388,8 +388,8 @@ public interface Expressions {
}
@Override
- public String evaluate(Feature feature) {
- Object property = feature.getProperty("geom");
+ public String evaluate(Row row) {
+ Object property = row.get("geom");
if (property instanceof Point) {
return "Point";
} else if (property instanceof LineString) {
@@ -518,9 +518,9 @@ public interface Expressions {
return mapper.writeValueAsString(expression);
}
- static Predicate<Feature> asPredicate(Expression expression) {
- return feature -> {
- var result = expression.evaluate(feature);
+ static Predicate<Row> asPredicate(Expression expression) {
+ return row -> {
+ var result = expression.evaluate(row);
if (result instanceof Boolean booleanResult) {
return booleanResult;
}
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/storage/DataFrameProjectionTransform.java b/baremaps-core/src/main/java/org/apache/baremaps/storage/DataFrameProjectionTransform.java
new file mode 100644
index 00000000..9074d45e
--- /dev/null
+++ b/baremaps-core/src/main/java/org/apache/baremaps/storage/DataFrameProjectionTransform.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed 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;
+
+
+
+import java.util.Iterator;
+import org.apache.baremaps.collection.AbstractDataCollection;
+import org.apache.baremaps.dataframe.Column;
+import org.apache.baremaps.dataframe.DataFrame;
+import org.apache.baremaps.dataframe.DataType;
+import org.apache.baremaps.dataframe.Row;
+import org.apache.baremaps.openstreetmap.utils.ProjectionTransformer;
+import org.locationtech.jts.geom.Geometry;
+
+public class DataFrameProjectionTransform extends AbstractDataCollection<Row> implements DataFrame {
+
+ private final DataFrame dataFrame;
+
+ private final ProjectionTransformer projectionTransformer;
+
+ public DataFrameProjectionTransform(DataFrame dataFrame,
+ ProjectionTransformer projectionTransformer) {
+ this.dataFrame = dataFrame;
+ this.projectionTransformer = projectionTransformer;
+ }
+
+ @Override
+ public DataType dataType() {
+ return dataFrame.dataType();
+ }
+
+ public Row transformProjection(Row row) {
+ var columns = dataType().columns().stream()
+ .filter(column -> column.type().isInstance(Geometry.class)).toList();
+ for (Column column : columns) {
+ var name = column.name();
+ var geometry = (Geometry) row.get(name);
+ row.set(name, projectionTransformer.transform(geometry));
+ }
+ return row;
+ }
+
+ @Override
+ public Iterator<Row> iterator() {
+ return dataFrame.stream().map(this::transformProjection).iterator();
+ }
+
+ @Override
+ public long sizeAsLong() {
+ return 0;
+ }
+}
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/storage/FeatureSetProjectionTransform.java b/baremaps-core/src/main/java/org/apache/baremaps/storage/FeatureSetProjectionTransform.java
deleted file mode 100644
index c02beb7c..00000000
--- a/baremaps-core/src/main/java/org/apache/baremaps/storage/FeatureSetProjectionTransform.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Licensed 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;
-
-
-
-import java.io.IOException;
-import java.util.stream.Stream;
-import org.apache.baremaps.feature.Feature;
-import org.apache.baremaps.feature.FeatureType;
-import org.apache.baremaps.feature.ReadableFeatureSet;
-import org.apache.baremaps.openstreetmap.utils.ProjectionTransformer;
-import org.locationtech.jts.geom.Geometry;
-
-public class FeatureSetProjectionTransform implements ReadableFeatureSet {
-
- private final ReadableFeatureSet featureSetReader;
-
- private final ProjectionTransformer projectionTransformer;
-
- public FeatureSetProjectionTransform(ReadableFeatureSet featureSetReader,
- ProjectionTransformer projectionTransformer) {
- this.featureSetReader = featureSetReader;
- this.projectionTransformer = projectionTransformer;
- }
-
- @Override
- public FeatureType getType() throws IOException {
- return featureSetReader.getType();
- }
-
- @Override
- public Stream<Feature> read() throws IOException {
- return featureSetReader.read().map(this::transformProjection);
- }
-
- public Feature transformProjection(Feature feature) {
- for (var property : feature.getType().getPropertyTypes().values()) {
- var name = property.getName();
- var value = feature.getProperty(name);
- if (value instanceof Geometry geometry) {
- var projectedGeometry = projectionTransformer.transform(geometry);
- feature.setProperty(name, projectedGeometry);
- }
- }
- return feature;
- }
-}
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/storage/flatgeobuf/FeatureIterator.java b/baremaps-core/src/main/java/org/apache/baremaps/storage/flatgeobuf/FeatureIterator.java
index a5b5affd..cb1dab60 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/storage/flatgeobuf/FeatureIterator.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/storage/flatgeobuf/FeatureIterator.java
@@ -18,17 +18,16 @@ import java.nio.ByteOrder;
import java.nio.channels.SeekableByteChannel;
import java.util.Iterator;
import java.util.NoSuchElementException;
-import java.util.Spliterator;
-import java.util.function.Consumer;
-import org.apache.baremaps.feature.FeatureType;
+import org.apache.baremaps.dataframe.DataType;
+import org.apache.baremaps.dataframe.Row;
import org.wololo.flatgeobuf.HeaderMeta;
import org.wololo.flatgeobuf.generated.Feature;
-public class FeatureIterator implements Iterator<org.apache.baremaps.feature.Feature> {
+public class FeatureIterator implements Iterator<Row> {
private final HeaderMeta headerMeta;
- private final FeatureType featureType;
+ private final DataType dataType;
private final SeekableByteChannel channel;
@@ -37,10 +36,10 @@ public class FeatureIterator implements Iterator<org.apache.baremaps.feature.Fea
private long cursor = 0;
public FeatureIterator(SeekableByteChannel channel, HeaderMeta headerMeta,
- FeatureType featureType) {
+ DataType dataType) {
this.channel = channel;
this.headerMeta = headerMeta;
- this.featureType = featureType;
+ this.dataType = dataType;
this.buffer = ByteBuffer.allocate(1 << 20).order(ByteOrder.LITTLE_ENDIAN);
}
@@ -50,21 +49,21 @@ public class FeatureIterator implements Iterator<org.apache.baremaps.feature.Fea
}
@Override
- public org.apache.baremaps.feature.Feature next() {
+ public Row next() {
try {
channel.read(buffer);
buffer.flip();
var featureSize = buffer.getInt();
- var feature =
- FeatureConversions.asFeature(headerMeta, featureType, Feature.getRootAsFeature(buffer));
+ var row =
+ RowConversions.asFeature(headerMeta, dataType, Feature.getRootAsFeature(buffer));
buffer.position(Integer.BYTES + featureSize);
buffer.compact();
cursor++;
- return feature;
+ return row;
} catch (IOException e) {
throw new NoSuchElementException(e);
}
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/storage/flatgeobuf/FlatGeoBufFeatureSet.java b/baremaps-core/src/main/java/org/apache/baremaps/storage/flatgeobuf/FlatGeoBufFeatureSet.java
index b9b5edc9..6d22a890 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/storage/flatgeobuf/FlatGeoBufFeatureSet.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/storage/flatgeobuf/FlatGeoBufFeatureSet.java
@@ -13,7 +13,6 @@
package org.apache.baremaps.storage.flatgeobuf;
import com.google.flatbuffers.FlatBufferBuilder;
-
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
@@ -21,11 +20,9 @@ import java.nio.channels.Channels;
import java.nio.channels.SeekableByteChannel;
import java.util.Collection;
import java.util.Iterator;
-import java.util.Map.Entry;
-
-import org.apache.baremaps.collection.DataCollection;
-import org.apache.baremaps.feature.Feature;
-import org.apache.baremaps.feature.FeatureType;
+import org.apache.baremaps.collection.AbstractDataCollection;
+import org.apache.baremaps.dataframe.DataType;
+import org.apache.baremaps.dataframe.Row;
import org.locationtech.jts.geom.Geometry;
import org.wololo.flatgeobuf.Constants;
import org.wololo.flatgeobuf.GeometryConversions;
@@ -35,124 +32,125 @@ import org.wololo.flatgeobuf.generated.GeometryType;
public class FlatGeoBufFeatureSet {
- private final SeekableByteChannel channel;
+ private final SeekableByteChannel channel;
- private HeaderMeta headerMeta;
+ private HeaderMeta headerMeta;
- private FeatureType featureType;
+ private DataType dataType;
- public FlatGeoBufFeatureSet(SeekableByteChannel channel) {
- this.channel = channel;
- }
+ public FlatGeoBufFeatureSet(SeekableByteChannel channel) {
+ this.channel = channel;
+ }
- public FlatGeoBufFeatureSet(SeekableByteChannel channel, FeatureType featureType) {
- this.channel = channel;
- this.featureType = featureType;
- }
+ public FlatGeoBufFeatureSet(SeekableByteChannel channel, DataType dataType) {
+ this.channel = channel;
+ this.dataType = dataType;
+ }
- public FeatureType getType() throws IOException {
- readHeaderMeta();
- return featureType;
- }
+ public DataType getType() throws IOException {
+ readHeaderMeta();
+ return dataType;
+ }
- public Collection<Feature> read() throws IOException {
- readHeaderMeta();
+ public Collection<Row> read() throws IOException {
+ readHeaderMeta();
- return new DataCollection<>() {
+ return new AbstractDataCollection<>() {
- @Override
- public Iterator<Feature> iterator() {
- try {
- channel.position(headerMeta.offset);
+ @Override
+ public Iterator<Row> iterator() {
+ try {
+ channel.position(headerMeta.offset);
- // skip the index
- var indexSize =
- (int) PackedRTree.calcSize((int) headerMeta.featuresCount, headerMeta.indexNodeSize);
- channel.position(headerMeta.offset + indexSize);
+ // skip the index
+ var indexSize =
+ (int) PackedRTree.calcSize((int) headerMeta.featuresCount, headerMeta.indexNodeSize);
+ channel.position(headerMeta.offset + indexSize);
- // create the feature stream
- return new FeatureIterator(channel, headerMeta, featureType);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
+ // create the feature stream
+ return new FeatureIterator(channel, headerMeta, dataType);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
- @Override
- public long sizeAsLong() {
- return headerMeta.featuresCount;
- }
+ @Override
+ public long sizeAsLong() {
+ return headerMeta.featuresCount;
+ }
- };
- }
+ };
+ }
- public void readHeaderMeta() throws IOException {
- channel.position(0);
- var headerMetaBuffer = ByteBuffer.allocate(1 << 20).order(ByteOrder.LITTLE_ENDIAN);
- channel.read(headerMetaBuffer);
- headerMetaBuffer.flip();
- headerMeta = HeaderMeta.read(headerMetaBuffer);
- featureType = FeatureConversions.asFeatureType(headerMeta);
- }
+ public void readHeaderMeta() throws IOException {
+ channel.position(0);
+ var headerMetaBuffer = ByteBuffer.allocate(1 << 20).order(ByteOrder.LITTLE_ENDIAN);
+ channel.read(headerMetaBuffer);
+ headerMetaBuffer.flip();
+ headerMeta = HeaderMeta.read(headerMetaBuffer);
+ dataType = RowConversions.asFeatureType(headerMeta);
+ }
- public void write(Collection<Feature> features) throws IOException {
- channel.position(0);
+ public void write(Collection<Row> features) throws IOException {
+ channel.position(0);
- var outputStream = Channels.newOutputStream(channel);
+ var outputStream = Channels.newOutputStream(channel);
- outputStream.write(Constants.MAGIC_BYTES);
+ outputStream.write(Constants.MAGIC_BYTES);
- var bufferBuilder = new FlatBufferBuilder();
+ var bufferBuilder = new FlatBufferBuilder();
- var headerMeta = new HeaderMeta();
- headerMeta.geometryType = GeometryType.Unknown;
- headerMeta.indexNodeSize = 16;
- headerMeta.featuresCount = features instanceof DataCollection<Feature> c ? c.sizeAsLong() : features.size();
- headerMeta.name = featureType.getName();
- headerMeta.columns = FeatureConversions.asColumns(featureType.getPropertyTypes());
+ var headerMeta = new HeaderMeta();
+ headerMeta.geometryType = GeometryType.Unknown;
+ headerMeta.indexNodeSize = 16;
+ headerMeta.featuresCount =
+ features instanceof AbstractDataCollection<Row>c ? c.sizeAsLong() : features.size();
+ headerMeta.name = dataType.name();
+ headerMeta.columns = RowConversions.asColumns(dataType.columns());
- HeaderMeta.write(headerMeta, outputStream, bufferBuilder);
+ HeaderMeta.write(headerMeta, outputStream, bufferBuilder);
- var indexSize =
- (int) PackedRTree.calcSize((int) headerMeta.featuresCount, headerMeta.indexNodeSize);
+ var indexSize =
+ (int) PackedRTree.calcSize((int) headerMeta.featuresCount, headerMeta.indexNodeSize);
- for (int i = 0; i < indexSize; i++) {
- outputStream.write(0);
- }
+ for (int i = 0; i < indexSize; i++) {
+ outputStream.write(0);
+ }
- var iterator = features.iterator();
- while (iterator.hasNext()) {
- var feature = iterator.next();
-
- var featureBuilder = new FlatBufferBuilder();
- var geometryOffset = 0;
- var propertiesOffset = 0;
- var propertiesBuffer = ByteBuffer.allocate(1 << 20).order(ByteOrder.LITTLE_ENDIAN);
- var i = 0;
- for (Entry<String, Object> entry : feature.getProperties().entrySet()) {
- if (entry.getValue() instanceof Geometry) {
- try {
- var geometry = (Geometry) entry.getValue();
- geometryOffset = GeometryConversions.serialize(featureBuilder, geometry, headerMeta.geometryType);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- } else {
- var column = headerMeta.columns.get(i);
- var value = feature.getProperty(column.name);
- propertiesBuffer.putShort((short) i);
- FeatureConversions.writeValue(propertiesBuffer, column, value);
- i++;
- }
- }
- propertiesBuffer.flip();
- propertiesOffset = org.wololo.flatgeobuf.generated.Feature.createPropertiesVector(featureBuilder, propertiesBuffer);
-
- var featureOffset =
- org.wololo.flatgeobuf.generated.Feature.createFeature(featureBuilder, geometryOffset, propertiesOffset, 0);
-
- featureBuilder.finishSizePrefixed(featureOffset);
-
- channel.write(featureBuilder.dataBuffer());
+ var iterator = features.iterator();
+ while (iterator.hasNext()) {
+ var row = iterator.next();
+ var featureBuilder = new FlatBufferBuilder();
+ var geometryOffset = 0;
+ var propertiesOffset = 0;
+ var propertiesBuffer = ByteBuffer.allocate(1 << 20).order(ByteOrder.LITTLE_ENDIAN);
+ var i = 0;
+ for (Object value : row.values()) {
+ if (value instanceof Geometry geometry) {
+ try {
+ geometryOffset =
+ GeometryConversions.serialize(featureBuilder, geometry, headerMeta.geometryType);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ } else {
+ var column = headerMeta.columns.get(i);
+ propertiesBuffer.putShort((short) i);
+ RowConversions.writeValue(propertiesBuffer, column, value);
+ i++;
}
+ }
+ propertiesBuffer.flip();
+ propertiesOffset = org.wololo.flatgeobuf.generated.Feature
+ .createPropertiesVector(featureBuilder, propertiesBuffer);
+
+ var featureOffset =
+ org.wololo.flatgeobuf.generated.Feature.createFeature(featureBuilder, geometryOffset,
+ propertiesOffset, 0);
+
+ featureBuilder.finishSizePrefixed(featureOffset);
+
+ channel.write(featureBuilder.dataBuffer());
}
+ }
}
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/storage/flatgeobuf/FeatureConversions.java b/baremaps-core/src/main/java/org/apache/baremaps/storage/flatgeobuf/RowConversions.java
similarity index 77%
rename from baremaps-core/src/main/java/org/apache/baremaps/storage/flatgeobuf/FeatureConversions.java
rename to baremaps-core/src/main/java/org/apache/baremaps/storage/flatgeobuf/RowConversions.java
index 6e290804..53d08391 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/storage/flatgeobuf/FeatureConversions.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/storage/flatgeobuf/RowConversions.java
@@ -14,44 +14,40 @@ package org.apache.baremaps.storage.flatgeobuf;
import com.google.flatbuffers.FlatBufferBuilder;
-import org.apache.baremaps.feature.FeatureType;
-import org.apache.baremaps.feature.FeatureTypeImpl;
-import org.apache.baremaps.feature.PropertyType;
-import org.wololo.flatgeobuf.ColumnMeta;
-import org.wololo.flatgeobuf.GeometryConversions;
-import org.wololo.flatgeobuf.HeaderMeta;
-import org.wololo.flatgeobuf.generated.Column;
-import org.wololo.flatgeobuf.generated.ColumnType;
-import org.wololo.flatgeobuf.generated.Crs;
-import org.wololo.flatgeobuf.generated.Header;
-
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.WritableByteChannel;
import java.nio.charset.StandardCharsets;
-import java.util.HashMap;
+import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
+import org.apache.baremaps.dataframe.*;
+import org.wololo.flatgeobuf.ColumnMeta;
+import org.wololo.flatgeobuf.GeometryConversions;
+import org.wololo.flatgeobuf.HeaderMeta;
+import org.wololo.flatgeobuf.generated.ColumnType;
+import org.wololo.flatgeobuf.generated.Crs;
+import org.wololo.flatgeobuf.generated.Feature;
+import org.wololo.flatgeobuf.generated.Header;
-public class FeatureConversions {
+public class RowConversions {
- public static FeatureType asFeatureType(HeaderMeta headerMeta) {
+ public static DataType asFeatureType(HeaderMeta headerMeta) {
var name = headerMeta.name;
- var properties = headerMeta.columns.stream().collect(
- Collectors.toMap(
- column -> column.name,
- column -> new PropertyType(column.name, column.getBinding())));
- return new FeatureTypeImpl(name, properties);
+ var columns = headerMeta.columns.stream()
+ .map(column -> new ColumnImpl(column.name, column.getBinding()))
+ .map(Column.class::cast)
+ .toList();
+ return new DataTypeImpl(name, columns);
}
- public static org.apache.baremaps.feature.Feature asFeature(HeaderMeta headerMeta,
- FeatureType featureType, org.wololo.flatgeobuf.generated.Feature feature) {
- var properties = new HashMap<String, Object>();
+ public static RowImpl asFeature(HeaderMeta headerMeta, DataType dataType, Feature feature) {
+ var values = new ArrayList();
var geometryBuffer = feature.geometry();
var geometry = GeometryConversions.deserialize(geometryBuffer, geometryBuffer.type());
- properties.put("geometry", geometry);
+ values.add(geometry);
if (feature.propertiesLength() > 0) {
var propertiesBuffer = feature.propertiesAsByteBuffer();
@@ -59,25 +55,26 @@ public class FeatureConversions {
var type = propertiesBuffer.getShort();
var column = headerMeta.columns.get(type);
var value = readValue(propertiesBuffer, column);
- properties.put(column.name, value);
+ values.add(value);
}
}
- return new org.apache.baremaps.feature.FeatureImpl(featureType, properties);
+ return new RowImpl(dataType, values);
}
public static void writeHeaderMeta(HeaderMeta headerMeta, WritableByteChannel channel,
- FlatBufferBuilder builder) throws IOException {
+ FlatBufferBuilder builder) throws IOException {
int[] columnsArray = headerMeta.columns.stream().mapToInt(c -> {
int nameOffset = builder.createString(c.name);
int type = c.type;
- return Column.createColumn(builder, nameOffset, type, 0, 0, c.width, c.precision, c.scale, c.nullable, c.unique,
- c.primary_key, 0);
+ return org.wololo.flatgeobuf.generated.Column.createColumn(builder, nameOffset, type, 0, 0,
+ c.width, c.precision, c.scale, c.nullable, c.unique,
+ c.primary_key, 0);
}).toArray();
int columnsOffset = Header.createColumnsVector(builder, columnsArray);
int nameOffset = 0;
- if (headerMeta.name!=null) {
+ if (headerMeta.name != null) {
nameOffset = builder.createString(headerMeta.name);
}
int crsOffset = 0;
@@ -89,11 +86,12 @@ public class FeatureConversions {
int envelopeOffset = 0;
if (headerMeta.envelope != null) {
envelopeOffset = Header.createEnvelopeVector(builder,
- new double[] { headerMeta.envelope.getMinX(), headerMeta.envelope.getMinY(), headerMeta.envelope.getMaxX(), headerMeta.envelope.getMaxY() });
+ new double[] {headerMeta.envelope.getMinX(), headerMeta.envelope.getMinY(),
+ headerMeta.envelope.getMaxX(), headerMeta.envelope.getMaxY()});
}
Header.startHeader(builder);
Header.addGeometryType(builder, headerMeta.geometryType);
- Header.addIndexNodeSize(builder, headerMeta.indexNodeSize );
+ Header.addIndexNodeSize(builder, headerMeta.indexNodeSize);
Header.addColumns(builder, columnsOffset);
Header.addEnvelope(builder, envelopeOffset);
Header.addName(builder, nameOffset);
@@ -138,7 +136,8 @@ public class FeatureConversions {
case ColumnType.Json -> writeJson(propertiesBuffer, value);
case ColumnType.DateTime -> writeDateTime(propertiesBuffer, value);
case ColumnType.Binary -> writeBinary(propertiesBuffer, value);
- default -> {}
+ default -> {
+ }
};
}
@@ -189,19 +188,19 @@ public class FeatureConversions {
Double.class, ColumnType.Double,
String.class, ColumnType.String);
- public static List<ColumnMeta> asColumns(Map<String, PropertyType> propertyTypes) {
- return propertyTypes.values().stream()
- .map(FeatureConversions::asColumn)
+ public static List<ColumnMeta> asColumns(List<Column> columns) {
+ return columns.stream()
+ .map(RowConversions::asColumn)
.collect(Collectors.toList());
}
- public static ColumnMeta asColumn(PropertyType propertyType) {
- var type = types.get(propertyType.getType());
+ public static ColumnMeta asColumn(Column column) {
+ var type = types.get(column.type());
if (type == null) {
- throw new IllegalArgumentException("Unsupported type " + propertyType);
+ throw new IllegalArgumentException("Unsupported type " + type);
}
var columnMeta = new ColumnMeta();
- columnMeta.name = propertyType.getName();
+ columnMeta.name = column.name();
columnMeta.type = type.byteValue();
return columnMeta;
}
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/storage/geopackage/GeoPackageDatabase.java b/baremaps-core/src/main/java/org/apache/baremaps/storage/geopackage/GeoPackageDatabase.java
index b405315a..1b05afe5 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/storage/geopackage/GeoPackageDatabase.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/storage/geopackage/GeoPackageDatabase.java
@@ -13,17 +13,16 @@
package org.apache.baremaps.storage.geopackage;
-
-import java.io.IOException;
import java.nio.file.Path;
-import java.util.stream.Stream;
+import java.util.Collection;
import mil.nga.geopackage.GeoPackage;
import mil.nga.geopackage.GeoPackageManager;
-import org.apache.baremaps.feature.ReadableAggregate;
-import org.apache.baremaps.feature.Resource;
+import org.apache.baremaps.dataframe.DataFrame;
+import org.apache.baremaps.dataframe.DataFrameException;
+import org.apache.baremaps.dataframe.DataStore;
-public class GeoPackageDatabase implements ReadableAggregate, AutoCloseable {
+public class GeoPackageDatabase implements DataStore, AutoCloseable {
private final GeoPackage geoPackage;
@@ -32,13 +31,33 @@ public class GeoPackageDatabase implements ReadableAggregate, AutoCloseable {
}
@Override
- public Stream<Resource> read() throws IOException {
+ public void close() throws Exception {
+ geoPackage.close();
+ }
+
+ @Override
+ public Collection<DataFrame> list() throws DataFrameException {
return geoPackage.getFeatureTables().stream()
- .map(table -> new GeoPackageTable(geoPackage.getFeatureDao(table)));
+ .map(table -> new GeoPackageTable(geoPackage.getFeatureDao(table)))
+ .map(DataFrame.class::cast)
+ .toList();
}
@Override
- public void close() throws Exception {
- geoPackage.close();
+ public DataFrame get(String name) throws DataFrameException {
+ return list().stream()
+ .filter(dataFrame -> dataFrame.dataType().name().equals(name))
+ .findFirst()
+ .orElseThrow(() -> new DataFrameException());
+ }
+
+ @Override
+ public void add(DataFrame value) throws DataFrameException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void remove(String name) throws DataFrameException {
+ throw new UnsupportedOperationException();
}
}
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/storage/geopackage/GeoPackageTable.java b/baremaps-core/src/main/java/org/apache/baremaps/storage/geopackage/GeoPackageTable.java
index 9fb0e186..b406f29c 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/storage/geopackage/GeoPackageTable.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/storage/geopackage/GeoPackageTable.java
@@ -13,47 +13,33 @@
package org.apache.baremaps.storage.geopackage;
-
-import java.io.IOException;
import java.util.*;
-import java.util.stream.Stream;
-import java.util.stream.StreamSupport;
import mil.nga.geopackage.features.user.FeatureColumn;
import mil.nga.geopackage.features.user.FeatureDao;
import mil.nga.geopackage.features.user.FeatureResultSet;
import mil.nga.geopackage.geom.GeoPackageGeometryData;
-import org.apache.baremaps.feature.*;
-import org.locationtech.jts.geom.Coordinate;
-import org.locationtech.jts.geom.Geometry;
-import org.locationtech.jts.geom.GeometryCollection;
-import org.locationtech.jts.geom.GeometryFactory;
-import org.locationtech.jts.geom.LineString;
-import org.locationtech.jts.geom.LinearRing;
-import org.locationtech.jts.geom.MultiLineString;
-import org.locationtech.jts.geom.MultiPoint;
-import org.locationtech.jts.geom.MultiPolygon;
-import org.locationtech.jts.geom.Point;
-import org.locationtech.jts.geom.Polygon;
-import org.locationtech.jts.geom.PrecisionModel;
-
-public class GeoPackageTable implements ReadableFeatureSet {
+import org.apache.baremaps.collection.AbstractDataCollection;
+import org.apache.baremaps.dataframe.*;
+import org.locationtech.jts.geom.*;
+
+public class GeoPackageTable extends AbstractDataCollection<Row> implements DataFrame {
private final FeatureDao featureDao;
- private final FeatureType featureType;
+ private final DataType featureType;
private final GeometryFactory geometryFactory;
protected GeoPackageTable(FeatureDao featureDao) {
this.featureDao = featureDao;
var name = featureDao.getTableName();
- var properties = new HashMap<String, PropertyType>();
+ var columns = new ArrayList<Column>();
for (FeatureColumn column : featureDao.getColumns()) {
var propertyName = column.getName();
var propertyType = classType(column);
- properties.put(propertyName, new PropertyType(propertyName, propertyType));
+ columns.add(new ColumnImpl(propertyName, propertyType));
}
- featureType = new FeatureTypeImpl(name, properties);
+ featureType = new DataTypeImpl(name, columns);
geometryFactory = new GeometryFactory(new PrecisionModel(), (int) featureDao.getSrs().getId());
}
@@ -66,27 +52,31 @@ public class GeoPackageTable implements ReadableFeatureSet {
}
@Override
- public FeatureType getType() throws IOException {
- return featureType;
+ public Iterator<Row> iterator() {
+ return new FeatureIterator(featureDao.queryForAll(), featureType);
+ }
+
+ @Override
+ public long sizeAsLong() {
+ return 0;
}
@Override
- public Stream<Feature> read() throws IOException {
- var featureIterator = new FeatureIterator(featureDao.queryForAll(), featureType);
- return StreamSupport.stream(Spliterators.spliteratorUnknownSize(featureIterator, 0), false);
+ public DataType dataType() {
+ return null;
}
- public class FeatureIterator implements Iterator<Feature> {
+ public class FeatureIterator implements Iterator<Row> {
private final FeatureResultSet featureResultSet;
- private final FeatureType featureType;
+ private final DataType dataType;
private boolean hasNext;
- public FeatureIterator(FeatureResultSet featureResultSet, FeatureType featureType) {
+ public FeatureIterator(FeatureResultSet featureResultSet, DataType dataType) {
this.featureResultSet = featureResultSet;
- this.featureType = featureType;
+ this.dataType = dataType;
this.hasNext = featureResultSet.moveToFirst();
}
@@ -96,19 +86,19 @@ public class GeoPackageTable implements ReadableFeatureSet {
}
@Override
- public Feature next() {
+ public Row next() {
if (!hasNext) {
throw new NoSuchElementException();
}
- Feature feature = featureType.newInstance();
+ Row row = dataType.newInstance();
for (FeatureColumn featureColumn : featureResultSet.getColumns().getColumns()) {
var value = featureResultSet.getValue(featureColumn);
if (value != null) {
- feature.setProperty(featureColumn.getName(), asValue(value));
+ row.set(featureColumn.getName(), asValue(value));
}
}
hasNext = featureResultSet.moveToNext();
- return feature;
+ return row;
}
}
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/storage/postgres/PostgresTable.java b/baremaps-core/src/main/java/org/apache/baremaps/storage/postgres/PostgresDataFrame.java
similarity index 51%
rename from baremaps-core/src/main/java/org/apache/baremaps/storage/postgres/PostgresTable.java
rename to baremaps-core/src/main/java/org/apache/baremaps/storage/postgres/PostgresDataFrame.java
index d7f8407a..3c49de7c 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/storage/postgres/PostgresTable.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/storage/postgres/PostgresDataFrame.java
@@ -14,27 +14,32 @@ package org.apache.baremaps.storage.postgres;
-import java.io.IOException;
-import java.util.stream.Stream;
-import org.apache.baremaps.feature.Feature;
-import org.apache.baremaps.feature.FeatureType;
-import org.apache.baremaps.feature.WritableFeatureSet;
+import java.util.Iterator;
+import org.apache.baremaps.collection.AbstractDataCollection;
+import org.apache.baremaps.dataframe.DataFrame;
+import org.apache.baremaps.dataframe.DataType;
+import org.apache.baremaps.dataframe.Row;
-public class PostgresTable implements WritableFeatureSet {
+public class PostgresDataFrame extends AbstractDataCollection<Row> implements DataFrame {
- private final FeatureType featureType;
+ private final DataType dataType;
- public PostgresTable(FeatureType featureType) {
- this.featureType = featureType;
+ public PostgresDataFrame(DataType dataType) {
+ this.dataType = dataType;
}
@Override
- public FeatureType getType() throws IOException {
- return featureType;
+ public Iterator<Row> iterator() {
+ return null;
}
@Override
- public void write(Stream<Feature> features) throws IOException {
- throw new UnsupportedOperationException();
+ public long sizeAsLong() {
+ return 0;
+ }
+
+ @Override
+ public DataType dataType() {
+ return dataType();
}
}
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/storage/postgres/PostgresDatabase.java b/baremaps-core/src/main/java/org/apache/baremaps/storage/postgres/PostgresDatabase.java
index f7214c27..76df463a 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/storage/postgres/PostgresDatabase.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/storage/postgres/PostgresDatabase.java
@@ -13,13 +13,12 @@
package org.apache.baremaps.storage.postgres;
-
import de.bytefish.pgbulkinsert.pgsql.handlers.*;
-import java.io.IOException;
import java.sql.SQLException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
+import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -27,12 +26,12 @@ import java.util.stream.Collectors;
import javax.sql.DataSource;
import org.apache.baremaps.database.copy.CopyWriter;
import org.apache.baremaps.database.copy.PostgisGeometryValueHandler;
-import org.apache.baremaps.feature.*;
+import org.apache.baremaps.dataframe.*;
import org.locationtech.jts.geom.*;
import org.postgresql.PGConnection;
import org.postgresql.copy.PGCopyOutputStream;
-public class PostgresDatabase implements WritableAggregate {
+public class PostgresDatabase implements DataStore {
// TODO: Instantiate with Map.of()
private static Map<Class, String> typeToName = new HashMap<>();
@@ -90,108 +89,112 @@ public class PostgresDatabase implements WritableAggregate {
this.dataSource = dataSource;
}
- private FeatureType createFeatureType(FeatureType featureType) {
- var name = featureType.getName().replaceAll("[^a-zA-Z0-9]", "_");
- var properties = featureType.getPropertyTypes().values().stream()
- .filter(type -> typeToName.containsKey(type.getType()))
- .collect(Collectors.toMap(k -> k.getName(), v -> v));
- return new FeatureTypeImpl(name, properties);
+ private DataType adaptDataType(DataType datatype) {
+ var name = datatype.name().replaceAll("[^a-zA-Z0-9]", "_");
+ var properties = datatype.columns().stream()
+ .filter(columnType -> typeToName.containsKey(columnType.type()))
+ .toList();
+ return new DataTypeImpl(name, properties);
}
@Override
- public void write(Resource resource) throws IOException {
- if (resource instanceof ReadableFeatureSet featureSetReader) {
- try (var connection = dataSource.getConnection()) {
- var featureType = createFeatureType(featureSetReader.getType());
-
- // Drop the table if it exists
- var dropQuery = dropTable(featureType);
- try (var dropStatement = connection.prepareStatement(dropQuery)) {
- dropStatement.execute();
- }
+ public Collection<DataFrame> list() throws DataFrameException {
+ throw new UnsupportedOperationException();
+ }
- // Create the table
- var createQuery = createTable(featureType);
- try (var createStatement = connection.prepareStatement(createQuery)) {
- createStatement.execute();
- }
+ @Override
+ public DataFrame get(String name) throws DataFrameException {
+ throw new UnsupportedOperationException();
+ }
- // Populate the table with a copy query
- PGConnection pgConnection = connection.unwrap(PGConnection.class);
- var copyQuery = copyTable(featureType);
- try (var writer = new CopyWriter(new PGCopyOutputStream(pgConnection, copyQuery))) {
- writer.writeHeader();
- var featureIterator = featureSetReader.read().iterator();
- while (featureIterator.hasNext()) {
- var feature = featureIterator.next();
- var attributes = getAttributes(featureType);
- writer.startRow(attributes.size());
- for (var attribute : attributes) {
- var name = attribute.getName().toString();
- var value = feature.getProperty(name);
- if (value == null) {
- writer.writeNull();
- } else {
- writer.write(typeToHandler.get(value.getClass()), value);
- }
+ @Override
+ public void add(DataFrame dataFrame) {
+ try (var connection = dataSource.getConnection()) {
+ var dataType = adaptDataType(dataFrame.dataType());
+
+ // Drop the table if it exists
+ var dropQuery = dropTable(dataType);
+ try (var dropStatement = connection.prepareStatement(dropQuery)) {
+ dropStatement.execute();
+ }
+
+ // Create the table
+ var createQuery = createTable(dataType);
+ try (var createStatement = connection.prepareStatement(createQuery)) {
+ createStatement.execute();
+ }
+
+ // Populate the table with a copy query
+ PGConnection pgConnection = connection.unwrap(PGConnection.class);
+ var copyQuery = copyTable(dataType);
+ try (var writer = new CopyWriter(new PGCopyOutputStream(pgConnection, copyQuery))) {
+ writer.writeHeader();
+ var featureIterator = dataFrame.iterator();
+ while (featureIterator.hasNext()) {
+ var feature = featureIterator.next();
+ var attributes = getAttributes(dataType);
+ writer.startRow(attributes.size());
+ for (var attribute : attributes) {
+ var name = attribute.name().toString();
+ var value = feature.get(name);
+ if (value == null) {
+ writer.writeNull();
+ } else {
+ writer.write(typeToHandler.get(value.getClass()), value);
}
}
}
- } catch (SQLException e) {
- throw new IOException(e);
}
+ } catch (Exception e) {
+ throw new RuntimeException(e);
}
}
- private List<PropertyType> getAttributes(FeatureType featureType) {
- return featureType.getPropertyTypes().values().stream()
+ private List<Column> getAttributes(DataType dataType) {
+ return dataType.columns().stream()
.filter(this::isSupported).collect(Collectors.toList());
}
- private boolean isSupported(PropertyType propertyType) {
- return typeToName.containsKey(propertyType.getType());
+ private boolean isSupported(Column column) {
+ return typeToName.containsKey(column.type());
}
- private String createTable(FeatureType featureType) {
+ private String createTable(DataType dataType) {
StringBuilder builder = new StringBuilder();
builder.append("CREATE TABLE ");
- builder.append(featureType.getName());
+ builder.append(dataType.name());
builder.append(" (");
- builder.append(featureType.getPropertyTypes().values().stream()
- .map(attributeType -> attributeType.getName()
- + " " + typeToName.get(attributeType.getType()))
+ builder.append(dataType.columns().stream()
+ .map(column -> column.name()
+ + " " + typeToName.get(column.type()))
.collect(Collectors.joining(", ")));
builder.append(")");
return builder.toString();
}
- private String copyTable(FeatureType featureType) {
+ private String copyTable(DataType dataType) {
StringBuilder builder = new StringBuilder();
builder.append("COPY ");
- builder.append(featureType.getName());
+ builder.append(dataType.name());
builder.append(" (");
- builder.append(featureType.getPropertyTypes().values().stream()
- .map(propertyType -> propertyType.getName())
+ builder.append(dataType.columns().stream()
+ .map(column -> column.name())
.collect(Collectors.joining(", ")));
builder.append(") FROM STDIN BINARY");
return builder.toString();
}
@Override
- public void remove(Resource resource) throws IOException {
- if (resource instanceof FeatureSet featureSet) {
- var type = featureSet.getType();
- try (var connection = dataSource.getConnection();
- var statement = connection.createStatement()) {
- statement.executeQuery(String.format("DROP TABLE IF EXISTS %s CASCADE", type.getName()));
- } catch (SQLException e) {
- throw new RuntimeException(e);
- }
+ public void remove(String name) {
+ try (var connection = dataSource.getConnection();
+ var statement = connection.createStatement()) {
+ statement.executeQuery(String.format("DROP TABLE IF EXISTS %s CASCADE", name));
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
}
}
- private String dropTable(FeatureType type) {
- return String.format("DROP TABLE IF EXISTS %s CASCADE", type.getName());
+ private String dropTable(DataType type) {
+ return String.format("DROP TABLE IF EXISTS %s CASCADE", type.name());
}
-
}
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/storage/shapefile/ShapefileDataFrame.java b/baremaps-core/src/main/java/org/apache/baremaps/storage/shapefile/ShapefileDataFrame.java
new file mode 100644
index 00000000..8226ea26
--- /dev/null
+++ b/baremaps-core/src/main/java/org/apache/baremaps/storage/shapefile/ShapefileDataFrame.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed 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.shapefile;
+
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import org.apache.baremaps.collection.AbstractDataCollection;
+import org.apache.baremaps.dataframe.DataFrame;
+import org.apache.baremaps.dataframe.DataFrameException;
+import org.apache.baremaps.dataframe.DataType;
+import org.apache.baremaps.dataframe.Row;
+import org.apache.baremaps.storage.shapefile.internal.InputFeatureStream;
+import org.apache.baremaps.storage.shapefile.internal.ShapefileReader;
+
+public class ShapefileDataFrame extends AbstractDataCollection<Row>
+ implements DataFrame, AutoCloseable {
+
+ private final ShapefileReader shapeFile;
+
+ public ShapefileDataFrame(Path file) {
+ this.shapeFile = new ShapefileReader(file.toString());
+ }
+
+ @Override
+ public DataType dataType() throws DataFrameException {
+ try (var input = shapeFile.read()) {
+ return input.getDataType();
+ } catch (IOException e) {
+ throw new DataFrameException(e);
+ }
+ }
+
+ @Override
+ public Iterator<Row> iterator() {
+ try {
+ return new RowIterator(shapeFile.read());
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public long sizeAsLong() {
+ return 0;
+ }
+
+ @Override
+ public void close() throws Exception {
+
+ }
+
+ static class RowIterator implements Iterator<Row> {
+
+ private final InputFeatureStream inputFeatureStream;
+
+ private Row next;
+
+ public RowIterator(InputFeatureStream inputFeatureStream) {
+ this.inputFeatureStream = inputFeatureStream;
+ }
+
+
+ @Override
+ public boolean hasNext() {
+ try {
+ if (next == null) {
+ next = inputFeatureStream.readFeature();
+ }
+ return true;
+ } catch (IOException exception) {
+ return false;
+ }
+ }
+
+ @Override
+ public Row next() {
+ try {
+ if (next == null) {
+ next = inputFeatureStream.readFeature();
+ }
+ Row current = next;
+ next = null;
+ return current;
+ } catch (Exception e) {
+ throw new NoSuchElementException();
+ }
+ }
+ }
+}
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/storage/shapefile/ShapefileDirectory.java b/baremaps-core/src/main/java/org/apache/baremaps/storage/shapefile/ShapefileDirectory.java
index a187b7e1..919bc062 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/storage/shapefile/ShapefileDirectory.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/storage/shapefile/ShapefileDirectory.java
@@ -17,11 +17,12 @@ package org.apache.baremaps.storage.shapefile;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.util.stream.Stream;
-import org.apache.baremaps.feature.ReadableAggregate;
-import org.apache.baremaps.feature.Resource;
+import java.util.Collection;
+import org.apache.baremaps.dataframe.DataFrame;
+import org.apache.baremaps.dataframe.DataFrameException;
+import org.apache.baremaps.dataframe.DataStore;
-public class ShapefileDirectory implements ReadableAggregate {
+public class ShapefileDirectory implements DataStore {
private final Path directory;
@@ -30,10 +31,33 @@ public class ShapefileDirectory implements ReadableAggregate {
}
@Override
- public Stream<Resource> read() throws IOException {
- return Files.list(directory)
- .filter(file -> file.toString().toLowerCase().endsWith(".shp"))
- .map(file -> new ShapefileFeatureSet(file));
+ public Collection<DataFrame> list() {
+ try {
+ return Files.list(directory)
+ .filter(file -> file.toString().toLowerCase().endsWith(".shp"))
+ .map(file -> new ShapefileDataFrame(file))
+ .map(DataFrame.class::cast)
+ .toList();
+ } catch (IOException e) {
+ throw new DataFrameException(e);
+ }
+ }
+
+ @Override
+ public DataFrame get(String name) {
+ return list().stream()
+ .filter(dataFrame -> dataFrame.dataType().name().equals(name))
+ .findFirst()
+ .orElseThrow(() -> new DataFrameException());
+ }
+ @Override
+ public void add(DataFrame value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void remove(String name) {
+ throw new UnsupportedOperationException();
}
}
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/storage/shapefile/ShapefileFeatureSet.java b/baremaps-core/src/main/java/org/apache/baremaps/storage/shapefile/ShapefileFeatureSet.java
deleted file mode 100644
index bf688b8b..00000000
--- a/baremaps-core/src/main/java/org/apache/baremaps/storage/shapefile/ShapefileFeatureSet.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Licensed 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.shapefile;
-
-
-
-import java.io.IOException;
-import java.nio.file.Path;
-import java.util.Spliterator;
-import java.util.function.Consumer;
-import java.util.stream.Stream;
-import java.util.stream.StreamSupport;
-import org.apache.baremaps.feature.Feature;
-import org.apache.baremaps.feature.FeatureType;
-import org.apache.baremaps.feature.ReadableFeatureSet;
-import org.apache.baremaps.storage.shapefile.internal.InputFeatureStream;
-import org.apache.baremaps.storage.shapefile.internal.ShapefileReader;
-
-public class ShapefileFeatureSet implements ReadableFeatureSet, AutoCloseable {
-
- private final ShapefileReader shapeFile;
-
- public ShapefileFeatureSet(Path file) {
- this.shapeFile = new ShapefileReader(file.toString());
- }
-
- @Override
- public FeatureType getType() throws IOException {
- try (var input = shapeFile.read()) {
- return input.getFeaturesType();
- }
- }
-
- @Override
- public Stream<Feature> read() throws IOException {
- return StreamSupport.stream(new FeatureSpliterator(shapeFile.read()), false);
- }
-
- static class FeatureSpliterator implements Spliterator<Feature> {
-
- private final InputFeatureStream inputFeatureStream;
-
- public FeatureSpliterator(InputFeatureStream inputFeatureStream) {
- this.inputFeatureStream = inputFeatureStream;
- }
-
- @Override
- public boolean tryAdvance(Consumer<? super Feature> action) {
- try {
- var feature = inputFeatureStream.readFeature();
- if (feature != null) {
- action.accept(feature);
- return true;
- } else {
- return false;
- }
- } catch (Exception e) {
- return false;
- }
- }
-
- @Override
- public Spliterator<Feature> trySplit() {
- return null;
- }
-
- @Override
- public long estimateSize() {
- return Long.MAX_VALUE;
- }
-
- @Override
- public int characteristics() {
- return 0;
- }
- }
-
- @Override
- public void close() throws Exception {
-
- }
-}
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/storage/shapefile/internal/DbaseByteReader.java b/baremaps-core/src/main/java/org/apache/baremaps/storage/shapefile/internal/DbaseByteReader.java
index 13eea12e..e48a1e0d 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/storage/shapefile/internal/DbaseByteReader.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/storage/shapefile/internal/DbaseByteReader.java
@@ -22,7 +22,7 @@ import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
import java.text.MessageFormat;
import java.util.*;
-import org.apache.baremaps.feature.Feature;
+import org.apache.baremaps.dataframe.Row;
/**
* Reader of a Database Binary content.
@@ -99,9 +99,9 @@ public class DbaseByteReader extends CommonByteReader implements AutoCloseable {
/**
* Load a row into a feature.
*
- * @param feature Feature to fill.
+ * @param row Feature to fill.
*/
- public void loadRowIntoFeature(Feature feature) {
+ public void loadRow(Row row) {
// TODO: ignore deleted records
getByteBuffer().get(); // denotes whether deleted or current
// read first part of record
@@ -138,7 +138,7 @@ public class DbaseByteReader extends CommonByteReader implements AutoCloseable {
case DateTime -> value;
};
- feature.setProperty(fd.getName(), object);
+ row.set(fd.getName(), object);
}
}
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/storage/shapefile/internal/InputFeatureStream.java b/baremaps-core/src/main/java/org/apache/baremaps/storage/shapefile/internal/InputFeatureStream.java
index 89849c6a..7fb8d72e 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/storage/shapefile/internal/InputFeatureStream.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/storage/shapefile/internal/InputFeatureStream.java
@@ -19,8 +19,8 @@ import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLFeatureNotSupportedException;
import java.util.List;
-import org.apache.baremaps.feature.Feature;
-import org.apache.baremaps.feature.FeatureType;
+import org.apache.baremaps.dataframe.DataType;
+import org.apache.baremaps.dataframe.Row;
/**
* Input Stream of features.
@@ -48,7 +48,7 @@ public class InputFeatureStream extends InputStream {
private boolean hasShapefileIndex;
/** Type of the features contained in this shapefile. */
- private FeatureType featuresType;
+ private DataType dataType;
/** Shapefile reader. */
private ShapefileByteReader shapefileReader;
@@ -74,7 +74,7 @@ public class InputFeatureStream extends InputStream {
this.shapefileReader =
new ShapefileByteReader(this.shapefile, this.databaseFile, this.shapefileIndex);
- this.featuresType = this.shapefileReader.getFeaturesType();
+ this.dataType = this.shapefileReader.getDataType();
}
/**
@@ -113,7 +113,7 @@ public class InputFeatureStream extends InputStream {
* @throws ShapefileException if the current connection used to query the shapefile has been
* closed.
*/
- public Feature readFeature() throws ShapefileException {
+ public Row readFeature() throws ShapefileException {
return internalReadFeature();
}
@@ -122,8 +122,8 @@ public class InputFeatureStream extends InputStream {
*
* @return Features type.
*/
- public FeatureType getFeaturesType() {
- return featuresType;
+ public DataType getDataType() {
+ return dataType;
}
/**
@@ -160,14 +160,14 @@ public class InputFeatureStream extends InputStream {
* @throws SQLFeatureNotSupportedException if a SQL ability is not currently available through
* this driver.
*/
- private Feature internalReadFeature() throws ShapefileException {
+ private Row internalReadFeature() throws ShapefileException {
if (!this.dbaseReader.nextRowAvailable()) {
return null;
}
- Feature feature = this.featuresType.newInstance();
- this.dbaseReader.loadRowIntoFeature(feature);
+ Row row = this.dataType.newInstance();
+ this.dbaseReader.loadRow(row);
this.shapefileReader.setRowNum(this.dbaseReader.getRowNum());
- this.shapefileReader.completeFeature(feature);
- return feature;
+ this.shapefileReader.completeFeature(row);
+ return row;
}
}
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/storage/shapefile/internal/ShapefileByteReader.java b/baremaps-core/src/main/java/org/apache/baremaps/storage/shapefile/internal/ShapefileByteReader.java
index 8dbb3fbd..a7572903 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/storage/shapefile/internal/ShapefileByteReader.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/storage/shapefile/internal/ShapefileByteReader.java
@@ -19,10 +19,7 @@ import java.nio.ByteOrder;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.util.*;
-import org.apache.baremaps.feature.Feature;
-import org.apache.baremaps.feature.FeatureType;
-import org.apache.baremaps.feature.FeatureTypeImpl;
-import org.apache.baremaps.feature.PropertyType;
+import org.apache.baremaps.dataframe.*;
import org.locationtech.jts.algorithm.Orientation;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.CoordinateList;
@@ -48,7 +45,7 @@ public class ShapefileByteReader extends CommonByteReader {
private List<DBaseFieldDescriptor> databaseFieldsDescriptors;
/** Type of the features contained in this shapefile. */
- private FeatureType featuresType;
+ private DataType dataType;
/** Shapefile index. */
private File shapeFileIndex;
@@ -83,7 +80,7 @@ public class ShapefileByteReader extends CommonByteReader {
loadShapefileIndexes();
}
- this.featuresType = getFeatureType(shapefile.getName());
+ this.dataType = getDataType(shapefile.getName());
}
/**
@@ -109,8 +106,8 @@ public class ShapefileByteReader extends CommonByteReader {
*
* @return Features type.
*/
- public FeatureType getFeaturesType() {
- return this.featuresType;
+ public DataType getDataType() {
+ return this.dataType;
}
/**
@@ -119,13 +116,12 @@ public class ShapefileByteReader extends CommonByteReader {
* @param name Name of the field.
* @return The feature type.
*/
- private FeatureType getFeatureType(final String name) {
+ private DataType getDataType(final String name) {
Objects.requireNonNull(name, "The feature name cannot be null.");
- var properties = new HashMap<String, PropertyType>();
+ var columns = new ArrayList<Column>();
for (int i = 0; i < databaseFieldsDescriptors.size(); i++) {
var fieldDescriptor = this.databaseFieldsDescriptors.get(i);
-
var propertyName = fieldDescriptor.getName();
var propertyType = switch (fieldDescriptor.getType()) {
case Character -> String.class;
@@ -147,13 +143,13 @@ public class ShapefileByteReader extends CommonByteReader {
case DateTime -> String.class;
};
- properties.put(propertyName, new PropertyType(propertyName, propertyType));
+ columns.add(new ColumnImpl(propertyName, propertyType));
}
- // Add geometry field.
- properties.put(GEOMETRY_NAME, new PropertyType(GEOMETRY_NAME, Geometry.class));
+ // Add geometry column.
+ columns.add(new ColumnImpl(GEOMETRY_NAME, Geometry.class));
- return new FeatureTypeImpl(name, properties);
+ return new DataTypeImpl(name, columns);
}
/** Load shapefile descriptor. */
@@ -260,7 +256,7 @@ public class ShapefileByteReader extends CommonByteReader {
*
* @param feature Feature to complete.
*/
- public void completeFeature(Feature feature) throws ShapefileException {
+ public void completeFeature(Row feature) throws ShapefileException {
// insert points into some type of list
int RecordNumber = getByteBuffer().getInt();
int ContentLength = getByteBuffer().getInt();
@@ -300,11 +296,11 @@ public class ShapefileByteReader extends CommonByteReader {
*
* @param feature Feature to fill.
*/
- private void loadPointFeature(Feature feature) {
+ private void loadPointFeature(Row feature) {
double x = getByteBuffer().getDouble();
double y = getByteBuffer().getDouble();
Point pnt = geometryFactory.createPoint(new Coordinate(x, y));
- feature.setProperty(GEOMETRY_NAME, pnt);
+ feature.set(GEOMETRY_NAME, pnt);
}
/**
@@ -312,7 +308,7 @@ public class ShapefileByteReader extends CommonByteReader {
*
* @param feature Feature to fill.
*/
- private void loadPolygonFeature(Feature feature) {
+ private void loadPolygonFeature(Row feature) {
double xmin = getByteBuffer().getDouble();
double ymin = getByteBuffer().getDouble();
double xmax = getByteBuffer().getDouble();
@@ -323,7 +319,7 @@ public class ShapefileByteReader extends CommonByteReader {
Geometry multiPolygon = readMultiplePolygon(numParts, numPoints);
- feature.setProperty(GEOMETRY_NAME, multiPolygon);
+ feature.set(GEOMETRY_NAME, multiPolygon);
}
/**
@@ -388,7 +384,7 @@ public class ShapefileByteReader extends CommonByteReader {
*
* @param feature Feature to fill.
*/
- private void loadPolylineFeature(Feature feature) {
+ private void loadPolylineFeature(Row feature) {
/* double xmin = */ getByteBuffer().getDouble();
/* double ymin = */ getByteBuffer().getDouble();
/* double xmax = */ getByteBuffer().getDouble();
@@ -420,7 +416,7 @@ public class ShapefileByteReader extends CommonByteReader {
}
}
- feature.setProperty(GEOMETRY_NAME,
+ feature.set(GEOMETRY_NAME,
geometryFactory.createLineString(coordinates.toCoordinateArray()));
}
}
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/storage/shapefile/internal/ShapefileReader.java b/baremaps-core/src/main/java/org/apache/baremaps/storage/shapefile/internal/ShapefileReader.java
index 97625402..9d5314ec 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/storage/shapefile/internal/ShapefileReader.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/storage/shapefile/internal/ShapefileReader.java
@@ -18,7 +18,7 @@ import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
-import org.apache.baremaps.feature.FeatureType;
+import org.apache.baremaps.dataframe.DataType;
/**
* Provides a ShapeFile Reader.
@@ -44,7 +44,7 @@ public class ShapefileReader {
private File shapeFileIndex;
/** Type of the features contained in this shapefile. */
- private FeatureType featuresType;
+ private DataType dataType;
/** Shapefile descriptor. */
private ShapefileDescriptor shapefileDescriptor;
@@ -117,8 +117,8 @@ public class ShapefileReader {
*
* @return Feature type.
*/
- public FeatureType getFeaturesType() {
- return this.featuresType;
+ public DataType getDataType() {
+ return this.dataType;
}
/**
@@ -174,7 +174,7 @@ public class ShapefileReader {
public InputFeatureStream read() throws IOException {
InputFeatureStream is =
new InputFeatureStream(this.shapefile, this.databaseFile, this.shapeFileIndex);
- this.featuresType = is.getFeaturesType();
+ this.dataType = is.getDataType();
this.shapefileDescriptor = is.getShapefileDescriptor();
this.databaseFieldsDescriptors = is.getDatabaseFieldsDescriptors();
return is;
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/Entity.java b/baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/Entity.java
index 17a8d336..b173a0c2 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/Entity.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/Entity.java
@@ -12,15 +12,13 @@
package org.apache.baremaps.workflow.tasks;
-import java.util.HashMap;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
-import org.apache.baremaps.feature.Feature;
-import org.apache.baremaps.feature.FeatureType;
-import org.apache.baremaps.feature.FeatureTypeImpl;
-import org.apache.baremaps.feature.PropertyType;
+import org.apache.baremaps.dataframe.*;
import org.locationtech.jts.geom.Geometry;
-public class Entity implements Feature {
+public class Entity implements Row {
private long id;
@@ -36,23 +34,23 @@ public class Entity implements Feature {
@Override
- public FeatureType getType() {
- var map = new HashMap<String, PropertyType>();
- map.put("id", new PropertyType<>("id", Long.class));
+ public DataType dataType() {
+ var columns = new ArrayList<Column>();
+ columns.add(new ColumnImpl("id", Long.class));
+ columns.add(new ColumnImpl("geometry", Geometry.class));
for (var entry : tags.entrySet()) {
- map.put(entry.getKey(), new PropertyType<>(entry.getKey(), String.class));
+ columns.add(new ColumnImpl(entry.getKey(), String.class));
}
- map.put("geometry", new PropertyType<>("geometry", Geometry.class));
- return new FeatureTypeImpl("entity", map);
+ return new DataTypeImpl("entity", columns);
}
@Override
- public void setProperty(String name, Object value) {
+ public void set(String name, Object value) {
tags.put(name, value.toString());
}
@Override
- public Object getProperty(String name) {
+ public Object get(String name) {
if (name.equals("id")) {
return id;
} else if (name.equals("geometry")) {
@@ -63,11 +61,11 @@ public class Entity implements Feature {
}
@Override
- public Map<String, Object> getProperties() {
- var map = new HashMap<String, Object>();
- map.put("id", id);
- map.putAll(tags);
- map.put("geometry", geometry);
+ public List<Object> values() {
+ var map = new ArrayList();
+ map.add(id);
+ map.add(geometry);
+ map.addAll(tags.values());
return map;
}
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 6ec56f67..735127df 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,9 +13,8 @@
package org.apache.baremaps.workflow.tasks;
import java.nio.file.Path;
-import org.apache.baremaps.feature.ReadableFeatureSet;
import org.apache.baremaps.openstreetmap.utils.ProjectionTransformer;
-import org.apache.baremaps.storage.FeatureSetProjectionTransform;
+import org.apache.baremaps.storage.DataFrameProjectionTransform;
import org.apache.baremaps.storage.geopackage.GeoPackageDatabase;
import org.apache.baremaps.storage.postgres.PostgresDatabase;
import org.apache.baremaps.workflow.Task;
@@ -37,12 +36,10 @@ public record ImportGeoPackage(Path file, String database, Integer sourceSRID, I
try (var geoPackageStore = new GeoPackageDatabase(path)) {
var dataSource = context.getDataSource(database);
var postgresDatabase = new PostgresDatabase(dataSource);
- for (var resource : geoPackageStore.read().toList()) {
- if (resource instanceof ReadableFeatureSet featureSet) {
- var transformer = new ProjectionTransformer(sourceSRID, targetSRID);
- var transformedFeatureSet = new FeatureSetProjectionTransform(featureSet, transformer);
- postgresDatabase.write(transformedFeatureSet);
- }
+ for (var dataFrame : geoPackageStore.list()) {
+ var transformer = new ProjectionTransformer(sourceSRID, targetSRID);
+ var transformedDataFrame = new DataFrameProjectionTransform(dataFrame, transformer);
+ postgresDatabase.add(transformedDataFrame);
}
logger.info("Finished importing {} into {}", file, database);
} catch (Exception e) {
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 ca0b3208..4582efe6 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
@@ -14,9 +14,9 @@ package org.apache.baremaps.workflow.tasks;
import java.nio.file.Path;
import org.apache.baremaps.openstreetmap.utils.ProjectionTransformer;
-import org.apache.baremaps.storage.FeatureSetProjectionTransform;
+import org.apache.baremaps.storage.DataFrameProjectionTransform;
import org.apache.baremaps.storage.postgres.PostgresDatabase;
-import org.apache.baremaps.storage.shapefile.ShapefileFeatureSet;
+import org.apache.baremaps.storage.shapefile.ShapefileDataFrame;
import org.apache.baremaps.workflow.Task;
import org.apache.baremaps.workflow.WorkflowContext;
import org.apache.baremaps.workflow.WorkflowException;
@@ -33,10 +33,10 @@ public record ImportShapefile(Path file, String database, Integer sourceSRID, In
public void execute(WorkflowContext context) throws Exception {
logger.info("Importing {} into {}", file, database);
var path = file.toAbsolutePath();
- try (var featureSet = new ShapefileFeatureSet(path)) {
+ try (var featureSet = new ShapefileDataFrame(path)) {
var dataSource = context.getDataSource(database);
var postgresDatabase = new PostgresDatabase(dataSource);
- postgresDatabase.write(new FeatureSetProjectionTransform(
+ postgresDatabase.add(new DataFrameProjectionTransform(
featureSet, new ProjectionTransformer(sourceSRID, targetSRID)));
logger.info("Finished importing {} into {}", file, database);
} catch (Exception e) {
diff --git a/baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/TransformEntityCollection.java b/baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/TransformEntityCollection.java
index b39a06f9..f2cc47b3 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/TransformEntityCollection.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/TransformEntityCollection.java
@@ -15,15 +15,15 @@ package org.apache.baremaps.workflow.tasks;
import java.nio.file.Path;
import java.util.ArrayList;
-import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
-import java.util.Map;
import java.util.stream.Collectors;
+import java.util.stream.IntStream;
import java.util.stream.Stream;
import org.apache.baremaps.collection.AppendOnlyBuffer;
import org.apache.baremaps.collection.algorithm.UnionStream;
import org.apache.baremaps.collection.memory.MemoryMappedFile;
-import org.apache.baremaps.feature.*;
+import org.apache.baremaps.dataframe.*;
import org.apache.baremaps.mvt.expression.Expressions.Expression;
import org.apache.baremaps.storage.postgres.PostgresDatabase;
import org.apache.baremaps.workflow.Task;
@@ -53,25 +53,42 @@ public record TransformEntityCollection(Path collection, String database,
public void execute(WorkflowContext context) throws Exception {
logger.info("Transform {} with {}", collection, recipe);
- var featureType = new FeatureTypeImpl(recipe.name, propertyTypes());
+ var dataType = new DataTypeImpl(recipe.name, columns());
var groups = new AppendOnlyBuffer<>(new EntityDataType(), new MemoryMappedFile(collection))
.stream()
.filter(this::filter)
.collect(Collectors.groupingBy(this::propertyValues));
- var featureStream = groups.entrySet().stream().flatMap(entry -> {
- var group = entry.getKey();
- var entities = entry.getValue();
- var geometries = simplify(entities.stream().map(Entity::getGeometry));
- return geometries.map(geometry -> new Entity(0, group, geometry));
+ var entityStream = groups.entrySet().stream().flatMap(entry -> {
+ var tags = IntStream.range(0, recipe.groupBy.size()).boxed()
+ .collect(Collectors.toMap(i -> recipe.groupBy.get(i), i -> entry.getKey().get(i)));
+ var geometries = entry.getValue();
+ var simplified = simplify(geometries.stream().map(Entity::getGeometry));
+ return simplified.map(geometry -> (Row) new Entity(0, tags, geometry));
});
- var featureSet = new ReadableFeatureStream(featureType, featureStream);
+ var dataFrame = new AbstractDataFrame() {
+
+ @Override
+ public DataType dataType() {
+ return dataType;
+ }
+
+ @Override
+ public long sizeAsLong() {
+ return 0;
+ }
+
+ @Override
+ public Iterator<Row> iterator() {
+ return entityStream.iterator();
+ }
+ };
var dataSource = context.getDataSource(database);
var postgresDatabase = new PostgresDatabase(dataSource);
- postgresDatabase.write(featureSet);
+ postgresDatabase.add(dataFrame);
}
private Stream<Geometry> simplify(Stream<Geometry> geometries) {
@@ -86,19 +103,19 @@ public record TransformEntityCollection(Path collection, String database,
return recipe.groupBy() == null ? List.of() : recipe.groupBy();
}
- private Map<String, PropertyType> propertyTypes() {
- var map = new HashMap<String, PropertyType>();
+ private List<Column> columns() {
+ var list = new ArrayList<Column>();
for (var property : groupBy()) {
- map.put(property, new PropertyType<>(property, String.class));
+ list.add(new ColumnImpl(property, String.class));
}
- map.put("geometry", new PropertyType<>("geometry", Geometry.class));
- return map;
+ list.add(new ColumnImpl("geometry", Geometry.class));
+ return list;
}
- private Map<String, String> propertyValues(Entity entity) {
- var map = new HashMap<String, String>();
+ private List<String> propertyValues(Entity entity) {
+ var map = new ArrayList<String>();
for (var property : groupBy()) {
- map.put(property, entity.getProperty(property).toString());
+ map.add(entity.get(property).toString());
}
return map;
}
diff --git a/baremaps-core/src/test/java/org/apache/baremaps/mvt/ExpressionsTest.java b/baremaps-core/src/test/java/org/apache/baremaps/mvt/ExpressionsTest.java
index f6bd831b..83e7b80b 100644
--- a/baremaps-core/src/test/java/org/apache/baremaps/mvt/ExpressionsTest.java
+++ b/baremaps-core/src/test/java/org/apache/baremaps/mvt/ExpressionsTest.java
@@ -17,34 +17,34 @@ import static org.junit.jupiter.api.Assertions.*;
import java.io.IOException;
import java.util.List;
import java.util.Map;
-import org.apache.baremaps.feature.Feature;
-import org.apache.baremaps.feature.FeatureType;
+import org.apache.baremaps.dataframe.DataType;
+import org.apache.baremaps.dataframe.Row;
import org.apache.baremaps.mvt.expression.Expressions;
import org.apache.baremaps.mvt.expression.Expressions.*;
import org.junit.jupiter.api.Test;
class ExpressionsTest {
- record FeatureMock(Map<String, Object> properties) implements Feature {
+ record RowMock(Map<String, Object> properties) implements Row {
@Override
- public FeatureType getType() {
+ public DataType dataType() {
throw new UnsupportedOperationException();
}
@Override
- public void setProperty(String name, Object value) {
- properties.put(name, value);
+ public List<Object> values() {
+ return properties.values().stream().toList();
}
@Override
- public Object getProperty(String name) {
- return properties.get(name);
+ public void set(String name, Object value) {
+ properties.put(name, value);
}
@Override
- public Map<String, Object> getProperties() {
- return properties;
+ public Object get(String name) {
+ return properties.get(name);
}
}
@@ -68,15 +68,15 @@ class ExpressionsTest {
@Test
public void get() throws IOException {
assertEquals("value",
- new Get("key").evaluate(new FeatureMock(Map.of("key", "value"))));
- assertEquals(null, new Get("key").evaluate(new FeatureMock(Map.of())));
+ new Get("key").evaluate(new RowMock(Map.of("key", "value"))));
+ assertEquals(null, new Get("key").evaluate(new RowMock(Map.of())));
}
@Test
public void has() throws IOException {
assertEquals(true,
- new Has("key").evaluate(new FeatureMock(Map.of("key", "value"))));
- assertEquals(false, new Has("key").evaluate(new FeatureMock(Map.of())));
+ new Has("key").evaluate(new RowMock(Map.of("key", "value"))));
+ assertEquals(false, new Has("key").evaluate(new RowMock(Map.of())));
}
@Test
diff --git a/baremaps-core/src/test/java/org/apache/baremaps/storage/flatgeobuf/FlatGeoBufFeatureSetTest.java b/baremaps-core/src/test/java/org/apache/baremaps/storage/flatgeobuf/FlatGeoBufFeatureSetTest.java
index 3c17ea83..a47088be 100644
--- a/baremaps-core/src/test/java/org/apache/baremaps/storage/flatgeobuf/FlatGeoBufFeatureSetTest.java
+++ b/baremaps-core/src/test/java/org/apache/baremaps/storage/flatgeobuf/FlatGeoBufFeatureSetTest.java
@@ -18,7 +18,6 @@ import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
-
import org.apache.baremaps.testing.TestFiles;
import org.junit.jupiter.api.Test;
@@ -29,8 +28,8 @@ class FlatGeoBufFeatureSetTest {
try (var channel = FileChannel.open(TestFiles.resolve("countries.fgb"))) {
var featureSet = new FlatGeoBufFeatureSet(channel);
var featureType = featureSet.getType();
- assertEquals(featureType.getName(), null);
- assertEquals(featureType.getPropertyTypes().size(), 2);
+ assertEquals(featureType.name(), null);
+ assertEquals(featureType.columns().size(), 2);
}
}
@@ -48,7 +47,7 @@ class FlatGeoBufFeatureSetTest {
var file = Files.createTempFile("countries", ".fgb");
file.toFile().deleteOnExit();
try (var channel1 = FileChannel.open(TestFiles.resolve("countries.fgb"));
- var channel2 = FileChannel.open(file, StandardOpenOption.WRITE)) {
+ var channel2 = FileChannel.open(file, StandardOpenOption.WRITE)) {
var featureSet1 = new FlatGeoBufFeatureSet(channel1);
var featureList = featureSet1.read().stream().toList();
var featureSet2 = new FlatGeoBufFeatureSet(channel2, featureSet1.getType());