# protomapr An R package to add [Protomaps](https://protomaps.com/) 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 ```r # Install from local source devtools::install_local("path/to/protomapr") # Or install dependencies and load install.packages(c("leaflet", "htmltools", "htmlwidgets", "jsonlite")) ``` ## Quick Start ```r 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: ```r 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/ ```r leaflet() %>% addProtomaps(url = "https://your-bucket.s3.amazonaws.com/tiles.pmtiles") ``` ### 3. Local file For local development, you can serve a PMTiles file locally: ```r # Serve with a local HTTP server, then: leaflet() %>% addProtomaps(url = "http://localhost:8080/tiles.pmtiles") ``` ## Basic Usage ```r 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: ```r # 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: ```r 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: ```r 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: ```r # 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: ```r pmPolygonSymbolizer( fill = "#cccccc", # Fill color stroke = "#333", # Outline color width = 1, # Outline width opacity = 0.8 # Fill opacity (0-1) ) ``` ### pmLineSymbolizer Style line features: ```r 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: ```r pmCircleSymbolizer( radius = 6, # Circle radius in pixels fill = "red", # Fill color stroke = "black", # Outline color width = 1 # Outline width ) ``` ### pmCenteredTextSymbolizer Add centered text labels: ```r 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): ```r pmLineLabelSymbolizer( font = "11px Arial", fill = "#333", stroke = "white", width = 1 ) ``` ### pmShieldSymbolizer Add shield/badge labels (e.g., highway markers): ```r pmShieldSymbolizer( font = "10px Arial", fill = "black", background = "white", stroke = "black", padding = 2 ) ``` ## Additional Options ```r 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](https://github.com/protomaps/protomaps-leaflet), created by [Brandon Liu](https://bdon.org/). The Protomaps project provides an incredible open-source stack for self-hosted vector maps, including the [PMTiles](https://docs.protomaps.com/pmtiles/) single-file tile archive format. Thanks to Brandon for making beautiful, customizable maps accessible to everyone. ## Links - [Protomaps](https://protomaps.com/) - [protomaps-leaflet GitHub](https://github.com/protomaps/protomaps-leaflet) - [PMTiles specification](https://docs.protomaps.com/pmtiles/) - [Brandon Liu](https://bdon.org/)