Created
October 27, 2025 18:22
-
-
Save arthurgailes/2d80a11eb95cc550907c89d0533f73da to your computer and use it in GitHub Desktop.
rtileserver demo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 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