Created
March 16, 2013 05:04
-
-
Save keiya/5175072 to your computer and use it in GitHub Desktop.
日の出・日の入りの計算アルゴリズム
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <html><head> | |
| <meta http-equiv="content-type" content="text/html; charset=utf-8"> | |
| <style> | |
| div#map_canvas { | |
| width: 640px; | |
| height: 320px; | |
| } | |
| </style> | |
| <title>SOLAR</title> | |
| </head> | |
| <body> | |
| <form> | |
| <h2>地点選択</h2> | |
| <input type='button' id='ui_curr' value='現在地' /> | |
| <div id="map_canvas" style="border-left:1px solid #555555;"></div> | |
| 緯度(lat.)<input name="lat" size="10" value="35.65" type="TEXT">N | |
| 経度(lng.)<input name="lon" size="10" value="139.7333" type="TEXT">E | |
| 標高(alt.)<input name="alt" size="10" value="0.0" type="TEXT">m<br> | |
| <h2>日付</h2> | |
| <input value="今日" id='ui_today' type="button"> | |
| 西暦<input name="year" size="5" value="2013" type="TEXT">年 | |
| <input name="month" size="5" value="3" type="TEXT">月 | |
| <input name="dayn" size="5" value="16" type="TEXT">日 <br> | |
| グリニッジ標準時との時差<input name="def" size="5" value="9" type="TEXT">時間<br><br> | |
| <h2>結果</h2> | |
| <input value="計算開始" id='ui_calc' type="button"><br> | |
| </form> | |
| <div id='result'></div> | |
| <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> | |
| <script src='jquery-1.9.1.min.js'></script> | |
| <script src='solar.js'></script> | |
| <script src='ui.js'></script> | |
| </body></html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| * thanks to | |
| * http://www.hoshi-lab.info/env/solar-j.html | |
| */ | |
| if (!jp) var jp = {}; | |
| if (!jp.co) jp.co = {}; | |
| if (!jp.co.missinglink) jp.co.missinglink = {}; | |
| if (!jp.co.missinglink.aerograce) jp.co.missinglink.aerograce = {}; | |
| jp.co.missinglink.aerograce.solar = function() {}; | |
| (function(){ | |
| // sin function using degree | |
| function sind(d) { | |
| return Math.sin(d*Math.PI/180) ;} | |
| // cos function using degree | |
| function cosd(d) { | |
| return Math.cos(d*Math.PI/180) ; } | |
| // tan function using degree | |
| function tand(d) { | |
| return Math.tan(d*Math.PI/180) ; } | |
| // calculate Julius year (year from 2000/1/1, for variable "t") | |
| function jy(yy,mm,dd,h,m,s,i) { // yy/mm/dd h:m:s, i: time difference | |
| yy -= 2000 ; | |
| if(mm <= 2) { | |
| mm += 12 ; | |
| yy-- ; } | |
| var k = 365 * yy + 30 * mm + dd - 33.5 - i / 24 + Math.floor(3 * (mm + 1) / 5) | |
| + Math.floor(yy / 4) - Math.floor(yy / 100) + Math.floor(yy / 400); | |
| k += ((s / 60 + m) / 60 + h) / 24 ; // plus time | |
| k += (65 + yy) / 86400 ; // plus delta T | |
| return k / 365.25 ; | |
| } | |
| // solar position1 (celestial longitude, degree) | |
| function spls(t) { // t: Julius year | |
| var l = 280.4603 + 360.00769 * t | |
| + (1.9146 - 0.00005 * t) * sind(357.538 + 359.991 * t) | |
| + 0.0200 * sind(355.05 + 719.981 * t) | |
| + 0.0048 * sind(234.95 + 19.341 * t) | |
| + 0.0020 * sind(247.1 + 329.640 * t) | |
| + 0.0018 * sind(297.8 + 4452.67 * t) | |
| + 0.0018 * sind(251.3 + 0.20 * t) | |
| + 0.0015 * sind(343.2 + 450.37 * t) | |
| + 0.0013 * sind( 81.4 + 225.18 * t) | |
| + 0.0008 * sind(132.5 + 659.29 * t) | |
| + 0.0007 * sind(153.3 + 90.38 * t) | |
| + 0.0007 * sind(206.8 + 30.35 * t) | |
| + 0.0006 * sind( 29.8 + 337.18 * t) | |
| + 0.0005 * sind(207.4 + 1.50 * t) | |
| + 0.0005 * sind(291.2 + 22.81 * t) | |
| + 0.0004 * sind(234.9 + 315.56 * t) | |
| + 0.0004 * sind(157.3 + 299.30 * t) | |
| + 0.0004 * sind( 21.1 + 720.02 * t) | |
| + 0.0003 * sind(352.5 + 1079.97 * t) | |
| + 0.0003 * sind(329.7 + 44.43 * t) ; | |
| while(l >= 360) { l -= 360 ; } | |
| while(l < 0) { l += 360 ; } | |
| return l ; | |
| } | |
| // solar position2 (distance, AU) | |
| function spds(t) { // t: Julius year | |
| var r = (0.007256 - 0.0000002 * t) * sind(267.54 + 359.991 * t) | |
| + 0.000091 * sind(265.1 + 719.98 * t) | |
| + 0.000030 * sind( 90.0) | |
| + 0.000013 * sind( 27.8 + 4452.67 * t) | |
| + 0.000007 * sind(254 + 450.4 * t) | |
| + 0.000007 * sind(156 + 329.6 * t) | |
| r = Math.pow(10,r) ; | |
| return r ; | |
| } | |
| // solar position3 (declination, degree) | |
| function spal(t) { // t: Julius year | |
| var ls = spls(t) ; | |
| var ep = 23.439291 - 0.000130042 * t ; | |
| var al = Math.atan(tand(ls) * cosd(ep)) * 180 / Math.PI ; | |
| if((ls >= 0)&&(ls < 180)) { | |
| while(al < 0) { al += 180 ; } | |
| while(al >= 180) { al -= 180 ; } } | |
| else { | |
| while(al < 180) { al += 180 ; } | |
| while(al >= 360) { al -= 180 ; } } | |
| return al ; | |
| } | |
| // solar position4 (the right ascension, degree) | |
| function spdl(t) { // t: Julius year | |
| var ls = spls(t) ; | |
| var ep = 23.439291 - 0.000130042 * t ; | |
| var dl = Math.asin(sind(ls) * sind(ep)) * 180 / Math.PI ; | |
| return dl ; | |
| } | |
| // Calculate sidereal hour (degree) | |
| function sh(t,h,m,s,l,i) { // t: julius year, h: hour, m: minute, s: second, | |
| // l: longitude, i: time difference | |
| var d = ((s / 60 + m) / 60 + h) / 24 ; // elapsed hour (from 0:00 a.m.) | |
| var th = 100.4606 + 360.007700536 * t + 0.00000003879 * t * t - 15 * i ; | |
| th += l + 360 * d ; | |
| while(th >= 360) { th -= 360 ; } | |
| while(th < 0) { th += 360 ; } | |
| return th ; | |
| } | |
| // Calculating the seeming horizon altitude "sa"(degree) | |
| function eandp(alt,ds) { // subfunction for altitude and parallax | |
| var e = 0.035333333 * Math.sqrt(alt) ; | |
| var p = 0.002442818 / ds ; | |
| return p - e ; | |
| } | |
| function sa(alt,ds) { // alt: altitude (m), ds: solar distance (AU) | |
| var s = 0.266994444 / ds ; | |
| var r = 0.585555555 ; | |
| var k = eandp(alt,ds) - s - r ; | |
| return k ; | |
| } | |
| // Calculating solar alititude (degree) | |
| function soal(la,th,al,dl) { // la: latitude, th: sidereal hour, | |
| // al: solar declination, dl: right ascension | |
| var h = sind(dl) * sind(la) + cosd(dl) * cosd(la) * cosd(th - al) ; | |
| h = Math.asin(h) * 180 / Math.PI ; | |
| return h; | |
| } | |
| // Calculating solar direction (degree) | |
| function sodr(la,th,al,dl) { // la: latitude, th: sidereal hour, | |
| // al: solar declination, dl: right ascension | |
| var t = th - al ; | |
| var dc = - cosd(dl) * sind(t) ; | |
| var dm = sind(dl) * sind(la) - cosd(dl) * cosd(la) * cosd(t) ; | |
| if(dm == 0) { | |
| st = sind(t) ; | |
| if(st > 0) dr = -90 ; | |
| if(st == 0) dr = 9999 ; | |
| if(st < 0) dr = 90 ; | |
| } | |
| else { | |
| var dr = Math.atan(dc / dm) * 180 / Math.PI ; | |
| if(dm <0) dr += 180 ; | |
| } | |
| if(dr < 0) dr += 360 ; | |
| return dr ; | |
| } | |
| jp.co.missinglink.aerograce.solar.prototype.calc = function (yy,mm,dd,i,alt,lat,lng) { | |
| var t = jy(yy,mm,dd-1,23,59,0,i) ; | |
| var th = sh(t,23,59,0,lng,i) ; | |
| var ds = spds(t) ; | |
| var ls = spls(t) ; | |
| var alp = spal(t) ; | |
| var dlt = spdl(t) ; | |
| var pht = soal(lat,th,alp,dlt) ; | |
| var pdr = sodr(lat,th,alp,dlt) ; | |
| var res = { | |
| 'sast':{},'snt':{},'sciv':{},'sciv':{},'mer':{},'sr':{},'ss':{},'east':{},'ent':{},'eciv':{} | |
| }; | |
| for(hh=0; hh<24; ++hh) { | |
| for(m=0; m<60; ++m) { | |
| t = jy(yy,mm,dd,hh,m,0,i) ; | |
| th = sh(t,hh,m,0,lng,i) ; | |
| ds = spds(t) ; | |
| ls = spls(t) ; | |
| alp = spal(t) ; | |
| dlt = spdl(t) ; | |
| var ht = soal(lat,th,alp,dlt) ; | |
| var dr = sodr(lat,th,alp,dlt) ; | |
| var tt = eandp(alt,ds) ; | |
| var t1 = tt - 18 ; | |
| var t2 = tt - 12 ; | |
| var t3 = tt - 6 ; | |
| var t4 = sa(alt,ds) ; | |
| // Solar check | |
| // 0: non, 1: astronomical twilight start , 2: voyage twilight start, | |
| // 3: citizen twilight start, 4: sun rise, 5: meridian, 6: sun set, | |
| // 7: citizen twilight end, 8: voyage twilight end, | |
| // 9: astronomical twilight end | |
| if((pht<t1)&&(ht>t1)) { | |
| res.sast.h = hh | |
| res.sast.m = m; | |
| } | |
| else if((pht<t2)&&(ht>t2)) { | |
| res.snt.h = hh | |
| res.snt.m = m; | |
| } | |
| else if((pht<t3)&&(ht>t3)) { | |
| res.sciv.h = hh | |
| res.sciv.m = m; | |
| } | |
| else if((pht<t4)&&(ht>t4)) { | |
| res.sr.h = hh | |
| res.sr.m = m; | |
| res.sr.or = Math.floor(dr); | |
| } | |
| else if((pdr<180)&&(dr>180)) { | |
| res.mer.h = hh; | |
| res.mer.m = m; | |
| res.mer.ang = Math.floor(ht); | |
| } | |
| else if((pht>t4)&&(ht<t4)) { | |
| res.ss.h = hh; | |
| res.ss.m = m; | |
| res.ss.or = Math.floor(dr); | |
| } | |
| else if((pht>t3)&&(ht<t3)) { | |
| res.eciv.h = hh; | |
| res.eciv.m = m; | |
| } | |
| else if((pht>t2)&&(ht<t2)) { | |
| res.ent.h = hh; | |
| res.ent.m = m; | |
| } | |
| else if((pht>t1)&&(ht<t1)) { | |
| res.east.h = hh; | |
| res.east.m = m; | |
| } | |
| pht = ht ; | |
| pdr = dr ; | |
| } | |
| } | |
| return res; | |
| } | |
| }()); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| $('document').ready(function(){ | |
| $('#ui_calc').click( | |
| _calc | |
| ); | |
| $('#ui_curr').click(function(){ | |
| if(navigator.geolocation) { | |
| navigator.geolocation.getCurrentPosition(function(pos) { | |
| $lat.val(pos.coords.latitude); | |
| $lng.val(pos.coords.longitude); | |
| _calc(); | |
| }, function() { | |
| }); | |
| } else { | |
| // Browser doesn't support Geolocation | |
| } | |
| }); | |
| var $year = $('input[name="year"]'); | |
| var $month = $('input[name="month"]'); | |
| var $day = $('input[name="dayn"]'); | |
| var $td = $('input[name="def"]'); | |
| var $alt = $('input[name="alt"]'); | |
| var $lat = $('input[name="lat"]'); | |
| var $lng = $('input[name="lon"]'); | |
| var $result = $('#result'); | |
| var marker; | |
| function today() { // get doday | |
| Td = new Date() ; | |
| $year.val(Td.getFullYear()); | |
| $month.val(Td.getMonth() + 1); | |
| $day.val(Td.getDate()); | |
| } | |
| today(); | |
| $('#ui_today').click(function(){ | |
| today(); | |
| _calc(); | |
| }); | |
| $year.change(_calc); | |
| $month.change(_calc); | |
| $day.change(_calc); | |
| $td.change(_calc); | |
| $alt.change(_calc); | |
| function _calc() { | |
| var r = map.getCenter(); | |
| var lat = parseFloat($lat.val()); | |
| var lng = parseFloat($lng.val()); | |
| var yy = $year.val(); | |
| var mm = $month.val(); | |
| var dd = $day.val(); | |
| var i = $td.val(); | |
| var alt = $alt.val();//標高 | |
| var ans = "<h3>" + yy + "/" + mm + "/" + dd + "</h3><table>"; | |
| var solar = new jp.co.missinglink.aerograce.solar; | |
| var res = solar.calc($year.val(),$month.val(),$day.val(),$td.val(),$alt.val(),lat,lng); | |
| ans += "<tr class='res_sa'><td class='res_clock'>" + res.sast.h + ":" + res.sast.m + "</td><td class='res_desc'>start of Astronomical twilight</td></tr>\n" ; | |
| ans += "<tr class='res_sn'><td class='res_clock'>" + res.snt.h + ":" + res.snt.m + "</td><td class='res_desc'>start of Nautical twilight</td></tr>\n" ; | |
| ans += "<tr class='res_sc'><td class='res_clock'>" + res.sciv.h + ":" + res.sciv.m + "</td><td class='res_desc'>start of Civil twilight</td></tr>\n" ; | |
| ans += "<tr class='res_sr'><td class='res_clock'>" + res.sr.h + ":" + res.sr.m + "</td><td class='res_desc'>Sunrise 日出</td><td ='res_add'>orientation:" + res.sr.or +"deg</td></tr>\n"; | |
| ans += "<tr class='res_m'> <td class='res_clock'>" + res.mer.h + ":" + res.mer.m + "</td><td class='res_desc'>Meridian 南中</td><td class='res_add'>altitude:" +res.mer.ang+"deg</td></tr>\n"; | |
| ans += "<tr class='res_ss'><td class='res_clock'>" + res.ss.h + ":" + res.ss.m + "</td><td class='res_desc'>Sunset 日没</td><td class='res_add'>orientation:" + res.ss.or +"deg</td></tr>\n"; | |
| ans += "<tr class='res_ec'><td class='res_clock'>" + res.eciv.h + ":" + res.eciv.m + "</td><td class='res_desc'>end of Civil twilight</td></tr>\n" ; | |
| ans += "<tr class='res_en'><td class='res_clock'>" + res.ent.h + ":" + res.ent.m + "</td><td class='res_desc'>end of Nautical twilight</td></tr>\n" ; | |
| ans += "<tr class='res_ea'><td class='res_clock'>" + res.east.h + ":" + res.east.m + "</td><td class='res_desc'>end of Astronomical twilight</td></tr>\n" ; | |
| ans += "</table>"; | |
| $result.html(ans); | |
| } | |
| var target = new google.maps.LatLng(35.668143,139.733294); | |
| var crosshairShape = {coords:[0,0,0,0],type:'rect'}; | |
| var myOptions = { | |
| zoom: 8, | |
| mapTypeId: google.maps.MapTypeId.ROADMAP, | |
| mapTypeControl:false, | |
| center: target, | |
| overviewMapControl : true, | |
| scaleControl : true, | |
| panControl : true, | |
| zoomControl : true, | |
| streetViewControl: false, | |
| } | |
| var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); | |
| marker = new google.maps.Marker({ | |
| map: map, | |
| icon: 'http://www.daftlogic.com/images/cross-hairs.gif', | |
| shape: crosshairShape | |
| }); | |
| marker.bindTo('position', map, 'center'); | |
| map.setOptions( | |
| { | |
| styles:[ | |
| { | |
| featureType: "all", | |
| stylers: [ | |
| { | |
| hue: '#38a5ee' | |
| }, | |
| {invert_lightness:true}, | |
| {gamma:1.2} | |
| ] | |
| } | |
| ] | |
| } | |
| ); | |
| google.maps.event.addListener(map,'center_changed',function(){ | |
| var r = map.getCenter(); | |
| $lat.val(r.lat()); | |
| $lng.val(r.lng()); | |
| marker.setVisible(false); | |
| }); | |
| google.maps.event.addListener(map,'idle',function(){ | |
| var r = map.getCenter(); | |
| $lat.val(r.lat()); | |
| $lng.val(r.lng()); | |
| _calc(); | |
| marker.setVisible(true); | |
| }); | |
| }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment