libaditya 0.3.4__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- libaditya/__init__.py +46 -0
- libaditya/_version.py +29 -0
- libaditya/calc/__init__.py +9 -0
- libaditya/calc/api.py +30 -0
- libaditya/calc/avasthas.py +346 -0
- libaditya/calc/docs/jaimini-get-arch.md +95 -0
- libaditya/calc/hellenistic.py +37 -0
- libaditya/calc/jaimini.py +335 -0
- libaditya/calc/jaimini_get.py +240 -0
- libaditya/calc/kala.py +73 -0
- libaditya/calc/panchanga.py +422 -0
- libaditya/calc/rashi.py +612 -0
- libaditya/calc/returns.py +50 -0
- libaditya/calc/swe_functions.py +118 -0
- libaditya/calc/varga.py +287 -0
- libaditya/calc/vimshottari.py +431 -0
- libaditya/cards/__init__.py +5 -0
- libaditya/cards/card.py +90 -0
- libaditya/cards/cards_constants.py +115 -0
- libaditya/cards/cards_of_truth.py +323 -0
- libaditya/cards/cot.py +142 -0
- libaditya/cards/deck.py +52 -0
- libaditya/charts/__init__.py +6 -0
- libaditya/charts/api.py +36 -0
- libaditya/charts/bodygraph.py +80 -0
- libaditya/charts/chart.py +286 -0
- libaditya/charts/jaimini.py +83 -0
- libaditya/charts/tajika.py +36 -0
- libaditya/constants.py +1776 -0
- libaditya/draw/__init__.py +20 -0
- libaditya/draw/draw_bodygraph.py +489 -0
- libaditya/draw/draw_sbc.py +712 -0
- libaditya/draw/themes/default-theme.hd +53 -0
- libaditya/ephe/ast0/se00010s.se1 +0 -0
- libaditya/ephe/seas_00.se1 +0 -0
- libaditya/ephe/seas_06.se1 +0 -0
- libaditya/ephe/seas_12.se1 +0 -0
- libaditya/ephe/seas_18.se1 +0 -0
- libaditya/ephe/seas_24.se1 +0 -0
- libaditya/ephe/seas_30.se1 +0 -0
- libaditya/ephe/seas_36.se1 +0 -0
- libaditya/ephe/seas_42.se1 +0 -0
- libaditya/ephe/seas_48.se1 +0 -0
- libaditya/ephe/seasm06.se1 +0 -0
- libaditya/ephe/seasm12.se1 +0 -0
- libaditya/ephe/seasm18.se1 +0 -0
- libaditya/ephe/seasm24.se1 +0 -0
- libaditya/ephe/seasm30.se1 +0 -0
- libaditya/ephe/seasm36.se1 +0 -0
- libaditya/ephe/seasm42.se1 +0 -0
- libaditya/ephe/seasm48.se1 +0 -0
- libaditya/ephe/seasm54.se1 +0 -0
- libaditya/ephe/sefstars.txt +4245 -0
- libaditya/ephe/semo_00.se1 +0 -0
- libaditya/ephe/semo_06.se1 +0 -0
- libaditya/ephe/semo_12.se1 +0 -0
- libaditya/ephe/semo_18.se1 +0 -0
- libaditya/ephe/semo_24.se1 +0 -0
- libaditya/ephe/semo_30.se1 +0 -0
- libaditya/ephe/semo_36.se1 +0 -0
- libaditya/ephe/semo_42.se1 +0 -0
- libaditya/ephe/semo_48.se1 +0 -0
- libaditya/ephe/semom06.se1 +0 -0
- libaditya/ephe/semom12.se1 +0 -0
- libaditya/ephe/semom18.se1 +0 -0
- libaditya/ephe/semom24.se1 +0 -0
- libaditya/ephe/semom30.se1 +0 -0
- libaditya/ephe/semom36.se1 +0 -0
- libaditya/ephe/semom42.se1 +0 -0
- libaditya/ephe/semom48.se1 +0 -0
- libaditya/ephe/semom54.se1 +0 -0
- libaditya/ephe/sepl_00.se1 +0 -0
- libaditya/ephe/sepl_06.se1 +0 -0
- libaditya/ephe/sepl_12.se1 +0 -0
- libaditya/ephe/sepl_18.se1 +0 -0
- libaditya/ephe/sepl_24.se1 +0 -0
- libaditya/ephe/sepl_30.se1 +0 -0
- libaditya/ephe/sepl_36.se1 +0 -0
- libaditya/ephe/sepl_42.se1 +0 -0
- libaditya/ephe/sepl_48.se1 +0 -0
- libaditya/ephe/seplm06.se1 +0 -0
- libaditya/ephe/seplm12.se1 +0 -0
- libaditya/ephe/seplm18.se1 +0 -0
- libaditya/ephe/seplm24.se1 +0 -0
- libaditya/ephe/seplm30.se1 +0 -0
- libaditya/ephe/seplm36.se1 +0 -0
- libaditya/ephe/seplm42.se1 +0 -0
- libaditya/ephe/seplm48.se1 +0 -0
- libaditya/ephe/seplm54.se1 +0 -0
- libaditya/hd/__init__.py +8 -0
- libaditya/hd/calc.py +55 -0
- libaditya/hd/constants.py +127 -0
- libaditya/hd/longitude.py +271 -0
- libaditya/objects/__init__.py +19 -0
- libaditya/objects/celestial_object.py +206 -0
- libaditya/objects/context.py +133 -0
- libaditya/objects/cusps.py +259 -0
- libaditya/objects/julian_day.py +265 -0
- libaditya/objects/location.py +167 -0
- libaditya/objects/longitude.py +987 -0
- libaditya/objects/nakshatras.py +285 -0
- libaditya/objects/planets.py +2059 -0
- libaditya/objects/shadbala.py +398 -0
- libaditya/objects/signs.py +690 -0
- libaditya/objects/swe_functions.py +75 -0
- libaditya/print_functions.py +548 -0
- libaditya/read.py +665 -0
- libaditya/stars/__init__.py +4 -0
- libaditya/stars/fixed_star.py +216 -0
- libaditya/stars/make_swe_stars.py +407 -0
- libaditya/stars/star-sign-boundaries +44 -0
- libaditya/stars/stellarium/__init__.py +6 -0
- libaditya/stars/stellarium/remote_control/__init__.py +22 -0
- libaditya/stars/stellarium/remote_control/location.py +82 -0
- libaditya/stars/stellarium/remote_control/locationsearch.py +35 -0
- libaditya/stars/stellarium/remote_control/main.py +165 -0
- libaditya/stars/stellarium/remote_control/objects.py +63 -0
- libaditya/stars/stellarium/remote_control/scripts.py +81 -0
- libaditya/stars/stellarium/remote_control/simbad.py +20 -0
- libaditya/stars/stellarium/remote_control/stelaction.py +31 -0
- libaditya/stars/stellarium/remote_control/stelproperty.py +30 -0
- libaditya/stars/stellarium/remote_control/view.py +85 -0
- libaditya/stars/stellarium/stellarium.py +92 -0
- libaditya/stars/the_stars.py +522 -0
- libaditya/stars/utilities.py +539 -0
- libaditya/utils.py +431 -0
- libaditya/write.py +67 -0
- libaditya-0.3.4.dist-info/METADATA +588 -0
- libaditya-0.3.4.dist-info/RECORD +131 -0
- libaditya-0.3.4.dist-info/WHEEL +5 -0
- libaditya-0.3.4.dist-info/licenses/LICENSE +661 -0
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
# This file is part of libaditya.
|
|
2
|
+
#
|
|
3
|
+
# Copyright (c) 2025 Josh Harper <humanhaven@substack.com>
|
|
4
|
+
#
|
|
5
|
+
# libaditya is free software: you can redistribute it and/or modify
|
|
6
|
+
# it under the terms of the GNU Affero General Public License as published by
|
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
# (at your option) any later version.
|
|
9
|
+
#
|
|
10
|
+
# libaditya is distributed in the hope that it will be useful,
|
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
# GNU Affero General Public License for more details.
|
|
14
|
+
#
|
|
15
|
+
# You should have received a copy of the GNU Affero General Public License
|
|
16
|
+
# along with libaditya. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
+
|
|
18
|
+
import swisseph as swe
|
|
19
|
+
|
|
20
|
+
import time
|
|
21
|
+
|
|
22
|
+
from libaditya import utils
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
nowtime = time.gmtime()
|
|
26
|
+
nowjdfloat = utils.tmod_to_jd(nowtime)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class JulianDay:
|
|
30
|
+
"""
|
|
31
|
+
takes a float representing a julian day
|
|
32
|
+
or (year,month,day,hour)
|
|
33
|
+
any arguments not given are filled by the current time
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
# time units in julian days
|
|
37
|
+
onedayjd = 1
|
|
38
|
+
oneyearjd = onedayjd * 365.25
|
|
39
|
+
onemonthjd = onedayjd * 30
|
|
40
|
+
onehrjd = onedayjd / 24
|
|
41
|
+
oneminjd = onehrjd / 60
|
|
42
|
+
onesecjd = oneminjd / 60
|
|
43
|
+
|
|
44
|
+
def __init__(self, jd=nowjdfloat, utcoffset=0, timezone="UTC"):
|
|
45
|
+
"""
|
|
46
|
+
initialize JulianDay class
|
|
47
|
+
:jd - can be a float or a tuple(year, month, day, decimal_time)
|
|
48
|
+
:utcoffset - a float
|
|
49
|
+
:timezone - a string representing the timezone
|
|
50
|
+
"""
|
|
51
|
+
if isinstance(jd, float) or isinstance(jd, int):
|
|
52
|
+
self.jd = jd
|
|
53
|
+
elif isinstance(jd, tuple):
|
|
54
|
+
self.jd = swe.julday(jd[0], jd[1], jd[2], jd[3])
|
|
55
|
+
elif jd == "now":
|
|
56
|
+
nowtime = time.gmtime()
|
|
57
|
+
jd = utils.tmod_to_jd(nowtime)
|
|
58
|
+
self.jd = jd
|
|
59
|
+
self.datetime = swe.revjul(self.jd)
|
|
60
|
+
self.utcoffset = float(utcoffset)
|
|
61
|
+
self._timezone = self.mktimezone(timezone)
|
|
62
|
+
self.usrdatetime = self.usrdt()
|
|
63
|
+
|
|
64
|
+
def __repr__(self):
|
|
65
|
+
return str(self.jd)
|
|
66
|
+
|
|
67
|
+
def __str__(self):
|
|
68
|
+
if self.utcoffset == 0:
|
|
69
|
+
return f"{self.date()} at {self.time()}\n{self.jd}"
|
|
70
|
+
else:
|
|
71
|
+
return f"{self.date()} at {self.time()}\n{self.usrdate()} at {self.usrtime()}\n{self.jd}"
|
|
72
|
+
|
|
73
|
+
def __lt__(self, jd2):
|
|
74
|
+
return self.jd < jd2.jd
|
|
75
|
+
|
|
76
|
+
def __le__(self, jd2):
|
|
77
|
+
return self.jd <= jd2.jd
|
|
78
|
+
|
|
79
|
+
def __gt__(self, jd2):
|
|
80
|
+
return self.jd > jd2.jd
|
|
81
|
+
|
|
82
|
+
def __ge__(self, jd2):
|
|
83
|
+
return self.jd >= jd2.jd
|
|
84
|
+
|
|
85
|
+
def T(self):
|
|
86
|
+
"""
|
|
87
|
+
T = (Julian Day - 2451545) / 36525
|
|
88
|
+
for use in cheshta bala calculations
|
|
89
|
+
"""
|
|
90
|
+
return (self.jd_number() - 2451545) / 36525
|
|
91
|
+
|
|
92
|
+
def indent_print(self, n=1) -> None:
|
|
93
|
+
"""
|
|
94
|
+
print like with __str__, but indenting each line n times
|
|
95
|
+
"""
|
|
96
|
+
tab = utils.mktab(n)
|
|
97
|
+
print(
|
|
98
|
+
f"{tab}{self.date()} at {self.time()}\n{tab}{self.usrdate()} at {self.usrtime()}\n{tab}{self.jd}"
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
def indent_print_str(self, n=1) -> str:
|
|
102
|
+
"""
|
|
103
|
+
print like with __str__, but indenting each line n times
|
|
104
|
+
"""
|
|
105
|
+
tab = utils.mktab(n)
|
|
106
|
+
return f"{tab}{self.date()} at {self.time()}\n{tab}{self.usrdate()} at {self.usrtime()}\n{tab}{self.jd}"
|
|
107
|
+
|
|
108
|
+
def mktimezone(self, timezone="UTC") -> str:
|
|
109
|
+
"""
|
|
110
|
+
this only kind of timezone libaditya uses is UTC and UTC +/- (f: float)
|
|
111
|
+
"""
|
|
112
|
+
sign = ""
|
|
113
|
+
appendix = ""
|
|
114
|
+
if self.utcoffset > 0:
|
|
115
|
+
sign = "+"
|
|
116
|
+
if self.utcoffset == 0 or timezone != "UTC":
|
|
117
|
+
appendix = ""
|
|
118
|
+
else:
|
|
119
|
+
appendix = sign + f"{round(self.utcoffset, 2)}"
|
|
120
|
+
return timezone + appendix
|
|
121
|
+
|
|
122
|
+
def timezone(self):
|
|
123
|
+
return self._timezone
|
|
124
|
+
|
|
125
|
+
def jd_number(self):
|
|
126
|
+
return self.jd
|
|
127
|
+
|
|
128
|
+
def date(self, tz="utc"):
|
|
129
|
+
if tz != "utc":
|
|
130
|
+
return f"{utils.date2str(self.usrdatetime)}"
|
|
131
|
+
else:
|
|
132
|
+
return f"{utils.date2str(self.datetime)}"
|
|
133
|
+
|
|
134
|
+
def time(self, tz="utc", print_tz=True, debug=""):
|
|
135
|
+
if debug:
|
|
136
|
+
debug=f" ({self.day(tz)})"
|
|
137
|
+
ptz = ""
|
|
138
|
+
ret = ""
|
|
139
|
+
if tz != "utc":
|
|
140
|
+
if print_tz:
|
|
141
|
+
ptz = " " + self._timezone
|
|
142
|
+
ret += f"{utils.time2str(utils.dec2dms(self.usrdatetime[3]))}{ptz}"
|
|
143
|
+
else:
|
|
144
|
+
if print_tz:
|
|
145
|
+
ptz = " UTC"
|
|
146
|
+
ret += f"{utils.time2str(utils.dec2dms(self.datetime[3]))}{ptz}"
|
|
147
|
+
return ret + debug
|
|
148
|
+
|
|
149
|
+
def timedate(self):
|
|
150
|
+
return f"{utils.time2str(utils.dec2dms(self.datetime[3]))} UTC on {utils.date2str(self.datetime)}"
|
|
151
|
+
|
|
152
|
+
def year(self, tz="utc"):
|
|
153
|
+
if tz != "utc:":
|
|
154
|
+
return self.usryear()
|
|
155
|
+
else:
|
|
156
|
+
return int(self.datetime[0])
|
|
157
|
+
|
|
158
|
+
def month(self, tz="utc"):
|
|
159
|
+
if tz != "utc:":
|
|
160
|
+
return self.usrmonth()
|
|
161
|
+
else:
|
|
162
|
+
return int(self.datetime[1])
|
|
163
|
+
|
|
164
|
+
def day(self, tz="utc"):
|
|
165
|
+
if tz != "utc":
|
|
166
|
+
return self.usrday()
|
|
167
|
+
else:
|
|
168
|
+
return int(self.datetime[2])
|
|
169
|
+
|
|
170
|
+
def hour(self, tz="utc"):
|
|
171
|
+
if tz != "utc":
|
|
172
|
+
return self.usrhour()
|
|
173
|
+
else:
|
|
174
|
+
return float(self.datetime[3])
|
|
175
|
+
|
|
176
|
+
def age(self, datejd):
|
|
177
|
+
"""
|
|
178
|
+
distance in years between self and date
|
|
179
|
+
"""
|
|
180
|
+
return (datejd-self.jd)/365.24221
|
|
181
|
+
|
|
182
|
+
def current_age(self):
|
|
183
|
+
"""
|
|
184
|
+
distance in years between self and date
|
|
185
|
+
"""
|
|
186
|
+
nowtime = time.gmtime()
|
|
187
|
+
jd = utils.tmod_to_jd(nowtime)
|
|
188
|
+
return (jd-self.jd)/self.oneyearjd
|
|
189
|
+
|
|
190
|
+
def current_age_days(self):
|
|
191
|
+
"""
|
|
192
|
+
distance in years between self and date
|
|
193
|
+
"""
|
|
194
|
+
return self.current_age()*365.25
|
|
195
|
+
|
|
196
|
+
def usrdate(self):
|
|
197
|
+
return f"{utils.date2str(self.usrdatetime)}"
|
|
198
|
+
|
|
199
|
+
def usryear(self):
|
|
200
|
+
return int(self.usrdatetime[0])
|
|
201
|
+
|
|
202
|
+
def usrmonth(self):
|
|
203
|
+
return int(self.usrdatetime[1])
|
|
204
|
+
|
|
205
|
+
def usrday(self):
|
|
206
|
+
return int(self.usrdatetime[2])
|
|
207
|
+
|
|
208
|
+
def usrhour(self):
|
|
209
|
+
return float(self.usrdatetime[3])
|
|
210
|
+
|
|
211
|
+
def usrtime(self):
|
|
212
|
+
return f"{utils.time2str(utils.dec2dms(self.usrdatetime[3]))} {self._timezone}"
|
|
213
|
+
|
|
214
|
+
def usrtimedate(self):
|
|
215
|
+
return f"{utils.time2str(utils.dec2dms(self.usrdatetime[3]))} {self._timezone} on {utils.date2str(self.usrdatetime)}"
|
|
216
|
+
|
|
217
|
+
def midnightjd(self):
|
|
218
|
+
"""return the jd that is at midnight of this JulianDay's calendar day"""
|
|
219
|
+
return swe.julday(self.datetime[0], self.datetime[1], self.datetime[2], 0)
|
|
220
|
+
|
|
221
|
+
def midnightJD(self):
|
|
222
|
+
"""return the jd that is at midnight of this JulianDay's calendar day"""
|
|
223
|
+
return JulianDay(swe.julday(self.datetime[0], self.datetime[1], self.datetime[2], 0),self.utcoffset)
|
|
224
|
+
|
|
225
|
+
def next_midnightjd(self):
|
|
226
|
+
"""return the jd that is at next_midnight of this JulianDay's calendar day"""
|
|
227
|
+
return swe.julday(self.datetime[0], self.datetime[1], self.datetime[2], 0)+1
|
|
228
|
+
|
|
229
|
+
def next_midnightJD(self):
|
|
230
|
+
"""return the jd that is at next_midnight of this JulianDay's calendar day"""
|
|
231
|
+
return JulianDay(swe.julday(self.datetime[0], self.datetime[1], self.datetime[2], 0)+1,self.utcoffset,self.timezone())
|
|
232
|
+
|
|
233
|
+
def ecliptic_obliquity(self):
|
|
234
|
+
return swe.calc(self.jd, swe.ECL_NUT)[0][0]
|
|
235
|
+
|
|
236
|
+
def shift(self, dir, unit, number):
|
|
237
|
+
"""
|
|
238
|
+
shift the julianday in 'dir'ection 'f'orward or 'b'ackward
|
|
239
|
+
by number units, 'second','minute','hour','day','month','year'
|
|
240
|
+
"""
|
|
241
|
+
sf = 1 # scale factor
|
|
242
|
+
if dir.startswith("b"):
|
|
243
|
+
sf = -1
|
|
244
|
+
if unit.startswith("s"):
|
|
245
|
+
sf = sf * self.onesecjd
|
|
246
|
+
elif unit.startswith("min"):
|
|
247
|
+
sf = sf * self.oneminjd
|
|
248
|
+
elif unit.startswith("mon"):
|
|
249
|
+
sf = sf * self.onemonthjd
|
|
250
|
+
elif unit.startswith("h"):
|
|
251
|
+
sf = sf * self.onehrjd
|
|
252
|
+
elif unit.startswith("d"):
|
|
253
|
+
sf = sf * self.onedayjd
|
|
254
|
+
elif unit.startswith("y"):
|
|
255
|
+
sf = sf * self.oneyearjd
|
|
256
|
+
else:
|
|
257
|
+
print("given unit not recognized")
|
|
258
|
+
return JulianDay(self.jd + (number * sf),self.utcoffset,self._timezone)
|
|
259
|
+
|
|
260
|
+
def usrdt(self):
|
|
261
|
+
"""
|
|
262
|
+
transform utc time into user specified time with self.utcoffset and timezone string
|
|
263
|
+
return a tuple (year,month,day,hour)
|
|
264
|
+
"""
|
|
265
|
+
return swe.revjul(self.jd + self.utcoffset / 24)
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# This file is part of libaditya.
|
|
2
|
+
#
|
|
3
|
+
# Copyright (c) 2025 Josh Harper <humanhaven@substack.com>
|
|
4
|
+
#
|
|
5
|
+
# libaditya is free software: you can redistribute it and/or modify
|
|
6
|
+
# it under the terms of the GNU Affero General Public License as published by
|
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
# (at your option) any later version.
|
|
9
|
+
#
|
|
10
|
+
# libaditya is distributed in the hope that it will be useful,
|
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
# GNU Affero General Public License for more details.
|
|
14
|
+
#
|
|
15
|
+
# You should have received a copy of the GNU Affero General Public License
|
|
16
|
+
# along with libaditya. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
+
|
|
18
|
+
import swisseph as swe
|
|
19
|
+
from metar import Metar
|
|
20
|
+
|
|
21
|
+
from libaditya import constants as const
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class Location:
|
|
25
|
+
def __init__(
|
|
26
|
+
self,
|
|
27
|
+
lat=0,
|
|
28
|
+
long=165.76666666666668,
|
|
29
|
+
alt=0,
|
|
30
|
+
placename="Yamakoti",
|
|
31
|
+
utcoffset="12",
|
|
32
|
+
icao=None,
|
|
33
|
+
planet="Earth"
|
|
34
|
+
):
|
|
35
|
+
self.lat = float(lat)
|
|
36
|
+
self.long = float(long)
|
|
37
|
+
self.alt = float(alt)
|
|
38
|
+
self._placename = placename
|
|
39
|
+
self.utcoffset = float(utcoffset)
|
|
40
|
+
self._timezone = f"{"+" if self.utcoffset > 0 else ""}{self.utcoffset}"
|
|
41
|
+
self.icao = icao
|
|
42
|
+
self._planet = planet
|
|
43
|
+
self._atmospheric_pressure, self._atmospheric_temperature, self._relative_humidity = self.init_environment(self.icao)
|
|
44
|
+
|
|
45
|
+
def __str__(self):
|
|
46
|
+
return f"{self._placename} ({round(self.lat,3)} lat,{round(self.long,3)} long)\nelevation {self.alt} m\ntimezone: UTC{self._timezone}"
|
|
47
|
+
|
|
48
|
+
def stellarium(self):
|
|
49
|
+
"""
|
|
50
|
+
so we could do self.rc().location.setLocation(*context.location.stellarium())
|
|
51
|
+
but we need the id...actually if there is an id, we dont need anything else
|
|
52
|
+
|
|
53
|
+
i changed RemoteControl.location.setLocation() to ignore id is it is set to 0
|
|
54
|
+
"""
|
|
55
|
+
return [0,self.latitude(),self.longitude(),self.placename(),self.placename(),self.planet()]
|
|
56
|
+
|
|
57
|
+
def place(self):
|
|
58
|
+
return f"{self.placename()} ({round(self.lat, 3)},{round(self.long, 3)})"
|
|
59
|
+
|
|
60
|
+
def planet(self):
|
|
61
|
+
return self._planet
|
|
62
|
+
|
|
63
|
+
def placename(self):
|
|
64
|
+
return self._placename
|
|
65
|
+
|
|
66
|
+
def latitude(self):
|
|
67
|
+
return self.lat
|
|
68
|
+
|
|
69
|
+
def longitude(self):
|
|
70
|
+
return self.long
|
|
71
|
+
|
|
72
|
+
def atmospheric_pressure(self):
|
|
73
|
+
return self._atmospheric_pressure
|
|
74
|
+
|
|
75
|
+
def atmospheric_temperature(self):
|
|
76
|
+
return self._atmospheric_temperature
|
|
77
|
+
|
|
78
|
+
def relative_humidity(self):
|
|
79
|
+
return self._relative_humidity
|
|
80
|
+
|
|
81
|
+
def __repr__(self):
|
|
82
|
+
return f"({self.lat},{self.long})"
|
|
83
|
+
|
|
84
|
+
def swe_location(self):
|
|
85
|
+
"""
|
|
86
|
+
if you need a location for a swe library function, use this
|
|
87
|
+
this returns a tuple, which is what "geopos" usually is in the python functions
|
|
88
|
+
"""
|
|
89
|
+
# swe argument order is long, lat, alt
|
|
90
|
+
return (self.long, self.lat, self.alt)
|
|
91
|
+
|
|
92
|
+
def nearest_equatorial_crossing(self):
|
|
93
|
+
"""
|
|
94
|
+
return a position lat,long where lat=0 and long is self.long
|
|
95
|
+
"""
|
|
96
|
+
return Location(lat=0,long=self.long,alt=self.alt,placename=self._placename,utcoffset=self.utcoffset,icao=self.icao,planet=self._planet)
|
|
97
|
+
|
|
98
|
+
def get_metar(self, icao=None):
|
|
99
|
+
"""
|
|
100
|
+
get metar for icao
|
|
101
|
+
this will be used for swe.heliacal_ut() and any other place-based things like that
|
|
102
|
+
for atmospheric pressure, tempature, and the dewpoint can hopefully be used to calculate relative humidity
|
|
103
|
+
|
|
104
|
+
need to figure out if i can get past data; this is only current data
|
|
105
|
+
|
|
106
|
+
url is taken from get_report.py from python-metar package
|
|
107
|
+
"""
|
|
108
|
+
BASE_URL = "https://tgftp.nws.noaa.gov/data/observations/metar/stations"
|
|
109
|
+
if icao is not None:
|
|
110
|
+
name = icao
|
|
111
|
+
else:
|
|
112
|
+
name = self.icao
|
|
113
|
+
url = f"{BASE_URL}/{name}.TXT"
|
|
114
|
+
from urllib.request import urlopen
|
|
115
|
+
urlh = urlopen(url)
|
|
116
|
+
report = ""
|
|
117
|
+
for line in urlh:
|
|
118
|
+
if not isinstance(line, str):
|
|
119
|
+
line = line.decode() # convert Python3 bytes buffer to string
|
|
120
|
+
if line.startswith(name):
|
|
121
|
+
report = line.strip()
|
|
122
|
+
obs = Metar.Metar(line)
|
|
123
|
+
return obs
|
|
124
|
+
break
|
|
125
|
+
if not report:
|
|
126
|
+
print("No data for ", name, "\n\n")
|
|
127
|
+
|
|
128
|
+
def init_environment(self, icao=None):
|
|
129
|
+
"""
|
|
130
|
+
ideally initialize environment from the weather report, from the metar data from
|
|
131
|
+
self.icao by way of get_metar()
|
|
132
|
+
|
|
133
|
+
relative humidity not current implemented; TODO
|
|
134
|
+
|
|
135
|
+
pressure and temperature can be gotten from metar
|
|
136
|
+
right now i can get the most recent one...not sure about historical?
|
|
137
|
+
"""
|
|
138
|
+
# do this somehow
|
|
139
|
+
# metar was suddenly giving an error
|
|
140
|
+
# if icao is not None:
|
|
141
|
+
# metar = self.get_metar(icao)
|
|
142
|
+
# # since this is for swe, we use millibars and celsius
|
|
143
|
+
# # metar...value() can do other units too
|
|
144
|
+
# # 0 is for relative humidity
|
|
145
|
+
# # need to figure out how to calculate it from dewpoint, then it can go in here
|
|
146
|
+
# return (metar.press.value("mb"),metar.temp.value("c"),0)
|
|
147
|
+
return (0,0,0)
|
|
148
|
+
|
|
149
|
+
def swe_location_azalt(self, coords=swe.ECL2HOR):
|
|
150
|
+
"""
|
|
151
|
+
return a tuple suitable for swe.azalt()
|
|
152
|
+
to compute azimuth and altitde at this Location and JulianDay
|
|
153
|
+
|
|
154
|
+
default coords is eclipitc to azimuthal
|
|
155
|
+
other option is swe.EQU2HOR
|
|
156
|
+
"""
|
|
157
|
+
geopos = self.swe_location()
|
|
158
|
+
atpress = self.atmospheric_pressure()
|
|
159
|
+
attemp = self.atmospheric_temperature()
|
|
160
|
+
return (geopos), atpress, attemp
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
# Yamakoti is an ancient prime meridian
|
|
164
|
+
# this spot is used to calculate the vara, a savana day that is the same at once in the whole world
|
|
165
|
+
# PKMJ is Marshall Islands International Airport
|
|
166
|
+
# an airport close to Yamakoti, for purposes of weather information
|
|
167
|
+
Yamakoti = Location(0, 165.76666666666668, 0, "Yamakoti", "12", "PKMJ")
|