Skip to content

Commit

Permalink
add all suncalc function
Browse files Browse the repository at this point in the history
  • Loading branch information
bthieurmel committed May 12, 2017
1 parent 2552b04 commit c52ed36
Show file tree
Hide file tree
Showing 14 changed files with 674 additions and 54 deletions.
9 changes: 7 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
Package: suncalc
Version: 0.1
Date: 2017-05-05
Date: 2017-05-12
Title: Compute sun position, sunlight phases, moon position and lunar phase
Authors@R: c(person("Benoit", "Thieurmel", role = c("aut", "cre"), email = "[email protected]"))
Authors@R: c(
person("Vladimir", "Agafonkin", role = c("aut", "cph"),
comment = "suncalc.js library/lib, https://github.com/mourner"),
person("Benoit", "Thieurmel", role = c("aut", "cre"),
comment = "R interface", email = "[email protected]")
)
Description: R interface to suncalc.js library, part of the SunCalc.net project <http://suncalc.net>,
for calculating sun position, sunlight phases (times for sunrise, sunset, dusk, etc.),
moon position and lunar phase for the given location and time.
Expand Down
3 changes: 3 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Generated by roxygen2: do not edit by hand

export(getMoonIllumination)
export(getMoonPosition)
export(getMoonTimes)
export(getSunlightPosition)
export(getSunlightTimes)
import(V8)
86 changes: 86 additions & 0 deletions R/getMoonIllumination.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#' Get Moon illumination
#'
#' @param date : Single or multiple DateTime. Can be a \code{Date} (YYYY-MM-DD),
#' a \code{character} in UTC (YYYY-MM-DD HH:mm:ss) or a \code{POSIXct}
#' @param keep : \code{character}. Vector of variables to keep. See \code{Details}
#'
#' @return \code{data.frame}
#'
#' @details
#'
#' Returns an object with the following properties:
#'
#' \itemize{
#' \item{"fraction"}{ : illuminated fraction of the moon; varies from 0.0 (new moon) to 1.0 (full moon)}
#' \item{"phase"}{ : moon phase; varies from 0.0 to 1.0, described below}
#' \item{"angle"}{ : midpoint angle in radians of the illuminated limb of the moon reckoned eastward from
#' the north point of the disk; the moon is waxing if the angle is negative, and waning if positive}
#' }
#'
#' Moon phase value should be interpreted like this:
#' \itemize{
#' \item{0}{ : New Moon}
#' \item{}{Waxing Crescent}
#' \item{0.25}{ : First Quarter}
#' \item{}{ : Waxing Gibbous}
#' \item{0.5}{Full Moon}
#' \item{}{ : Waning Gibbous}
#' \item{0.75}{Last Quarter}
#' \item{}{ : Waning Crescent}
#'}
#'
#' By subtracting the parallacticAngle from the angle one can get the zenith angle of the moons bright limb (anticlockwise). The zenith angle can be used do draw the moon shape from the observers perspective (e.g. moon lying on its back).
#'
#' @examples
#'
#' # one date
#' getMoonIllumination(date = Sys.Date())
#'
#' # in character
#' getMoonIllumination(date = c("2017-05-12", "2017-05-12 00:00:00"),
#' keep = c("fraction", "phase"))
#'
#' # in POSIXct
#' getMoonIllumination(date = as.POSIXct("2017-05-12 00:00:00", tz = "UTC"))
#' getMoonIllumination(date = as.POSIXct("2017-05-12 02:00:00", tz = "CET"))
#'
#'
#' @import V8
#'
#' @export
#'
#' @seealso \link{getSunlightTimes}, \link{getMoonTimes}, \link{getMoonIllumination},
#' \link{getMoonPosition},\link{getSunlightPosition}
#'
getMoonIllumination <- function(date = Sys.Date(),
keep = c("fraction", "phase", "angle")){
# tz and date control
request_date <- .buildRequestDate(date)

# variable control
available_var <- c("fraction", "phase", "angle")
stopifnot(all(keep %in% available_var))

# call suncalc.js
ct <- v8()

load_suncalc <- ct$source(system.file("suncalc/suncalc.js", package = "suncalc"))

mat_res <- cbind.data.frame(date = date,
data.frame(matrix(nrow = length(date), ncol = length(available_var), NA),
stringsAsFactors = FALSE))
colnames(mat_res)[-1] <- available_var
add_res <- lapply(1:nrow(mat_res), function(x){
ct$eval(paste0("var tmp_res = SunCalc.getMoonIllumination(new Date('",
request_date[x], "Z'));"))

tmp_res <- unlist(ct$get("tmp_res"))
mat_res[x, names(tmp_res)] <<- tmp_res
invisible()
})

# format
mat_res <- mat_res[, c("date", keep)]

mat_res
}
93 changes: 93 additions & 0 deletions R/getMoonPosition.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#' Get Moon position
#'
#' @param date : Single or multiple DateTime. Can be a \code{Date} (YYYY-MM-DD),
#' a \code{character} in UTC (YYYY-MM-DD HH:mm:ss) or a \code{POSIXct}
#' @param lat : \code{numeric}. Single latitude
#' @param lon : \code{numeric}. Single longitude
#' @param data : \code{data.frame}. Alternative to use \code{date}, \code{lat}, \code{lon} for passing multiple coordinates
#' @param keep : \code{character}. Vector of variables to keep. See \code{Details}
#'
#' @return \code{data.frame}
#'
#' @details
#'
#' Returns an object with the following properties:
#'
#' \itemize{
#' \item{"altitude"}{ : moon altitude above the horizon in radians}
#' \item{"azimuth"}{ : moon azimuth in radians}
#' \item{"distance"}{ : distance to moon in kilometers}
#' \item{"parallacticAngle"}{ : parallactic angle of the moon in radians}
#' }
#'
#' @examples
#'
#' # one date
#' getMoonPosition(date = Sys.Date(), lat = 50.1, lon = 1.83)
#'
#' # in character
#' getMoonPosition(date = c("2017-05-12", "2017-05-12 00:00:00"),
#' lat = 50.1, lon = 1.83)
#'
#' # in POSIXct
#' getMoonPosition(date = as.POSIXct("2017-05-12 00:00:00", tz = "UTC"),
#' lat = 50.1, lon = 1.83)
#' getMoonPosition(date = as.POSIXct("2017-05-12 02:00:00", tz = "CET"),
#' lat = 50.1, lon = 1.83)
#'
#' # multiple date + subset
#' getMoonPosition(date = seq.Date(Sys.Date()-9, Sys.Date(), by = 1),
#' keep = c("altitude", "azimuth"),
#' lat = 50.1, lon = 1.83)
#'
#' # multiple coordinates
#' data <- data.frame(date = seq.Date(Sys.Date()-9, Sys.Date(), by = 1),
#' lat = c(rep(50.1, 10), rep(49, 10)),
#' lon = c(rep(1.83, 10), rep(2, 10)))
#'
#' getMoonPosition(data = data,
#' keep = c("altitude", "azimuth"))
#'
#'
#' @import V8
#'
#' @export
#'
#' @seealso \link{getSunlightTimes}, \link{getMoonTimes}, \link{getMoonIllumination},
#' \link{getMoonPosition},\link{getSunlightPosition}
#'
getMoonPosition <- function(date = NULL, lat = NULL, lon = NULL, data = NULL,
keep = c("altitude", "azimuth", "distance", "parallacticAngle")){

# data control
data <- .buildData(date = date, lat = lat, lon = lon, data = data)

# tz and date control
request_date <- .buildRequestDate(data$date)

# variable control
available_var <- c("altitude", "azimuth", "distance", "parallacticAngle")
stopifnot(all(keep %in% available_var))

# call suncalc.js
ct <- v8()

load_suncalc <- ct$source(system.file("suncalc/suncalc.js", package = "suncalc"))

mat_res <- data.frame(matrix(nrow = nrow(data), ncol = length(available_var), NA),
stringsAsFactors = FALSE)
colnames(mat_res) <- available_var
add_res <- lapply(1:nrow(mat_res), function(x){
ct$eval(paste0("var tmp_res = SunCalc.getMoonPosition(new Date('",
request_date[x], "Z'),", data[x, "lat"], ", ", data[x, "lon"], ");"))

tmp_res <- unlist(ct$get("tmp_res"))
mat_res[x, names(tmp_res)] <<- tmp_res
invisible()
})

# format
mat_res <- mat_res[, keep]
res <- cbind(data, mat_res)
res
}
32 changes: 6 additions & 26 deletions R/getMoonTimes.R
Original file line number Diff line number Diff line change
Expand Up @@ -41,35 +41,16 @@
#'
#' @export
#'
#' @seealso \link{getSunlightTimes}, \link{getMoonTimes}, \link{getMoonIllumination},
#' \link{getMoonPosition},\link{getSunlightPosition}
#'
getMoonTimes <- function(date = NULL, lat = NULL, lon = NULL, data = NULL,
keep = c("rise", "set", "alwaysUp", "alwaysDown"),
tz = "UTC"){

# data control
if(!is.null(data)){
if(!is.null(date) | !is.null(lat) | !is.null(lon)){
stop("Must use only 'data' argument, or 'date', 'lat', and 'lon' together. See examples")
}

if(!isTRUE(all.equal("data.frame", class(data)))){
data <- data.frame(data)
}

} else {
if(is.null(date) | is.null(lat) | is.null(lon)){
stop("Must use only 'data' argument, or 'date', 'lat', and 'lon' together. See examples")
}

if(length(lat) > 1){
stop("'lat' must be a unique element. Use 'data' for multiple 'lat'")
}
if(length(lon) > 1){
stop("'lon' must be a unique element. Use 'data' for multiple 'lon'")
}
data <- data.frame(date = date, lat = lat, lon = lon)
}

stopifnot(all(c("date", "lat", "lon") %in% colnames(data)))
# data control
data <- .buildData(date = date, lat = lat, lon = lon, data = data)

if(!"Date" %in% class(data$date)){
stop("date must to be a Date object (class Date)")
Expand All @@ -89,7 +70,7 @@ getMoonTimes <- function(date = NULL, lat = NULL, lon = NULL, data = NULL,
colnames(mat_res) <- available_var
mat_res$alwaysUp <- FALSE
mat_res$alwaysDown <- FALSE
add_res <- lapply(1:nrow(data), function(x){
add_res <- lapply(1:nrow(mat_res), function(x){
ct$eval(paste0("var tmp_res = SunCalc.getMoonTimes(new Date('",
data[x, "date"], "'),", data[x, "lat"], ", ", data[x, "lon"], ", true);"))

Expand All @@ -99,7 +80,6 @@ getMoonTimes <- function(date = NULL, lat = NULL, lon = NULL, data = NULL,
})

# format
colnames(mat_res) <- available_var
mat_res <- mat_res[, keep]

# tz
Expand Down
91 changes: 91 additions & 0 deletions R/getSunlightPosition.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#' Get Sunlight position
#'
#' @param date : Single or multiple DateTime. Can be a \code{Date} (YYYY-MM-DD),
#' a \code{character} in UTC (YYYY-MM-DD HH:mm:ss) or a \code{POSIXct}
#' @param lat : \code{numeric}. Single latitude
#' @param lon : \code{numeric}. Single longitude
#' @param data : \code{data.frame}. Alternative to use \code{date}, \code{lat}, \code{lon} for passing multiple coordinates
#' @param keep : \code{character}. Vector of variables to keep. See \code{Details}
#'
#' @return \code{data.frame}
#'
#' @details
#'
#' Returns an object with the following properties:
#'
#' \itemize{
#' \item{"altitude"}{ : sun altitude above the horizon in radians, e.g. 0 at the horizon and PI/2 at the zenith (straight over your head)}
#' \item{"azimuth"}{ : sun azimuth in radians (direction along the horizon, measured from south to west), e.g. 0 is south and Math.PI * 3/4 is northwest}
#' }
#'
#' @examples
#'
#' # one date
#' getSunlightPosition(date = Sys.Date(), lat = 50.1, lon = 1.83)
#'
#' # in character
#' getSunlightPosition(date = c("2017-05-12", "2017-05-12 00:00:00"),
#' lat = 50.1, lon = 1.83)
#'
#' # in POSIXct
#' getSunlightPosition(date = as.POSIXct("2017-05-12 00:00:00", tz = "UTC"),
#' lat = 50.1, lon = 1.83)
#' getSunlightPosition(date = as.POSIXct("2017-05-12 02:00:00", tz = "CET"),
#' lat = 50.1, lon = 1.83)
#'
#' # multiple date + subset
#' getSunlightPosition(date = seq.Date(Sys.Date()-9, Sys.Date(), by = 1),
#' keep = c("altitude"),
#' lat = 50.1, lon = 1.83)
#'
#' # multiple coordinates
#' data <- data.frame(date = seq.Date(Sys.Date()-9, Sys.Date(), by = 1),
#' lat = c(rep(50.1, 10), rep(49, 10)),
#' lon = c(rep(1.83, 10), rep(2, 10)))
#'
#' getSunlightPosition(data = data,
#' keep = c("altitude", "azimuth"))
#'
#'
#' @import V8
#'
#' @export
#'
#' @seealso \link{getSunlightTimes}, \link{getMoonTimes}, \link{getMoonIllumination},
#' \link{getMoonPosition},\link{getSunlightPosition}
#'
getSunlightPosition <- function(date = NULL, lat = NULL, lon = NULL, data = NULL,
keep = c("altitude", "azimuth")){

# data control
data <- .buildData(date = date, lat = lat, lon = lon, data = data)

# tz and date control
request_date <- .buildRequestDate(data$date)

# variable control
available_var <- c("altitude", "azimuth")
stopifnot(all(keep %in% available_var))

# call suncalc.js
ct <- v8()

load_suncalc <- ct$source(system.file("suncalc/suncalc.js", package = "suncalc"))

mat_res <- data.frame(matrix(nrow = nrow(data), ncol = length(available_var), NA),
stringsAsFactors = FALSE)
colnames(mat_res) <- available_var
add_res <- lapply(1:nrow(mat_res), function(x){
ct$eval(paste0("var tmp_res = SunCalc.getPosition(new Date('",
request_date[x], "Z'),", data[x, "lat"], ", ", data[x, "lon"], ");"))

tmp_res <- unlist(ct$get("tmp_res"))
mat_res[x, names(tmp_res)] <<- tmp_res
invisible()
})

# format
mat_res <- mat_res[, keep]
res <- cbind(data, mat_res)
res
}
Loading

0 comments on commit c52ed36

Please sign in to comment.