| Title: | R Interface to PMTiles |
|---|---|
| Description: | Provides R bindings to the PMTiles command-line interface for working with PMTiles archives. PMTiles is a single-file archive format for tiled data that enables efficient cloud-native storage and retrieval of map tiles. This package wraps the go-pmtiles CLI to provide functions for inspecting, extracting, converting, and serving PMTiles archives. |
| Authors: | Kyle Walker [aut, cre], Brandon Liu [cph] (go-pmtiles library author), Protomaps LLC [cph] (go-pmtiles library copyright holder) |
| Maintainer: | Kyle Walker <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.2.0 |
| Built: | 2026-10-04 14:39:27 UTC |
| Source: | https://github.com/walkerke/pmtiles |
These helpers build the bucket specification used by pm_upload(),
pm_show(), pm_extract(), pm_tile(), and pm_serve_zxy(), so you
never have to hand-assemble a "s3://bucket?endpoint=...®ion=..." URL.
Each helper knows the URL format and required parameters for its provider:
r2_bucket(): Cloudflare R2 (the recommended PMTiles host; no egress fees)
s3_bucket(): Amazon S3
gcs_bucket(): Google Cloud Storage
azure_bucket(): Azure Blob Storage
s3_compatible_bucket(): any other S3-compatible service (MinIO,
DigitalOcean Spaces, Backblaze B2, Source Cooperative, ...)
Credentials can optionally be supplied to each helper. When provided, they
are passed only to the pmtiles subprocess for that one command – they
are never written into your R session's environment variables. When
omitted, the standard environment variables for the provider are used
(e.g. AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY for S3 and R2).
r2_bucket( bucket, account_id, jurisdiction = NULL, access_key = NULL, secret_key = NULL ) s3_bucket( bucket, region = NULL, access_key = NULL, secret_key = NULL, session_token = NULL ) gcs_bucket(bucket, credentials_file = NULL) azure_bucket(container, storage_account, access_key = NULL, sas_token = NULL) s3_compatible_bucket( bucket, endpoint, region = NULL, path_style = FALSE, access_key = NULL, secret_key = NULL, session_token = NULL )r2_bucket( bucket, account_id, jurisdiction = NULL, access_key = NULL, secret_key = NULL ) s3_bucket( bucket, region = NULL, access_key = NULL, secret_key = NULL, session_token = NULL ) gcs_bucket(bucket, credentials_file = NULL) azure_bucket(container, storage_account, access_key = NULL, sas_token = NULL) s3_compatible_bucket( bucket, endpoint, region = NULL, path_style = FALSE, access_key = NULL, secret_key = NULL, session_token = NULL )
bucket |
Name of the bucket (as shown in your cloud provider's
console), e.g. |
account_id |
For |
jurisdiction |
For |
access_key, secret_key
|
Optional access key ID and secret access key
for S3-style providers (for |
region |
For |
session_token |
For |
credentials_file |
For |
container |
For |
storage_account |
For |
sas_token |
For |
endpoint |
For |
path_style |
Logical. Use path-style addressing
( |
An object of class pmtiles_bucket: the bucket URL plus any
credentials to pass to the pmtiles subprocess. Pass it as the bucket
argument of pm_upload() and friends, anywhere a bucket string is
accepted.
You need three things, all from the Cloudflare dashboard:
Account ID: R2 overview page, right-hand Account Details panel.
Access key + secret key: Manage R2 API Tokens > Create API
Token with "Object Read & Write" permission. The token-creation
screen shows the Access Key ID and Secret Access Key once – store
them (e.g. in ~/.Renviron).
Bucket name: the name you gave the bucket when creating it.
R2's S3 API requires region=auto; the helper sets this for you.
Credentials follow the standard AWS chain: AWS_ACCESS_KEY_ID /
AWS_SECRET_ACCESS_KEY environment variables, shared config files
(~/.aws/credentials), or an attached IAM role. Supply access_key /
secret_key only if you want to override that chain for this command.
Authentication uses Application Default Credentials. Either run
gcloud auth application-default login once, or create a service account
key (IAM & Admin > Service Accounts > Keys) and pass its JSON file path
as credentials_file.
Find the storage account's access keys under Storage account >
Security + networking > Access keys in the Azure portal. Pass one as
access_key, or use a SAS token via sas_token. If neither is given,
the AZURE_STORAGE_KEY / AZURE_STORAGE_SAS_TOKEN environment variables
are used.
Use s3_compatible_bucket() with the provider's endpoint:
| Provider | Endpoint | Notes |
| MinIO | https://minio.example.com |
needs path_style = TRUE and region |
| DigitalOcean Spaces | https://{region}.digitaloceanspaces.com |
region inferred |
| Backblaze B2 | https://s3.{region}.backblazeb2.com |
region inferred |
| Source Cooperative | https://data.source.coop |
bucket is your org name; pass session_token
|
## Not run: # Cloudflare R2: upload with credentials from ~/.Renviron pm_upload( "tiles.pmtiles", "tiles.pmtiles", bucket = r2_bucket( "my-tiles", account_id = "0123456789abcdef0123456789abcdef", access_key = Sys.getenv("R2_ACCESS_KEY_ID"), secret_key = Sys.getenv("R2_SECRET_ACCESS_KEY") ) ) # Amazon S3, using the standard AWS credential chain pm_upload( "tiles.pmtiles", "tiles.pmtiles", bucket = s3_bucket("my-tiles", region = "us-east-1") ) # Google Cloud Storage with a service account key pm_upload( "tiles.pmtiles", "tiles.pmtiles", bucket = gcs_bucket("my-tiles", credentials_file = "~/keys/gcs.json") ) # Azure Blob Storage pm_upload( "tiles.pmtiles", "tiles.pmtiles", bucket = azure_bucket( "tiles-container", storage_account = "mystorageaccount", access_key = Sys.getenv("AZURE_STORAGE_KEY") ) ) # DigitalOcean Spaces (any S3-compatible service) pm_upload( "tiles.pmtiles", "tiles.pmtiles", bucket = s3_compatible_bucket( "my-tiles", endpoint = "https://nyc3.digitaloceanspaces.com", access_key = Sys.getenv("DO_SPACES_KEY"), secret_key = Sys.getenv("DO_SPACES_SECRET") ) ) # The helpers work everywhere a bucket is accepted bucket <- r2_bucket("my-tiles", account_id = "0123456789abcdef0123456789abcdef") pm_show("tiles.pmtiles", bucket = bucket) pm_extract("tiles.pmtiles", "subset.pmtiles", bucket = bucket, maxzoom = 10) ## End(Not run)## Not run: # Cloudflare R2: upload with credentials from ~/.Renviron pm_upload( "tiles.pmtiles", "tiles.pmtiles", bucket = r2_bucket( "my-tiles", account_id = "0123456789abcdef0123456789abcdef", access_key = Sys.getenv("R2_ACCESS_KEY_ID"), secret_key = Sys.getenv("R2_SECRET_ACCESS_KEY") ) ) # Amazon S3, using the standard AWS credential chain pm_upload( "tiles.pmtiles", "tiles.pmtiles", bucket = s3_bucket("my-tiles", region = "us-east-1") ) # Google Cloud Storage with a service account key pm_upload( "tiles.pmtiles", "tiles.pmtiles", bucket = gcs_bucket("my-tiles", credentials_file = "~/keys/gcs.json") ) # Azure Blob Storage pm_upload( "tiles.pmtiles", "tiles.pmtiles", bucket = azure_bucket( "tiles-container", storage_account = "mystorageaccount", access_key = Sys.getenv("AZURE_STORAGE_KEY") ) ) # DigitalOcean Spaces (any S3-compatible service) pm_upload( "tiles.pmtiles", "tiles.pmtiles", bucket = s3_compatible_bucket( "my-tiles", endpoint = "https://nyc3.digitaloceanspaces.com", access_key = Sys.getenv("DO_SPACES_KEY"), secret_key = Sys.getenv("DO_SPACES_SECRET") ) ) # The helpers work everywhere a bucket is accepted bucket <- r2_bucket("my-tiles", account_id = "0123456789abcdef0123456789abcdef") pm_show("tiles.pmtiles", bucket = bucket) pm_extract("tiles.pmtiles", "subset.pmtiles", bucket = bucket, maxzoom = 10) ## End(Not run)
Cluster an unclustered PMTiles archive, optimizing its size and layout. Archives created by tippecanoe, planetiler, and the pmtiles CLI are already clustered and do not need this operation.
pm_cluster(input, no_deduplication = FALSE, verbose = TRUE)pm_cluster(input, no_deduplication = FALSE, verbose = TRUE)
input |
Path to input PMTiles file. The file will be modified in place. |
no_deduplication |
Logical. If |
verbose |
Logical. If |
Invisibly returns the path to the clustered archive.
## Not run: # Cluster an archive pm_cluster("archive.pmtiles") # Cluster without deduplication (faster) pm_cluster("archive.pmtiles", no_deduplication = TRUE) ## End(Not run)## Not run: # Cluster an archive pm_cluster("archive.pmtiles") # Cluster without deduplication (faster) pm_cluster("archive.pmtiles", no_deduplication = TRUE) ## End(Not run)
Convert an MBTiles database to PMTiles format. The conversion process automatically deduplicates tiles unless disabled.
pm_convert( input, output, force = FALSE, no_deduplication = FALSE, tmpdir = NULL, verbose = TRUE )pm_convert( input, output, force = FALSE, no_deduplication = FALSE, tmpdir = NULL, verbose = TRUE )
input |
Path to input MBTiles file. |
output |
Path for output PMTiles file. |
force |
Logical. If |
no_deduplication |
Logical. If |
tmpdir |
Optional path to a folder for temporary files during conversion. If not specified, uses the system temporary directory. |
verbose |
Logical. If |
Invisibly returns the path to the output archive.
## Not run: # Convert MBTiles to PMTiles pm_convert("input.mbtiles", "output.pmtiles") # Convert without deduplication (faster) pm_convert("input.mbtiles", "output.pmtiles", no_deduplication = TRUE) # Force overwrite existing file pm_convert("input.mbtiles", "output.pmtiles", force = TRUE) ## End(Not run)## Not run: # Convert MBTiles to PMTiles pm_convert("input.mbtiles", "output.pmtiles") # Convert without deduplication (faster) pm_convert("input.mbtiles", "output.pmtiles", no_deduplication = TRUE) # Force overwrite existing file pm_convert("input.mbtiles", "output.pmtiles", force = TRUE) ## End(Not run)
Generate vector tiles from GeoJSON, FlatGeobuf, or CSV input using tippecanoe. This function requires tippecanoe to be installed on your system. See https://github.com/felt/tippecanoe for installation instructions.
pm_create( input, output, layer_name = NULL, min_zoom = NULL, max_zoom = NULL, guess_maxzoom = FALSE, smallest_maximum_zoom_guess = NULL, base_zoom = NULL, extend_zooms_if_still_dropping = FALSE, full_detail = NULL, low_detail = NULL, minimum_detail = NULL, extra_detail = NULL, exclude = NULL, include = NULL, exclude_all = FALSE, drop_rate = NULL, drop_densest_as_needed = FALSE, drop_fraction_as_needed = FALSE, drop_smallest_as_needed = FALSE, drop_lines = FALSE, drop_polygons = FALSE, coalesce = FALSE, coalesce_smallest_as_needed = FALSE, coalesce_densest_as_needed = FALSE, coalesce_fraction_as_needed = FALSE, cluster_distance = NULL, cluster_maxzoom = NULL, simplification = NULL, no_line_simplification = FALSE, simplify_only_low_zooms = FALSE, no_tiny_polygon_reduction = FALSE, detect_shared_borders = FALSE, no_simplification_of_shared_nodes = FALSE, preserve_input_order = FALSE, reorder = FALSE, hilbert = FALSE, maximum_tile_bytes = NULL, maximum_tile_features = NULL, no_feature_limit = FALSE, no_tile_size_limit = FALSE, generate_ids = TRUE, calculate_feature_density = FALSE, read_parallel = FALSE, attribution = NULL, description = NULL, buffer = NULL, other_options = NULL, force = TRUE, keep_geojson = FALSE, quiet = FALSE )pm_create( input, output, layer_name = NULL, min_zoom = NULL, max_zoom = NULL, guess_maxzoom = FALSE, smallest_maximum_zoom_guess = NULL, base_zoom = NULL, extend_zooms_if_still_dropping = FALSE, full_detail = NULL, low_detail = NULL, minimum_detail = NULL, extra_detail = NULL, exclude = NULL, include = NULL, exclude_all = FALSE, drop_rate = NULL, drop_densest_as_needed = FALSE, drop_fraction_as_needed = FALSE, drop_smallest_as_needed = FALSE, drop_lines = FALSE, drop_polygons = FALSE, coalesce = FALSE, coalesce_smallest_as_needed = FALSE, coalesce_densest_as_needed = FALSE, coalesce_fraction_as_needed = FALSE, cluster_distance = NULL, cluster_maxzoom = NULL, simplification = NULL, no_line_simplification = FALSE, simplify_only_low_zooms = FALSE, no_tiny_polygon_reduction = FALSE, detect_shared_borders = FALSE, no_simplification_of_shared_nodes = FALSE, preserve_input_order = FALSE, reorder = FALSE, hilbert = FALSE, maximum_tile_bytes = NULL, maximum_tile_features = NULL, no_feature_limit = FALSE, no_tile_size_limit = FALSE, generate_ids = TRUE, calculate_feature_density = FALSE, read_parallel = FALSE, attribution = NULL, description = NULL, buffer = NULL, other_options = NULL, force = TRUE, keep_geojson = FALSE, quiet = FALSE )
input |
An sf object, path to a GeoJSON/FlatGeobuf/CSV file, or a list for multi-layer output. For multi-layer PMTiles, provide either:
|
output |
Path to output file (.pmtiles or .mbtiles) |
layer_name |
Name for the layer in the tileset. If NULL, derived from input filename or a random string for sf objects (tippecanoe -l). For multi-layer input, can be a character vector of names (one per layer), or names will be derived from list names. |
min_zoom |
Minimum zoom level (tippecanoe -Z, default 0) |
max_zoom |
Maximum zoom level (tippecanoe -z, default 14) |
guess_maxzoom |
If TRUE, guess appropriate maxzoom based on feature density (tippecanoe -zg) |
smallest_maximum_zoom_guess |
Use specified zoom if lower maxzoom is guessed (tippecanoe –smallest-maximum-zoom-guess) |
base_zoom |
Zoom at and above which all points are included (tippecanoe -B). If NULL, defaults to maxzoom. |
extend_zooms_if_still_dropping |
Increase maxzoom if features still being dropped (tippecanoe -ae) |
full_detail |
Detail at max zoom (default 12, for 4096 tile resolution, tippecanoe -d) |
low_detail |
Detail at lower zooms (default 12, tippecanoe -D) |
minimum_detail |
Minimum detail if tiles too big (default 7, tippecanoe -m) |
extra_detail |
Generate tiles with extra detail for precision (tippecanoe –extra-detail) |
exclude |
Character vector of attribute names to exclude (tippecanoe -x) |
include |
Character vector of attribute names to include, excluding all others (tippecanoe -y) |
exclude_all |
If TRUE, exclude all attributes and encode only geometries (tippecanoe -X) |
drop_rate |
Rate at which features dropped at zoom levels below basezoom (default 2.5, tippecanoe -r). Use "g" for auto-guess. |
drop_densest_as_needed |
Reduce feature spacing if tile too large (tippecanoe -as) |
drop_fraction_as_needed |
Drop fraction of features to keep under size limit (tippecanoe -ad) |
drop_smallest_as_needed |
Drop smallest features to keep under size limit (tippecanoe -an) |
drop_lines |
Apply dot-dropping to lines (tippecanoe -al) |
drop_polygons |
Apply dot-dropping to polygons (tippecanoe -ap) |
coalesce |
Coalesce consecutive features with same attributes (tippecanoe -ac) |
coalesce_smallest_as_needed |
Combine smallest features into nearby ones (tippecanoe -aN) |
coalesce_densest_as_needed |
Combine densest features into nearby ones (tippecanoe -aD) |
coalesce_fraction_as_needed |
Combine fraction of features into nearby ones (tippecanoe -aS) |
cluster_distance |
Cluster points within distance of each other (tippecanoe -K, max 255) |
cluster_maxzoom |
Max zoom for clustering (tippecanoe -k). Use "g" to set to maxzoom - 1. |
simplification |
Multiply tolerance for line/polygon simplification (tippecanoe -S, default ~1) |
no_line_simplification |
Don't simplify lines and polygons (tippecanoe -ps) |
simplify_only_low_zooms |
Don't simplify at maxzoom (tippecanoe -pS) |
no_tiny_polygon_reduction |
Don't combine tiny polygons into squares (tippecanoe -pt) |
detect_shared_borders |
Detect and simplify shared polygon borders identically (tippecanoe -ab) |
no_simplification_of_shared_nodes |
Don't simplify nodes where lines converge/diverge (tippecanoe -pn) |
preserve_input_order |
Preserve original input order instead of geographic order (tippecanoe -pi) |
reorder |
Reorder features to put same attributes in sequence (tippecanoe -ao) |
hilbert |
Use Hilbert Curve order instead of Z-order (tippecanoe -ah) |
maximum_tile_bytes |
Maximum compressed tile size in bytes (default 500K, tippecanoe -M) |
maximum_tile_features |
Maximum features per tile (default 200,000, tippecanoe -O) |
no_feature_limit |
Don't limit tiles to 200,000 features (tippecanoe -pf) |
no_tile_size_limit |
Don't limit tiles to 500K bytes (tippecanoe -pk) |
generate_ids |
Add feature IDs to features without them (tippecanoe -ai) |
calculate_feature_density |
Add tippecanoe_feature_density attribute (tippecanoe -ag) |
read_parallel |
Use multiple threads for line-delimited GeoJSON (tippecanoe -P) |
attribution |
Attribution text for tileset (tippecanoe -A) |
description |
Description for tileset (tippecanoe -N) |
buffer |
Buffer size in screen pixels (default 5, tippecanoe -b) |
other_options |
Character vector of additional tippecanoe options not covered by other parameters. Example: c("-pf", "-pk", "–coalesce") |
force |
If TRUE, overwrite existing output file (default TRUE, tippecanoe -f) |
keep_geojson |
If TRUE, keep temporary GeoJSON file for sf objects |
quiet |
If TRUE, suppress progress messages (tippecanoe -q) |
This function wraps the tippecanoe command-line tool. Tippecanoe must be installed separately:
macOS: brew install tippecanoe
Ubuntu: sudo apt-get install tippecanoe
From source: https://github.com/felt/tippecanoe
The function handles sf objects by converting them to temporary GeoJSON files.
For faster GeoJSON writing with large datasets, install the yyjsonr
package, which can be significantly faster than the default sf::st_write().
Path to output file (invisibly)
pm_layer() for creating layers with per-layer options
## Not run: library(sf) # Simple usage with sf object pm_create( my_sf_data, "output.pmtiles", max_zoom = 14 ) # Complex parcel tileset pm_create( "parcels.geojson", "parcels.pmtiles", layer_name = "parcels", min_zoom = 10, max_zoom = 18, full_detail = 15, preserve_input_order = TRUE, no_tiny_polygon_reduction = TRUE, coalesce_densest_as_needed = TRUE, coalesce_fraction_as_needed = TRUE, extend_zooms_if_still_dropping = TRUE, simplification = 1, detect_shared_borders = TRUE, other_options = c("-pf", "-pk", "-ai") ) # Point clustering pm_create( points_sf, "points.pmtiles", max_zoom = 14, cluster_distance = 10, cluster_maxzoom = "g", generate_ids = TRUE ) # With attribute filtering pm_create( roads_sf, "roads.pmtiles", include = c("name", "highway", "surface"), drop_densest_as_needed = TRUE, simplification = 10 ) # Multi-layer with shared options (simple) pm_create( input = list( counties = counties_sf, tracts = tracts_sf ), output = "census.pmtiles", min_zoom = 2, max_zoom = 12 ) # Multi-layer with per-layer options (using pm_layer) pm_create( input = list( pm_layer( input = counties_sf, layer_name = "counties", min_zoom = 2, max_zoom = 8 ), pm_layer( input = tracts_sf, layer_name = "tracts", min_zoom = 8, max_zoom = 14, drop_densest_as_needed = TRUE ) ), output = "census.pmtiles", generate_ids = TRUE ) ## End(Not run)## Not run: library(sf) # Simple usage with sf object pm_create( my_sf_data, "output.pmtiles", max_zoom = 14 ) # Complex parcel tileset pm_create( "parcels.geojson", "parcels.pmtiles", layer_name = "parcels", min_zoom = 10, max_zoom = 18, full_detail = 15, preserve_input_order = TRUE, no_tiny_polygon_reduction = TRUE, coalesce_densest_as_needed = TRUE, coalesce_fraction_as_needed = TRUE, extend_zooms_if_still_dropping = TRUE, simplification = 1, detect_shared_borders = TRUE, other_options = c("-pf", "-pk", "-ai") ) # Point clustering pm_create( points_sf, "points.pmtiles", max_zoom = 14, cluster_distance = 10, cluster_maxzoom = "g", generate_ids = TRUE ) # With attribute filtering pm_create( roads_sf, "roads.pmtiles", include = c("name", "highway", "surface"), drop_densest_as_needed = TRUE, simplification = 10 ) # Multi-layer with shared options (simple) pm_create( input = list( counties = counties_sf, tracts = tracts_sf ), output = "census.pmtiles", min_zoom = 2, max_zoom = 12 ) # Multi-layer with per-layer options (using pm_layer) pm_create( input = list( pm_layer( input = counties_sf, layer_name = "counties", min_zoom = 2, max_zoom = 8 ), pm_layer( input = tracts_sf, layer_name = "tracts", min_zoom = 8, max_zoom = 14, drop_densest_as_needed = TRUE ) ), output = "census.pmtiles", generate_ids = TRUE ) ## End(Not run)
Modify parts of the PMTiles archive header or replace the JSON metadata. Editing only the header modifies the file in-place, while editing metadata creates a new copy.
pm_edit(input, header_json = NULL, metadata = NULL, verbose = TRUE)pm_edit(input, header_json = NULL, metadata = NULL, verbose = TRUE)
input |
Path to PMTiles file to edit. |
header_json |
Path to JSON file containing modified header data.
Use |
metadata |
Path to JSON file containing replacement metadata.
Use |
verbose |
Logical. If |
Invisibly returns the path to the edited archive.
The following header fields can be modified:
tile_type: Type of tiles (e.g., "mvt", "png", "jpg")
tile_compression: Compression format
minzoom: Minimum zoom level
maxzoom: Maximum zoom level
bounds: Geographic bounds
center: Center point and zoom
Other header fields are not editable.
Editing only the header modifies the file in-place
Writing new metadata requires creating a new archive copy
The new copy will replace the original file
## Not run: # Get current header and metadata header <- pm_show("archive.pmtiles", header_json = TRUE) metadata <- pm_show("archive.pmtiles", metadata = TRUE) # Modify and save to JSON files jsonlite::write_json(header, "header.json", auto_unbox = TRUE) jsonlite::write_json(metadata, "metadata.json", auto_unbox = TRUE) # Edit the archive pm_edit("archive.pmtiles", header_json = "header.json", metadata = "metadata.json") ## End(Not run)## Not run: # Get current header and metadata header <- pm_show("archive.pmtiles", header_json = TRUE) metadata <- pm_show("archive.pmtiles", metadata = TRUE) # Modify and save to JSON files jsonlite::write_json(header, "header.json", auto_unbox = TRUE) jsonlite::write_json(metadata, "metadata.json", auto_unbox = TRUE) # Edit the archive pm_edit("archive.pmtiles", header_json = "header.json", metadata = "metadata.json") ## End(Not run)
Create a smaller PMTiles archive from a larger one by extracting a subset of zoom levels or a geographic region. The source archive can be local or remote.
pm_extract( input, output, bbox = NULL, region = NULL, minzoom = NULL, maxzoom = NULL, bucket = NULL, download_threads = 4, overfetch = 0.05, dry_run = FALSE, verbose = TRUE )pm_extract( input, output, bbox = NULL, region = NULL, minzoom = NULL, maxzoom = NULL, bucket = NULL, download_threads = 4, overfetch = 0.05, dry_run = FALSE, verbose = TRUE )
input |
Path to input PMTiles archive (local or remote URL). |
output |
Path for the output PMTiles archive. |
bbox |
Numeric vector of bounding box coordinates in the form
|
region |
Path to a GeoJSON file containing a Polygon, MultiPolygon,
Feature, or FeatureCollection defining the area of interest.
Mutually exclusive with |
minzoom |
Minimum zoom level to extract (inclusive). Default is 0. |
maxzoom |
Maximum zoom level to extract (inclusive). If not specified, extracts all zoom levels from the source. |
bucket |
Optional remote bucket specification if |
download_threads |
Number of parallel download threads for remote archives. Default is 4. |
overfetch |
Ratio of extra data to download to minimize number of requests. For example, 0.05 means 5 percent overfetch. Default is 0.05. |
dry_run |
Logical. If |
verbose |
Logical. If |
Extracting a full sub-pyramid from zoom 0 to maxzoom is an efficient
operation. However, using a minzoom > 0 may require many more requests
and should only be used when necessary.
Invisibly returns the path to the output archive.
## Not run: # Extract zoom levels 0-10 pm_extract("large.pmtiles", "subset.pmtiles", maxzoom = 10) # Extract by bounding box pm_extract( "large.pmtiles", "bbox_subset.pmtiles", bbox = c(-122.5, 37.7, -122.3, 37.9) ) # Extract by GeoJSON region pm_extract( "large.pmtiles", "region_subset.pmtiles", region = "boundary.geojson", maxzoom = 12 ) # Extract from remote archive pm_extract( "large.pmtiles", "local_copy.pmtiles", bucket = "s3://my-bucket", maxzoom = 10, download_threads = 8 ) ## End(Not run)## Not run: # Extract zoom levels 0-10 pm_extract("large.pmtiles", "subset.pmtiles", maxzoom = 10) # Extract by bounding box pm_extract( "large.pmtiles", "bbox_subset.pmtiles", bbox = c(-122.5, 37.7, -122.3, 37.9) ) # Extract by GeoJSON region pm_extract( "large.pmtiles", "region_subset.pmtiles", region = "boundary.geojson", maxzoom = 12 ) # Extract from remote archive pm_extract( "large.pmtiles", "local_copy.pmtiles", bucket = "s3://my-bucket", maxzoom = 10, download_threads = 8 ) ## End(Not run)
Creates a layer specification for use with pm_create() when building
multi-layer PMTiles with per-layer tippecanoe options. Each layer can have
its own zoom levels, drop rates, simplification settings, and other options.
pm_layer( input, layer_name, min_zoom = NULL, max_zoom = NULL, guess_maxzoom = NULL, smallest_maximum_zoom_guess = NULL, base_zoom = NULL, extend_zooms_if_still_dropping = NULL, full_detail = NULL, low_detail = NULL, minimum_detail = NULL, extra_detail = NULL, exclude = NULL, include = NULL, exclude_all = NULL, drop_rate = NULL, drop_densest_as_needed = NULL, drop_fraction_as_needed = NULL, drop_smallest_as_needed = NULL, drop_lines = NULL, drop_polygons = NULL, coalesce = NULL, coalesce_smallest_as_needed = NULL, coalesce_densest_as_needed = NULL, coalesce_fraction_as_needed = NULL, cluster_distance = NULL, cluster_maxzoom = NULL, simplification = NULL, no_line_simplification = NULL, simplify_only_low_zooms = NULL, no_tiny_polygon_reduction = NULL, detect_shared_borders = NULL, no_simplification_of_shared_nodes = NULL, preserve_input_order = NULL, reorder = NULL, hilbert = NULL, maximum_tile_bytes = NULL, maximum_tile_features = NULL, no_feature_limit = NULL, no_tile_size_limit = NULL, generate_ids = NULL, calculate_feature_density = NULL, read_parallel = NULL, buffer = NULL, other_options = NULL )pm_layer( input, layer_name, min_zoom = NULL, max_zoom = NULL, guess_maxzoom = NULL, smallest_maximum_zoom_guess = NULL, base_zoom = NULL, extend_zooms_if_still_dropping = NULL, full_detail = NULL, low_detail = NULL, minimum_detail = NULL, extra_detail = NULL, exclude = NULL, include = NULL, exclude_all = NULL, drop_rate = NULL, drop_densest_as_needed = NULL, drop_fraction_as_needed = NULL, drop_smallest_as_needed = NULL, drop_lines = NULL, drop_polygons = NULL, coalesce = NULL, coalesce_smallest_as_needed = NULL, coalesce_densest_as_needed = NULL, coalesce_fraction_as_needed = NULL, cluster_distance = NULL, cluster_maxzoom = NULL, simplification = NULL, no_line_simplification = NULL, simplify_only_low_zooms = NULL, no_tiny_polygon_reduction = NULL, detect_shared_borders = NULL, no_simplification_of_shared_nodes = NULL, preserve_input_order = NULL, reorder = NULL, hilbert = NULL, maximum_tile_bytes = NULL, maximum_tile_features = NULL, no_feature_limit = NULL, no_tile_size_limit = NULL, generate_ids = NULL, calculate_feature_density = NULL, read_parallel = NULL, buffer = NULL, other_options = NULL )
input |
An sf object, or path to a GeoJSON, FlatGeobuf, or CSV file |
layer_name |
Name for this layer in the tileset (required) |
min_zoom |
Minimum zoom level (tippecanoe -Z) |
max_zoom |
Maximum zoom level (tippecanoe -z) |
guess_maxzoom |
If TRUE, guess appropriate maxzoom based on feature density (tippecanoe -zg) |
smallest_maximum_zoom_guess |
Use specified zoom if lower maxzoom is guessed (tippecanoe –smallest-maximum-zoom-guess) |
base_zoom |
Zoom at and above which all points are included (tippecanoe -B). If NULL, defaults to maxzoom. |
extend_zooms_if_still_dropping |
Increase maxzoom if features still being dropped (tippecanoe -ae) |
full_detail |
Detail at max zoom (default 12, for 4096 tile resolution, tippecanoe -d) |
low_detail |
Detail at lower zooms (default 12, tippecanoe -D) |
minimum_detail |
Minimum detail if tiles too big (default 7, tippecanoe -m) |
extra_detail |
Generate tiles with extra detail for precision (tippecanoe –extra-detail) |
exclude |
Character vector of attribute names to exclude (tippecanoe -x) |
include |
Character vector of attribute names to include, excluding all others (tippecanoe -y) |
exclude_all |
If TRUE, exclude all attributes and encode only geometries (tippecanoe -X) |
drop_rate |
Rate at which features dropped at zoom levels below basezoom (tippecanoe -r). Use "g" for auto-guess. |
drop_densest_as_needed |
Reduce feature spacing if tile too large (tippecanoe -as) |
drop_fraction_as_needed |
Drop fraction of features to keep under size limit (tippecanoe -ad) |
drop_smallest_as_needed |
Drop smallest features to keep under size limit (tippecanoe -an) |
drop_lines |
Apply dot-dropping to lines (tippecanoe -al) |
drop_polygons |
Apply dot-dropping to polygons (tippecanoe -ap) |
coalesce |
Coalesce consecutive features with same attributes (tippecanoe -ac) |
coalesce_smallest_as_needed |
Combine smallest features into nearby ones (tippecanoe -aN) |
coalesce_densest_as_needed |
Combine densest features into nearby ones (tippecanoe -aD) |
coalesce_fraction_as_needed |
Combine fraction of features into nearby ones (tippecanoe -aS) |
cluster_distance |
Cluster points within distance of each other (tippecanoe -K, max 255) |
cluster_maxzoom |
Max zoom for clustering (tippecanoe -k). Use "g" to set to maxzoom - 1. |
simplification |
Multiply tolerance for line/polygon simplification (tippecanoe -S) |
no_line_simplification |
Don't simplify lines and polygons (tippecanoe -ps) |
simplify_only_low_zooms |
Don't simplify at maxzoom (tippecanoe -pS) |
no_tiny_polygon_reduction |
Don't combine tiny polygons into squares (tippecanoe -pt) |
detect_shared_borders |
Detect and simplify shared polygon borders identically (tippecanoe -ab) |
no_simplification_of_shared_nodes |
Don't simplify nodes where lines converge/diverge (tippecanoe -pn) |
preserve_input_order |
Preserve original input order instead of geographic order (tippecanoe -pi) |
reorder |
Reorder features to put same attributes in sequence (tippecanoe -ao) |
hilbert |
Use Hilbert Curve order instead of Z-order (tippecanoe -ah) |
maximum_tile_bytes |
Maximum compressed tile size in bytes (tippecanoe -M) |
maximum_tile_features |
Maximum features per tile (tippecanoe -O) |
no_feature_limit |
Don't limit tiles to 200,000 features (tippecanoe -pf) |
no_tile_size_limit |
Don't limit tiles to 500K bytes (tippecanoe -pk) |
generate_ids |
Add feature IDs to features without them (tippecanoe -ai) |
calculate_feature_density |
Add tippecanoe_feature_density attribute (tippecanoe -ag) |
read_parallel |
Use multiple threads for line-delimited GeoJSON (tippecanoe -P) |
buffer |
Buffer size in screen pixels (tippecanoe -b) |
other_options |
Character vector of additional tippecanoe options not covered by other parameters. Example: c("–coalesce") |
A list with class "pm_layer" containing the input and all
specified options.
## Not run: library(sf) # Create a multi-layer PMTiles with per-layer options pm_create( input = list( pm_layer( input = counties_sf, layer_name = "counties", min_zoom = 2, max_zoom = 8 ), pm_layer( input = tracts_sf, layer_name = "tracts", min_zoom = 8, max_zoom = 14, drop_densest_as_needed = TRUE ) ), output = "census.pmtiles", generate_ids = TRUE ) ## End(Not run)## Not run: library(sf) # Create a multi-layer PMTiles with per-layer options pm_create( input = list( pm_layer( input = counties_sf, layer_name = "counties", min_zoom = 2, max_zoom = 8 ), pm_layer( input = tracts_sf, layer_name = "tracts", min_zoom = 8, max_zoom = 14, drop_densest_as_needed = TRUE ) ), output = "census.pmtiles", generate_ids = TRUE ) ## End(Not run)
Combine two or more disjoint PMTiles archives into a single archive. Archives are disjoint when no tile coordinate appears in more than one input – for example, tilesets covering non-overlapping geographic regions at the same zoom levels, or the same region at non-overlapping zoom ranges.
pm_merge(inputs, output, verbose = TRUE)pm_merge(inputs, output, verbose = TRUE)
inputs |
Character vector of paths to two or more local PMTiles archives to merge. |
output |
Path for the merged output archive. |
verbose |
Logical. If |
Merging is performed by the go-pmtiles CLI (pmtiles merge). The input
archives must be disjoint; merging archives that contain the same tile
coordinates is an error. All inputs must also share the same tile type
and tile compression.
The merged archive's JSON metadata and center are copied from the
first input only. In particular, vector_layers metadata comes from
the first archive – so inputs should use the same layer name(s), or
layers present only in later inputs will be missing from the merged
metadata even though their tiles are included. To recombine tilesets
with differing layers, re-create the archive from source data instead
(see pm_create(), which supports multi-layer output via pm_layer()).
Invisibly returns the path to the output archive.
pm_create(), pm_extract(), pm_convert()
## Not run: # Merge two regional tilesets into one archive pm_merge( c("west_region.pmtiles", "east_region.pmtiles"), output = "combined.pmtiles" ) ## End(Not run)## Not run: # Merge two regional tilesets into one archive pm_merge( c("west_region.pmtiles", "east_region.pmtiles"), output = "combined.pmtiles" ) ## End(Not run)
Start a local HTTP server to serve PMTiles files with CORS headers enabled.
This allows PMTiles to be consumed by web maps (like mapgl) using the
PMTiles.js client library. The server runs in the background and can be
stopped with pm_stop_server().
pm_serve(path, port = 8080, background = TRUE)pm_serve(path, port = 8080, background = TRUE)
path |
Path to a directory containing PMTiles files, or a single PMTiles file. If a single file, its directory will be served. |
port |
Port number for the HTTP server. Default is 8080. |
background |
Logical. If |
This function serves the raw PMTiles files with CORS headers, allowing
them to be consumed by PMTiles.js in the browser. This works with mapgl's
PMTiles protocol and pm_view() for quick visualization.
For a file at tiles/data.pmtiles, it will be available at:
http://localhost:PORT/data.pmtiles
File size: Works well for files up to ~1GB. For larger files, consider
pm_serve_zxy() or serving from a Node.js server like http-server.
The server uses httpuv with custom CORS headers and HTTP range request support.
When background = TRUE, the server runs as a background daemon.
If background = TRUE, returns a list with:
url: Base URL of the server
port: Port number
dir: Directory being served
daemon: Server daemon ID (for stopping)
If background = FALSE, blocks until interrupted and returns nothing.
## Not run: # Serve a single PMTiles file server <- pm_serve("data.pmtiles", port = 8080) # File available at: http://localhost:8080/data.pmtiles # Use in mapgl mapgl::add_pmtiles_source(url = paste0(server$url, "/data.pmtiles")) # Serve a directory of PMTiles files server <- pm_serve("tiles/", port = 8080) # Stop the server when done pm_stop_server(server) # Or run in foreground (blocks) pm_serve("data.pmtiles", background = FALSE) ## End(Not run)## Not run: # Serve a single PMTiles file server <- pm_serve("data.pmtiles", port = 8080) # File available at: http://localhost:8080/data.pmtiles # Use in mapgl mapgl::add_pmtiles_source(url = paste0(server$url, "/data.pmtiles")) # Serve a directory of PMTiles files server <- pm_serve("tiles/", port = 8080) # Stop the server when done pm_stop_server(server) # Or run in foreground (blocks) pm_serve("data.pmtiles", background = FALSE) ## End(Not run)
Start a local tile server that serves PMTiles archives as standard Z/X/Y tile
endpoints (e.g., /\{tileset\}/\{z\}/\{x\}/\{y\}.mvt). This uses the native
pmtiles serve command and works with any map client, not just PMTiles.js.
Unlike pm_serve() which serves raw .pmtiles files for direct consumption by
PMTiles.js, this function extracts individual tiles on-demand, making the tiles
accessible to any mapping library that supports standard tile URLs.
pm_serve_zxy( path = ".", bucket = NULL, port = 8080, cors = "*", cache_size = 64, public_url = NULL, background = FALSE )pm_serve_zxy( path = ".", bucket = NULL, port = 8080, cors = "*", cache_size = 64, public_url = NULL, background = FALSE )
path |
Directory containing PMTiles files, or a specific path prefix.
Default is current directory ( |
bucket |
Optional cloud storage bucket specification: a helper object
from |
port |
Port number for the tile server. Default is 8080. |
cors |
CORS origins to allow. Can be |
cache_size |
Cache size in megabytes. Default is 64 MB. |
public_url |
Public-facing URL for TileJSON generation (e.g.,
|
background |
Logical. If |
If background = FALSE, blocks until server is stopped (Ctrl+C).
If background = TRUE, invisibly returns the processx::process object.
The server provides these endpoints:
Tiles: http://localhost:PORT/TILESET/\{z\}/\{x\}/\{y\}.ext
Extension (.mvt, .png, .jpg, etc.) is auto-detected from PMTiles metadata
TileJSON: http://localhost:PORT/TILESET.json (requires public_url)
Returns TileJSON metadata for the tileset
This approach works with any map client and is particularly useful for:
Large PMTiles files (multi-GB)
Serving directly from cloud storage
Clients that don't support the PMTiles protocol
You can serve tiles directly from cloud storage without downloading:
Cloudflare R2:
pm_serve_zxy( bucket = "s3://my-bucket?endpoint=https://account.r2.cloudflarestorage.com®ion=auto" )
AWS S3:
pm_serve_zxy(bucket = "s3://my-bucket")
Requires appropriate environment variables for authentication
(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY).
When background = TRUE, the server runs in a background process. Use
pm_stop_server() to stop background servers.
pm_serve(): Serves raw .pmtiles files for PMTiles.js (HTTP Range requests)
pm_serve_zxy(): Serves individual Z/X/Y tiles for any map client
Use pm_serve_zxy() when you need standard tile URLs or want to serve from
cloud storage. Use pm_serve() for quick local preview with PMTiles.js.
## Not run: # Serve all PMTiles in current directory pm_serve_zxy() # Serve specific directory on custom port pm_serve_zxy(path = "~/pmtiles", port = 9000) # Serve from Cloudflare R2 pm_serve_zxy( bucket = "s3://my-bucket?endpoint=https://account.r2.cloudflarestorage.com®ion=auto", public_url = "https://tiles.example.com" ) # Run in background server <- pm_serve_zxy(background = TRUE) # ... do other work ... pm_stop_server(server) ## End(Not run)## Not run: # Serve all PMTiles in current directory pm_serve_zxy() # Serve specific directory on custom port pm_serve_zxy(path = "~/pmtiles", port = 9000) # Serve from Cloudflare R2 pm_serve_zxy( bucket = "s3://my-bucket?endpoint=https://account.r2.cloudflarestorage.com®ion=auto", public_url = "https://tiles.example.com" ) # Run in background server <- pm_serve_zxy(background = TRUE) # ... do other work ... pm_stop_server(server) ## End(Not run)
Inspect a local or remote PMTiles archive and display header information and metadata.
pm_show( input, bucket = NULL, metadata = FALSE, header_json = FALSE, tilejson = FALSE, public_url = NULL )pm_show( input, bucket = NULL, metadata = FALSE, header_json = FALSE, tilejson = FALSE, public_url = NULL )
input |
Path to a local PMTiles file or URL to a remote archive. Remote archives can be HTTP URLs or cloud storage paths. |
bucket |
Optional remote bucket specification for cloud storage:
a helper object from |
metadata |
Logical. If |
header_json |
Logical. If |
tilejson |
Logical. If |
public_url |
Character. Public base URL for TileJSON
(e.g., "https://example.com/tiles"). Only used when |
If metadata = TRUE or header_json = TRUE or tilejson = TRUE:
Returns a parsed list from the JSON output
Otherwise: Returns invisible NULL and prints archive information
PMTiles supports reading from cloud storage buckets. The easiest way to specify one is with a bucket helper (see bucket_helpers):
Cloudflare R2: bucket = r2_bucket("my-tiles", account_id = "...")
S3: bucket = s3_bucket("my-tiles", region = "us-east-1")
Azure: bucket = azure_bucket("container", storage_account = "...")
Google Cloud: bucket = gcs_bucket("my-tiles")
Raw URL strings such as "s3://BUCKET?endpoint=https://example.com®ion=auto"
are also accepted. Authentication uses credentials supplied to the bucket
helper, or standard cloud provider environment variables
(e.g., AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY for S3).
## Not run: # Show local archive info pm_show("path/to/archive.pmtiles") # Get metadata as list metadata <- pm_show("archive.pmtiles", metadata = TRUE) # Show remote archive on Cloudflare R2 pm_show( "archive.pmtiles", bucket = r2_bucket("my-bucket", account_id = "your-account-id") ) # Get TileJSON tilejson <- pm_show( "archive.pmtiles", tilejson = TRUE, public_url = "https://example.com/tiles" ) ## End(Not run)## Not run: # Show local archive info pm_show("path/to/archive.pmtiles") # Get metadata as list metadata <- pm_show("archive.pmtiles", metadata = TRUE) # Show remote archive on Cloudflare R2 pm_show( "archive.pmtiles", bucket = r2_bucket("my-bucket", account_id = "your-account-id") ) # Get TileJSON tilejson <- pm_show( "archive.pmtiles", tilejson = TRUE, public_url = "https://example.com/tiles" ) ## End(Not run)
Stop a PMTiles server that was started with pm_serve() or pm_serve_zxy().
pm_stop_server(server = NULL)pm_stop_server(server = NULL)
server |
A server object returned by |
Invisibly returns TRUE if server was stopped, FALSE otherwise.
## Not run: # Start servers server1 <- pm_serve("data.pmtiles") server2 <- pm_serve_zxy(background = TRUE) # Stop specific server pm_stop_server(server1) # Or stop by port pm_stop_server(8080) # Or stop all servers pm_stop_server() ## End(Not run)## Not run: # Start servers server1 <- pm_serve("data.pmtiles") server2 <- pm_serve_zxy(background = TRUE) # Stop specific server pm_stop_server(server1) # Or stop by port pm_stop_server(8080) # Or stop all servers pm_stop_server() ## End(Not run)
Fetch one tile from a local or remote PMTiles archive and save it to a file.
pm_tile(input, z, x, y, output = NULL, bucket = NULL)pm_tile(input, z, x, y, output = NULL, bucket = NULL)
input |
Path to a local PMTiles file or URL to a remote archive. |
z |
Integer zoom level. |
x |
Integer tile column. |
y |
Integer tile row. |
output |
Path where the tile should be saved. If |
bucket |
Optional remote bucket specification for cloud storage:
a helper object from |
If output is specified, writes tile to file and returns the output path invisibly.
If output is NULL, returns the tile data as a raw vector.
## Not run: # Get tile data tile_data <- pm_tile("archive.pmtiles", z = 0, x = 0, y = 0) # Save tile to file pm_tile("archive.pmtiles", z = 5, x = 10, y = 12, output = "tile.mvt") ## End(Not run)## Not run: # Get tile data tile_data <- pm_tile("archive.pmtiles", z = 0, x = 0, y = 0) # Save tile to file pm_tile("archive.pmtiles", z = 5, x = 10, y = 12, output = "tile.mvt") ## End(Not run)
Upload a local PMTiles archive to cloud storage (S3, Cloudflare R2, Google
Cloud Storage, Azure, or any S3-compatible service). The easiest way to
specify the destination is with a bucket helper – see r2_bucket() and
friends – which builds the bucket URL and can carry credentials for you.
pm_upload(input, remote, bucket, max_concurrency = 2, verbose = TRUE)pm_upload(input, remote, bucket, max_concurrency = 2, verbose = TRUE)
input |
Path to local PMTiles file to upload. |
remote |
Name for the PMTiles file in cloud storage. |
bucket |
Destination bucket: either a helper object from
|
max_concurrency |
Maximum number of parallel upload threads. Default is 2. |
verbose |
Logical. If |
Invisibly returns TRUE on success.
The bucket helpers handle each provider's URL format and authentication details (see bucket_helpers for provider-by-provider setup guides):
# Cloudflare R2
bucket = r2_bucket("my-tiles", account_id = "your-account-id")
# Amazon S3
bucket = s3_bucket("my-tiles", region = "us-east-1")
# Google Cloud Storage
bucket = gcs_bucket("my-tiles")
# Azure Blob Storage
bucket = azure_bucket("my-container", storage_account = "myaccount")
A raw URL string is also accepted, e.g.
"s3://bucket?endpoint=https://account.r2.cloudflarestorage.com®ion=auto".
Credentials can be supplied directly to the bucket helpers (passed only to the pmtiles subprocess), or via the provider's standard environment variables:
S3 / R2 / S3-compatible: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY
Google Cloud Storage: Application Default Credentials or
GOOGLE_APPLICATION_CREDENTIALS
Azure: AZURE_STORAGE_ACCOUNT plus AZURE_STORAGE_KEY or
AZURE_STORAGE_SAS_TOKEN
## Not run: # Upload to Cloudflare R2, with credentials stored in ~/.Renviron pm_upload( "local.pmtiles", "remote.pmtiles", bucket = r2_bucket( "my-tiles", account_id = "your-cloudflare-account-id", access_key = Sys.getenv("R2_ACCESS_KEY_ID"), secret_key = Sys.getenv("R2_SECRET_ACCESS_KEY") ) ) # Upload to S3 using the standard AWS credential chain pm_upload( "local.pmtiles", "remote.pmtiles", bucket = s3_bucket("my-bucket", region = "us-east-1") ) ## End(Not run)## Not run: # Upload to Cloudflare R2, with credentials stored in ~/.Renviron pm_upload( "local.pmtiles", "remote.pmtiles", bucket = r2_bucket( "my-tiles", account_id = "your-cloudflare-account-id", access_key = Sys.getenv("R2_ACCESS_KEY_ID"), secret_key = Sys.getenv("R2_SECRET_ACCESS_KEY") ) ) # Upload to S3 using the standard AWS credential chain pm_upload( "local.pmtiles", "remote.pmtiles", bucket = s3_bucket("my-bucket", region = "us-east-1") ) ## End(Not run)
Check that a PMTiles archive is ordered correctly and has correct header information. This verifies the archive structure without checking individual tile contents.
pm_verify(input)pm_verify(input)
input |
Path to a local PMTiles file. |
Invisibly returns TRUE if verification succeeds, throws an error otherwise.
## Not run: # Verify an archive pm_verify("archive.pmtiles") ## End(Not run)## Not run: # Verify an archive pm_verify("archive.pmtiles") ## End(Not run)
Display the version information of the PMTiles command-line tool.
pm_version()pm_version()
Character string containing version information.
## Not run: pm_version() ## End(Not run)## Not run: pm_version() ## End(Not run)
Quickly visualize a PMTiles archive or TileJSON endpoint on an interactive map using mapgl. Automatically detects the tile type and applies appropriate styling. For local files, automatically starts a background server.
pm_view( input, source_layer = NULL, style = NULL, port = 8080, layer_type = c("auto", "fill", "line", "circle"), fill_color = "#088", fill_opacity = 0.5, line_color = "#088", line_width = 1, circle_color = "#088", circle_radius = 5, inspect_features = FALSE, highlight = FALSE, promote_id = NULL, ... )pm_view( input, source_layer = NULL, style = NULL, port = 8080, layer_type = c("auto", "fill", "line", "circle"), fill_color = "#088", fill_opacity = 0.5, line_color = "#088", line_width = 1, circle_color = "#088", circle_radius = 5, inspect_features = FALSE, highlight = FALSE, promote_id = NULL, ... )
input |
Path to a local PMTiles file, URL to a remote archive, or TileJSON endpoint URL. |
source_layer |
Name of the source layer to display. If |
style |
Base map style. Can be a mapgl style function like
|
port |
Port for local server (only used for local files). Default is 8080. |
layer_type |
Type of layer to add: |
fill_color |
Fill color for polygons. Default is |
fill_opacity |
Fill opacity. Default is 0.5. |
line_color |
Line color. Default is |
line_width |
Line width. Default is 1. |
circle_color |
Circle color for points. Default is |
circle_radius |
Circle radius for points. Default is 5. |
inspect_features |
Logical. If |
highlight |
Logical. If |
promote_id |
Optional. Column name to promote as the feature ID for hover
highlighting. Only used when |
... |
Additional arguments passed to the layer function. |
A mapgl map object.
Local files: If input is a local file path, pm_view() automatically:
Starts a background PMTiles server via pm_serve()
Extracts metadata to determine source layer and geometry type
Creates an appropriate map visualization
The server runs in the background and will be automatically stopped when the
R session ends. You can manually stop it with pm_stop_server().
Remote files: If input is a URL (starts with http:// or https://),
uses the URL directly without starting a local server.
TileJSON endpoints: If input ends with .json, it's treated as a TileJSON
endpoint. The function fetches the TileJSON metadata and uses add_vector_source()
to display the tiles.
When layer_type = "auto", the function inspects the metadata to determine
the geometry type and applies appropriate styling:
Polygon/MultiPolygon → fill layer
LineString/MultiLineString → line layer
Point/MultiPoint → circle layer
Set inspect_features = TRUE to show tooltips with feature attributes on hover.
This works for any tileset.
Set highlight = TRUE to enable hover highlighting effects (features change
color/style when hovered). Important: This requires the tileset to have an
ID property configured. You can either:
Configure IDs during tile generation (recommended)
Use promote_id = "column_name" to promote an existing attribute as the ID
If the tileset lacks proper IDs, highlighting will not work even if enabled.
## Not run: # View a local PMTiles file pm_view("data.pmtiles") # Customize the display pm_view("data.pmtiles", fill_color = "#ff0000", fill_opacity = 0.7) # View remote PMTiles pm_view("https://example.com/tiles.pmtiles") # View TileJSON endpoint pm_view("http://localhost:8080/tiles.json") # Use specific source layer pm_view("data.pmtiles", source_layer = "buildings") # Enable feature inspection with tooltips pm_view("data.pmtiles", inspect_features = TRUE) # Enable hover highlighting (requires ID property in tileset) pm_view("data.pmtiles", inspect_features = TRUE, highlight = TRUE, promote_id = "id") # Further customize with mapgl pm_view("data.pmtiles") |> mapgl::fit_bounds(c(-122.5, 37.7, -122.3, 37.9)) ## End(Not run)## Not run: # View a local PMTiles file pm_view("data.pmtiles") # Customize the display pm_view("data.pmtiles", fill_color = "#ff0000", fill_opacity = 0.7) # View remote PMTiles pm_view("https://example.com/tiles.pmtiles") # View TileJSON endpoint pm_view("http://localhost:8080/tiles.json") # Use specific source layer pm_view("data.pmtiles", source_layer = "buildings") # Enable feature inspection with tooltips pm_view("data.pmtiles", inspect_features = TRUE) # Enable hover highlighting (requires ID property in tileset) pm_view("data.pmtiles", inspect_features = TRUE, highlight = TRUE, promote_id = "id") # Further customize with mapgl pm_view("data.pmtiles") |> mapgl::fit_bounds(c(-122.5, 37.7, -122.3, 37.9)) ## End(Not run)