php - 给定一天中的时间,纬度和经度的太阳位置在php中

标签 php r math astronomy azimuth

这是 Josh r code 的 php 实现计算给定日期和时间的太阳位置:

这是在 MvG 帮助后更正的代码:

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));
}

这已在刚果(赤道附近)lat/long 进行了测试:-4.77867/11.86364,日期为 2013 年 9 月 1 日 10:00。在这种情况下,正确答案是: 海拔 = 67.77503 方位角 = 54.51532

感谢您帮助调试此 php 代码!

格雷格·法 bool 。

最佳答案

相信线

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

所以我会说这解决了问题。

关于php - 给定一天中的时间,纬度和经度的太阳位置在php中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19165498/

相关文章:

php - Typo3 8.7.3 ExtBase - 存储库中的单个 MySQL 查询

php - .htaccess 重定向,url 中包含 mysql 内容

XAMPP 上的 Php-intl 安装

r - 将 geom_vline 与facet_wrap 结合使用

r - 使用 ggplot 在 R 中创建堆叠百分比条形图

c - 计算点与多个面之间最小距离的有效方法

php - 如何检查 header 是否已在 PHP 中发送

android - 什么是(如果有)与 iOS 加速/veclib vDSP 框架等效的首选 Android?

javascript - 如何将小数四舍五入到最接近的分数?

如果 R 中的 n Obs < x,则删除重复的 obs 数据