rmapdeck

Is is possible to color path by elevation?


I'm using mapdeck::add_path() to show aircraft flight paths. I would like to color the paths by elevation; is this possible? Here is a short example:

library(mapdeck)
library(sf)
# From https://github.com/kent37/mapdeck_play/blob/master/tracks_2019_03_11.gpkg?raw=true
one_day = st_read('tracks_2019_03_11.gpkg')

key = 'your_api_key'
mapdeck(location=c(-71.128184, 42.3769824), zoom=14, key=key) %>% 
  add_path(one_day)

enter image description here

Thanks!


Solution

  • Update 2024-01-03

    The way to do this is to supply a colour-per-vertex. Which in sf temrs means you need to add a list-column, where each list element is the same length as the number of coordinate pairs in the LINESTRING

    
    df_roads <- sfheaders::sf_to_df(mapdeck::roads, fill = TRUE)
    
    ## Add a random value for each coordinate
    ## These will become our colours at each vertex
    df_roads$random <- sample(0:100, size = nrow(df_roads), replace = TRUE)
    
    ## rebuild the sf and include the `random` column as a `list`, so the value 
    ## persists per vertex
    sf_roads <- sfheaders::sf_linestring(
        obj = df_roads
        , x = "x"
        , y = "y"
        , linestring_id = "linestring_id"
        , list_columns = "random"
        , keep = TRUE
    )
    
    mapdeck() %>%
        add_path(
            data = sf_roads
            , stroke_colour = "random"
            , stroke_width = 10
        )
    

    enter image description here


    Original answer

    It's currently not possible to have a multi-coloured path, but it is on my todo list.

    To achieve what you're after you'll have to use a line layer, which takes an 'origin' and 'destination' and draws a straight line (i.e., the constituent parts of a path)

    To get the Origin-Destination columns we need to decompose the sf object into a data.frame, add the '_to' columns, then make it an sf object again.

    (I also have a todo to allow data.frames to use Z and M, but for now we have to do this final conversion to sf again)

    library(data.table)
    library(sfheaders)
    
    df <- sfheaders::sf_to_df( one_day, fill = TRUE )
    
    setDT( df )[
      , `:=`(
        x_to = shift(x, type = "lead")
        , y_to = shift(y, type = "lead")
        , z_to = shift(z, type = "lead")
        , m_to = shift(m, type = "lead")
        )
      , by = flight
    ]
    
    df <- df[ !is.na( x_to ) ]
    
    df$origin <- sfheaders::sfc_point(
      obj = df
      , x = "x"
      , y = "y"
      , z = "z"
      , m = "m"
    )
    
    df$destination <- sfheaders::sfc_point(
      obj = df
      , x = "x_to"
      , y = "y_to"
      , z = "z_to"
      , m = "m_to"
    )
    
    sf <- sf::st_as_sf( df )
    
    mapdeck(
      style = mapdeck_style("dark")
    ) %>%
      add_line(
        data = sf
        , origin = "origin"
        , destination = "destination"
        , stroke_colour = "z"
      )
    

    enter image description here