Leaflet is an open-source JavaScript library for mobile-friendly interactive maps. We can make interactive panning/zooming and overlay object on maps:
We can embed maps in R Markdown documents and Shiny apps. We can embed maps into websites.
We can render spatial objects from the sp or sf packages, or data frames with latitude/longitude columns.
With leftlet
grammar, we can build a set of overlays with the magrittr
pipe operator (%>%
).
Consult the documentation and the website for the specifics.
Let’s build the first map and limit the zoom in.
Montréal, Jacques-Cartier
library(leaflet)
##
## Attachement du package : 'leaflet'
## L'objet suivant est masqué depuis 'package:xts':
##
## addLegend
<- leaflet(options = leafletOptions(minZoom = 0, maxZoom = 13)) %>%
m addTiles() %>% # add default OpenStreetMap map tiles
addMarkers(lng=-73.546428, lat=45.522660,
popup="Montréal, Jacques-Cartier",
label = "lng=-73.546428, lat=45.522660")
# print the map m
Here is the equivalent without using pipes. We limit the zoom out.
library(leaflet)
<- leaflet(options = leafletOptions(minZoom = 10, maxZoom = 18))
m <- addTiles(m)
m <- addMarkers(m, lng=-73.546428, lat=45.522660,
m popup="Montréal, Jacques-Cartier",
label = "lng=-73.546428, lat=45.522660")
m
Center the view with coordinates with setView
.
library(leaflet)
<- leaflet() %>%
m addTiles() %>% # Add default OpenStreetMap map tiles
addMarkers(lng=-73.546428, lat=45.522660,
popup="Montréal, Jacques-Cartier",
label = "lng=-73.546428, lat=45.522660") %>%
setView(lng=-73.54, lat=45.52,
zoom = 15)
m
Frame the view with coordinates with fitBounds
. We can clear the bounds with clearBounds()
.
library(leaflet)
<- leaflet() %>%
m addTiles() %>% # Add default OpenStreetMap map tiles
addMarkers(lng=-73.546428, lat=45.522660,
popup="Montréal, Jacques-Cartier",
label = "lng=-73.546428, lat=45.522660") %>%
fitBounds(-73, 45, -74, 46)
m
library(htmlwidgets)
saveWidget(m, file="m.html")
We can load data from a data frame object (with lng/lat columns) or from the map()
function. We can also load sp
objects (SpatialPoints[DataFrame]
, Line/Lines
, SpatialLines[DataFrame]
, Polygon/Polygons
, SpatialPolygons[DataFrame]
). Calling addPolygons
on the map widget will know to add the polygons from that SpatialPolygonsDataFrame
.
There are 5 potential column names: lat, latitude, lng, long, longitude
.
Let’s generate a map with quasi-random coordinates.
library(leaflet)
# add some circles to a map
= data.frame(Lat = rep(45.5, 10), Long = rnorm(10)-73)
df df
leaflet(data = df) %>%
addTiles() %>%
addCircles()
We change the names.
library(leaflet)
# add some circles to a map
= data.frame(latitude = rep(45.5, 10), longitude = rnorm(10)-73)
df
leaflet(data = df) %>%
addTiles() %>%
addCircles()
Leftlet pulls rasters from OpenStreetMap by default.
library(leaflet)
<- leaflet() %>%
m setView(lng=-73.546428, lat=45.522660, zoom = 12)
%>%
m addTiles() # with no arguments; by default, OpenStreetMap
Many popular (free) third-party basemaps can be added.
Stamen.
library(leaflet)
%>%
m addProviderTiles(providers$Stamen.Toner)
library(leaflet)
%>%
m addProviderTiles(providers$Stamen.Watercolor)
CartoDB.
library(leaflet)
%>%
m addProviderTiles(providers$CartoDB.Positron)
NatGeoWorldMap.
library(leaflet)
%>%
m addProviderTiles(providers$Esri.NatGeoWorldMap)
Other providers: HERE, Mapbox, Esri/ArcGIS.
Consult this website to view the complete collection. Here is an overview:
We can also add a weather layer with addWMSTiles
and timezone layers.
We can stack basemaps by adding multiple tile layers. This generally only makes sense if the front tiles consist of semi-transparent tiles.
library(leaflet)
%>%
m addProviderTiles(providers$Stamen.Toner)
vs.
library(leaflet)
%>% addProviderTiles(providers$MtbMap) %>%
m addProviderTiles(providers$Stamen.TonerLines, options = providerTileOptions(opacity = 0.35)) %>%
addProviderTiles(providers$Stamen.TonerLabels)
<- data.frame(lieu = c('Jacques-Cartier', 'La Ronde', 'Parc Jean-Drapeau'),
data lng = c(-73.546428, -73.53447, -73.53323),
lat = c(45.522660, 45.52267, 45.5141))
data
Point data for markers can come from a variety of sources:
SpatialPoints
or SpatialPointsDataFrame
objects (sp
package).POINT
, sfc_POINT
, and sf
objects (sf
package); only X
and Y
dimensions.addMarkers(lng = ~Longitude, lat = ~Latitude))
; let the function look for columns named lat, latitude
and lon, lng, long, longitude
.library(leaflet)
leaflet(data) %>%
addTiles() %>%
addMarkers(~lng, ~lat,
popup = ~as.character(lieu),
label = ~as.character(lieu))
We can customize the markers. We can also use .jpg and .png files as symbols.
library(leaflet)
<- makeIcon(
redLeafIcon iconUrl = "http://leafletjs.com/examples/custom-icons/leaf-red.png",
iconWidth = 38, iconHeight = 95,
iconAnchorX = 22, iconAnchorY = 94,
shadowUrl = "http://leafletjs.com/examples/custom-icons/leaf-shadow.png",
shadowWidth = 50, shadowHeight = 64,
shadowAnchorX = 4, shadowAnchorY = 62
)
leaflet(data) %>%
addTiles() %>%
addMarkers(~lng, ~lat,
popup = ~as.character(lieu),
label = ~as.character(lieu),
icon = redLeafIcon)
We can add conditions (if, else if, else) to change the markers. Conditions are based on vectors in the data frame.
When there are a large number of markers on a map, you can cluster them using the clusterOptions = markerClusterOptions()
. For example, markerClusterOptions(freezeAtZoom = 5)
will freeze the cluster at zoom level 5 regardless of the user’s actual zoom level. We can see an example further down, in the With marker clusters section.
We can add circle markers. They can be empty circles or plain bubbles.
library(leaflet)
leaflet(data) %>%
addTiles() %>%
addCircleMarkers(~lng, ~lat,
popup = ~as.character(lieu),
label = ~as.character(lieu),
radius = 16,
color = 'blue',
stroke = TRUE,
fillOpacity = 0.3)
The radius
, color
, stroke
and fillOpacity
(and many more options) can be set by the data frame. We can add conditions (if, else if, else) as well.
We can write addresses, add comments, links, etc.
library(leaflet)
<- paste(sep = "<br/>",
content "<b><a href='https://en.wikipedia.org/wiki/Jacques_Cartier_Bridge'>Jacques-Cartier</a></b>",
"from Montreal Island, Montreal, Quebec,",
"to the south shore at Longueuil, Quebec, Canada,",
"crosses Île Sainte-Hélène,",
"access to the Parc Jean-Drapeau and La Ronde amusement park"
)
leaflet() %>%
addTiles() %>%
addPopups(lng=-73.546428, lat=45.522660,
content,options = popupOptions(closeButton = TRUE)
)
A label is a textual or HTML content that can be attached to markers to be displayed on mouse over. Unlike popups you don’t need to click a marker for the label to be shown.
htmlEscape
can be used to sanitize any characters in the name that might be interpreted as HTML; doing so is important in any situation where the data may come from a file or database, or from the user.
library(leaflet)
library(htmltools)
leaflet(data) %>%
addTiles() %>%
addMarkers(~lng, ~lat,
popup = ~htmlEscape(lieu),
label = ~htmlEscape(lieu))
We can customize marker labels using the labelOptions
argument of the addMarkers
function.
Line and polygon data can come from a variety of sources:
SpatialPolygons
, SpatialPolygonsDataFrame
, Polygons
, and Polygon
objects (sp
package)SpatialLines
, SpatialLinesDataFrame
, Lines
, and Line
objects (sp
package)MULTIPOLYGON
, POLYGON
, MULTILINESTRING
, and LINESTRING
objects (sf
package)map
objects (maps
package; use map(fill = TRUE)
for polygons, FALSE
for polylines.We can load shapefiles with the rgdal
, maptools
or PBSmapping
packages.
Let’s load a SpatialPolygonsDataFrame
: the distribution of sugar maple species (acer saccharum).
library(rgdal)
## Le chargement a nécessité le package : sp
## Please note that rgdal will be retired by the end of 2023,
## plan transition to sf/stars/terra functions using GDAL and PROJ
## at your earliest convenience.
##
## rgdal: version: 1.5-27, (SVN revision 1148)
## Geospatial Data Abstraction Library extensions to R successfully loaded
## Loaded GDAL runtime: GDAL 3.3.2, released 2021/09/01
## Path to GDAL shared files: /usr/share/gdal
## GDAL binary built with GEOS: TRUE
## Loaded PROJ runtime: Rel. 7.2.1, January 1st, 2021, [PJ_VERSION: 721]
## Path to PROJ shared files: /home/ugo/.local/share/proj:/usr/share/proj
## PROJ CDN enabled: FALSE
## Linking to sp version:1.4-5
## To mute warnings of possible GDAL/OSR exportToProj4() degradation,
## use options("rgdal_show_exportToProj4_warnings"="none") before loading sp or rgdal.
<- readOGR('data/acersacr.shp', GDAL1_integer64_policy = TRUE) acersacr
## OGR data source with driver: ESRI Shapefile
## Source: "/home/ugo/Documents/Projets_TI_R/ugodown_github/data/acersacr.shp", layer: "acersacr"
## with 441 features
## It has 5 fields
## Integer64 fields read as doubles: ACERSACR_ ACERSACR_I
When the shapefile has layers, we can specify which one with: layer = "cb_2013_us_state_20m"
for example. We can them subset the shapefile with neStates <- subset(states, states$STUSPS %in% c("CT","ME","MA","NH","RI","VT","NY","NJ","PA"))
.
library(leaflet)
leaflet(acersacr) %>%
addTiles() %>%
addPolygons(color = "gray",
weight = 1,
smoothFactor = 0.5,
opacity = 1.0,
fillOpacity = 0.5,
fillColor = "darkgreen",
highlightOptions = highlightOptions(color = "white", weight = 2, bringToFront = TRUE))
We can simplify complex polygons/polylines (reduce the size or number of bytes) with the rmapshaper
package.
We can set the size of circle markers.
<- data.frame(lieu = c('Jacques-Cartier', 'La Ronde', 'Parc Jean-Drapeau'),
data2 lng = c(-73.546428, -73.53447, -73.53323),
lat = c(45.522660, 45.52267, 45.5141),
priority = c(2, 2, 3))
data2
library(leaflet)
leaflet(data2) %>%
addTiles() %>%
addCircles(lng = ~lng, lat = ~lat,
weight = 1,
radius = ~(priority*2)**3,
popup = ~as.character(lieu),
label = ~as.character(priority),
color = 'blue',
stroke = TRUE,
fillOpacity = 0.3)
<- read.csv(textConnection("
cities City,Lat,Long,Pop
Boston,42.3601,-71.0589,645966
Hartford,41.7627,-72.6743,125017
New York City,40.7127,-74.0059,8406000
Philadelphia,39.9500,-75.1667,1553000
Pittsburgh,40.4397,-79.9764,305841
Providence,41.8236,-71.4222,177994
"))
library(leaflet)
leaflet(cities) %>% addTiles() %>%
addCircles(lng = ~Long, lat = ~Lat,
weight = 1,
radius = ~sqrt(Pop) * 30,
popup = ~City
)
We need 4 values.
library(leaflet)
leaflet() %>%
setView(lng=-73.546428, lat=45.522660, zoom = 12) %>%
addTiles() %>%
addRectangles(
lng1=-73.5, lat1=45.5,
lng2=-73.55, lat2=45.54,
fillColor = "transparent")
sp
objects or vector filesWe can pull the files from http://eric.clst.org/Stuff/USGeoJSON and https://en.wikipedia.org/wiki/List_of_United_States_counties_and_county_equivalents.
geojsonio
package to geojson_read
GeoJSON/TopoJSON as sp
objects.
geojsonio::geojson_read("json/nycounties.geojson", what = "sp")
.rgdal
package to readOGR
GeoJSON/TopoJSON as OGRGeoJSON
objects.
readOGR("json/nycounties.geojson", "OGRGeoJSON")
.Let’s run an example to show the size per county in the state of NY. The larger the county, the paler the colour.
library(rgdal)
<- readOGR("data/gz_2010_us_050_00_500k.json") xy
## OGR data source with driver: GeoJSON
## Source: "/home/ugo/Documents/Projets_TI_R/ugodown_github/data/gz_2010_us_050_00_500k.json", layer: "gz_2010_us_050_00_500k"
## with 3221 features
## It has 6 fields
names(xy)
## [1] "GEO_ID" "STATE" "COUNTY" "NAME" "LSAD"
## [6] "CENSUSAREA"
head(xy@data)
# NY state should be number 36
<- xy[xy$STATE == 36, ]
nyc head(nyc@data)
<- colorNumeric("viridis", NULL)
pal
library(leaflet)
leaflet(nyc) %>%
addTiles() %>%
addPolygons(stroke = FALSE, smoothFactor = 0.3, fillOpacity = 1,
fillColor = ~pal(log10(CENSUSAREA)),
label = ~paste0(NAME, ": ", formatC(CENSUSAREA, big.mark = ","))) %>%
addLegend(pal = pal,
values = ~log10(CENSUSAREA),
opacity = 1.0,
labFormat = labelFormat(transform = function(x) round(10^x)))
We can download more vector files.
The addGeoJSON()
and addTopoJSON()
functions accept GeoJSON data in either parsed (nested lists) or stringified (single-element character vector) format.
You can modify the style of GeoJSON/TopoJSON features.
Two-dimensional RasterLayer
objects (using the raster
package) can be turned into images and added to Leaflet maps using the addRasterImage
function.
Shiny makes it easy to build interactive web apps. You can host standalone apps on a webpage (Shinyapps.io vs on-premises), embed them into R Markdown documents or build dashboards.
The palette
argument specifies the colors to map the data:
RColorBrewer
package, e.g. "RdYlBu"
, "Accent"
or "Greens"
.viridis
palette: "viridis"
, "magma"
, "inferno"
, or "plasma"
.palette(c("#000000", "#0000FF", "#FFFFFF")
, palette(topo.colors(10))
.colorRamp(c("#000000", "#FFFFFF"), interpolate="spline")
.<- colorNumeric(c("red", "green", "blue"), 1:10)
pal # Pass the palette function a data vector to get the corresponding colors
pal(c(1,6,9))
## [1] "#FF0000" "#52E74B" "#6854D8"
colorNumeric
)domain
indicates the set of input values that we are mapping to these colors. For colorNumeric
, we can provide either a min/max (below), or a set of numbers that colorNumeric
can call range()
on.
library(rgdal)
<- readOGR("data/countries.geojson") countries
## OGR data source with driver: GeoJSON
## Source: "/home/ugo/Documents/Projets_TI_R/ugodown_github/data/countries.geojson", layer: "countries"
## with 177 features
## It has 63 fields
library(leaflet)
<- colorNumeric(palette = "Blues", domain = countries$gdp_md_est) pal
We could have used c("white", "navy")
or c("#FFFFFF", "#000080")
for a similar effect.
Let’s apply the continuous palette.
library(leaflet)
<- leaflet(countries, options = leafletOptions(minZoom = 1))
map
%>%
map addPolygons(stroke = FALSE,
smoothFactor = 0.2,
fillOpacity = 1,
color = ~pal(gdp_md_est))
colorBin
and colorQuantile
)colorBin
maps numeric input data to a fixed number of output colors using binning (slicing the input domain up by value).
library(rgdal)
<- readOGR("data/countries.geojson") countries
## OGR data source with driver: GeoJSON
## Source: "/home/ugo/Documents/Projets_TI_R/ugodown_github/data/countries.geojson", layer: "countries"
## with 177 features
## It has 63 fields
library(leaflet)
<- colorBin("Blues", countries$gdp_md_est, 6, pretty = FALSE)
binpal
%>%
map addPolygons(stroke = FALSE,
smoothFactor = 0.2,
fillOpacity = 1,
color = ~binpal(gdp_md_est))
colorQuantile
maps numeric input data to a fixed number of output colors using quantiles (slicing the input domain into subsets with equal numbers of observations).
library(rgdal)
<- readOGR("data/countries.geojson") countries
## OGR data source with driver: GeoJSON
## Source: "/home/ugo/Documents/Projets_TI_R/ugodown_github/data/countries.geojson", layer: "countries"
## with 177 features
## It has 63 fields
<- colorQuantile("Blues", countries$gdp_md_est, n = 7)
qpal
library(leaflet)
%>%
map addPolygons(stroke = FALSE,
smoothFactor = 0.2,
fillOpacity = 1,
color = ~qpal(gdp_md_est))
colorFactor
)If the palette contains the same number of elements as there are factor levels, then the mapping will be 1:1; otherwise, the palette will be interpolated to produce the desired number of colors.
library(rgdal)
<- readOGR("data/countries.geojson") countries
## OGR data source with driver: GeoJSON
## Source: "/home/ugo/Documents/Projets_TI_R/ugodown_github/data/countries.geojson", layer: "countries"
## with 177 features
## It has 63 fields
# Make up some 5 random levels
$category <- factor(sample.int(5L, nrow(countries), TRUE))
countries
library(leaflet)
<- colorFactor(topo.colors(5), countries$category)
factpal
leaflet(countries, options = leafletOptions(minZoom = 1)) %>%
addPolygons(stroke = FALSE,
smoothFactor = 0.2,
fillOpacity = 1,
color = ~factpal(category))
library(rgdal)
<- readOGR("data/countries.geojson") countries
## OGR data source with driver: GeoJSON
## Source: "/home/ugo/Documents/Projets_TI_R/ugodown_github/data/countries.geojson", layer: "countries"
## with 177 features
## It has 63 fields
library(leaflet)
<- leaflet(countries, options = leafletOptions(minZoom = 1)) %>%
map addTiles()
map
Use the addLegend
function to add a legend.
library(rgdal)
<- readOGR("data/countries.geojson") countries
## OGR data source with driver: GeoJSON
## Source: "/home/ugo/Documents/Projets_TI_R/ugodown_github/data/countries.geojson", layer: "countries"
## with 177 features
## It has 63 fields
# Continuous input, continuous colours
<- colorNumeric(
pal palette = "YlGnBu",
domain = countries$gdp_md_est
)
library(leaflet)
%>%
map addPolygons(stroke = FALSE, smoothFactor = 0.2, fillOpacity = 1, color = ~pal(gdp_md_est)
%>%
) addLegend("bottomright",
pal = pal,
values = ~gdp_md_est,
title = "Est. GDP (2010)",
labFormat = labelFormat(prefix = "$"),
opacity = 1
)
library(rgdal)
<- readOGR("data/countries.geojson") countries
## OGR data source with driver: GeoJSON
## Source: "/home/ugo/Documents/Projets_TI_R/ugodown_github/data/countries.geojson", layer: "countries"
## with 177 features
## It has 63 fields
# Continuous input, discrete colors
<- colorQuantile("RdYlBu", countries$gdp_md_est, n = 5)
qpal
library(leaflet)
%>%
map addPolygons(stroke = FALSE, smoothFactor = 0.2, fillOpacity = 1, color = ~qpal(gdp_md_est)
%>%
) addLegend("bottomright",
pal = qpal,
values = ~gdp_md_est,
opacity = 1)
We can allow users to decide what layers to show and hide, or programmatically control the visibility of layers using server-side code in Shiny.
The fundamental unit of showing/hiding is the group. Many layers can belong to the same group. But each layer can only belong to zero or one groups (you can’t assign a layer to two groups). Consult the doc for an explanation about groups and layers.
We create two groups: A and B. We can display several Circles or Markers differentiated by groups.
library(leaflet)
leaflet(data3) %>%
addTiles() %>%
addCircles(data = data2,
group = "A",
lng = ~lng, lat = ~lat,
weight = 1,
radius = ~(priority*2)**3,
popup = ~as.character(lieu),
label = ~as.character(priority),
color = 'blue',
stroke = TRUE,
fillOpacity = 0.3) %>%
addCircles(data = data3,
group = "B",
lng = ~lng, lat = ~lat,
weight = 1,
radius = ~(priority*2)**3,
popup = ~as.character(lieu),
label = ~as.character(priority),
color = 'red',
stroke = TRUE,
fillOpacity = 0.3)
library(leaflet)
<- quakes[chull(quakes$long, quakes$lat),]
outline
<- leaflet(quakes) %>%
map # Base groups
addTiles(group = "OSM (default)") %>%
addProviderTiles(providers$Stamen.Toner, group = "Toner") %>%
addProviderTiles(providers$Stamen.TonerLite, group = "Toner Lite") %>%
# Overlay groups
addCircles(~long, ~lat, ~10^mag/5, stroke = F, group = "Quakes") %>%
addPolygons(data = outline, lng = ~long, lat = ~lat,
fill = F, weight = 2, color = "#FFFFCC", group = "Outline") %>%
# Layers control
addLayersControl(
baseGroups = c("OSM (default)", "Toner", "Toner Lite"),
overlayGroups = c("Quakes", "Outline"),
options = layersControlOptions(collapsed = FALSE)
)
map
We can use the showGroup
and hideGroup
functions.
library(leaflet)
%>%
map hideGroup("Outline")
library(leaflet)
<- quakes %>%
quakes ::mutate(mag.level = cut(mag,c(3,4,5,6),
dplyrlabels = c('>3 & <=4', '>4 & <=5', '>5 & <=6')))
<- split(quakes, quakes$mag.level)
quakes.df
<- leaflet() %>% addTiles()
l
names(quakes.df) %>%
::walk( function(df) {
purrr<<- l %>%
l addMarkers(data=quakes.df[[df]],
lng=~long, lat=~lat,
label=~as.character(mag),
popup=~as.character(mag),
group = df,
clusterOptions = markerClusterOptions(removeOutsideVisibleBounds = F),
labelOptions = labelOptions(noHide = F,
direction = 'auto'))
})
%>%
l addLayersControl(
overlayGroups = names(quakes.df),
options = layersControlOptions(collapsed = FALSE)
)
Plain.
library(leaflet)
leaflet(nyc) %>%
addTiles() %>%
addPolygons(stroke = TRUE,
weight = 2,
color = 'snow',
opacity = 0.2,
smoothFactor = 0.3,
fillOpacity = 0.3,
fillColor = 'blue',
label = ~paste0(NAME, ": ", formatC(CENSUSAREA, big.mark = ",")))
Factored.
library(leaflet)
<- c(0, 10, 20, 50, 100, 200, 500, 1000, Inf)
bins #pal <- colorBin("YlOrRd", domain = nyc$CENSUSAREA, bins = bins)
<- colorNumeric("viridis", NULL)
pal
leaflet(nyc) %>%
addTiles() %>%
addPolygons(stroke = TRUE,
weight = 2,
color = 'snow',
opacity = 0.7,
dashArray = "3",
smoothFactor = 0.3,
fillOpacity = 0.7,
fillColor = ~pal(log10(CENSUSAREA)),
label = ~paste0(NAME, ": ", formatC(CENSUSAREA, big.mark = ",")),
highlight = highlightOptions(weight = 3,
color = "gray",
dashArray = "",
fillOpacity = 0.7,
bringToFront = TRUE)) %>%
addLegend(pal = pal,
values = ~log10(CENSUSAREA),
opacity = 0.7,
title = "Size",
position = "bottomleft",
labFormat = labelFormat(transform = function(x) round(10^x)))
We can even customize the labels with labelOptions
.
The leaflet
package expects all point, line, and shape data to be specified in latitude and longitude using WGS 84 (a.k.a. EPSG:4326). The same goes for tiles, markers, and circles under and over the map.
By default, when displaying this data it projects everything to EPSG:3857 and expects that any map tiles are also displayed in EPSG:3857.
We can display data with a different projection with the Proj4Leaflet plugin, which in theory gives Leaflet access to any CRS that is supported by Proj4js. Consult the doc.
Other projections:
addRasterImage
currently works only with EPSG:3857 Web Mercator.We can add widgets to maps.
We add a ‘measuring tape’.
library(leaflet)
leaflet(data) %>%
addTiles() %>%
addMarkers(~lng, ~lat,
popup = ~as.character(lieu),
label = ~as.character(lieu)) %>%
addMeasure(position = "bottomleft",
primaryLengthUnit = "meters",
primaryAreaUnit = "sqmeters",
activeColor = "#3D535D",
completedColor = "#7D4479")
We add a grid. The interval
is the gap between each graticule line: ‘every x degrees’.
library(leaflet)
leaflet() %>%
addTiles() %>%
setView(0,0,2) %>%
addGraticule(interval = 10,
style = list(color = "#FF0000", weight = 1))
library(leaflet)
leaflet() %>%
addTiles() %>%
setView(0,0,2) %>%
addGraticule(group = "Graticule",
interval = 10,
style = list(color = "#FF0000", weight = 1)) %>%
addLayersControl(overlayGroups = c("Graticule"),
options = layersControlOptions(collapsed = FALSE))
We can add a day/night indicator.
library(leaflet)
leaflet() %>%
addTiles() %>%
addTerminator(resolution=10,
time = "2017-10-02T21:00:00Z",
group = "daylight") %>%
addLayersControl(
overlayGroups = "daylight",
options = layersControlOptions(collapsed = FALSE))
We can add a browsing widget.
library(leaflet)
leaflet() %>%
addTiles() %>%
setView(-75,45,4) %>%
addProviderTiles(providers$Esri.WorldStreetMap) %>%
addMiniMap()
htmlwidget::onRender
The htmlwidget::onRender
function can be used to add custom behavior to the leaflet map using native Javascript.
library(leaflet)
<- leaflet() %>% setView(-70,45,7)
l
<- grep("^Esri", providers, value = TRUE)
esri
for (provider in esri) {
<- l %>% addProviderTiles(provider, group = provider)
l
}
%>%
l addLayersControl(baseGroups = names(esri),
options = layersControlOptions(collapsed = FALSE)) %>%
addMiniMap(tiles = esri[[1]], toggleDisplay = TRUE,
position = "bottomleft") %>%
::onRender("
htmlwidgets function(el, x) {
var myMap = this;
myMap.on('baselayerchange',
function (e) {
myMap.minimap.changeLayer(L.tileLayer.provider(e.name));
})
}")