Skip to contents

Adds a colour-coded surface of spatial objects (polygons, lines, or points generated by extract_osm_objects to a graphics object initialised with osm_basemap. The surface is spatially interpolated between the values given in dat, which has to be a matrix of data.frame of 3 columns (x, y, z), where (x,y) are (longitude, latitude), and z are the values to be interpolated. Interpolation uses spatstat.explore::Smooth.ppp, which applies a Gaussian kernel smoother optimised to the given data, and is effectively non-parametric.

Usage

add_osm_surface(
  map,
  obj,
  dat,
  method = "idw",
  grid_size = 100,
  cols = heat.colors(30),
  bg,
  size,
  shape
)

Arguments

map

A ggplot2 object to which the surface are to be added

obj

An sp SpatialPolygonsDataFrame or SpatialLinesDataFrame (list of polygons or lines) returned by extract_osm_objects

dat

A matrix or data frame of 3 columns (x, y, z), where (x, y) are (longitude, latitude), and z are the values to be interpolated

method

Either idw (Inverse Distance Weighting as spatstat.explore::idw; default), Gaussian for kernel smoothing (as spatstat.explore::Smooth.ppp), or any other value to avoid interpolation. In this case, dat must be regularly spaced in x and y.

grid_size

size of interpolation grid

cols

Vector of colours for shading z-values (for example, terrain.colors (30))

bg

If specified, OSM objects outside the convex hull surrounding dat are plotted in this colour, otherwise they are included in the interpolation (which will generally be inaccurate for peripheral values)

size

Size argument passed to ggplot2 (polygon, path, point) functions: determines width of lines for (polygon, line), and sizes of points. Respective defaults are (0, 0.5, 0.5). If bg is provided and size has 2 elements, the second determines the size of the background objects.

shape

Shape of lines or points, for details of which see ?ggplot::shape. If bg is provided and shape has 2 elements, the second determines the shape of the background objects.

Value

modified version of map to which surface has been added

Note

Points beyond the spatial boundary of dat are included in the surface if bg is not given. In such cases, values for these points may exceed the range of provided data because the surface will be extrapolated beyond its domain. Actual plotted values are therefore restricted to the range of given values, so any extrapolated points greater or less than the range of dat are simply set to the respective maximum or minimum values. This allows the limits of dat to be used precisely when adding colourbars with add_colourbar.

See also

osm_basemap, add_colourbar.

Other maps-with-data: add_osm_groups()

Examples

# Get some data
bbox <- get_bbox (c (-0.13, 51.5, -0.11, 51.52))
# dat_B <- extract_osm_objects (key = 'building', bbox = bbox)
# These data are also provided in
dat_B <- london$dat_BNR # actuall non-residential buildings
# Make a data surface across the map coordinates, and remove periphery
n <- 5
x <- seq (bbox [1, 1], bbox [1, 2], length.out = n)
y <- seq (bbox [2, 1], bbox [2, 2], length.out = n)
dat <- data.frame (
    x = as.vector (array (x, dim = c (n, n))),
    y = as.vector (t (array (y, dim = c (n, n)))),
    z = x * y
)
if (FALSE) { # \dontrun{
map <- osm_basemap (bbox = bbox, bg = "gray20")
map <- add_osm_surface (map, dat_B, dat = dat, cols = heat.colors (30))
print_osm_map (map)
} # }

# If data do not cover the entire map region, then the peripheral remainder
# can be plotted by specifying the 'bg' colour. First remove periphery from
# 'dat':
d <- sqrt ((dat$x - mean (dat$x))^2 + (dat$y - mean (dat$y))^2)
dat <- dat [which (d < 0.01), ]
if (FALSE) { # \dontrun{
map <- osm_basemap (bbox = bbox, bg = "gray20")
map <- add_osm_surface (
    map,
    dat_B,
    dat = dat,
    cols = heat.colors (30),
    bg = "gray40"
)
print_osm_map (map)
} # }

# Polygons and (lines/points) can be overlaid as data surfaces with different
# colour schemes.
# dat_HP <- extract_osm_objects (key = 'highway',
#                                value = 'primary',
#                                bbox = bbox)
# These data are also provided in
dat_HP <- london$dat_HP
cols <- adjust_colours (heat.colors (30), adj = -0.2) # darken by 20%
if (FALSE) { # \dontrun{
map <- add_osm_surface (
    map,
    dat_HP,
    dat,
    cols = cols,
    bg = "gray60",
    size = c (1.5, 0.5)
)
print_osm_map (map)
} # }

# Adding multiple surfaces of either polygons or (lines/points) produces a
# 'ggplot2' warning, and forces the colour gradient to revert to the last
# given value.
dat_T <- london$dat_T # trees
if (FALSE) { # \dontrun{
map <- osm_basemap (bbox = bbox, bg = "gray20")
map <- add_osm_surface (
    map,
    dat_B,
    dat = dat,
    cols = heat.colors (30),
    bg = "gray40"
)
map <- add_osm_surface (
    map,
    dat_HP,
    dat,
    cols = heat.colors (30),
    bg = "gray60",
    size = c (1.5, 0.5)
)
map <- add_osm_surface (
    map,
    dat_T,
    dat,
    cols = topo.colors (30),
    bg = "gray70",
    size = c (5, 2),
    shape = c (8, 1)
)
print_osm_map (map) # 'dat_HP' is in 'topo.colors' not 'heat.colors'
} # }

# Add axes and colourbar
if (FALSE) { # \dontrun{
map <- add_axes (map)
map <- add_colourbar (
    map,
    cols = heat.colors (100),
    zlims = range (dat$z),
    barwidth = c (0.02),
    barlength = c (0.6, 0.99),
    vertical = TRUE
)
print_osm_map (map)
} # }