diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index 3ec072899..01d2a4e1a 100644 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -17,8 +17,6 @@ jobs: uses: rstudio/shiny-workflows/.github/workflows/website.yaml@v1 routine: uses: rstudio/shiny-workflows/.github/workflows/routine.yaml@v1 - with: - node-version: '12' R-CMD-check: uses: rstudio/shiny-workflows/.github/workflows/R-CMD-check.yaml@v1 with: diff --git a/DESCRIPTION b/DESCRIPTION index 3f1d9c87c..343e9edc6 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -60,7 +60,6 @@ Imports: magrittr, methods, png, - raster (>= 3.6.3), RColorBrewer, rlang, scales (>= 1.0.0), @@ -73,12 +72,13 @@ Suggests: maps, purrr, R6, + raster (>= 3.6-3), RJSONIO, rmarkdown, s2, shiny (>= 1.0.0), sp, - terra, + terra (>= 1.6-3), testthat (>= 3.0.0) Config/Needs/website: dplyr, ncdf4, rnaturalearth, tidyverse/tidytemplate Config/testthat/edition: 3 diff --git a/NEWS.md b/NEWS.md index fdd730d70..82edeb197 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,7 @@ # leaflet (development version) +* `{leaflet}` no longer installs `{raster}` `{terra}` by default (@olivroy, #943). If you are using leaflet interactively, you will receive a prompt to install it. + # leaflet 2.2.3 * `{leaflet}` is now licensed under the MIT license (was GPL-2) (#958). @@ -14,8 +16,6 @@ * 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) - * `addProviderTiles()` will now error if the chosen `provider` does not match any currently loaded provider (by default, those in `providers`). This behaviour can be toggled off by setting the new `check` argument to `FALSE` (@jack-davison, #929) # leaflet 2.2.2 diff --git a/R/layers.R b/R/layers.R index 946cbd69d..a8269a7df 100644 --- a/R/layers.R +++ b/R/layers.R @@ -240,7 +240,7 @@ epsg3857 <- "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y #' @param method the method used for computing values of the new, projected raster image. #' `"bilinear"` (the default) is appropriate for continuous data, #' `"ngb"` - nearest neighbor - is appropriate for categorical data. -#' Ignored if `project = FALSE`. See [raster::projectRaster()] for details. +#' Ignored if `project = FALSE`. See [terra::project()] for details. #' @param maxBytes the maximum number of bytes to allow for the projected image #' (before base64 encoding); defaults to 4MB. #' @param options a list of additional options, intended to be provided by @@ -250,12 +250,12 @@ epsg3857 <- "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y #' @seealso [addRasterLegend()] for an easy way to add a legend for a #' SpatRaster with a color table. #' -#' @examples -#' \donttest{library(raster) +#' @examplesIf rlang::is_installed("terra") +#' \donttest{ #' -#' r <- raster(xmn = -2.8, xmx = -2.79, ymn = 54.04, ymx = 54.05, nrows = 30, ncols = 30) -#' values(r) <- matrix(1:900, nrow(r), ncol(r), byrow = TRUE) -#' crs(r) <- CRS("+init=epsg:4326") +#' r <- terra::rast(xmin = -2.8, xmax = -2.79, ymin = 54.04, ymax = 54.05, nrows = 30, ncols = 30) +#' terra::values(r) <- matrix(1:900, nrow(r), ncol(r), byrow = TRUE) +#' terra::crs(r) <- "epsg:4326" #' #' pal <- colorNumeric("Spectral", domain = c(0, 1000)) #' leaflet() %>% addTiles() %>% @@ -324,7 +324,7 @@ addRasterImage <- function( #' @param layer the layer of the raster to target #' @param ... additional arguments to pass through to [addLegend()] #' @seealso [addRasterImage()] -#' @examplesIf interactive() +#' @examplesIf interactive() && rlang::is_installed("terra") #' #' library(terra) #' @@ -346,6 +346,7 @@ addRasterImage <- function( #' @export addRasterLegend <- function(map, x, layer = 1, ...) { stopifnot(inherits(x, "SpatRaster")) + rlang::check_installed("terra (>= 1.6-3)") stopifnot(length(layer) == 1 && layer > 0 && layer <= terra::nlyr(x)) # might as well do this here and only once. Subsetting would otherwise have @@ -419,6 +420,8 @@ addRasterImage_RasterLayer <- function( options = gridOptions(), data = getMapData(map) ) { + rlang::check_installed("raster") + options$opacity <- opacity options$attribution <- attribution @@ -442,8 +445,8 @@ addRasterImage_RasterLayer <- function( bounds <- raster::extent( raster::projectExtent( - raster::projectExtent(x, crs = sp::CRS(epsg3857)), - crs = sp::CRS(epsg4326) + raster::projectExtent(x, crs = raster::crs(epsg3857)), + crs = raster::crs(epsg4326) ) ) @@ -652,6 +655,7 @@ addRasterImage_SpatRaster <- function( #' @export projectRasterForLeaflet <- function(x, method) { if (inherits(x, "SpatRaster")) { + rlang::check_installed("terra (>= 1.6-3)") if (method == "ngb") { method = "near" } @@ -661,10 +665,11 @@ projectRasterForLeaflet <- function(x, method) { method = method ) } else { + rlang::check_installed("raster") raster_is_factor <- raster::is.factor(x) projected <- raster::projectRaster( x, - raster::projectExtent(x, crs = sp::CRS(epsg3857)), + raster::projectExtent(x, crs = raster::crs(epsg3857)), method = method ) # if data is factor data, make the result factors as well. diff --git a/R/leaflet.R b/R/leaflet.R index c654186c4..b0e476226 100644 --- a/R/leaflet.R +++ b/R/leaflet.R @@ -29,10 +29,14 @@ leafletSizingPolicy <- function( #' Create a Leaflet map widget #' -#' This function creates a Leaflet map widget using \pkg{htmlwidgets}. The +#' @description +#' * `leaflet()` creates a Leaflet map widget using \pkg{htmlwidgets}. The #' widget can be rendered on HTML pages generated from R Markdown, Shiny, or #' other applications. +#' * `leafletOptions()`: options for map creation +#' * `leafletCRS()`: class to create custom CRS. #' +#' @details #' The `data` argument is only needed if you are going to reference #' variables in this object later in map layers. For example, `data` can be #' a data frame containing columns `latitude` and `longitude`, then @@ -152,13 +156,12 @@ mapOptions <- function(map, zoomToLimits = c("always", "first", "never")) { #' @param minZoom Minimum zoom level of the map. Overrides any `minZoom` set on map layers. #' @param maxZoom Maximum zoom level of the map. This overrides any `maxZoom` set on map layers. #' @param crs Coordinate Reference System to use. Don't change this if you're not sure what it means. -#' @seealso [leafletCRS()] for creating a custom CRS. #' @param worldCopyJump With this option enabled, the map tracks when you pan #' to another "copy" of the world and seamlessly jumps to the original #' one so that all overlays like markers and vector layers are still visible. #' @param preferCanvas Whether leaflet.js Paths should be rendered on a Canvas renderer. #' @param ... other options used for leaflet.js map creation. -#' @describeIn leaflet Options for map creation +#' @rdname leaflet #' @seealso See for details and more options. #' @export leafletOptions <- function( @@ -200,7 +203,7 @@ crsClasses <- list("L.CRS.EPSG3857", "L.CRS.EPSG4326", "L.CRS.EPSG3395", #' Proj4Leaflet will use this in the getSize method, otherwise #' defaulting to Leaflet's default CRS size #' @param tileSize DEPRECATED! Specify the tilesize in the [tileOptions()] argument. -#' @describeIn leaflet class to create a custom CRS +#' @rdname leaflet #' @export leafletCRS <- function( crsClass = "L.CRS.EPSG3857", diff --git a/R/normalize-terra.R b/R/normalize-terra.R index f5e8ff6ff..40cd304d3 100644 --- a/R/normalize-terra.R +++ b/R/normalize-terra.R @@ -51,7 +51,7 @@ polygonData.SpatVector <- function(obj) { # helpers ----------------------------------------------------------------- check_crs_terra <- function(x) { - rlang::check_installed("terra") + rlang::check_installed("terra (>= 1.6-3)") crs <- terra::crs(x) # Don't have enough information to check diff --git a/inst/examples/geojson.R b/inst/examples/geojson.R index 103c24471..f87157ddb 100644 --- a/inst/examples/geojson.R +++ b/inst/examples/geojson.R @@ -1,17 +1,16 @@ library(leaflet) -library(sp) #'

#' The V8 part is simply to read the JSON embeded in the Javascript.
-#' For a geojson file `jsonlite::fromfromJSON()` or `geojsonio::regeojson_read()` will do +#' For a geojson file `jsonlite::fromJSON()` or `geojsonio::geojson_read()` will do #' jsURL <- "https://rawgit.com/Norkart/Leaflet-MiniMap/master/example/local_pubs_restaurant_norway.js" v8 <- V8::v8() v8$source(jsURL) geoJson <- geojsonio::as.json(v8$get("pubsGeoJSON")) -# This is the kicker, convert geojson to a Spatial object. +# This is the kicker, convert geojson to a sf object. # This then allows us to use formulas in our markers, polygons etc. -spdf <- geojsonio::geojson_sp(geoJson) +spdf <- geojsonio::geojson_sf(geoJson) icons <- awesomeIconList( pub = makeAwesomeIcon(icon = "glass", library = "fa", markerColor = "red"), @@ -34,7 +33,7 @@ leaflet() %>% #' Another examples this time with polygons url <- "https://www.partners-popdev.org/wp-content/themes/original-child/vendor/Geojson/States/Maharashtra.geojson" -mhSPDF <- geojsonio::geojson_read(url, what = "sp") +mhSPDF <- sf::st_read(url) cols <- colorFactor(topo.colors(nrow(mhSPDF)), mhSPDF$NAME_2) diff --git a/inst/examples/leaflet.R b/inst/examples/leaflet.R index 74d28ee69..092d14633 100644 --- a/inst/examples/leaflet.R +++ b/inst/examples/leaflet.R @@ -152,4 +152,3 @@ m %>% addCircleMarkers(~lng, ~lat, radius = ~size, color = ~greens(value), fillOpacity = 0.5) } - diff --git a/inst/examples/normalize.R b/inst/examples/normalize.R index fea03b6e5..821018574 100644 --- a/inst/examples/normalize.R +++ b/inst/examples/normalize.R @@ -1,3 +1,4 @@ +# obsolete library(leaflet) library(sp) library(maps) diff --git a/inst/examples/proj4Leaflet-PolarProjections.R b/inst/examples/proj4Leaflet-PolarProjections.R index daa5bfb67..0d1b27a15 100644 --- a/inst/examples/proj4Leaflet-PolarProjections.R +++ b/inst/examples/proj4Leaflet-PolarProjections.R @@ -103,8 +103,8 @@ resolutions <- c(8192, 4096, 2048, 1024, 512, 256) zoom <- 0 maxZoom <- 5 -border <- geojsonio::geojson_read(system.file("examples/Seamask_medium_res_polygon.kml", package = "leaflet"), what = "sp") -points <- geojsonio::geojson_read(system.file("examples/Historic_sites_and_monuments_point.kml", package = "leaflet"), what = "sp") +border <- sf::st_read(system.file("examples/Seamask_medium_res_polygon.kml", package = "leaflet")) +points <- sf::st_read(system.file("examples/Historic_sites_and_monuments_point.kml", package = "leaflet")) crsAntartica <- leafletCRS( crsClass = "L.Proj.CRS", diff --git a/man/addRasterImage.Rd b/man/addRasterImage.Rd index 675ac0d0b..3260ca415 100644 --- a/man/addRasterImage.Rd +++ b/man/addRasterImage.Rd @@ -51,7 +51,7 @@ coordinates} \item{method}{the method used for computing values of the new, projected raster image. \code{"bilinear"} (the default) is appropriate for continuous data, \code{"ngb"} - nearest neighbor - is appropriate for categorical data. -Ignored if \code{project = FALSE}. See \code{\link[raster:projectRaster]{raster::projectRaster()}} for details.} +Ignored if \code{project = FALSE}. See \code{\link[terra:project]{terra::project()}} for details.} \item{maxBytes}{the maximum number of bytes to allow for the projected image (before base64 encoding); defaults to 4MB.} @@ -93,17 +93,19 @@ maps, you can perform the projection ahead of time using \code{project = FALSE}. } \examples{ -\donttest{library(raster) +\dontshow{if (rlang::is_installed("terra")) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} +\donttest{ -r <- raster(xmn = -2.8, xmx = -2.79, ymn = 54.04, ymx = 54.05, nrows = 30, ncols = 30) -values(r) <- matrix(1:900, nrow(r), ncol(r), byrow = TRUE) -crs(r) <- CRS("+init=epsg:4326") +r <- terra::rast(xmin = -2.8, xmax = -2.79, ymin = 54.04, ymax = 54.05, nrows = 30, ncols = 30) +terra::values(r) <- matrix(1:900, nrow(r), ncol(r), byrow = TRUE) +terra::crs(r) <- "epsg:4326" pal <- colorNumeric("Spectral", domain = c(0, 1000)) leaflet() \%>\% addTiles() \%>\% addRasterImage(r, colors = pal, opacity = 0.8) \%>\% addLegend(pal = pal, values = c(0, 1000)) } +\dontshow{\}) # examplesIf} } \seealso{ \code{\link[=addRasterLegend]{addRasterLegend()}} for an easy way to add a legend for a diff --git a/man/addRasterLegend.Rd b/man/addRasterLegend.Rd index fd2d3a05c..dd4a9f297 100644 --- a/man/addRasterLegend.Rd +++ b/man/addRasterLegend.Rd @@ -21,7 +21,7 @@ for \link[terra:SpatRaster-class]{terra::SpatRaster} objects, with categorical v own \link[terra:colors]{color table}. } \examples{ -\dontshow{if (interactive()) withAutoprint(\{ # examplesIf} +\dontshow{if (interactive() && rlang::is_installed("terra")) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} library(terra) diff --git a/man/leaflet.Rd b/man/leaflet.Rd index e1f1f1fd2..1c8781077 100644 --- a/man/leaflet.Rd +++ b/man/leaflet.Rd @@ -104,9 +104,13 @@ A HTML widget object, on which we can add graphics layers using \verb{\%>\%} (see examples). } \description{ -This function creates a Leaflet map widget using \pkg{htmlwidgets}. The +\itemize{ +\item \code{leaflet()} creates a Leaflet map widget using \pkg{htmlwidgets}. The widget can be rendered on HTML pages generated from R Markdown, Shiny, or other applications. +\item \code{leafletOptions()}: options for map creation +\item \code{leafletCRS()}: class to create custom CRS. +} } \details{ The \code{data} argument is only needed if you are going to reference @@ -116,13 +120,6 @@ we may add a circle layer to the map by \code{leaflet(data) \%>\% addCircles(lat = ~latitude, lng = ~longitude)}, where the variables in the formulae will be evaluated in the \code{data}. } -\section{Functions}{ -\itemize{ -\item \code{leafletOptions()}: Options for map creation - -\item \code{leafletCRS()}: class to create a custom CRS - -}} \examples{ # !formatR library(leaflet) @@ -278,10 +275,7 @@ m \%>\% addCircleMarkers(~lng, ~lat, radius = ~size, color = ~greens(value), fillOpacity = 0.5) } - } \seealso{ -\code{\link[=leafletCRS]{leafletCRS()}} for creating a custom CRS. - See \url{https://web.archive.org/web/20220702182250/https://leafletjs.com/reference-1.3.4.html#map-option} for details and more options. } diff --git a/scripts/raster.R b/scripts/raster.R index 347b04dc7..70ec06e65 100644 --- a/scripts/raster.R +++ b/scripts/raster.R @@ -24,7 +24,6 @@ plot(r - invn) r <- raster(xmn = -60, xmx = -25, ymn = 70, ymx = 81, nrows = 30, ncols = 30) set.seed(0) values(r) <- matrix(sample(1:5, 900, replace = TRUE), nrow(r), ncol(r), byrow = TRUE) -# crs(r) <- CRS("+init=epsg:4326") l <- function(method = "auto") { leaflet() %>% addTiles() %>% diff --git a/tests/testthat/helper.R b/tests/testthat/helper.R index e268c0e7a..ba37e0b07 100644 --- a/tests/testthat/helper.R +++ b/tests/testthat/helper.R @@ -14,4 +14,8 @@ create_square <- function(width = 2, lng = 0, lat = 0, hole = FALSE, type = sp:: } } - +expect_maps_equal <- function(m1, m2) { + attr(m1$x, "leafletData") <- NULL + attr(m2$x, "leafletData") <- NULL + expect_equal(m1, m2, ignore_function_env = TRUE, ignore_formula_env = TRUE) +} diff --git a/tests/testthat/test-normalize-2.R b/tests/testthat/test-normalize-2.R index 5ebbf52fc..37bfb35b7 100644 --- a/tests/testthat/test-normalize-2.R +++ b/tests/testthat/test-normalize-2.R @@ -1,10 +1,3 @@ - -expect_maps_equal <- function(m1, m2) { - attr(m1$x, "leafletData") <- NULL - attr(m2$x, "leafletData") <- NULL - expect_equal(m1, m2, ignore_function_env = TRUE, ignore_formula_env = TRUE) -} - normalize_multipolygon <- function(df) { # A multipolygon is a nested list of lng/lat data frames. Each data frame # represents a single polygon (may be an island or a hole), that is, a series diff --git a/tests/testthat/test-normalize-3.R b/tests/testthat/test-normalize-3.R index 209b2ee5e..0c8df45a5 100644 --- a/tests/testthat/test-normalize-3.R +++ b/tests/testthat/test-normalize-3.R @@ -1,13 +1,6 @@ - -expect_maps_equal <- function(m1, m2) { - attr(m1$x, "leafletData") <- NULL - attr(m2$x, "leafletData") <- NULL - expect_equal(m1, m2, ignore_function_env = TRUE, ignore_formula_env = TRUE) -} - - test_that("normalize terra", { skip_if_not_installed("raster") + skip_if_not_installed("terra") skip_if_not_installed("sp") library(terra) @@ -20,7 +13,7 @@ test_that("normalize terra", { leaflet(x) %>% addTiles() %>% addPolygons() } - poldata <- vect(gadmCHE) + poldata <- terra::vect(gadmCHE) crs(poldata) <- "+proj=longlat +datum=WGS84" (r1 <- pgontest(poldata)) @@ -30,7 +23,7 @@ test_that("normalize terra", { ### lines ----------------------------------------------------------------- - lindata <- vect(atlStorms2005) + lindata <- terra::vect(atlStorms2005) crs(lindata) <- "+proj=longlat +datum=WGS84" plinetest <- function(x) { @@ -43,7 +36,7 @@ test_that("normalize terra", { expect_maps_equal(l1, l2) ### points ---------------------------------------------------------------- - ptsdata <- vect(breweries91) + ptsdata <- terra::vect(breweries91) crs(ptsdata) <- "+proj=longlat +datum=WGS84" (p1 <- leaflet() %>% addTiles() %>% addCircleMarkers(data = ptsdata)) @@ -66,7 +59,7 @@ test_that("normalize terra", { )) # these "commented" Spatial objects need to go through # sf for terra to understand them properly - vpolys = vect(sf::st_as_sf(spolys )) + vpolys = terra::vect(sf::st_as_sf(spolys )) (l101 <- leaflet(spolys) %>% addPolygons()) (l102 <- leaflet(vpolys) %>% addPolygons()) expect_maps_equal(l101, l102) @@ -74,8 +67,8 @@ test_that("normalize terra", { (l104 <- leaflet(vpolys) %>% addPolylines()) expect_maps_equal(l103, l104) - slines <- SpatialLines(list( - Lines(list( + slines <- sp::SpatialLines(list( + sp::Lines(list( create_square(type = Line), create_square(, 5, 5, type = Line), create_square(1, hole = TRUE, type = Line), @@ -83,7 +76,7 @@ test_that("normalize terra", { create_square(0.4, 4.25, 4.25, hole = TRUE, type = Line) ), "A") )) - vslines <- vect(slines) + vslines <- terra::vect(slines) (l105 <- leaflet(slines) %>% addPolylines()) (l106 <- leaflet(vslines) %>% addPolylines()) expect_maps_equal(l105, l106) diff --git a/tests/testthat/test-raster.R b/tests/testthat/test-raster.R index 8357013f7..8bd657c0b 100644 --- a/tests/testthat/test-raster.R +++ b/tests/testthat/test-raster.R @@ -1,10 +1,3 @@ - -expect_maps_equal <- function(m1, m2) { - attr(m1$x, "leafletData") <- NULL - attr(m2$x, "leafletData") <- NULL - expect_equal(m1, m2, ignore_function_env = TRUE, ignore_formula_env = TRUE) -} - # Some proj4string values differ only by one having whole numbers represented as # x while others have x.0. So, strip each trailing .0 value. normalize_zero_values <- function(str) { @@ -12,8 +5,8 @@ normalize_zero_values <- function(str) { } test_that("rasters", { + skip_if_not_installed("raster") skip_if_not_installed("terra") - library(terra) library(raster) @@ -37,7 +30,7 @@ test_that("rasters", { expect_maps_equal(r1, r2) - # test with color map + # test with color map r <- terra::rast(ncols=10, nrows=10, vals=rep_len(10:15, length.out=100), xmin=0, xmax=10^6, ymin=0, ymax=10^6, crs=pmerc) r[5,] <- NA coltab(r) <- c(rep("#FFFFFF", 10), rainbow(6, end=.9)) diff --git a/vignettes/articles/projections.Rmd b/vignettes/articles/projections.Rmd index 232750ed0..eae39bf99 100644 --- a/vignettes/articles/projections.Rmd +++ b/vignettes/articles/projections.Rmd @@ -82,7 +82,7 @@ This example uses data from the `{rnaturalearth}` package and projects it to the ```{r message=FALSE,warning=FALSE} north_america <- rnaturalearth::countries110 |> - dplyr::filter(CONTINENT == "North America") + dplyr::filter(.data$CONTINENT == "North America") epsg9311 <- leafletCRS( crsClass = "L.Proj.CRS",