solang.js
下記ファイルの内容を表示しています。 ダウンロードを行うにはファイル名をクリックしてください。
// 太陽高度・方位を求める関数
function solar_angle(lat,lon,dt,timelon) {
/*
この関数は下記サイトにある solang2c.c を移植したものです
http://tama.green.gifu-u.ac.jp/~tama/soft/sample_prog/solang/
<引数>
lat : 緯度
lng : 経度
dt : 日時 Unixタイムスタンプ
timelon : 標準時子午線経度
<戻り値>
配列に、太陽高度、方位が度単位で戻ります
<使い方>
list($elevation,$azimuth) = solar_angle(37,139,time(),135);
*/
/*
! calculate solar elevation angle and azimuthal angle
! using day_of_year, and time (hour)
! latitude and longitude of the place is set below
! also latitude of the place for time (JST)
! elevation, azimuth in radian
! from http://ffpsc.agr.kyushu-u.ac.jp/forman/muratac/solar/solpos1.html
! it say 'from 6s'
*/
// デフォルト値は日本経緯度原点
lat = lat===undefined ? 35+39/60+29.1572/3600 : lat;
lon = lon===undefined ? 139+44/60+28.8869/3600 : lon;
// デフォルト値は現在日時(JST)
dt = dt===undefined ? new Date() : dt;
timelon = timelon===undefined ? 135 : timelon;
var gt = new Date(dt.getFullYear(),0,1);
var yday = Math.ceil((dt.getTime()-gt.getTime())/(24*60*60*1000));
var hour = dt.getHours()+dt.getMinutes()/60+dt.getSeconds()/3600;
var lat1 = lat * Math.PI/180;
var lon1 = lon * Math.PI/180;
var A = 2*Math.PI*yday/365;
var declination = 0.006918 - 0.399912*Math.cos(A)+0.070257*Math.sin(A)
-0.006758*Math.cos(2*A) + 0.000907*Math.sin(2*A)
-0.002697*Math.cos(3*A) + 0.001480*Math.sin(3*A);
var localtime = hour + (lon-timelon)/15;
var B = 2*Math.PI*yday/365;
var et = (0.000075 + 0.001868 * Math.cos(B) -0.032077*Math.sin(B)
-0.014615 * Math.cos(2*B) -0.040849 * Math.sin(2*B) ) * 12 / Math.PI;
var t = 15 * (Math.PI/180) * (localtime + et - 12);
var coszenith = Math.sin(declination)*Math.sin(lat1)
+Math.cos(declination)*Math.cos(lat1)*Math.cos(t);
var elevation = 0.5*Math.PI - Math.acos(coszenith);
var sinkai = Math.cos(declination)*Math.sin(t)/Math.sin(0.5*Math.PI-elevation);
var coskai = (-Math.cos(lat1)*Math.sin(declination)+Math.sin(lat1)*Math.cos(declination)*Math.cos(t))
/Math.sin(0.5*Math.PI-elevation);
var kai = Math.asin( sinkai );
if (coskai<0) {
kai1 = Math.PI - kai;
} else if (coskai>0 && sinkai<0) {
kai1 = 2*Math.PI+kai;
} else {
kai1 = kai;
}
var kai1 = kai1+Math.PI;
if (kai1>2*Math.PI) {
kai1 = kai1 - 2*Math.PI;
}
var azimuth = kai1;
return Array(elevation*180/Math.PI,azimuth*180/Math.PI);
}
// 10進経緯度⇒60進経緯度変換
function dec2sex(dec) {
var pms = (dec<0) ? '-' : '';
dec = Math.abs(dec);
var sex0 = Math.floor(dec);
var sex1 = Math.floor((dec-sex0)*60);
var sex2 = Math.floor((dec-sex0-sex1/60)*3600);
return pms+sex0+'°'+('0'+sex1).slice(-2)+"'"+('0'+sex2).slice(-2)+'"';
}
// 16方位に変換
function dir16(dir,e) {
e = e===undefined ? 'J' : e;
var d16 = new Object();
d16['J'] = Array('北','北北東','北東','東北東','東','東南東','南東','南南東','南','南南西','南西','西南西','西','西北西','北西','北北西');
d16['E'] = Array('N','NNE','NE','ENE','E','ESE','SE','SSE','S','SSW','SW','WSW','W','WNW','SW','SSW');
dir += 360/16/2;
if (dir>=360) dir -= 360;
var i = Math.floor(dir/(360/16));
return d16[e][i];
}