Skip to content

Commit

Permalink
export addGeoRaster & addGeotiff #25
Browse files Browse the repository at this point in the history
  • Loading branch information
tim-salabim committed Jul 19, 2020
1 parent 6f2c88a commit ff4a8e0
Show file tree
Hide file tree
Showing 5 changed files with 384 additions and 5 deletions.
7 changes: 7 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ export(addCopyExtent)
export(addExtent)
export(addFeatures)
export(addFgb)
export(addGeoRaster)
export(addGeotiff)
export(addHomeButton)
export(addImageQuery)
export(addLocalFile)
Expand All @@ -15,6 +17,7 @@ export(addStarsRGB)
export(addStaticLabels)
export(addTileFolder)
export(clip2sfc)
export(colorOptions)
export(garnishMap)
export(removeHomeButton)
export(removeMouseCoordinates)
Expand All @@ -40,5 +43,9 @@ importFrom(raster,projection)
importFrom(raster,sampleRegular)
importFrom(sf,st_as_sfc)
importFrom(sf,st_bbox)
importFrom(sf,st_is_longlat)
importFrom(sf,st_transform)
importFrom(stars,st_as_stars)
importFrom(stars,st_warp)
importFrom(stars,write_stars)
importFrom(stats,quantile)
165 changes: 160 additions & 5 deletions R/addGeoRaster.R
Original file line number Diff line number Diff line change
@@ -1,3 +1,61 @@
#' Add stars/raster image to a leaflet map using optimised rendering.
#'
#' @details
#' This uses the leaflet plugin 'georaster-layer-for-leaflet' to render raster data.
#' See \url{https://github.com/GeoTIFF/georaster-layer-for-leaflet} for details.
#' The clue is that rendering uses simple nearest neighbor interpolation on-the-fly
#' to ensure smooth rendering. This enables handling of larger rasters than with
#' the standard \code{\link[leaflet]{addRasterImage}}.
#'
#' @param map the map to add the raster data to.
#' @param x the stars/raster object to be rendered.
#' @param group he name of the group this raster image should belong to.
#' @param layerId the layerId.
#' @param resolution the target resolution for the simple nearest neighbor interpolation.
#' Larger values will result in more detailed rendering, but may impact performance.
#' Default is 96 (pixels).
#' @param opacity opacity of the rendered layer.
#' @param options options to be passed to the layer.
#' See \code{\link[leaflet]{tileOptions}} for details.
#' @param colorOptions list defining the palette, breaks and na.color to be used.
#' @param project whether to project the RasterLayer to conform with leaflets
#' expected crs. Defaults to \code{TRUE} and things are likely to go haywire
#' if set to \code{FALSE}.
#' @param pixelValuesToColorFn optional JS function to be passed to the browser.
#' Can be used to fine tune and manipulate the color mapping.
#' See \url{https://github.com/r-spatial/leafem/issues/25} for some examples.
#' @param ... currently not used.
#'
#' @return
#' A leaflet map object.
#'
#' @examples
#' if (interactive()) {
#' library(leaflet)
#' library(leafem)
#' library(stars)
#'
#' tif = system.file("tif/L7_ETMs.tif", package = "stars")
#' x1 = read_stars(tif)
#' x1 = x1[, , , 3] # band 3
#'
#' leaflet() %>%
#' addTiles() %>%
#' leafem:::addGeoRaster(
#' x1
#' , opacity = 1
#' , colorOptions = colorOptions(
#' palette = hcl.colors(256, "inferno")
#' )
#' )
#' }
#'
#' @importFrom stars st_as_stars st_warp write_stars
#' @importFrom sf st_is_longlat
#'
#' @export addGeoRaster
#' @name addGeoRaster
#' @rdname addGeoRaster
addGeoRaster = function(map,
x,
group = NULL,
Expand All @@ -6,13 +64,15 @@ addGeoRaster = function(map,
opacity = 0.8,
options = leaflet::tileOptions(),
colorOptions = colorOptions(),
pixelValuesToColorFn = NULL) {
project = TRUE,
pixelValuesToColorFn = NULL,
...) {

if (inherits(x, "Raster")) {
x = stars::st_as_stars(x)
}

if (!sf::st_is_longlat(x)) {
if (project && !sf::st_is_longlat(x)) {
x = stars::st_warp(x, crs = 4326)
}

Expand Down Expand Up @@ -42,7 +102,92 @@ addGeoRaster = function(map,
}



#' Add a GeoTIFF file to a leaflet map using optimised rendering.
#'
#' @details
#' This uses the leaflet plugin 'georaster-layer-for-leaflet' to render GeoTIFF data.
#' See \url{https://github.com/GeoTIFF/georaster-layer-for-leaflet} for details.
#' The GeoTIFF file is read directly in the browser using geotiffjs
#' (\url{https://geotiffjs.github.io/}), so there's no need to read data into
#' the current R session. GeoTIFF files can be read from the file system or via url.
#' The clue is that rendering uses simple nearest neighbor interpolation on-the-fly
#' to ensure smooth rendering. This enables handling of larger rasters than with
#' the standard \code{\link[leaflet]{addRasterImage}}.
#'
#' @param map the map to add the raster data to.
#' @param file path to the GeoTIFF file to render.
#' @param url url to the GeoTIFF file to render. Ignored if \code{file} is provided.
#' @param group he name of the group this raster image should belong to.
#' @param layerId the layerId.
#' @param resolution the target resolution for the simple nearest neighbor interpolation.
#' Larger values will result in more detailed rendering, but may impact performance.
#' Default is 96 (pixels).
#' @param opacity opacity of the rendered layer.
#' @param options options to be passed to the layer.
#' See \code{\link[leaflet]{tileOptions}} for details.
#' @param colorOptions list defining the palette, breaks and na.color to be used.
#' @param pixelValuesToColorFn optional JS function to be passed to the browser.
#' Can be used to fine tune and manipulate the color mapping.
#' See examples & \url{https://github.com/r-spatial/leafem/issues/25} for some examples.
#' @param ... currently not used.
#'
#' @return
#' A leaflet map object.
#'
#' @examples
#' if (interactive()) {
#' library(leaflet)
#' library(leafem)
#'
#' chrpsfl_202004 = "https://data.chc.ucsb.edu/products/CHIRPS-2.0/africa_monthly/tifs/chirps-v2.0.2020.04.tif.gz"
#' dsn_202004 = file.path(tempdir(), basename(chrpsfl_202004))
#'
#' download.file(chrpsfl_202004, dsn_202004)
#'
#' tiffl_202004 = gsub(".gz", "", dsn_202004)
#' R.utils::gunzip(dsn_202004, tiffl_202004)
#'
#' myCustomJSFunc = htmlwidgets::JS(
#' "
#' pixelValuesToColorFn = (raster, colorOptions) => {
#' const cols = colorOptions.palette;
#' var scale = chroma.scale(cols);
#'
#' if (colorOptions.breaks !== null) {
#' scale = scale.classes(colorOptions.breaks);
#' }
#' var pixelFunc = values => {
#' let clr = scale.domain([raster.mins, raster.maxs]);
#' if (isNaN(values)) return colorOptions.naColor;
#' if (values < 120) return colorOptions.naColor;
#' return clr(values).hex();
#' };
#' return pixelFunc;
#' };
#' "
#' )
#'
#' leaflet() %>%
#' addTiles() %>%
#' addGeotiff(
#' file = tiffl_202004
#' , opacity = 0.9
#' , colorOptions = colorOptions(
#' palette = hcl.colors(256, "viridis")
#' , breaks = seq(0, 1000, 10)
#' , na.color = "transparent"
#' )
#' , pixelValuesToColorFn = myCustomJSFunc
#' )
#'
#' }
#'
#' @importFrom stars st_as_stars st_warp write_stars
#' @importFrom sf st_is_longlat
#'
#' @export addGeotiff
#' @name addGeotiff
#' @rdname addGeotiff
addGeotiff = function(map,
file = NULL,
url = NULL,
Expand All @@ -51,8 +196,9 @@ addGeotiff = function(map,
resolution = 96,
opacity = 0.8,
options = leaflet::tileOptions(),
colorOptions = colorOptions(),
pixelValuesToColorFn = NULL) {
colorOptions = NULL, #colorOptions(),
pixelValuesToColorFn = NULL,
...) {

if (inherits(map, "mapview")) map = mapview2leaflet(map)

Expand Down Expand Up @@ -116,6 +262,15 @@ addGeotiff = function(map,

}


#' Color options for addGeoRaster and addGeotiff
#'
#' @param palette the color palette to use. Can be a set of colors or a
#' color generating function such as the result of \code{\link[grDevices]{colorRampPalette}}.
#' @param breaks the breaks at which color should change.
#' @param na.color color for NA values (will map to NaN in Javascript).
#'
#' @export
colorOptions = function(palette = NULL,
breaks = NULL,
na.color = "#bebebe22") {
Expand Down
85 changes: 85 additions & 0 deletions man/addGeoRaster.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit ff4a8e0

Please sign in to comment.