complete documentation
parent
a2d71ac3e8
commit
0f80075bf5
@ -0,0 +1,13 @@
|
||||
# Generated by roxygen2: do not edit by hand
|
||||
|
||||
S3method(osem_measurements,bbox)
|
||||
S3method(osem_measurements,default)
|
||||
S3method(osem_measurements,sensebox)
|
||||
S3method(osem_phenomena,sensebox)
|
||||
export(osem_box)
|
||||
export(osem_boxes)
|
||||
export(osem_counts)
|
||||
export(osem_measurements)
|
||||
export(osem_phenomena)
|
||||
importFrom(graphics,plot)
|
||||
importFrom(magrittr,"%>%")
|
@ -0,0 +1,125 @@
|
||||
# ==============================================================================
|
||||
#
|
||||
#' Get a set of senseBoxes from the openSenseMap
|
||||
#'
|
||||
#' Boxes can be selected by a set of filters.
|
||||
#' Note that some filters do not work together:
|
||||
#' \enumerate{
|
||||
#' \item \code{phenomenon} can only be applied together with \code{date} or
|
||||
#' \code{from / to}
|
||||
#' \item \code{date} and \code{from / to} cannot be specified together
|
||||
#' }
|
||||
#'
|
||||
#' @param exposure Only return boxes with the given exposure ('indoor', 'outdoor', 'mobile')
|
||||
#' @param model Only return boxes with the given model
|
||||
#' @param grouptag Only return boxes with the given grouptag
|
||||
#' @param date Only return boxes that were measuring within ±4 hours of the given time
|
||||
#' @param from Only return boxes that were measuring later than this time
|
||||
#' @param to Only return boxes that were measuring earlier than this time
|
||||
#' @param phenomenon Only return boxes that measured the given phenomenon in the
|
||||
#' time interval as specified through \code{date} or \code{from / to}
|
||||
#' @param endpoint The URL of the openSenseMap API instance
|
||||
#' @return A \code{sensebox data.frame} containing a box in each row
|
||||
#'
|
||||
#' @seealso \href{https://docs.opensensemap.org/#api-Measurements-findAllBoxes}{openSenseMap API documentation (web)}
|
||||
#' @seealso \code{\link{osem_phenomena}}
|
||||
#' @export
|
||||
#' @examples
|
||||
#' # TODO
|
||||
osem_boxes = function (exposure = NA, model = NA, grouptag = NA,
|
||||
date = NA, from = NA, to = NA, phenomenon = NA,
|
||||
endpoint = 'https://api.opensensemap.org') {
|
||||
|
||||
# error, if phenomenon, but no time given
|
||||
if (!is.na(phenomenon) && is.na(date) && is.na(to) && is.na(from))
|
||||
stop('Parameter "phenomenon" can only be used together with "date" or "from"/"to"')
|
||||
|
||||
# error, if date and from/to given
|
||||
if (!is.na(date) && (!is.na(to) || !is.na(from)))
|
||||
stop('Parameter "date" cannot be used together with "from"/"to"')
|
||||
|
||||
# error, if only one of from/to given
|
||||
if (
|
||||
(!is.na(to) && is.na(from)) ||
|
||||
(is.na(to) && !is.na(from))
|
||||
) {
|
||||
stop('Parameter "from"/"to" must be used together')
|
||||
}
|
||||
|
||||
query = list(endpoint = endpoint)
|
||||
if (!is.na(exposure)) query$exposure = exposure
|
||||
if (!is.na(model)) query$model = model
|
||||
if (!is.na(grouptag)) query$grouptag = grouptag
|
||||
if (!is.na(phenomenon)) query$phenomenon = phenomenon
|
||||
|
||||
if (!is.na(to) && !is.na(from)) {
|
||||
# error, if from is after to
|
||||
# convert dates to commaseparated UTC ISOdates
|
||||
query$date = parse_dateparams(from, to) %>% paste(collapse = ',')
|
||||
|
||||
} else if (!is.na(date)) {
|
||||
query$date = utc_date(date) %>% date_as_isostring()
|
||||
}
|
||||
|
||||
do.call(get_boxes_, query)
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
#
|
||||
#' Get a single senseBox by its ID
|
||||
#'
|
||||
#' @param boxId A string containing a senseBox ID
|
||||
#' @param endpoint The URL of the openSenseMap API instance
|
||||
#' @return A \code{sensebox data.frame} containing a box in each row
|
||||
#'
|
||||
#' @seealso \href{https://docs.opensensemap.org/#api-Measurements-findAllBoxes}{openSenseMap API documentation (web)}
|
||||
#' @seealso \code{\link{osem_phenomena}}
|
||||
#' @export
|
||||
#' @examples
|
||||
#' # TODO
|
||||
osem_box = function (boxId, endpoint = 'https://api.opensensemap.org') {
|
||||
get_box_(boxId, endpoint = endpoint)
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
#
|
||||
#' Construct a senseBox data.frame
|
||||
#'
|
||||
#' Parses the fields of a \code{/boxes} response from the openSenseMap API
|
||||
#'
|
||||
#' @param boxdata A named \code{list} containing the data for a box
|
||||
#' @return A \code{data.frame} with an attached class \code{sensebox}.
|
||||
#' @noRd
|
||||
parse_senseboxdata = function (boxdata) {
|
||||
# extract nested lists for later use & clean them from the list
|
||||
# to allow a simple data.frame structure
|
||||
sensors = boxdata$sensors
|
||||
location = boxdata$loc
|
||||
boxdata[c('loc', 'sensors', 'image', 'boxType')] <- NULL
|
||||
thebox = as.data.frame(boxdata, stringsAsFactors = F)
|
||||
|
||||
# parse timestamps (updatedAt might be not defined)
|
||||
thebox$createdAt = as.POSIXct(strptime(thebox$createdAt, format='%FT%T', tz = 'GMT'))
|
||||
if (!is.null(thebox$updatedAt))
|
||||
thebox$updatedAt = as.POSIXct(strptime(thebox$updatedAt, format='%FT%T', tz = 'GMT'))
|
||||
|
||||
# extract metadata from sensors
|
||||
thebox$phenomena = list(unlist(lapply(sensors, function(s) { s$title })))
|
||||
# FIXME: if one sensor has NA, max() returns bullshit
|
||||
thebox$lastMeasurement = max(lapply(sensors, function(s) {
|
||||
if (!is.null(s$lastMeasurement))
|
||||
as.POSIXct(strptime(s$lastMeasurement$createdAt, format = '%FT%T', tz = 'GMT'))
|
||||
else
|
||||
NA
|
||||
})[[1]])
|
||||
|
||||
# extract coordinates & transform to simple feature object
|
||||
thebox$lon = location[[1]]$geometry$coordinates[[1]]
|
||||
thebox$lat = location[[1]]$geometry$coordinates[[2]]
|
||||
if (length(location[[1]]$geometry$coordinates) == 3)
|
||||
thebox$height = location[[1]]$geometry$coordinates[[3]]
|
||||
|
||||
# attach a custom class for methods
|
||||
class(thebox) = c('sensebox', class(thebox))
|
||||
thebox
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
`%>%` = magrittr::`%>%`
|
||||
|
||||
osem_boxes = function (exposure = NA, model = NA, grouptag = NA,
|
||||
date = NA, from = NA, to = NA, phenomenon = NA,
|
||||
endpoint = 'https://api.opensensemap.org') {
|
||||
|
||||
# error, if phenomenon, but no time given
|
||||
if (!is.na(phenomenon) && is.na(date) && is.na(to) && is.na(from))
|
||||
stop('Parameter "phenomenon" can only be used together with "date" or "from"/"to"')
|
||||
|
||||
# error, if date and from/to given
|
||||
if (!is.na(date) && (!is.na(to) || !is.na(from)))
|
||||
stop('Parameter "date" cannot be used together with "from"/"to"')
|
||||
|
||||
# error, if only one of from/to given
|
||||
if (
|
||||
(!is.na(to) && is.na(from)) ||
|
||||
(is.na(to) && !is.na(from))
|
||||
) {
|
||||
stop('Parameter "from"/"to" must be used together')
|
||||
}
|
||||
|
||||
query = list(endpoint = endpoint)
|
||||
if (!is.na(exposure)) query$exposure = exposure
|
||||
if (!is.na(model)) query$model = model
|
||||
if (!is.na(grouptag)) query$grouptag = grouptag
|
||||
if (!is.na(phenomenon)) query$phenomenon = phenomenon
|
||||
|
||||
if (!is.na(to) && !is.na(from)) {
|
||||
# error, if from is after to
|
||||
# convert dates to commaseparated UTC ISOdates
|
||||
query$date = parse_dateparams(from, to) %>% paste(collapse = ',')
|
||||
|
||||
} else if (!is.na(date)) {
|
||||
query$date = utc_date(date) %>% date_as_isostring()
|
||||
}
|
||||
|
||||
do.call(get_boxes_, query)
|
||||
}
|
||||
|
||||
osem_box = function (boxId, endpoint = 'https://api.opensensemap.org') {
|
||||
get_box_(boxId, endpoint = endpoint)
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
parse_senseboxdata = function (boxdata) {
|
||||
# extract nested lists for later use & clean them from the list
|
||||
# to allow a simple data.frame structure
|
||||
sensors = boxdata$sensors
|
||||
location = boxdata$loc
|
||||
boxdata[c('loc', 'sensors', 'image', 'boxType')] <- NULL
|
||||
thebox = as.data.frame(boxdata, stringsAsFactors = F)
|
||||
|
||||
# parse timestamps (updatedAt might be not defined)
|
||||
thebox$createdAt = as.POSIXct(strptime(thebox$createdAt, format='%FT%T', tz = 'GMT'))
|
||||
if (!is.null(thebox$updatedAt))
|
||||
thebox$updatedAt = as.POSIXct(strptime(thebox$updatedAt, format='%FT%T', tz = 'GMT'))
|
||||
|
||||
# extract metadata from sensors
|
||||
thebox$phenomena = list(unlist(lapply(sensors, function(s) { s$title })))
|
||||
# FIXME: if one sensor has NA, max() returns bullshit
|
||||
thebox$lastMeasurement = max(lapply(sensors, function(s) {
|
||||
if (!is.null(s$lastMeasurement))
|
||||
as.POSIXct(strptime(s$lastMeasurement$createdAt, format = '%FT%T', tz = 'GMT'))
|
||||
else
|
||||
NA
|
||||
})[[1]])
|
||||
|
||||
# extract coordinates & transform to simple feature object
|
||||
thebox$lon = location[[1]]$geometry$coordinates[[1]]
|
||||
thebox$lat = location[[1]]$geometry$coordinates[[2]]
|
||||
if (length(location[[1]]$geometry$coordinates) == 3)
|
||||
thebox$height = location[[1]]$geometry$coordinates[[3]]
|
||||
|
||||
# attach a custom class for methods
|
||||
class(thebox) = c('sensebox', class(thebox))
|
||||
thebox
|
||||
}
|
||||
|
||||
get_phenomena = function (x, ...) UseMethod('get_phenomena')
|
||||
get_phenomena.default = function (x, ...) stop('not implemented')
|
||||
get_phenomena.sensebox = function (x, ...) {
|
||||
# FIXME: only returns first box for get_boxes!
|
||||
x$phenomena[[1]]
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
# ==============================================================================
|
||||
#
|
||||
#' Get count statistics of the openSenseMap Instance
|
||||
#'
|
||||
#' Provides information on number of senseBoxes, measurements, and measurements per minute.
|
||||
#'
|
||||
#' @details Note that the API caches these values for 5 minutes.
|
||||
#'
|
||||
#' @param endpoint The URL of the openSenseMap API
|
||||
#' @return A named \code{list} containing the counts
|
||||
#'
|
||||
#' @export
|
||||
#' @seealso \href{https://docs.opensensemap.org/#api-Misc-getStatistics}{openSenseMap API documentation (web)}
|
||||
osem_counts = function (endpoint = 'https://api.opensensemap.org') {
|
||||
get_stats_(endpoint)
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
osem_counts = function (endpoint = 'https://api.opensensemap.org') {
|
||||
get_stats_(endpoint)
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
#' opensensemap: Work with sensor data from opensensemap.org
|
||||
#'
|
||||
#' The opensensemap package provides three categories functions:
|
||||
#' \enumerate{
|
||||
#' \item retrieval of senseBoxes
|
||||
#' \item retrieval of measurements
|
||||
#' \item general stats about the opensensemap database
|
||||
#' }
|
||||
#'
|
||||
#' @section Retrieving senseBox metadata:
|
||||
#' TODO
|
||||
#'
|
||||
#' @section Retrieving measurements:
|
||||
#' TODO
|
||||
#'
|
||||
#' @section Retrieving statistics:
|
||||
#' TODO
|
||||
#'
|
||||
#' @section Working with spatial data from openSenseMap:
|
||||
#' TODO
|
||||
#'
|
||||
#' @docType package
|
||||
#' @name opensensemap
|
||||
'_PACKAGE'
|
||||
|
||||
#' @importFrom graphics plot
|
||||
|
||||
#' @importFrom magrittr %>%
|
||||
`%>%` = magrittr::`%>%`
|
@ -0,0 +1,35 @@
|
||||
# ==============================================================================
|
||||
#
|
||||
#' Get the counts of sensors for each observed phenomenon.
|
||||
#'
|
||||
#' @param boxes A \code{sensebox data.frame} of boxes
|
||||
#' @return An \code{data.frame} containing the count of sensors observing a
|
||||
#' phenomenon per column.
|
||||
#' @export
|
||||
osem_phenomena = function (boxes) UseMethod('osem_phenomena')
|
||||
|
||||
# ==============================================================================
|
||||
#
|
||||
#' @describeIn osem_phenomena Get counts of sensors observing each phenomenon
|
||||
#' from a set of senseBoxes.
|
||||
#' @export
|
||||
#' @seealso \code{\link{osem_boxes}}
|
||||
#' @examples
|
||||
#' # get the phenomena for a single senseBox
|
||||
#' osem_phenomena(osem_box('593bcd656ccf3b0011791f5a'))
|
||||
#'
|
||||
#' # get the phenomena for a group of senseBoxes
|
||||
#' osem_phenomena(
|
||||
#' osem_boxes(grouptag = 'ifgi', exposure = 'outdoor', date = Sys.time())
|
||||
#' )
|
||||
#'
|
||||
#' # get phenomena with at least 10 sensors on opensensemap
|
||||
#' phenoms = osem_phenomena(osem_boxes())
|
||||
#' colnames(dplyr::select_if(phenoms, function(v) v > 9))
|
||||
#'
|
||||
osem_phenomena.sensebox = function (boxes) {
|
||||
Reduce(`c`, boxes$phenomena) %>% # get all the row contents in a single vector
|
||||
table() %>% # get count for each phenomenon
|
||||
t() %>% # transform the table to a df
|
||||
as.data.frame.matrix()
|
||||
}
|
Loading…
Reference in New Issue