Interactive maps are a great way to present geospatial data, allowing
people to zoom, pan, and click on results. leaflet
is an
R
library for making interactive maps built on top of a
JavaScript mapping library called Leaflet. The results of queries made
using the osdatahub
package are returned in GeoJSON format,
which is an ideal input for interactive mapping libraries with
JavaScript underpinnings, and the OS Maps API can supply tiles for
basemaps giving that all important context to your data.
library(osdatahub)
library(leaflet)
library(sf)
The example uses NGD Water features to show how to plot the API results onto an interactive map and provide additional information about the data to users through popups.
# Choose data
<- 'wtr-fts-water-1'
collection
# Define query extent. leaflet maps expect shapes in WGS 1984,
# the extent is specified in degrees longitude and latitude
<- -1.328
W <- 50.979
S <- -1.322
E <- 50.9815
N
<- 'CRS84'
crs <- extent_from_bbox(c(W, S, E, N), crs = crs)
extent
# Query API
<- query_ngd(extent,
surface_water collection = collection,
crs = crs,
max_results = 100000)
The first step in creating a leaflet map is to create a map object. This defines the location in view when the map first loads. Leaflet maps always use coordinates in the WGS84 coordinate reference system, so the starting location must be specified in degrees latitude and longitude.
# m is the map object all other layers will be added to.
<- leaflet() %>%
m setView(lng = -1.325, lat = 50.98, zoom = 16)
This defines the base map. You can access base map tiles via the OS Maps API. By adding the Maps API to the same project as the NGD Features API, you can use the same key for both. To find out more about API keys, check out the “Setting up an API key” example.
<- 'Outdoor_3857'
LAYER <- paste0('Contains OS data © Crown copyright and database right ',
ATTR format(Sys.Date(), "%Y"))
<- m %>% addTiles(urlTemplate = paste0('https://api.os.uk/maps/raster/v1/zxy/',
m
LAYER ,'/{z}/{x}/{y}.png?key=',
get_os_key()),
attribution = ATTR,
group = 'OS Maps Outdoor')
Add the API results to the map with a popup showing the area of each
polygon. It’s possible to add a simple overlay using
addGeoJSON()
; however, it’s easier if the query results are
parsed to create an sf
object. This will give us more
control to add a popup to each feature.
<- st_read(surface_water, crs = st_crs('CRS:84'), quiet = TRUE)
df <- paste0('Area (m2):', round(df$geometry_area, 1))
popup
<- m %>%
m addPolygons(data = df,
group = 'Surface Water',
popup = popup)
<- extent$polygon
bbox
# Add the bounding box to the map.
<- m %>%
m addPolygons(data = bbox,
group = 'Bounding Box',
fill = FALSE,
color = 'black',
opacity = 0.9,
weight = 1.2,
dashArray = 10)
# Add ability to toggle layers
<- m %>% addLayersControl(overlayGroups = c("OS Maps Outdoor", "Surface Water", "Bounding Box"))
m
# View the map
m