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.core::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.core::idw`

; default),`Gaussian`

for kernel smoothing (as`spatstat.core::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.

## 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`

.

## 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) {
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) {
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) {
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) {
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) {
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)
}
```