2013-10-03 73 views
3

的太陽給定的時間這是一個PHP實現的Josh r code來計算太陽的位置給定日期和時間:位置的一天,經度和緯度的PHP

這是MVG幫助後,更正後的代碼:在10h00 -4.77867/11.86364日期2013年9月1日:

function getSunPosition($lat, $long, $year, $month, $day, $hour, $min) { 
    // From https://stackoverflow.com/questions/8708048/position-of-the-sun-given-time-of-day-latitude-and-longitude?rq=1 

    // Get Julian date for date at noon 
    $jd = gregoriantojd($month,$day,$year); 

    //correct for half-day offset 
    $dayfrac = $hour/24 - .5; 

    //now set the fraction of a day  
    $frac = $dayfrac + $min/60/24; 
    $jd = $jd + $frac; 

    // The input to the Atronomer's almanach is the difference between 
    // the Julian date and JD 2451545.0 (noon, 1 January 2000) 
    $time = ($jd - 2451545); 
    // Ecliptic coordinates 

    // Mean longitude 
    $mnlong = (280.460 + 0.9856474 * $time); 
    $mnlong = fmod($mnlong,360);  
    if ($mnlong < 0) $mnlong = ($mnlong + 360); 

    // Mean anomaly 
    $mnanom = (357.528 + 0.9856003 * $time); 
    $mnanom = fmod($mnanom,360); 
    if ($mnanom < 0) $mnanom = ($mnanom + 360); 
    $mnanom = deg2rad($mnanom); 

    // Ecliptic longitude and obliquity of ecliptic 
    $eclong = ($mnlong + 1.915 * sin($mnanom) + 0.020 * sin(2 * $mnanom)); 
    $eclong = fmod($eclong,360); 
    if ($eclong < 0) $eclong = ($eclong + 360); 
    $oblqec = (23.439 - 0.0000004 * $time); 
    $eclong = deg2rad($eclong); 
    $oblqec = deg2rad($oblqec); 

    // Celestial coordinates 
    // Right ascension and declination 
    $num = (cos($oblqec) * sin($eclong)); 
    $den = (cos($eclong)); 
    $ra = (atan($num/$den)); 
    if ($den < 0) $ra = ($ra + pi()); 
    if ($den >= 0 && $num <0) $ra = ($ra + 2*pi()); 
    $dec = (asin(sin($oblqec) * sin($eclong))); 

    // Local coordinates 
    // Greenwich mean sidereal time 
    //$h = $hour + $min/60 + $sec/3600; 
    $h = $hour + $min/60; 
    $gmst = (6.697375 + .0657098242 * $time + $h); 
    $gmst = fmod($gmst,24); 
    if ($gmst < 0) $gmst = ($gmst + 24); 

    // Local mean sidereal time 
    $lmst = ($gmst + $long/15); 
    $lmst = fmod($lmst,24); 
    if ($lmst < 0) $lmst = ($lmst + 24); 
    $lmst = deg2rad($lmst * 15); 

    // Hour angle 
    $ha = ($lmst - $ra); 
    if ($ha < pi()) $ha = ($ha + 2*pi()); 
    if ($ha > pi()) $ha = ($ha - 2*pi()); 

    // Latitude to radians 
    $lat = deg2rad($lat); 

    // Azimuth and elevation 
    $el = (asin(sin($dec) * sin($lat) + cos($dec) * cos($lat) * cos($ha))); 
    $az = (asin(-cos($dec) * sin($ha)/cos($el))); 

    // For logic and names, see Spencer, J.W. 1989. Solar Energy. 42(4):353  
    if ((sin($dec) - sin($el) * sin($lat)) >00) { 
    if(sin($az) < 0) $az = ($az + 2*pi()); 
    } else { 
    $az = (pi() - $az); 
    } 

    $el = rad2deg($el); 
    $az = rad2deg($az); 
    $lat = rad2deg($lat); 

    return array(number_format($el,2),number_format($az,2)); 
} 

這已被用剛果(赤道附近)緯度/經度測試。在這種情況下,正確答案是: elevation = 67.77503 方位角= 54.51532

感謝您的幫助調試此PHP代碼!

Greg Fabre。

+0

這不是唯一的問題,但是你引用的樣本的第52行('$ h = $ hour + $ min/60 + sec/3600;')和未定義的常量'sec' - 我從原來你應該有一個參數$秒或可以設置爲零? – danielpsc

+0

謝謝丹尼爾,當我複製/粘貼代碼時,這是一個錯字。我刪除了秒,因爲它對我的使用來說太精確了。我糾正了代碼,我仍然在尋找(數學)錯誤! – iero

+1

比較您的代碼和R代碼之間的所有中間結果,並找出第一個區別。 – MvG

回答

2

我相信行

if ($dayfrac < 0) $dayfrac += 1; 

是錯誤的。如果你在中午之前,你不想在一天後的同一時間提及,而是你想指定中午之前的時間,即從中午的朱利安日期中減去。

Removing that line,您的示例日期對應於使用http://www.imcce.fr/en/grandpublic/temps/jour_julien.php計算的日期,即2456536.9166666665。得到的

$el = 67.775028608168 
$az = 54.515316112281 

看起來相當不錯。特別是,它的R運行

elevation = 67.77503 
azimuth = 54.51532 

,並與什麼Stellarium表示同意(儘管我引用了這個錯誤在評論以上):

Alt = 67°46'30" = 67.775 
Az = 54°30'60" = 45.5167 

它也(幾乎)與sunearthtools.com同意,所以我想你搞錯了第一輸入數據時,有:

Screenshot from sunearthtools

所以我想說的是解決在p roblem。

+0

謝謝,你說得對。我期望的答案來自http://www.sunearthtools.com,它似乎是越野車(可能接近equateur)。非常感謝您的幫助,我會更正它可以幫助別人的代碼! – iero

+0

@iero:無法用sunearthtools.com重現您的問題;如上面的屏幕截圖所示,適用於我。 – MvG

+0

我無法上傳圖片,因爲我需要'10聲譽'。但你可以看到我得到的結果[這個鏈接](http://oi39.tinypic.com/ff1ymw.jpg) – iero