我有返回日出,日落,太阳能中午和黄昏次为一给定的位置的函数。该函数使用pyephem,并且由于不推荐使用,我想我会重新编写该函数以使用skyfield。然而,skyfield不具有的功能的.previous_rising
,.next_setting
或.next_transit
(至少,我不能找到它们),这是我与pyephem使用。
skyfield确实具有功能find_discrete
,这将给出时间之间搜索找到当一个函数变化,所以我写以下测试:
from datetime import datetime, timedelta
from skyfield import api, almanac
import pytz
ts = api.load.timescale()
planets = api.load('de421.bsp')
sun, earth = planets['sun'], planets['earth']
lat, lon = '44.59028 N', '104.71528 W' # UFO Mooring Site
tzn, elv = 'US/Mountain', 1559
tz = pytz.timezone(tzn)
loc = api.Topos(lat, lon, elevation_m=elv)
earth_loc = earth + loc
def civil_twil(time):
"returns true/false if sun is above -6 degrees"
alt, az, dis = earth_loc.at(time).observe(sun).apparent().altaz()
return alt > -6
t0 = ts.utc(datetime.now(tz))
t1 = ts.utc(tz.normalize(datetime.now(tz) + timedelta(1)))
civil_dawn = almanac.find_discrete(t0, t1, civil_twil)
但是,这只是给了我一个错误,该函数缺少“rough_period”属性和文件没有提到什么可能。我猜想也许它仅对历书类中定义的功能有效;但还是没有提及。
那么,如何通过天空找到/确定黄昏时间?
答案 0 :(得分:3)
文档中有一个example,可使用find_discrete函数查找日出和日落的值。有关此功能,请参见almanac.py中的源代码。唯一的问题是,仅当太阳的顶部与地平线平齐时才进行计算。在以下示例中,我将sunrise_sunset
函数更改为daylength
函数。这样,您可以为daylength
函数指定所需的角度。
from skyfield import api, almanac
from datetime import datetime, timedelta
import pytz
from skyfield.nutationlib import iau2000b
DAYLENGTH_CENTER_HORIZON = 0.0
DAYLENGTH_TOP_HORIZON = 0.26667
DAYLENGTH_TOP_HORIZON_APPARENTLY = 0.8333
DAYLENGTH_CIVIL_TWILIGHT = 6.0
DAYLENGTH_NAUTICAL_TWILIGHT = 12.0
DAYLENGTH_ASTRONOMICAL_TWILIGHT = 18.0
def daylength(ephemeris, topos, degrees):
"""Build a function of time that returns the daylength.
The function that this returns will expect a single argument that is a
:class:`~skyfield.timelib.Time` and will return ``True`` if the sun is up
or twilight has started, else ``False``.
"""
sun = ephemeris['sun']
topos_at = (ephemeris['earth'] + topos).at
def is_sun_up_at(t):
"""Return `True` if the sun has risen by time `t`."""
t._nutation_angles = iau2000b(t.tt)
return topos_at(t).observe(sun).apparent().altaz()[0].degrees > -degrees
is_sun_up_at.rough_period = 0.5 # twice a day
return is_sun_up_at
ts = api.load.timescale()
planets = api.load('de421.bsp')
sun = planets['sun']
earth = planets['earth']
lat, lon = '44.59028 N', '104.71528 W' # UFO Mooring Site
tzn, elv = 'US/Mountain', 1559
tz = pytz.timezone(tzn)
loc = api.Topos(lat, lon, elevation_m=elv)
t0 = ts.utc(datetime.now(tz))
t1 = ts.utc(tz.normalize(datetime.now(tz) + timedelta(1)))
center_time, center_up = almanac.find_discrete(t0, t1, daylength(planets, loc,
DAYLENGTH_CENTER_HORIZON))
print('Sunrise Sunset center of sun is even with horizon:')
print(center_time.utc_iso(), center_up)
apparent_top_time, apparent_top_up = almanac.find_discrete(t0, t1,
daylength(planets, loc, DAYLENGTH_TOP_HORIZON_APPARENTLY))
print('Sunrise Sunset top of sun is apparently even with horizon:')
print(apparent_top_time.utc_iso(), apparent_top_up)
civil_twil_time, civil_twil_up = almanac.find_discrete(t0, t1,
daylength(planets, loc, DAYLENGTH_CIVIL_TWILIGHT))
print('Civil twilight:')
print(civil_twil_time.utc_iso(), civil_twil_up)
这将打印以下结果:
日出太阳的日落中心与地平线齐平:
['2019-02-03T14:20:33Z','2019-02-04T00:05:20Z'] [对错]日出显然,即使有地平线,太阳的日落也是如此:
['2019-02-03T14:15:28Z','2019-02-04T00:10:25Z'] [对错]民事暮光之城:
['2019-02-03T13:44:36Z','2019-02-04T00:41:18Z'] [对错]
第一个列表显示发现更改的时间,第二个列表显示True
(如果太阳升起(或暮光开始))和False
(设置太阳)。
您的案例中缺少的rough_period
应该是一个浮点值,其中包含一天发生的次数。太阳每天升起并落下一次,因此该功能中的事件每天发生两次。这意味着rough_period
是0.5
。例如,当您要计算月相时,可以将rough_period
设置为7.0
(满月轨道为27.3天,每个相为6.825天)。请参见almanac.py源代码中有关季节或月相计算的其他示例。