Skip to content

Instantly share code, notes, and snippets.

@arthurgailes
Created October 27, 2025 18:22
Show Gist options
  • Select an option

  • Save arthurgailes/2d80a11eb95cc550907c89d0533f73da to your computer and use it in GitHub Desktop.

Select an option

Save arthurgailes/2d80a11eb95cc550907c89d0533f73da to your computer and use it in GitHub Desktop.
rtileserver demo
# DuckDB Vector Tiles with rtileserver and mapgl
# This script demonstrates how to serve vector tiles from DuckDB using the rtileserver package
# Original demo: https://gist.github.com/walkerke/c90ab6b8f403169e615eabeb0339b15b
library(mapgl) # Requires dev version.
library(duckdb) # Requires DuckDB >= 1.4.0
library(sf)
library(duckspatial)
library(tigris)
library(rtileserver) # The magic happens here!
# 1. Setup DuckDB connection and load spatial extension
con <- dbConnect(duckdb::duckdb(), dbdir = "tiles.duckdb")
ddbs_install(con)
ddbs_load(con)
# 2. Load your spatial data into DuckDB
# Example: Load an sf object into DuckDB and transform to Web Mercator (EPSG:3857)
# All US block groups: 242,000 polygons
data <- block_groups(cb = TRUE)
# Transform to Web Mercator for tiling
data_mercator <- st_transform(data, 3857)
# Write to DuckDB using duckspatial
ddbs_write_vector(con, data_mercator, "features", overwrite = TRUE)
# Optional: Create a spatial index for better performance
dbExecute(con, "CREATE INDEX idx_geom ON features USING RTREE (geometry)")
# 3. Start the tile server with rtileserver - that's it!
# All the httpuv server setup, tile parsing, and SQL generation is handled for you
server <- start_tile_server(
con,
table_name = "features",
geometry_column = "geometry",
properties = c("GEOID", "NAME") # Only include the columns you need
)
# Print server info
print(server)
# 4. Create the mapgl map with the DuckDB vector tile source
m <- maplibre(
center = c(-79.5, 35.5),
zoom = 6,
style = carto_style("positron")
) |>
add_vector_source(
id = "duckdb-tiles",
tiles = server$url, # Use the server URL from rtileserver
minzoom = 0,
maxzoom = 14,
promote_id = "GEOID"
) |>
add_fill_layer(
id = "features-fill",
source = "duckdb-tiles",
source_layer = "layer", # ST_AsMVT default layer name
fill_color = "steelblue",
fill_opacity = 0.6,
tooltip = "GEOID",
hover_options = list(
fill_color = "yellow",
fill_opacity = 1
)
) |>
add_line_layer(
id = "features-line",
source = "duckdb-tiles",
source_layer = "layer",
line_color = "white",
line_width = 1
)
# Display the map
m
# Cleanup: Stop the server when done (also disconnects the database)
# stop_tile_server(server, disconnect_db = TRUE)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment