найти сумерки раз с неба - PullRequest
       45

найти сумерки раз с неба

0 голосов
/ 01 февраля 2019

У меня есть функция, которая возвращает время восхода, захода солнца, солнечного полдня и сумерек для заданного местоположения.Эта функция использует 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», и в документации не указано, что это может быть.Я собираюсь догадаться, что, возможно, он действителен только для функций, определенных в классе альманаха;но опять же, это не упоминается.

Итак, как я могу найти / определить время сумерек через небесное поле?

1 Ответ

0 голосов
/ 03 февраля 2019

В документации есть пример для поиска значения восхода и захода солнца с помощью функции 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'] [True False]

Восход ЗакатСолнце, очевидно, даже с горизонтом:
['2019-02-03T14: 15: 28Z', '2019-02-04T00: 10: 25Z'] [Верно Неверно]

Гражданские сумерки:
['2019-02-03T13: 44: 36Z', '2019-02-04T00: 41: 18Z'] [True False]

Theпервый список показывает время, когда было обнаружено изменение, а второй список показывает True, если солнце взошло (или наступили сумерки), и False, когда солнце садится.

rough_period, которое былопропущенное в вашем случае должно быть значение с плавающей запятой с тем, сколько это происходит за день.Солнце встает и садится один раз в день, поэтому событие в этой функции происходит два раза в день.Это означает, что rough_period является 0.5.Например, если вы хотите рассчитать фазы луны, rough_period можно установить на 7.0 (орбита полной луны составляет 27,3 дня, что составляет 6,825 дней на фазу).См. Другие примеры для расчета сезона или фазы луны в исходном коде almanac.py .

...