関数名: get_sun_position
緯度、経度、日時を入力として受け取り、度(Degrees)単位で高度と方位(北=0°, 東=90°, 南=180°, 西=270°)を返す関数です。
#' 太陽の高度と方位を計算する関数
#'
#' @param lat 緯度(度、10進数)
#' @param lon 経度(度、10進数)
#' @param datetime 日時(POSIXct型)
#' @return 高度(elevation)と方位(azimuth)のリスト(単位は度)
get_sun_position <- function(lat, lon, datetime) {
if (!inherits(datetime, "POSIXct")) {
stop("エラー: datetimeはPOSIXct型である必要があります。")
}
# --- 内部ヘルパー関数 ---
deg2rad <- function(deg) deg * pi / 180
rad2deg <- function(rad) rad * 180 / pi
# --- 1. 時間の計算 ---
unix_time <- as.numeric(datetime)
jd <- (unix_time / 86400.0) + 2440587.5
jc <- (jd - 2451545.0) / 36525.0
# --- 2. 地球と太陽の軌道要素 ---
l0 <- (280.46646 + jc * (36000.76983 + jc * 0.0003032)) %% 360
m <- 357.52911 + jc * (35999.05029 - 0.0001537 * jc)
e <- 0.016708634 - jc * (0.000042037 + 0.0000001267 * jc)
c_rad <- sin(deg2rad(m)) * (1.914602 - jc * (0.004817 + 0.000014 * jc)) +
sin(deg2rad(2 * m)) * (0.019993 - 0.000101 * jc) +
sin(deg2rad(3 * m)) * 0.000289
lambda <- l0 + c_rad
omega <- 125.04 - 1934.136 * jc
lambda_app <- lambda - 0.00569 - 0.00478 * sin(deg2rad(omega))
eps0 <- 23.0 + (26.0 + ((21.448 - jc * (46.815 + jc * (0.00059 - jc * 0.001813))) / 60.0)) / 60.0
eps <- eps0 + 0.00256 * cos(deg2rad(omega))
# --- 3. 太陽赤緯と均時差 ---
declination <- rad2deg(asin(sin(deg2rad(eps)) * sin(deg2rad(lambda_app))))
y <- tan(deg2rad(eps / 2.0))^2
eot <- 4.0 * rad2deg(
y * sin(deg2rad(2 * l0)) -
2.0 * e * sin(deg2rad(m)) +
4.0 * e * y * sin(deg2rad(m)) * cos(deg2rad(2 * l0)) -
0.5 * y^2 * sin(deg2rad(4 * l0)) -
1.25 * e^2 * sin(deg2rad(2 * m))
)
# --- 4. 真太陽時と時角 ---
time_utc_min <- (unix_time %% 86400) / 60.0
tst <- (time_utc_min + eot + 4.0 * lon) %% 1440
ha <- (tst / 4.0) - 180.0
# --- 5. 高度と方位の計算(球面三角法) ---
lat_rad <- deg2rad(lat)
dec_rad <- deg2rad(declination)
ha_rad <- deg2rad(ha)
# 幾何学的な高度
el_rad <- asin(sin(lat_rad) * sin(dec_rad) + cos(lat_rad) * cos(dec_rad) * cos(ha_rad))
elevation_true <- rad2deg(el_rad)
# 大気差の補正 (Atmospheric Refraction) を追加
# 光が地球の大気を通過する際の屈折を補正します(地平線に近いほど影響大)
refraction <- ifelse(
elevation_true > -1,
1.02 / tan(deg2rad(elevation_true + 10.3 / (elevation_true + 5.11))) / 60.0,
0
)
elevation <- elevation_true + refraction
# 太陽方位 (Azimuth) の計算
# atan2() を使用することで、北(0度)から時計回りの角度を全ての象限で取得
sin_az <- -sin(ha_rad) * cos(dec_rad) / cos(el_rad)
cos_az <- (sin(dec_rad) - sin(lat_rad) * sin(el_rad)) / (cos(lat_rad) * cos(el_rad))
az_rad <- atan2(sin_az, cos_az)
azimuth <- (rad2deg(az_rad) + 360) %% 360
return(list(
elevation = elevation,
azimuth = azimuth
))
}実行例
日時を定義する際は、必ず tz 引数でタイムゾーン(日本なら “Asia/Tokyo”)を指定してください。
# 緯度・経度を設定(例: 東京)
my_lat <- 35.689
my_lon <- 139.691
# 日時を設定(必ずタイムゾーン "Asia/Tokyo" などを指定する)
# 例として、2026年4月3日の正午(12:00)を計算
my_datetime <- as.POSIXct("2026-04-03 12:00:00", tz = "Asia/Tokyo")
# 関数の実行
result <- get_sun_position(lat = my_lat, lon = my_lon, datetime = my_datetime)
# 結果の表示
cat(sprintf("日時: %s\n", my_datetime))
cat(sprintf("太陽の高度: %.2f 度\n", result$elevation))
cat(sprintf("太陽の方位: %.2f 度 (北=0, 東=90, 南=180, 西=270)\n", result$azimuth))日時: 2026-04-03 12:00:00
太陽の高度: 59.40 度
太陽の方位: 187.55 度 (北=0, 東=90, 南=180, 西=270)以上です。

