diff --git a/DESCRIPTION b/DESCRIPTION index 668a7722a..57aa49d00 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -78,7 +78,7 @@ Suggests: terra, testthat (>= 3.0.0) Config/testthat/edition: 3 -Config/Needs/website: dplyr, geojsonio, ncdf4, tidyverse/tidytemplate +Config/Needs/website: dplyr, ncdf4, rnaturalearth, tidyverse/tidytemplate Encoding: UTF-8 LazyData: true RoxygenNote: 7.3.2 diff --git a/NEWS.md b/NEWS.md index 73275ee27..e1b4faf39 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,6 +1,10 @@ # leaflet (development version) -* Color palette improvements. All color palette functions now support all `{viridisLite}` palettes ("magma", "inferno", "plasma", "viridis", "cividis", "rocket", "mako", and "turbo"). +* Color palette improvements. All color palette functions now support all `{viridisLite}` palettes ("magma", "inferno", "plasma", "viridis", "cividis", "rocket", "mako", and "turbo") (@jack-davison, #924). + +* Updated vignettes to replace `{sp}`/`{raster}` usage with `{sf}`/`{terra}` and their corresponding examples. (@jack-davison, #928) + +* Updated vignettes to replace `{sp}`/`{raster}` usage with `{sf}`/`{terra} and their corresponding examples. (@jack-davison, #928) # leaflet 2.2.2 diff --git a/R/colors.R b/R/colors.R index d290de0fb..01fefe8c0 100644 --- a/R/colors.R +++ b/R/colors.R @@ -10,7 +10,7 @@ #' @param domain The possible values that can be mapped. #' #' For `colorNumeric()` and `colorBin()`, this can be a simple numeric -#' range (e.g. `c(0, 100)`); `colorQuantile()` needs representative +#' range (e.g., `c(0, 100)`); `colorQuantile()` needs representative #' numeric data; and `colorFactor()` needs categorical data. #' #' If `NULL`, then whenever the resulting color function is called, the @@ -250,7 +250,7 @@ colorFactor <- function(palette, domain, levels = NULL, ordered = FALSE, #' @details The `palette` argument can be any of the following: #' \enumerate{ #' \item{A character vector of RGB or named colors. Examples: `palette()`, `c("#000000", "#0000FF", "#FFFFFF")`, `topo.colors(10)`} -#' \item{The name of an RColorBrewer palette, e.g. `"BuPu"` or `"Greens"`.} +#' \item{The name of an RColorBrewer palette, e.g., `"BuPu"` or `"Greens"`.} #' \item{The full name of a viridis palette: `"magma"`, `"inferno"`, `"plasma"`, `"viridis"`, `"cividis"`, `"rocket"`, `"mako"`, or `"turbo"`} #' \item{A function that receives a single value between 0 and 1 and returns a color. Examples: `colorRamp(c("#000000", "#FFFFFF"), interpolate = "spline")`.} #' } @@ -287,8 +287,8 @@ safePaletteFunc <- function(pal, na.color, alpha, nlevels = NULL) { } # nlevels is a positive or negative integer (or integral number) indicating the -# number of levels to use for a discrete scale (i.e. factor, i.e. qualitative, -# i.e. categorical); or NULL if it is a continuous scale. A negative value means +# number of levels to use for a discrete scale (i.e., factor, i.e., qualitative, +# i.e., categorical); or NULL if it is a continuous scale. A negative value means # that the user has asked for a "reversed" palette, so pull from the tail of the # color palette rather than from the head. # diff --git a/R/layers.R b/R/layers.R index 528e7a727..6f321d709 100644 --- a/R/layers.R +++ b/R/layers.R @@ -25,7 +25,7 @@ evalFormula <- function(list, data) { # least they are the same shape as the Spatial bounding boxes). #' Notifies the map of new latitude/longitude of items of interest on the map -# So that we can expand the limits (i.e. bounding box). We will use this as the +# So that we can expand the limits (i.e., bounding box). We will use this as the # initial view if the user doesn't explicitly specify bounds using fitBounds. #' @param map map object #' @param lat vector of latitudes @@ -624,7 +624,7 @@ clearImages <- function(map) { #' minZoom,maxZoom,maxNativeZoom,tileSize,subdomains,errorTileUrl,tms,noWrap,zoomOffset,zoomReverse,zIndex,unloadInvisibleTiles,updateWhenIdle,detectRetina #' the tile layer options; see #' -#' @param ... extra options passed to underlying Javascript object constructor. +#' @param ... extra options passed to underlying JavaScript object constructor. #' @describeIn map-options Options for tile layers #' @export tileOptions <- function( @@ -765,7 +765,7 @@ WMSTileOptions <- function( #' (for [clearGroup()] and [addLayersControl()] purposes). #' Human-friendly group names are permitted--they need not be short, #' identifier-style names. Any number of layers and even different types of -#' layers (e.g. markers and polygons) can share the same group name. +#' layers (e.g., markers and polygons) can share the same group name. #' @template data-getMapData #' @describeIn map-layers Add popups to the map #' @export @@ -924,7 +924,7 @@ addMarkers <- function( if (!is.null(icon)) { # If custom icons are specified, we need to 1) deduplicate any URLs/files, - # so we can efficiently send e.g. 1000 markers that all use the same 2 + # so we can efficiently send e.g., 1000 markers that all use the same 2 # icons; and 2) do base64 encoding on any local icon files (as opposed to # URLs [absolute or relative] which will be left alone). @@ -1113,7 +1113,7 @@ makeIcon <- function(iconUrl = NULL, iconRetinaUrl = NULL, iconWidth = NULL, ico #' icon image #' @param iconWidth,iconHeight size of the icon image in pixels #' @param iconAnchorX,iconAnchorY the coordinates of the "tip" of the icon -#' (relative to its top left corner, i.e. the top left corner means +#' (relative to its top left corner, i.e., the top left corner means #' `iconAnchorX = 0` and `iconAnchorY = 0`), and the icon will be #' aligned so that this point is at the marker's geographical location #' @param shadowUrl the URL or file path to the icon shadow image @@ -1216,7 +1216,7 @@ markerOptions <- function( #' to style spider legs. By default, they are #' \code{\{weight: 1.5, color: "#222", opacity: 0.5 \}}. #' @param freezeAtZoom Allows you to freeze cluster expansion to a zoom level. -#' Can be a zoom level e.g. 10, 12 or "max" or "maxKeepSpiderify". +#' Can be a zoom level e.g., 10, 12 or "max" or "maxKeepSpiderify". #' See . #' @describeIn map-options Options for marker clusters #' @export @@ -1240,12 +1240,12 @@ markerClusterOptions <- function( #' @param radius a numeric vector of radii for the circles; it can also be a #' one-sided formula, in which case the radius values are derived from the #' `data` (units in meters for circles, and pixels for circle markers) -#' @param stroke whether to draw stroke along the path (e.g. the borders of +#' @param stroke whether to draw stroke along the path (e.g., the borders of #' polygons or circles) #' @param color stroke color #' @param weight stroke width in pixels #' @param opacity stroke opacity (or layer opacity for tile layers) -#' @param fill whether to fill the path with color (e.g. filling on polygons or +#' @param fill whether to fill the path with color (e.g., filling on polygons or #' circles) #' @param fillColor fill color #' @param fillOpacity fill opacity diff --git a/R/legend.R b/R/legend.R index 55850153d..660f58215 100644 --- a/R/legend.R +++ b/R/legend.R @@ -1,6 +1,6 @@ #' Add a color legend to a map #' -#' When a color palette function is used in a map (e.g. +#' When a color palette function is used in a map (e.g., #' [colorNumeric()]), a color legend can be automatically derived from #' the palette function. You can also manually specify the colors and labels for #' the legend. @@ -54,7 +54,7 @@ #' with this name and will auto add/remove the legend as the #' group is added/removed, for example via `layerControl()`. #' You will need to set the `group` when you add a layer -#' (e.g. [addPolygons()]) and supply the same name here. +#' (e.g., [addPolygons()]) and supply the same name here. #' @template data-getMapData #' @example inst/examples/legend.R #' @export diff --git a/R/mapPane.R b/R/mapPane.R index 46d7d3979..b1bdfafdf 100644 --- a/R/mapPane.R +++ b/R/mapPane.R @@ -6,7 +6,7 @@ #' overlay pane) and 500 (the default shadow pane). You can then use this pane #' to render overlays (points, lines, polygons) by setting the `pane` #' argument in [leafletOptions()]. This will give you control -#' over the order of the layers, e.g. points always on top of polygons. +#' over the order of the layers, e.g., points always on top of polygons. #' If two layers are provided to the same pane, overlay will be determined by #' order of adding. See examples below. #' See for details. diff --git a/R/normalize.R b/R/normalize.R index 9e22e4280..f09e54cf8 100644 --- a/R/normalize.R +++ b/R/normalize.R @@ -198,7 +198,7 @@ checkMatrix <- function(x) { # - to_ring # # Each of the specific sp/sf classes need only implement whichever ONE of those -# actually makes sense (e.g. to_multipolygon_list.sfc, +# actually makes sense (e.g., to_multipolygon_list.sfc, # to_multipolygon.MULTIPOLYGON, to_polygon.POLYGON, to_ring.LINESTRING). The # higher-level polygonData wrappers will simply call to_multipolygon_list(x), # and the default implementations of those methods will fall through to the next diff --git a/R/plugin-awesomeMarkers.R b/R/plugin-awesomeMarkers.R index 43cb47ceb..96ba3fc86 100644 --- a/R/plugin-awesomeMarkers.R +++ b/R/plugin-awesomeMarkers.R @@ -235,7 +235,7 @@ verifyIconLibrary <- function(library) { #' (for [clearGroup()] and [addLayersControl()] purposes). #' Human-friendly group names are permitted--they need not be short, #' identifier-style names. Any number of layers and even different types of -#' layers (e.g. markers and polygons) can share the same group name. +#' layers (e.g., markers and polygons) can share the same group name. #' @param data the data object from which the argument values are derived; by #' default, it is the `data` object provided to `leaflet()` #' initially, but can be overridden diff --git a/R/plugin-terminator.R b/R/plugin-terminator.R index 9ec980154..2f0e996a4 100644 --- a/R/plugin-terminator.R +++ b/R/plugin-terminator.R @@ -16,7 +16,7 @@ leafletTerminatorDependencies <- function() { #' #' @param map a map widget object #' @param resolution the step size at which the terminator points are computed. -#' The step size is 1 degree/resolution, i.e. higher resolution values have +#' The step size is 1 degree/resolution, i.e., higher resolution values have #' smaller step sizes and more points in the polygon. The default value is 2. #' @param time Time #' @param layerId the layer id diff --git a/man/addAwesomeMarkers.Rd b/man/addAwesomeMarkers.Rd index 8511ed5da..aa8691dd7 100644 --- a/man/addAwesomeMarkers.Rd +++ b/man/addAwesomeMarkers.Rd @@ -40,7 +40,7 @@ the latitude column from \code{data})} (for \code{\link[=clearGroup]{clearGroup()}} and \code{\link[=addLayersControl]{addLayersControl()}} purposes). Human-friendly group names are permitted--they need not be short, identifier-style names. Any number of layers and even different types of -layers (e.g. markers and polygons) can share the same group name.} +layers (e.g., markers and polygons) can share the same group name.} \item{icon}{the icon(s) for markers;} diff --git a/man/addLegend.Rd b/man/addLegend.Rd index dd2f2c9b9..f1831ff12 100644 --- a/man/addLegend.Rd +++ b/man/addLegend.Rd @@ -75,7 +75,7 @@ Supplying this value will tie the legend to the leaflet layer group with this name and will auto add/remove the legend as the group is added/removed, for example via \code{layerControl()}. You will need to set the \code{group} when you add a layer -(e.g. \code{\link[=addPolygons]{addPolygons()}}) and supply the same name here.} +(e.g., \code{\link[=addPolygons]{addPolygons()}}) and supply the same name here.} \item{data}{the data object from which the argument values are derived; by default, it is the \code{data} object provided to \code{leaflet()} @@ -95,7 +95,7 @@ labels (by default, it is a dash)} \item{transform}{a function to transform the label value} } \description{ -When a color palette function is used in a map (e.g. +When a color palette function is used in a map (e.g., \code{\link[=colorNumeric]{colorNumeric()}}), a color legend can be automatically derived from the palette function. You can also manually specify the colors and labels for the legend. diff --git a/man/addMapPane.Rd b/man/addMapPane.Rd index cb91b6177..faeb9a641 100644 --- a/man/addMapPane.Rd +++ b/man/addMapPane.Rd @@ -20,7 +20,7 @@ ordering. We recommend a \code{zIndex} value between 400 (the default overlay pane) and 500 (the default shadow pane). You can then use this pane to render overlays (points, lines, polygons) by setting the \code{pane} argument in \code{\link[=leafletOptions]{leafletOptions()}}. This will give you control -over the order of the layers, e.g. points always on top of polygons. +over the order of the layers, e.g., points always on top of polygons. If two layers are provided to the same pane, overlay will be determined by order of adding. See examples below. See \url{https://web.archive.org/web/20220702182250/https://leafletjs.com/reference-1.3.4.html#map-pane} for details. diff --git a/man/addTerminator.Rd b/man/addTerminator.Rd index 7c81b8de6..5d2b6befd 100644 --- a/man/addTerminator.Rd +++ b/man/addTerminator.Rd @@ -17,7 +17,7 @@ addTerminator( \item{map}{a map widget object} \item{resolution}{the step size at which the terminator points are computed. -The step size is 1 degree/resolution, i.e. higher resolution values have +The step size is 1 degree/resolution, i.e., higher resolution values have smaller step sizes and more points in the polygon. The default value is 2.} \item{time}{Time} diff --git a/man/colorNumeric.Rd b/man/colorNumeric.Rd index 9079376f7..6dfd124b6 100644 --- a/man/colorNumeric.Rd +++ b/man/colorNumeric.Rd @@ -53,7 +53,7 @@ colorFactor( \item{domain}{The possible values that can be mapped. For \code{colorNumeric()} and \code{colorBin()}, this can be a simple numeric -range (e.g. \code{c(0, 100)}); \code{colorQuantile()} needs representative +range (e.g., \code{c(0, 100)}); \code{colorQuantile()} needs representative numeric data; and \code{colorFactor()} needs categorical data. If \code{NULL}, then whenever the resulting color function is called, the @@ -124,7 +124,7 @@ interpolation is used. The \code{palette} argument can be any of the following: \enumerate{ \item{A character vector of RGB or named colors. Examples: \code{palette()}, \code{c("#000000", "#0000FF", "#FFFFFF")}, \code{topo.colors(10)}} -\item{The name of an RColorBrewer palette, e.g. \code{"BuPu"} or \code{"Greens"}.} +\item{The name of an RColorBrewer palette, e.g., \code{"BuPu"} or \code{"Greens"}.} \item{The full name of a viridis palette: \code{"magma"}, \code{"inferno"}, \code{"plasma"}, \code{"viridis"}, \code{"cividis"}, \code{"rocket"}, \code{"mako"}, or \code{"turbo"}} \item{A function that receives a single value between 0 and 1 and returns a color. Examples: \code{colorRamp(c("#000000", "#FFFFFF"), interpolate = "spline")}.} } diff --git a/man/icons.Rd b/man/icons.Rd index 68b84392a..54e553468 100644 --- a/man/icons.Rd +++ b/man/icons.Rd @@ -31,7 +31,7 @@ icon image} \item{iconWidth, iconHeight}{size of the icon image in pixels} \item{iconAnchorX, iconAnchorY}{the coordinates of the "tip" of the icon -(relative to its top left corner, i.e. the top left corner means +(relative to its top left corner, i.e., the top left corner means \code{iconAnchorX = 0} and \code{iconAnchorY = 0}), and the icon will be aligned so that this point is at the marker's geographical location} diff --git a/man/makeIcon.Rd b/man/makeIcon.Rd index 650aedd2f..17400320d 100644 --- a/man/makeIcon.Rd +++ b/man/makeIcon.Rd @@ -31,7 +31,7 @@ icon image} \item{iconWidth, iconHeight}{size of the icon image in pixels} \item{iconAnchorX, iconAnchorY}{the coordinates of the "tip" of the icon -(relative to its top left corner, i.e. the top left corner means +(relative to its top left corner, i.e., the top left corner means \code{iconAnchorX = 0} and \code{iconAnchorY = 0}), and the icon will be aligned so that this point is at the marker's geographical location} diff --git a/man/map-layers.Rd b/man/map-layers.Rd index 37a6697a9..d0ba592f0 100644 --- a/man/map-layers.Rd +++ b/man/map-layers.Rd @@ -291,7 +291,7 @@ initially, but can be overridden} (for \code{\link[=clearGroup]{clearGroup()}} and \code{\link[=addLayersControl]{addLayersControl()}} purposes). Human-friendly group names are permitted--they need not be short, identifier-style names. Any number of layers and even different types of -layers (e.g. markers and polygons) can share the same group name.} +layers (e.g., markers and polygons) can share the same group name.} \item{options}{a list of extra options for tile layers, popups, paths (circles, rectangles, polygons, ...), or other map elements} @@ -339,7 +339,7 @@ options} one-sided formula, in which case the radius values are derived from the \code{data} (units in meters for circles, and pixels for circle markers)} -\item{stroke}{whether to draw stroke along the path (e.g. the borders of +\item{stroke}{whether to draw stroke along the path (e.g., the borders of polygons or circles)} \item{color}{stroke color} @@ -348,7 +348,7 @@ polygons or circles)} \item{opacity}{stroke opacity (or layer opacity for tile layers)} -\item{fill}{whether to fill the path with color (e.g. filling on polygons or +\item{fill}{whether to fill the path with color (e.g., filling on polygons or circles)} \item{fillColor}{fill color} diff --git a/man/map-options.Rd b/man/map-options.Rd index a5a28c15a..105b193f5 100644 --- a/man/map-options.Rd +++ b/man/map-options.Rd @@ -118,7 +118,7 @@ pathOptions( \item{opacity}{Tooltip container opacity. Ranges from 0 to 1. Default value is \code{1} (different from leaflet.js \code{0.9}); see \url{https://web.archive.org/web/20220702182250/https://leafletjs.com/reference-1.3.4.html#tooltip-opacity}} -\item{...}{extra options passed to underlying Javascript object constructor.} +\item{...}{extra options passed to underlying JavaScript object constructor.} \item{styles}{comma-separated list of WMS styles} @@ -171,7 +171,7 @@ to style spider legs. By default, they are \code{\{weight: 1.5, color: "#222", opacity: 0.5 \}}.} \item{freezeAtZoom}{Allows you to freeze cluster expansion to a zoom level. -Can be a zoom level e.g. 10, 12 or "max" or "maxKeepSpiderify". +Can be a zoom level e.g., 10, 12 or "max" or "maxKeepSpiderify". See \url{https://github.com/ghybs/Leaflet.MarkerCluster.Freezable#api-reference}.} \item{lineCap}{a string that defines \href{https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linecap}{shape to be used at the end} diff --git a/vignettes/articles/choropleths.Rmd b/vignettes/articles/choropleths.Rmd index 236705a59..0359b2c51 100644 --- a/vignettes/articles/choropleths.Rmd +++ b/vignettes/articles/choropleths.Rmd @@ -20,7 +20,7 @@ library(magrittr) ```{r fig.height = 4.75, echo = FALSE, message = FALSE} # From https://leafletjs.com/examples/choropleth/us-states.js -states <- geojsonio::geojson_read("https://rstudio.github.io/leaflet/json/us-states.geojson", what = "sp") +states <- sf::read_sf("https://rstudio.github.io/leaflet/json/us-states.geojson") bins <- c(0, 10, 20, 50, 100, 200, 500, 1000, Inf) pal <- colorBin("YlOrRd", domain = states$density, bins = bins) @@ -61,16 +61,15 @@ leaflet(states) %>% We'll start by loading the data from JSON. While the Leaflet.js example loads the JSON directly into JavaScript, with the Leaflet R package we instead want to load the data into R. -In this case, we'll use the `geojsonio` package to load the data into `sp` objects, which will let us easily manipulate the geographic features, and their properties, in R. +In this case, we'll use the `{sf}` package to load the data into an `sf` `data.frame`, which will let us easily manipulate the geographic features, and their properties, in R. - ```{r} -states <- geojsonio::geojson_read("https://rstudio.github.io/leaflet/json/us-states.geojson", what = "sp") +states <- sf::read_sf("https://rstudio.github.io/leaflet/json/us-states.geojson") class(states) names(states) ``` -As you can see, we now have a `SpatialPolygonsDataFrame` with `name` (state name) and `density` (population density in people/mi2) columns from the GeoJSON. +As you can see, we now have an `sf` `data.frame` with `name` (state name) and `density` (population density in people/mi2) columns from the GeoJSON. ### Basic states map @@ -187,7 +186,7 @@ m %>% addLegend(pal = pal, values = ~density, opacity = 0.7, title = NULL, ```{r results = 'hide'} # From https://leafletjs.com/examples/choropleth/us-states.js -states <- geojsonio::geojson_read("https://rstudio.github.io/leaflet/json/us-states.geojson", what = "sp") +states <- sf::read_sf("https://rstudio.github.io/leaflet/json/us-states.geojson") bins <- c(0, 10, 20, 50, 100, 200, 500, 1000, Inf) pal <- colorBin("YlOrRd", domain = states$density, bins = bins) diff --git a/vignettes/articles/colors.Rmd b/vignettes/articles/colors.Rmd index 8907e9a73..f32ba8a0b 100644 --- a/vignettes/articles/colors.Rmd +++ b/vignettes/articles/colors.Rmd @@ -11,7 +11,7 @@ knitr::opts_chunk$set( An important part of spatial visualization is mapping variables to colors. While R has no shortage of built-in functionality to map values to colors, we found that there was enough friction in the process to warrant introducing some wrapper functions that do a lot of the work for you. -To that end, we've created a family of `color*()` convenience functions that can be used to easily generate *palette functions*. Essentially, you call the appropriate color function with 1) the colors you want to use and 2) optionally, the range of inputs (i.e. *domain*) that are expected. The color function returns a palette function that can be passed a vector of input values, and it'll return a vector of colors in `#RRGGBB(AA)` format. +To that end, we've created a family of `color*()` convenience functions that can be used to easily generate *palette functions*. Essentially, you call the appropriate color function with 1) the colors you want to use and 2) optionally, the range of inputs (i.e., *domain*) that are expected. The color function returns a palette function that can be passed a vector of input values, and it'll return a vector of colors in `#RRGGBB(AA)` format. ```{r, include = FALSE} library(leaflet) @@ -34,20 +34,19 @@ The four color functions all have two required arguments, `palette` and `domain` The `palette` argument specifies the colors to map the data to. This argument can take one of several forms: -1. The name of a preset palette from the `RColorBrewer` package, e.g. `"RdYlBu"`, `"Accent"`, or `"Greens"`. +1. The name of a preset palette from the `RColorBrewer` package, e.g., `"RdYlBu"`, `"Accent"`, or `"Greens"`. 2. The full name of a `viridis` palette: `"magma"`, `"inferno"`, `"plasma"`, `"viridis"`, `"cividis"`, `"rocket"`, `"mako"`, or `"turbo"`. -3. A character vector of RGB or named colors, e.g. `palette()`, `c("#000000", "#0000FF", "#FFFFFF")`, `topo.colors(10)`. -4. A function that receives a single value between 0 and 1 and returns a color, e.g.: +3. A character vector of RGB or named colors, e.g., `palette()`, `c("#000000", "#0000FF", "#FFFFFF")`, `topo.colors(10)`. +4. A function that receives a single value between 0 and 1 and returns a color, e.g.,: `colorRamp(c("#000000", "#FFFFFF"), interpolate="spline")` The `domain` argument tells the color function the range of input values. You can pass `NULL` here to create a palette function that doesn't have a preset range; the range will be inferred from the data each time you invoke the palette function. If you use a palette function multiple times across different data, it's important to provide a non-`NULL` value for `domain` so the scaling between data and colors is consistent. ## Coloring continuous data - ```{r message=FALSE,warning=FALSE,results='hide'} # From http://data.okfn.org/data/datasets/geo-boundaries-world-110m -countries <- sf::st_read("https://rstudio.github.io/leaflet/json/countries.geojson") +countries <- sf::read_sf("https://rstudio.github.io/leaflet/json/countries.geojson") map <- leaflet(countries) ``` @@ -82,7 +81,7 @@ map %>% color = ~pal(gdp_md_est)) ``` -### Continuous input, discrete colors (`colorBin` and `colorQuantile`) +### Continuous input, discrete colors (`colorBin()` and `colorQuantile()`) `colorBin()` maps numeric input data to a fixed number of output colors using binning (slicing the input domain up by value). diff --git a/vignettes/articles/extending.Rmd b/vignettes/articles/extending.Rmd index 37bff1623..71ffd5687 100644 --- a/vignettes/articles/extending.Rmd +++ b/vignettes/articles/extending.Rmd @@ -19,11 +19,11 @@ Certain functions have been made available for you to use in your code while ext ## derivePoints/derivePolygons -`derivePoints()` and `derivePolygons()` can be used to extract point or shape (polygon/line/circle/rectangle) data from a `data.frame` or a spatial object from the `sp` package. It tries to auto determine the latitude/longitude colnames if not specified or use user supplied column mappings. +`derivePoints()` and `derivePolygons()` can be used to extract point or shape (polygon/line/circle/rectangle) data from a `data.frame` or a spatial object from the `{sf}` package. It tries to auto determine the latitude/longitude colnames if not specified or use user supplied column mappings. ## evalFormula -`evalFormula()` is used to evaluate a formula on a given data and return the results. e.g. `leaflet(some.data.frame) %>% addMarkers(label=~name)` internally uses `evalFormula()` to calculate the correct label values from the data using the `~name` formula. +`evalFormula()` is used to evaluate a formula on a given data and return the results. e.g., `leaflet(some.data.frame) %>% addMarkers(label=~name)` internally uses `evalFormula()` to calculate the correct label values from the data using the `~name` formula. ## expandLimits @@ -31,15 +31,15 @@ You can call `expandLimits()` to make sure that your map's view is just enough ## filterNULL -Often when passing a list from R to Javascript it is desirable to remove any null elements, and that's exactly what `filterNULL()` does. +Often when passing a list from R to JavaScript it is desirable to remove any null elements, and that's exactly what `filterNULL()` does. ## getMapData -`getMapData()` accesses the data object passed when calling `leaflet()` funtion. +`getMapData()` accesses the data object passed when calling `leaflet()` function. ## invokeMethod -`invokeMethod()` is the glue between the R code and JavaScript code. Requires a corresponding method on the Javascript side. +`invokeMethod()` is the glue between the R code and JavaScript code. Requires a corresponding method on the JavaScript side. # Example diff --git a/vignettes/articles/json.Rmd b/vignettes/articles/json.Rmd index 476f0b959..4c278d247 100644 --- a/vignettes/articles/json.Rmd +++ b/vignettes/articles/json.Rmd @@ -2,12 +2,11 @@ title: "Working with GeoJSON & TopoJSON" --- +For working with GeoJSON/TopoJSON data you have two options: either read it into `sf` `data.frame`s; or use the `addGeoJSON()` and `addTopoJSON()` functions. -For working with GeoJSON/TopoJSON data you have two options: either read it into `sp` objects; or use the `addGeoJSON()` and `addTopoJSON()` functions. +# Reading as `{sf}` -# Reading as `sp` - -The first approach is to use either `sf` or `geojsonio` (packages) to read GeoJSON/TopoJSON as `sp` objects. Then, you can use the full functionality of [polygons](https://rstudio.github.io/leaflet/articles/shapes.html), [markers](https://rstudio.github.io/leaflet/articles/markers.html), [colors](https://rstudio.github.io/leaflet/articles/colors.html), [legends](https://rstudio.github.io/leaflet/articles/legends.html), etc. +The first approach is to use the `{sf}` packages to read GeoJSON/TopoJSON as `sf` `data.frame`s. Then, you can use the full functionality of [polygons](https://rstudio.github.io/leaflet/articles/shapes.html), [markers](https://rstudio.github.io/leaflet/articles/markers.html), [colors](https://rstudio.github.io/leaflet/articles/colors.html), [legends](https://rstudio.github.io/leaflet/articles/legends.html), etc. ```{r, include = FALSE} library(leaflet) @@ -18,8 +17,6 @@ library(magrittr) # From https://eric.clst.org/tech/usgeojson/ and # https://en.wikipedia.org/wiki/List_of_United_States_counties_and_county_equivalents nycounties <- sf::read_sf("https://rstudio.github.io/leaflet/json/nycounties.geojson") -# Or use the geojsonio equivalent: -# nycounties <- geojsonio::geojson_read("https://rstudio.github.io/leaflet/json/nycounties.geojson", what = "sp") pal <- colorNumeric("viridis", NULL) @@ -64,7 +61,7 @@ See Leaflet's [path](https://leafletjs.com/reference.html#path-options) options The previous example demonstrated the style arguments. Below is a more involved example that sets both global styles and per-feature styles directly into the JSON object. -(This approach is not recommended for applying styling in R; instead, use the approach described above where we convert to `sp` first. However, if you have control over the process that generates the GeoJSON in the first place, you might use these techniques to put the styling information directly in the JSON.) +(This approach is not recommended for applying styling in R; instead, use the approach described above where we convert to `sf` first. However, if you have control over the process that generates the GeoJSON in the first place, you might use these techniques to put the styling information directly in the JSON.) ```{r echo=FALSE,warning=FALSE,message=FALSE} library(jsonlite, quietly = TRUE) diff --git a/vignettes/articles/leaflet.Rmd b/vignettes/articles/leaflet.Rmd index e78f1d4ae..b35ff98c9 100644 --- a/vignettes/articles/leaflet.Rmd +++ b/vignettes/articles/leaflet.Rmd @@ -27,9 +27,9 @@ This R package makes it easy to integrate and control Leaflet maps in R. * GeoJSON * Create maps right from the R console or RStudio * Embed maps in [knitr](https://yihui.org/knitr/)/[R Markdown](https://rmarkdown.rstudio.com/)/[Quarto](https://quarto.org) documents, and [Shiny](https://shiny.posit.co/) apps -* Easily render spatial objects from the `sp` or `sf` packages, or data frames with latitude/longitude columns +* Easily render spatial objects from the `{sf}` package, or data frames with latitude/longitude columns * Use map bounds and mouse events to drive Shiny logic -* Display maps in non spherical mercator projections +* Display maps in non spherical Mercator projections * Augment map features using chosen plugins from [leaflet plugins repository](https://leafletjs.com/plugins) ### Installation @@ -49,7 +49,7 @@ Once installed, you can use this package at the R console, within [R Markdown](h You create a Leaflet map with these basic steps: 1. Create a map widget by calling `leaflet()`. -2. Add _layers_ (i.e., features) to the map by using layer functions (e.g. `addTiles`, `addMarkers`, `addPolygons`) to modify the map widget. +2. Add _layers_ (i.e., features) to the map by using layer functions (e.g., `addTiles`, `addMarkers`, `addPolygons`) to modify the map widget. 3. Repeat step 2 as desired. 4. Print the map widget to display it. diff --git a/vignettes/articles/legends.Rmd b/vignettes/articles/legends.Rmd index 81436a749..8e0810a11 100644 --- a/vignettes/articles/legends.Rmd +++ b/vignettes/articles/legends.Rmd @@ -19,11 +19,11 @@ library(magrittr) ```{r} # From http://data.okfn.org/data/datasets/geo-boundaries-world-110m -countries <- sf::st_read("https://rstudio.github.io/leaflet/json/countries.geojson") +countries <- sf::read_sf("https://rstudio.github.io/leaflet/json/countries.geojson") map <- leaflet(countries) %>% addTiles() ``` -Use the `addLegend` function to add a legend. The easiest way to use `addLegend` is to provide `pal` (a palette function, as generated from `colorNumeric` et al.) and `values`, and let it calculate the colors and labels for you. +Use the `addLegend()` function to add a legend. The easiest way to use `addLegend()` is to provide `pal` (a palette function, as generated from `colorNumeric()` et al.) and `values`, and let it calculate the colors and labels for you. In most cases you will simply be separating the function and argument you passed into `addPolygons(color=...)`, as in this example: @@ -43,7 +43,7 @@ map %>% ) ``` -The `addLegend()` function is aware of the different types of palette functions, and will create an appropriate default rendering for each type. For example, contrast the legend created for the `colorNumeric`-based palette above with the `colorQuantile`-based palette below. The latter shows probability ranges, with a value range tooltip. +The `addLegend()` function is aware of the different types of palette functions, and will create an appropriate default rendering for each type. For example, contrast the legend created for the `colorNumeric()`-based palette above with the `colorQuantile()`-based palette below. The latter shows probability ranges, with a value range tooltip. ```{r} qpal <- colorQuantile("RdYlBu", countries$gdp_md_est, n = 5) diff --git a/vignettes/articles/markers.Rmd b/vignettes/articles/markers.Rmd index dabe80d44..627173066 100644 --- a/vignettes/articles/markers.Rmd +++ b/vignettes/articles/markers.Rmd @@ -19,13 +19,12 @@ Use markers to call out points on the map. Marker locations are expressed in lat Point data for markers can come from a variety of sources: -- `SpatialPoints` or `SpatialPointsDataFrame` objects (from the `sp` package) -- `POINT`, `sfc_POINT`, and `sf` objects (from the `sf` package); only `X` and `Y` dimensions will be considered +- `POINT`, `sfc_POINT`, and `sf` objects (from the `{sf}` package); only `X` and `Y` dimensions will be considered - Two-column numeric matrices (first column is longitude, second is latitude) -- Data frame with latitude and longitude columns. You can explicitly tell the marker function which columns contain the coordinate data (e.g. `addMarkers(lng = ~Longitude, lat = ~Latitude)`), or let the function look for columns named `lat`/`latitude` and `lon`/`lng`/`long`/`longitude` (case insensitive). +- Data frame with latitude and longitude columns. You can explicitly tell the marker function which columns contain the coordinate data (e.g., `addMarkers(lng = ~Longitude, lat = ~Latitude)`), or let the function look for columns named `lat`/`latitude` and `lon`/`lng`/`long`/`longitude` (case insensitive). - Simply provide numeric vectors as `lng` and `lat` arguments -Note that `MULTIPOINT` objects from `sf` are not supported at this time. +Note that `MULTIPOINT` objects from `{sf}` are not supported at this time. # Icon Markers @@ -59,7 +58,7 @@ leaflet(data = quakes[1:4,]) %>% addTiles() %>% addMarkers(~long, ~lat, icon = greenLeafIcon) ``` -If you have several icons to apply that vary only by a couple of parameters (i.e. they share the same size and anchor points but have different URLs), use `icons()` `icons()` performs similarly to `data.frame()`, in that any arguments that are shorter than the number of markers will be recycled to fit. +If you have several icons to apply that vary only by a couple of parameters (i.e., they share the same size and anchor points but have different URLs), use `icons()` `icons()` performs similarly to `data.frame()`, in that any arguments that are shorter than the number of markers will be recycled to fit. ```{r fig.height=2} quakes1 <- quakes[1:10,] @@ -85,20 +84,29 @@ Finally, if you have a set of icons that vary in multiple parameters, it may be ```{r fig.height=1.75} # Make a list of icons. We'll index into it based on name. oceanIcons <- iconList( - ship = makeIcon("ferry-18.png", "ferry-18@2x.png", 18, 18), - pirate = makeIcon("danger-24.png", "danger-24@2x.png", 24, 24) + ship = makeIcon( + "https://upload.wikimedia.org/wikipedia/commons/thumb/0/0b/Maki2-ferry-18.svg/480px-Maki2-ferry-18.svg.png", + "https://upload.wikimedia.org/wikipedia/commons/thumb/0/0b/Maki2-ferry-18.svg/18px-Maki2-ferry-18.svg.png", + 18, + 18 + ), + pirate = makeIcon( + "https://upload.wikimedia.org/wikipedia/commons/thumb/c/c3/Maki2-danger-24.svg/240px-Maki2-danger-24.svg.png", + "https://upload.wikimedia.org/wikipedia/commons/thumb/c/c3/Maki2-danger-24.svg/24px-Maki2-danger-24.svg.png", + 24, + 24 + ) ) # Some fake data -df <- sp::SpatialPointsDataFrame( - cbind( - (runif(20) - .5) * 10 - 90.620130, # lng - (runif(20) - .5) * 3.8 + 25.638077 # lat +df <- sf::st_as_sf( + data.frame( + type = factor(ifelse(runif(20) > 0.75, "pirate", "ship"), c("ship", "pirate")), + lng = (runif(20) - .5) * 10 - 90.620130, + lat = (runif(20) - .5) * 3.8 + 25.638077 ), - data.frame(type = factor( - ifelse(runif(20) > 0.75, "pirate", "ship"), - c("ship", "pirate") - )) + coords = c("lng", "lat"), + crs = 4326 ) leaflet(df) %>% addTiles() %>% @@ -110,7 +118,6 @@ leaflet(df) %>% addTiles() %>% Leaflet supports even more customizable markers using the [awesome markers](https://github.com/lennardv2/Leaflet.awesome-markers) leaflet plugin. - The `addAwesomeMarkers()` function is similar to `addMarkers()` function but additionally allows you to specify custom colors for the markers as well as icons from the [Font Awesome](https://fontawesome.com/icons), [Bootstrap Glyphicons](https://getbootstrap.com/components/), and [Ion icons](https://ionic.io/ionicons) icon libraries. Similar to `makeIcon()`, `icons()`, and `iconList()` described above, you have `makeAwesomeIcon()`, `awesomeIcons()` and `awesomeIconList()` functions, which enable you to add awesome icons. @@ -146,7 +153,7 @@ The `library` argument has to be one of 'ion', 'fa', or 'glyphicon'. The `icon` ## Marker Clusters -When there are a large number of markers on a map, you can cluster them using the [Leaflet.markercluster](https://github.com/Leaflet/Leaflet.markercluster) plug-in. To enable this plug-in, you can provide a list of options to the argument `clusterOptions`, e.g. +When there are a large number of markers on a map, you can cluster them using the [Leaflet.markercluster](https://github.com/Leaflet/Leaflet.markercluster) plug-in. To enable this plug-in, you can provide a list of options to the argument `clusterOptions`, e.g., ```{r fig.height=2.5, message=FALSE} leaflet(quakes) %>% addTiles() %>% addMarkers( diff --git a/vignettes/articles/morefeatures.Rmd b/vignettes/articles/morefeatures.Rmd index 796368597..2535b4dac 100644 --- a/vignettes/articles/morefeatures.Rmd +++ b/vignettes/articles/morefeatures.Rmd @@ -181,7 +181,7 @@ leaflet() %>% addTiles() %>% ## Custom JavaScript with `htmlwidgets::onRender()` -`htmlwidgets::onRender()` can be used to add custom behavior to the leaflet map using native Javascript. This is a some what advanced use case and requires you to know Javascript. Using `onRender` you can customize your map's behavior using any of the APIs as defined in the Leaflet.js [documentation](https://leafletjs.com/reference.html). +`htmlwidgets::onRender()` can be used to add custom behavior to the leaflet map using native JavaScript. This is a some what advanced use case and requires you to know JavaScript. Using `onRender` you can customize your map's behavior using any of the APIs as defined in the Leaflet.js [documentation](https://leafletjs.com/reference.html). Below is an example where we sync the base layer of the mini-map with the baselayer of the main map, using the 'baselayerchange' event. diff --git a/vignettes/articles/popups.Rmd b/vignettes/articles/popups.Rmd index 718c7b94c..fcc8d4be1 100644 --- a/vignettes/articles/popups.Rmd +++ b/vignettes/articles/popups.Rmd @@ -48,7 +48,7 @@ leaflet(df) %>% addTiles() %>% addMarkers(~Long, ~Lat, popup = ~htmlEscape(Name)) ``` -In the preceding example, `htmltools::htmlEscape` was used to santize any characters in the name that might be interpreted as HTML. While it wasn't necessary for this example (as the restaurant names contained no HTML markup), doing so is important in any situation where the data may come from a file or database, or from the user. +In the preceding example, `htmltools::htmlEscape()` was used to sanitize any characters in the name that might be interpreted as HTML. While it wasn't necessary for this example (as the restaurant names contained no HTML markup), doing so is important in any situation where the data may come from a file or database, or from the user. In addition to markers you can also add popups on shapes like lines, circles and other polygons. @@ -71,7 +71,7 @@ leaflet(df) %>% addTiles() %>% #### Customizing Marker Labels -You can customize marker labels using the `labelOptions` argument of the `addMarkers` function. The `labelOptions` argument can be populated using the `labelOptions()` function. If `noHide` is false (the default) then the label is displayed only when you hover the mouse over the marker; if `noHide` is set to true then the label is always displayed. +You can customize marker labels using the `labelOptions` argument of the `addMarkers()` function. The `labelOptions` argument can be populated using the `labelOptions()` function. If `noHide` is false (the default) then the label is displayed only when you hover the mouse over the marker; if `noHide` is set to true then the label is always displayed. ```{r, fig.height=4} # Change Text Size and text Only and also a custom CSS diff --git a/vignettes/articles/projections.Rmd b/vignettes/articles/projections.Rmd index 004a5db47..78df7a89c 100644 --- a/vignettes/articles/projections.Rmd +++ b/vignettes/articles/projections.Rmd @@ -74,28 +74,46 @@ leaflet() %>% # Displaying shapes with custom projections -While tiles must be in the same projection as used in `leafletCRS()`, you must always use WGS 84 longitude/latitude data for markers, circles, polygons, and lines. Leaflet will automatically project the coordinates when displaying. +While tiles must be in the same projection as used in `leafletCRS()`, you must always use WGS 84 longitude/latitude data for markers, circles, polygons, and lines. Leaflet will automatically project the coordinates when displaying. -This example uses [EPSG:2163](https://epsg.io/2163) (US National Atlas Equal Area projection). The dataset we use (`usa_sf` from the `albersusa` package, though we're not actually using Albers projection here) has Alaska and Hawaii moved closer to mainland US as well as rotated and resized accordingly. +This example uses data from the `{rnaturalearth}` package and projects it to the [EPSG:9311](https://epsg.io/9311) (US National Atlas Equal Area) coordinate system. Compare the first map, which uses the default CRS, to the second map, which is reprojected. -```{r message=FALSE,warning=FALSE,eval=FALSE} -library(sp) -library(albersusa) # not possible to install due to rgdal archival. -spdf <- rmapshaper::ms_simplify(usa_sf(), keep = 0.1) -pal <- colorNumeric("Blues", domain = spdf$pop_2014) -epsg2163 <- leafletCRS( +```{r message=FALSE,warning=FALSE} +north_america <- + rnaturalearth::countries110 |> + dplyr::filter(CONTINENT == "North America") + +epsg9311 <- leafletCRS( crsClass = "L.Proj.CRS", - code = "EPSG:2163", + code = "EPSG:9311", proj4def = "+proj=laea +lat_0=45 +lon_0=-100 +x_0=0 +y_0=0 +a=6370997 +b=6370997 +units=m +no_defs", - resolutions = 2^(16:7)) + resolutions = 2 ^ (16:7) +) -leaflet(spdf, options = leafletOptions(crs = epsg2163)) %>% - addPolygons(weight = 1, color = "#444444", opacity = 1, - fillColor = ~pal(pop_2014), fillOpacity = 0.7, smoothFactor = 0.5, - label = ~paste(name, pop_2014), - labelOptions = labelOptions(direction = "auto")) +pal <- leaflet::colorNumeric(palette = "viridis", domain = north_america$POP_EST) + +plot_na_map <- function(opts = leafletOptions()) { + leaflet(north_america, options = opts) %>% + addPolygons( + weight = 1, + color = "#444444", + opacity = 1, + fillColor = ~ pal(POP_EST), + fillOpacity = 0.7, + smoothFactor = 0.5, + label = ~ paste(SOVEREIGNT, POP_EST), + labelOptions = labelOptions(direction = "auto") + ) +} + +plot_na_map() ``` +```{r message=FALSE,warning=FALSE} +plot_na_map(opts = leafletOptions(crs = epsg9311)) +``` + + # Polar projections It's possible to use polar projections, though you may encounter even more problems and incompatibilities with other Leaflet.js plugins than when using other types of custom projections. diff --git a/vignettes/articles/raster.Rmd b/vignettes/articles/raster.Rmd index ab92e325a..a77d827dc 100644 --- a/vignettes/articles/raster.Rmd +++ b/vignettes/articles/raster.Rmd @@ -9,7 +9,7 @@ knitr::opts_chunk$set( ) ``` -Two-dimensional `SpatRaster` objects (from the [`terra` package](https://CRAN.R-project.org/package=terra)) or `RasterLayer` objects (from the [`raster` package](https://CRAN.R-project.org/package=raster)) can be turned into images and added to Leaflet maps using `addRasterImage()`. +Two-dimensional `SpatRaster` objects (from the [`terra` package](https://CRAN.R-project.org/package=terra)) can be turned into images and added to Leaflet maps using `addRasterImage()`. `addRasterImage()` works by projecting the `SpatRaster` or `RasterLayer` object to [EPSG:3857](https://spatialreference.org/ref/epsg/3857/) and encoding each cell to an RGBA color, to produce a PNG image. That image is then embedded in the map widget. @@ -23,11 +23,11 @@ crs(r) <- "+proj=longlat +datum=WGS84" Because `addRasterImage()` embeds the image in the map widget, it will increase the size of the generated HTML proportionally. In order to avoid unacceptable download times and memory usage, `addRasterImage()` will error when the PNG is beyond the size indicated by the `maxBytes` argument (defaults to 4 megabytes). -If you have a large raster layer, you can provide a larger number of bytes and see how it goes, or use `terra::resample()`, `raster::resample()`, or `raster::aggregate()` to decrease the number of cells. +If you have a large raster layer, you can provide a larger number of bytes and see how it goes, or use `terra::resample()` to decrease the number of cells. # Projection Performance -`addRasterImage()` projects using `terra::project()` or `raster::projectRaster()`, which can take a while on all but the smallest rasters. If you have a large raster layer or expect to call `addRasterImage()` on the same raster layer many times, you can perform the [EPSG:3857](https://spatialreference.org/ref/epsg/3857/) projection yourself (either using `leaflet::projectRasterForLeaflet()` or using another GIS library or program) and call `addRasterImage()` with `project = FALSE`. +`addRasterImage()` projects using `terra::project()`, which can take a while on all but the smallest rasters. If you have a large raster layer or expect to call `addRasterImage()` on the same raster layer many times, you can perform the [EPSG:3857](https://spatialreference.org/ref/epsg/3857/) projection yourself (either using `leaflet::projectRasterForLeaflet()` or using another GIS library or program) and call `addRasterImage()` with `project = FALSE`. Be sure that your pre-projected raster layer is tagged with an accurate extent and CRS, as these values are still needed to place the image in the proper position on the map. @@ -43,18 +43,18 @@ In order to render the raster object as an image, each cell value must be conver ```{r echo=FALSE} suppressPackageStartupMessages({ - library(raster) - r <- suppressWarnings(raster("nc/oisst-sst.nc")) + library(terra) + r <- suppressWarnings(rast("nc/oisst-sst.nc")) }) library(leaflet) # ncdf4 emits partial match warnings ``` ```{r eval=FALSE} -library(raster) +library(terra) library(leaflet) # you can download by accessing https://rstudio.github.io/leaflet/nc/oisst-sst.nc -r <- raster("nc/oisst-sst.nc") +r <- rast("nc/oisst-sst.nc") ``` ```{r} diff --git a/vignettes/articles/shapes.Rmd b/vignettes/articles/shapes.Rmd index 513d9626b..5d6564b42 100644 --- a/vignettes/articles/shapes.Rmd +++ b/vignettes/articles/shapes.Rmd @@ -20,15 +20,13 @@ Leaflet makes it easy to take spatial lines and shapes from R and add them to ma Line and polygon data can come from a variety of sources: -* `SpatialPolygons`, `SpatialPolygonsDataFrame`, `Polygons`, and `Polygon` objects (from the `sp` package) -* `SpatialLines`, `SpatialLinesDataFrame`, `Lines`, and `Line` objects (from the `sp` package) -* `MULTIPOLYGON`, `POLYGON`, `MULTILINESTRING`, and `LINESTRING` objects (from the `sf` package) -* `map` objects (from the `maps` package's `map()` function); use `map(fill = TRUE)` for polygons, `FALSE` for polylines -* Two-column numeric matrix; the first column is longitude and the second is latitude. Polygons are separated by rows of `(NA, NA)`. It is not possible to represent multi-polygons nor polygons with holes using this method; use `SpatialPolygons` instead. +* `MULTIPOLYGON`, `POLYGON`, `MULTILINESTRING`, and `LINESTRING` objects (from the `{sf}` package) +* `map` objects (from `maps::map()`); use `map(fill = TRUE)` for polygons, `FALSE` for polylines +* Two-column numeric matrix; the first column is longitude and the second is latitude. Polygons are separated by rows of `(NA, NA)`. It is not possible to represent multi-polygons nor polygons with holes using this method; use `sf::st_polygon()` instead. ```{r states,message=FALSE,warning=FALSE} # From https://www.census.gov/geo/maps-data/data/cbf/cbf_state.html -states <- sf::st_read("shp/cb_2013_us_state_20m.shp", +states <- sf::read_sf("shp/cb_2013_us_state_20m.shp", layer = "cb_2013_us_state_20m") neStates <- subset(states, states$STUSPS %in% c( @@ -49,12 +47,10 @@ The above example uses the `highlightOptions` parameter to emphasize the current #### Simplifying complex polygons/polylines -Very detailed (i.e. large) shape data can present a problem for Leafet, since it is all eventually passed into the browser and rendered as SVG, which is very expressive and convenient but has scalability limits. In these cases, consider using `rmapshaper::ms_simplify`, which does topology-preserving simplification conveniently from R. +Very detailed (i.e., large) shape data can present a problem for Leafet, since it is all eventually passed into the browser and rendered as SVG, which is very expressive and convenient but has scalability limits. In these cases, consider using `rmapshaper::ms_simplify()`, which does topology-preserving simplification conveniently from R. ```{r message=FALSE,warning=FALSE,eval=FALSE} -library(albersusa) # Requires rgdal, archived. - -fullsize <- usa_sf() +fullsize <- rnaturalearth::countries110 object.size(fullsize) simplified <- rmapshaper::ms_simplify(fullsize) diff --git a/vignettes/articles/shiny.Rmd b/vignettes/articles/shiny.Rmd index e76d60113..087f4daa3 100644 --- a/vignettes/articles/shiny.Rmd +++ b/vignettes/articles/shiny.Rmd @@ -14,7 +14,7 @@ knitr::opts_chunk$set( The Leaflet package includes powerful and convenient features for integrating with Shiny applications. -Most Shiny output widgets are incorporated into an app by including an output (e.g. `plotOutput()`) for the widget in the UI definition, and using a render function (e.g. `renderPlot()`) in the server function. Leaflet maps are no different; in the UI you call `leafletOutput()`, and on the server side you assign a `renderLeaflet()` call to the output. Inside the `renderLeaflet()` expression, you return a Leaflet map object. +Most Shiny output widgets are incorporated into an app by including an output (e.g., `plotOutput()`) for the widget in the UI definition, and using a render function (e.g., `renderPlot()`) in the server function. Leaflet maps are no different; in the UI you call `leafletOutput()`, and on the server side you assign a `renderLeaflet()` call to the output. Inside the `renderLeaflet()` expression, you return a Leaflet map object. ```{r eval=FALSE} library(shiny) diff --git a/vignettes/articles/showhide.Rmd b/vignettes/articles/showhide.Rmd index 00574ca5e..408ccf871 100644 --- a/vignettes/articles/showhide.Rmd +++ b/vignettes/articles/showhide.Rmd @@ -41,7 +41,7 @@ Groups and [Layer IDs](https://rstudio.github.io/leaflet/articles/shiny.html#und You generally provide one `group` value for the entire `addMarkers()` call, and you can reuse that same `group` value in future `add*()` calls to add to that group's membership (as in the example above). -`layerId` arguments are *always* vectorized: when calling e.g. `addMarkers()` you need to provide one layer ID per marker, and they must all be unique. If you add a circle with a layer ID of `"foo"` and later add a different shape with the same layer ID, the original circle will be removed. +`layerId` arguments are *always* vectorized: when calling e.g., `addMarkers()` you need to provide one layer ID per marker, and they must all be unique. If you add a circle with a layer ID of `"foo"` and later add a different shape with the same layer ID, the original circle will be removed. diff --git a/vignettes/articles/widget.Rmd b/vignettes/articles/widget.Rmd index c42760d39..251f3c606 100644 --- a/vignettes/articles/widget.Rmd +++ b/vignettes/articles/widget.Rmd @@ -25,7 +25,7 @@ library(magrittr) leaflet(options = leafletOptions(minZoom = 0, maxZoom = 18)) ``` -The `leafletOptions()` can be passed any option described in the leaflet [reference document](https://web.archive.org/web/20220702182250/https://leafletjs.com/reference-1.3.4.html#map-option). Using the `leafletOptions()`, you can set a custom [CRS](https://en.wikipedia.org/wiki/Spatial_reference_system) and have your map displayed in a non spherical mercator projection as described in [projections](https://rstudio.github.io/leaflet/articles/projections.html). +The `leafletOptions()` can be passed any option described in the leaflet [reference document](https://web.archive.org/web/20220702182250/https://leafletjs.com/reference-1.3.4.html#map-option). Using the `leafletOptions()`, you can set a custom [CRS](https://en.wikipedia.org/wiki/Spatial_reference_system) and have your map displayed in a non spherical Mercator projection as described in [projections](https://rstudio.github.io/leaflet/articles/projections.html). # Map Methods @@ -42,18 +42,15 @@ Both `leaflet()` and the map layer functions have an optional `data` parameter t - From base R: - lng/lat matrix - data frame with lng/lat columns -- From the [**sp** package](https://cran.rstudio.com/package=sp): - - `SpatialPoints[DataFrame]` - - `Line`/`Lines` - - `SpatialLines[DataFrame]` - - `Polygon`/`Polygons` - - `SpatialPolygons[DataFrame]` -- From the [**maps** package](https://cran.rstudio.com/package=maps): +- From the `{maps}` package: - the data frame from returned from `map()` +- Simple features from the `{sf}` package. -The `data` argument is used to derive spatial data for functions that need it; for example, if `data` is a `SpatialPolygonsDataFrame` object, then calling `addPolygons` on that map widget will know to add the polygons from that `SpatialPolygonsDataFrame`. +`leaflet()` is, additionally, back-compatible with `{sp}` `SpatailDataFrames`, although the use of these is [discouraged](https://r-spatial.org/r/2023/04/10/evolution3.html) for new users. -It is straightforward to derive these variables from **sp** objects since they always represent spatial data in the same way. On the other hand, for a normal matrix or data frame, any numeric column could potentially contain spatial data. So we resort to guessing based on column names: +The `data` argument is used to derive spatial data for functions that need it; for example, if `data` is a `{sf}` Simple Features data.frame, then calling `addPolygons()` on that map widget will know to add the polygons from the geometry column. + +It is straightforward to derive these variables from `{sf}` objects since they always represent spatial data in the same way. On the other hand, for a normal matrix or data frame, any numeric column could potentially contain spatial data. So we resort to guessing based on column names: - the latitude variable is guessed by looking for columns named `lat` or `latitude` (case-insensitive) - the longitude variable is guessed by looking for `lng`, `long`, or `longitude` @@ -81,26 +78,28 @@ leaflet() %>% addCircles(data = df) leaflet() %>% addCircles(data = df, lat = ~ Lat, lng = ~ Long) ``` -Below are examples of using **sp** and **maps**, respectively: +Below are examples of using `{sf}` and `{maps}`, respectively: ```{r message=FALSE} -library(sp) -Sr1 = Polygon(cbind(c(2, 4, 4, 1, 2), c(2, 3, 5, 4, 2))) -Sr2 = Polygon(cbind(c(5, 4, 2, 5), c(2, 3, 2, 2))) -Sr3 = Polygon(cbind(c(4, 4, 5, 10, 4), c(5, 3, 2, 5, 5))) -Sr4 = Polygon(cbind(c(5, 6, 6, 5, 5), c(4, 4, 3, 3, 4)), hole = TRUE) -Srs1 = Polygons(list(Sr1), "s1") -Srs2 = Polygons(list(Sr2), "s2") -Srs3 = Polygons(list(Sr4, Sr3), "s3/4") -SpP = SpatialPolygons(list(Srs1, Srs2, Srs3), 1:3) -leaflet(height = "300px") %>% addPolygons(data = SpP) +library(sf) +polygon1 <- st_polygon(list(cbind(c(2, 4, 4, 1, 2), c(2, 3, 5, 4, 2)))) +polygon2 <- st_polygon(list(cbind(c(5, 4, 2, 5), c(2, 3, 2, 2)))) +polygon3 <- st_polygon(list(cbind(c(4, 4, 5, 10, 4), c(5, 3, 2, 5, 5)))) +polygon4 <- st_polygon(list(cbind(c(5, 6, 6, 5, 5), c(4, 4, 3, 3, 4)))) +multi_polygon <- st_multipolygon(list( + list(cbind(c(4, 4, 5, 10, 4), c(5, 3, 2, 5, 5))), + list(cbind(c(5, 6, 6, 5, 5), c(4, 4, 3, 3, 4))) +)) +sf_polygons <- st_sf(geometry = st_sfc(polygon1, polygon2, multi_polygon)) +leaflet(height = "300px") %>% addPolygons(data = sf_polygons) + library(maps) mapStates = map("state", fill = TRUE, plot = FALSE) -leaflet(data = mapStates) %>% addTiles() %>% +leaflet(data = mapStates) %>% + addTiles() %>% addPolygons(fillColor = topo.colors(10, alpha = NULL), stroke = FALSE) ``` - # The Formula Interface The arguments of all layer functions can take normal R objects, such as a numeric vector for the `lat` argument, or a character vector of colors for the `color` argument. They can also take a one-sided formula, in which case the formula will be evaluated using the `data` argument as the environment. For example, `~ x` means the variable `x` in the data object, and you can write arbitrary expressions on the right-hand side, e.g., `~ sqrt(x + 1)`.