Giter VIP home page Giter VIP logo

mapdeck's Introduction

mapdeck

R build status [Codecov test coverage CRAN_Status_Badge downloads CRAN RStudio mirror downloads Github Stars

What is mapdeck?

An R library which lets you plot large data sets (as much as your GPU & browser can handle), on interactive maps using Mapbox GL and Deck.gl

What is mapbox?

Mapbox is the location data platform for mobile and web applications. We provide building blocks to add location features like maps, search, and navigation into any experience you create.

What is deck.gl?

deck.gl is a WebGL-powered framework for visual exploratory data analysis of large datasets.

How do I use it?

First you need to install it, either from CRAN

install.packages("mapdeck")

Or from github (to get the latest development version)

remotes::install_github("SymbolixAU/mapdeck")

If the github version fails to install, you’ll probably need to update dependencies first

remotes::install_github("dcooley/geometries")
remotes::install_github("dcooley/sfheaders")
remotes::install_github("SymbolixAU/spatialwidget")

Then everything you need to know to get you started is on the home page

Quick Start

Mapdeck uses Mapbox maps, and to use Mapbox you need an access token.

Once you’ve generate a token you can use their maps.

Call mapdeck(token = 'your_token') to generate a basic map. Then start adding layers by using one of the various add_*() functions.

url <- 'https://raw.githubusercontent.com/plotly/datasets/master/2011_february_aa_flight_paths.csv'
flights <- read.csv(url)
flights$info <- paste0("<b>",flights$airport1, " - ", flights$airport2, "</b>")

mapdeck(token = key, style = mapdeck_style('dark')) %>%
  add_arc(
    data = flights
    , origin = c("start_lon", "start_lat")
    , destination = c("end_lon", "end_lat")
    , stroke_from = "airport1"
    , stroke_to = "airport2"
    , tooltip = "info"
    , layer_id = 'arclayer'
  )

Arcs

Arcs

See the Layers page for more examples

Getting help

For general help and advice the best place to ask is on StackOverflow (using the mapdeck tag).

If you’ve found a bug, or want a new feature added then use the issue tracker on github.

I don’t respond to emails asking for help because this is an open source package, and any advice should be kept open so everyone can benefit. (unless you want to pay me!)

mapdeck's People

Contributors

batpigandme avatar chrismuir avatar dcooley avatar kimnewzealand avatar mdsumner avatar michaelchirico avatar mitchelloharawild avatar mpadge avatar nowosad avatar tylerlittlefield avatar zacdav avatar zekiye-y avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mapdeck's Issues

colorDomain

Grids/hexagons require a colour domain.

Will allow the user to pass in a palette of n colours (e.g. viridisLite::viridis(5)), which will get translated into the domain

'force' argument to by-pass the shape constructor

Have a force = c(FALSE, TRUE) argument so we can by-pass the shape construction.

Will be useful when trying to render millions of points, AND the input data is in the correct shape

This is currently slow in R because it has to set the colours and create the shape.

n <- 5e6  ## 5 million
dots <- data.frame(x=c(runif(n, -93.701281, -93.533053)),
			y=c(runif(n,  41.515962,  41.644369)))


dots$letter <- sample(letters, size = n, replace = T)

mapdeck(
  style = mapdeck_style('dark')
  ) %>%
    add_scatterplot(
      data = dots
      , lon = "x"
      , lat = "y"
      , fill_colour = "letter"
      , radius = 5
      , fill_opacity = 50
      , layer_id = "dots"
    )

Maybe also expose the 'shape construction' functions so users can use it prior to calling the plotting function.

This may also be possible through the new JSON Api they are implementing

udpate triggers

Design ideas

  • each layer gets a triggers argument
  • this argument accepts one or many trigger objects
  • a trigger is an html input
my_input <- list(
  type = 'range'
  , id = 'unique_id'
  , name = 'my_name'
  , step = '10'
  , min = '100'
  , max = '1000000'
  , value = '100'
)
trigger <- list(
  id = 'unique_id'  # user-defined
  , input = my_input
  , accessor = 'radius'   ## one of the other args of the function which corresponds to a data accessor (e.g. `getRadius`)
  , data_column = NULL  ## if not-null, the input value is 'applied' to the column value
  , 
)
  • need a way to create and use a function. But, the Function constructor is not recommended
  • and also support .js files uploaded as part of a shiny, where you can call the functions on those.

Functions can be passed in using htmlwidgets::JS("function my_radius(d, r) { return d * r; }"). This can either be done in the mapdeck() call, or for each add_ layer.
If done on each add_ layer it will be re-evaluated every time the function is called, including everytime the input callback is fired. So I'm going to make users supply functions inside mapdeck()

mapdeck(
  js_functions = list(
    htmlwidgets::JS("function my_radius1(d, r) { return d * r; }")
    , htmlwidgets::JS("function my_radius2(d, r) { return d / r; }")
  )
)

where d is the value in the getRadius: d => accessor, and r is the input/slider value.

Another thought is, rather than defining / finding / creating the various getRadius, getPosition functions inside each add_() javascript method, is to have a separate .js script which defines those functions so they're then available already constructed. This may require a 2-step invoke_method(), which I'm not sure is possible.

colours

TODO

  • colours can accept column of hex colours
  • support function palettes - NO - issuing a warning.
  • na_colour

For function palettes, generate a palette with the default for each function, and issue a deprecated warning

conflicting divs (legend & tooltip) with multiple maps

library(shiny)
library(shinydashboard)
library(mapdeck)
set_token(read.dcf("~/.googleAPI", fields = "MAPBOX"))

ui <- dashboardPage(
	dashboardHeader()
	, dashboardSidebar()
	, dashboardBody(
		mapdeckOutput(
			outputId = "map1"
		)
		, mapdeckOutput(
			outputId = "map2"
		)
	)
)

server <- function(input, output) {

	df <- melbourne
	df$elevation <- sample(200:5000, size = nrow(df))
	df$info <- paste0("<b>SA2 - </b><br>",df$SA2_NAME)

	output$map1 <- renderMapdeck({
		mapdeck(
			style = mapdeck_style('dark')
			, location = c(145, -38)
			, zoom = 8
		) %>%
			add_polygon(
				data = df
				, polyline = "geometry"
				, layer = "polygon_layer"
				, fill_colour = "SA2_NAME"
				, elevation = "elevation"
				, stroke_width = 0
				, tooltip = 'info'
				, legend = T
			)
	})
	
	output$map2 <- renderMapdeck({
		mapdeck(
			style = mapdeck_style('dark')
			, location = c(145, -38)
			, zoom = 8
		) %>%
			add_polygon(
				data = df
				, polyline = "geometry"
				, layer = "polygon_layer"
				, fill_colour = "SA3_NAME"
				, elevation = "elevation"
				, stroke_width = 0
				, tooltip = 'info'
				, legend = T
			)
	})
}
shinyApp(ui, server)

I think the solution is to use the map_id value inside the div

Support Aggregations in add_grid

Enhancement Request:

add_grid scales the elevation of grids according to the number of data elements contained in the given geography. However, it should also support the designation of an arbitrary column as the designator of elevation.

Use Case:

Suppose you wanted to plot sales opportunities across the country. By default, add_grid will show markets with lots of opportunities as having the highest elevations. However, one market with 5 very large deals is more important than a market with 20 very small deals - And you'd like to see that reflected in the market elevations.

Essentially, what you would actually like to do is pass a Deal Size column as a parameter to add_grid as an elevation parameter. Then, the heights of your markets would be reflect not of the number of opportunities in a given market, but rather the aggregate sum of the opportunity in that market.

clear layers

TODO

  • arc
  • geojson
  • grid
  • line
  • path
  • pointcloud
  • polygon
  • scatterplot
  • screengrid
  • text

dependency on spatialwidget

now that library(jsonify) exists, do I remove googlePolylines encoding?

Speed (in r)

library(sf)
library(mapdeck)
library(jsonify)
library(googlePolylines)
library(microbenchmark)

sf <- mapdeck::roads

microbenchmark(
	google = { googlePolylines::encode( sf ) },
	jsonify = { jsonify::to_json( sf ) },
	geojson = { geojsonsf::sf_geojson( sf ) },
	times = 5
)

# Unit: milliseconds
# expr      min       lq     mean   median       uq      max neval
# google 754.0125 782.9268 821.1052 819.7165 854.9187 893.9515     5
# jsonify 118.5501 118.8821 125.6056 125.7312 129.9120 134.9523     5
# geojson 139.2036 143.3345 145.7768 145.2627 149.1138 151.9693     5

Size

google = googlePolylines::encode( sf )
jsonify = jsonify::to_json( sf )
geojson = geojsonsf::sf_geojson( sf ) 

format( object.size( google ), units = "Mb" )
# [1] "11.2 Mb"
format( object.size( jsonify ), units = "Mb" )
# [1] "6.6 Mb"
format( object.size( geojson ), units = "Mb" )
# [1] "7.9 Mb"

Do I switch?

TODO

  • benchmark conversion to JSON
  • benchmark object sizes (inc transfer to javascript)

jsonify on it's own won't work. For eample, the data format of a path is

 Data format:
   * [
   *   {
   *     path: [[-122.4, 37.7], [-122.5, 37.8], [-122.6, 37.85]],
   *     name: 'Richmond - Millbrae',
   *     color: [255, 0, 0]
   *   },
   *   ...
   * ]

so it needs the extra layer of brackets, which is what GeoJSON gives.

TODO - R objects

  • sf (need to down-filter by geometry type)
  • data.frame
  • sfencoded (need to down-filter by geometry type)
  • sfendcodedLite (the quickest!)

TODO - R functions

  • force = FALSE/TRUE to by-pass row filters - not using a force argument
  • if attr(sf$geometry, "class") == sf_geometry, set force = TRUE because there is ONLY one type of geom.

TODO - javascript functions

  • arc
  • grid
  • hexagon
  • line
  • path
  • pointcloud
  • polygon
  • scatterplot
  • screengrid
  • text

TODO - sf objects

  • arc
  • grid
  • hexagon
  • line
  • path
  • pointcloud
  • polygon
  • scatterplot
  • screengrid
  • text

TODO - sf objects

  • arc
  • grid
  • hexagon
  • line
  • path
  • pointcloud
  • polygon
  • scatterplot
  • screengrid
  • text

TODO - df with polyline

  • arc
  • grid
  • hexagon
  • line
  • path
  • pointcloud
  • polygon
  • scatterplot
  • screengrid
  • text

TODO - df OD objects

  • arc
  • line

TODO - sfencoded

  • grid
  • hexagon
  • path
  • polygon
  • scatterplot
  • screengrid
  • text

arc - requires multi-encoded cols
line - requires multi-encoded cols
pointcloud - requries Z attr on encoded col

TODO - sfencodedlite

  • grid
  • hexagon
  • path
  • polygon
  • scatterplot
  • screengrid
  • text

arc - requires multi-encoded cols
line - requires multi-encoded cols
pointcloud - requries Z attr on encoded col

autoHighlight

layers to get a autoHighlight argument, NULL or hex colour.

if hex colour, set

autoHighlight: true,
HighlightColor: [r,g,b,a]

TODO - auto_highlight

  • arc
  • geojson
  • grid
  • hexagon
  • line
  • path
  • pointcloud
  • polygon
  • scatterplot
    screengrid
  • text

TODO - highlight_colour

  • arc
  • geojson
  • grid
  • hexagon
  • line
  • path
  • pointcloud
  • polygon
  • scatterplot
    screengrid
  • text

TODO - checks

  • highlight hex string has alpha component


TODO

  • News
  • Version
  • docs

Polygon Layer - multi-polygon plotting issue

library(googleway)
library(mapdeck)
library(sf)

set_key(read.dcf("~/Documents/.googleAPI", fields = "GOOGLE_MAP_KEY"))
set_token(read.dcf("~/Documents/.googleAPI", fields = "MAPBOX"))

nc <- st_read(system.file("shape/nc.shp", package="sf"))
sf <- nc[nc$NAME == "Dare", ]

google_map() %>%
  add_polygons(
    data = sf
  )


mapdeck(
  location = c(-80, 36)
  , zoom = 6
) %>%
  add_polygon(
    data = sf
  )

Reference

onHover

  • arc
  • hexagon
  • line
  • path
  • pointcloud
  • polygon
  • scatterplot
  • text

grid - NA
screengrid - NA

Invalid ELF header

I am unable to install the dev version of mapdeck on Ubuntu 16.04 due to an invalid ELF header.

Using GitHub PAT from envvar GITHUB_PAT
Downloading GitHub repo SymbolixAU/mapdeck@master
from URL https://api.github.com/repos/SymbolixAU/mapdeck/zipball/master
Installing mapdeck
'/usr/lib/R/bin/R' --no-site-file --no-environ --no-save --no-restore --quiet CMD  \
  INSTALL '/tmp/RtmpUEFdy9/devtools2bb01e0a32c0/SymbolixAU-mapdeck-779ec24'  \
  --library='/home/garrett/R/rlibs' --install-tests 

* installing *source* package ‘mapdeck’ ...
** libs
make: Nothing to be done for 'all'.
installing to /home/garrett/R/rlibs/mapdeck/libs
** R
** data
*** moving datasets to lazyload DB
** inst
** tests
** byte-compile and prepare package for lazy loading
** help
*** installing help indices
** building package indices
** installing vignettes
** testing if installed package can be loaded
Error: package or namespace load failed for ‘mapdeck’ in dyn.load(file, DLLpath = DLLpath, ...):
 unable to load shared object '/home/garrett/R/rlibs/mapdeck/libs/mapdeck.so':
  /home/garrett/R/rlibs/mapdeck/libs/mapdeck.so: invalid ELF header
Error: loading failed
Execution halted
ERROR: loading failed
* removing ‘/home/garrett/R/rlibs/mapdeck’
* restoring previous ‘/home/garrett/R/rlibs/mapdeck’
Installation failed: Command failed (1)
Session info -------------------------------------------------------------------------
 setting  value                       
 version  R version 3.5.1 (2018-07-02)
 system   x86_64, linux-gnu           
 ui       RStudio (1.2.1022)          
 language en_US                       
 collate  en_US.UTF-8                 
 tz       America/New_York            
 date     2018-10-05                  

Packages -----------------------------------------------------------------------------
 package   * version     date       source                         
 base      * 3.5.1       2018-07-03 local                          
 compiler    3.5.1       2018-07-03 local                          
 curl        3.2         2018-03-28 CRAN (R 3.5.0)                 
 datasets  * 3.5.1       2018-07-03 local                          
 devtools    1.13.6      2018-06-27 CRAN (R 3.5.1)                 
 digest      0.6.17      2018-09-12 CRAN (R 3.5.1)                 
 git2r       0.23.0.9000 2018-08-06 Github (ropensci/git2r@e18e8f7)
 graphics  * 3.5.1       2018-07-03 local                          
 grDevices * 3.5.1       2018-07-03 local                          
 httr        1.3.1       2018-07-02 Github (r-lib/httr@976289a)    
 knitr       1.20.15     2018-08-26 Github (yihui/knitr@4cf7a6f)   
 memoise     1.1.0       2018-07-11 Github (r-lib/memoise@06d16ec) 
 methods   * 3.5.1       2018-07-03 local                          
 R6          2.3.0       2018-10-05 Github (wch/R6@db787d4)        
 stats     * 3.5.1       2018-07-03 local                          
 tools       3.5.1       2018-07-03 local                          
 utils     * 3.5.1       2018-07-03 local                          
 withr       2.1.2       2018-08-23 Github (r-lib/withr@8b9cee2)   
 xfun        0.3.9       2018-09-11 Github (yihui/xfun@dc8eb19)    

Shiny

related to update triggers and deck.gl issue

The dev work is on the triggers branch

Issues:

  • local mapbox & deck.gl js dependencies are not included in <head> in shiny, but they are in viewer
  • props.data recognises the data has changed, but the layer stays in Awaiting State

layer_id

needs a layer <- match.arg( layer ) inside layerId()

transitions

sf objects

Polygons ((MULTI)POLYGONS), paths ((MULTI)LINESTRINGS) and scatterplots ((MULTI)POINT) will work on a sfc column

Arcs and Lines will work on 2 sfc columns, one for origin and one for destination

Progress

  • POINT - add_scatterplot()
  • POINT - add_arc()
  • POINT - add_line()
  • POINT - add_grid()
  • POINT - add_pointcloud()
  • POINT - add_screengrid()
  • POINT - add_hexagon()
  • POINT - add_text()

  • MULTIPOINT - add_scatterplot()
  • MULTIPOINT - add_grid()
  • MULTIPOINT - add_pointcloud()
  • MULTIPOINT - add_screengrid()
  • MULTIPOINT - add_hexagon()
  • MULTIPOINT - add_text()

  • LINESTRING - add_path()
  • MULTILINESTRING - add_path()

  • POLYGON - add_polygon()
  • MULTIPOLYGON - add_polygon()

Error / Warning / Message on

  • MULTIPOINT - add_arc() - point-to-point, so multipoint doesn't make sense
  • MULTIPOINT - add_line() - point-to-point, so multipoint doesn't make sense

TODO - docs
document each function saying which sf object and geometries they accept (now in #77 )

layer_id

I'm going to make this optional for the next release, where

if(is.null(layer_id)) layer_id <- "some default value"

(because I don't want to have to keep typing it). It's up to the user to read the documents to know what it's for...


TODO

  • update documentation

Light settings

Various layer support light settings (but not the main map, which seems odd, as different layers can have different light sources?)

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

  1. Wrap the map in a div in order to target the map object,
  2. Replace the htmlwidget ids with static ids, and
  3. 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")

RStudio errors

The viewer pane is blank/white on Ubuntu and Windows (using version RStudio 1.1.456)

The interim solution is to 'open in browser'

conflicts with googleway

When loading a mapdeck after googleway the window object gets overwritten, so the 'window.params' in googleway are no longer available

GeoJSON

  • filled - default: true
  • stroked - default: true
  • extruded - default: true
  • wireframe
  • lineWidthScale - default: 1
  • lineWidthMinPiels - default: 1
  • lineJointRounded - default: true
  • pointRadiusScale - default: 1
  • pointRadiusMinPixels - default: 0.5
  • lightSettings
  • onHover

Data Accessors

function (to call on the property attribute), or a single value to apply to all features

  • getLineColor
  • getFillColor
  • getRadius
  • getLineWidth
  • getElevation

Also need to expose opacity for fill and line


TODO - Other things I've noticed

  • getLineWidth doesn't seem to work when using roads

  • pointRadiusMaxPixels
  • pointRadiusScale
  • lineWidthUnits
  • lineWidthScale
  • lineWidthMinPixels
  • lineDashJustified
  • getLineDashArray
  • lineWidthMaxPixels
  • lineMiterLimit
  • elevationScale

data update

the add_layer() methods will all trigger a data update.

LinkingTo secondary LinkingTo packages

I'm getting a compilation error related to boost header files when I try to install the current dev version on a Mac.

I'm having to use local = FALSE in my call to devtools::install_github(), per this issue comment, here's what I'm seeing:

> devtools::install_github("SymbolixAU/mapdeck", local = FALSE)
Downloading GitHub repo SymbolixAU/mapdeck@master
from URL https://api.github.com/repos/SymbolixAU/mapdeck/zipball/master
Installing mapdeck
'/Library/Frameworks/R.framework/Resources/bin/R' --no-site-file --no-environ --no-save --no-restore --quiet CMD build  \
  '/private/var/folders/dz/ngc9frz55hx9pjpvw3mts1sr0000gn/T/Rtmp0Gt55R/devtools2f352d4b0d1c/SymbolixAU-mapdeck-779ec24'  \
  --no-resave-data --no-manual --no-build-vignettes 

* checking for file/private/var/folders/dz/ngc9frz55hx9pjpvw3mts1sr0000gn/T/Rtmp0Gt55R/devtools2f352d4b0d1c/SymbolixAU-mapdeck-779ec24/DESCRIPTION... OK
* preparingmapdeck:
* checking DESCRIPTION meta-information ... OK
* cleaning src
* checking for LF line-endings in source and make files and shell scripts
* checking for empty or unneeded directories
* looking to see if adata/datalistfile should be added
* buildingmapdeck_0.1.002.tar.gz'/Library/Frameworks/R.framework/Resources/bin/R' --no-site-file --no-environ --no-save --no-restore --quiet CMD INSTALL  \
  '/private/var/folders/dz/ngc9frz55hx9pjpvw3mts1sr0000gn/T/Rtmp0Gt55R/mapdeck_0.1.002.tar.gz'  \
  --library='/Users/chrismuir/r_libs' --install-tests 

* installing *source* packagemapdeck...
** libs
/usr/local/clang4/bin/clang++ -std=gnu++11 -I"/Library/Frameworks/R.framework/Resources/include" -DNDEBUG -DSTRICT_R_HEADERS -I"/Users/chrismuir/r_libs/Rcpp/include" -I"/Users/chrismuir/r_libs/rapidjsonr/include" -I"/Users/chrismuir/r_libs/colourvalues/include" -I"/Users/chrismuir/r_libs/jsonify/include" -I/usr/local/include  -I../inst/include -fPIC  -Wall -g -O2 -c RcppExports.cpp -o RcppExports.o
/usr/local/clang4/bin/clang++ -std=gnu++11 -I"/Library/Frameworks/R.framework/Resources/include" -DNDEBUG -DSTRICT_R_HEADERS -I"/Users/chrismuir/r_libs/Rcpp/include" -I"/Users/chrismuir/r_libs/rapidjsonr/include" -I"/Users/chrismuir/r_libs/colourvalues/include" -I"/Users/chrismuir/r_libs/jsonify/include" -I/usr/local/include  -I../inst/include -fPIC  -Wall -g -O2 -c scatterplot.cpp -o scatterplot.o
In file included from scatterplot.cpp:5:
In file included from ../inst/include/palette/palette.hpp:10:
In file included from /Users/chrismuir/r_libs/colourvalues/include/colourvalues/colours/colours_hex.hpp:5:
/Users/chrismuir/r_libs/colourvalues/include/colourvalues/colours.hpp:10:10: fatal error: 'boost/math/interpolators/cubic_b_spline.hpp' file not found
#include <boost/math/interpolators/cubic_b_spline.hpp>
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
make: *** [scatterplot.o] Error 1
ERROR: compilation failed for packagemapdeck* removing/Users/chrismuir/r_libs/mapdeck* restoring previous/Users/chrismuir/r_libs/mapdeckInstallation failed: Command failed (1)

I cloned mapdeck, and if I just add BH to the LinkingTo field in the DESCRIPTION file, it compiles without issues and all tests pass. I'm not sure if that's the best way to fix this or not.

I spent some time looking for an example of a package that's LinkingTo a package that is LinkingTo BH (that's what's happening here.....mapdeck links to colourvalues, which links to BH). I couldn't find one (RcppParallel has reverse links, and is itself LinkingTo BH, but as far as I can tell it's not actually using the boost header files anywhere in its code).

polygon stroke_width

is this doing anything?

mapdeck(
  token = key
  , style = mapdeck_style('dark')
  , location = c(145, -38)
  , zoom = 8
  ) %>%
  add_polygon(
    data = melbourne
    , polyline = "geometry"
    , layer = "polygon_layer"
    , stroke_colour = "#00FF00",
    , stroke_width = 1000
   )

Reference : visgl/deck.gl#1992

Can't load polygon

Hi!

First, thank you for the package!! It's awesome!. I have problems with this shapefile
shape.zip I don't the reason why the polygon isn't loading. Can you help me?

test <- read_sf("test_shape.shp")
mapdeck(token = key, style = 'mapbox://styles/mapbox/dark-v9', pitch = 45 ) %>%
  add_polygon(data = test,
              layer = "test",
              fill_colour = "Bsc_PoP")

TODO

map-independent libraries

Given deck.gl will work without the map layer, it's not necessarily reliant on Mapbox. Maybe there's scope / desire to have

  • a map-independent library which will just handle all the data manipulation (all the C++ code I've been working on)
  • a library to handle the deck.gl javascript rendering
  • hooks so it can be used by leaflet/mapdeck/google(way)/base/sf?

parameter checks

  • arc
  • geojson
  • grid
  • line
  • path
  • pointcloud
  • polygon
  • scatter
  • screengrid
  • text

Can't load sfc objects (Polygons, Points...)

Hey,

I can't load any sfc objects on the basemaps and I really don't know what's the issue. I did downcast Multipolygons to Polygons so it's supposed to work but it doesn't.

#data step
test894 <- st_read('donnees/COM 894.MIF')
data894 = filter(test894, NB_DIV894 > 0)
st_crs(data894) = 2154 
d894 <- st_transform(data894, 4326)
d894f <- st_cast(d894, 'POLYGON')
dd <- st_sf(d894f)

#mapping step
set_token(Sys.getenv('MAPBOX'))
md <- mapdeck_style('dark')

mapdeck(map, style = md, pitch = 45, location = c(0.58, 46.95), zoom = 7) %>%
  add_polygon(
    data = dd,
    layer = 'polygon_layer',
    fill_colour = 'NB_DIV894'
  )

Then I thought, ok lets try with POINT and the add_grid function but I have the same results : I only have the basemap and no data loads.

dd_centr <- st_centroid(dd)
mapdeck(style = md, pitch = 45, location = c(0.58, 46.95), zoom = 7) %>%
add_grid(
  data = dd_centr
  , lat = "Y_centroid"
  , lon = "X_centroid"
  , cell_size = 1000
  , elevation_scale = 50
  , layer_id = "grid_test"
)

Any help would be really appreciated as I'd love to go further with this package.

rcpp

TODO - layers

  • arc
  • grid
  • hexagon
  • line
  • path
  • pointcloud
  • polygon
  • scatterplot
  • screengrid
  • text

TODO

  • ensure scoped variables / arguments are handled (as per SymbolixAU/googleway#182)
  • defaults are overwritten by user-supplied values, constants and columns of data
  • stroke_width (as well as colour & opacity)
  • stroke_from & stroke_to
  • opacity from & opacity to
    add_path() colours are different
  • categorical colouring is not quicker. Numeric is quicker (but because the old implementation is slow). Can see this in the new add_path()
    don't colour twice if the same variable is used for stroke & fill

TODO - legend

  • keep track of fill & stroke colours for use in legend
  • legend_options
  • legend title defaults
  • legend - JS errors if incorrect fill/stroke parameter is defined
  • specify T and/or F for fill & stroke
  • don't 'resolve' the fill/stroke if the user didn't ask for it. (colourvalues::colour_values() asks for summary, but, it's not used)
  • If you don't specify fill_colour, it still needs to make a colour from the 'default' colour
  • legend_options docs

TODO - other

  • auto-highlight still works

legends

TODO - layers

  • path
  • pointcloud
  • polygon
  • scatterplot
  • line

TODO - functionality

  • add_legend
  • update_legend (shiny)
  • clear_legend (shiny) - with clear_layer()
  • fill & stroke legends (for the same layer)
  • non-overlapping legends (if they have the same position)
    two maps in the same shiny / markdown don't conflict legends new issue: #65

TODO - a bit harder

  • arc (from and/or to)
    screengrid (uses colour_range)
    grid (uses colour_range)
    geojson (uses different colouring)

(example) attempt at XYZ POLYGON

Here is my attempt to get XYZ triangles into mapdeck, so we have a shared example to run with.

key <- Sys.getenv("MAPBOX_TOKEN")


elevate_triangles <- function(g, r) {
	## assuming geometry of POLYGON
	sf::st_polygon(list(cbind(g[[1]], raster::extract(r, g[[1]]))))
}

elevate_sf <- function(x, r, exag = 1) {
	sf::st_set_geometry(x, sf::st_sfc(purrr::map(sf::st_geometry(x), elevate_triangles, r = r * exag), crs = sf::st_crs(x)))
}

## get sf data (in longlat)
nc <- sf::read_sf(system.file("shape/nc.shp", package="sf"))
bb <- sf::st_bbox(nc)
bb <- bb + c(-2, -2, 2, 2)
## get topo data (also longlat)
topo <- marmap::as.raster(marmap::getNOAA.bathy(bb["xmax"], bb["xmin"], bb["ymax"], bb["ymin"], 
																								resolution = 2))
## sf POLYGON triangle for every element (a is *area* in native coordinates )
triangles <- sf::st_cast(sfdct::ct_triangulate(nc, a = .1))


library(mapdeck)
zfac <- 1
x <- elevate_sf(triangles, topo * zfac)

## my attempt at mapdeck XYZ triangle glory
mapdeck(token = key, style = 'mapbox://styles/mapbox/dark-v9', location = c(mean(bb[c("xmin", "xmax")]), mean(bb[c("ymin", "ymax")])), zoom = 5) %>% 
		add_polygon(data = x, layer_id = "polylayer") 
	

I use exaggeration (zfac) to make sure it's not just a scaling issue. So far all POLYGONs are totally flat!

Here's how I go about it with silicate/anglr (if installation gives you grief just let me know, It might not be setting up all deps properly).

## same but done with rgl
library(anglr)
plot3d(TRI(x))  ## triangulating is redundant here, but works with any sf polygon layer (use DEL for better/denser triangles with "max_area" arg 
rgl::aspect3d(1, 1, 1/10)
## if you in RStudio Server the output needs a widget (it's slow, much faster with local rgl device)
rgl::rglwidget()  ## also rerun this if aspect3d is updated ...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.