| inst/htmlwidgets/lib/protomaps-leaflet-5.1.0 | ||
| man | ||
| R | ||
| tests | ||
| vignettes | ||
| _pkgdown.yml | ||
| cran-comments.md | ||
| DESCRIPTION | ||
| LICENSE | ||
| NAMESPACE | ||
| NEWS.md | ||
| protomapr.Rproj | ||
| README.md | ||
protomapr
An R package to add Protomaps vector tile layers to Leaflet maps.
Why Protomaps?
Standard Leaflet maps use addProviderTiles() to load raster tiles from services like OpenStreetMap or CartoDB. Protomaps offers a vector tile alternative with key advantages:
| Raster Tiles | Protomaps (Vector) | |
|---|---|---|
| Customization | Limited to provider styles | Full control over colors, labels, features |
| Self-hosting | Requires tile server | Single PMTiles file, no server needed |
| Feature control | Show everything or nothing | Hide roads, buildings, labels selectively |
| Privacy | Requests to third-party servers | Self-host for complete privacy |
| Rate limits | Often have API quotas | No limits when self-hosted |
| Zoom quality | Can pixelate | Smooth at any zoom level |
| File size | Large (pre-rendered images) | Smaller (compressed vectors) |
Use Protomaps when you need:
- Custom branded maps matching your color scheme
- Minimal basemaps for data visualization (hide distracting features)
- Offline or embedded applications
- Privacy-sensitive contexts
- High-traffic apps without API rate limits
Use providerTiles when:
- Default styling is fine
- You need satellite/aerial imagery
- Quick prototypes
Installation
# Install from local source
devtools::install_local("path/to/protomapr")
# Or install dependencies and load
install.packages(c("leaflet", "htmltools", "htmlwidgets", "jsonlite"))
Quick Start
library(leaflet)
library(protomapr)
# Use the demo URL (free Protomaps daily build)
leaflet() %>%
setView(lng = -122.4, lat = 37.8, zoom = 12) %>%
addProtomaps(url = protomaps_demo_url())
Data Sources
You have several options for PMTiles data:
1. Demo/Development (free)
Use protomaps_demo_url() which points to the Protomaps daily OpenStreetMap build:
leaflet() %>%
addProtomaps(url = protomaps_demo_url())
2. Self-hosted (recommended for production)
Download a PMTiles file and host it on cloud storage (S3, GCS, Cloudflare R2, etc.):
- Download daily builds: https://maps.protomaps.com/builds/
- Extract a region: https://slice.openstreetmap.us/
leaflet() %>%
addProtomaps(url = "https://your-bucket.s3.amazonaws.com/tiles.pmtiles")
3. Local file
For local development, you can serve a PMTiles file locally:
# Serve with a local HTTP server, then:
leaflet() %>%
addProtomaps(url = "http://localhost:8080/tiles.pmtiles")
Basic Usage
library(leaflet)
library(protomapr)
leaflet() %>%
setView(lng = -122.4, lat = 37.8, zoom = 12) %>%
addProtomaps(
url = protomaps_demo_url(),
flavor = "light"
)
Flavors
Five built-in flavors are available:
# Light flavor (default)
leaflet() %>%
addProtomaps(url = protomaps_demo_url(), flavor = "light")
# Dark flavor
leaflet() %>%
addProtomaps(url = protomaps_demo_url(), flavor = "dark")
# White flavor (for data visualization)
leaflet() %>%
addProtomaps(url = protomaps_demo_url(), flavor = "white")
# Grayscale flavor
leaflet() %>%
addProtomaps(url = protomaps_demo_url(), flavor = "grayscale")
# Black flavor
leaflet() %>%
addProtomaps(url = protomaps_demo_url(), flavor = "black")
Custom Styling
Paint Rules
Control how features are rendered using paint rules:
leaflet() %>%
setView(lng = -122.4, lat = 37.8, zoom = 12) %>%
addProtomaps(
url = protomaps_demo_url(),
paintRules = list(
pmPaintRule("water", pmPolygonSymbolizer(fill = "steelblue")),
pmPaintRule("earth", pmPolygonSymbolizer(fill = "#f0f0f0")),
pmPaintRule("roads", pmLineSymbolizer(color = "gray", width = 1)),
pmPaintRule("buildings", pmPolygonSymbolizer(
fill = "#d4d4d4",
stroke = "#999",
width = 0.5
))
)
)
Label Rules
Add text labels to features:
leaflet() %>%
setView(lng = -122.4, lat = 37.8, zoom = 14) %>%
addProtomaps(
url = protomaps_demo_url(),
labelRules = list(
pmLabelRule("places",
pmCenteredTextSymbolizer(
font = "14px Arial",
fill = "black",
stroke = "white",
width = 2
)
),
pmLabelRule("roads",
pmLineLabelSymbolizer(
font = "11px Arial",
fill = "#333"
),
minzoom = 14
)
)
)
Filtering Features
Use JavaScript filter expressions to style features based on their properties:
# Cities only (not towns/villages)
pmLabelRule("places", pmCenteredTextSymbolizer(font = "14px Arial", fill = "black"),
filter = "feature.props.kind_detail === 'city'")
# States/regions
pmLabelRule("places", pmCenteredTextSymbolizer(font = "18px Arial", fill = "#666"),
filter = "feature.props.kind === 'region'")
# Important places (low min_zoom = more important)
pmLabelRule("places", pmCenteredTextSymbolizer(font = "16px Arial", fill = "black"),
filter = "feature.props.min_zoom <= 6")
# Highways only
pmPaintRule("roads", pmLineSymbolizer(color = "orange", width = 3),
filter = "feature.props.kind === 'highway'")
# Show features at specific zoom levels
pmPaintRule("buildings", pmPolygonSymbolizer(fill = "#ccc"),
minzoom = 14, maxzoom = 18)
Layers and Properties
For full documentation run ?protomaps_layers in R. Quick reference:
Layer Names
| Layer | Description |
|---|---|
earth |
Land polygons |
water |
Water bodies |
landuse |
Parks, forests, residential, etc. |
roads |
Streets and highways |
buildings |
Building footprints |
places |
City/town/region labels |
pois |
Points of interest |
boundaries |
Administrative boundaries |
Key Properties for Filtering
places:
kind: "country", "region", "locality"kind_detail: "city", "town", "village", "state", "province"min_zoom: importance (lower = more important)population_rank: size (higher = larger)
water:
kind: "water", "lake", "ocean"kind_detail: "river", "lake", "reservoir", "stream"
roads:
kind: "highway", "major_road", "minor_road", "path"kind_detail: "motorway", "primary", "residential", "footway"
landuse:
kind: "park", "forest", "residential", "industrial"
Symbolizer Reference
pmPolygonSymbolizer
Style polygon features:
pmPolygonSymbolizer(
fill = "#cccccc", # Fill color
stroke = "#333", # Outline color
width = 1, # Outline width
opacity = 0.8 # Fill opacity (0-1)
)
pmLineSymbolizer
Style line features:
pmLineSymbolizer(
color = "#000000", # Line color
width = 2, # Line width in pixels
dash = c(4, 2), # Dash pattern (4px dash, 2px gap)
lineCap = "round", # "butt", "round", or "square"
lineJoin = "round", # "miter", "round", or "bevel"
opacity = 1 # Line opacity (0-1)
)
pmCircleSymbolizer
Style point features as circles:
pmCircleSymbolizer(
radius = 6, # Circle radius in pixels
fill = "red", # Fill color
stroke = "black", # Outline color
width = 1 # Outline width
)
pmCenteredTextSymbolizer
Add centered text labels:
pmCenteredTextSymbolizer(
font = "14px Arial", # CSS font specification
fill = "black", # Text color
stroke = "white", # Halo color
width = 2 # Halo width
)
pmLineLabelSymbolizer
Add labels along line features (e.g., street names):
pmLineLabelSymbolizer(
font = "11px Arial",
fill = "#333",
stroke = "white",
width = 1
)
pmShieldSymbolizer
Add shield/badge labels (e.g., highway markers):
pmShieldSymbolizer(
font = "10px Arial",
fill = "black",
background = "white",
stroke = "black",
padding = 2
)
Additional Options
leaflet() %>%
addProtomaps(
url = protomaps_demo_url(),
flavor = "light",
lang = "en", # Language for labels
attribution = "Protomaps", # Attribution text
options = protomapsOptions(
maxDataZoom = 14, # Max zoom for tile data
tileSize = 256, # Tile size in pixels
debug = FALSE # Debug mode
)
)
Acknowledgments
This package is a wrapper around protomaps-leaflet, created by Brandon Liu. The Protomaps project provides an incredible open-source stack for self-hosted vector maps, including the PMTiles single-file tile archive format. Thanks to Brandon for making beautiful, customizable maps accessible to everyone.