@@ -206,8 +206,8 @@ epsg3857 <- "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y
206
206
# ' @param x a \code{\link[terra]{SpatRaster}} or a \code{RasterLayer} object--see \code{\link[raster]{raster}}
207
207
# ' @param colors the color palette (see \code{\link{colorNumeric}}) or function
208
208
# ' to use to color the raster values (hint: if providing a function, set
209
- # ' \code{na.color} to \code{"#00000000"} to make \code{NA} areas transparent).
210
- # ' The palette is ignored if \code{x} is a SpatRaster with a color table or if
209
+ # ' \code{na.color} to \code{"#00000000"} to make \code{NA} areas transparent).
210
+ # ' The palette is ignored if \code{x} is a SpatRaster with a color table or if
211
211
# ' it has RGB channels.
212
212
# ' @param opacity the base opacity of the raster, expressed from 0 to 1
213
213
# ' @param attribution the HTML string to show as the attribution for this layer
@@ -227,15 +227,20 @@ epsg3857 <- "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y
227
227
# ' (before base64 encoding); defaults to 4MB.
228
228
# ' @template data-getMapData
229
229
# '
230
+ # ' @seealso \code{\link{addRasterLegend}} for an easy way to add a legend for a
231
+ # ' SpatRaster with a color table.
232
+ # '
230
233
# ' @examples
231
234
# ' \donttest{library(raster)
232
235
# '
233
236
# ' r <- raster(xmn = -2.8, xmx = -2.79, ymn = 54.04, ymx = 54.05, nrows = 30, ncols = 30)
234
237
# ' values(r) <- matrix(1:900, nrow(r), ncol(r), byrow = TRUE)
235
238
# ' crs(r) <- CRS("+init=epsg:4326")
236
239
# '
240
+ # ' pal <- colorNumeric("Spectral", domain = c(0, 1000))
237
241
# ' leaflet() %>% addTiles() %>%
238
- # ' addRasterImage(r, colors = "Spectral", opacity = 0.8)
242
+ # ' addRasterImage(r, colors = pal, opacity = 0.8) %>%
243
+ # ' addLegend(pal = pal, values = c(0, 1000))
239
244
# ' }
240
245
# ' @export
241
246
addRasterImage <- function (
@@ -285,6 +290,76 @@ addRasterImage <- function(
285
290
}
286
291
287
292
293
+ # ' Add a color legend for a SpatRaster to a map
294
+ # '
295
+ # ' A function for adding a [legend][addLegend()] that is specifically designed
296
+ # ' for [terra::SpatRaster] objects, with categorical values, that carry their
297
+ # ' own [color table][terra::coltab()].
298
+ # '
299
+ # ' @param map a map widget object
300
+ # ' @param x a [SpatRaster][terra::SpatRaster] object with a color table
301
+ # ' @param layer the layer of the raster to target
302
+ # ' @param ... additional arguments to pass through to [addLegend()]
303
+ # ' @seealso [addRasterImage()]
304
+ # ' @examples
305
+ # '
306
+ # ' library(terra)
307
+ # '
308
+ # ' r <- rast("/vsicurl/https://geodata.ucdavis.edu/test/pr_nlcd.tif")
309
+ # ' leaflet() |>
310
+ # ' addTiles() |>
311
+ # ' addRasterImage(r, opacity = 0.75) |>
312
+ # ' addRasterLegend(r, opacity = 0.75)
313
+ # '
314
+ # ' plot.new() # pause in interactive mode
315
+ # '
316
+ # ' rr <- r
317
+ # ' levels(rr) <- NULL
318
+ # ' leaflet() |>
319
+ # ' addTiles() |>
320
+ # ' addRasterImage(rr, opacity = 0.75) |>
321
+ # ' addRasterLegend(rr, opacity = 0.75)
322
+ # '
323
+ # ' @md
324
+ # ' @export
325
+ addRasterLegend <- function (map , x , layer = 1 , ... ) {
326
+ stopifnot(inherits(x , " SpatRaster" ))
327
+ stopifnot(length(layer ) == 1 && layer > 0 && layer < = terra :: nlyr(x ))
328
+
329
+ # Retrieve the color table from the layer. If one doesn't exist, that means
330
+ # the raster was colored some other way, like using colorFactor or something,
331
+ # and the regular addLegend() is designed for those cases.
332
+ ct <- terra :: coltab(x )[[layer ]]
333
+ if (is.null(ct )) {
334
+ stop(" addRasterLegend() can only be used on layers with color tables (see ?terra::coltab). Otherwise, use addLegend()." )
335
+ }
336
+
337
+ # Create a data frame that has value and color columns
338
+ # Extract the colors in #RRGGBBAA format
339
+ color_info <- data.frame (
340
+ value = ct [[1 ]],
341
+ color = grDevices :: rgb(ct $ red / 255 , ct $ green / 255 , ct $ blue / 255 , ct $ alpha / 255 )
342
+ )
343
+
344
+ lvls <- terra :: levels(x )[[layer ]]
345
+
346
+ res <- if (is.data.frame(lvls )) {
347
+ # Use the labels from levels(x), and look up the matching colors in the
348
+ # color table
349
+ colnames(lvls ) <- c(" value" , " label" )
350
+ base :: merge(color_info , lvls , by.x = " value" , by.y = 1 )
351
+ } else {
352
+ cbind(color_info , label = color_info $ value )
353
+ }
354
+
355
+ # Drop values that aren't part of the layer
356
+ res <- res [res [[" value" ]] %in% terra :: values(x ),]
357
+
358
+ addLegend(map , colors = res [[" color" ]], labels = res [[" label" ]], ... )
359
+ }
360
+
361
+
362
+
288
363
addRasterImage_RasterLayer <- function (
289
364
map ,
290
365
x ,
@@ -382,11 +457,11 @@ addRasterImage_SpatRaster <- function(
382
457
}
383
458
384
459
raster_is_factor <- terra :: is.factor(x )
385
-
460
+
386
461
# there 1.5-50 has terra::has.colors(x)
387
462
ctab <- terra :: coltab(x )[[1 ]]
388
463
has_colors <- ! is.null(ctab )
389
-
464
+
390
465
method <- match.arg(method )
391
466
if (method == " ngb" ) method = " near"
392
467
if (method == " auto" ) {
@@ -426,7 +501,7 @@ addRasterImage_SpatRaster <- function(
426
501
if (has_colors ) {
427
502
colors <- rgb(ctab [,2 ], ctab [,3 ], ctab [,4 ], ctab [,5 ], maxColorValue = 255 )
428
503
domain <- ctab [,1 ]
429
- }
504
+ }
430
505
colors <- colorFactor(colors , domain = domain , na.color = " #00000000" , alpha = TRUE )
431
506
} else {
432
507
# 'numeric'
0 commit comments