Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/r-barnes/webglobe

3D globe visualization for R
https://github.com/r-barnes/webglobe

3d cesiumjs data-visualization globe r visualization

Last synced: 2 months ago
JSON representation

3D globe visualization for R

Awesome Lists containing this project

README

        

webglobe: Interactive 3D Maps
=============================

You want to understand your data, but it's spatially distributed and you're
afraid that trying to make sense of it on something gross, like a Mercator
projection, is going to lead you to bad intuitions.

![Mercator Projection](vignettes/mercator.png)

(Greenland is nowhere near that big in reality.)

webglobe can help you do this! It allows you to interactively visualize your
data on either a three-dimensional globe or a flat map.

Example: Earth quakes
-----------------------------

library(webglobe) #Load the library
data(quakes) #Load up some data

wg <- webglobe(immediate=TRUE) #Make a webglobe (should open a net browser)
Sys.sleep(10) #Wait for browser to start, or it won't work
wg + wgpoints(quakes$lat, quakes$lon, size=5*quakes$mag) #Plot quakes
wg + wgcamcenter(-24, 178.0650, 8000) #Move camera

![Webglobe earthquakes visualization](vignettes/webglobe_quakes.png)

Example: States
-----------------------------

library(webglobe) #Load the library
m <- ggplot2::map_data("state") #Get data
m$extrude_height <- 1000000*runif(nrow(m),min=0,max=1)
wg <- webglobe(immediate=TRUE) #Make a webglobe (should open a net browser)
Sys.sleep(10) #Wait for browser to start, or it won't work
wg + wgpolygondf(m,fill="blue",alpha=1,stroke=NA)
Sys.sleep(10) #Wait, in case you copy-pasted this
wg + wgclear() #Clears the above

![Webglobe states visualization](vignettes/webglobe_states.png)

Modes
-----------------------------

webglobes have two modes: **immediate** and **not-immediate**. Immediate mode
displays a webglobe upon initialization and immediately prints all commands to
that globe. Not-immediate mode stores commands and displays them all at once,
allowing you to stage visualization without intermediate display. The difference
is illustrated below.

Display timing in intermediate mode:

library(webglobe)
data(quakes) #Get data
q <- quakes #Alias data
wgi <- webglobe(immediate=TRUE) #Webglobe is displayed now
Sys.sleep(10) #Ensure webglobe runs before continuing
wgi + wgpoints( q$lat, q$lon) #Data displays now!
wgi + wgpoints(-q$lat, -q$lon) #Data displays now!
#Reloading the browser window clears everything

Display timing in not-intermediate mode:

library(webglobe)
data(quakes) #Get data
q <- quakes #Alias data
wgn <- webglobe(immediate=FALSE) #Webglobe is not displayed
Sys.sleep(0) #No need to wait
#Note that we have to store commands
wgn <- wgn + wgpoints( q$lat, q$lon) #Nothing shown yet
wgn <- wgn + wgpoints(-q$lat, -q$lon) #Nothing shown yet
wgn <- wgn + wgcamcenter(2.89,-175.962,21460) #Nothing shown yet
wgn #Show it all now!
#Reloading the browser window keeps everything

You can also switch between modes:

library(webglobe)
data(quakes) #Get data
q <- quakes #Alias data
wgn <- webglobe(immediate=FALSE) #Webglobe is not displayed
Sys.sleep(0) #No need to wait
#Note that we have to store commands
wgn <- wgn + wgpoints( q$lat, q$lon) #Nothing shown yet
wgn <- wgn + wgpoints(-q$lat, -q$lon) #Nothing shown yet
wgn <- wgn + wgcamcenter(2.89,-175.962,21460) #Nothing shown yet
wgn + wgimmediate() #Make it all immediate
wgn
wgn + wgpoints(q$lat, -q$lon) #This is shown right away
#Reloading the browser window keeps everything up to `wgimmediate()`

Installation
-----------------------------

webglobe **hopefully will be** available from CRAN via:

install.packages('webglobe')

If you want your code to be as up-to-date as possible, you can install it using:

library(devtools) #Use `install.packages('devtools')` if need be
install_github('r-barnes/webglobe', vignette=TRUE)

Developer Notes
-----------------------------

**How To Add Functionality**

There are really only two files that are import to contributing developers:
[inst/client/webglobe.js](inst/client/webglobe.js)
and
[R/webglobe.R](R/webglobe.R)
.

The package uses a JSON websocket message passing scheme to communicate data
between R and the JavaScript client.

Each `wg*()` function generates a JSON payload as follows:

toString(jsonlite::toJSON(list(
command = jsonlite::unbox("COMMAND_NAME"), #Required
lat = lat, #Example
lon = lon #Example
)))

The payload consists of a `command` and accompanying data.

For more complex data, `geojsonio` can be leveraged to conveniently encode the
data. However, the resulting GeoJSON must be decoded, so that the whole packae
can be sent with only one level of encoding, as follows:

toString(jsonlite::toJSON(list(
command = jsonlite::unbox("polygons"),
polys = jsonlite::fromJSON(geojsonio::geojson_json(df, group='group', geometry='polygon'))
)))

On the JavaScript side, look for an object named `router`. `router` contains a
variety of fields which correspond to command names. To add a new command, add a
field with a corresponding function, such as:

points: function(msg){
var points = viewer.scene.primitives.add(new Cesium.PointPrimitiveCollection());
for(var i=0;i