pmtiles CLI
Installation
pmtiles is a single binary with no external dependencies.
The source code is on GitHub at protomaps/go-pmtiles.
To download, see Releases on GitHub for your OS and architecture.
An official Docker Hub image is available at protomaps/go-pmtiles.
CLI Overview
Local archives
The CLI works with local tilesets on disk, for example:
pmtiles show test.pmtilesRemote archives
However, pmtiles can also work with remote HTTP archives and tilesets on cloud storage, even in private buckets.
pmtiles show https://r2-public.protomaps.com/protomaps-sample-datasets/cb_2018_us_zcta510_500k.pmtilespmtiles uses the go-cloud library for connecting and authenticating to cloud storage.
Commands for S3, Azure Blob and Google Cloud Storage:
INFO
Commands that uses URL characters like ? and &, should be escaped by a backslash \ in your shell.
pmtiles show test.pmtiles --bucket=s3://BUCKET_NAME pmtiles show test.pmtiles --bucket=azblob://CONTAINER_NAME?storage_account=ACCOUNT pmtiles show test.pmtiles --bucket=gs://BUCKET_NAMEFor S3-compatible blob storage (Minio, Cloudflare R2, etc) outside of AWS:
pmtiles show test.pmtiles --bucket=s3://BUCKET_NAME?endpoint=https://example.com®ion=autoINFO
Some S3-compatible storage servers like Minio, Ceph and SeaweedFS may require additional URL options like s3ForcePathStyle=true.
Private buckets
pmtiles uses go-cloud's default authentication methods for each cloud provider.
For example, the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables are used to sign requests to private S3-compatible buckets:
export AWS_ACCESS_KEY_ID=MY_KEY export AWS_SECRET_ACCESS_KEY=MY_SECRET pmtiles show NAME.pmtiles --bucket=s3://R2_BUCKET_NAME\?endpoint=https://R2_ACCOUNT_ID.r2.cloudflarestorage.com\®ion=autoCommands
show
pmtiles show INPUT.pmtiles pmtiles show INPUT.pmtiles --bucket=s3://BUCKET_NAME pmtiles show INPUT.pmtiles --header-json pmtiles show INPUT.pmtiles --metadataPrint an archive's header data and metadata.
--header-json: print a JSON representation of part of the header to stdout.--metadata: print the JSON metadata to stdout.
tile
pmtiles tile INPUT.pmtiles 0 0 0Output a single tile's contents to stdout.
verify
pmtiles verify INPUT.pmtilesCheck that an archive is ordered correctly and has correct header information.
extract
pmtiles extract INPUT.pmtiles OUTPUT.pmtiles --bbox=MIN_LON,MIN_LAT,MAX_LON,MAX_LAT pmtiles extract INPUT.pmtiles OUTPUT.pmtiles --region=REGION.geojson pmtiles extract https://example.com/INPUT.pmtiles OUTPUT.pmtiles --maxzoom=MAXZOOM pmtiles extract INPUT.pmtiles OUTPUT.pmtiles --maxzoom=MAXZOOM --bucket=s3://BUCKET_NAMECreate a smaller archive from a larger archive. The source archive may be local or remote. The source archive must be clustered.
Options:
--maxzoom: Extract only a subset of zoom levels. Extracting a full sub-pyramid from 0 tomaxzoomis always an efficient operation that makes minimal I/O or network requests to the source archive.--minzoom: Extract only a partial sub-pyramid. This may require many more requests than leaving the default--minzoom=0. Because this removes overview zoom levels, it should only be used in specific situations.--region: a GeoJSON Polygon, Multipolygon, Feature, or FeatureCollection.--download-threadsNumber of parallel requests to speed up downloads.--overfetchextra data to download to batch small requests: 0.05 is 5%.
merge
pmtiles merge INPUT_1.pmtiles INPUT_2.pmtiles OUTPUT.pmtiles pmtiles merge INPUT_1.pmtiles INPUT_2.pmtiles INPUT_3.pmtiles OUTPUT.pmtilesCombine disjoint archives into a single archive. The output archive contains all tile data in the inputs. All inputs must be clustered and match in tile type and compression.
serve
The simplest way to consume PMTiles on the web is directly in the browser with pmtiles.js along with a renderer-specific client. However, decoding PMTiles on the server and exposing a ZXY API works with more clients and can result in lower latency. A ZXY API is directly supported by web and native renderers such as MapLibre, without needing the PMTiles client library. Using pmtiles serve also allows serving a public API from a private storage bucket.
INFO
When using pmtiles serve, requests for the raw file like /test.pmtiles, either whole or partial range requests, are not supported. A standard web server like Apache, Nginx or Caddy can serve those.
Serve a directory or bucket of tilesets (like TILESET.pmtiles) from local or cloud storage as a ZXY endpoint:
pmtiles serve . # serves this directory at http://localhost:8080/TILESET/{z}/{x}/{y}.mvt # the .pmtiles extension is added automatically # TileJSON at http://localhost:8080/TILESET.json pmtiles serve . --bucket=https://example.com pmtiles serve / --bucket=s3://BUCKET_NAME pmtiles serve PREFIX --bucket=s3://BUCKET_NAMEFor ZXY URLs, the extension must match the type of the tiles in the archive, for example mvt, png, jpg, webp, avif.
Flags:
--cors=ORIGIN1,ORIGIN2set the valid origins for theAccess-Control-Allow-OriginCORS header.*is a valid value but must be escaped in your shell. Appropriate for development use.--cache-size=SIZE_MBset the global size of the header and directory LRU cache, shared across all archives. Default is 64 MB.--port=PORTspecify the HTTP port. Defaults to 8080.--public-url: Required for serving TileJSON. Specify the full URL as it should appear to the browser client likehttp://localhost:8080orhttps://example.com.
For production usage, it's recommended to run behind a CDN or reverse proxy like Caddy to handle SSL and CORS. See the guide on Accelerating PMTiles.
convert
Convert an MBTiles archive to PMTiles.
pmtiles convert INPUT.mbtiles OUTPUT.pmtilesFor the Docker image:
docker run -v $(pwd):/data --rm protomaps/go-pmtiles convert /data/INPUT.mbtiles /data/OUTPUT.pmtilesOptions:
--no-deduplication: Do not attempt to de-duplicate tile contents. Use this to speed upconvertif you know the input has only unique tiles.--tmpdir: specify the location of the temporary directory.
cluster
Cluster an unclustered existing archive, optimizing the size and layout. Archives created by tippecanoe, planetiler, and the pmtiles CLI are already clustered.
pmtiles cluster INPUT.pmtilesOptions:
--no-deduplication: Do not attempt to de-duplicate tile contents. Use this to speed upclusterif you know the input has only unique tiles.
upload
Upload an archive to cloud storage.
# requires environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY credentials pmtiles upload INPUT.pmtiles REMOTE.pmtiles --bucket=s3://BUCKET_NAME # upload to a s3-compatible endpoint # some storage systems require path-style requests pmtiles upload INPUT.pmtiles REMOTE.pmtiles --bucket=s3://BUCKET_NAME?region=auto&endpoint=https://example.com&use_path_style=trueYou will need write permissions to the bucket, for example this AWS IAM policy:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "s3:*", "Resource": "arn:aws:s3:::my-bucket-name/*" } ] }edit
Change parts of the archive header, or replace the archive JSON metadata.
pmtiles show NAME.pmtiles --header-json > header.json pmtiles show NAME.pmtiles --metadata > metadata.json # make changes to header.json or metadata.json pmtiles edit NAME.pmtiles --header-json=header.json --metadata=metadata.json- The
tile_type,tile_compresssion,minzoom,maxzoom,boundsandcenterof the header can be edited. Other fields are not editable. Editing only the header will modify the file in-place. - Writing the JSON metadata requires writing a new copy of the archive, which will then replace
NAME.pmtiles.
version
pmtiles versionPrint the version of the command line tool.