Cloud-optimized, single-file archive format for pyramids of map tiles

Overview

PMTiles

PMTiles is a single-file archive format for tiled data. A PMTiles archive can be hosted on a commodity storage platform such as S3, and enables low-cost, zero-maintenance map applications that are "serverless" - free of a custom tile backend or third party provider.

Demo - watch your network request log

See also:

How To Use

Python library: pip install pmtiles

pmtiles-convert TILES.mbtiles TILES.pmtiles
pmtiles-convert TILES.pmtiles DIRECTORY
pmtiles-show TILES.pmtiles // see info about a PMTiles directory
pmtiles-serve TILES.pmtiles // start an HTTP server that decodes PMTiles into traditional Z/X/Y paths

See https://github.com/protomaps/PMTiles/tree/master/python/bin for library usage

JavaScript usage:

Include the script:

<script src="https://unpkg.com/[email protected]/pmtiles.js"></script>

Example of a raster PMTiles archive decoded and displayed in Leaflet:

const p = new pmtiles.PMTiles('osm_carto.pmtiles',{allow_200:true})
p.leafletLayer({attribution:'© <a href="https://openstreetmap.org">OpenStreetMap</a> contributors'}).addTo(map)

Specification

A detailed specification is forthcoming. PMTiles is a binary serialization format designed for two main access patterns: over the network, via HTTP 1.1 Byte Serving (Range: requests), or via memory-mapped files on disk.

Design considerations

  • Directories are recursive, with a maximum of 21,845 entries per directory.
    • 21845 is the total tiles of a pyramid with 8 levels, or 1+4+16+64+256+1024+4096+16384
  • Deduplication of tile data is handled by multiple entries pointing to the same offset in the archive.
  • The order of tile data in the archive is unspecified; an optimized implementation should arrange tiles on a 2D space-filling curve.

Details

  • The first 512,000 bytes of a PMTiles archive are reserved, and contain the headers as well as a root directory.
  • All integer values are little-endian.
  • The headers begin with a 2-byte magic number, "PM"
  • 2 bytes: the PMTiles specification version, right now always 1.
  • 4 bytes: the length of metadata (M bytes)
  • 2 bytes: the number of entries in the root directory (N)
  • M bytes: the metadata, by convention a JSON object.
  • N * 17 bytes: the root directory.

Directory structure

A directory is a sequence of 17 byte entries. An entry consists of:

  • 1 byte: the zoom level (Z) of the entry, with the top bit set to 1 instead of 0 to indicate the data is a child directory, not tile content.
  • 3 bytes: the X (column) of the entry.
  • 3 bytes: the Y (row) of the entry.
  • 6 bytes: the offset of where the data begins in the archive.
  • 4 bytes: the length of the data.

License

The reference implementations of PMTiles are published under the BSD 3-Clause License. The PMTiles specification itself is public domain, or under a CC0 license where applicable.

Comments
  • Alternative dir structure for a more compact storage and proximity clustering

    Alternative dir structure for a more compact storage and proximity clustering

    I would like to propose some changes to the directory structure, but these might be totally irrelevant due to my misunderstanding.

    Current directory entry is fixed at 17bytes, stores x,y as individual values, and requires x,y sorting order. I think all of those may benefit from a bit of restructuring:

    • Combine x and y values into a single interleaved value (z-curve). This will make tiles more locale-clustered, possibly reducing the number of range requests (web).
    • Make the combined x,y value size depend on the zoom level, rounding to the nearest byte boundary. zooms 0..3 -- 1 byte, 4..7 -- 2 bytes, etc. All leaf nodes are required to be the same zoom, making the directory entries the same size only inside a single directory block, rather than everywhere.
    • For the root dir, it could still be 17bytes (although it seems 6 bytes is a bit too much -- zoom 16..19 only requires 5 bytes, so unless pmtiles wants to support more... and even that can be made flex)
    v3 
    opened by nyurik 41
  • Using python Reader object with cloud storage

    Using python Reader object with cloud storage

    It seems like go-pmtiles is set up to read from cloud storage (S3, Google Storage etc), but the python version here is not. Is that correct? How hard would it be to add that? I use Google, but an S3 example would be great.

    If the Reader API is robust, I can add it into a flask/fastapi endpoint pretty trivially, implement my own authentication etc, but it definitely seems like being able to read the tiles from a file in Storage (rather than locally) is the really powerful use case here.

    opened by fscottfoti 12
  • js: slow to load due to no network parallelism

    js: slow to load due to no network parallelism

    When using pmtiles.js, network performance is a big bottleneck.

    This is visible in the leaflet raster demo but mitigated by a very fast backend (read from a small pmtiles file), so response-time is ~15ms per tile. Still you can see in the chrome dev tools that each fetch request is "stalled" (queued) until the previous one is answered.

    My setup responds in ~150ms per tile, so time from scrolling to display is several seconds.

    How can this be optimised?

    • Reducing number of requests using Multipart Ranges does not seem possible without adding complexity to the leaflet integration.
    • ... but according to chrome we're supposed to have up to 6 concurrent TCP connections per origin?
    opened by eddy-geek 11
  • Compression (spec v3)

    Compression (spec v3)

    Options:

    • Gzip compression - requires a library like pako, may be expensive
    • Cap'n proto packing: https://capnproto.org/encoding.html
    • Protobuf varints: https://developers.google.com/protocol-buffers/docs/encoding

    Use cases:

    • Dense tile pyramids
    • Sparse pyramids (tippecanoe output)
    v3 
    opened by bdon 9
  • Cordova support?

    Cordova support?

    I'm using Cordova/Ionic in order to serve offline tiles. I'm doing this by leveraging sqlite-ext to open a mbtiles file on the device and serve the tiles from there. Is there a way to to use pmtiles in Cordova in similar manor? From the documentation it seems that there's a need to use memory mapped file or something similar, have you experimented with this?

    opened by HarelM 9
  • writer: Leaf directories: Find best base zoom

    writer: Leaf directories: Find best base zoom

    ... to avoid extra indirection for as many tiles as we can

    Previously, we hardcoded a "base_zoom = 7", which is only only optimal for a whole world map. instead "7" is replaced with min zoom that fits all tiles.

    I only tested on one example (Bugianen, 152742 tiles) and got the expected base zoom of 14.

    
    ```sh
    sqlite3 Bugianen.mbtiles "SELECT  zoom_level, COUNT(*) FROM tiles GROUP BY zoom_level"
    12|448
    13|1792
    14|7168
    15|28672
    16|114662
    
    PYTHONPATH=$PWD bin/pmtiles-convert Bugianen.mbtiles optim_Bugianen.pmtiles
    Num tiles: 152742
    Num unique tiles: 151947
    Num leaves: 7168
    

    So, this needs more testing.

    opened by eddy-geek 8
  • pmtiles-convert Attribute Error

    pmtiles-convert Attribute Error

    I'm getting a python AttributeError when converting a .mbtiles file to .pmtiles

    pmtiles-convert postcode.mbtiles postcode2.pmtiles
    ('compression:', 'disabled')
    Traceback (most recent call last):
      File "/home/malcolm/.local/bin/pmtiles-convert", line 38, in <module>
        mbtiles_to_pmtiles(args.input, args.output, args.maxzoom, args.gzip)
      File "/home/malcolm/.local/lib/python2.7/site-packages/pmtiles/convert.py", line 40, in mbtiles_to_pmtiles
        writer.write_tile(row[0], row[1], flipped, force_compress(row[3], gzip))
      File "/home/malcolm/.local/lib/python2.7/site-packages/pmtiles/convert.py", line 15, in force_compress
        return gzip.decompress(data)
    AttributeError: 'module' object has no attribute 'decompress'
    

    postcode.zip

    opened by mem48 7
  • Consumes all memory on large input

    Consumes all memory on large input

    I'm trying to convert a 66 GB file and it quickly consumes 32GB ram then stops.

    Is there a solution to converting large files besides launching a super huge VM to handle conversions?

    opened by j 7
  • Unable to display map on browsers

    Unable to display map on browsers

    Hi! I'm new to this project. I tried running some html files in the example section in Safari/Chrome but maps were not shown. I got the following errors: image I couldn't figure out why fetch is aborted. Is there something I'm missing here?

    Thank you.

    opened by xinyuluo 7
  • Split a pmtiles file

    Split a pmtiles file

    Some hosts (like github pages) have maximum file sizes. Alternatives like https://github.com/phiresky/sql.js-httpvfs provide a way to split the tile archive until it is less than that max file size (https://github.com/phiresky/sql.js-httpvfs/blob/master/create_db.sh). Would it be possible for the pmtiles reader and writer to optionally support splitting a pmtiles file?

    opened by msbarry 6
  • canvas tile display seems to be transparent :/

    canvas tile display seems to be transparent :/

    hi, i'm using our own pmtiles tileset server, the test url is : https://tilesets.urbanease.io/cadastre/64/64102/without_protobuf.pmtiles the location for seeing it is :bayonne, france latlng=[43.492949,-1.474841]

    on the viewer, all seems to be ok bit leaflet preview don't work viewer i'm using react and leaflet with the npm protomaps package version 1.19.0

    my code is simple const map = useMap(); const url = 'https://tilesets.urbanease.io/cadastre/64/64102/without_protobuf.pmtiles'; const layer = protomaps.leafletLayer({ url: url, id: 'cadastral', }); layer.addTo(map);

    canvas are created but seems to be transparent, colors in paint_rules layer are good and opacity ok

    i don't understand where is the pb bad pmtiles file? no compatibility with leaflet? thx for help

    opened by DavidDvpt 5
  • More detailed Specification

    More detailed Specification

    Hey :)

    First of all. Thank you for the great format. It is imho the perfect solution to a problem that will become more and more prevalent in the near future.

    I tried to implement my own reader / writer in rust and found myself looking at the first-party implementations quite a lot, because I stumbled upon things that are not really clear in the specification.

    I think the project would benefit a lot from having a WAY MORE detailed specification (at least more than something I could print on a single page) and I was wondering whether a contribution on my part would be welcomed.

    I took the opportunity and wrote a really rough draft, of the section on the header. Just to give you an impression of what I would envision and get your feedback.

    PS: It's also totally fine if you do not think the specification needs to be improved.

    opened by DerZade 1
  • Refactor JS client to use streams instead of ArrayBuffers

    Refactor JS client to use streams instead of ArrayBuffers

    This will require a major version bump, as the Source API should return a ReadableStream. This is made possible by Lambda now supporting Node 18.

    Should also include #90 API changes as well to use If-Match.

    • [ ] fflate readablestream
    • [ ] varint readable stream
    opened by bdon 1
  • ETag problems in JavaScript client + passing through other metadata

    ETag problems in JavaScript client + passing through other metadata

    If the new resource has a new ETag but it shorter than the previous, the server might return 416 Range not Satisfiable, which does not have an accompanying ETag. This will invalidate the header, but present a bunch of errors in the console.

    We should unify on using the If-Match header in sending the requests, which will return 412 Precondition Failed in the mismatch case, which is designed for this specific situation.

    bug 
    opened by bdon 0
  • Inspector app improvements

    Inspector app improvements

    • [x] SVG tile previews should be zoomable
    • [x] Should be able to drill down into leaf directories
    • [x] should be able to preview vector tiles in leaflet
    • [ ] SVG should be feature-level inspectable
    • [ ] map preview should be feature-level inspectable
    • [ ] see directory Len and header-level metadata
    • [ ] inspect SVG with mismatched extents
    • [ ] correctly read tile and map hash states
    opened by bdon 1
Releases(v0.0.0-alpha)
A stable telegram bot to get restricted messages with custom thumbnail support

Save restricted content Bot A stable telegram bot to get restricted messages with custom thumbnail support

DEVANSH 3 Feb 09, 2022
The implementation of Learning Instance and Task-Aware Dynamic Kernels for Few Shot Learning

INSTA: Learning Instance and Task-Aware Dynamic Kernels for Few Shot Learning This repository provides the implementation and demo of Learning Instanc

11 Jan 02, 2023
Template to create a telegram bot in python

Template for Telegram Bot Template to create a telegram bot in python. How to Run Set your telegram bot token as environment variable TELEGRAM_BOT_TOK

PyTopia 12 Aug 14, 2022
A simple API wrapper for the Tenor API

Gifpy A simple API wrapper for the Tenor API Installation Python 3.9 or higher is recommended python3 -m pip install gifpy Clone repository: $ git cl

Juan Ignacio Battiston 4 Dec 22, 2021
A simple discord bot written in python which can surf subreddits, send a random meme, jokes and also weather of a given place

A simple Discord Bot A simple discord bot written in python which can surf subreddits, send a random meme, jokes and also weather of a given place. We

1 Jan 24, 2022
A synchronous, object oriented API wrapper for thecatapi

cats.py A synchronous, object oriented API wrapper for thecatapi Table Of Content cats.py Table Of Content Installation Usage Contributing FAQ License

Marcus 2 Feb 04, 2022
Telegram bot made with Python to get notified when visa slots are available

Visa slot bot I created this bot to getnotified when screenshots are available in the Telegram channel for dropbox appointments. How do I use this? Ch

Jimil 7 Jan 03, 2023
👾 Telegram Smart Group Assistant 🤖

DarkHelper 🌖 Features ⚡️ Smart anti-apam & anti-NFSW message checker Tag Members , Entertain facility , Welcommer ban , unban , mute , unmute , lock

amirali rajabi 38 Dec 18, 2022
Telegram Bot to store Posts and Documents and it can Access by Special Links.

Telegram Bot to store Posts and Documents and it can Access by Special Links. I Guess This Will Be Usefull For Many People..... 😇 . Features Fully cu

REX BOTZ 1 Dec 23, 2021
Telegram-Discord Bridge

imperial-toilet Скрипт, пересылающий сообщения из нескольких каналов Telegram в один/несколько каналов Discord. Технически это Telegram-юзербот и Disc

1 Jan 17, 2022
Projeto sobre BioInformática - MoA (mecanismos de ação)

Projeto: MoA no Paredawn Projeto sobre Bioinformatica - Mecanismos de Ação (MoA) MODELO PREDITIVO PARA PREVER O ATIVAMENTO DO MOA E MODELO PARA PREVER

Junior Torres 36 Feb 15, 2022
Query Amalgamator over StackOverflow and YouTube

QASY Query Amalgamator over StackOverflow and YouTube Decription A software you can use to save your valuable time of googling the errors you encounte

1 Nov 07, 2021
Discord bot that plays cricket with the user

CricBot Table of content Commands Installation Game rules License Commands S.No Command Use 1. cric Open the home window. This command is not necessa

Raveesh Yadav 1 Nov 19, 2021
cipher bot telegram

cipher-bot-telegram cipher bot telegram Telegram bot that encode/decode your messages To work correctly, you must install the latest version of python

anonim 1 Oct 10, 2021
The Fastest multi spambot of Telegram 🤞 🤞

Revil Spam Bot The Fastest multi spambot of Telegram 🤞 🤞 𝚂𝚄𝙿𝙿𝙾𝚁𝚃 🖤 ᴄʀᴇᴀᴛᴏʀ 🖤 ⚡ 𝓡𝓮𝓿𝓲𝓵 𝓗𝓾𝓷𝓽𝓮𝓻 𝔐𝔲𝔩𝔱𝔦 ẞø✞︎ ⚡ 𝓐 𝕾мοοτн 𝓐и∂ 𝕱

REVIL HUNTER 4 Dec 08, 2021
Project for the discipline of Visual Data Analysis at EMAp FGV.

Analysis of the dissemination of fake news about COVID-19 on Twitter This project was the final work for the discipline of Visual Data Analysis of the

Giovani Valdrighi 2 Jan 17, 2022
Client library for accessing IQM quantum computers

IQM Client Client-side library for connecting to an IQM quantum computer. Installation IQM client is not intended to be used directly by human users.

IQM 10 Dec 21, 2022
Create light scenes , voice control, ifttt, fuzzywuzzy speech correction and much more with Tuya light bulbs.

LightBox Features: Auto discover tuya lights Set and create moods (aka: light profiles) Change moods via IFTTT List moods via IFTTT FuzzyWuzzy, speech

Robert Nagtegaal 1 Dec 20, 2021
The official Magenta Voice Skill SDK used to develop skills for the Magenta Voice Assistant using Voice Platform!

Magenta Voice Skill SDK Development • Support • Contribute • Contributors • Licensing Magenta Voice Skill SDK for Python is a package that assists in

Telekom Open Source Software 18 Nov 19, 2022
A Python SDK for connecting devices to Microsoft Azure IoT services

V2 - We are now GA! This repository contains code for the Azure IoT SDKs for Python. This enables python developers to easily create IoT device soluti

Microsoft Azure 381 Dec 30, 2022