pmtiles¶
PMTiles utilities in punkst currently cover:
- Export point-only PMTiles as TSV
- Write mono raster PMTiles from tiled counts
- Write single-level polygon-only PMTiles
- Write generic polygon PMTiles from arbitrary properties
- Build PMTiles pyramids
Point and simple-polygon PMTiles support both MLT and MVT.
For writing point/pixel-only PMTiles, see tile-op.
Acknowledgement: PMTiles support in punkst depends on Clipper2 for polygon operations, borrows from tippecanoe (which supports MVT) and MLT's cpp implementation.
Export PMTiles as TSV¶
punkst export-pmtiles reads an MLT- or MVT-backed PMTiles archive. Point archives export back to a plain TSV plus .index that tile-op can read again. Simple-polygon archives export to a TSV with centroid, vertices, optional feature ID, and properties.
Requirements and behavior:
--inor--in-datamust point to a point PMTiles archive with MLT or MVT format--outspecifies the output prefix. The output includespath/prefix.tsvandpath/prefix.index--tile-sizeis required and defines the tile size for the output file (in the original units)- by default, data is read from the archive's max-zoom level
- use
--zoom <z>to export a specific PMTiles zoom level; the command errors if the archive has no tiles at that zoom - output columns are
x,y, optionalz, then the decoded PMTiles schema columns - missing
KandPvalues are rendered as-1and0; other nullable fields are rendered asNA
Region filters are supported in this mode:
--xmin,--xmax,--ymin,--ymax--extract-region-geojson--zmin,--zmax
For simple-polygon archives, add --polygon. Polygon export writes only path/prefix.tsv; --tile-size is not required. --zoom is also supported for polygon export.
Write mono raster PMTiles¶
punkst tiles2mono writes grayscale PNG raster PMTiles from a tiled transcript/count TSV produced by pts2tiles. It is used by deploy-cartoscope to generate the SGE mono basemap.
punkst tiles2mono \
--in path/transcripts.tiled \
--min-zoom 7 \
--max-zoom 18 \
--display-transform linear \
--out path/sge-mono-dark.pmtiles \
--threads 4
Options:
--inis shorthand for--in-tsv path/prefix.tsv --in-index path/prefix.index; if available,path/prefix.coord_range.tsvis used for raster bounds--icol-x,--icol-y, and--icol-countselect the 0-based x, y, and count columns (defaults:0,1,3)--min-zoomand--max-zoomset the raster PMTiles zoom range--adjust-quantilecontrols per-zoom density auto-adjustment (default:0.99); use--no-auto-adjustto write capped raw count intensities--display-transformcontrols the final grayscale mapping after auto-adjustment:linear(default) orlog1p- by default, raw data is parsed only for
--max-zoom; lower zoom levels are derived by summing child pixels into parent pixels while preserving full count dynamic range until final PNG encoding --max-zoom-from-rawparses raw data for zooms greater than or equal to the given value, then derives lower zooms from parent layers; set it to--min-zoomto parse every zoom from raw data
Write single-zoom polygon PMTiles¶
punkst poly2pmtiles writes a polygon-only MLT or MVT PMTiles archive with a single zoom level from a factor-probability table (output from punkst topic-model or lda-transform). Use --format MVT for MVT output; the default is MLT.
It supports two input styles:
- hexagon mode: build polygon geometry from hex centers
- generic polygon mode: link factor-probability rows to polygon geometry by polygon ID
Shared settings¶
These options apply to both hexagon mode and generic simple-polygon mode.
Shared factor table settings¶
--in-tsvpoints to the factor-probability table--outsets the output PMTiles archive--formatcan beMLTorMVT(default:MLT)--pmtiles-zoom(required) sets the output zoom level--topk-coland--topp-colset column names for the top factor ID and probability (default:topKandtopP)- compact
K1/P1,K2/P2, ... columns are recognized automatically - dense numeric factor columns named
0..K-1are recognized automatically --factor-col-beginand--factor-col-endexplicitly select dense factor probability columns by a 0-based inclusive column range; selected columns are mapped to factor IDs0..K-1in column order--top-kcontrols how many top factors are retained from dense factor columns (default:3)--prob-threskeeps only factor probabilities above the threshold as nullable properties (default:1e-4)--coord-scalescales input coordinates before Web Mercator tiling (default:1, no scaling)--layer-nameoptionally sets the PMTiles layer name (default: basename of--out)--threadssets the number of encode threads
Polygon tiling behavior¶
These options are similar to tippecanoe's clipping options:
--tile-buffer-pxsets the screen-pixel buffer used by the default clipped/duplicated mode (default:5) (matchingtippecanoe -b)--no-clippingduplicates each polygon into every touched tile without clipping it to tile boundaries (matchingtippecanoe -pc)--no-duplicationstores each polygon intact in exactly one tile at the requested zoom instead of clipping and duplicating it across tile boundaries (matchingtippecanoe -pD)--no-clippingand--no-duplicationare mutually exclusive--clip-scalesets the integer scale used internally for polygon clipping--extentsets the vector tile extent
Hexagon mode specific settings¶
Use this when the input table contains x and y coordinates as hexagon centers.
punkst poly2pmtiles \
--in-tsv path/model.results.tsv.gz \
--hex-grid-dist 12 \
--pmtiles-zoom 18 \
--out path/model.hex.z18.pmtiles
Options:
--hex-grid-dist(required) specifies the distance between adjacent grid points on the hexagonal grid--x-coland--y-colset column names for the hex center coordinates (default:xandy)
Generic simple-polygon mode with geometry file¶
Use this when the factor-probability table contains a polygon ID column and polygon geometry is provided in a separate file. For example, if you ran punkst topic-model on segmented cells and you want to create a PMTiles archive with cell boundaries as geometry.
punkst poly2pmtiles \
--in-tsv path/cells.results.tsv \
--id-col cell_id \
--in-geom path/cell_boundaries.csv.gz \
--g-icol-id 0 \
--g-icol-x 1 \
--g-icol-y 2 \
--pmtiles-zoom 18 \
--out path/cells.z18.pmtiles
Options:
--in-geompoints to the polygon geometry file--id-colis required in generic polygon mode and names the polygon ID column in the factor-probability table--geom-formatcan beauto,table,geojson, orjson;autouses the file extension--geom-id-propnames the GeoJSON/JSON feature property used as the polygon ID--id-is-u32tellspunkstto parse that input ID directly as au32MLT feature ID- if
--id-is-u32is not used,punkstassigns each polygon an internal feature ID in first-encounter order from the geometry file --keep-org-idoptionally keeps the original input string ID as a regular string property column in the PMTiles output--g-icol-id,--g-icol-x, and--g-icol-yset the 0-based table-geometry columns for polygon ID,x, andy--g-icol-orderis optional; if omitted, the geometry rows are assumed to already be in vertex order--out-sidecar-tsvoptionally writespolygon_id,part_index,feature_id,center_x, andcenter_y--cartoscope-boundarywrites the CartoScope boundary schema (cell_id,topK,topP,K2/P2, ...); factor IDs in boundary properties are stored as strings for CartoScope compatibility
Geometry file format:
- plain or gzipped TSV/CSV, or GeoJSON/JSON with Polygon/MultiPolygon features
- one row per vertex
- empty lines and lines starting with
#are ignored - if the first non-comment line does not contain numeric
xandyvalues at the selected geometry columns, it is treated as a header and skipped - later malformed numeric rows are treated as errors
Example geometry file:
Output:
- writes one PMTiles archive at the requested zoom level
- stores the polygon ID in the dedicated MLT feature ID column
- stores
topK,topP, and retained dense factor probabilities as feature properties; in--cartoscope-boundarymode it stores nullableK2/P2...Kn/Pninstead - if
--keep-org-idis used, also stores the original string ID as a regular string property column - output from this step can be passed to
punkst build-pyramid --polygon
Boundary behavior:
- by default, polygons that cross tile boundaries are clipped to each tile plus a
--tile-buffer-pxscreen-pixel buffer, and may appear in more than one tile - with
--no-clipping, polygons are duplicated across touched tiles but kept intact in each copy - with
--no-duplication, each polygon is assigned to a single tile and stored there intact --no-duplicationis mainly useful when polygons are much smaller than the tile size
For CartoScope cell-level PMTiles and deployment packaging, see Deploy punkst results to CartoScope.
Write generic polygon PMTiles from arbitrary properties¶
punkst poly2pmtiles-generic writes a single-zoom polygon PMTiles archive from
an arbitrary property TSV plus polygon geometry. It reuses the same simple
polygon geometry reader and clipping behavior as poly2pmtiles, but does not
interpret the input as factor probabilities.
punkst poly2pmtiles-generic \
--in-tsv cell_stats.tsv \
--id-col cell_id \
--in-geom cell_boundaries.tsv \
--g-icol-id 0 --g-icol-x 1 --g-icol-y 2 --g-icol-order 3 \
--string-cols cell_name,cell_type \
--int-cols cluster \
--float-cols residual,cosine_sim,entropy \
--format MVT \
--pmtiles-zoom 18 \
--layer-name cell_boundaries \
--out cell_stats.z18.pmtiles
The input TSV must have a header. --id-col names the column used to join rows
to geometry records. The same ID is also written as a string property so that
build-pyramid --polygon-id-col <id-col> can reconstruct lower zoom levels from
the original geometry source.
Property columns are explicit:
--string-cols,--int-cols, and--float-colsaccept repeated values or comma-separated names.- Missing values (
"",NA,NaN,nan,NULL,null) are written as nullable properties. - The output supports both
--format MVTand--format MLT; MVT is the browser-oriented choice.
After writing the single-zoom archive, build a pyramid with:
punkst build-pyramid \
--polygon-in cell_stats.z18.pmtiles \
--polygon-source cell_boundaries.tsv \
--polygon-id-col cell_id \
--icol-id 0 --icol-x 1 --icol-y 2 --icol-order 3 \
--min-zoom 10 \
--out cell_stats.pmtiles
Build PMTiles pyramids¶
punkst build-pyramid builds an MLT or MVT PMTiles pyramid from existing max-zoom PMTiles inputs.
Use --point-in for point PMTiles, --polygon-in for simple-polygon PMTiles, or both to write one mixed point+polygon pyramid. The older --point --in ... and --polygon --in ... forms are still accepted for compatibility.
Point-only pyramids¶
punkst build-pyramid \
--point-in path/pixel.z18.pmtiles \
--min-zoom 10 \
--max-tile-bytes 5000000 \
--max-tile-features 50000 \
--scale-factor-compression 10 \
--threads 4 \
--out path/pixel.pyramid.pmtiles
Simple-polygon pyramids¶
punkst build-pyramid --polygon builds lower zoom levels for simple-polygon MLT or MVT PMTiles.
Current support is limited to:
- simple polygons only
- no holes
- no multipolygon in the internal pyramid representation
- polygon inputs that carry one unique polygon ID per feature
punkst build-pyramid \
--polygon-in path/hex.z18.pmtiles \
--min-zoom 10 \
--polygon-priority area \
--max-tile-bytes 5000000 \
--max-tile-features 50000 \
--scale-factor-compression 10 \
--threads 4 \
--out path/hex.pyramid.pmtiles
--polygon-prioritychooses how polygons are retained when down-sampling is needed:random,area(default, in decreasing order)
Mixed point and polygon pyramids¶
Provide both input flags to build a single PMTiles archive with a point layer and a polygon layer:
punkst build-pyramid \
--point-in path/pixel.z18.pmtiles \
--polygon-in path/hex.z18.pmtiles \
--min-zoom 10 \
--max-tile-bytes 5000000 \
--max-tile-features 50000 \
--threads 4 \
--out path/mixed.pyramid.pmtiles
The point and polygon inputs must use the same PMTiles vector format (MLT or MVT), gzip tile compression, and max zoom. The polygon input follows the same simple-polygon metadata requirements as polygon-only pyramid building.
If a single input PMTiles already contains both point and polygon layers, use the explicit compatibility form:
punkst build-pyramid --mixed \
--in path/mixed.z18.pmtiles \
--min-zoom 10 \
--out path/mixed.pyramid.pmtiles
Behavior:
- by default, if the input PMTiles has an MLT feature ID column, that is used as the polygon ID
--polygon-id-colis optional and acts as a hard override when you want to use a regular property column instead of the MLT feature ID column- if neither an MLT feature ID column nor
--polygon-id-colis available, the command reports an error - for PMTiles written by
punkst poly2pmtilesin hex mode, which contains only hexagons, a shortcut is taken by using the stored hexagonal grid coordinates to build the geometry instead of recovering it from the encoded geometry - for generic polygon inputs, uses the finest input zoom level to recover one canonical polygon per ID before building parent levels
- if
--polygon-sourceis provided, that file is used as the geometry source override - by default, parent tiles use clipped polygons that may appear in more than one tile, with clipping buffered by
--tile-buffer-pxscreen pixels --tile-buffer-pxoverrides that buffer in--polygonmode; if omitted, the value stored in the input archive metadata is used- with
--no-clipping, parent tiles keep duplicated polygons intact instead of clipping them to tile boundaries - with
--no-duplication, each polygon is kept intact and written to only one tile per zoom level --no-clippingand--no-duplicationare mutually exclusive
Limitations for the generic polygon mode:
- supports only simple polygons without holes
- when the truth
--polygon-sourceis not provided and polygons are recovered from the max-zoom geometry, we may need to repair polygons that are clipped and duplicated across tile boundaries. If a polygon becomes multipolygons or acquires holes after that repair, it is ignored
Optional polygon source file:
--polygon-source optionally specifies a polygon-vertex table to override geometry recovery from the finest input zoom. Plain or gzipped TSV/CSV files are supported.
By default, coordinates read from --polygon-source are multiplied by the input archive's coord_scale metadata before EPSG:3857 tiling so they match the packaged PMTiles coordinate space. Use --polygon-source-coord-scale to override that default when the source table is already pre-scaled or uses a different scale.
Required fields (specified by 0-based column index):
- polygon ID --icol-id (default: 0)
- x coordinate --icol-x (default: 1)
- y coordinate --icol-y (default: 2)
Optional field: vertex order --icol-order. If provided, it is used to assemble each polygon ring, otherwise, rows in the input file are assumed to already be in polygon-vertex order.
- --polygon-source-coord-scale optionally overrides the scale applied to --polygon-source coordinates before EPSG:3857 tiling
(Empty lines and lines starting with # are ignored; if the first non-comment line does not have numeric x and y values at --icol-x and --icol-y, it is treated as a header line and skipped; after that first line, malformed numeric values are treated as errors)
Example:
Shared requirements and options¶
Requirements:
--in(or--in-data, used equivalently) must point to the input PMTiles archive--outmust be a concrete PMTiles file path- choose point, polygon, or mixed mode. Use
--point-in,--polygon-in, or both for the explicit form; the older compatibility form uses--point,--polygon, or--mixedwith--in
Main options:
--min-zoomsets the coarsest zoom that should exist in the output archive--max-tile-bytessets a target upper bound on compressed tile size (default: 5MB)--max-tile-featuressets a target upper bound on the number of features per tile (default: 50K)--scale-factor-compressioncontrols how aggressively features are kept before the final tile-size check (default: 10)--threadscontrols parallel processing--polygon-id-colis an optional hard override for polygon ID lookup in--polygonmode--polygon-prioritysets polygon retention mode for--polygon--polygon-sourceand--icol-*options are used only for--polygonin generic polygon mode--tile-buffer-pxsets the screen-pixel clip buffer for the default clipped polygon mode--no-clippingswitches polygon output to intact duplicated polygons without tile-boundary clipping--no-duplicationswitches polygon output from clipped/duplicated tiles to single-tile intact storage
Input PMTiles handling:
- if the input already contains zoom levels down to or below
--min-zoom, the command exits directly - if the input already contains some lower zoom levels but not enough, those existing levels are preserved byte-for-byte and only the missing coarser levels are built