diff --git a/DESCRIPTION b/DESCRIPTION index 9f326ba..5d8bb94 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -19,22 +19,23 @@ Roxygen: list(markdown = TRUE) Depends: R (>= 4.1.0) Imports: - htmlwidgets, - geojsonsf, - sf, - rlang, - htmltools, - grDevices, - base64enc, - terra, - classInt, - shiny, - viridisLite, - png, - jsonlite, - httpuv + htmlwidgets, + geojsonsf, + sf, + rlang, + htmltools, + grDevices, + base64enc, + terra, + classInt, + shiny, + viridisLite, + png, + jsonlite, + httpuv Suggests: chromote, + duckspatial (>= 1.2.0), knitr, mapboxapi, testthat (>= 3.0.0), diff --git a/NEWS.md b/NEWS.md index 73fa2e8..8076d39 100644 --- a/NEWS.md +++ b/NEWS.md @@ -40,6 +40,8 @@ * Fixed a bug where passing a geometry-only `sf` object (no non-geometry columns) as a layer source caused a serialization error. `geojsonsf::sf_geojson()` simplifies property-less sf objects into a vector of individual geometry strings rather than a FeatureCollection, which `htmlwidgets` cannot serialize. All internal calls now use `simplify = FALSE` to consistently return a FeatureCollection (#212). +* `duckspatial_df` objects from the `duckspatial` package are now accepted wherever `sf` objects are: `add_source()`, `add_layer()` and all specific layer functions, `fit_bounds()`, the `bounds` argument of `maplibre()` and `mapboxgl()`, `set_source()`, and `add_markers()`. CRS is validated and reprojected to EPSG:4326 automatically (#213). + # mapgl 0.5.0 * Tooltips and popups now accept `{brace}` templates package-wide. Any layer's `tooltip`/`popup` (and `set_tooltip()`/`set_popup()`) can take a glue-style template such as `"{name}: {population}"`, in addition to the existing column name and `concat()`/`number_format()` expression forms; substituted values are HTML-escaped. diff --git a/R/layers.R b/R/layers.R index 3ab343c..15b611e 100644 --- a/R/layers.R +++ b/R/layers.R @@ -5,7 +5,7 @@ #' @param map A map object created by the `mapboxgl()` or `maplibre()` functions. #' @param id A unique ID for the layer. #' @param type The type of the layer (e.g., "fill", "line", "circle"). -#' @param source The ID of the source, alternatively an sf object (which will be converted to a GeoJSON source) or a named list that specifies `type` and `url` for a remote source. +#' @param source The ID of the source, alternatively an sf object or a `duckspatial_df` object (both converted to a GeoJSON source), or a named list that specifies `type` and `url` for a remote source. #' @param source_layer The source layer (for vector sources). #' @param paint A list of paint properties for the layer. #' @param layout A list of layout properties for the layer. @@ -102,6 +102,15 @@ add_layer <- function( data = geojson, generateId = TRUE ) + } else if (inherits(source, "duckspatial_df")) { + check_duckspatial() + source <- ddbs_ensure_wgs84(source, "source") + geojson <- duckspatial::ddbs_as_geojson(source) + source <- list( + type = "geojson", + data = geojson, + generateId = TRUE + ) } map <- mapgl_resolve_pending_flowmaps(map, before_id = id) @@ -206,7 +215,7 @@ add_layer <- function( #' #' @param map A map object created by the `mapboxgl` or `maplibre` functions. #' @param id A unique ID for the layer. -#' @param source The ID of the source, alternatively an sf object (which will be converted to a GeoJSON source) or a named list that specifies `type` and `url` for a remote source. +#' @param source The ID of the source, alternatively an sf object or a `duckspatial_df` object (both converted to a GeoJSON source), or a named list that specifies `type` and `url` for a remote source. #' @param source_layer The source layer (for vector sources). #' @param fill_antialias Whether or not the fill should be antialiased. #' @param fill_color The color of the filled part of this layer. @@ -335,9 +344,9 @@ add_fill_layer <- function( #' #' @param map A map object created by the `mapboxgl` or `maplibre` functions. #' @param id A unique ID for the layer. -#' @param source The ID of the source, alternatively an sf object (which will be -#' converted to a GeoJSON source) or a named list that specifies `type` and -#' `url` for a remote source. +#' @param source The ID of the source, alternatively an sf object or a +#' `duckspatial_df` object (both converted to a GeoJSON source), or a named +#' list that specifies `type` and `url` for a remote source. #' @param source_layer The source layer (for vector sources). #' @param line_blur Amount to blur the line, in pixels. #' @param line_cap The display of line endings. One of "butt", "round", "square". @@ -518,7 +527,7 @@ add_line_layer <- function( #' #' @param map A map object created by the `mapboxgl` or `maplibre` functions. #' @param id A unique ID for the layer. -#' @param source The ID of the source, alternatively an sf object (which will be converted to a GeoJSON source) or a named list that specifies `type` and `url` for a remote source. +#' @param source The ID of the source, alternatively an sf object or a `duckspatial_df` object (both converted to a GeoJSON source), or a named list that specifies `type` and `url` for a remote source. #' @param source_layer The source layer (for vector sources). #' @param heatmap_color The color of the heatmap points. #' @param heatmap_intensity The intensity of the heatmap points. @@ -623,7 +632,7 @@ add_heatmap_layer <- function( #' #' @param map A map object created by the `mapboxgl` or `maplibre` functions. #' @param id A unique ID for the layer. -#' @param source The ID of the source, alternatively an sf object (which will be converted to a GeoJSON source) or a named list that specifies `type` and `url` for a remote source. +#' @param source The ID of the source, alternatively an sf object or a `duckspatial_df` object (both converted to a GeoJSON source), or a named list that specifies `type` and `url` for a remote source. #' @param source_layer The source layer (for vector sources). #' @param fill_extrusion_ambient_occlusion_intensity Controls the intensity of ambient occlusion shading. Value between 0 and 1; around 0.3 provides the most plausible results for buildings. #' @param fill_extrusion_ambient_occlusion_radius Shades area near ground and concave angles between walls. Default 3.0 corresponds to one floor height. @@ -958,7 +967,7 @@ cluster_options <- function( #' #' @param map A map object created by the `mapboxgl` or `maplibre` functions. #' @param id A unique ID for the layer. -#' @param source The ID of the source, alternatively an sf object (which will be converted to a GeoJSON source) or a named list that specifies `type` and `url` for a remote source. +#' @param source The ID of the source, alternatively an sf object or a `duckspatial_df` object (both converted to a GeoJSON source), or a named list that specifies `type` and `url` for a remote source. #' @param source_layer The source layer (for vector sources). #' @param circle_blur Amount to blur the circle. #' @param circle_color The color of the circle. @@ -1122,7 +1131,8 @@ add_circle_layer <- function( # Dispatch on source shape. sf/sfc takes precedence so existing # calls that incidentally pass `source_layer` alongside sf data # (silently ignored today) don't regress. - if (inherits(source, c("sf", "sfc"))) { + if (inherits(source, c("sf", "sfc", "duckspatial_df"))) { + if (inherits(source, "duckspatial_df")) check_duckspatial() # Native live clustering: inject a clustered GeoJSON source. map <- add_source( map, @@ -1387,7 +1397,7 @@ add_raster_layer <- function( #' #' @param map A map object created by the `mapboxgl` or `maplibre` functions. #' @param id A unique ID for the layer. -#' @param source The ID of the source, alternatively an sf object (which will be converted to a GeoJSON source) or a named list that specifies `type` and `url` for a remote source. +#' @param source The ID of the source, alternatively an sf object or a `duckspatial_df` object (both converted to a GeoJSON source), or a named list that specifies `type` and `url` for a remote source. #' @param source_layer The source layer (for vector sources). #' @param icon_allow_overlap If TRUE, the icon will be visible even if it collides with other previously drawn symbols. #' @param icon_anchor Part of the icon placed closest to the anchor. @@ -1715,7 +1725,8 @@ add_symbol_layer <- function( if (!is.null(cluster_options)) { # Dispatch on source shape. See add_circle_layer() for notes. - if (inherits(source, c("sf", "sfc"))) { + if (inherits(source, c("sf", "sfc", "duckspatial_df"))) { + if (inherits(source, "duckspatial_df")) check_duckspatial() map <- add_source( map, id = id, diff --git a/R/mapboxgl.R b/R/mapboxgl.R index a8b4799..f15fb3d 100644 --- a/R/mapboxgl.R +++ b/R/mapboxgl.R @@ -10,6 +10,7 @@ #' @param access_token Your Mapbox access token. #' @param bounds The bounding box to fit the map to. Accepts one of the following: #' * `sf` object; +#' * `duckspatial_df` object; #' * output of `st_bbox()`; #' * unnamed numeric vector of the form `c(xmin, ymin, xmax, ymax)`. #' @param width The width of the output htmlwidget. @@ -79,6 +80,10 @@ mapboxgl <- function( } if (inherits(bounds, "sf")) { bounds <- as.vector(sf::st_bbox(sf::st_transform(bounds, 4326))) + } else if (inherits(bounds, "duckspatial_df")) { + check_duckspatial() + bounds <- ddbs_ensure_wgs84(bounds, "bounds") + bounds <- as.vector(duckspatial::ddbs_bbox(bounds)) } else if (inherits(bounds, "bbox")) { # Curiously, anyNA(bounds) or any(is.na(bounds)) would return FALSE even # if one of the four values is NA. diff --git a/R/maplibre.R b/R/maplibre.R index 232001e..e154439 100644 --- a/R/maplibre.R +++ b/R/maplibre.R @@ -8,6 +8,7 @@ #' @param projection The map projection to use (e.g., "mercator", "globe"). #' @param bounds The bounding box to fit the map to. Accepts one of the following: #' * `sf` object; +#' * `duckspatial_df` object; #' * output of `st_bbox()`; #' * unnamed numeric vector of the form `c(xmin, ymin, xmax, ymax)`. #' @param width The width of the output htmlwidget. @@ -62,6 +63,10 @@ maplibre <- function( } if (inherits(bounds, "sf")) { bounds <- as.vector(sf::st_bbox(sf::st_transform(bounds, 4326))) + } else if (inherits(bounds, "duckspatial_df")) { + check_duckspatial() + bounds <- ddbs_ensure_wgs84(bounds, "bounds") + bounds <- as.vector(duckspatial::ddbs_bbox(bounds)) } else if (inherits(bounds, "bbox")) { # Curiously, anyNA(bounds) or any(is.na(bounds)) would return FALSE even # if one of the four values is NA. diff --git a/R/markers.R b/R/markers.R index a24d2fe..1f814a0 100644 --- a/R/markers.R +++ b/R/markers.R @@ -1,7 +1,7 @@ #' Add markers to a Mapbox GL or Maplibre GL map #' #' @param map A map object created by the `mapboxgl` or `maplibre` functions. -#' @param data A length-2 numeric vector of coordinates, a list of length-2 numeric vectors, or an `sf` POINT object. +#' @param data A length-2 numeric vector of coordinates, a list of length-2 numeric vectors, an `sf` POINT object, or a `duckspatial_df` POINT object. #' @param color The color of the marker (default is "red"). #' @param rotation The rotation of the marker (default is 0). #' @param popup A column name for popups (if data is an `sf` object) or a string for a single popup (if data is a numeric vector or list of vectors). @@ -114,6 +114,27 @@ add_markers <- function(map, data, color = "red", rotation = 0, popup = NULL, ma options = options ) }) + } else if (inherits(data, "duckspatial_df")) { + check_duckspatial() + if (duckspatial::ddbs_geometry_type(data, FALSE)[1] == "POINT") { + lng <- duckspatial::ddbs_x(data, mode = "sf") + lat <- duckspatial::ddbs_y(data, mode = "sf") + properties <- duckspatial::ddbs_drop_geometry(data) |> dplyr::collect() + if (!is.null(marker_id) && !marker_id %in% colnames(properties)) { + stop("When providing an sf object, marker_id must be a column name in the object.") + } + markers <- lapply(seq_len(length(lng)), function(i) { + list( + id = if (!is.null(marker_id)) properties[[marker_id]][i] else paste0("marker_", i), + lng = lng[i], + lat = lat[i], + color = color, + rotation = rotation, + popup = if (!is.null(popup)) as.character(properties[i, popup]) else NULL, + options = options + ) + }) + } } else { stop("Data must be either a length-2 numeric vector, a list of length-2 numeric vectors, or an sf POINT object.") } diff --git a/R/shiny.R b/R/shiny.R index 106c0ae..b465dd4 100644 --- a/R/shiny.R +++ b/R/shiny.R @@ -668,7 +668,7 @@ set_popup <- function(map, layer_id = NULL, popup, layer = NULL, style = NULL) { #' #' @param map A map object created by the `mapboxgl` or `maplibre` function, or a proxy object. #' @param layer_id The ID of the layer to update. -#' @param source An sf object (which will be converted to a GeoJSON source). +#' @param source An sf object or a `duckspatial_df` object (both converted to a GeoJSON source). #' @param layer Deprecated. Use `layer_id` instead. #' #' @return The updated map object. @@ -697,6 +697,9 @@ set_source <- function(map, layer_id = NULL, source, layer = NULL) { source, crs = 4326 ), simplify = FALSE) + } else if (inherits(source, "duckspatial_df")) { + check_duckspatial() + source <- duckspatial::ddbs_as_geojson(ddbs_ensure_wgs84(source, "source")) } if ( diff --git a/R/sources.R b/R/sources.R index 3c2c6d3..4beb8bc 100644 --- a/R/sources.R +++ b/R/sources.R @@ -2,7 +2,7 @@ #' #' @param map A map object created by the `mapboxgl` or `maplibre` function. #' @param id A unique ID for the source. -#' @param data An sf object or a URL pointing to a remote GeoJSON file. +#' @param data An sf object, a `duckspatial_df` object, or a URL pointing to a remote GeoJSON file. #' @param ... Additional arguments to be passed to the JavaScript addSource method. #' #' @return The modified map object with the new source added. @@ -17,10 +17,14 @@ add_source <- function(map, id, data, ...) { data <- sf::st_transform(data, crs = 4326) } geojson <- geojsonsf::sf_geojson(data, simplify = FALSE) + } else if (inherits(data, "duckspatial_df")) { + check_duckspatial() + data <- ddbs_ensure_wgs84(data, "data") + geojson <- duckspatial::ddbs_as_geojson(data) } else if (is.character(data) && grepl("^http", data)) { geojson <- data } else { - stop("Data must be an sf object or a URL to a remote GeoJSON file.") + stop("Data must be an sf object, a duckspatial_df, or a URL to a remote GeoJSON file.") } source <- list( diff --git a/R/utils.R b/R/utils.R index 3f67b4c..e781d82 100644 --- a/R/utils.R +++ b/R/utils.R @@ -605,6 +605,36 @@ mapgl_invoke_method <- function(map, type, ...) { return(map) } +# Ensures a duckspatial_df is in EPSG:4326, transforming if needed. +# Stops if the object has no CRS set. +ddbs_ensure_wgs84 <- function(x, arg = deparse(substitute(x))) { + crs <- duckspatial::ddbs_crs(x) + if (is.na(crs)) { + stop(sprintf("`%s` doesn't have a CRS set.", arg)) + } + if (!crs$input %in% c("EPSG:4326", "WGS 84", "4326")) { + x <- duckspatial::ddbs_transform(x, "EPSG:4326") + } + x +} + +# Checks if duckspatial is installed when needed, and triggers its installation +check_duckspatial <- function( + min_version = "1.2.0", + call = rlang::caller_env() +) { + + rlang::check_installed( + "duckspatial", + version = min_version, + call = call + ) + + invisible(TRUE) + +} + + # Shared htmlDependency for the layers control (JS IControl + stylesheet), # used by mapboxgl(), maplibre(), and both compare widgets layers_control_dependency <- function() { diff --git a/R/views.R b/R/views.R index 8c87575..da0165a 100644 --- a/R/views.R +++ b/R/views.R @@ -1,7 +1,7 @@ #' Fit the map to a bounding box #' #' @param map A map object created by the `mapboxgl` or `maplibre` function or a proxy object. -#' @param bbox A bounding box specified as a numeric vector of length 4 (minLng, minLat, maxLng, maxLat), or an sf object from which a bounding box will be calculated. +#' @param bbox A bounding box specified as a numeric vector of length 4 (minLng, minLat, maxLng, maxLat), an sf object, or a `duckspatial_df` object, from which a bounding box will be calculated. #' @param animate A logical value indicating whether to animate the transition to the new bounds. Defaults to FALSE. #' @param ... Additional named arguments for fitting the bounds. #' @@ -14,6 +14,10 @@ fit_bounds <- function(map, bbox, animate = FALSE, ...) { if (inherits(bbox, "sf")) { bbox <- as.vector(sf::st_bbox(sf::st_transform(bbox, 4326))) + } else if (inherits(bbox, "duckspatial_df")) { + check_duckspatial() + bbox <- ddbs_ensure_wgs84(bbox, "bbox") + bbox <- as.vector(duckspatial::ddbs_bbox(bbox)) } if (inherits(map, "mapboxgl_proxy") || inherits(map, "maplibre_proxy")) { diff --git a/man/add_circle_layer.Rd b/man/add_circle_layer.Rd index 5b3cc00..116f93e 100644 --- a/man/add_circle_layer.Rd +++ b/man/add_circle_layer.Rd @@ -41,7 +41,7 @@ add_circle_layer( \item{id}{A unique ID for the layer.} -\item{source}{The ID of the source, alternatively an sf object (which will be converted to a GeoJSON source) or a named list that specifies \code{type} and \code{url} for a remote source.} +\item{source}{The ID of the source, alternatively an sf object or a \code{duckspatial_df} object (both converted to a GeoJSON source), or a named list that specifies \code{type} and \code{url} for a remote source.} \item{source_layer}{The source layer (for vector sources).} diff --git a/man/add_fill_extrusion_layer.Rd b/man/add_fill_extrusion_layer.Rd index 5902ce7..db01bb6 100644 --- a/man/add_fill_extrusion_layer.Rd +++ b/man/add_fill_extrusion_layer.Rd @@ -40,7 +40,7 @@ add_fill_extrusion_layer( \item{id}{A unique ID for the layer.} -\item{source}{The ID of the source, alternatively an sf object (which will be converted to a GeoJSON source) or a named list that specifies \code{type} and \code{url} for a remote source.} +\item{source}{The ID of the source, alternatively an sf object or a \code{duckspatial_df} object (both converted to a GeoJSON source), or a named list that specifies \code{type} and \code{url} for a remote source.} \item{source_layer}{The source layer (for vector sources).} diff --git a/man/add_fill_layer.Rd b/man/add_fill_layer.Rd index 68cfaab..0068d36 100644 --- a/man/add_fill_layer.Rd +++ b/man/add_fill_layer.Rd @@ -38,7 +38,7 @@ add_fill_layer( \item{id}{A unique ID for the layer.} -\item{source}{The ID of the source, alternatively an sf object (which will be converted to a GeoJSON source) or a named list that specifies \code{type} and \code{url} for a remote source.} +\item{source}{The ID of the source, alternatively an sf object or a \code{duckspatial_df} object (both converted to a GeoJSON source), or a named list that specifies \code{type} and \code{url} for a remote source.} \item{source_layer}{The source layer (for vector sources).} diff --git a/man/add_heatmap_layer.Rd b/man/add_heatmap_layer.Rd index f46c011..d077c20 100644 --- a/man/add_heatmap_layer.Rd +++ b/man/add_heatmap_layer.Rd @@ -27,7 +27,7 @@ add_heatmap_layer( \item{id}{A unique ID for the layer.} -\item{source}{The ID of the source, alternatively an sf object (which will be converted to a GeoJSON source) or a named list that specifies \code{type} and \code{url} for a remote source.} +\item{source}{The ID of the source, alternatively an sf object or a \code{duckspatial_df} object (both converted to a GeoJSON source), or a named list that specifies \code{type} and \code{url} for a remote source.} \item{source_layer}{The source layer (for vector sources).} diff --git a/man/add_layer.Rd b/man/add_layer.Rd index b6842e3..94ac210 100644 --- a/man/add_layer.Rd +++ b/man/add_layer.Rd @@ -31,7 +31,7 @@ add_layer( \item{type}{The type of the layer (e.g., "fill", "line", "circle").} -\item{source}{The ID of the source, alternatively an sf object (which will be converted to a GeoJSON source) or a named list that specifies \code{type} and \code{url} for a remote source.} +\item{source}{The ID of the source, alternatively an sf object or a \code{duckspatial_df} object (both converted to a GeoJSON source), or a named list that specifies \code{type} and \code{url} for a remote source.} \item{source_layer}{The source layer (for vector sources).} diff --git a/man/add_line_layer.Rd b/man/add_line_layer.Rd index d154e04..75fc468 100644 --- a/man/add_line_layer.Rd +++ b/man/add_line_layer.Rd @@ -52,9 +52,9 @@ add_line_layer( \item{id}{A unique ID for the layer.} -\item{source}{The ID of the source, alternatively an sf object (which will be -converted to a GeoJSON source) or a named list that specifies \code{type} and -\code{url} for a remote source.} +\item{source}{The ID of the source, alternatively an sf object or a +\code{duckspatial_df} object (both converted to a GeoJSON source), or a named +list that specifies \code{type} and \code{url} for a remote source.} \item{source_layer}{The source layer (for vector sources).} diff --git a/man/add_markers.Rd b/man/add_markers.Rd index 07fd5fb..2312f0b 100644 --- a/man/add_markers.Rd +++ b/man/add_markers.Rd @@ -18,7 +18,7 @@ add_markers( \arguments{ \item{map}{A map object created by the \code{mapboxgl} or \code{maplibre} functions.} -\item{data}{A length-2 numeric vector of coordinates, a list of length-2 numeric vectors, or an \code{sf} POINT object.} +\item{data}{A length-2 numeric vector of coordinates, a list of length-2 numeric vectors, an \code{sf} POINT object, or a \code{duckspatial_df} POINT object.} \item{color}{The color of the marker (default is "red").} diff --git a/man/add_source.Rd b/man/add_source.Rd index bcc971b..d6c0e8c 100644 --- a/man/add_source.Rd +++ b/man/add_source.Rd @@ -11,7 +11,7 @@ add_source(map, id, data, ...) \item{id}{A unique ID for the source.} -\item{data}{An sf object or a URL pointing to a remote GeoJSON file.} +\item{data}{An sf object, a \code{duckspatial_df} object, or a URL pointing to a remote GeoJSON file.} \item{...}{Additional arguments to be passed to the JavaScript addSource method.} } diff --git a/man/add_symbol_layer.Rd b/man/add_symbol_layer.Rd index 7a33aa5..b2f1192 100644 --- a/man/add_symbol_layer.Rd +++ b/man/add_symbol_layer.Rd @@ -94,7 +94,7 @@ add_symbol_layer( \item{id}{A unique ID for the layer.} -\item{source}{The ID of the source, alternatively an sf object (which will be converted to a GeoJSON source) or a named list that specifies \code{type} and \code{url} for a remote source.} +\item{source}{The ID of the source, alternatively an sf object or a \code{duckspatial_df} object (both converted to a GeoJSON source), or a named list that specifies \code{type} and \code{url} for a remote source.} \item{source_layer}{The source layer (for vector sources).} diff --git a/man/fit_bounds.Rd b/man/fit_bounds.Rd index 77a61b2..cb3bbac 100644 --- a/man/fit_bounds.Rd +++ b/man/fit_bounds.Rd @@ -9,7 +9,7 @@ fit_bounds(map, bbox, animate = FALSE, ...) \arguments{ \item{map}{A map object created by the \code{mapboxgl} or \code{maplibre} function or a proxy object.} -\item{bbox}{A bounding box specified as a numeric vector of length 4 (minLng, minLat, maxLng, maxLat), or an sf object from which a bounding box will be calculated.} +\item{bbox}{A bounding box specified as a numeric vector of length 4 (minLng, minLat, maxLng, maxLat), an sf object, or a \code{duckspatial_df} object, from which a bounding box will be calculated.} \item{animate}{A logical value indicating whether to animate the transition to the new bounds. Defaults to FALSE.} diff --git a/man/mapboxgl.Rd b/man/mapboxgl.Rd index a309534..35f7180 100644 --- a/man/mapboxgl.Rd +++ b/man/mapboxgl.Rd @@ -39,6 +39,7 @@ mapboxgl( \item{bounds}{The bounding box to fit the map to. Accepts one of the following: \itemize{ \item \code{sf} object; +\item \code{duckspatial_df} object; \item output of \code{st_bbox()}; \item unnamed numeric vector of the form \code{c(xmin, ymin, xmax, ymax)}. }} diff --git a/man/maplibre.Rd b/man/maplibre.Rd index 8339e28..5638970 100644 --- a/man/maplibre.Rd +++ b/man/maplibre.Rd @@ -33,6 +33,7 @@ maplibre( \item{bounds}{The bounding box to fit the map to. Accepts one of the following: \itemize{ \item \code{sf} object; +\item \code{duckspatial_df} object; \item output of \code{st_bbox()}; \item unnamed numeric vector of the form \code{c(xmin, ymin, xmax, ymax)}. }} diff --git a/man/set_source.Rd b/man/set_source.Rd index e3ca929..4a525ba 100644 --- a/man/set_source.Rd +++ b/man/set_source.Rd @@ -11,7 +11,7 @@ set_source(map, layer_id = NULL, source, layer = NULL) \item{layer_id}{The ID of the layer to update.} -\item{source}{An sf object (which will be converted to a GeoJSON source).} +\item{source}{An sf object or a \code{duckspatial_df} object (both converted to a GeoJSON source).} \item{layer}{Deprecated. Use \code{layer_id} instead.} }