原始碼如下,使用介面 請按此
library(shiny)
library(dplyr)
library(shinyTime)
# for time zone
cuts <- c(-Inf, -172.5, -157.5, -142.5, -127.5, -112.5, -97.5, -82.5, -67.5,
-52.5, -37.5, -22.5, -7.5, 7.5, 22.5, 37.5, 52.5,
67.5, 82.5, 97.5, 112.5, 127.5, 142.5, 157.5, 172.5, Inf)
labs <- c("-180", "-165", "-150", "-135", "-120", "-105", "-90", "-75",
"-60", "-45", "-30", "-15", "0", "15", "30", "45", "60",
"75", "90", "105", "120", "135", "150", "165", "180")
# Define UI for application that draws a histogram
ui <- fluidPage(
# Application title
titlePanel("Solar Calculator"),
p("created by I-Ting Lai"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
# date
dateInput(inputId = "date", label = "Date input", value = "2017-01-01"),
# time
timeInput(inputId = "time", label = "Time [Hour/Minute/Second]"),
hr(),
# Latitude, Longitude
numericInput(inputId = "long", label = "Longitude [Degree East]", value = 120,
min = -180, max = 180),
numericInput(inputId = "lat", label = "Latitude [Degree North]", value = 23.5,
min = -90, max = 90),
hr(),
# Surface Tilt Angle (β)
numericInput(inputId = "surtl_angle", label = "Surface Tilt Angle [Degree]", value = 0,
min = 0, max = 180),
helpText("* Flat: 0, vertical: 90"),
# Surface Azimuth Angle
numericInput(inputId = "suraz_angle", label = "Surface Azimuth Angle [Degree]", value = 0),
helpText("* Facing south: 0, facing east: -90"),
hr(),
# Beam Normal Solar Radiation
numericInput(inputId = "bn_solradiation", label = "Beam Normal Solar Radiation [W/m2]",
value = 0, min = 0, max = 1367),
submitButton("Update View")
),
# Show a plot of the generated distribution
mainPanel(
h4("Result"),
tableOutput("table")
)
)
)
# sin cos is radian, degree * (pi/180) = radian
# Define server logic required to draw a histogram
server <- function(input, output) {
# 表格-------------------------
dataInput <- reactive({
# n --------------------------------
n <- format(input$date, "%j") %>% as.integer()
# ----------------------------------
# Equation of time (min) -----------
eqt <- ( 9.87*sin( 4*pi*(n-81)/364 ) - 7.53*cos( 2*pi*(n-81)/364 ) - 1.5*sin( 2*pi*(n-81)/364 ) )
# ----------------------------------
# Local time (hour) ----------------
x.lt <- as.POSIXlt(input$time)
local_time <- as.numeric(x.lt$hour + x.lt$min/60 + x.lt$sec/3600)
# ----------------------------------
# Standard longitude (degree) ------
Ls <- cut(input$long, breaks = cuts, labels = labs, include.lowest = TRUE) %>%
as.character() %>%
as.numeric()
# ----------------------------------
# Solar time (hour) ----------------
sol_time <- local_time + eqt/60 + (Ls - input$long)/15
# ----------------------------------
# Solar hour angle (degree) --------
sol_hour <- (sol_time - 12)*15
# ----------------------------------
# Solar declination (degree) -------
sol_declin <- 23.45*sin( 360*(284+n)/365 * (pi/180) ) # check
# ----------------------------------
# solar altitude -------------------
sol_alti <- asin( cos( input$lat*(pi/180) ) * cos( sol_declin*(pi/180) ) * cos( sol_hour*(pi/180) ) + sin( input$lat*(pi/180) ) * sin( sol_declin*(pi/180) ) )
sol_alti_degree <- sol_alti*(180/pi) # degree
# ----------------------------------
# solar zenith (degree) ------------
sol_zen_degree <- 90 - sol_alti_degree
# ----------------------------------
# solar azimuth (degree) -----------
# 分子
numerator <- sin( sol_alti_degree*(pi/180) ) * sin( input$lat*(pi/180) ) - sin( sol_declin*(pi/180) )
# 分母
denominator <- cos( sol_alti_degree*(pi/180) ) * cos( input$lat*(pi/180) )
sol_azim <- acos(numerator/denominator) * (sol_hour*(pi/180)/abs(sol_hour*(pi/180)))
sol_azim_degree <- sol_azim*(180/pi) # degree
# ----------------------------------
# Surface solar azimuth (degree) ----
sur_sol_azim_degree <- abs(sol_azim_degree - input$suraz_angle)
# ----------------------------------
# Incident angle (degree) ----------
incident_angle <- acos( cos( sol_alti_degree*(pi/180) ) * cos( sur_sol_azim_degree*(pi/180) ) * sin( input$surtl_angle*(pi/180) ) + sin( sol_alti_degree*(pi/180) ) * cos( input$surtl_angle*(pi/180) ) )
incident_angle_degree <- incident_angle*(180/pi) # degree
# ----------------------------------
# Beam Solar Radiation on any Surface ----
radiation_on_surface <- input$bn_solradiation * cos( incident_angle_degree*(pi/180) )
# ----------------------------------
# Compose data frame
data.frame(
Item = c("Day of the year",
"Equation of time",
"Solar time",
"Solar hour angle",
"Solar declination",
"Solar altitude",
"Solar zenith",
"Solar azimuth",
"Surface solar azimuth",
"Incident angle",
"Beam solar radiation on the surface"),
Value = as.numeric(c(n,
round(eqt, digits = 2),
round(sol_time, digits = 2),
round(sol_hour, digits = 2),
round(sol_declin, digits = 2),
round(sol_alti_degree, digits = 2),
round(sol_zen_degree, digits = 2),
round(sol_azim_degree, digits = 2),
round(sur_sol_azim_degree, digits = 2),
round(incident_angle_degree, digits = 2),
round(radiation_on_surface, digits = 2))),
Units = c("day",
"min",
"hour",
"degree",
"degree",
"degree",
"degree",
"degree",
"degree",
"degree",
"W/m2"),
Details = c("",
"",
"",
"",
"",
"horizon: 0",
"",
"south: 0, west: 90, east: -90",
"",
"",
""),
stringsAsFactors = FALSE)
})
output$table <- renderTable({
dataInput() # 輸出表格
})
# -----------------------------
}
# Run the application
shinyApp(ui = ui, server = server)