init
This commit is contained in:
commit
116abafc09
58 changed files with 5749 additions and 0 deletions
327
vignettes/labels-and-filters.Rmd
Normal file
327
vignettes/labels-and-filters.Rmd
Normal file
|
|
@ -0,0 +1,327 @@
|
|||
---
|
||||
title: "Labels, Filters, and Feature Selection"
|
||||
output: rmarkdown::html_vignette
|
||||
vignette: >
|
||||
%\VignetteIndexEntry{Labels, Filters, and Feature Selection}
|
||||
%\VignetteEngine{knitr::rmarkdown}
|
||||
%\VignetteEncoding{UTF-8}
|
||||
---
|
||||
|
||||
```{r, include = FALSE}
|
||||
knitr::opts_chunk$set(
|
||||
collapse = TRUE,
|
||||
comment = "#>",
|
||||
eval = FALSE
|
||||
)
|
||||
```
|
||||
|
||||
*Note: Code examples are not evaluated in this vignette. Copy and run them in your R console to see the interactive maps.*
|
||||
|
||||
## Introduction
|
||||
|
||||
Protomaps vector tiles contain rich metadata about each feature. This vignette shows how to use filters to selectively style and label features based on their properties.
|
||||
|
||||
## Understanding Feature Properties
|
||||
|
||||
Each feature in the vector tiles has a `props` object with metadata. Common properties include:
|
||||
|
||||
| Layer | Property | Values |
|
||||
|-------|----------|--------|
|
||||
| places | `kind` | "country", "region", "locality" |
|
||||
| places | `min_zoom` | 1-15 (lower = more important) |
|
||||
| roads | `kind` | "highway", "major_road", "minor_road", "path" |
|
||||
| water | `kind` | "ocean", "lake", "river" |
|
||||
| landuse | `kind` | "park", "forest", "residential", "industrial" |
|
||||
|
||||
## Hierarchical City Labels
|
||||
|
||||
Style cities by importance using `min_zoom`:
|
||||
|
||||
```{r}
|
||||
library(leaflet)
|
||||
library(protomapr)
|
||||
|
||||
leaflet() %>%
|
||||
setView(lng = -100, lat = 40, zoom = 5) %>%
|
||||
addProtomaps(
|
||||
url = protomaps_url(),
|
||||
flavor = "light",
|
||||
labelRules = list(
|
||||
# Capital cities and major metros (min_zoom 1-3)
|
||||
pmLabelRule("places", pmCenteredTextSymbolizer(
|
||||
font = "700 16px sans-serif",
|
||||
fill = "#1a1a1a",
|
||||
stroke = "white",
|
||||
width = 3
|
||||
), filter = "feature.props.kind === 'locality' && feature.props.min_zoom <= 3"),
|
||||
|
||||
# Large cities (min_zoom 4-5)
|
||||
pmLabelRule("places", pmCenteredTextSymbolizer(
|
||||
font = "600 13px sans-serif",
|
||||
fill = "#333333",
|
||||
stroke = "white",
|
||||
width = 2
|
||||
), filter = "feature.props.kind === 'locality' && feature.props.min_zoom > 3 && feature.props.min_zoom <= 5"),
|
||||
|
||||
# Medium cities (min_zoom 6-7)
|
||||
pmLabelRule("places", pmCenteredTextSymbolizer(
|
||||
font = "500 11px sans-serif",
|
||||
fill = "#555555",
|
||||
stroke = "white",
|
||||
width = 2
|
||||
), filter = "feature.props.kind === 'locality' && feature.props.min_zoom > 5 && feature.props.min_zoom <= 7"),
|
||||
|
||||
# States/provinces
|
||||
pmLabelRule("places", pmCenteredTextSymbolizer(
|
||||
font = "italic 300 14px sans-serif",
|
||||
fill = "#888888",
|
||||
stroke = "white",
|
||||
width = 1
|
||||
), filter = "feature.props.kind === 'region'")
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
## Road Hierarchy Styling
|
||||
|
||||
Style different road types with distinct colors and widths:
|
||||
|
||||
```{r}
|
||||
leaflet() %>%
|
||||
setView(lng = -122.4, lat = 37.78, zoom = 13) %>%
|
||||
addProtomaps(
|
||||
url = protomaps_url(),
|
||||
paintRules = list(
|
||||
# Base layers
|
||||
pmPaintRule("earth", pmPolygonSymbolizer(fill = "#f5f5f5")),
|
||||
pmPaintRule("water", pmPolygonSymbolizer(fill = "#cce0eb")),
|
||||
pmPaintRule("landuse", pmPolygonSymbolizer(fill = "#e8f0e8"),
|
||||
filter = "feature.props.kind === 'park'"),
|
||||
|
||||
# Highways - orange, thick
|
||||
pmPaintRule("roads", pmLineSymbolizer(color = "#f59e0b", width = 4),
|
||||
filter = "feature.props.kind === 'highway'"),
|
||||
|
||||
# Major roads - dark gray, medium
|
||||
pmPaintRule("roads", pmLineSymbolizer(color = "#6b7280", width = 2.5),
|
||||
filter = "feature.props.kind === 'major_road'"),
|
||||
|
||||
# Minor roads - light gray, thin
|
||||
pmPaintRule("roads", pmLineSymbolizer(color = "#9ca3af", width = 1.5),
|
||||
filter = "feature.props.kind === 'minor_road'"),
|
||||
|
||||
# Paths - dashed
|
||||
pmPaintRule("roads", pmLineSymbolizer(color = "#d1d5db", width = 1, dash = c(3, 2)),
|
||||
filter = "feature.props.kind === 'path'")
|
||||
),
|
||||
labelRules = list(
|
||||
pmLabelRule("roads", pmLineLabelSymbolizer(
|
||||
font = "600 10px sans-serif",
|
||||
fill = "#f59e0b",
|
||||
stroke = "white",
|
||||
width = 2
|
||||
), filter = "feature.props.kind === 'highway'", minzoom = 12),
|
||||
|
||||
pmLabelRule("roads", pmLineLabelSymbolizer(
|
||||
font = "500 9px sans-serif",
|
||||
fill = "#4b5563",
|
||||
stroke = "white",
|
||||
width = 2
|
||||
), filter = "feature.props.kind === 'major_road'", minzoom = 14)
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
## Water Feature Labels
|
||||
|
||||
Style different water bodies appropriately:
|
||||
|
||||
```{r}
|
||||
leaflet() %>%
|
||||
setView(lng = -122.4, lat = 37.8, zoom = 10) %>%
|
||||
addProtomaps(
|
||||
url = protomaps_url(),
|
||||
colors = pmColors(
|
||||
earth = "#f0f0f0",
|
||||
water = "#1e40af"
|
||||
),
|
||||
labelRules = list(
|
||||
# Ocean labels - large, bold
|
||||
pmLabelRule("water", pmCenteredTextSymbolizer(
|
||||
font = "italic 700 18px sans-serif",
|
||||
fill = "#1e3a5f",
|
||||
stroke = "#e0f0ff",
|
||||
width = 2,
|
||||
lineHeight = 1.5
|
||||
), filter = "feature.props.kind === 'ocean'"),
|
||||
|
||||
# Bay/gulf labels
|
||||
pmLabelRule("water", pmCenteredTextSymbolizer(
|
||||
font = "italic 500 14px sans-serif",
|
||||
fill = "#1e4070",
|
||||
stroke = "#e0f0ff",
|
||||
width = 2,
|
||||
lineHeight = 1.5
|
||||
), filter = "feature.props.kind === 'bay' || feature.props.kind === 'gulf'"),
|
||||
|
||||
# Lakes
|
||||
pmLabelRule("water", pmCenteredTextSymbolizer(
|
||||
font = "italic 11px sans-serif",
|
||||
fill = "#2050a0",
|
||||
stroke = "#e0f0ff",
|
||||
width = 1,
|
||||
lineHeight = 1.5
|
||||
), filter = "feature.props.kind === 'lake' || feature.props.kind === 'water'")
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
## Zoom-Dependent Visibility
|
||||
|
||||
Show different features at different zoom levels:
|
||||
|
||||
```{r}
|
||||
leaflet() %>%
|
||||
setView(lng = -122.4, lat = 37.78, zoom = 14) %>%
|
||||
addProtomaps(
|
||||
url = protomaps_url(),
|
||||
paintRules = list(
|
||||
pmPaintRule("earth", pmPolygonSymbolizer(fill = "#f8f8f8")),
|
||||
pmPaintRule("water", pmPolygonSymbolizer(fill = "#d0e8f0")),
|
||||
pmPaintRule("landuse", pmPolygonSymbolizer(fill = "#e0f0e0")),
|
||||
|
||||
# Buildings only visible at zoom 14+
|
||||
pmPaintRule("buildings", pmPolygonSymbolizer(
|
||||
fill = "#e0e0e0",
|
||||
stroke = "#cccccc",
|
||||
width = 0.5
|
||||
), minzoom = 14),
|
||||
|
||||
# Roads
|
||||
pmPaintRule("roads", pmLineSymbolizer(color = "#888888", width = 2))
|
||||
),
|
||||
labelRules = list(
|
||||
# Neighborhoods at medium zoom
|
||||
pmLabelRule("places", pmCenteredTextSymbolizer(
|
||||
font = "600 12px sans-serif",
|
||||
fill = "#444444",
|
||||
stroke = "white",
|
||||
width = 2
|
||||
), filter = "feature.props.kind === 'neighbourhood'", minzoom = 13, maxzoom = 16),
|
||||
|
||||
# Street names at high zoom only
|
||||
pmLabelRule("roads", pmLineLabelSymbolizer(
|
||||
font = "500 9px sans-serif",
|
||||
fill = "#666666",
|
||||
stroke = "white",
|
||||
width = 2
|
||||
), minzoom = 15)
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
## POI (Points of Interest) Styling
|
||||
|
||||
Show specific categories of points of interest:
|
||||
|
||||
```{r}
|
||||
leaflet() %>%
|
||||
setView(lng = -122.4, lat = 37.78, zoom = 15) %>%
|
||||
addProtomaps(
|
||||
url = protomaps_url(),
|
||||
flavor = "light",
|
||||
paintRules = list(
|
||||
# Restaurants
|
||||
pmPaintRule("pois", pmCircleSymbolizer(
|
||||
radius = 5,
|
||||
fill = "#ef4444",
|
||||
stroke = "white",
|
||||
width = 1
|
||||
), filter = "feature.props.kind === 'restaurant'"),
|
||||
|
||||
# Cafes
|
||||
pmPaintRule("pois", pmCircleSymbolizer(
|
||||
radius = 5,
|
||||
fill = "#8b5cf6",
|
||||
stroke = "white",
|
||||
width = 1
|
||||
), filter = "feature.props.kind === 'cafe'"),
|
||||
|
||||
# Parks
|
||||
pmPaintRule("pois", pmCircleSymbolizer(
|
||||
radius = 6,
|
||||
fill = "#22c55e",
|
||||
stroke = "white",
|
||||
width = 1
|
||||
), filter = "feature.props.kind === 'park'")
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
## Combining Multiple Filters
|
||||
|
||||
Use logical operators for complex filtering:
|
||||
|
||||
```{r}
|
||||
leaflet() %>%
|
||||
setView(lng = -122.4, lat = 37.78, zoom = 12) %>%
|
||||
addProtomaps(
|
||||
url = protomaps_url(),
|
||||
colors = pmColors(earth = "#f5f5f5", water = "#ddeeff"),
|
||||
labelRules = list(
|
||||
# Large cities in California (using bounding box approximation)
|
||||
pmLabelRule("places", pmCenteredTextSymbolizer(
|
||||
font = "600 14px sans-serif",
|
||||
fill = "#1a1a1a",
|
||||
stroke = "white",
|
||||
width = 2
|
||||
), filter = "feature.props.kind === 'locality' && feature.props.min_zoom <= 6"),
|
||||
|
||||
# Exclude small water features
|
||||
pmLabelRule("water", pmCenteredTextSymbolizer(
|
||||
font = "italic 11px sans-serif",
|
||||
fill = "#3366aa",
|
||||
stroke = "#ddeeff",
|
||||
width = 1,
|
||||
lineHeight = 1.5
|
||||
), filter = "feature.props.kind !== 'stream' && feature.props.kind !== 'river'")
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
## Filter Expression Reference
|
||||
|
||||
Filters are JavaScript expressions with access to `zoom` and `feature`:
|
||||
|
||||
```javascript
|
||||
// Equality
|
||||
feature.props.kind === 'highway'
|
||||
|
||||
// Inequality
|
||||
feature.props.min_zoom <= 5
|
||||
|
||||
// Logical AND
|
||||
feature.props.kind === 'locality' && feature.props.min_zoom <= 4
|
||||
|
||||
// Logical OR
|
||||
feature.props.kind === 'lake' || feature.props.kind === 'reservoir'
|
||||
|
||||
// NOT
|
||||
feature.props.kind !== 'path'
|
||||
|
||||
// Zoom-based (though minzoom/maxzoom params are preferred)
|
||||
zoom >= 12 && feature.props.kind === 'minor_road'
|
||||
|
||||
// Check if property exists
|
||||
feature.props.name !== undefined
|
||||
```
|
||||
|
||||
## Tips
|
||||
|
||||
1. **Use minzoom/maxzoom params** instead of zoom filters when possible - they're more efficient
|
||||
|
||||
2. **Order matters**: Rules are applied in order; later rules can override earlier ones
|
||||
|
||||
3. **Test with the built-in flavors first** to understand which features appear at which zooms
|
||||
|
||||
4. **Check the console**: Invalid filter expressions log errors to the browser console
|
||||
Loading…
Add table
Add a link
Reference in a new issue