This is an automated email from the ASF dual-hosted git repository.

bchapuis pushed a commit to branch simplify-geometries
in repository https://gitbox.apache.org/repos/asf/incubator-baremaps.git


The following commit(s) were added to refs/heads/simplify-geometries by this 
push:
     new 4660ce35 Create and simplify collections
4660ce35 is described below

commit 4660ce35658e7b247bbfd8deaa88ae746bf1c86c
Author: Bertil Chapuis <[email protected]>
AuthorDate: Wed Feb 15 00:58:15 2023 +0100

    Create and simplify collections
---
 .../baremaps/collection/AppendOnlyBuffer.java      |  10 +-
 .../baremaps/collection/type/ListDataType.java     |   3 +-
 .../baremaps/collection/type/MapDataType.java      |  70 ++++++++++
 .../baremaps/mvt/expression/Expressions.java       |  32 ++++-
 .../baremaps/openstreetmap/CollectionUtils.java    |   1 -
 .../workflow/tasks/CreateEntityCollection.java     |  97 +++++++++++++
 .../org/apache/baremaps/workflow/tasks/Entity.java |  74 ++++++++++
 .../baremaps/workflow/tasks/EntityDataType.java    |  64 +++++++++
 .../workflow/tasks/SimplifyEntityCollection.java   |  91 ++++++++++++
 .../workflow/tasks/SimplifyOpenStreetMap.java      | 155 ---------------------
 .../baremaps/collection/type/DataTypeProvider.java |  10 +-
 .../baremaps/collection/type/DataTypeTest.java     |   6 +-
 ...java => EntityDataTypeGeometryBuilderTest.java} |   2 +-
 ....java => XmlEntitySpliteratorTestDataType.java} |   2 +-
 ... => CreateAndSimplifyEntityCollectionTest.java} |  19 ++-
 15 files changed, 464 insertions(+), 172 deletions(-)

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 cb775ae7..19ffb6c4 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
@@ -60,8 +60,8 @@ public class AppendOnlyBuffer<E> extends DataCollection<E> {
     this.dataType = dataType;
     this.memory = memory;
     this.segmentSize = memory.segmentSize();
-    this.offset = 0;
-    this.size = 0;
+    this.offset = Long.BYTES;
+    this.size = memory.segment(0).getLong(0);
   }
 
   /**
@@ -122,6 +122,10 @@ public class AppendOnlyBuffer<E> extends DataCollection<E> 
{
     return size;
   }
 
+  public void close() {
+    memory.segment(0).putLong(0, size);
+  }
+
   /** {@inheritDoc} */
   @Override
   public void clear() {
@@ -142,7 +146,7 @@ public class AppendOnlyBuffer<E> extends DataCollection<E> {
 
       private long index = 0;
 
-      private long position = 0;
+      private long position = Long.BYTES;
 
       @Override
       public boolean hasNext() {
diff --git 
a/baremaps-core/src/main/java/org/apache/baremaps/collection/type/ListDataType.java
 
b/baremaps-core/src/main/java/org/apache/baremaps/collection/type/ListDataType.java
index ed5b6329..63737368 100644
--- 
a/baremaps-core/src/main/java/org/apache/baremaps/collection/type/ListDataType.java
+++ 
b/baremaps-core/src/main/java/org/apache/baremaps/collection/type/ListDataType.java
@@ -53,9 +53,10 @@ public class ListDataType<T> implements DataType<List<T>> {
   @Override
   public void write(ByteBuffer buffer, int position, List<T> values) {
     buffer.putInt(position, size(values));
+    position += Integer.BYTES;
     for (T value : values) {
-      position += dataType.size(value);
       dataType.write(buffer, position, value);
+      position += dataType.size(value);
     }
   }
 
diff --git 
a/baremaps-core/src/main/java/org/apache/baremaps/collection/type/MapDataType.java
 
b/baremaps-core/src/main/java/org/apache/baremaps/collection/type/MapDataType.java
new file mode 100644
index 00000000..dbf98c4a
--- /dev/null
+++ 
b/baremaps-core/src/main/java/org/apache/baremaps/collection/type/MapDataType.java
@@ -0,0 +1,70 @@
+/*
+ * 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.collection.type;
+
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.Map;
+
+public class MapDataType<K, V> implements DataType<Map<K, V>> {
+
+  private final DataType<K> keyType;
+
+  private final DataType<V> valueType;
+
+  public MapDataType(DataType<K> keyType, DataType<V> valueType) {
+    this.keyType = keyType;
+    this.valueType = valueType;
+  }
+
+  @Override
+  public int size(Map<K, V> value) {
+    int size = Integer.BYTES;
+    for (Map.Entry<K, V> entry : value.entrySet()) {
+      size += keyType.size(entry.getKey());
+      size += valueType.size(entry.getValue());
+    }
+    return size;
+  }
+
+  @Override
+  public int size(ByteBuffer buffer, int position) {
+    return buffer.getInt(position);
+  }
+
+  @Override
+  public void write(ByteBuffer buffer, int position, Map<K, V> value) {
+    buffer.putInt(position, size(value));
+    position += Integer.BYTES;
+    for (Map.Entry<K, V> entry : value.entrySet()) {
+      keyType.write(buffer, position, entry.getKey());
+      position += keyType.size(entry.getKey());
+      valueType.write(buffer, position, entry.getValue());
+      position += valueType.size(entry.getValue());
+    }
+  }
+
+  @Override
+  public Map<K, V> read(ByteBuffer buffer, int position) {
+    int size = buffer.getInt(position);
+    Map<K, V> map = new HashMap<>(size);
+    for (int p = position + Integer.BYTES; p < position + size;) {
+      K key = keyType.read(buffer, p);
+      p += keyType.size(key);
+      V value = valueType.read(buffer, p);
+      p += valueType.size(value);
+      map.put(key, value);
+    }
+    return map;
+  }
+}
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 30396b4e..3d48ff3a 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,6 +32,7 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.function.Predicate;
 import org.apache.baremaps.feature.Feature;
+import org.locationtech.jts.geom.*;
 
 public interface Expressions {
 
@@ -378,6 +379,36 @@ public interface Expressions {
     }
   }
 
+  record GeometryType(Expression expression) implements Expression<String> {
+
+    @Override
+    public String name() {
+      return "geometry-type";
+    }
+
+    @Override
+    public String evaluate(Feature feature) {
+      Object property = feature.getProperty("geom");
+      if (property instanceof Point) {
+        return "Point";
+      } else if (property instanceof LineString) {
+        return "LineString";
+      } else if (property instanceof Polygon) {
+        return "Polygon";
+      } else if (property instanceof MultiPoint) {
+        return "MultiPoint";
+      } else if (property instanceof MultiLineString) {
+        return "MultiLineString";
+      } else if (property instanceof MultiPolygon) {
+        return "MultiPolygon";
+      } else if (property instanceof GeometryCollection) {
+        return "GeometryCollection";
+      } else {
+        return "Unknown";
+      }
+    }
+  }
+
 
   class ExpressionSerializer extends StdSerializer<Expression> {
 
@@ -407,7 +438,6 @@ public interface Expressions {
     }
   }
 
-
   class ExpressionDeserializer extends StdDeserializer<Expression> {
 
     protected ExpressionDeserializer() {
diff --git 
a/baremaps-core/src/main/java/org/apache/baremaps/openstreetmap/CollectionUtils.java
 
b/baremaps-core/src/main/java/org/apache/baremaps/openstreetmap/CollectionUtils.java
index a2841fe5..d0f1fc81 100644
--- 
a/baremaps-core/src/main/java/org/apache/baremaps/openstreetmap/CollectionUtils.java
+++ 
b/baremaps-core/src/main/java/org/apache/baremaps/openstreetmap/CollectionUtils.java
@@ -30,7 +30,6 @@ public class CollectionUtils {
 
   private CollectionUtils() {}
 
-
   public static DataMap<Coordinate> denseCoordinateMap() throws IOException {
     var cacheDir = Files.createTempDirectory(Paths.get("."), "coordinates_");
     var coordinatesFile = Files.createFile(cacheDir.resolve("values"));
diff --git 
a/baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/CreateEntityCollection.java
 
b/baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/CreateEntityCollection.java
new file mode 100644
index 00000000..d2a14557
--- /dev/null
+++ 
b/baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/CreateEntityCollection.java
@@ -0,0 +1,97 @@
+/*
+ * 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.workflow.tasks;
+
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.HashMap;
+import org.apache.baremaps.collection.AppendOnlyBuffer;
+import org.apache.baremaps.collection.MemoryAlignedDataList;
+import org.apache.baremaps.collection.MonotonicDataMap;
+import org.apache.baremaps.collection.memory.MemoryMappedFile;
+import org.apache.baremaps.collection.type.*;
+import org.apache.baremaps.collection.utils.FileUtils;
+import org.apache.baremaps.openstreetmap.model.*;
+import org.apache.baremaps.openstreetmap.pbf.PbfEntityReader;
+import org.apache.baremaps.openstreetmap.utils.ProjectionTransformer;
+import org.apache.baremaps.workflow.Task;
+import org.apache.baremaps.workflow.WorkflowContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public record CreateEntityCollection(Path file, Path collection,
+    Integer targetSrid) implements Task {
+
+  private static final Logger logger = 
LoggerFactory.getLogger(ImportOpenStreetMap.class);
+
+  @Override
+  public void execute(WorkflowContext context) throws Exception {
+    logger.info("Importing {} into {}", file, collection);
+
+    var path = file.toAbsolutePath();
+    var cacheDir = Files.createTempDirectory(Paths.get("."), "cache_");
+
+    var coordinatesKeysFile = 
Files.createFile(cacheDir.resolve("coordinates_keys"));
+    var coordinatesValsFile = 
Files.createFile(cacheDir.resolve("coordinates_vals"));
+    var coordinateMap = new MonotonicDataMap<>(
+        new MemoryAlignedDataList<>(new PairDataType<>(new LongDataType(), new 
LongDataType()),
+            new MemoryMappedFile(coordinatesKeysFile)),
+        new AppendOnlyBuffer<>(new LonLatDataType(), new 
MemoryMappedFile(coordinatesValsFile)));
+
+    var referencesKeysFile = 
Files.createFile(cacheDir.resolve("references_keys"));
+    var referencesValuesFile = 
Files.createFile(cacheDir.resolve("references_vals"));
+    var referenceMap = new MonotonicDataMap<>(
+        new MemoryAlignedDataList<>(new PairDataType<>(new LongDataType(), new 
LongDataType()),
+            new MemoryMappedFile(referencesKeysFile)),
+        new AppendOnlyBuffer<>(new LongListDataType(), new 
MemoryMappedFile(referencesValuesFile)));
+
+    Files.deleteIfExists(collection);
+
+
+    var entityCollection =
+        new AppendOnlyBuffer<>(new EntityDataType(), new 
MemoryMappedFile(collection));
+
+    var projectionTransformer = new ProjectionTransformer(4326, targetSrid);
+
+    // Read the PBF file and dispatch the elements to the consumers
+    new PbfEntityReader()
+        .geometries(true)
+        .coordinateMap(coordinateMap)
+        .referenceMap(referenceMap)
+        .stream(Files.newInputStream(path))
+        .filter(Element.class::isInstance)
+        .map(Element.class::cast)
+        .filter(element -> !element.getTags().isEmpty())
+        .filter(element -> element.getGeometry() != null)
+        .map(element -> {
+          var geometry = element.getGeometry();
+          geometry = projectionTransformer.transform(geometry);
+          var tags = new HashMap<String, String>();
+          for (var tag : element.getTags().entrySet()) {
+            tags.put(tag.getKey(), tag.getValue().toString());
+          }
+          return new Entity(element.id(), tags, geometry);
+        })
+        .forEach(entityCollection::add);
+
+    entityCollection.close();
+
+    FileUtils.deleteRecursively(cacheDir);
+
+    logger.info("Finished importing {} into {}", file, collection);
+  }
+
+}
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
new file mode 100644
index 00000000..ccdfde6e
--- /dev/null
+++ b/baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/Entity.java
@@ -0,0 +1,74 @@
+/*
+ * 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.workflow.tasks;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.baremaps.feature.Feature;
+import org.apache.baremaps.feature.FeatureType;
+import org.apache.baremaps.feature.PropertyType;
+import org.locationtech.jts.geom.Geometry;
+
+public class Entity implements Feature {
+
+  private final long id;
+
+  private final Map<String, String> tags;
+
+  private final Geometry geometry;
+
+  public Entity(long id, Map<String, String> tags, Geometry geometry) {
+    this.id = id;
+    this.tags = tags;
+    this.geometry = geometry;
+  }
+
+
+  @Override
+  public FeatureType getType() {
+    var map = new HashMap<String, PropertyType>();
+    map.put("id", new PropertyType<>("id", Long.class));
+    for (var entry : tags.entrySet()) {
+      map.put(entry.getKey(), new PropertyType<>(entry.getKey(), 
String.class));
+    }
+    map.put("geometry", new PropertyType<>("geometry", Geometry.class));
+    return new FeatureType("entity", map);
+  }
+
+  @Override
+  public void setProperty(String name, Object value) {
+    tags.put(name, value.toString());
+  }
+
+  @Override
+  public Object getProperty(String name) {
+    return tags.get(name);
+  }
+
+  @Override
+  public Map<String, Object> getProperties() {
+    return Map.copyOf(tags);
+  }
+
+  public long getId() {
+    return id;
+  }
+
+  public Map<String, String> getTags() {
+    return tags;
+  }
+
+  public Geometry getGeometry() {
+    return geometry;
+  }
+}
diff --git 
a/baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/EntityDataType.java
 
b/baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/EntityDataType.java
new file mode 100644
index 00000000..f9c9a2de
--- /dev/null
+++ 
b/baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/EntityDataType.java
@@ -0,0 +1,64 @@
+/*
+ * 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.workflow.tasks;
+
+import java.nio.ByteBuffer;
+import java.util.Map;
+import org.apache.baremaps.collection.type.*;
+import org.locationtech.jts.geom.Geometry;
+
+public class EntityDataType implements DataType<Entity> {
+
+  private LongDataType idType = new LongDataType();
+
+  private MapDataType<String, String> tagsType =
+      new MapDataType<>(new StringDataType(), new StringDataType());
+
+  private GeometryDataType geometryType = new GeometryDataType();
+
+  @Override
+  public int size(Entity value) {
+    int size = 0;
+    size += idType.size();
+    size += tagsType.size(value.getTags());
+    size += geometryType.size(value.getGeometry());
+    return size;
+  }
+
+  @Override
+  public int size(ByteBuffer buffer, int position) {
+    return buffer.getInt(position);
+  }
+
+  @Override
+  public void write(ByteBuffer buffer, int position, Entity value) {
+    buffer.putInt(position, size(value));
+    position += Integer.BYTES;
+    idType.write(buffer, position, value.getId());
+    position += idType.size();
+    tagsType.write(buffer, position, value.getTags());
+    position += tagsType.size(value.getTags());
+    geometryType.write(buffer, position, value.getGeometry());
+  }
+
+  @Override
+  public Entity read(ByteBuffer buffer, int position) {
+    position += Integer.BYTES;
+    long id = idType.read(buffer, position);
+    position += idType.size(id);
+    Map<String, String> tags = tagsType.read(buffer, position);
+    position += tagsType.size(tags);
+    Geometry geometry = geometryType.read(buffer, position);
+    return new Entity(id, tags, geometry);
+  }
+}
diff --git 
a/baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/SimplifyEntityCollection.java
 
b/baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/SimplifyEntityCollection.java
new file mode 100644
index 00000000..2edbf29d
--- /dev/null
+++ 
b/baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/SimplifyEntityCollection.java
@@ -0,0 +1,91 @@
+/*
+ * 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.workflow.tasks;
+
+
+import java.nio.file.Path;
+import java.util.Map;
+import java.util.function.*;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
+import org.apache.baremaps.collection.*;
+import org.apache.baremaps.collection.AppendOnlyBuffer;
+import org.apache.baremaps.collection.memory.MemoryMappedFile;
+import org.apache.baremaps.collection.type.*;
+import org.apache.baremaps.feature.*;
+import org.apache.baremaps.mvt.expression.Expressions.Expression;
+import org.apache.baremaps.storage.postgres.PostgresDatabase;
+import org.apache.baremaps.workflow.Task;
+import org.apache.baremaps.workflow.WorkflowContext;
+import org.locationtech.jts.geom.Geometry;
+import org.locationtech.jts.geom.Polygon;
+import org.locationtech.jts.geom.util.GeometryFixer;
+import org.locationtech.jts.operation.union.CascadedPolygonUnion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public record SimplifyEntityCollection(Path collection, String database,
+    Recipe recipe) implements Task {
+
+  private static final Logger logger = 
LoggerFactory.getLogger(ImportOpenStreetMap.class);
+
+  record Recipe(String name, Expression<Boolean> filter, Operation operation) {
+  }
+
+  enum Operation {
+    union, merge, none
+  }
+
+  @Override
+  public void execute(WorkflowContext context) throws Exception {
+    // read the original collection
+    var entities =
+        new AppendOnlyBuffer<>(new EntityDataType(), new 
MemoryMappedFile(collection));
+
+    // filter the entities of the collection
+    var filteredEntities = entities.stream()
+        .filter(entity -> recipe.filter.evaluate(entity))
+        .toList();
+
+    var geometries = filteredEntities.stream()
+        .map(Entity::getGeometry)
+        .filter(Polygon.class::isInstance)
+        .map(Polygon.class::cast)
+        .map(GeometryFixer::fix)
+        .toList();
+
+    // Apply the operation to each recipe and store the result in the 
collection
+    var unionedGeometry = new CascadedPolygonUnion(geometries).union();
+
+    var featureType =
+        new FeatureType(recipe.name, Map.of("geom", new PropertyType("geom", 
Geometry.class)));
+
+    Stream<Feature> stream = IntStream.range(0, 
unionedGeometry.getNumGeometries())
+        .mapToObj(unionedGeometry::getGeometryN)
+        .map(geometry -> new FeatureImpl(featureType, Map.of("geom", 
geometry)));
+
+    var dataSource = context.getDataSource(database);
+    var postgresDatabase = new PostgresDatabase(dataSource);
+    postgresDatabase.write(new ReadableFeatureSet() {
+      @Override
+      public FeatureType getType() {
+        return featureType;
+      }
+
+      @Override
+      public Stream<Feature> read() {
+        return stream;
+      }
+    });
+  }
+}
diff --git 
a/baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/SimplifyOpenStreetMap.java
 
b/baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/SimplifyOpenStreetMap.java
deleted file mode 100644
index dfd352b9..00000000
--- 
a/baremaps-core/src/main/java/org/apache/baremaps/workflow/tasks/SimplifyOpenStreetMap.java
+++ /dev/null
@@ -1,155 +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.workflow.tasks;
-
-
-import com.google.common.base.Predicates;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.*;
-import java.util.stream.Collectors;
-import java.util.stream.IntStream;
-import java.util.stream.Stream;
-import org.apache.baremaps.collection.*;
-import org.apache.baremaps.collection.AppendOnlyBuffer;
-import org.apache.baremaps.collection.MemoryAlignedDataList;
-import org.apache.baremaps.collection.memory.MemoryMappedFile;
-import org.apache.baremaps.collection.memory.OffHeapMemory;
-import org.apache.baremaps.collection.type.*;
-import org.apache.baremaps.collection.utils.FileUtils;
-import org.apache.baremaps.feature.*;
-import org.apache.baremaps.openstreetmap.model.Element;
-import org.apache.baremaps.openstreetmap.pbf.PbfEntityReader;
-import org.apache.baremaps.openstreetmap.utils.ProjectionTransformer;
-import org.apache.baremaps.storage.postgres.PostgresDatabase;
-import org.apache.baremaps.workflow.Task;
-import org.apache.baremaps.workflow.WorkflowContext;
-import org.locationtech.jts.geom.Geometry;
-import org.locationtech.jts.operation.union.CascadedPolygonUnion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public record SimplifyOpenStreetMap(Path file, String database, Integer 
databaseSrid)
-    implements
-      Task {
-
-  private static final Logger logger = 
LoggerFactory.getLogger(ImportOpenStreetMap.class);
-
-  @Override
-  public void execute(WorkflowContext context) throws Exception {
-    logger.info("Importing {} into {}", file, database);
-
-    var path = file.toAbsolutePath();
-
-    var cacheDir = Files.createTempDirectory(Paths.get("."), "cache_");
-
-    var coordinatesKeysFile = 
Files.createFile(cacheDir.resolve("coordinates_keys"));
-    var coordinatesValsFile = 
Files.createFile(cacheDir.resolve("coordinates_vals"));
-    var coordinateMap = new MonotonicDataMap<>(
-        new MemoryAlignedDataList<>(new PairDataType<>(new LongDataType(), new 
LongDataType()),
-            new MemoryMappedFile(coordinatesKeysFile)),
-        new AppendOnlyBuffer<>(new LonLatDataType(), new 
MemoryMappedFile(coordinatesValsFile)));
-
-    var referencesKeysFile = 
Files.createFile(cacheDir.resolve("references_keys"));
-    var referencesValuesFile = 
Files.createFile(cacheDir.resolve("references_vals"));
-    var referenceMap = new MonotonicDataMap<>(
-        new MemoryAlignedDataList<>(new PairDataType<>(new LongDataType(), new 
LongDataType()),
-            new MemoryMappedFile(referencesKeysFile)),
-        new AppendOnlyBuffer<>(new LongListDataType(), new 
MemoryMappedFile(referencesValuesFile)));
-
-    var collection = new AppendOnlyBuffer<>(new GeometryDataType(), new 
OffHeapMemory());
-    var projectionTransformer = new ProjectionTransformer(4326, databaseSrid);
-    new PbfEntityReader()
-        .geometries(true)
-        .coordinateMap(coordinateMap)
-        .referenceMap(referenceMap)
-        .stream(Files.newInputStream(path))
-        .filter(Element.class::isInstance)
-        .map(Element.class::cast)
-        .filter(element -> element.getTags().containsKey("building"))
-        .map(Element::getGeometry)
-        .filter(Predicates.notNull())
-        .map(projectionTransformer::transform)
-        .forEach(collection::add);
-    var unionedGeometry = new CascadedPolygonUnion(collection).union();
-
-    var dataSource = context.getDataSource(database);
-    var postgresDatabase = new PostgresDatabase(dataSource);
-
-    var featureType =
-        new FeatureType("buildings", Map.of("geom", new PropertyType("geom", 
Geometry.class)));
-    Stream<Feature> stream = IntStream.range(0, 
unionedGeometry.getNumGeometries())
-        .mapToObj(unionedGeometry::getGeometryN)
-        .map(geometry -> new FeatureImpl(featureType, Map.of("geom", 
geometry)));
-
-    postgresDatabase.write(new ReadableFeatureSet() {
-      @Override
-      public FeatureType getType() {
-        return featureType;
-      }
-
-      @Override
-      public Stream<Feature> read() {
-        return stream;
-      }
-    });
-
-    FileUtils.deleteRecursively(cacheDir);
-
-    logger.info("Finished importing {} into {}", file, database);
-  }
-
-  public static class PolygonUnionConsumer implements Consumer<Element> {
-
-    private final Map<Map<String, Object>, Collection<Element>> groups = new 
ConcurrentHashMap<>();
-
-    private final Supplier<Collection<Element>> collectionSupplier;
-
-    private final Predicate<Element> filter;
-
-    private final List<String> groupBy;
-
-    public PolygonUnionConsumer(Supplier<Collection<Element>> 
collectionSupplier,
-        Predicate<Element> filter, List<String> groupBy) {
-      this.collectionSupplier = collectionSupplier;
-      this.filter = filter;
-      this.groupBy = groupBy;
-    }
-
-    @Override
-    public void accept(Element element) {
-      if (filter.test(element)) {
-        var key =
-            groupBy.stream().collect(Collectors.toMap(Function.identity(), 
element.getTags()::get));
-        var collection = groups.computeIfAbsent(key, k -> 
collectionSupplier.get());
-        collection.add(element);
-      }
-    }
-
-    public Stream<Geometry> geometries() {
-      return groups.entrySet().stream()
-          .flatMap(entry -> {
-            // var tags = entry.getKey();
-            var collection = entry.getValue();
-            var geometry = new CascadedPolygonUnion(collection).union();
-            return IntStream.range(0, geometry.getNumGeometries())
-                .mapToObj(geometry::getGeometryN);
-          });
-    }
-  }
-}
diff --git 
a/baremaps-core/src/test/java/org/apache/baremaps/collection/type/DataTypeProvider.java
 
b/baremaps-core/src/test/java/org/apache/baremaps/collection/type/DataTypeProvider.java
index f6d53d92..12f731e4 100644
--- 
a/baremaps-core/src/test/java/org/apache/baremaps/collection/type/DataTypeProvider.java
+++ 
b/baremaps-core/src/test/java/org/apache/baremaps/collection/type/DataTypeProvider.java
@@ -15,6 +15,7 @@ package org.apache.baremaps.collection.type;
 
 
 import java.util.List;
+import java.util.Map;
 import java.util.stream.Stream;
 import org.junit.jupiter.params.provider.Arguments;
 import org.locationtech.jts.geom.Coordinate;
@@ -23,7 +24,8 @@ import org.locationtech.jts.geom.GeometryFactory;
 public class DataTypeProvider {
 
   private static Stream<Arguments> dataTypes() {
-    return Stream.of(Arguments.of(new StringDataType(), "Hello, World!"),
+    return Stream.of(
+        Arguments.of(new StringDataType(), "Hello, World!"),
         Arguments.of(new ByteDataType(), (byte) 1),
         Arguments.of(new ByteListDataType(), List.of((byte) 1, (byte) 2, 
(byte) 3)),
         Arguments.of(new DoubleDataType(), (double) 1),
@@ -42,6 +44,9 @@ public class DataTypeProvider {
         Arguments.of(new ShortDataType(), (short) 1),
         Arguments.of(new ShortListDataType(), List.of((short) 1, (short) 2, 
(short) 3)),
         Arguments.of(new ListDataType<>(new IntegerDataType()), List.of(1, 2, 
3)),
+        Arguments.of(new ListDataType<>(new StringDataType()), List.of("aaaa", 
"bbbb", "cccc")),
+        Arguments.of(new MapDataType<>(new StringDataType(), new 
IntegerDataType()),
+            Map.of("a", 1, "b", 2, "c", 3)),
         Arguments.of(new CoordinateDataType(), new Coordinate(-180, -90)),
         Arguments.of(new CoordinateDataType(), new Coordinate(180, 90)),
         Arguments.of(new LonLatDataType(), new Coordinate(-180, -90)),
@@ -70,7 +75,8 @@ public class DataTypeProvider {
         Arguments.of(new SmallLongDataType(7), (long) -Math.pow(2, 55)),
         Arguments.of(new SmallLongDataType(8), Long.MAX_VALUE),
         Arguments.of(new SmallLongDataType(8), Long.MIN_VALUE),
-        Arguments.of(new PairDataType<>(new LongDataType(), new 
LongDataType()),
+        Arguments.of(
+            new PairDataType<>(new LongDataType(), new LongDataType()),
             new PairDataType.Pair<>(1l, 2l)));
   }
 }
diff --git 
a/baremaps-core/src/test/java/org/apache/baremaps/collection/type/DataTypeTest.java
 
b/baremaps-core/src/test/java/org/apache/baremaps/collection/type/DataTypeTest.java
index 67afada8..e548d6ff 100644
--- 
a/baremaps-core/src/test/java/org/apache/baremaps/collection/type/DataTypeTest.java
+++ 
b/baremaps-core/src/test/java/org/apache/baremaps/collection/type/DataTypeTest.java
@@ -26,7 +26,9 @@ class DataTypeTest {
     var size = dataType.size(value);
     var buffer = ByteBuffer.allocate(size);
     dataType.write(buffer, 0, value);
-    assertEquals(value, dataType.read(buffer, 0));
-    assertEquals(size, dataType.size(buffer, 0));
+    var recordSize = dataType.size(buffer, 0);
+    var recordValue = dataType.read(buffer, 0);
+    assertEquals(size, recordSize);
+    assertEquals(value, recordValue);
   }
 }
diff --git 
a/baremaps-core/src/test/java/org/apache/baremaps/openstreetmap/geometry/EntityGeometryBuilderTest.java
 
b/baremaps-core/src/test/java/org/apache/baremaps/openstreetmap/geometry/EntityDataTypeGeometryBuilderTest.java
similarity index 99%
rename from 
baremaps-core/src/test/java/org/apache/baremaps/openstreetmap/geometry/EntityGeometryBuilderTest.java
rename to 
baremaps-core/src/test/java/org/apache/baremaps/openstreetmap/geometry/EntityDataTypeGeometryBuilderTest.java
index c015f4bb..50e88394 100644
--- 
a/baremaps-core/src/test/java/org/apache/baremaps/openstreetmap/geometry/EntityGeometryBuilderTest.java
+++ 
b/baremaps-core/src/test/java/org/apache/baremaps/openstreetmap/geometry/EntityDataTypeGeometryBuilderTest.java
@@ -46,7 +46,7 @@ import org.locationtech.proj4j.CoordinateTransform;
 import org.locationtech.proj4j.Proj4jException;
 import org.locationtech.proj4j.ProjCoordinate;
 
-class EntityGeometryBuilderTest {
+class EntityDataTypeGeometryBuilderTest {
 
   static final CRSFactory CRS_FACTORY = new CRSFactory();
 
diff --git 
a/baremaps-core/src/test/java/org/apache/baremaps/openstreetmap/xml/XmlEntitySpliteratorTest.java
 
b/baremaps-core/src/test/java/org/apache/baremaps/openstreetmap/xml/XmlEntitySpliteratorTestDataType.java
similarity index 97%
rename from 
baremaps-core/src/test/java/org/apache/baremaps/openstreetmap/xml/XmlEntitySpliteratorTest.java
rename to 
baremaps-core/src/test/java/org/apache/baremaps/openstreetmap/xml/XmlEntitySpliteratorTestDataType.java
index b04edbba..6587cedc 100644
--- 
a/baremaps-core/src/test/java/org/apache/baremaps/openstreetmap/xml/XmlEntitySpliteratorTest.java
+++ 
b/baremaps-core/src/test/java/org/apache/baremaps/openstreetmap/xml/XmlEntitySpliteratorTestDataType.java
@@ -26,7 +26,7 @@ import org.apache.baremaps.stream.AccumulatingConsumer;
 import org.apache.baremaps.stream.HoldingConsumer;
 import org.junit.jupiter.api.Test;
 
-class XmlEntitySpliteratorTest {
+class XmlEntitySpliteratorTestDataType {
 
   @Test
   void tryAdvance() throws IOException {
diff --git 
a/baremaps-core/src/test/java/org/apache/baremaps/workflow/tasks/SimplifyOpenStreetMapTest.java
 
b/baremaps-core/src/test/java/org/apache/baremaps/workflow/tasks/CreateAndSimplifyEntityCollectionTest.java
similarity index 55%
rename from 
baremaps-core/src/test/java/org/apache/baremaps/workflow/tasks/SimplifyOpenStreetMapTest.java
rename to 
baremaps-core/src/test/java/org/apache/baremaps/workflow/tasks/CreateAndSimplifyEntityCollectionTest.java
index 8943f849..56a42ea4 100644
--- 
a/baremaps-core/src/test/java/org/apache/baremaps/workflow/tasks/SimplifyOpenStreetMapTest.java
+++ 
b/baremaps-core/src/test/java/org/apache/baremaps/workflow/tasks/CreateAndSimplifyEntityCollectionTest.java
@@ -14,21 +14,30 @@ package org.apache.baremaps.workflow.tasks;
 
 
 
+import java.nio.file.Paths;
+import org.apache.baremaps.mvt.expression.Expressions.Has;
 import org.apache.baremaps.testing.PostgresContainerTest;
 import org.apache.baremaps.testing.TestFiles;
 import org.apache.baremaps.workflow.WorkflowContext;
+import org.apache.baremaps.workflow.tasks.SimplifyEntityCollection.Operation;
+import org.apache.baremaps.workflow.tasks.SimplifyEntityCollection.Recipe;
 import org.junit.jupiter.api.Tag;
 import org.junit.jupiter.api.Test;
 
-class SimplifyOpenStreetMapTest extends PostgresContainerTest {
+class CreateAndSimplifyEntityCollectionTest extends PostgresContainerTest {
 
   @Test
   @Tag("integration")
   void execute() throws Exception {
-    var file = TestFiles.resolve("data.osm.pbf");
+    var file = TestFiles.resolve("monaco/monaco.osm.pbf");
+    var collection = Paths.get("entity_collection");
     var jdbcUrl = jdbcUrl();
-    var srid = 3857;
-    var task = new SimplifyOpenStreetMap(file, jdbcUrl, srid);
-    task.execute(new WorkflowContext());
+
+    var createTask = new CreateEntityCollection(file, collection, 3857);
+    createTask.execute(new WorkflowContext());
+
+    var simplifyTask = new SimplifyEntityCollection(collection, jdbcUrl,
+        new Recipe("building", new Has("building"), Operation.union));
+    simplifyTask.execute(new WorkflowContext());
   }
 }


Reply via email to