14 Creating Cropped 3d rayshader Models

As well as viewing the “full” scene using a 3D rayshader model, the rayshader package provides us with a baseshape parameter to the rayshader::plot_3d()` function that allows us to crop the view to a particular shape.

We can also use a manual cropping technique to crop the extent of the model we wish to render.

14.1 Load in Base Data

As ever, let’s load in our stage data:

library(tidyr)

geojson_filename = 'montecarlo_2021.geojson'
geojson_sf = sf::st_read(geojson_filename)
## Reading layer `montecarlo_2021' from data source `/Users/tonyhirst/Documents/GitHub/visualising-rally-stages/montecarlo_2021.geojson' using driver `GeoJSON'
## Simple feature collection with 9 features and 2 fields
## geometry type:  LINESTRING
## dimension:      XY
## bbox:           xmin: 5.243488 ymin: 43.87633 xmax: 6.951953 ymax: 44.81973
## geographic CRS: WGS 84
stage_bbox = sf::st_bbox(geojson_sf)

We have already seen how we can overlay an elevation model raster on a leaflet map, as well as rendering two dimensional topographic models using the raytracer package.

The raytracer package itself works with a matrix of raster values. Having saved the download raster to a tif file, we can load the data back in from and convert it to a matrix using the rayshader::raster_to_matrix() function:

library(rayshader)
library(raster)

# Previously downloaded TIF digital elevation model (DEM) file
stage_tif = "buffered_stage_elevation.tif"

# Load in the previously saved image raster
elev_img = raster(stage_tif)

# Get the natural zscale
auto_zscale = geoviz::raster_zscale(elev_img)

# Note we can pass in a file name or a raster object
elmat = raster_to_matrix(stage_tif) 
options(rgl.useNULL = TRUE,
        rgl.printRglwidget = TRUE)

Let’s create a demo map that we can use as as test piece:

demo_map = elmat %>%
              sphere_shade(texture = "desert") %>%
              add_water(detect_water(elmat, progbar = FALSE),
                        color = "desert")

14.2 Cropping the Rendered 3D View

We can crop the rendered 3D view according to three predefined shapes: circle, hex, or the rectangle default.

# Additional baseshape parameter can be: circle, hex, or rectangle
library(rgl)

options(rgl.useNULL = FALSE,
        rgl.printRglwidget = FALSE)
#rgl::rgl.open()
rgl::clear3d()
demo_map %>%
      plot_3d(elmat, zscale = 10,
              baseshape="circle")

#rgl::rgl.close()
rgl::rglwidget()