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];

}