首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >与JPL视野交互的库

与JPL视野交互的库
EN

Code Review用户
提问于 2020-07-30 00:11:17
回答 1查看 451关注 0票数 10

我正在编写一个小型Python库,它从Horizons、JPL的太阳系数据和星历计算服务中获取数据。他们的批处理CGI的概述是这里。虽然脚本很简单,但我想使它尽可能清晰和标准化。

其思想是使用观察者(中心)、目标(命令)、日期时间和所需数据(数量)的位置初始化HorizonsRequest类。响应可以作为发送回的行的完整列表检索,也可以作为请求值的字典检索。

示例请求

要求木星(599)的角度,它的距离,和相对于地球的光旅行时间(399)在当前时间。Horizons用户可以使用web界面找到这些数字ids。

代码语言:javascript
复制
request = horizons.HorizonsRequest("399", "599", datetime.utcnow(), "2,20,21")
request.send()

dictionary = request.get_dictionary()
for key in dictionary:
    print(key, ":", dictionary[key])

图书馆

代码语言:javascript
复制
import sys
import urllib.request
import math
from datetime import datetime, timedelta

def get_julian_datetime(date):
    # Ensure correct format
    if not isinstance(date, datetime):
        raise TypeError('Invalid type for parameter "date" - expecting datetime')
    elif date.year < 1801 or date.year > 2099:
        raise ValueError('Datetime must be between year 1801 and 2099')

    # Perform the calculation
    julian_datetime = 367 * date.year - int((7 * (date.year + int((date.month + 9) 
    / 12.0))) / 4.0) + int((275 * date.month) / 9.0) + date.day + 1721013.5 
    + (date.hour + date.minute / 60.0 + date.second / math.pow(60,2)) / 24.0 
    - 0.5 * math.copysign(1, 100 * date.year + date.month - 190002.5) + 0.5

    return julian_datetime

class HorizonsRequest:
    def __init__(self, center, target, datetime, quantities):
        self.keys = {
            "CENTER": center,
            "COMMAND": target,
            "QUANTITIES": quantities,
            "TLIST": str(get_julian_datetime(datetime)),
            "MAKE_EPHEM": "YES",
            "OBJ_DATA": "NO",
            "TABLE_TYPE": "OBSERVER",
            "CAL_FORMAT": "BOTH",
            "ANG_FORMAT": "DEG",
            "CSV_FORMAT": "YES"
        }
        self.response = []
        self.dictionary = {}
    
    def set_key(self, key, value):
        self.keys[key] = str(value)

    def delete_key(self, key):
        self.keys.pop(key, None)    

    def send(self):
        # create request
        request = "https://ssd.jpl.nasa.gov/horizons_batch.cgi?batch=1"
        for key in self.keys:
            request += "&" + key + "='" + self.keys[key] + "'"

        # send request
        file = urllib.request.urlopen(request)
        for line in file:
            self.response.append(line.decode('utf-8').replace('\n', ''))

    def get_dictionary(self):
        keys = []
        values = [] 

        # locate data position in response
        i = 0
        while i < len(self.response):
            if "$SOE" in self.response[i]:
                keys = self.response[i - 2].split(",")
                values = self.response[i + 1].split(",")
            i += 1

        # create dictionary
        i = 0
        while i < len(keys):
            self.dictionary[keys[i].strip()] = values[i].strip()
            i += 1

        return self.dictionary

    def get_response(self):
        return self.response

如有任何反馈,将不胜感激。

EN

回答 1

Code Review用户

回答已采纳

发布于 2020-07-30 01:17:59

使用请求

urllib是一种痛苦的使用。使用请求代替。除其他外,所有这些代码:

代码语言:javascript
复制
    for key in self.keys:
        request += "&" + key + "='" + self.keys[key] + "'"

就会消失。请求具有字典中的查询字符串格式。

儒略转换

你是否需要自己做这件事是值得怀疑的。找到像https://pypi.org/project/julian/这样的库。

组合-不等式语法

代码语言:javascript
复制
date.year < 1801 or date.year > 2099

应该是

代码语言:javascript
复制
not (1800 < date.year < 2100)

平方

代码语言:javascript
复制
math.pow(60,2)

应该只是

代码语言:javascript
复制
60**2

后期序列化

我建议HorizonsRequest.keys (顺便说一句,它不仅仅是一个键的集合--它是一个字典,所以它的名字是错的)在send中需要它之前不要构造它。也不应公开任意的set_key / delete_key。理论上,您应该对请求格式有足够的了解,即要创建它的信息存储在更强类型的变量中,这些变量可以得到更好的验证。例如,不要存储

代码语言:javascript
复制
"OBJ_DATA": "NO",

作为类成员;相反,存储

代码语言:javascript
复制
obj_data: bool = False
票数 11
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/246205

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档