+ * Example usages: + * + *
+ * --input=tiles.mbtiles --output=tiles.mbtiles + * --input=tiles.mbtiles --output=tiles.pmtiles --skip_empty=false + * --input=tiles.pmtiles --output=tiles.mbtiles + * --input=tiles.mbtiles --output=tiles/ + * --input=tiles.mbtiles --output=tiles.json --out_tile_compression=gzip + * --input=tiles.mbtiles --output=tiles.csv --out_tile_compression=none + * --input=tiles.mbtiles --output=tiles.proto + *+ */ +public class TileCopy { + + private static final Logger LOGGER = LoggerFactory.getLogger(TileCopy.class); + + private final TileCopyConfig config; + + private final Counter.MultiThreadCounter tilesWrittenOverall = Counter.newMultiThreadCounter(); + + + TileCopy(TileCopyConfig config) { + this.config = config; + } + + public void run() throws IOException { + + if (!config.inArchive().exists()) { + throw new IllegalArgumentException("the input archive does not exist"); + } + + config.outArchive().setup(config.force(), config.append(), config.tileWriterThreads()); + + final var loggers = ProgressLoggers.create() + .addRateCounter("tiles", tilesWrittenOverall::get); + + try ( + var reader = TileArchives.newReader(config.inArchive(), config.inArguments()); + var writer = TileArchives.newWriter(config.outArchive(), config.outArguments()) + ) { + + final TileArchiveMetadata inMetadata = getInMetadata(reader); + final TileArchiveMetadata outMetadata = getOutMetadata(inMetadata); + + writer.initialize(); + try ( + var rawTiles = reader.getAllTiles(); + var it = config.skipEmpty() ? rawTiles.filter(t -> t.bytes() != null && t.bytes().length > 0) : rawTiles + ) { + + final var tileConverter = tileConverter(inMetadata.tileCompression(), outMetadata.tileCompression(), writer); + var pipeline = WorkerPipeline.start("archive", config.stats()) + .readFrom("tiles", () -> it) + .addBuffer("buffer", config.queueSize()) + .sinkTo("write", config.tileWriterThreads(), itt -> tileWriter(writer, itt, tileConverter)); + + final var f = pipeline.done().thenRun(() -> writer.finish(outMetadata)); + + loggers.awaitAndLog(f, config.logInterval()); + } + } + } + + private void tileWriter(WriteableTileArchive archive, Iterable
+ * Supported arguments: + *