Chapter 5 Transforming spatial data to 3D forms

  • What tools exist to convert data to meshes in R?
  • What forms of mesh data are available?

The key package is rgl, the OpenGL package for R. This tends to be very low level, but has improved helpers and is becoming easier to use. The key functions are plot3d(), lines3d() and points3d() and these are used just like the 2D base funtions in R (with the ‘3d’ on the end).

For polygons we first need to create triangles, and then use triangle3d(). For rasters we can create triangles or quads, and use quads3d(). There is also a mesh type object, mesh3d to store data with material properties. To plot mesh3d we use the shade3d() function.

5.1 Algorithms

Converting points to 3D is really trivial, we only need the X-Y-Z coordinates, and we can set properties directly on them.

Converting lines is also relatively easy, but here we might use a path model, sequential lists of coordinates that imply a connected line, or a segments model where every single individual line segment is specified separately. The segment model is really a mesh, because we have the opportunity to store every coordinate just once and refer to segments by their index.

Converting polygons is much harder, and there are multiple ways to do it. The main division is by near-Delaunay triangulation, or by ear-cutting algorithms.

  • near-Delaunay - high quality triangulations, suitable for surface modelling
  • ear-cutting - low quality triangulation, suitable for flat surfaces

The main tools available for geospatial data:

  • quadmesh (on CRAN) - convert any raster to mesh3d quads, optionally with image textures
  • anglr (not on CRAN) - convert any sp, sf lines or polygons to mesh3d triangles

The rgl package has ear-cutting in triangulate3d().

The sfdct package (via RTriangle) has near-Delaunay in ct_triangulate()

The decido package has ear-cutting in earcut().

Converting raster data is available in various ways.

  • rgl::surface3d(), this is analogous to the old base image() function that can take x, y, z = matrix
  • quadmesh::quadmesh(), converts raster, matrix, some stars to mesh3d
  • rayshader determines elevation colouring from a matrix, and has many plotting helpers, and the best looking 3D plots and animations

5.2 raster

A straightforward way to convert a raster layer to rgl mesh3d (cell values are Z-coordinate) is quadmesh.

5.3 vector

Lines, and polygons in spatial classes can be converted using the anglr package.

plot3d() will create the rgl plot and return a mesh3d() object

as.mesh3d() will convert the object directly (very much in-development)

The approach to converting polygons to mesh uses the functions TRI() or DEL() both produce triangulations, one with ear-cutting and one with “constrained Delaunay” methods. These aren’t ready for general use, so as.mesh3d() and plot3d() are the recommended ways to use the tools for now.

5.4 Image textures

Image-textures is a very powerful way to map imagery onto a surface, the surface can be created from a raster or polygons, and can use quad or triangle primitives.

The concept of texturing has some abstract details to it, but amounts to defining the 0,1 , 0,1 pixel index of the image on the vertices of the mesh. These are defined as $texcoords on the mesh3d object.

Consider a simplified volcano data set as a quadmesh.

The 2D plot above can be emulated in 3D with quad textures, the resolution of the image and the surface can be completely different.

## writing texture image to /rdsi/PRIVATE/raad/dev/__tmp_mike/Rtmpbyz5Eb/file9e344b44780.png

This section requires a Mapbox API key to run from scratch - and can’t be shared directly, so it will simply be illustrated.

The process is a little complicated, but the key is that the elevation raster provides a space in which to map other data too. In this case the raster is in Mercator, and the image is as well. Under the hood we have to map the spatial part of the image into 0, 1, 0, 1 space of a PNG image, but in the final event we get a scene where real-world data may be added directly.

5.5 Triangles or quads from geospatial

This is my work-in-progress approach to meshing any polygon data structure with raster elevation.

This is pseudo code but a real example is used with the North Carolina counties data set in the examples.

5.6 Various other 3D tools in R

  • rgl::triangulate and decido::earcut will triangulate polygons with holes but only suitable for plane-filling, because ugly triangles, no control over size and shape.

  • RTriangle::triangulate (and sfdct::ct_triangulate) do high-quality “near-Delaunay” triangulations

  • quadmesh::quadmesh() to create rgl-ready mesh3d from a raster

  • cubeview::cubeView() does very compelling interactive raster-cube visualization

  • mapdeck::mapdeck() a 3D viewer using Uber’s deck.gl

  • deckgl package, another package using deck.gl

  • threejs - 3D visualization with the ‘three.js’ library

  • rayshader - very compelling 3D visualization and animation from matrix height map

  • tylermorganwall/rayrender - general 3D scene creation, animation

  • Rvcg package on CRAN has a number of mesh-processing and visualization tools

  • hypertidy/silicate, hypertidy/anglr - these are evolving together

  • short workshop on using A-Frame Virtual Reality with geospatial data: https://github.com/MilesMcBain/gis_vs_web3D

  • coolbutuseless/threed - transformations on 3D objects