Passing additional options to mapdeck layer in recentered maps
Passing additional options to mapdeck layer in recentered maps
There are some situations where maps are centered to a fixed location (e.g., city, point of interest, etc.). In the example below, I've pulled a list world airport locations and generated arcs (random arcs) from a fixed point of origin (Sydney International Airport). Destination points in North and South America were adjusted so they are plotted to the right of the home location (Sydney).
The location of the base map can be set using the argument location. However, since the location of the destination points extend into the next map tile this causes issues with the navigating the map. Any movement past the international date line causes all data points (arcs, points, text, etc.) to shift to the right by one tile. Using options such as max bounds and location are useful in these circumstances for re-positioning the base layer and fixing the map dimensions. The mapbox documentation states has the following options available: maxBounds and renderWorldCopies. However there does not seem to be method for passing these arguments to the map layer in R (i.e., mapdeck().
I've attempted to append the map with these arguments using the htmltools and htmlwidgets packages using htmltools::browsable(..., tags$script(...)) and htmlwidgets::onStaticRenderComplete(...,..some js code...), but did not have much luck as these arguments had no effect on a post-rendered map (see last example).
Is there another method for passing these arguments to the mapdeck function? If not, is it possible to expaned the mapdeck function to allow for these options to be passed to the map layer?
Example
Build sample data
# pkgs
# install.packages("tidyverse")
# devtools::install_github("SymbolixAU/googlePolylines")
# devtools::install_github("SymbolixAU/mapdeck")
library(tidyverse)
# build dataset (using sample data from openflights.org)
# and add column names as listed here: https://openflights.org/data.html
url <- "https://raw.githubusercontent.com/jpatokal/openflights/master/data/airports-extended.dat"
raw <- read.table(url,sep = ",", stringsAsFactors = FALSE)
mapDF <- raw[,c(1:4,7,8)] # select columns of interest
# adding "dest" as a prefix for lat and long colnames.
colnames(mapDF) <- c("airportID", "name","city","country","dest_lat","dest_long")
# define center point and add to dataset: Sydney Kingsford Smith International Airport
originDF <- mapDF %>% filter(name == "Sydney Kingsford Smith International Airport")
mapDF$origin <- "Sydney International Airport"
mapDF$origin_lat <- originDF$dest_lat
mapDF$origin_lng <- originDF$dest_long
# reposition longitude values as the origin of the map is Sydney International Airport
center <- 151.177
mapDF$dest_long_fixed<- ifelse(mapDF$dest_long < center - 180,
mapDF$dest_long + 360,
mapDF$dest_long)
# grab a sample of rows for better performance
plotDF <- mapDF[sample(NROW(mapDF),1000),]
Build map
Note: update the access token with yours. I am also saving the map as a standalone file.
# pkgs
library(mapdeck)
key = "your_token_goes_here"
# build map
map <- mapdeck(token = key,
style = "mapbox://styles/mapbox/dark-v9", pitch = 45,
location = c(151.177, -33.9461), zoom = 1,
height = "100%") %>%
# plot 1000 arcs
add_arc(data = plotDF,
origin = c("origin_lng","origin_lat"),
destination = c("dest_long_fixed","dest_lat"),
stroke_from = "#FFC8FB",
stroke_to = "#FFC8FB",
stroke_from_opacity = 100,
stroke_to_opacity = 200,
stroke_width = 2,
layer_id = "arc_layer") %>%
# plot all points
add_scatterplot(data= mapDF,
lon = "dest_long_fixed",
lat = "dest_lat",
radius = 10000,
fill_colour = "#ffffff")
# save as standalone file
save_html(map,file = "world_flight_paths.html",background = "#000000")
Example passing additional js code to the map
My thinking on this was to
- Wrap the map in a div in order to target the map object,
- Replace the
htmlwidgetids with static ids, and - Pass options to the map using the new id
mapOut <- tagList(
tags$div(id="mapbox",
style="width:100vw; height:100vh;background-color: black;padding: 0;margin:0;",
map,
tags$script("
// manually set htmlwidget ids with static ids
var widget = document.getElementById('mapbox');
var wDivs = widget.querySelector('div');
wDivs.id = 'map';
// manually update the script with corresponding id
var scripts = document.querySelectorAll('script');
scripts[6].dataset.for = 'map';
// set access token
mapboxgl.accessToken =' replace with your token'
// set options
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/dark-v9',
maxBounds: [ [-180,85], [180,85] ],
center: [151.2073, -33.86785 ],
zoom: 1,
pitch: 40,
renderWorldCopies: false
});")
)
)
# save as standalone file
save_html(map,file = "world_flight_paths.html",background = "#000000")
@davidruvolo51 thanks for the suggestion.
At first glance this looks possible. I'll dive deeper into it in a day or so.
I haven't forgotten about this, but have prioritised other libraries. I'm working on this now.
This will be moved to mapbox
This is very exciting! I look forward to trying it out.