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

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

commit f63e7f12ec6a6b17760931e3ae226ef4bcfe44e9
Author: Bertil Chapuis <[email protected]>
AuthorDate: Sun Apr 23 12:44:02 2023 +0200

    Serve contour tiles
---
 .../java/org/apache/baremaps/cli/map/Contour.java  | 91 ++++++++++++++++++++++
 .../main/java/org/apache/baremaps/cli/map/Map.java |  2 +-
 .../apache/baremaps/raster/ContourTileStore.java   | 33 +++++---
 .../org/apache/baremaps/vectortile/Feature.java    |  8 +-
 .../baremaps/vectortile/VectorTileEncoder.java     |  5 +-
 .../baremaps/vectortile/VectorTileUtils.java       | 20 ++++-
 .../apache/baremaps/vectortile/VectorTileTest.java |  4 +-
 .../baremaps/vectortile/VectorTileViewer.java      | 13 +++-
 .../apache/baremaps/server/ServerResources.java    |  7 +-
 examples/contour/style.json                        |  4 +-
 examples/contour/tileset.json                      | 11 +--
 11 files changed, 160 insertions(+), 38 deletions(-)

diff --git 
a/baremaps-cli/src/main/java/org/apache/baremaps/cli/map/Contour.java 
b/baremaps-cli/src/main/java/org/apache/baremaps/cli/map/Contour.java
new file mode 100644
index 00000000..b301876b
--- /dev/null
+++ b/baremaps-cli/src/main/java/org/apache/baremaps/cli/map/Contour.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.cli.map;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.github.benmanes.caffeine.cache.CaffeineSpec;
+import io.servicetalk.http.netty.HttpServers;
+import io.servicetalk.http.router.jersey.HttpJerseyRouterBuilder;
+import org.apache.baremaps.cli.Options;
+import org.apache.baremaps.database.PostgresUtils;
+import org.apache.baremaps.database.tile.PostgresTileStore;
+import org.apache.baremaps.database.tile.TileCache;
+import org.apache.baremaps.database.tile.TileStore;
+import org.apache.baremaps.mvt.tileset.Tileset;
+import org.apache.baremaps.raster.ContourTileStore;
+import org.apache.baremaps.server.ConfigReader;
+import org.apache.baremaps.server.CorsFilter;
+import org.apache.baremaps.server.ServerResources;
+import org.glassfish.hk2.utilities.binding.AbstractBinder;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Mixin;
+import picocli.CommandLine.Option;
+
+import java.nio.file.Path;
+import java.util.concurrent.Callable;
+
+import static 
io.servicetalk.data.jackson.jersey.ServiceTalkJacksonSerializerFeature.contextResolverFor;
+import static 
org.apache.baremaps.server.DefaultObjectMapper.defaultObjectMapper;
+
+@Command(name = "contour", description = "Start a tile server with caching 
capabilities.")
+public class Contour implements Callable<Integer> {
+
+  private static final Logger logger = LoggerFactory.getLogger(Contour.class);
+
+  @Option(names = {"--cache"}, paramLabel = "CACHE", description = "The 
caffeine cache directive.")
+  private String cache = "";
+
+  @Option(names = {"--tileset"}, paramLabel = "TILESET", description = "The 
tileset file.",
+      required = true)
+  private Path tileset;
+
+  @Option(names = {"--style"}, paramLabel = "STYLE", description = "The style 
file.",
+      required = true)
+  private Path style;
+
+  @Option(names = {"--host"}, paramLabel = "HOST", description = "The host of 
the server.")
+  private String host = "localhost";
+
+  @Option(names = {"--port"}, paramLabel = "PORT", description = "The port of 
the server.")
+  private int port = 9000;
+
+  @Override
+  public Integer call() throws Exception {
+    var objectMapper = defaultObjectMapper();
+    var tileStore = new ContourTileStore();
+
+    // Configure the application
+    var application =
+        new 
ResourceConfig().register(CorsFilter.class).register(ServerResources.class)
+            .register(contextResolverFor(objectMapper)).register(new 
AbstractBinder() {
+              @Override
+              protected void configure() {
+                bind(Contour.this.tileset).to(Path.class).named("tileset");
+                bind(style).to(Path.class).named("style");
+                bind(objectMapper).to(ObjectMapper.class);
+                bind(tileStore).to(TileStore.class);
+              }
+            });
+
+    var httpService = new 
HttpJerseyRouterBuilder().buildBlockingStreaming(application);
+    var serverContext = 
HttpServers.forPort(port).listenBlockingStreamingAndAwait(httpService);
+
+    logger.info("Listening on {}", serverContext.listenAddress());
+
+    serverContext.awaitShutdown();
+    return 0;
+  }
+}
diff --git a/baremaps-cli/src/main/java/org/apache/baremaps/cli/map/Map.java 
b/baremaps-cli/src/main/java/org/apache/baremaps/cli/map/Map.java
index 9ed602d0..e1d1a3e5 100644
--- a/baremaps-cli/src/main/java/org/apache/baremaps/cli/map/Map.java
+++ b/baremaps-cli/src/main/java/org/apache/baremaps/cli/map/Map.java
@@ -18,7 +18,7 @@ import picocli.CommandLine;
 import picocli.CommandLine.Command;
 
 @Command(name = "map", description = "Map commands.",
-    subcommands = {Init.class, Export.class, Serve.class, Dev.class}, 
sortOptions = false)
+    subcommands = {Init.class, Export.class, Serve.class, Dev.class, 
Contour.class}, sortOptions = false)
 public class Map implements Runnable {
 
   @Override
diff --git 
a/baremaps-core/src/main/java/org/apache/baremaps/raster/ContourTileStore.java 
b/baremaps-core/src/main/java/org/apache/baremaps/raster/ContourTileStore.java
index 9e2b093b..bd206eee 100644
--- 
a/baremaps-core/src/main/java/org/apache/baremaps/raster/ContourTileStore.java
+++ 
b/baremaps-core/src/main/java/org/apache/baremaps/raster/ContourTileStore.java
@@ -15,6 +15,7 @@ package org.apache.baremaps.raster;
 import java.nio.ByteBuffer;
 import java.nio.file.Paths;
 import java.util.List;
+import java.util.Map;
 import java.util.Vector;
 import java.util.stream.IntStream;
 import java.util.stream.LongStream;
@@ -24,6 +25,10 @@ import org.apache.baremaps.database.tile.TileStore;
 import org.apache.baremaps.database.tile.TileStoreException;
 import org.apache.baremaps.openstreetmap.utils.GeometryUtils;
 import org.apache.baremaps.openstreetmap.utils.ProjectionTransformer;
+import org.apache.baremaps.vectortile.Feature;
+import org.apache.baremaps.vectortile.Layer;
+import org.apache.baremaps.vectortile.VectorTileEncoder;
+import org.apache.baremaps.vectortile.VectorTileUtils;
 import org.gdal.gdal.Dataset;
 import org.gdal.gdal.WarpOptions;
 import org.gdal.gdal.gdal;
@@ -31,6 +36,8 @@ import org.gdal.gdalconst.gdalconstConstants;
 import org.gdal.ogr.FieldDefn;
 import org.gdal.ogr.ogr;
 import org.gdal.osr.SpatialReference;
+import org.locationtech.jts.geom.Envelope;
+import org.locationtech.jts.geom.GeometryFactory;
 import org.locationtech.jts.geom.util.GeometryTransformer;
 import org.locationtech.proj4j.ProjCoordinate;
 
@@ -53,6 +60,12 @@ public class ContourTileStore implements TileStore, 
AutoCloseable {
     var sourceBand = sourceDataset.GetRasterBand(1);
     var envelope = tile.envelope();
 
+    // Transform the extent to the source projection
+    var transformer = GeometryUtils.coordinateTransform(4326, 3857);
+    var min = transformer.transform(new ProjCoordinate(envelope.getMinX(), 
envelope.getMinY()), new ProjCoordinate());
+    var max = transformer.transform(new ProjCoordinate(envelope.getMaxX(), 
envelope.getMaxY()), new ProjCoordinate());
+    var targetEnvelope = new Envelope(min.x, max.x, min.y, max.y);
+
     // Warp the raster to the requested extent
     var rasterOptions = new WarpOptions(new Vector<>(List.of(
             "-of", "MEM",
@@ -62,30 +75,30 @@ public class ContourTileStore implements TileStore, 
AutoCloseable {
     var rasterBand = rasterDataset.GetRasterBand(1);
 
     // Generate the contours
-    //var wkt = rasterDataset.GetProjection();
-    //var srs = new SpatialReference(wkt);
-    var srs = new SpatialReference("EPSG:4326");
+    var wkt = rasterDataset.GetProjection();
+    var srs = new SpatialReference(wkt);
     var vectorDriver = ogr.GetDriverByName("Memory");
     var vectorDataSource = vectorDriver.CreateDataSource("vector");
     var vectorLayer = vectorDataSource.CreateLayer("vector", srs, 
ogr.wkbLineString);
-    gdal.ContourGenerateEx(rasterBand, vectorLayer, new 
Vector<>(List.of("LEVEL_INTERVAL=" + 10)));
+    gdal.ContourGenerateEx(rasterBand, vectorLayer, new 
Vector<>(List.of("LEVEL_INTERVAL=" + 50)));
 
     // return the contours
-    var geometries = LongStream.range(0, vectorLayer.GetFeatureCount())
+    var features = LongStream.range(0, vectorLayer.GetFeatureCount())
             .mapToObj(vectorLayer::GetFeature)
             .map(feature -> feature.GetGeometryRef())
             .map(geometry -> GeometryUtils.deserialize(geometry.ExportToWkb()))
+            .map(geometry -> VectorTileUtils.asVectorTileGeom(geometry, 
targetEnvelope, 4096, 0, true))
+            .map(geometry -> new Feature(null, Map.of(), geometry))
             .toList();
 
-    var transformer = GeometryUtils.coordinateTransform(4326, 3857);
-    var min = transformer.transform(new ProjCoordinate(envelope.getMinX(), 
envelope.getMinY()), new ProjCoordinate());
-    var max = transformer.transform(new ProjCoordinate(envelope.getMaxX(), 
envelope.getMaxY()), new ProjCoordinate());
+    var vectorTile = VectorTileUtils.asVectorTile(new 
org.apache.baremaps.vectortile.Tile(List.of(new Layer("contours", 4096, 
features))));
+
 
     rasterBand.delete();
     rasterDataset.delete();
     sourceBand.delete();
 
-    return null;
+    return vectorTile;
   }
 
   @Override
@@ -106,7 +119,7 @@ public class ContourTileStore implements TileStore, 
AutoCloseable {
   public static void main(String[] args) throws Exception {
     var store = new ContourTileStore();
     store.read(new Tile(8492, 5792, 14).parent());
-  }
 
+  }
 
 }
diff --git 
a/baremaps-core/src/main/java/org/apache/baremaps/vectortile/Feature.java 
b/baremaps-core/src/main/java/org/apache/baremaps/vectortile/Feature.java
index c9d7dccb..71ba3fb9 100644
--- a/baremaps-core/src/main/java/org/apache/baremaps/vectortile/Feature.java
+++ b/baremaps-core/src/main/java/org/apache/baremaps/vectortile/Feature.java
@@ -21,7 +21,7 @@ import org.locationtech.jts.geom.Geometry;
  */
 public class Feature {
 
-  private long id;
+  private Long id;
 
   private Map<String, Object> tags;
 
@@ -39,7 +39,7 @@ public class Feature {
    * @param tags The tags of the feature.
    * @param geometry The geometry of the feature.
    */
-  public Feature(long id, Map<String, Object> tags, Geometry geometry) {
+  public Feature(Long id, Map<String, Object> tags, Geometry geometry) {
     this.id = id;
     this.tags = tags;
     this.geometry = geometry;
@@ -50,7 +50,7 @@ public class Feature {
    *
    * @return The id of the feature.
    */
-  public long getId() {
+  public Long getId() {
     return id;
   }
 
@@ -59,7 +59,7 @@ public class Feature {
    *
    * @param id The id of the feature.
    */
-  public void setId(long id) {
+  public void setId(Long id) {
     this.id = id;
   }
 
diff --git 
a/baremaps-core/src/main/java/org/apache/baremaps/vectortile/VectorTileEncoder.java
 
b/baremaps-core/src/main/java/org/apache/baremaps/vectortile/VectorTileEncoder.java
index 7dcad1f7..4e4b427d 100644
--- 
a/baremaps-core/src/main/java/org/apache/baremaps/vectortile/VectorTileEncoder.java
+++ 
b/baremaps-core/src/main/java/org/apache/baremaps/vectortile/VectorTileEncoder.java
@@ -120,9 +120,10 @@ public class VectorTileEncoder {
     cy = 0;
 
     VectorTile.Tile.Feature.Builder builder = 
VectorTile.Tile.Feature.newBuilder();
-    builder.setId(feature.getId());
+    if (feature.getId() != null) {
+      builder.setId(feature.getId());
+    }
     builder.setType(encodeGeometryType(feature.getGeometry()));
-
     encodeTag(feature.getTags(), builder::addTags);
     encodeGeometry(feature.getGeometry(), builder::addGeometry);
 
diff --git 
a/baremaps-core/src/main/java/org/apache/baremaps/vectortile/VectorTileUtils.java
 
b/baremaps-core/src/main/java/org/apache/baremaps/vectortile/VectorTileUtils.java
index f3d48a29..3ab24f53 100644
--- 
a/baremaps-core/src/main/java/org/apache/baremaps/vectortile/VectorTileUtils.java
+++ 
b/baremaps-core/src/main/java/org/apache/baremaps/vectortile/VectorTileUtils.java
@@ -88,10 +88,18 @@ public class VectorTileUtils {
    * @return The transformed tile
    */
   public static ByteBuffer asVectorTile(Tile vectorTile) {
-    return new VectorTileEncoder()
+    ByteBuffer original = new VectorTileEncoder()
         .encodeTile(vectorTile)
         .toByteString()
         .asReadOnlyByteBuffer();
+
+    ByteBuffer clone = ByteBuffer.allocate(original.capacity());
+    original.rewind();//copy from the beginning
+    clone.put(original);
+    original.rewind();
+    clone.flip();
+
+    return clone;
   }
 
   /**
@@ -101,10 +109,18 @@ public class VectorTileUtils {
    * @return The transformed layer
    */
   public static ByteBuffer asVectorTileLayer(Layer layer) {
-    return new VectorTileEncoder()
+    ByteBuffer original = new VectorTileEncoder()
         .encodeLayer(layer)
         .toByteString()
         .asReadOnlyByteBuffer();
+
+    ByteBuffer clone = ByteBuffer.allocate(original.capacity());
+    original.rewind();//copy from the beginning
+    clone.put(original);
+    original.rewind();
+    clone.flip();
+
+    return clone;
   }
 
   /**
diff --git 
a/baremaps-core/src/test/java/org/apache/baremaps/vectortile/VectorTileTest.java
 
b/baremaps-core/src/test/java/org/apache/baremaps/vectortile/VectorTileTest.java
index 1fb353bc..db66f294 100644
--- 
a/baremaps-core/src/test/java/org/apache/baremaps/vectortile/VectorTileTest.java
+++ 
b/baremaps-core/src/test/java/org/apache/baremaps/vectortile/VectorTileTest.java
@@ -36,9 +36,9 @@ public class VectorTileTest {
   public void endToEnd() {
     var tile = new Tile(List.of(
         new Layer("layer", 256, List.of(
-            new Feature(1, Map.of("a", 1.0, "b", "2"),
+            new Feature(1l, Map.of("a", 1.0, "b", "2"),
                 GEOMETRY_FACTORY.createPoint(new Coordinate(1, 2))),
-            new Feature(2, Map.of("c", 3.0, "d", "4"),
+            new Feature(2l, Map.of("c", 3.0, "d", "4"),
                 GEOMETRY_FACTORY.createPoint(new Coordinate(2, 3)))))));
 
     var encoded = new VectorTileEncoder().encodeTile(tile);
diff --git 
a/baremaps-core/src/test/java/org/apache/baremaps/vectortile/VectorTileViewer.java
 
b/baremaps-core/src/test/java/org/apache/baremaps/vectortile/VectorTileViewer.java
index 079d70a1..349c666c 100644
--- 
a/baremaps-core/src/test/java/org/apache/baremaps/vectortile/VectorTileViewer.java
+++ 
b/baremaps-core/src/test/java/org/apache/baremaps/vectortile/VectorTileViewer.java
@@ -14,6 +14,7 @@ package org.apache.baremaps.vectortile;
 
 import java.awt.*;
 import java.awt.Dimension;
+import java.net.URL;
 import java.nio.ByteBuffer;
 import java.nio.file.Files;
 import java.nio.file.Path;
@@ -29,10 +30,14 @@ import org.locationtech.jts.geom.Polygon;
 public class VectorTileViewer {
 
   public static void main(String... args) throws Exception {
-    String arg =
-        args.length > 0 ? args[0] : 
"baremaps-core/src/test/resources/vectortile/14-8493-5795.mvt";
-    var path = Path.of(arg);
-    try (var input = new GZIPInputStream(Files.newInputStream(path))) {
+//    String arg =
+//        args.length > 0 ? args[0] : 
"baremaps-core/src/test/resources/vectortile/14-8493-5795.mvt";
+//    var path = Path.of(arg);
+//    try (var input = new GZIPInputStream(Files.newInputStream(path))) {
+
+    var url = new URL("http://localhost:9000/tiles/14/8628/5750.mvt";);
+
+    try (var input = url.openStream()) {
       var buffer = ByteBuffer.wrap(input.readAllBytes());
       var parsed = 
org.apache.baremaps.mvt.binary.VectorTile.Tile.parseFrom(buffer);
       var tile = new VectorTileDecoder().decodeTile(parsed);
diff --git 
a/baremaps-server/src/main/java/org/apache/baremaps/server/ServerResources.java 
b/baremaps-server/src/main/java/org/apache/baremaps/server/ServerResources.java
index 0300046d..3a495ca9 100644
--- 
a/baremaps-server/src/main/java/org/apache/baremaps/server/ServerResources.java
+++ 
b/baremaps-server/src/main/java/org/apache/baremaps/server/ServerResources.java
@@ -85,9 +85,12 @@ public class ServerResources {
     try {
       ByteBuffer blob = tileStore.read(tile);
       if (blob != null) {
+        var array = blob.array();
         return Response.status(200) // lgtm [java/xss]
-            .header(ACCESS_CONTROL_ALLOW_ORIGIN, "*").header(CONTENT_TYPE, 
TILE_TYPE)
-            .header(CONTENT_ENCODING, 
TILE_ENCODING).entity(blob.array()).build();
+            .header(ACCESS_CONTROL_ALLOW_ORIGIN, "*")
+            .header(CONTENT_TYPE, TILE_TYPE)
+            //.header(CONTENT_ENCODING, TILE_ENCODING)
+            .entity(array).build();
       } else {
         return Response.status(204).build();
       }
diff --git a/examples/contour/style.json b/examples/contour/style.json
index 16047415..bb982ecc 100644
--- a/examples/contour/style.json
+++ b/examples/contour/style.json
@@ -14,10 +14,10 @@
       "background-color" : "rgba(255, 255, 255, 1)"
     }
   }, {
-    "id" : "aster_dem",
+    "id" : "contours",
     "type" : "line",
     "source" : "baremaps",
-    "source-layer" : "aster_dem",
+    "source-layer" : "contours",
     "layout" : {
       "line-cap" : "round",
       "line-join" : "round"
diff --git a/examples/contour/tileset.json b/examples/contour/tileset.json
index 7999eb55..98108edf 100644
--- a/examples/contour/tileset.json
+++ b/examples/contour/tileset.json
@@ -5,23 +5,16 @@
     47.166,
     14.0
   ],
-  "bounds": [
-    9.471078,
-    47.04774,
-    9.636217,
-    47.27128
-  ],
   "tiles": [
     "http://localhost:9000/tiles/{z}/{x}/{y}.mvt";
   ],
   "vector_layers": [
     {
-      "id": "aster_dem",
+      "id": "contours",
       "queries": [
         {
           "minzoom": 0,
-          "maxzoom": 20,
-          "sql": "SELECT ogc_fid, jsonb_build_object('elevation', 
elevation::text), wkb_geometry FROM aster_dem"
+          "maxzoom": 20
         }
       ]
     }

Reply via email to