From 68c9022c560467951752e5ce750cd0ef40a11e5e Mon Sep 17 00:00:00 2001 From: Bertil Chapuis Date: Thu, 26 Sep 2024 22:53:50 +0200 Subject: [PATCH] Raster processing and digital elevation models (#890) * Implement algorithms to process digital elevation models * Distinguish TileStore for raster and vector tiles * Add utilities to serve and preview DEM data --- .run/basemap-dem.run.xml | 17 + baremaps-cli/pom.xml | 4 + .../org/apache/baremaps/cli/Baremaps.java | 10 +- .../java/org/apache/baremaps/cli/dem/DEM.java | 41 ++ .../org/apache/baremaps/cli/dem/Serve.java | 123 +++++ .../baremaps/cli/dem/VectorTileContours.java | 105 ++++ .../java/org/apache/baremaps/cli/map/Dev.java | 8 +- .../org/apache/baremaps/cli/map/MBTiles.java | 10 +- .../org/apache/baremaps/cli/map/Serve.java | 12 +- baremaps-core/pom.xml | 16 + .../baremaps/tilestore/TileChannel.java | 17 +- .../apache/baremaps/tilestore/TileCoord.java | 36 ++ .../apache/baremaps/tilestore/TileEntry.java | 13 +- .../apache/baremaps/tilestore/TileStore.java | 15 +- .../tilestore/TileStoreException.java | 6 +- .../tilestore/file/FileTileStore.java | 2 +- .../tilestore/mbtiles/MBTilesStore.java | 8 +- .../tilestore/pmtiles/PMTilesStore.java | 2 +- .../postgres/PostgresQueryGenerator.java | 112 ---- .../tilestore/postgres/PostgresTileStore.java | 2 +- .../raster/BicubicInterpolation.java | 64 +++ .../tilestore/raster/GeoTiffException.java | 52 ++ .../tilestore/raster/GeoTiffReader.java | 148 +++++ .../raster/RasterHillshadeTileStore.java | 115 ++++ .../tilestore/raster/RasterTileCache.java | 93 ++++ .../tilestore/raster/TerrariumTileStore.java | 92 ++++ .../raster/VectorContourTileStore.java | 131 +++++ .../raster/VectorHillshadeTileStore.java | 136 +++++ .../VectorTileCache.java} | 30 +- .../apache/baremaps/config/TileSetTest.java | 21 +- .../tilestore/TileDataSchemaTest.java | 4 +- .../postgres/PostgresQueryGeneratorTest.java | 43 -- baremaps-dem/pom.xml | 20 + .../apache/baremaps/dem/ChaikinSmoother.java | 128 +++++ .../apache/baremaps/dem/ContourTracer.java | 506 ++++++++++++++++++ .../apache/baremaps/dem/ElevationUtils.java | 214 ++++++++ .../baremaps/dem/HillshadeCalculator.java | 150 ++++++ .../java/org/apache/baremaps/dem/Martini.java | 294 ++++++++++ .../org/apache/baremaps/dem/RasterUtils.java | 49 ++ .../baremaps/dem/ChaikinSmootherTest.java | 40 ++ .../apache/baremaps/dem/ContourRenderer.java | 93 ++++ .../dem/ContourTracerLineStringTest.java | 161 ++++++ .../dem/ContourTracerPolygonTest.java | 191 +++++++ .../baremaps/dem/ContourTracerTest.java | 89 +++ .../baremaps/dem/HillShadeRenderer.java | 155 ++++++ .../baremaps/dem/HillshadeCalculatorTest.java | 103 ++++ .../baremaps/dem/MarchingSquareRenderer.java | 113 ++++ .../baremaps/dem/MarchingSquareUtils.java | 127 +++++ .../org/apache/baremaps/dem/MartiniTest.java | 62 +++ baremaps-dem/src/test/resources/fuji.png | Bin 0 -> 578765 bytes .../openstreetmap/utils/GeometryUtils.java | 43 +- .../server/BufferedImageResource.java | 90 ++++ ...eResource.java => VectorTileResource.java} | 24 +- .../src/main/resources/dem/favicon.ico | Bin 0 -> 15086 bytes .../src/main/resources/dem/index.html | 150 ++++++ .../src/main/resources/static/server.html | 7 +- .../src/main/resources/static/viewer.html | 4 +- .../baremaps/testing/GeometryAssertions.java | 48 +- .../apache/baremaps/testing/TestFiles.java | 6 + basemap/index.html | 15 +- examples/openstreetmap/index.html | 15 +- pom.xml | 33 +- 62 files changed, 4155 insertions(+), 263 deletions(-) create mode 100644 .run/basemap-dem.run.xml create mode 100644 baremaps-cli/src/main/java/org/apache/baremaps/cli/dem/DEM.java create mode 100644 baremaps-cli/src/main/java/org/apache/baremaps/cli/dem/Serve.java create mode 100644 baremaps-cli/src/main/java/org/apache/baremaps/cli/dem/VectorTileContours.java delete mode 100644 baremaps-core/src/main/java/org/apache/baremaps/tilestore/postgres/PostgresQueryGenerator.java create mode 100644 baremaps-core/src/main/java/org/apache/baremaps/tilestore/raster/BicubicInterpolation.java create mode 100644 baremaps-core/src/main/java/org/apache/baremaps/tilestore/raster/GeoTiffException.java create mode 100644 baremaps-core/src/main/java/org/apache/baremaps/tilestore/raster/GeoTiffReader.java create mode 100644 baremaps-core/src/main/java/org/apache/baremaps/tilestore/raster/RasterHillshadeTileStore.java create mode 100644 baremaps-core/src/main/java/org/apache/baremaps/tilestore/raster/RasterTileCache.java create mode 100644 baremaps-core/src/main/java/org/apache/baremaps/tilestore/raster/TerrariumTileStore.java create mode 100644 baremaps-core/src/main/java/org/apache/baremaps/tilestore/raster/VectorContourTileStore.java create mode 100644 baremaps-core/src/main/java/org/apache/baremaps/tilestore/raster/VectorHillshadeTileStore.java rename baremaps-core/src/main/java/org/apache/baremaps/tilestore/{TileCache.java => vector/VectorTileCache.java} (70%) delete mode 100644 baremaps-core/src/test/java/org/apache/baremaps/tilestore/postgres/PostgresQueryGeneratorTest.java create mode 100644 baremaps-dem/pom.xml create mode 100644 baremaps-dem/src/main/java/org/apache/baremaps/dem/ChaikinSmoother.java create mode 100644 baremaps-dem/src/main/java/org/apache/baremaps/dem/ContourTracer.java create mode 100644 baremaps-dem/src/main/java/org/apache/baremaps/dem/ElevationUtils.java create mode 100644 baremaps-dem/src/main/java/org/apache/baremaps/dem/HillshadeCalculator.java create mode 100644 baremaps-dem/src/main/java/org/apache/baremaps/dem/Martini.java create mode 100644 baremaps-dem/src/main/java/org/apache/baremaps/dem/RasterUtils.java create mode 100644 baremaps-dem/src/test/java/org/apache/baremaps/dem/ChaikinSmootherTest.java create mode 100644 baremaps-dem/src/test/java/org/apache/baremaps/dem/ContourRenderer.java create mode 100644 baremaps-dem/src/test/java/org/apache/baremaps/dem/ContourTracerLineStringTest.java create mode 100644 baremaps-dem/src/test/java/org/apache/baremaps/dem/ContourTracerPolygonTest.java create mode 100644 baremaps-dem/src/test/java/org/apache/baremaps/dem/ContourTracerTest.java create mode 100644 baremaps-dem/src/test/java/org/apache/baremaps/dem/HillShadeRenderer.java create mode 100644 baremaps-dem/src/test/java/org/apache/baremaps/dem/HillshadeCalculatorTest.java create mode 100644 baremaps-dem/src/test/java/org/apache/baremaps/dem/MarchingSquareRenderer.java create mode 100644 baremaps-dem/src/test/java/org/apache/baremaps/dem/MarchingSquareUtils.java create mode 100644 baremaps-dem/src/test/java/org/apache/baremaps/dem/MartiniTest.java create mode 100644 baremaps-dem/src/test/resources/fuji.png create mode 100644 baremaps-server/src/main/java/org/apache/baremaps/server/BufferedImageResource.java rename baremaps-server/src/main/java/org/apache/baremaps/server/{TileResource.java => VectorTileResource.java} (76%) create mode 100644 baremaps-server/src/main/resources/dem/favicon.ico create mode 100644 baremaps-server/src/main/resources/dem/index.html diff --git a/.run/basemap-dem.run.xml b/.run/basemap-dem.run.xml new file mode 100644 index 000000000..0b345455d --- /dev/null +++ b/.run/basemap-dem.run.xml @@ -0,0 +1,17 @@ + + + + \ No newline at end of file diff --git a/baremaps-cli/pom.xml b/baremaps-cli/pom.xml index 7003b2c62..825f6248f 100644 --- a/baremaps-cli/pom.xml +++ b/baremaps-cli/pom.xml @@ -43,6 +43,10 @@ limitations under the License. org.apache.baremaps baremaps-core + + org.apache.baremaps + baremaps-dem + org.apache.baremaps baremaps-server diff --git a/baremaps-cli/src/main/java/org/apache/baremaps/cli/Baremaps.java b/baremaps-cli/src/main/java/org/apache/baremaps/cli/Baremaps.java index 3a0aee76e..abe4dfee0 100644 --- a/baremaps-cli/src/main/java/org/apache/baremaps/cli/Baremaps.java +++ b/baremaps-cli/src/main/java/org/apache/baremaps/cli/Baremaps.java @@ -25,6 +25,7 @@ import java.util.concurrent.Callable; import org.apache.baremaps.cli.Baremaps.VersionProvider; import org.apache.baremaps.cli.database.Database; +import org.apache.baremaps.cli.dem.DEM; import org.apache.baremaps.cli.geocoder.Geocoder; import org.apache.baremaps.cli.iploc.IpLoc; import org.apache.baremaps.cli.map.Map; @@ -42,7 +43,14 @@ name = "baremaps", description = "A toolkit for producing vector tiles.", versionProvider = VersionProvider.class, - subcommands = {Workflow.class, Database.class, Map.class, Geocoder.class, IpLoc.class}, + subcommands = { + Workflow.class, + Database.class, + Map.class, + Geocoder.class, + IpLoc.class, + DEM.class + }, sortOptions = false) @SuppressWarnings("squid:S106") public class Baremaps implements Callable { diff --git a/baremaps-cli/src/main/java/org/apache/baremaps/cli/dem/DEM.java b/baremaps-cli/src/main/java/org/apache/baremaps/cli/dem/DEM.java new file mode 100644 index 000000000..25373ecf4 --- /dev/null +++ b/baremaps-cli/src/main/java/org/apache/baremaps/cli/dem/DEM.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.baremaps.cli.dem; + + + +import picocli.CommandLine; +import picocli.CommandLine.Command; + +/** + * A command group that contains commands for processing digital elevation models (DEMs). + */ +@Command(name = "dem", description = "Digital Elevation Models (DEMs) processing", + subcommands = { + Serve.class, + VectorTileContours.class + }, + sortOptions = false) +@SuppressWarnings("squid:S106") +public class DEM implements Runnable { + + @Override + public void run() { + CommandLine.usage(this, System.out); + } +} diff --git a/baremaps-cli/src/main/java/org/apache/baremaps/cli/dem/Serve.java b/baremaps-cli/src/main/java/org/apache/baremaps/cli/dem/Serve.java new file mode 100644 index 000000000..91d27f089 --- /dev/null +++ b/baremaps-cli/src/main/java/org/apache/baremaps/cli/dem/Serve.java @@ -0,0 +1,123 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.baremaps.cli.dem; + +import static org.apache.baremaps.utils.ObjectMapperUtils.objectMapper; + +import com.linecorp.armeria.common.*; +import com.linecorp.armeria.server.Server; +import com.linecorp.armeria.server.annotation.JacksonResponseConverterFunction; +import com.linecorp.armeria.server.cors.CorsService; +import com.linecorp.armeria.server.docs.DocService; +import com.linecorp.armeria.server.file.HttpFile; +import java.nio.file.Path; +import java.util.concurrent.Callable; +import org.apache.baremaps.dem.ElevationUtils; +import org.apache.baremaps.server.BufferedImageResource; +import org.apache.baremaps.server.VectorTileResource; +import org.apache.baremaps.tilestore.raster.*; +import picocli.CommandLine.Command; +import picocli.CommandLine.Option; + +/** + * A command that starts a tile server to preview elevation data. The server serves raster tiles for + * elevation and hillshade data, and vector tiles for contour and hillshade data. + */ +@Command(name = "serve", description = "Start a tile server to preview elevation data.") +public class Serve implements Callable { + + @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; + + @Option(names = {"--path"}, paramLabel = "PATH", + description = "The path of a digital elevation model (DEM) file in the geotiff format.") + private Path path; + + @Override + public Integer call() throws Exception { + // Initialize the tile stores + var geoTiffReader = new GeoTiffReader(path); + var rasterElevationTileStore = new TerrariumTileStore(geoTiffReader); + var rasterHillshadeTileStore = + new RasterHillshadeTileStore( + geoTiffReader, + ElevationUtils::terrariumToElevation); + var vectorHillshadeTileStore = + new VectorHillshadeTileStore( + geoTiffReader); + var vectorContourTileStore = + new VectorContourTileStore(geoTiffReader); + + // Initialize the server + var objectMapper = objectMapper(); + var jsonResponseConverter = new JacksonResponseConverterFunction(objectMapper); + var serverBuilder = Server.builder(); + serverBuilder.http(port); + + // Register the services + serverBuilder.annotatedService( + "/raster/elevation", + new BufferedImageResource(() -> rasterElevationTileStore), + jsonResponseConverter); + serverBuilder.annotatedService( + "/raster/hillshade", + new BufferedImageResource(() -> rasterHillshadeTileStore), + jsonResponseConverter); + serverBuilder.annotatedService( + "/vector/contour", + new VectorTileResource(() -> vectorContourTileStore), + jsonResponseConverter); + serverBuilder.annotatedService( + "/vector/hillshade", + new VectorTileResource(() -> vectorHillshadeTileStore), + jsonResponseConverter); + + var index = HttpFile.of(ClassLoader.getSystemClassLoader(), "/dem/index.html"); + serverBuilder.service("/", index.asService()); + + serverBuilder.decorator(CorsService.builderForAnyOrigin() + .allowAllRequestHeaders(true) + .allowRequestMethods( + HttpMethod.GET, + HttpMethod.POST, + HttpMethod.PUT, + HttpMethod.DELETE, + HttpMethod.OPTIONS, + HttpMethod.HEAD) + .allowCredentials() + .exposeHeaders(HttpHeaderNames.LOCATION) + .newDecorator()); + + serverBuilder.serviceUnder("/docs", new DocService()); + + serverBuilder.disableServerHeader(); + serverBuilder.disableDateHeader(); + var server = serverBuilder.build(); + + var startFuture = server.start(); + startFuture.join(); + + var shutdownFuture = server.closeOnJvmShutdown(); + shutdownFuture.join(); + + return 0; + } +} diff --git a/baremaps-cli/src/main/java/org/apache/baremaps/cli/dem/VectorTileContours.java b/baremaps-cli/src/main/java/org/apache/baremaps/cli/dem/VectorTileContours.java new file mode 100644 index 000000000..9328dd796 --- /dev/null +++ b/baremaps-cli/src/main/java/org/apache/baremaps/cli/dem/VectorTileContours.java @@ -0,0 +1,105 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.baremaps.cli.dem; + + + +import java.nio.file.Path; +import java.util.List; +import java.util.concurrent.Callable; +import org.apache.baremaps.maplibre.tileset.Tileset; +import org.apache.baremaps.maplibre.tileset.TilesetLayer; +import org.apache.baremaps.openstreetmap.stream.ProgressLogger; +import org.apache.baremaps.openstreetmap.stream.StreamUtils; +import org.apache.baremaps.tilestore.TileCoord; +import org.apache.baremaps.tilestore.TileEntry; +import org.apache.baremaps.tilestore.TileStoreException; +import org.apache.baremaps.tilestore.pmtiles.PMTilesStore; +import org.apache.baremaps.tilestore.raster.*; +import org.apache.baremaps.workflow.WorkflowException; +import org.apache.baremaps.workflow.tasks.ExportVectorTiles; +import org.locationtech.jts.geom.Envelope; +import picocli.CommandLine.Command; +import picocli.CommandLine.Option; + +@Command(name = "vector-contours", description = "Generate vector contours from a DEM.") +@SuppressWarnings({"squid:S106", "squid:S3864"}) +public class VectorTileContours implements Callable { + + @Option(names = {"--path"}, paramLabel = "PATH", description = "The path of a geoTIFF file.") + private Path path; + + @Option(names = {"--repository"}, paramLabel = "REPOSITORY", description = "The tile repository.", + required = true) + private Path repository; + + @Option(names = {"--format"}, paramLabel = "FORMAT", + description = "The format of the repository.") + private ExportVectorTiles.Format format = ExportVectorTiles.Format.FILE; + + + @Override + public Integer call() throws Exception { + var contourLayer = new TilesetLayer(); + contourLayer.setId("contours"); + + var tileset = new Tileset(); + tileset.setName("contours"); + tileset.setMinzoom(2); + tileset.setMaxzoom(10); + tileset.setCenter(List.of(0d, 0d, 1d)); + tileset.setBounds(List.of(-180d, -85.0511d, 180d, 85.0511d)); + tileset.setVectorLayers(List.of(contourLayer)); + + // Initialize the tile stores + try (var geoTiffReader = new GeoTiffReader(path); + var sourceTileStore = new VectorContourTileStore(geoTiffReader); + var targetTileStore = new PMTilesStore(repository, tileset);) { + + var envelope = new Envelope(-180, 180, -85.0511, 85.0511); + var count = TileCoord.count(envelope, 0, 10); + + var tileCoordIterator = + TileCoord.iterator(envelope, 2, 10); + var tileCoordStream = + StreamUtils.stream(tileCoordIterator).peek(new ProgressLogger<>(count, 1000)); + + + var bufferedTileEntryStream = StreamUtils.bufferInCompletionOrder(tileCoordStream, tile -> { + + try { + return new TileEntry<>(tile, sourceTileStore.read(tile)); + } catch (TileStoreException e) { + throw new WorkflowException(e); + } finally { + System.out.println("Processing tile " + tile); + } + }, 8); + + var partitionedTileEntryStream = StreamUtils.partition(bufferedTileEntryStream, 8); + partitionedTileEntryStream.forEach(batch -> { + try { + targetTileStore.write(batch); + } catch (TileStoreException e) { + throw new WorkflowException(e); + } + }); + return 0; + } + } +} diff --git a/baremaps-cli/src/main/java/org/apache/baremaps/cli/map/Dev.java b/baremaps-cli/src/main/java/org/apache/baremaps/cli/map/Dev.java index 13b37356c..9e81c4e56 100644 --- a/baremaps-cli/src/main/java/org/apache/baremaps/cli/map/Dev.java +++ b/baremaps-cli/src/main/java/org/apache/baremaps/cli/map/Dev.java @@ -27,6 +27,7 @@ import com.linecorp.armeria.server.file.FileService; import com.linecorp.armeria.server.file.HttpFile; import java.io.IOException; +import java.nio.ByteBuffer; import java.nio.file.Path; import java.util.concurrent.Callable; import java.util.function.Supplier; @@ -37,8 +38,8 @@ import org.apache.baremaps.maplibre.tileset.Tileset; import org.apache.baremaps.server.ChangeResource; import org.apache.baremaps.server.StyleResource; -import org.apache.baremaps.server.TileResource; import org.apache.baremaps.server.TilesetResource; +import org.apache.baremaps.server.VectorTileResource; import org.apache.baremaps.tilestore.TileStore; import org.apache.baremaps.tilestore.postgres.PostgresTileStore; import org.apache.baremaps.utils.PostgresUtils; @@ -96,7 +97,7 @@ public Integer call() throws Exception { } }; - var tileStoreSupplier = (Supplier) () -> { + var tileStoreSupplier = (Supplier>) () -> { var tileJSON = tilesetSupplier.get(); return new PostgresTileStore(datasource, tileJSON); }; @@ -116,7 +117,8 @@ public Integer call() throws Exception { var jsonResponseConverter = new JacksonResponseConverterFunction(objectMapper); serverBuilder.annotatedService(new ChangeResource(tilesetPath, stylePath), jsonResponseConverter); - serverBuilder.annotatedService(new TileResource(tileStoreSupplier), jsonResponseConverter); + serverBuilder.annotatedService("/tiles", new VectorTileResource(tileStoreSupplier), + jsonResponseConverter); serverBuilder.annotatedService(new StyleResource(styleSupplier), jsonResponseConverter); serverBuilder.annotatedService(new TilesetResource(tilesetSupplier), jsonResponseConverter); diff --git a/baremaps-cli/src/main/java/org/apache/baremaps/cli/map/MBTiles.java b/baremaps-cli/src/main/java/org/apache/baremaps/cli/map/MBTiles.java index 9628169d3..a6f52e6a2 100644 --- a/baremaps-cli/src/main/java/org/apache/baremaps/cli/map/MBTiles.java +++ b/baremaps-cli/src/main/java/org/apache/baremaps/cli/map/MBTiles.java @@ -28,6 +28,7 @@ import com.linecorp.armeria.server.docs.DocService; import com.linecorp.armeria.server.file.FileService; import com.linecorp.armeria.server.file.HttpFile; +import java.nio.ByteBuffer; import java.nio.file.Path; import java.util.concurrent.Callable; import java.util.function.Supplier; @@ -36,9 +37,9 @@ import org.apache.baremaps.maplibre.style.Style; import org.apache.baremaps.maplibre.tilejson.TileJSON; import org.apache.baremaps.server.*; -import org.apache.baremaps.tilestore.TileCache; import org.apache.baremaps.tilestore.TileStore; import org.apache.baremaps.tilestore.mbtiles.MBTilesStore; +import org.apache.baremaps.tilestore.vector.VectorTileCache; import org.apache.baremaps.utils.SqliteUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -83,8 +84,8 @@ public Integer call() throws Exception { var datasource = SqliteUtils.createDataSource(mbtilesPath, true); try (var tileStore = new MBTilesStore(datasource); - var tileCache = new TileCache(tileStore, caffeineSpec)) { - var tileStoreSupplier = (Supplier) () -> tileCache; + var tileCache = new VectorTileCache(tileStore, caffeineSpec)) { + var tileStoreSupplier = (Supplier>) () -> tileCache; var style = objectMapper.readValue(configReader.read(stylePath), Style.class); var styleSupplier = (Supplier + + +
+ + + \ No newline at end of file diff --git a/baremaps-server/src/main/resources/static/server.html b/baremaps-server/src/main/resources/static/server.html index d5ef77521..6c74e9a02 100644 --- a/baremaps-server/src/main/resources/static/server.html +++ b/baremaps-server/src/main/resources/static/server.html @@ -17,12 +17,15 @@ --> - + - + + + +