ropensci/neotoma

loc settings in get_dataset

Closed this issue · 1 comments

I tried the following search:
neotoma_datasets_list<- get_dataset(ageold = max_time, ageyoung = min_time, loc = c(-180, 0, -45, 90), datasettype = "vertebrate fauna")

and got the following error:
Error in get_dataset.default(ageold = max_time, ageyoung = min_time, loc = c(-180, :
loc must be in the form c(lonW, latS, lonE, latN).
Longitudes from -180 to 180, latitudes from -90 to 90.

However, my parameters seem to conform to those needed for the search.

I adjusted slightly and this is the search that worked:
neotoma_datasets_list<- get_dataset(ageold = max_time, ageyoung = min_time, loc = c(-179.9, 0, -45, 89.9), datasettype = "vertebrate fauna")

So I think either the original code needs to be changed, or the error needs to state that longitudes much be from > -180 and latitudes need to be > -90 (and maybe also long = <180 and lat <90, though I haven't tested those ends of the search).

The problem here is only with the latitude of 90; the lower longitude limit doesn't trigger the issue on its own. The buglet is in Line 148 of param_check.R, which has:

if (all(findInterval(cl$loc[c(2,4)], c(-90, 90)) == 1) &
            all(findInterval(cl$loc[c(1,3)], c(-180, 180)) == 1))

We can reproduce this using:

loc <- c(-180, 0, -45, 90)
findInterval(loc[c(2,4)], c(-90, 90))
all(findInterval(loc[c(2,4)], c(-90, 90)) == 1)

which gives

> findInterval(loc[c(2,4)], c(-90, 90))
[1] 1 2
> all(findInterval(loc[c(2,4)], c(-90, 90)) == 1)
[1] FALSE

The issue being the 90 is not in the first interval (-90, 90]. If we request checking of interval (-90, 90) then 90 would be within the interval:

> all(findInterval(loc[c(2,4)], c(-90, 90), rightmost.closed=TRUE) == 1)
[1] TRUE

param_check() will throw the same error if loc[3] were 180.

It might be simpler to just use the following checks

> all(loc[c(2,4)] >= -90 & loc[c(2,4)] <= 90)
[1] TRUE
> all(loc[c(1,3)] >= -180 & loc[c(2,4)] <= 180)
[1] TRUE

So line 148 becomes:

if (all(cl$loc[c(2,4)] >= -90 & cl$loc[c(2,4)] <= 90) &&
            all(cl$loc[c(1,3)] >= -180 & cl$loc[c(2,4)] <= 180))

And note the double && between the two all() calls: the original uses & which is technically a bug (if() should never use the & or | forms as those do element-wise logical operations.)