File indexing completed on 2023-12-10 07:31:34
0001 # SPDX-License-Identifier: LGPL-2.1-or-later 0002 # 0003 # SPDX-FileCopyrightText: 2012-2014 Rene Kuettner <rene@bitkanal.net> 0004 # 0005 0006 from __future__ import print_function 0007 0008 import time 0009 import calendar 0010 0011 from lxml import etree 0012 from lxml.builder import ElementMaker 0013 0014 0015 class SpaceObject(object): 0016 0017 DATE_FORMAT = '%Y-%m-%d %H:%M' 0018 0019 # object catagories 0020 CATEGORY_SPACECRAFTS = "Spacecrafts" 0021 CATEGORY_SPACEPROBES = "Spaceprobes" 0022 CATEGORY_MOONS = "Moons" 0023 0024 # body constants 0025 BODY_MERCUR = "Mercur" 0026 BODY_VENUS = "Venus" 0027 BODY_EARTH = "Earth" 0028 BODY_MARS = "Mars" 0029 BODY_JUPITER = "Jupiter" 0030 BODY_SATURN = "Saturn" 0031 BODY_URANUS = "Uranus" 0032 BODY_NEPTUN = "Neptun" 0033 BODY_MOON = "Moon" 0034 0035 def __init__(self, **kwargs): 0036 super(SpaceObject, self).__init__() 0037 self._data_source = None 0038 self._filename_prefix = None 0039 self._name = None 0040 self._category = None 0041 self._related_body = None 0042 self._mission_start = None 0043 self._mission_end = None 0044 self._data_from = None 0045 self._data_until = None 0046 self._data_interval_days = 31 0047 for prop in kwargs.keys(): 0048 if hasattr(self, prop): 0049 setattr(self, prop, kwargs[prop]) 0050 0051 @property 0052 def data_source(self): 0053 return self._data_source 0054 0055 @property 0056 def filename_prefix(self): 0057 if self._filename_prefix is None: 0058 # let's hope this is valid: 0059 return self.name.replace(' ', '_').lower() 0060 return self._filename_prefix 0061 0062 @filename_prefix.setter 0063 def filename_prefix(self, value): 0064 self._filename_prefix = str(value) 0065 0066 @property 0067 def name(self): 0068 return self._name 0069 0070 @name.setter 0071 def name(self, value): 0072 self._name = str(value) 0073 0074 @property 0075 def category(self): 0076 return self._category 0077 0078 @category.setter 0079 def category(self, value): 0080 self._category = str(value) 0081 0082 @property 0083 def related_body(self): 0084 return self._related_body 0085 0086 @related_body.setter 0087 def related_body(self, value): 0088 self._related_body = str(value) 0089 0090 @property 0091 def mission_start(self): 0092 return self._mission_start 0093 0094 @mission_start.setter 0095 def mission_start(self, value): 0096 t = time.strptime(value, self.DATE_FORMAT) 0097 self._mission_start = calendar.timegm(t) 0098 0099 @property 0100 def mission_end(self): 0101 return self._mission_end 0102 0103 @mission_end.setter 0104 def mission_end(self, value): 0105 t = time.strptime(value, self.DATE_FORMAT) 0106 self._mission_end = calendar.timegm(t) 0107 0108 @property 0109 def data_from(self): 0110 if self._data_from is None: 0111 if self.mission_start is None: 0112 return time.time() - (time.time() % (3600*24)) + 1 0113 else: 0114 return self.mission_start + (24*3600) 0115 return self._data_from 0116 0117 @data_from.setter 0118 def data_from(self, value): 0119 t = time.strptime(value, self.DATE_FORMAT) 0120 self._data_from = calendar.timegm(t) 0121 0122 @property 0123 def data_until(self): 0124 if self._data_until is None: 0125 if self.mission_end is None: 0126 return time.time() 0127 else: 0128 return self.mission_end - (24*3600) 0129 return self._data_until 0130 0131 @data_until.setter 0132 def data_until(self, value): 0133 t = time.strptime(value, self.DATE_FORMAT) 0134 self._data_until = calendar.timegm(t) 0135 0136 @property 0137 def data_for_day(self): 0138 return self.data_until - (self.data_until % (3600*24)) + 1 0139 0140 @data_for_day.setter 0141 def data_for_day(self, value): 0142 tm = time.strptime(value, self.DATE_FORMAT) 0143 t = calendar.timegm(tm) 0144 self._data_from = t 0145 self._data_until = t + 60 0146 0147 @property 0148 def data_interval_days(self): 0149 return self._data_interval_days 0150 0151 @data_interval_days.setter 0152 def data_interval_days(self, value): 0153 self._data_interval_days = int(value) 0154 0155 0156 class TASCSpaceObject(SpaceObject): 0157 0158 def __init__(self, **kwargs): 0159 super(TASCSpaceObject, self).__init__(**kwargs) 0160 self._tasc_mission = None 0161 0162 @property 0163 def tasc_mission(self): 0164 if self._tasc_mission is None: 0165 return self.name 0166 return self._tasc_mission 0167 0168 @tasc_mission.setter 0169 def tasc_mission(self, value): 0170 self._tasc_mission = value 0171 0172 0173 class HorizonsSpaceObject(SpaceObject): 0174 0175 def __init__(self, **kwargs): 0176 super(HorizonsSpaceObject, self).__init__(**kwargs) 0177 self._horizons_id = None 0178 0179 @property 0180 def horizons_id(self): 0181 if self._horizons_id is None: 0182 return self.name 0183 return self._horizons_id 0184 0185 @horizons_id.setter 0186 def horizons_id(self, value): 0187 self._horizons_id = value 0188 0189 0190 class SpaceObjectCatalog(object): 0191 0192 def __init__(self, filename, baseURL): 0193 super(SpaceObjectCatalog, self).__init__() 0194 self._filename = filename; 0195 self._baseURL = baseURL 0196 self._file = None 0197 self._open() 0198 self._initXML(); 0199 0200 def __del__(self): 0201 self._close() 0202 0203 def add(self, space_obj, latest_vector): 0204 #url = self._baseURL + "/" + space_obj.filename_prefix + '.txt' 0205 #icon = self._baseURL + "/" + space_obj.filename_prefix + '.png' 0206 satellite = self._E.satellite( 0207 self._E.name(space_obj.name), 0208 self._E.category(space_obj._category), 0209 self._E.relatedBody(space_obj.related_body), 0210 self._E.stateVector( 0211 self._E.position( 0212 x=str(latest_vector[1]), 0213 y=str(latest_vector[2]), 0214 z=str(latest_vector[3]) 0215 ), 0216 self._E.velocity( 0217 x=str(latest_vector[4]), 0218 y=str(latest_vector[5]), 0219 z=str(latest_vector[6]) 0220 ), 0221 mjd=str(latest_vector[0]) 0222 ), 0223 #allvectors=url, 0224 #icon=icon, 0225 ) 0226 mission = self._E.mission() 0227 if space_obj.mission_start is not None: 0228 mission.append(self._E.start(str(space_obj.mission_start))) 0229 if space_obj.mission_end is not None: 0230 mission.append(self._E.end(str(space_obj.mission_end))) 0231 if len(mission): 0232 satellite.append(mission) 0233 self._xml.append(satellite) 0234 print(space_obj.name + " added to object catalog.") 0235 0236 def write(self): 0237 print("Writing catalog to file: " + self._filename) 0238 self._file.write(etree.tostring(self._xml, 0239 pretty_print=True, 0240 xml_declaration=True, 0241 encoding='utf-8')) 0242 0243 def _initXML(self): 0244 self._E = ElementMaker( 0245 namespace="http://marble.kde.org/satellitecatalog", 0246 nsmap={'msc' : "http://marble.kde.org/satellitecatalog"}) 0247 self._xml = self._E.MarbleSatelliteCatalog() 0248 0249 def _open(self): 0250 self._file = open(self._filename, 'w+') 0251 self._file.truncate() 0252 0253 def _close(self): 0254 self._file.close()