Learn R Programming

Geoviz

Helper functions to draw 'rayshader' scenes.

  • Using elevation data from 'Mapzen' and 'Mapbox'
  • With map and satellite overlays
  • Blending between different overlays at different altitudes
  • with added GPS tracks
  • From EU Copernicus, NASA ASTER or any other DEM (Digital Elevation Model) data
  • With elevation shading (green valleys and snow capped peaks, or anything else you want)

'Rayshader' is an awesome bit of kit! I'm just doing some colouring in.

Installing

geoviz is on CRAN:

install.packages("geoviz")

Or for the latest development version:

devtools::install_github("neilcharles/geoviz")

Read news to understand the latest updates and bug fixes.

Geoviz helps you to draw images like these.

Example

library(geoviz)
library(rayshader)

#Load an example IGC (GPS track log) file

igc <- example_igc()

#Load a small example elevation raster showing a piece of the English Lake district

DEM <- example_raster()

sunangle = 270

zscale = 25

#Get a Stamen map that will cover our DEM

stamen_overlay <- slippy_overlay(DEM, image_source = "stamen", image_type = "watercolor", png_opacity = 0.3)

#Make an elevation shading layer with dark valleys and light peaks (not essential but I like it!)

elevation_overlay <- elevation_shade(DEM, elevation_palette = c("#000000", "#FFFFFF"), png_opacity = 0.6)


#Calculate the 'rayshader' scene (see 'rayshader' documentation)

elmat = matrix(
  raster::extract(DEM, raster::extent(DEM), method = 'bilinear'),
  nrow = ncol(DEM),
  ncol = nrow(DEM)
)

scene <- elmat %>%
  sphere_shade(sunangle = sunangle, texture = "bw") %>% 
  add_overlay(elevation_overlay) %>%
  add_overlay(stamen_overlay)


#Render the 'rayshader' scene

rayshader::plot_3d(
  scene,
  elmat,
  zscale = zscale,
  solid = FALSE,
  shadow = TRUE,
  shadowdepth = -100
)


#Add the gps track

add_gps_to_rayshader(
  DEM,
  igc$lat,
  igc$long,
  igc$altitude,
  line_width = 1.5,
  lightsaber = TRUE,
  colour = "red",
  zscale = zscale,
  ground_shadow = TRUE
)

Quick access to digital elevation model data

To draw scenes using sub 2m resolution DEM's, you'll need to download your own data (see below), but geoviz also has helpful functions to obtain DEM data from Mapbox and Mapzen. Mapzen doesn't require an API key and gives access to higher resolution data, depending on where in the world you request.


library(rayshader)
library(geoviz)

mapbox_key <- "YOUR MAPBOX KEY"

lat <- 54.4502651
long <- -3.1767946
square_km <- 20

#Get elevation data from Mapbox
dem <- mapbox_dem(lat, long, square_km, api_key = mapbox_key)

#Note: You can get elevation data from Mapzen instead, which doesn't require an API key.
#You'll still need an API key for any mapbox image overlays.
#Get a DEM from mapzen with:
#dem <- mapzen_dem(lat, long, square_km)

#Get an overlay image (Stamen for this example because it doesn't need an API key)
overlay_image <-
  slippy_overlay(dem, image_source = "stamen", image_type = "watercolor", png_opacity = 0.5)

#Optionally, turn mountainous parts of the overlay transparent
overlay_image <-
  elevation_transparency(overlay_image,
                        dem,
                        pct_alt_high = 0.5,
                        alpha_max = 0.9)


#Draw the 'rayshader' scene
elmat = matrix(
  raster::extract(dem, raster::extent(dem), method = 'bilinear'),
  nrow = ncol(dem),
  ncol = nrow(dem)
)

scene <- elmat %>%
  sphere_shade(sunangle = 270, texture = "desert") %>% 
  add_overlay(overlay_image)

rayshader::plot_3d(
  scene,
  elmat,
  zscale = raster_zscale(dem),
  solid = FALSE,
  shadow = TRUE,
  shadowdepth = -150
)

# You can also visualise your data in ggplot2 rather than 'rayshader'.

gg_overlay_image <-
  slippy_overlay(
    dem,
    image_source = "stamen",
    image_type = "watercolor",
    return_png = FALSE
  )

ggplot2::ggplot() +
  ggslippy(gg_overlay_image)

Handling digital elevation model data

DEM files can be downloaded from various sources, usually in .asc or .tif format. Often, they will be small files that need to be stitched together to render the scene that you want.

If you have downloaded a set of DEM files, use mosaic_files() to create a single raster for use with 'rayshader'. The mosaic_files() function is flexible and will accept a directory of files or zipped files, using any naming convention and file extension.

mosaic_files(
  "path/to/zip/files",
  extract_zip = TRUE,
  file_match = ".*.TIF",
  raster_output_file = "mosaic_out.raster"
)

raster_mosaic <- raster::raster("mosaic_out.gri")

DEM data sources

The following is by no means an exhaustive list of data sources, but it will get you started.

EU Copernicus

EU coverage.

Copernicus map tiles are large, typically 3-5GB each and covering a country sized area. Download Copernicus

zscale <- 25

OS Terrain 50

UK coverage. Copernicus also covers the UK and comes as a single file covering the whole UK if you want to use that instead.

Download OS Terrain 50

mosaic_files(
  "path/to/zip/files",
  extract_zip = TRUE,
  zip_file_match = ".*GRID.*.zip"
  file_match = ".*.asc",
  raster_output_file = "mosaic_out.raster"
)

raster_mosaic <- raster::raster("mosaic_out.gri")

zscale <- 50

NASA ASTER

Whole world coverage but quite noisy. Copernicus is better if you're mapping in the EU.

Download NASA Aster. Search for "ASTER" in the top left box and select "ASTER Global Digital Elevation Model V002" underneath the map. You won't realistically be able to stitch together a single file of the whole world - it would be enormous - so just download the areas you need.

Stitching together the separate files is the same process as for OS Terrain 50.

zscale <- 30

Slicing pieces out of the DEM

You probably don't want to render everything in your DEM data, you'll want to cut out a piece. Geoviz has two functions to help you do this.

Crop out a square around a point...


library(ggmap)

register_google(key = your_google_key)

#Note that the below will only work if you point it at DEM data that contains Keswick! 

coords <- geocode("Keswick, UK")

DEM <- crop_raster_square(big_DEM, coords$lat, coords$lon, square_km)

Or crop a section from your DEM to fit a GPS track...


igc <- example_igc()

DEM <- crop_raster_track(example_raster(), igc$lat, igc$long, width_buffer = 2)

Loading GPS tracks

You can load GPS track data any way that you like and pass decimal lat-longs as vectors to geoviz functions (see code examples above).

If your GPS data is in IGC format - commonly used for glider flight data - then geoviz has a function read_igc(), which will do all the formatting work for you.

If your GPS data is in .gpx format, the plotKML package has a handy function readGPX().

igc <- read_igc("path/to/your/file.igc")

Adding GPS traces to 'rayshader' scenes

Geoviz converts decimal lat-long GPS traces into the 'rayshader' coordinate system and then plots the GPS track using the function add_gps_to_rayshader(). Rather than adding a trace to a scene, if you just want to convert lat-long points into 'rayshader' coordinates and see the converted data (e.g. so you can add your own rgl shapes to the scene or for use with 'rayshder' render_label() function), use latlong_to_rayshader_coords().

Copy Link

Version

Install

install.packages('geoviz')

Monthly Downloads

28

Version

0.2.2

License

GPL-3

Issues

Pull Requests

Stars

Forks

Maintainer

Neil Charles

Last Published

January 12th, 2020

Functions in geoviz (0.2.2)

raster_zscale

Approximates the zscale of a raster Digital Elevation Model for 'rayshader'
%>%

Pipe operator
mosaic_files

Stitches together files into a single raster Requires a target directory of files that can be read with raster::raster(), e.g. .asc files, or a directory of .zip files containing these files
ggslippy

Adds a layer created using slippy_overlay() or slippy_raster() to a 'ggplot2' chart
latlong_to_rayshader_coords

Converts WGS84 lat long points into 'rayshader' coordinates. Useful for adding arbitrary points and text to a 'rayshader' scene.
read_igc

Load an IGC file
slippy_raster

Creates a square raster centred on any lat long point, or a rectangular raster surrounding a set of lat long points from 'Mapbox', 'Mapzen' or 'Stamen' Maps using the 'slippymath' package
slippy_overlay

Creates an overlay image from 'Mapbox' or 'Stamen' Maps using the 'slippymath' package
mapzen_dem

Gets Digital Elevation Model (DEM) data from 'mapzen' via 'Amazon Public Datasets'
mapbox_dem

Gets Digital Elevation Model (DEM) data from 'mapbox'
elevation_shade

Produces an elevation shaded image from a raster
example_igc

Returns an example IGC file using read_igc()
elevation_transparency

Turns overlay images transparent based on altitude. Can be used to create an image overlay that will only apply to valleys, or only to hills.
add_gps_to_rayshader

Adds a GPS trace to a 'rayshader' scene
crop_raster_square

Crops a raster and returns a smaller square raster
dplyr_data

.data to allow column name use in dplyr
crop_raster_track

Crops a raster into a rectangle surrounding a set of lat long points
get_slippy_map

Obtains and merges map tiles from various sources using the 'slippymath' package
example_raster

Returns an example digital elevation model raster file()
drybrush

Simulates a dry brushing effect. Differs from elevation_transparency() in that colour is applied based on local altitude peaks, not across the whole raster