| @@ -18,21 +18,13 @@ | |||
| import argparse | |||
| from datetime import date | |||
| import numpy | |||
| from kosmorrolib import dumper | |||
| from kosmorrolib.ephemerides import EphemeridesComputer, Position | |||
| # Fixes the "TypeError: Object of type int64 is not JSON serializable" | |||
| # See https://stackoverflow.com/a/50577730 | |||
| def json_default(obj): | |||
| if isinstance(obj, numpy.int64): | |||
| return int(obj) | |||
| raise TypeError('Object of type ' + str(type(obj)) + ' could not be integrated in the JSON') | |||
| def main(): | |||
| args = get_args() | |||
| output_formats = get_dumpers() | |||
| args = get_args(list(output_formats.keys())) | |||
| year = args.year | |||
| month = args.month | |||
| day = args.day | |||
| @@ -43,11 +35,18 @@ def main(): | |||
| ephemeris = EphemeridesComputer(Position(args.latitude, args.longitude, altitude=args.altitude)) | |||
| ephemerides = ephemeris.compute_ephemerides(year, month, day) | |||
| dump = dumper.TextDumper(ephemerides) | |||
| dump = output_formats[args.format](ephemerides) | |||
| print(dump.to_string()) | |||
| def get_args(): | |||
| def get_dumpers() -> {str: dumper.Dumper}: | |||
| return { | |||
| 'text': dumper.TextDumper, | |||
| 'json': dumper.JsonDumper | |||
| } | |||
| def get_args(output_formats: [str]): | |||
| today = date.today() | |||
| parser = argparse.ArgumentParser(description='Compute the ephemerides for a given date, at a given position' | |||
| @@ -56,6 +55,8 @@ def get_args(): | |||
| ' observer positioned at coordinates (0,0), with an altitude of 0.' | |||
| % today.strftime('%a %b %d, %Y')) | |||
| parser.add_argument('--format', '-f', type=str, default=output_formats[0], choices=output_formats, | |||
| help='The format under which the information have to be output') | |||
| parser.add_argument('--latitude', '-lat', type=float, default=0., | |||
| help="The observer's latitude on Earth") | |||
| parser.add_argument('--longitude', '-lon', type=float, default=0., | |||
| @@ -22,6 +22,18 @@ from typing import Union | |||
| from skyfield.api import Topos | |||
| from skyfield.timelib import Time | |||
| MOON_PHASES = { | |||
| 'NEW_MOON': 'New Moon', | |||
| 'FIRST_QUARTER': 'First Quarter', | |||
| 'FULL_MOON': 'Full Moon', | |||
| 'LAST_QUARTER': 'Last Quarter' | |||
| } | |||
| def skyfield_to_moon_phase(val: int) -> str: | |||
| phases = list(MOON_PHASES.keys()) | |||
| return phases[val] | |||
| class Position: | |||
| def __init__(self, latitude: float, longitude: float, altitude: float = 0): | |||
| @@ -18,9 +18,11 @@ | |||
| from abc import ABC, abstractmethod | |||
| import datetime | |||
| import json | |||
| from tabulate import tabulate | |||
| from skyfield import almanac | |||
| from .data import Object | |||
| from skyfield.timelib import Time | |||
| from numpy import int64 | |||
| from .data import Object, AsterEphemerides, MOON_PHASES | |||
| class Dumper(ABC): | |||
| @@ -33,6 +35,30 @@ class Dumper(ABC): | |||
| pass | |||
| class JsonDumper(Dumper): | |||
| def to_string(self): | |||
| return json.dumps(self.ephemeris, | |||
| default=self._json_default, | |||
| indent=4) | |||
| @staticmethod | |||
| def _json_default(obj): | |||
| # Fixes the "TypeError: Object of type int64 is not JSON serializable" | |||
| # See https://stackoverflow.com/a/50577730 | |||
| if isinstance(obj, int64): | |||
| return int(obj) | |||
| if isinstance(obj, Time): | |||
| return obj.utc_iso() | |||
| if isinstance(obj, Object): | |||
| obj = obj.__dict__ | |||
| obj.pop('skyfield_name') | |||
| return obj | |||
| if isinstance(obj, AsterEphemerides): | |||
| return obj.__dict__ | |||
| raise TypeError('Object of type "%s" could not be integrated in the JSON' % str(type(obj))) | |||
| class TextDumper(Dumper): | |||
| def to_string(self): | |||
| return '\n\n'.join(['Ephemerides of %s' % self.date.strftime('%A %B %d, %Y'), | |||
| @@ -69,4 +95,4 @@ class TextDumper(Dumper): | |||
| @staticmethod | |||
| def get_moon(moon): | |||
| return 'Moon phase: %s' % almanac.MOON_PHASES[moon['phase']] | |||
| return 'Moon phase: %s' % MOON_PHASES[moon['phase']] | |||
| @@ -20,7 +20,7 @@ import datetime | |||
| from skyfield import almanac | |||
| from skyfield.timelib import Time | |||
| from .data import Object, Position, AsterEphemerides | |||
| from .data import Object, Position, AsterEphemerides, skyfield_to_moon_phase | |||
| from .core import get_skf_objects, get_timescale, ASTERS, MONTHS | |||
| RISEN_ANGLE = -0.8333 | |||
| @@ -48,7 +48,7 @@ class EphemeridesComputer: | |||
| _, moon_phase = almanac.find_discrete(time1, time2, almanac.moon_phases(get_skf_objects())) | |||
| return {'phase': moon_phase[-1]} | |||
| return {'phase': skyfield_to_moon_phase(moon_phase[-1])} | |||
| @staticmethod | |||
| def get_asters_ephemerides_for_aster(aster, date: datetime.date, position: Position) -> Object: | |||