Closed enriquevaa closed 1 month ago
Is your tileset shared publicly? I can't seem to pull it in.
I made it public already: url="mapbox://enriquevaa.5t18pfv7" source_layer="AGEB_Mapbox_CDMX-5l1f2s"
Yeah, there's something wrong here with how sources are handled in a proxy session. I think I know how to fix, I'll post here.
I think I have an approach that works locally, but I can't get your layer to display outside a proxy session.
When I try this:
mapboxgl() %>%
add_vector_source(id="ageb_cdmx",url="mapbox://enriquevaa.5t18pfv7") %>%
add_fill_layer(
id = "AGEB",
source ="ageb_cdmx",
source_layer = "AGEB_Mapbox_CDMX-567l1f2s",
fill_color = interpolate(
column = "Densidad",
type = "linear",
values = c(0,1, 15000, 30000),
stops = c("lightgrey","#edf8b1", "#7fcdbb", "#2c7fb8"),
na_color = "lightgrey",
),
fill_opacity = 0.7,
tooltip = "tooltip")
I see: Error: Source layer "AGEB_Mapbox_CDMX-567l1f2s" does not exist on source "ageb_cdmx" as specified by style layer "AGEB"
Do you see the same?
Here's an approach I would recommend for now:
Add the source on map load outside the proxy session, then selectively display / clear the layer within the proxy session.
This will require re-installing from GitHub as I was passing through source-layer
incorrectly to JavaScript within proxy sessions.
library(shiny)
library(mapgl)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
actionButton("add_layer", "Add contours"),
actionButton("clear_layer", "Remove contours")
),
mainPanel(
mapboxgl::mapboxglOutput("map")
)
)
)
server <- function(input, output, session) {
output$map <- mapboxgl::renderMapboxgl({
mapboxgl(style = mapbox_style("light"), zoom = 13, center = c(-122.447303, 37.753574)) |>
add_vector_source(
id = "mapbox-contours",
url = "mapbox://mapbox.mapbox-terrain-v2"
)
})
observeEvent(input$add_layer, {
mapboxgl_proxy("map") |>
add_line_layer(
id = "terrain-data",
source = "mapbox-contours",
source_layer = "contour",
line_color = '#ff69b4',
line_width = 1
)
})
observeEvent(input$clear_layer, {
mapboxgl_proxy("map") |>
clear_layer("terrain-data")
})
}
shinyApp(ui, server)
I'm not closing this as I can't yet get a source added within a proxy session to communicate with add_layer()
correctly unless it is added using the source
argument directly.
I think I have an approach that works locally, but I can't get your layer to display outside a proxy session.
When I try this:
mapboxgl() %>% add_vector_source(id="ageb_cdmx",url="mapbox://enriquevaa.5t18pfv7") %>% add_fill_layer( id = "AGEB", source ="ageb_cdmx", source_layer = "AGEB_Mapbox_CDMX-567l1f2s", fill_color = interpolate( column = "Densidad", type = "linear", values = c(0,1, 15000, 30000), stops = c("lightgrey","#edf8b1", "#7fcdbb", "#2c7fb8"), na_color = "lightgrey", ), fill_opacity = 0.7, tooltip = "tooltip")
I see:
Error: Source layer "AGEB_Mapbox_CDMX-567l1f2s" does not exist on source "ageb_cdmx" as specified by style layer "AGEB"
Do you see the same?
I think is the name of the layer. This one is the correct: "AGEB_Mapbox_CDMX-5l1f2s"
Try this with the latest GitHub version of mapgl:
library(bslib)
library(mapgl)
library(magrittr)
library(shiny)
layers<-c("None","AGEBS")
ui <- page_sidebar(
title = "Layers Bug",
sidebar = sidebar(
width = 350,
selectInput("layer", "Select layer",layers,selected = "None")
),
card(
full_screen = TRUE,
card_header("Map"),
mapboxglOutput("map")
),
)
server <- function(input, output, session) {
output$map <- renderMapboxgl({
mapboxgl(style = mapbox_style("dark"),
center = mapboxapi::mb_geocode("Mexico City, Mexico"),
zoom = 9) %>%
add_vector_source(id="ageb_cdmx",url="mapbox://enriquevaa.5t18pfv7")
})
observeEvent(input$layer, {
if (input$layer== "AGEBS") {
mapboxgl_proxy("map") %>%
add_fill_layer(
id = "AGEB",
source ="ageb_cdmx",
source_layer = "AGEB_Mapbox_CDMX-5l1f2s",
fill_color = interpolate(
column = "Densidad",
type = "linear",
values = c(0,1, 15000, 30000),
stops = c("lightgrey","#edf8b1", "#7fcdbb", "#2c7fb8"),
na_color = "lightgrey",
),
fill_opacity = 0.7,
tooltip = "tooltip") %>%
add_layers_control(collapsible = TRUE) %>%
add_continuous_legend(
"Densidad por AGEB CDMX (2020)",
values = c("3k", "30k", "50k"),
colors = c("#edf8b1", "#7fcdbb", "#2c7fb8"),
position = "bottom-right"
)
}
if (input$layer== "None") {
mapboxgl_proxy("map") %>% clear_layer("AGEB") %>% clear_controls() %>% clear_legend()
}
})
}
shinyApp(ui, server)
This works great! Thank you
@walkerke I have detected another bug related to add_vector_source(). When you use add_fill_layer, hover_options doesn´t work.
In the first case, it doesn´t work; however, it does in the second chunk of code.
Thanks!
##With vector_source
mapboxgl(center = c( -99.133469,19.43267787),zoom = 10) %>%add_vector_source(id="ageb_cdmx",url="mapbox://enriquevaa.5t18pfv7") %>% add_fill_layer(
id = "AGEB",
source ="ageb_cdmx",
source_layer = "AGEB_Mapbox_CDMX-5l1f2s",
fill_opacity = 0.7,
fill_color = interpolate(
column = "Densidad",
type = "linear",
values = c(0,1, 15000, 30000),
stops = c("lightgrey","#edf8b1", "#7fcdbb", "#2c7fb8"),
na_color = "lightgrey"),
hover_options = list(
fill_color = "yellow",
fill_opacity = 1
))
##Without vector_source
mapboxgl(center = c( -99.133469,19.43267787),zoom = 10) %>% add_fill_layer(
id = "AGEB",
source =ageb_cdmx,
fill_opacity = 0.7,
fill_color = interpolate(
column = "Densidad",
type = "linear",
values = c(0,1, 15000, 30000),
stops = c("lightgrey","#edf8b1", "#7fcdbb", "#2c7fb8"),
na_color = "lightgrey"),
hover_options = list(
fill_color = "yellow",
fill_opacity = 1
))
Yeah, I don't have hover effects for vector tile sources enabled right now. I can see how it can be done (I use setFeatureState()
under the hood) but it also requires an id
in the vector tileset and I can't find any good examples anywhere of how that id
gets generated. For GeoJSON sources, it's straightforward as we use generateId: true
which takes care of it for us.
Have you seen any GL JS examples that show how to do hover effects for vector tile sources?
Some good info on setFeatureState() here
https://blog.mapbox.com/going-live-with-electoral-maps-a-guide-to-feature-state-b520e91a22d
The hover tooltips now work! See the example here:
The catch is that your vector tileset still needs an id
for its features. Mapbox Tiling Service does it by default, and tippecanoe can do it. I don't know about tilesets created in other ways.
@enriquevaa I also just tried your example above and the hover options do work with the vector source.
I have detected a bug: when I call a layer stored in my Mapbox studio from an add_vector_source() with mapbox_proxy() it doesn´t load in the map, but If I call it from renderMapboxgl() works fine.
Here are two reproducible examples. The first one does work, however, the second one hasn´t since the update of mapgl.