Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev #236

Merged
merged 48 commits into from
Apr 12, 2024
Merged

Dev #236

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
5234e25
Improve `check_fields()` regex #230 #220
daxkellie Feb 16, 2024
0e8428f
Add `galah_filter()` test for correct apostrophe parsing #214
daxkellie Feb 16, 2024
21bb1ab
Add tests for case where SDS data is requested via API #232
mjwestgate Feb 26, 2024
a96c3d7
Check - rather than overwrite - supplied vs returned field names #232
mjwestgate Feb 27, 2024
08fa507
Refine warnings for unexpected field names #232
mjwestgate Feb 27, 2024
9bd8d97
Update services for SBDI (#210) and BAO (#231)
mjwestgate Feb 27, 2024
b16ac65
fix bug in `show_all()` where errors rather than defaults to `show_al…
mjwestgate Feb 28, 2024
117f8b2
Add `show_all_distributions()` function
mjwestgate Mar 4, 2024
63a183a
add `atlas_distributions()` function
mjwestgate Mar 5, 2024
f8f992f
remove mistakenly added test image
mjwestgate Mar 5, 2024
fd39cda
Return correctly formatted field values by `show_values()` #233
daxkellie Mar 20, 2024
156cc33
add check within `collapse()` to see whether user has set an atlas
mjwestgate Mar 22, 2024
3215447
Fix `atlas_species()` for la-pipelines atlases (#234)
mjwestgate Mar 22, 2024
016a7db
Support `select()` for `atlas_species()` #227
mjwestgate Mar 25, 2024
4dce1dd
Change node message from `collapse()` to `.onLoad()`
mjwestgate Mar 25, 2024
7c61a7c
Fix error where labels were substituted for field values during `atla…
mjwestgate Mar 26, 2024
1bafd7c
Add styling to onLoad message
daxkellie Mar 26, 2024
47e40c1
Fix bug preventing `apply_profile()` working with `atlas_species()`
mjwestgate Mar 27, 2024
b564ffe
First pass at `galah_radius()` functionality #216
daxkellie Mar 27, 2024
38009bd
Merge branch 'dev' of https://github.com/AtlasOfLivingAustralia/galah…
daxkellie Mar 27, 2024
ab18406
Further fixes to `collect_occurrences_count()`
mjwestgate Mar 27, 2024
f02afb4
Add `group = "taxonomy"` option to `galah_select()`
mjwestgate Mar 27, 2024
0979732
Edits to `galah_radius()`, add info to `galah_geolocate()` #216
daxkellie Mar 27, 2024
1b6b3ef
First pass at improved filtering by assertions
mjwestgate Mar 28, 2024
df2d3ac
Remove incomplete functionality
mjwestgate Mar 28, 2024
a6937d6
Fix minor bugs in `galah_geolocate()`
mjwestgate Apr 2, 2024
b0585f7
clean up vignettes
mjwestgate Apr 2, 2024
a10c43b
first pass at updating NEWS.md
mjwestgate Apr 2, 2024
a8f0dbe
Add tests for type `radius` in `galah_geolocate()` #216
daxkellie Apr 3, 2024
eabf5d6
fix minor bugs discovered by `test()`
mjwestgate Apr 3, 2024
c1eb301
Add tests for `galah_radius()` #216
daxkellie Apr 3, 2024
4ad7d49
Merge branch 'dev' of https://github.com/AtlasOfLivingAustralia/galah…
daxkellie Apr 3, 2024
081aa6f
Test that `galah_radius()` works in a query
daxkellie Apr 3, 2024
36e4640
Add "experimental" badge to `galah_geolocate()` docs
daxkellie Apr 3, 2024
1adcd55
Add more to NEWS.md & reference issue numbers
daxkellie Apr 5, 2024
c0efa81
Avoid truncating list item values #235
daxkellie Apr 5, 2024
7acebfe
Add list item fix to NEWS.md
daxkellie Apr 5, 2024
18e387e
Minor adjustment to onLoad message
daxkellie Apr 9, 2024
48f43ef
Minor edits to vignettes
daxkellie Apr 9, 2024
22f980b
A few minor edits to choosing an atlas vignette
daxkellie Apr 9, 2024
199790a
support `galah_geolocate()` for GBIF queries
mjwestgate Apr 9, 2024
d7e6122
Support `galah_geolocate()` for GBIF occurrences
mjwestgate Apr 10, 2024
4b965ac
Clean up tests, minor bug fixes, update pkgdown.yml and NEWS.md
mjwestgate Apr 12, 2024
7577aa0
attempt to make startup messages 'quietable' using `suppressPackageSt…
mjwestgate Apr 12, 2024
1d3ad82
switch to packageStartupMessage() for onload()
mjwestgate Apr 12, 2024
cfaaba4
Get correct syntax for allowing users to prevent onload messages
mjwestgate Apr 12, 2024
34a60a8
Fix typos in tests for `galah_select()`
mjwestgate Apr 12, 2024
9826367
Fix typo in tests for `galah_select()`, but properly this time
mjwestgate Apr 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ docs/*
/doc/
/Meta/
docs
SECRETS.txt
3 changes: 2 additions & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Package: galah
Type: Package
Title: Biodiversity Data from the GBIF Node Network
Version: 2.0.1
Version: 2.0.2
Authors@R:
c(person(given = "Martin",
family = "Westgate",
Expand Down Expand Up @@ -52,6 +52,7 @@ Suggests:
knitr,
magrittr,
pkgdown,
reactable,
rmarkdown,
testthat
License: MPL-2.0
Expand Down
8 changes: 8 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export(galah_geolocate)
export(galah_group_by)
export(galah_identify)
export(galah_polygon)
export(galah_radius)
export(galah_select)
export(group_by)
export(identify)
Expand Down Expand Up @@ -120,6 +121,7 @@ importFrom(dplyr,filter)
importFrom(dplyr,full_join)
importFrom(dplyr,group_by)
importFrom(dplyr,join_by)
importFrom(dplyr,last_col)
importFrom(dplyr,mutate)
importFrom(dplyr,pull)
importFrom(dplyr,relocate)
Expand Down Expand Up @@ -174,6 +176,7 @@ importFrom(rlang,caller_env)
importFrom(rlang,enquo)
importFrom(rlang,enquos)
importFrom(rlang,eval_tidy)
importFrom(rlang,expr_text)
importFrom(rlang,f_lhs)
importFrom(rlang,f_rhs)
importFrom(rlang,format_error_bullets)
Expand All @@ -195,10 +198,12 @@ importFrom(rlang,quo_is_symbol)
importFrom(rlang,quo_squash)
importFrom(rlang,try_fetch)
importFrom(rlang,warn)
importFrom(sf,st_as_sf)
importFrom(sf,st_as_sfc)
importFrom(sf,st_as_text)
importFrom(sf,st_bbox)
importFrom(sf,st_cast)
importFrom(sf,st_coordinates)
importFrom(sf,st_crop)
importFrom(sf,st_crs)
importFrom(sf,st_geometry)
Expand All @@ -207,16 +212,19 @@ importFrom(sf,st_is_empty)
importFrom(sf,st_is_simple)
importFrom(sf,st_is_valid)
importFrom(stringr,str_detect)
importFrom(stringr,str_extract)
importFrom(stringr,str_extract_all)
importFrom(stringr,str_replace)
importFrom(stringr,str_replace_all)
importFrom(stringr,str_split)
importFrom(stringr,str_to_title)
importFrom(stringr,str_trim)
importFrom(tibble,as_tibble)
importFrom(tibble,tibble)
importFrom(tidyr,drop_na)
importFrom(tidyr,unnest_longer)
importFrom(tidyselect,eval_select)
importFrom(utils,URLdecode)
importFrom(utils,URLencode)
importFrom(utils,adist)
importFrom(utils,unzip)
22 changes: 22 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,25 @@
# galah 2.0.2

### Minor improvements
* Experimental `galah_geolocate(type = "radius")` added. Supports filtering by point location and radius (in km) (#216)
* Support `galah_geolocate()` and associated sub-functions for GBIF queries
* `galah_filter()` no longer fails when assertions are specified in `galah_filter()` (#199)
* Improved behaviour and robustness of `atlas_species()`, particularly for other atlases (#234)
* Improved behavior of `select()`, including supporting `atlas_species()` and adding new `group = "taxonomy"` option (#218)
* Updated namematching services for SBDI (Sweden) (#210)
* Add onLoad message so user is clear which organisation is being queried

### Bug fixes
* `collect_media()` no longer fails when a thumbnail is missing (#215)
* `galah_filter()` parses apostrophes correctly in value names (#214)
* `group_by() |> atlas_counts()` no longer truncates rows at 30 (#223, #198)
* Fix bug where `search_values()` did not return matched values
* `show_values()` & `atlas_counts()` return correctly formatted values (#233)
* `atlas_occurrences()` no longer overwrites returned field names with user-supplied ones
* `galah_apply_profile()` now works as expected
* List items are no longer truncated when using `show_values()` (#235)


# galah 2.0.1

### Minor improvements
Expand Down
37 changes: 37 additions & 0 deletions R/atlas_distributions.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#' Collect a set of expert distributions
#'
#' Not exported yet as taxonomic queries are not yet optimized
#' @param request optional `data_request` object: generated by a call to
#' [galah_call()].
#' @param identify `data.frame`: generated by a call to
#' [galah_identify()].
#' @param filter `data.frame`: generated by a call to
#' [galah_filter()]
#' @return An object of classes `sf`, `tbl`, `tbl_df` and `data.frame`
#' (aka a Simple feature collection) of distribution maps, with one column per
#' map, and spatial data stored in the `geometry` column.
#' @examples
#'
#' x <- show_all(distributions) |>
#' slice_head(n = 4)
#'
#' y <- galah_call() |>
#' filter(id == x$id) |>
#' atlas_distributions()
#' ggplot() +
#' geom_sf(data = ozmap_country) +
#' geom_sf(data = st_as_sf(x))
#' @noRd
#' @keywords Internal
atlas_distributions <- function(request = NULL,
filter = NULL,
identify = NULL){
args <- as.list(environment()) # capture supplied arguments
.query <- check_atlas_inputs(args) # convert to `data_request` object
.query$type <- "distributions"
collect(.query)
# NOTE:
# taxonomic queries *only* work for lsid's that specifically referenced;
# i.e. it acts more like `filter()` than `identify()`
# it could be made to act in a more 'taxonomic' way by calling `atlas_species()` first
}
50 changes: 34 additions & 16 deletions R/build.R
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,21 @@ build_query <- function(identify = NULL,
}
}
# merge
query <- list(fq = c(taxa_query, filter_query))
query <- list(fq = c(filter_query, taxa_query))
# geographic stuff
if (!is.null(location)) {
# if location is for a point radius vs polygon/bbox
if(!is.null(names(location))){
if(all(!is.null(location$radius))) { # `galah_radius()` will always pass radius argument
query$q <- paste0("*:*")
query$lon <- location$lon
query$lat <- location$lat
query$radius <- location$radius
}else
query$wkt <- location
} else {
query$wkt <- location
}
}
# add profiles information (ALA only)
if(pour("atlas", "region") == "Australia"){
Expand All @@ -68,11 +79,13 @@ build_query <- function(identify = NULL,
}

#' Build query list from constituent arguments for GBIF only
#' @importFrom glue glue_data
#' @importFrom potions pour
#' @noRd
#' @keywords Internal
#' @importFrom potions pour
build_query_gbif <- function(identify = NULL,
filter = NULL){
filter = NULL,
location = NULL){
if(is.null(identify)) {
taxa_query <- list(taxonKey = 1)
}else{
Expand All @@ -91,8 +104,22 @@ build_query_gbif <- function(identify = NULL,
filter_query <- build_filter_query(filter)
}
}
# return merged output
c(taxa_query, filter_query)
# merge
query <- c(taxa_query, filter_query)
# geographic stuff
if (!is.null(location)) {
# if location is for a point radius vs polygon/bbox
if(!is.null(names(location))){
if(all(!is.null(location$radius))) { # `galah_radius()` will always pass radius argument
query$geoDistance <- glue_data(location,
"{lat},{lon},{radius}km")
}else
query$geometry <- location
} else {
query$geometry <- location
}
}
query
}

#' collapse multiple fq args into one
Expand All @@ -101,8 +128,9 @@ build_query_gbif <- function(identify = NULL,
build_single_fq <- function(query){
if(any(names(query) == "fq")){
# ensure all arguments from galah_filter are enclosed in brackets
# EXCEPT for assertions
fq <- query$fq
missing_brackets <- !grepl("^\\(", fq)
missing_brackets <- !grepl("^\\(", fq) & !grepl("assertions", fq)
if(any(missing_brackets)){
fq[missing_brackets] <- paste0("(", fq[missing_brackets], ")")
}
Expand Down Expand Up @@ -154,16 +182,6 @@ build_taxa_query <- function(ids) {
}
}

#' Sub-function to convert assertions to logicals in `collect_occurrences()`
#' @noRd
#' @keywords Internal
fix_assertion_cols <- function(df, assertion_cols) {
for (col in assertion_cols) {
df[[col]] <- as.logical(df[[col]])
}
df
}

#' Internal function to handle APIs that return complex outputs
#' Currently only used by `collect_collection_values()`
#' It is pretty messy, as:
Expand Down
4 changes: 2 additions & 2 deletions R/build_checks.R
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ build_checks <- function(.query){
# parse `data`, including supplied metadata
# this assumes only one `data` field is available per `query_set`
.query[[which(data_lookup)]] |>
add_metadata(metadata_results)
add_metadata(metadata_results)
}else if(any(names_vec %in% c("metadata/fields-unnest",
"metadata/profiles-unnest",
"metadata/taxa-unnest"))){
Expand Down Expand Up @@ -43,7 +43,7 @@ parse_metadata <- function(names_vec, .query){
!grepl("-unnest$", names_vec) # unnest functions only parse in collect()
if(any(metadata_lookup)){
metadata_names <- names_vec[metadata_lookup]
metadata_results <- lapply(.query[metadata_lookup], collect)
metadata_results <- lapply(.query[which(metadata_lookup)], collect)
names(metadata_results) <- metadata_names
metadata_results
}else{
Expand Down
55 changes: 43 additions & 12 deletions R/build_predicates.R
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,31 @@
#'
#' predicates are JSON scripts for passing to GBIF offline downloads API.
#' https://www.gbif.org/developer/occurrence
#' @noRd
#' @keywords Internal
#' @importFrom potions pour
#' @importFrom jsonlite toJSON
#' @importFrom jsonlite unbox
#' @noRd
#' @keywords Internal
build_predicates <- function(
df, # where df is returned by galah_filter()
location,
format = "SIMPLE_CSV"
){

if(nrow(df) < 1){
return(NULL)
}

predicates_list <- parse_predicates(df)
if(nrow(df) > 1){
predicates_list <- c(
parse_predicates(df),
parse_predicates_spatial(location))

if(length(predicates_list) > 1){
predicates_list <- list(
type = unbox("and"),
predicates = parse_predicates(df)
predicates = predicates_list
)
}else{
predicates_list <- parse_predicates(df)[[1]]
}

data_list <- list(
creator = unbox(pour("user", "username", .pkg = "galah")),
notificationAddresses = pour("user", "email", .pkg = "galah"),
Expand All @@ -37,7 +38,38 @@ build_predicates <- function(
toJSON(data_list)
}

# parse galah_filter result into predicate format
#' most code borrowed from `build_query_gbif()`
#' @noRd
#' @keywords Internal
parse_predicates_spatial <- function(location){
if(!is.null(location)) {
# if location is for a point radius vs polygon/bbox
if(!is.null(names(location))){
if(all(!is.null(location$radius))) { # `galah_radius()` will always pass radius argument
list(type = unbox("geoDistance"),
latitude = unbox(location$lat),
longitude = unbox(location$lon),
distance = unbox(paste0(location$radius, "km"))) |>
list()
}else{
list(type = unbox("within"),
geometry = unbox(location)) |>
list()
}
}else{
list(type = unbox("within"),
geometry = unbox(location)) |>
list()
}
}else{
NULL
}
}

#' parse galah_filter result into predicate format
#' @importFrom jsonlite unbox
#' @noRd
#' @keywords Internal
parse_predicates <- function(df){
json_text <- lapply(
split(df, seq_len(nrow(df))),
Expand All @@ -58,8 +90,7 @@ parse_predicates <- function(df){
names(json_text) <- NULL
return(json_text)
}
# NOTE: currently missing: `within` (geolocate), `or`, `in`, `isNull`, `isNotNull`
# Q: how to add taxonomic names to gbif schema?
# NOTE: currently missing: `or`, `in`, `isNull`, `isNotNull`

# test object:
# df <- galah_filter(year == 1850)
Expand Down
Loading
Loading