consider adding functionality to render mvt/mbtiles
A continuation from https://twitter.com/_davecooley/status/1316992144226144256
A function to read and render mbtiles files or their respective folder structure version (.pbf files) should be easy enough... With mapview in mind, the hard thing is to create these tiles on the fly from a e.g. sf object. tippecanoe is fast but for "deep zoom" scenarios it is still way too slow. Running in background doesn't help as the leaflet copies the folder(s) on map creation to a different place so every tile set created afterwards is lost. Maybe this could be somehow addressed in htmlwidgets?
In any case, here's what I have so far:
library(sf)
library(leaflet)
library(htmlwidgets)
library(htmltools)
library(mapboxapi)
library(processx)
url = "https://raw.githubusercontent.com/bjornharrtell/flatgeobuf/3.0.1/test/data/UScounties.fgb"
tst = st_read(url)
tst = tst[, -5] # tippecanoe has a problem with the NAME column (not being proper utf8)
fldr = tempfile()
fl = tempfile(fileext = ".geojson")
st_write(tst, fl, append = FALSE)
system.time({
st_write(
tst
, dsn = fldr
, driver = "MVT"
, dataset_options = c(
"FORMAT=DIRECTORY"
, "COMPRESS=NO"
, "MAXZOOM=10"
)
, delete_dsn = TRUE
)
})
dir.create(fldr)
command = sprintf(
"tippecanoe -zg -f -pC -e %s %s"
, fldr
, fl
)
system.time({
system(command)
})
system.time({
processx::run(
"tippecanoe"
, args = c("-z 10", "-f", "-pC", "-e", fldr, fl)
)
})
p = processx::process$new(
"tippecanoe"
, args = c("-z 10", "-f", "-pC", "-e", fldr, fl)
)
p$is_alive()
leafgrid = htmlDependency(
name = "Leaflet.VectorGrid"
, version = "1.3.0"
, src = c(href = "https://unpkg.com/leaflet.vectorgrid@latest/dist/")
, script = "Leaflet.VectorGrid.bundled.js"
)
registerPlugin <- function(map, plugin) {
map$dependencies <- c(map$dependencies, list(plugin))
map
}
tiledDataDependency <- function(tiles_dir) {
htmltools::htmlDependency(
name = basename(tiles_dir),
version = "0.0.1",
src = c(file = tiles_dir)
)
}
leaflet() %>%
addTiles() %>%
registerPlugin(leafgrid) %>%
registerPlugin(tiledDataDependency(fldr)) %>%
setView(lng = -105.644, lat = 51.618, zoom = 3) %>%
onRender(
paste0(
"function(el, x) {
var pbfLayer = L.vectorGrid.protobuf('lib/"
, basename(fldr)
, "-0.0.1/{z}/{x}/{y}.pbf');
pbfLayer.addTo(this);
}"
)
) %>%
leafem::addMouseCoordinates()
This would be amazing.
While your workaround works, I understand that it wouldn't work in Shiny when you want to update a tile using leaftletProxy (because of the onRender piece).
Would that be feasible to implement?
Care for creating a PR?