rgisr-sfmapdeck

Error creating data layer using the add_trips function of mapdeck


Trying to use the new add_trips layer for mapdeck . Example code and errors below. Grateful for any assistance. Thanks.

The data I'm using:

> class(msi)
[1] "sf"         "tbl_df"     "tbl"        "data.frame"

> head(msi$geometry)
Geometry set for 6 features 
geometry type:  POINT
dimension:      XYZ
bbox:           xmin: 2.94486 ymin: 51.34172 xmax: 3.21298 ymax: 51.42742
epsg (SRID):    4326
proj4string:    +proj=longlat +datum=WGS84 +no_defs
First 5 geometries:
POINT Z (2.94486 51.42742 1573824004)
POINT Z (3.2062 51.35052 1573827317)
POINT Z (3.21298 51.34172 1573830334)
POINT Z (3.21298 51.34175 1573834830)
POINT Z (3.21297 51.34173 1573838433)

The mapdeck code:

key = "mykeyhere"

plot <- mapdeck( token = key, style = 'mapbox://styles/mapbox/dark-v9',
                         pitch = 30,
                         width="100%",
                         zoom=15) %>%
  add_trips(
    data = msi
  )

Error I'm getting:

Error in rcpp_path_geojson(data, l, geometry_column, digits, "trips") : Error creating data layer

Solution

  • Notes on your example

    1. The trips layer requires LINESTRINGs, not POINTs
    2. It also needs both Z (elevation) and M (time) attributes (the lines are rendered in space and time)

    Other details

    I wrote the trips layer with this pull-request into the sf library in mind, so I've designed it to automatically read the z_range and m_range of the sfc object.

    I also have the sfheaders library which can construct sf objects which include these attributes.

    I am using the github versions of sf and mapdeck

    remotes::install_github("r-spatial/sf")
    remotes::install_github("SymbolixAU/mapdeck")
    

    Working Example

    You haven't included a reproducible data set in your question, so I'm going to use my own.

    In this example I

    1. Take a sf LINESTRING object
    2. Convert into a data.table of coordinates
    3. Append Z and M columns
    4. Convert back to sf LINESTRING object
    5. Plot trips
    library(mapdeck)
    library(sf)
    library(sfheaders)
    library(data.table) 
    
    ## 'roads' is an sf object included in mapdeck
    sf_roads <- mapdeck::roads
    
    ## you don't need this, I only use it later in the plot so I can subset only 'long' 
    ## roads, so the gif is below 2mb!
    sf_roads$length <- as.numeric( sf::st_length( sf_roads ) )
    sf_roads$id <- 1:nrow( sf_roads )  ## for joining the 'length' back on
    
    ## grab the road coordinates
    dt <- sf::st_coordinates( sf_roads )
    dt <- as.data.table( dt )
    
    ## st_coordinates returns a L1 'id', which is equivalent to our 'id' above
    
    ## Need Z and M attributes
    dt[, Z := 0 ]   ## can be actual elevation if you have it
    dt[, M := 1:.N, by = .(L1)]   ## this 'M' is your timestamp
    
    ## convert back to sf LINESTRING
    sf_trips <- sfheaders::sf_linestring(
      obj = dt
      , x = "X"
      , y = "Y"
      , z = "Z"
      , m = "M"
      , linestring_id = "L1"
    )
    
    ## You don't need this bit, where I join the 'length' back on.
    sf_roads$geometry <- NULL
    
    sf_trips <- merge(
      x = sf_trips
      , y = sf_roads
      , by.x = "L1"
      , by.y = "id"
    )
    
    
    
    mapdeck(
      style = mapdeck_style("dark")
    ) %>%
      add_trips(
        data = sf_trips[ sf_trips$length > 500, ]  ## only showing 'long' roads
        , stroke_colour = "L1"
        , stroke_width = 100
        , opacity = 0.8
        , animation_speed = 10
        , trail_length = 50
        , palette = 
      )
    
    

    enter image description here