boB Rudis
6 years ago
commit
046c8139e5
21 changed files with 484 additions and 0 deletions
@ -0,0 +1,11 @@ |
|||
^.*\.Rproj$ |
|||
^\.Rproj\.user$ |
|||
^\.travis\.yml$ |
|||
^README\.*Rmd$ |
|||
^README\.*html$ |
|||
^NOTES\.*Rmd$ |
|||
^NOTES\.*html$ |
|||
^\.codecov\.yml$ |
|||
^README_files$ |
|||
^doc$ |
|||
^terminator-animation\.gif$ |
@ -0,0 +1 @@ |
|||
comment: false |
@ -0,0 +1,8 @@ |
|||
.DS_Store |
|||
.Rproj.user |
|||
.Rhistory |
|||
.RData |
|||
.Rproj |
|||
src/*.o |
|||
src/*.so |
|||
src/*.dll |
@ -0,0 +1,31 @@ |
|||
language: r |
|||
|
|||
warnings_are_errors: true |
|||
|
|||
sudo: required |
|||
|
|||
cache: packages |
|||
|
|||
r: |
|||
- oldrel |
|||
- release |
|||
- devel |
|||
|
|||
apt_packages: |
|||
- libv8-dev |
|||
- xclip |
|||
|
|||
env: |
|||
global: |
|||
- CRAN: http://cran.rstudio.com |
|||
|
|||
after_success: |
|||
- Rscript -e 'covr::codecov()' |
|||
|
|||
notifications: |
|||
email: |
|||
- bob@rud.is |
|||
irc: |
|||
channels: |
|||
- "104.236.112.222#builds" |
|||
nick: travisci |
@ -0,0 +1,27 @@ |
|||
Package: terminator |
|||
Type: Package |
|||
Title: Compute Global Terminator (Day/Night) Bands |
|||
Version: 0.1.0 |
|||
Date: 2018-01-25 |
|||
Authors@R: c( |
|||
person("Bob", "Rudis", email = "bob@rud.is", role = c("aut", "cre"), |
|||
comment = c(ORCID = "0000-0001-5670-2640")), |
|||
person("Joe", "Gallagher", email = "joedgallagher@gmail.com", role = "aut") |
|||
) |
|||
Encoding: UTF-8 |
|||
Maintainer: Bob Rudis <bob@rud.is> |
|||
Description: A good description goes here otherwise CRAN checks fail. |
|||
URL: https://github.com/hrbrmstr/terminator |
|||
BugReports: https://github.com/hrbrmstr/terminator/issues |
|||
License: AGPL |
|||
Suggests: |
|||
testthat, |
|||
covr |
|||
Depends: |
|||
R (>= 3.2.0) |
|||
Imports: |
|||
purrr, |
|||
Rcpp, |
|||
utils |
|||
RoxygenNote: 6.0.1.9000 |
|||
LinkingTo: Rcpp |
@ -0,0 +1,8 @@ |
|||
# Generated by roxygen2: do not edit by hand |
|||
|
|||
export(terminator) |
|||
export(terminator_lat_lon) |
|||
importFrom(Rcpp,sourceCpp) |
|||
importFrom(purrr,map_df) |
|||
importFrom(utils,globalVariables) |
|||
useDynLib(terminator) |
@ -0,0 +1,2 @@ |
|||
0.1.0 |
|||
* Initial release |
@ -0,0 +1,19 @@ |
|||
# Generated by using Rcpp::compileAttributes() -> do not edit by hand |
|||
# Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 |
|||
|
|||
#' Compute a single termiantor band |
|||
#' |
|||
#' Returns a dataframe of latitude and longitude for the line that separates illuminated |
|||
#' day and dark night for any given time |
|||
#' |
|||
#' @md |
|||
#' @param time time (numeric from `POSIXct`) for the computation (bands are time-dependent) |
|||
#' @param from,to,by latitude sequence setup |
|||
#' @return data frame |
|||
#' @references <https://github.com/joergdietrich/Leaflet.Terminator/blob/master/L.Terminator.js>, |
|||
#' <https://github.com/JoGall/terminator/blob/master/terminator.R> |
|||
#' @export |
|||
terminator <- function(time, from = -180, to = 180, by = 0.1) { |
|||
.Call('_terminator_terminator', PACKAGE = 'terminator', time, from, to, by) |
|||
} |
|||
|
@ -0,0 +1,10 @@ |
|||
#' Compute Global Terminator (Day/Night) Bands |
|||
#' |
|||
#' @name terminator |
|||
#' @docType package |
|||
#' @author Bob Rudis (bob@@rud.is) |
|||
#' @importFrom purrr map_df |
|||
#' @importFrom utils globalVariables |
|||
#' @useDynLib terminator |
|||
#' @importFrom Rcpp sourceCpp |
|||
NULL |
@ -0,0 +1,15 @@ |
|||
utils::globalVariables(c(".x")) |
|||
|
|||
#' Generate a full set of terminator frames |
|||
#' |
|||
#' @param day,from,to,by setup for the hours sequence |
|||
#' @export |
|||
terminator_lat_lon <- function(day = Sys.Date(), from=0, to=23, by=1) { |
|||
|
|||
purrr::map_df(seq(0, 23, 1), ~{ |
|||
out <- terminator(as.integer((as.POSIXct(day) + (60*60*.x))), -180, 190, 0.5) |
|||
out$frame <- .x |
|||
out |
|||
}) |
|||
|
|||
} |
@ -0,0 +1,57 @@ |
|||
--- |
|||
output: rmarkdown::github_document |
|||
editor_options: |
|||
chunk_output_type: console |
|||
--- |
|||
|
|||
# terminator |
|||
|
|||
Compute Global Terminator (Day/Night) Bands |
|||
|
|||
## Description |
|||
|
|||
Compute global terminator (day/night) bands which can be overlayed as day and night regions on a ggplot2 world map. |
|||
|
|||
## What's Inside The Tin |
|||
|
|||
The following functions are implemented: |
|||
|
|||
- `terminator`: Compute a single termiantor band |
|||
- `terminator_lat_lon`: Generate a full set of terminator frames |
|||
|
|||
## Installation |
|||
|
|||
```{r eval=FALSE} |
|||
devtools::install_github("hrbrmstr/terminator") |
|||
``` |
|||
|
|||
```{r message=FALSE, warning=FALSE, error=FALSE, include=FALSE} |
|||
options(width=120) |
|||
``` |
|||
|
|||
## Usage |
|||
|
|||
```{r message=FALSE, warning=FALSE, error=FALSE, eval=TRUE} |
|||
library(terminator) |
|||
library(ggplot2) |
|||
library(gganimate) # devtools::install_github("dgrtwo/gganimate") |
|||
|
|||
# current verison |
|||
packageVersion("terminator") |
|||
|
|||
term_seq <- terminator_lat_lon() |
|||
|
|||
chart <- ggplot(term_seq, aes(frame = frame)) + |
|||
borders("world", colour = "gray90", fill = "gray85") + |
|||
geom_ribbon(aes(lat, ymax = lon), ymin = 90, alpha = 0.2) + |
|||
coord_equal(xlim = c(-180, 190), ylim = c(-58, 85), expand = 0) + |
|||
ggthemes::theme_map() |
|||
|
|||
gganimate( |
|||
chart, |
|||
interval = 0.1, ani.width=1000, ani.height=600, |
|||
filename = "terminator-animation.gif" |
|||
) |
|||
``` |
|||
|
|||
![](terminator-animation.gif) |
@ -0,0 +1,53 @@ |
|||
|
|||
# terminator |
|||
|
|||
Compute Global Terminator (Day/Night) Bands |
|||
|
|||
## Description |
|||
|
|||
Compute global terminator (day/night) bands which can be overlayed as |
|||
day and night regions on a ggplot2 world map. |
|||
|
|||
## What’s Inside The Tin |
|||
|
|||
The following functions are implemented: |
|||
|
|||
- `terminator`: Compute a single termiantor band |
|||
- `terminator_lat_lon`: Generate a full set of terminator frames |
|||
|
|||
## Installation |
|||
|
|||
``` r |
|||
devtools::install_github("hrbrmstr/terminator") |
|||
``` |
|||
|
|||
## Usage |
|||
|
|||
``` r |
|||
library(terminator) |
|||
library(ggplot2) |
|||
library(gganimate) # devtools::install_github("dgrtwo/gganimate") |
|||
|
|||
# current verison |
|||
packageVersion("terminator") |
|||
``` |
|||
|
|||
## [1] '0.1.0' |
|||
|
|||
``` r |
|||
term_seq <- terminator_lat_lon() |
|||
|
|||
chart <- ggplot(term_seq, aes(frame = frame)) + |
|||
borders("world", colour = "gray90", fill = "gray85") + |
|||
geom_ribbon(aes(lat, ymax = lon), ymin = 90, alpha = 0.2) + |
|||
coord_equal(xlim = c(-180, 190), ylim = c(-58, 85), expand = 0) + |
|||
ggthemes::theme_map() |
|||
|
|||
gganimate( |
|||
chart, |
|||
interval = 0.1, ani.width=1000, ani.height=600, |
|||
filename = "terminator-animation.gif" |
|||
) |
|||
``` |
|||
|
|||
![](terminator-animation.gif) |
@ -0,0 +1,29 @@ |
|||
% Generated by roxygen2: do not edit by hand |
|||
% Please edit documentation in R/RcppExports.R, R/terminator-package.R |
|||
\docType{package} |
|||
\name{terminator} |
|||
\alias{terminator} |
|||
\alias{terminator-package} |
|||
\title{Compute a single termiantor band} |
|||
\usage{ |
|||
terminator(time, from = -180, to = 180, by = 0.1) |
|||
} |
|||
\arguments{ |
|||
\item{time}{time (numeric from \code{POSIXct}) for the computation (bands are time-dependent)} |
|||
|
|||
\item{from, to, by}{latitude sequence setup} |
|||
} |
|||
\value{ |
|||
data frame |
|||
} |
|||
\description{ |
|||
Returns a dataframe of latitude and longitude for the line that separates illuminated |
|||
day and dark night for any given time |
|||
} |
|||
\references{ |
|||
\url{https://github.com/joergdietrich/Leaflet.Terminator/blob/master/L.Terminator.js}, |
|||
\url{https://github.com/JoGall/terminator/blob/master/terminator.R} |
|||
} |
|||
\author{ |
|||
Bob Rudis (bob@rud.is) |
|||
} |
@ -0,0 +1,14 @@ |
|||
% Generated by roxygen2: do not edit by hand |
|||
% Please edit documentation in R/terminator_lat_lon.R |
|||
\name{terminator_lat_lon} |
|||
\alias{terminator_lat_lon} |
|||
\title{Generate a full set of terminator frames} |
|||
\usage{ |
|||
terminator_lat_lon(day = Sys.Date(), from = 0, to = 23, by = 1) |
|||
} |
|||
\arguments{ |
|||
\item{day, from, to, by}{setup for the hours sequence} |
|||
} |
|||
\description{ |
|||
Generate a full set of terminator frames |
|||
} |
@ -0,0 +1,3 @@ |
|||
*.o |
|||
*.so |
|||
*.dll |
@ -0,0 +1,31 @@ |
|||
// Generated by using Rcpp::compileAttributes() -> do not edit by hand
|
|||
// Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393
|
|||
|
|||
#include <Rcpp.h> |
|||
|
|||
using namespace Rcpp; |
|||
|
|||
// terminator
|
|||
DataFrame terminator(int time, double from, double to, double by); |
|||
RcppExport SEXP _terminator_terminator(SEXP timeSEXP, SEXP fromSEXP, SEXP toSEXP, SEXP bySEXP) { |
|||
BEGIN_RCPP |
|||
Rcpp::RObject rcpp_result_gen; |
|||
Rcpp::RNGScope rcpp_rngScope_gen; |
|||
Rcpp::traits::input_parameter< int >::type time(timeSEXP); |
|||
Rcpp::traits::input_parameter< double >::type from(fromSEXP); |
|||
Rcpp::traits::input_parameter< double >::type to(toSEXP); |
|||
Rcpp::traits::input_parameter< double >::type by(bySEXP); |
|||
rcpp_result_gen = Rcpp::wrap(terminator(time, from, to, by)); |
|||
return rcpp_result_gen; |
|||
END_RCPP |
|||
} |
|||
|
|||
static const R_CallMethodDef CallEntries[] = { |
|||
{"_terminator_terminator", (DL_FUNC) &_terminator_terminator, 4}, |
|||
{NULL, NULL, 0} |
|||
}; |
|||
|
|||
RcppExport void R_init_terminator(DllInfo *dll) { |
|||
R_registerRoutines(dll, NULL, CallEntries, NULL, NULL); |
|||
R_useDynamicSymbols(dll, FALSE); |
|||
} |
@ -0,0 +1,136 @@ |
|||
#define _USE_MATH_DEFINES |
|||
|
|||
#include <Rcpp.h> |
|||
#include <math.h> |
|||
|
|||
using namespace Rcpp; |
|||
|
|||
#define rad2deg(rad) ((rad * 180.0) / M_PI) |
|||
#define deg2rad(deg) ((deg * M_PI) / 180.0) |
|||
#define get_julian(time) (((double)time / 86400.0) + 2440587.5) |
|||
#define get_gmst(j_day) (fmod((18.697374558 + 24.06570982441908 * (j_day - 2451545.0)), 24.0)) |
|||
|
|||
inline std::vector < double > sun_ecliptic_position(double j_day) { |
|||
|
|||
// compute the position of the Sun in ecliptic coordinates days since start of J2000.0
|
|||
double n = j_day - 2451545.0; |
|||
|
|||
// mean longitude of the Sun
|
|||
double L = fmod((280.460 + 0.9856474 * n), 360.0); |
|||
|
|||
// mean anomaly of the Sun
|
|||
double g = fmod((357.528 + 0.9856003 * n), 360.0); |
|||
|
|||
// ecliptic longitude of Sun
|
|||
double lambda = L + 1.915 * sin(deg2rad(g)) + 0.02 * sin(2 * deg2rad(g)); |
|||
|
|||
// distance from Sun in AU
|
|||
double R = 1.00014 - 0.01671 * cos(deg2rad(g)) - 0.0014 * cos(2 * deg2rad(g)); |
|||
|
|||
std::vector< double > ret(2); |
|||
ret[0] = lambda; |
|||
ret[1] = R; |
|||
|
|||
return(ret); |
|||
|
|||
} |
|||
|
|||
inline double ecliptic_obliquity(double j_day) { |
|||
|
|||
double n = j_day - 2451545.0; |
|||
|
|||
// Julian centuries since J2000.0
|
|||
double T = n / 36525.0; |
|||
|
|||
// compute epsilon
|
|||
return(23.43929111 - |
|||
T * (46.836769 / 3600.0 |
|||
- T * (0.0001831 / 3600.0 |
|||
+ T * (0.00200340 / 3600.0 |
|||
- T * (0.576e-6 / 3600.0 |
|||
- T * 4.34e-8 / 3600.0))))); |
|||
|
|||
} |
|||
|
|||
std::vector< double > sun_equatorial_position(double lng, double obliq) { |
|||
|
|||
double alpha = rad2deg(atan(cos(deg2rad(obliq)) * tan(deg2rad(lng)))); |
|||
double delta = rad2deg(asin(sin(deg2rad(obliq)) * sin(deg2rad(lng)))); |
|||
|
|||
double lQuadrant = floor(lng / 90.0) * 90.0; |
|||
double raQuadrant = floor(alpha / 90.0) * 90.0; |
|||
|
|||
alpha = alpha + (lQuadrant - raQuadrant); |
|||
|
|||
std::vector< double > ret(2); |
|||
|
|||
ret[0] = alpha; |
|||
ret[1] = delta; |
|||
|
|||
return(ret); |
|||
|
|||
} |
|||
|
|||
inline double hour_angle(double lng, std::vector< double >sun_pos, double gst) { |
|||
return((gst + lng / 15.0) * 15.0 - sun_pos[0]); |
|||
} |
|||
|
|||
inline double longitude(double ha, std::vector< double >sun_pos) { |
|||
return(rad2deg(atan(-cos(deg2rad(ha)) / tan(deg2rad(sun_pos[1]))))); |
|||
} |
|||
|
|||
//' Compute a single termiantor band
|
|||
//'
|
|||
//' Returns a dataframe of latitude and longitude for the line that separates illuminated
|
|||
//' day and dark night for any given time
|
|||
//'
|
|||
//' @md
|
|||
//' @param time time (numeric from `POSIXct`) for the computation (bands are time-dependent)
|
|||
//' @param from,to,by latitude sequence setup
|
|||
//' @return data frame
|
|||
//' @references <https://github.com/joergdietrich/Leaflet.Terminator/blob/master/L.Terminator.js>,
|
|||
//' <https://github.com/JoGall/terminator/blob/master/terminator.R>
|
|||
//' @export
|
|||
// [[Rcpp::export]]
|
|||
DataFrame terminator(int time, double from = -180, double to = 180, double by = 0.1) { |
|||
|
|||
// calculate latitude and longitude of terminator within specified range using time (in POSIXct format, e.g. `Sys.time()`)
|
|||
double j_day = get_julian(time); |
|||
|
|||
double gst = get_gmst(j_day); |
|||
|
|||
std::vector< double > sunEclPos = sun_ecliptic_position(j_day); |
|||
|
|||
double eclObliq = ecliptic_obliquity(j_day); |
|||
|
|||
std::vector< double > sunEqPos = sun_equatorial_position(sunEclPos[0], eclObliq); |
|||
|
|||
std::vector< double > out_lat, out_lon; |
|||
|
|||
out_lat.reserve(4000); |
|||
out_lon.reserve(4000); |
|||
|
|||
int n=0; |
|||
|
|||
for (double i=from; i<=to; i+=by) { |
|||
n += 1; |
|||
out_lat.push_back(i); |
|||
out_lon.push_back( |
|||
longitude( |
|||
hour_angle(i, sunEqPos, gst), |
|||
sunEqPos |
|||
) |
|||
); |
|||
} |
|||
|
|||
out_lat.resize(n); |
|||
out_lon.resize(n); |
|||
|
|||
return( |
|||
DataFrame::create( |
|||
Named("lat") = out_lat, |
|||
Named("lon") = out_lon |
|||
) |
|||
); |
|||
|
|||
} |
After Width: | Height: | Size: 1.2 MiB |
@ -0,0 +1,21 @@ |
|||
Version: 1.0 |
|||
|
|||
RestoreWorkspace: Default |
|||
SaveWorkspace: Default |
|||
AlwaysSaveHistory: Default |
|||
|
|||
EnableCodeIndexing: Yes |
|||
UseSpacesForTab: Yes |
|||
NumSpacesForTab: 2 |
|||
Encoding: UTF-8 |
|||
|
|||
RnwWeave: Sweave |
|||
LaTeX: pdfLaTeX |
|||
|
|||
StripTrailingWhitespace: Yes |
|||
|
|||
BuildType: Package |
|||
PackageUseDevtools: Yes |
|||
PackageInstallArgs: --no-multiarch --with-keep.source |
|||
PackageBuildArgs: --resave-data |
|||
PackageRoxygenize: rd,collate,namespace |
@ -0,0 +1,2 @@ |
|||
library(testthat) |
|||
test_check("terminator") |
@ -0,0 +1,6 @@ |
|||
context("basic functionality") |
|||
test_that("we can do something", { |
|||
|
|||
#expect_that(some_function(), is_a("data.frame")) |
|||
|
|||
}) |
Loading…
Reference in new issue