I have a dataframe
containing nested ecological survey data. A conceptual description of the data - at the 'top' level is a survey site; within sites are n traps; within traps there can be n animals caught.
I would like to display a Leaflet
map showing markers which correspond to the data's top level (i.e. survey sites). When you click on a survey site, it should fan out and show markers of each trap within a survey site. When clicking a trap, it should then display a list of the animals caught within the trap (a regular Leaflet
pop up would be fine at this point).
I've no idea whether this is even possible within R
Leaflet
, despite many searches of Google and/or SO. I did find one potential Javascript solution but I don't know whether it would translate exactly to resolve the issue I'm facing. At the very least, however, the act of hovering on a marker and it displaying nested markers is the functionality that I'm after when viewing traps within sites.
I have included below an example nested dataframe of some dummy data, plus a barebones Leaflet
reprex. In the dummy data, and for simplicity, I have assigned each site
the same lat/lon. When clicking on any site
(001, 002, 003), the traps will fan out from that site. At Site 001 there is only 1 unique trap (ID = 001-001) but Site 2 has two unique traps (002-001 and 002-002). Site 003 has only one trap.
library(leaflet)
library(tidyverse)
x<-as_tibble(data.frame(site = c("001", "001", "001", "002", "002", "002", "003"),
trap = c("001-001", "001-001", "001-001", "002-001", "002-001", "002-002", "003-001"),
animal = c("001-001-001", "001-001-002", "001-001-003", "002-001-001", "002-001-002", "002-002-003", "003-001-001"),
lat = c(51.1, 51.1, 51.1, 52.4, 52.4, 52.4, 51.5),
lon = c(-1.1, -1.1, -1.1, -1.7, -1.7, -1.7, -1.2)))
leaflet() %>%
addProviderTiles(providers$OpenStreetMap, options = providerTileOptions(noWrap = TRUE), group = "Open Street Map") %>%
setView(lng = -1.900796, lat = 52.479380, zoom = 7) %>%
addLayersControl(baseGroups = c("Open Street Map")))
Hoping a solution is possible - any help would be very much appreciated.
There is an option to create clusters (clusterOptions = TRUE
) within the addCircleMarkers
function.
I am not sure if the code below generates what you want, but it might be able to help you to the next step.
leaflet() %>%
addProviderTiles(providers$OpenStreetMap, options = providerTileOptions(noWrap = TRUE), group = "Open Street Map") %>%
setView(lng = -1.900796, lat = 52.479380, zoom = 7) %>%
addLayersControl(baseGroups = c("Open Street Map")) %>%
addCircleMarkers(data = x, lng = ~lon, lat = ~lat, clusterOptions = TRUE,
popup = paste("<b>Site:</b>", x$site, "<br>",
"<b>lon:</b>", x$lon, "<br>",
"<b>lat:</b>", x$lat, "<br>",
"<b>trap:</b>", x$trap, "<br>",
"<b>animal:</b>", x$animal))
I added the popup to keep track of which marker was which, but you can do something with colors or shapes if that is more visually attractive.
An additional note: As you can see I have created the popup with some html script for the formatting (<b></b>
) and the linebreaks (<br>
). You can use other html tricks in these popups if you want, it usually works and it's highly customizable.
However, the leafpop
package might be a faster way to add tables, images and graphs in popups.