在PyEphem的世界地图上获取太阳的经度和经度

时间:2015-02-24 22:29:28

标签: astronomy pyephem astropy skyfield

我正在试图确定说太阳,月亮和火星的纬度和经度。我需要相对于地球赤道和本初子午线的结果,以产生类似于this map的结果。

我相信这也是this question的作者想要的,但是那里的答案并没有加起来(与第一个链接的值相比)。

预期结果,来自page linked to earlier

  

2015年1月1日星期四,00:00:00太阳在纬度上达到顶峰: 23°02'南,经度: 179°29'West

>>> import ephem; from math import degrees
>>> b = ephem.Sun(epoch='date'); b.compute('2015/1/1 00:00:00')
>>> print("{},{}".format(degrees(b.dec), degrees(b.ra)))
-23.040580418272267,281.12827017399906

所以纬度/赤纬似乎是正确的,但没有180°环绕将解决正确的提升,可能是因为它始于春分点。

我也试图在0,0使用观察者时失败。

可以使用PyEphem,Skyfield或astropy完成吗? PyEphem中的人造卫星具有方便的sublat和sublong属性似乎很奇怪,但它对天体来说太难了。

1 个答案:

答案 0 :(得分:2)

我终于明白了。有点。实际上我只是将libastro的相关位移植到Python。请注意,此代码针对Skyfield的当前git版本运行(be6c7296)。

这里(gist version):

#!/usr/bin/env python3

from datetime import datetime, timezone
from math import atan, atan2, degrees, floor, pi, radians, sin, sqrt

from skyfield.api import earth, JulianDate, now, sun


def earth_latlon(x, y, z, time):
    """
    For an object at the given XYZ coordinates relative to the center of
    the Earth at the given datetime, returns the latitude and longitude
    as it would appear on a world map.

    Units for XYZ don't matter.
    """
    julian_date = JulianDate(utc=time).tt
    # see https://en.wikipedia.org/wiki/Julian_date#Variants
    # libastro calls this "mjd", but the "Modified Julian Date" is
    # something entirely different
    dublin_julian_date = julian_date - 2415020

    # the following block closely mirrors libastro, so don't blame me
    # if you have no clue what the variables mean or what the magic
    # numbers are because I don't either
    sidereal_solar = 1.0027379093
    sid_day = floor(dublin_julian_date)
    t = (sid_day - 0.5) / 36525
    sid_reference = (6.6460656 + (2400.051262 * t) + (0.00002581 * (t**2))) / 24
    sid_reference -= floor(sid_reference)
    lon = 2 * pi * ((dublin_julian_date - sid_day) *
                    sidereal_solar + sid_reference) - atan2(y, x)
    lon = lon % (2 * pi)
    lon -= pi
    lat = atan(z / sqrt(x**2 + y**2))

    return degrees(lat), degrees(-lon)


if __name__ == '__main__':
    print("2015-01-01 00:00:00:")
    time = datetime(2015, 1, 1, tzinfo=timezone.utc)
    x, y, z = earth(JulianDate(utc=time)).observe(sun).apparent().position.au
    print(earth_latlon(x, y, z, time))

    print("now:")
    time = datetime.now(timezone.utc)
    x, y, z = earth(JulianDate(utc=time)).observe(sun).apparent().position.au
    print(earth_latlon(x, y, z, time))

输出:

2015-01-01 00:00:00:
(-23.05923949080624, -179.2173856294249)
now:
(-8.384551051991025, -47.12917634395421)

如您所见,2015-01-01 00:00:00的值与问题中的参考值相匹配。不完全是,但它对我来说已经足够了。就我所知,我的价值观可能会更好。

由于我对libastro代码中使用的无证魔法数字一无所知,我无法为地球以外的其他物体做这项工作。

@BrandonRhodes:如果您对在Skyfield中使用此功能感兴趣,请告诉我,然后我会尝试将拉取请求放在一起。