- Code
- Sharing your maps with others
- Leaflet maps in R
- Interactive Mapping (the basics)
- Stepping it up with leaflet maps
CODE:
Get the code used in the workflow described here and more
Sharing your maps with others
Producing maps is fun. Funner still is sharing them with your peers. You could do this by printing them out and sharing that way. Alternatively you could share them via customized interactive mapping products that can be visualized within a web browser.
Some notes about how to do this using R are given in our book.
I wanted to teach myself how i might be able to embed these interactive maps into a website, so i created an example to help me.
Interactive mapping makes sharing your data with colleagues simpler, and importantly improves the visualization experience via customization features.
The interactive mapping is made possible via the Leaflet
R package. Leaflet
is one of the most popular open-source JavaScript libraries for interactive maps. The Leaflet
R package makes it easy to integrate and control Leaflet
maps in R
. More detailed information about Leaflet can be found here, and information specifically about the R package is here.
Leaflet maps in R
There is a common workflow for creating Leaflet
maps in R.
- Creation of a map widget (calling)
- Adding of layers or features to the map by using layer functions (e.g.
addTiles
,addMarkers
,addPolygons
) to modify the map widget. - The map can then be printed and visualized in the R image window or saved to HTML file for visualization within a web browser or even embed it into a website like the one you are reading.
The following R script is a quick taste of creating an interactive Leaflet map. It is assumed that the leaflet
and magrittr
packages are installed.
First lets get our workflow initialised by loading up our R packages.
# Required R Packages
library(leaflet);library(magrittr)
library(ithir)
library(sf);library(terra)
library(RColorBrewer)
library(htmlwidgets)
We will be working with a small data set of soil information that was collected from the Hunter Valley, NSW in 2010 called HV100
. This data set is contained in the ithir
package.
If you have never been exposed to handling spatial data within the R
environment it would pay to look at introductory notes on this website regarding working with point and raster data and other cited helpful resources therein. The code below is what was covered there and will get you to the point where we can start doing the real work of interactive mapping with leaflet
. You can also download the code directly.
### load POINT data
data(HV100)
# get data frame into a spatial object
HV100 <- sf::st_as_sf(x = HV100,coords = c("x", "y"))
# establish the coordinate reference system
sf::st_crs(HV100) <- "+init=epsg:32756"
## Coordinate transformation (this is needed for doing the leaflet mapping).
HV100.ll <- sf::st_transform(x = HV100, crs = 4326)
### load RASTER data
data(HV_dem)
## convert data to raster object and CRS definition
r.DEM <- terra::rast(x = HV_dem, type = "xyz")
crs(r.DEM) <- "+init=epsg:32756"
## raster reprojection
p.r.DEM <- terra::project(x = r.DEM, y = "+init=epsg:4326", method = "bilinear")
Interactive Mapping (the basics)
Now we have our data. Lets first provide an example of what is meant by an interactive map. Explanation is to follow.
leaflet() %>%
addMarkers(lng = 151.210558, lat = -33.852543, popup = "The view from here is amazing!") %>%
addProviderTiles("Esri.WorldImagery")
Interactive features of this map include markers with text, plus ability to zoom and map panning. More will be discussed about the layer functions of the leaflet map further on.
If you look at the R
code supplied with this example, you will note the following code snippet:
m1<- leaflet() %>%
addMarkers(lng = 151.210558, lat = -33.852543, popup = "The view from here is amazing!") %>%
addProviderTiles("Esri.WorldImagery")
m1
# Save the object so that it can be embedded into website when called
# Size appropriately
m1$height<- 500
m1$width<- 700
# Save the HTML widget
library(htmlwidgets)
htmlwidgets::saveWidget(m1, file="~/m1.html")
First is the assignment of the leaflet
map to an object, here, m1
. Then the snippet moves to using the the htmlwidgets
package the create the html
file which can then be embedded into a webpage when called. Note there are sizing options too to help with map customization. There are likely several other options available to you for further alterations as desired.
Moving on, what has not been encountered yet is the forward pipe operator %>%
. This operator will forward a value, or the result of an expression, into the next function call or expression. To use this operator the magrittr
package is required. The example script below shows the same example using and not using the
forward pipe operator.
#Draw 100 random uniformly distributed numbers between 0 and 1
x <- runif(100)
sqrt(sum(range(x)))
## [1] 1.005229
##..is equivalent to (using forward pipe operator)
x %>% range %>% sum %>% sqrt
## [1] 1.005229
Sometimes what we want to do in R
can get lost within a jumble of brackets, whereas using the forward pipe operator the process of operations is a lot clearer.
Stepping it up with leaflet
maps
So lets begin to construct some Leaflet mapping using our prepared data from a little earlier regarding the point (HV100.ll
) and raster data (p.r.DEM
).
Firstly, lets create a basic map — example of not using and then using the forward pipe operator. Also note and assume the creation of the html widgets as demonstrated just before are replicated for the following maps displayed on this webpage.
# Basic map
# without piping operator
addMarkers(addTiles(leaflet()), data = HV100.ll)
# with forward pipe operator
leaflet() %>%
addTiles() %>%
addMarkers(data = HV100.ll)
With the above, we are calling upon a pre-existing base map via the addTiles()
function. Leaflet supports base maps using map tiles, popularized by Google Maps and now used by nearly all interactive web maps.
By default, OpenStreetMap tiles are used. Alternatively, many popular free third-party base maps can be added using the addProviderTiles()
function, which is implemented using the leaflet-providers plugin. For example, previously we used the Esri.WorldImagery
base mapping. The full set of possible
base maps can be found
here. Note that an internet connection is required for access to the base maps and map tiling.
The last function used above the the addMarkers
function, we we simply call up the point data we used previously, which are those soil point observations and measurements from the Hunter
Valley, NSW. A basic map will have been created with your plot window.
For the next step, lets populate the markers we have created with some of the data that was measured, then add the Esri.WorldImagery
base mapping.
# Populate pop-ups
my_pops <- paste0(
"<strong>Site: </strong>",
HV100.ll$site,
'<br>
<strong> Organic Carbon (%): </strong>',
HV100.ll$OC,
'<br>
<strong> soil pH: </strong>',
HV100.ll$pH)
# Create interactive map
leaflet() %>%
addProviderTiles("Esri.WorldImagery") %>%
addMarkers(data = HV100.ll, popup = my_pops)
Further, we can colour the markers and add a map legend. Here we will get the quantiles of the measured SOC percentage and color the markers accordingly. Note that you will need the colour ramp package RColorBrewer
installed.
# Colour ramp
pal1 <- colorQuantile("YlOrBr", domain = HV100.ll$OC)
# Create interactive map
leaflet() %>%
addProviderTiles("Esri.WorldImagery") %>%
addCircleMarkers(data = HV100.ll, color = ~pal1(OC), popup = my_pops) %>%
addLegend("bottomright", pal = pal1, values = HV100.ll$OC,
title = "Soil Organic Carbon (%) quantiles", opacity = 0.8)
It is very worth consulting the help files associated with the leaflet
R package for further tips on creating further customized maps. The website dedicated to that package, which was mentioned above is also a very helpful resource too.
Raster maps can also be featured in our interactive mapping too, as illustrated in the following script.
#Colour ramp
pal2 <- colorNumeric(
brewer.pal(n = 9, name = "YlOrBr"),
domain = values(p.r.DEM),
na.color = "transparent")
#interactive map
leaflet() %>%
addProviderTiles("Esri.WorldImagery") %>%
addRasterImage(p.r.DEM, colors = pal2, opacity = 0.7) %>%
addLegend("topright", opacity=0.8, pal = pal2, values = values(p.r.DEM), title = "Elevation"))
Lastly, we can create an interactive map that allows us to switch between the different mapping that we have created.
#layer switching
leaflet() %>%
addTiles(group = "OSM (default)") %>%
addProviderTiles("Esri.WorldImagery") %>%
addCircleMarkers(data = HV100.ll, color = ~pal1(OC),
group = "points", popup = my_pops) %>%
addRasterImage(p.r.DEM, colors = pal2,group = "raster",
opacity = 0.8) %>%
addLayersControl( baseGroups = c("OSM (default)", "Imagery"), overlayGroups = c("points", "raster"))
With the created interactive mapping, we can then export these as a web page in HTML format. This can be done using saveWidget
from the htmlwidgets
package described earlier or via the export menu within the R-Studio plot window, where you want to select the option for Save as Web page
. This file can then be easily shared and viewed by your colleagues.