diff --git a/planetiler-core/src/main/java/com/onthegomap/planetiler/Planetiler.java b/planetiler-core/src/main/java/com/onthegomap/planetiler/Planetiler.java index 596942be..a14f8e58 100644 --- a/planetiler-core/src/main/java/com/onthegomap/planetiler/Planetiler.java +++ b/planetiler-core/src/main/java/com/onthegomap/planetiler/Planetiler.java @@ -1,9 +1,8 @@ package com.onthegomap.planetiler; -import com.onthegomap.planetiler.archive.TileArchiveConfig; +import com.onthegomap.planetiler.archive.TileArchive; import com.onthegomap.planetiler.archive.TileArchiveMetadata; import com.onthegomap.planetiler.archive.TileArchiveWriter; -import com.onthegomap.planetiler.archive.TileArchives; import com.onthegomap.planetiler.archive.WriteableTileArchive; import com.onthegomap.planetiler.collection.FeatureGroup; import com.onthegomap.planetiler.collection.LongLongMap; @@ -86,7 +85,7 @@ public class Planetiler { private final PlanetilerConfig config; private FeatureGroup featureGroup; private OsmInputFile osmInputFile; - private TileArchiveConfig output; + private TileArchive output; private boolean overwrite = false; private boolean ran = false; // most common OSM languages @@ -548,7 +547,7 @@ public class Planetiler { @Deprecated(forRemoval = true) public Planetiler setOutput(String argument, Path fallback) { this.output = - TileArchiveConfig + TileArchive .from(arguments.getString("output|" + argument, "output tile archive path", fallback.toString())); return this; } @@ -561,10 +560,10 @@ public class Planetiler { * * @param defaultOutputUri The default output URI string to write to. * @return this runner instance for chaining - * @see TileArchiveConfig For details on URI string formats and options. + * @see TileArchive For details on URI string formats and options. */ public Planetiler setOutput(String defaultOutputUri) { - this.output = TileArchiveConfig.from(arguments.getString("output", "output tile archive URI", defaultOutputUri)); + this.output = TileArchive.from(arguments.getString("output", "output tile archive URI", defaultOutputUri)); return this; } @@ -592,7 +591,7 @@ public class Planetiler { * * @param defaultOutputUri The default output URI string to write to. * @return this runner instance for chaining - * @see TileArchiveConfig For details on URI string formats and options. + * @see TileArchive For details on URI string formats and options. */ public Planetiler overwriteOutput(String defaultOutputUri) { this.overwrite = true; @@ -698,7 +697,7 @@ public class Planetiler { // must construct this after bounds providers are added in order to infer bounds from the input source if not provided tileArchiveMetadata = new TileArchiveMetadata(profile, config); - try (WriteableTileArchive archive = TileArchives.newWriter(output, config)) { + try (WriteableTileArchive archive = output.newWriter(config)) { featureGroup = FeatureGroup.newDiskBackedFeatureGroup(archive.tileOrder(), featureDbPath, profile, config, stats); stats.monitorFile("nodes", nodeDbPath); diff --git a/planetiler-core/src/main/java/com/onthegomap/planetiler/archive/TileArchiveConfig.java b/planetiler-core/src/main/java/com/onthegomap/planetiler/archive/TileArchive.java similarity index 59% rename from planetiler-core/src/main/java/com/onthegomap/planetiler/archive/TileArchiveConfig.java rename to planetiler-core/src/main/java/com/onthegomap/planetiler/archive/TileArchive.java index 021ccc50..0bbe6056 100644 --- a/planetiler-core/src/main/java/com/onthegomap/planetiler/archive/TileArchiveConfig.java +++ b/planetiler-core/src/main/java/com/onthegomap/planetiler/archive/TileArchive.java @@ -3,7 +3,12 @@ package com.onthegomap.planetiler.archive; import static com.onthegomap.planetiler.util.LanguageUtils.nullIfEmpty; import com.onthegomap.planetiler.config.Arguments; +import com.onthegomap.planetiler.config.PlanetilerConfig; +import com.onthegomap.planetiler.mbtiles.Mbtiles; +import com.onthegomap.planetiler.pmtiles.ReadablePmtiles; +import com.onthegomap.planetiler.pmtiles.WriteablePmtiles; import com.onthegomap.planetiler.util.FileUtils; +import java.io.IOException; import java.net.URI; import java.net.URLDecoder; import java.nio.charset.StandardCharsets; @@ -32,19 +37,19 @@ import java.util.Map; * @param uri Full URI including scheme, location, and options * @param options Parsed query parameters from the definition string */ -public record TileArchiveConfig( +public record TileArchive( Format format, Scheme scheme, URI uri, Map options ) { - private static TileArchiveConfig.Scheme getScheme(URI uri) { + private static TileArchive.Scheme getScheme(URI uri) { String scheme = uri.getScheme(); if (scheme == null) { return Scheme.FILE; } - for (var value : TileArchiveConfig.Scheme.values()) { + for (var value : TileArchive.Scheme.values()) { if (value.id().equals(scheme)) { return value; } @@ -75,15 +80,15 @@ public record TileArchiveConfig( return result; } - private static TileArchiveConfig.Format getFormat(URI uri) { + private static TileArchive.Format getFormat(URI uri) { String format = parseQuery(uri).get("format"); if (format == null) { format = getExtension(uri); } if (format == null) { - return TileArchiveConfig.Format.MBTILES; + return TileArchive.Format.MBTILES; } - for (var value : TileArchiveConfig.Format.values()) { + for (var value : TileArchive.Format.values()) { if (value.id().equals(format)) { return value; } @@ -94,7 +99,7 @@ public record TileArchiveConfig( /** * Parses a string definition of a tileset from a URI-like string. */ - public static TileArchiveConfig from(String string) { + public static TileArchive from(String string) { // unix paths parse fine as URIs, but need to explicitly parse windows paths with backslashes if (string.contains("\\")) { String[] parts = string.split("\\?", 2); @@ -109,7 +114,7 @@ public record TileArchiveConfig( /** * Parses a string definition of a tileset from a URI. */ - public static TileArchiveConfig from(URI uri) { + public static TileArchive from(URI uri) { if (uri.getScheme() == null) { String base = Path.of(uri.getPath()).toAbsolutePath().toUri().normalize().toString(); if (uri.getRawQuery() != null) { @@ -117,7 +122,7 @@ public record TileArchiveConfig( } uri = URI.create(base); } - return new TileArchiveConfig( + return new TileArchive( getFormat(uri), getScheme(uri), uri, @@ -125,6 +130,72 @@ public record TileArchiveConfig( ); } + /** + * Returns a new {@link WriteableTileArchive} from the string definition in {@code archive} that will be parsed with + * {@link TileArchive}. + * + * @throws IOException if an error occurs creating the resource. + */ + public static WriteableTileArchive newWriter(String archive, PlanetilerConfig config) throws IOException { + return from(archive).newWriter(config); + } + + /** + * Returns a new {@link ReadableTileArchive} from the string definition in {@code archive} that will be parsed with + * {@link TileArchive}. + * + * @throws IOException if an error occurs opening the resource. + */ + public static ReadableTileArchive newReader(String archive, PlanetilerConfig config) throws IOException { + return from(archive).newReader(config); + } + + /** Alias for {@link #newReader(String, PlanetilerConfig)}. */ + public static ReadableTileArchive newReader(Path path, PlanetilerConfig config) throws IOException { + return newReader(path.toString(), config); + } + + /** Alias for {@link #newWriter(String, PlanetilerConfig)}. */ + public static WriteableTileArchive newWriter(Path path, PlanetilerConfig config) throws IOException { + return newWriter(path.toString(), config); + } + + /** + * Returns a new {@link WriteableTileArchive} from this definition. + * + * @throws IOException if an error occurs creating the resource. + */ + public WriteableTileArchive newWriter(PlanetilerConfig config) + throws IOException { + Arguments settings = applyFallbacks(config.arguments()); + return switch (format) { + case MBTILES -> + // pass-through legacy arguments for fallback + Mbtiles.newWriteToFileDatabase(getLocalPath(), settings.orElse(config.arguments() + .subset(Mbtiles.LEGACY_VACUUM_ANALYZE, Mbtiles.LEGACY_COMPACT_DB, Mbtiles.LEGACY_SKIP_INDEX_CREATION))); + case PMTILES -> WriteablePmtiles.newWriteToFile(getLocalPath()); + }; + } + + private Arguments applyFallbacks(Arguments arguments) { + // to resolve "option" look to "?option=value" query param or "--mbtiles-option=value" command-line arg + return Arguments.of(options).orElse(arguments.withPrefix(format.id)); + } + + /** + * Returns a new {@link ReadableTileArchive} from this definition. + * + * @throws IOException if an error occurs opening the resource. + */ + public ReadableTileArchive newReader(PlanetilerConfig config) + throws IOException { + var options = applyFallbacks(config.arguments()); + return switch (format) { + case MBTILES -> Mbtiles.newReadOnlyDatabase(getLocalPath(), options); + case PMTILES -> ReadablePmtiles.newReadFromFile(getLocalPath()); + }; + } + /** * Returns the local path on disk that this archive reads/writes to, or {@code null} if it is not on disk (ie. an HTTP * repository). @@ -157,13 +228,6 @@ public record TileArchiveConfig( return getLocalPath() == null ? 0 : FileUtils.size(getLocalPath()); } - /** - * Returns an {@link Arguments} instance that returns the value for options directly from the query parameters in the - * URI, or from {@code arguments} prefixed by {@code "format_"}. - */ - public Arguments applyFallbacks(Arguments arguments) { - return Arguments.of(options).orElse(arguments.withPrefix(format.id)); - } public enum Format { MBTILES("mbtiles"), diff --git a/planetiler-core/src/main/java/com/onthegomap/planetiler/archive/TileArchives.java b/planetiler-core/src/main/java/com/onthegomap/planetiler/archive/TileArchives.java deleted file mode 100644 index fdd4617b..00000000 --- a/planetiler-core/src/main/java/com/onthegomap/planetiler/archive/TileArchives.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.onthegomap.planetiler.archive; - -import com.onthegomap.planetiler.config.PlanetilerConfig; -import com.onthegomap.planetiler.mbtiles.Mbtiles; -import com.onthegomap.planetiler.pmtiles.ReadablePmtiles; -import com.onthegomap.planetiler.pmtiles.WriteablePmtiles; -import java.io.IOException; -import java.nio.file.Path; - -/** Utilities for creating {@link ReadableTileArchive} and {@link WriteableTileArchive} instances. */ -public class TileArchives { - private TileArchives() {} - - /** - * Returns a new {@link WriteableTileArchive} from the string definition in {@code archive} that will be parsed with - * {@link TileArchiveConfig}. - * - * @throws IOException if an error occurs creating the resource. - */ - public static WriteableTileArchive newWriter(String archive, PlanetilerConfig config) throws IOException { - return newWriter(TileArchiveConfig.from(archive), config); - } - - /** - * Returns a new {@link ReadableTileArchive} from the string definition in {@code archive} that will be parsed with - * {@link TileArchiveConfig}. - * - * @throws IOException if an error occurs opening the resource. - */ - public static ReadableTileArchive newReader(String archive, PlanetilerConfig config) throws IOException { - return newReader(TileArchiveConfig.from(archive), config); - } - - /** - * Returns a new {@link WriteableTileArchive} from the string definition in {@code archive}. - * - * @throws IOException if an error occurs creating the resource. - */ - public static WriteableTileArchive newWriter(TileArchiveConfig archive, PlanetilerConfig config) - throws IOException { - var options = archive.applyFallbacks(config.arguments()); - return switch (archive.format()) { - case MBTILES -> - // pass-through legacy arguments for fallback - Mbtiles.newWriteToFileDatabase(archive.getLocalPath(), options.orElse(config.arguments() - .subset(Mbtiles.LEGACY_VACUUM_ANALYZE, Mbtiles.LEGACY_COMPACT_DB, Mbtiles.LEGACY_SKIP_INDEX_CREATION))); - case PMTILES -> WriteablePmtiles.newWriteToFile(archive.getLocalPath()); - }; - } - - /** - * Returns a new {@link ReadableTileArchive} from the string definition in {@code archive}. - * - * @throws IOException if an error occurs opening the resource. - */ - public static ReadableTileArchive newReader(TileArchiveConfig archive, PlanetilerConfig config) - throws IOException { - var options = archive.applyFallbacks(config.arguments()); - return switch (archive.format()) { - case MBTILES -> Mbtiles.newReadOnlyDatabase(archive.getLocalPath(), options); - case PMTILES -> ReadablePmtiles.newReadFromFile(archive.getLocalPath()); - }; - } - - /** Alias for {@link #newReader(String, PlanetilerConfig)}. */ - public static ReadableTileArchive newReader(Path path, PlanetilerConfig config) throws IOException { - return newReader(path.toString(), config); - } - - /** Alias for {@link #newWriter(String, PlanetilerConfig)}. */ - public static WriteableTileArchive newWriter(Path path, PlanetilerConfig config) throws IOException { - return newWriter(path.toString(), config); - } - -} diff --git a/planetiler-core/src/test/java/com/onthegomap/planetiler/archive/TileArchiveConfigTest.java b/planetiler-core/src/test/java/com/onthegomap/planetiler/archive/TileArchiveConfigTest.java index 78ff0f06..6ccab8c4 100644 --- a/planetiler-core/src/test/java/com/onthegomap/planetiler/archive/TileArchiveConfigTest.java +++ b/planetiler-core/src/test/java/com/onthegomap/planetiler/archive/TileArchiveConfigTest.java @@ -10,27 +10,27 @@ class TileArchiveConfigTest { @Test void testMbtiles() { - var config = TileArchiveConfig.from("output.mbtiles"); - assertEquals(TileArchiveConfig.Format.MBTILES, config.format()); - assertEquals(TileArchiveConfig.Scheme.FILE, config.scheme()); + var config = TileArchive.from("output.mbtiles"); + assertEquals(TileArchive.Format.MBTILES, config.format()); + assertEquals(TileArchive.Scheme.FILE, config.scheme()); assertEquals(Map.of(), config.options()); assertEquals(Path.of("output.mbtiles").toAbsolutePath(), config.getLocalPath()); } @Test void testMbtilesWithOptions() { - var config = TileArchiveConfig.from("output.mbtiles?compact=true"); - assertEquals(TileArchiveConfig.Format.MBTILES, config.format()); - assertEquals(TileArchiveConfig.Scheme.FILE, config.scheme()); + var config = TileArchive.from("output.mbtiles?compact=true"); + assertEquals(TileArchive.Format.MBTILES, config.format()); + assertEquals(TileArchive.Scheme.FILE, config.scheme()); assertEquals(Map.of("compact", "true"), config.options()); assertEquals(Path.of("output.mbtiles").toAbsolutePath(), config.getLocalPath()); } @Test void testPmtiles() { - assertEquals(TileArchiveConfig.Format.PMTILES, TileArchiveConfig.from("output.pmtiles").format()); - assertEquals(TileArchiveConfig.Format.PMTILES, TileArchiveConfig.from("output.mbtiles?format=pmtiles").format()); - assertEquals(TileArchiveConfig.Format.PMTILES, - TileArchiveConfig.from("file:///output.mbtiles?format=pmtiles").format()); + assertEquals(TileArchive.Format.PMTILES, TileArchive.from("output.pmtiles").format()); + assertEquals(TileArchive.Format.PMTILES, TileArchive.from("output.mbtiles?format=pmtiles").format()); + assertEquals(TileArchive.Format.PMTILES, + TileArchive.from("file:///output.mbtiles?format=pmtiles").format()); } } diff --git a/planetiler-examples/src/main/java/com/onthegomap/planetiler/examples/ToiletsOverlayLowLevelApi.java b/planetiler-examples/src/main/java/com/onthegomap/planetiler/examples/ToiletsOverlayLowLevelApi.java index 801489af..262a2aa5 100644 --- a/planetiler-examples/src/main/java/com/onthegomap/planetiler/examples/ToiletsOverlayLowLevelApi.java +++ b/planetiler-examples/src/main/java/com/onthegomap/planetiler/examples/ToiletsOverlayLowLevelApi.java @@ -2,9 +2,9 @@ package com.onthegomap.planetiler.examples; import com.onthegomap.planetiler.Planetiler; import com.onthegomap.planetiler.Profile; +import com.onthegomap.planetiler.archive.TileArchive; import com.onthegomap.planetiler.archive.TileArchiveMetadata; import com.onthegomap.planetiler.archive.TileArchiveWriter; -import com.onthegomap.planetiler.archive.TileArchives; import com.onthegomap.planetiler.archive.WriteableTileArchive; import com.onthegomap.planetiler.collection.FeatureGroup; import com.onthegomap.planetiler.collection.LongLongMap; @@ -113,7 +113,7 @@ public class ToiletsOverlayLowLevelApi { // then process rendered features, grouped by tile, encoding them into binary vector tile format // and writing to the output mbtiles file. - try (WriteableTileArchive db = TileArchives.newWriter(output, config)) { + try (WriteableTileArchive db = TileArchive.newWriter(output, config)) { TileArchiveWriter.writeOutput(featureGroup, db, () -> FileUtils.fileSize(output), tileArchiveMetadata, config, stats); } catch (IOException e) {