Skip to content

Instantly share code, notes, and snippets.

@JesseCrocker
Last active March 28, 2024 21:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JesseCrocker/5394dea13524a3c033ffbfe2cb66806b to your computer and use it in GitHub Desktop.
Save JesseCrocker/5394dea13524a3c033ffbfe2cb66806b to your computer and use it in GitHub Desktop.
Extract tiles in a PMTiles file to a directory in z/x/y.ext format. Chat GPT wrote this for me.
#!/usr/bin/env python3
import argparse
import os
from pmtiles.reader import all_tiles
from pmtiles.reader import MmapSource
from pmtiles.reader import Reader
from pmtiles.tile import TileType
from tqdm import tqdm
def get_file_extension(tile_type: TileType) -> str:
extensions = {
TileType.UNKNOWN: "unknown",
TileType.MVT: "mvt",
TileType.PNG: "png",
TileType.JPEG: "jpg",
TileType.WEBP: "webp",
TileType.AVIF: "avif",
}
return extensions.get(tile_type, "unknown")
def extract_tiles(pmtiles_file: str, dest_dir: str) -> None:
if not os.path.exists(pmtiles_file):
print(f"Error: PMTiles file '{pmtiles_file}' does not exist.")
exit(1)
if not os.path.exists(dest_dir):
os.makedirs(dest_dir)
with open(pmtiles_file, "rb") as f:
source = MmapSource(f)
reader = Reader(source)
header = reader.header()
tile_type = header["tile_type"]
for zxy, tile_data in tqdm(
all_tiles(source), "Extracting tiles", unit=" tiles"
):
z, x, y = zxy
tile_dir = os.path.join(dest_dir, str(z), str(x))
os.makedirs(tile_dir, exist_ok=True)
extension = get_file_extension(tile_type)
tile_path = os.path.join(tile_dir, f"{y}.{extension}")
with open(tile_path, "wb") as tile_file:
tile_file.write(tile_data)
def main() -> None:
parser = argparse.ArgumentParser(description="Extract PMTiles to a directory.")
parser.add_argument("pmtiles_file", type=str, help="Path to the PMTiles file.")
parser.add_argument(
"dest_dir", type=str, help="Destination directory for the extracted tiles."
)
args = parser.parse_args()
extract_tiles(args.pmtiles_file, args.dest_dir)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment