kerykeion 4.0.6__py3-none-any.whl → 4.8.1__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.
Potentially problematic release.
This version of kerykeion might be problematic. Click here for more details.
- kerykeion/__init__.py +4 -3
- kerykeion/aspects/__init__.py +2 -2
- kerykeion/aspects/aspects_utils.py +186 -0
- kerykeion/aspects/natal_aspects.py +51 -221
- kerykeion/aspects/synastry_aspects.py +43 -20
- kerykeion/astrological_subject.py +185 -124
- kerykeion/charts/__init__.py +1 -1
- kerykeion/charts/charts_utils.py +339 -5
- kerykeion/charts/kerykeion_chart_svg.py +365 -485
- kerykeion/charts/templates/chart.xml +41 -14
- kerykeion/enums.py +50 -0
- kerykeion/fetch_geonames.py +16 -25
- kerykeion/kr_types/__init__.py +7 -0
- kerykeion/kr_types/chart_types.py +32 -32
- kerykeion/kr_types/kerykeion_exception.py +1 -1
- kerykeion/kr_types/kr_literals.py +11 -1
- kerykeion/kr_types/kr_models.py +14 -8
- kerykeion/kr_types/settings_models.py +180 -0
- kerykeion/relationship_score.py +7 -13
- kerykeion/report.py +3 -0
- kerykeion/settings/__init__.py +1 -1
- kerykeion/settings/kerykeion_settings.py +13 -183
- kerykeion/settings/kr.config.json +9 -9
- kerykeion/utilities.py +153 -4
- {kerykeion-4.0.6.dist-info → kerykeion-4.8.1.dist-info}/METADATA +16 -2
- kerykeion-4.8.1.dist-info/RECORD +32 -0
- {kerykeion-4.0.6.dist-info → kerykeion-4.8.1.dist-info}/WHEEL +1 -1
- kerykeion-4.0.6.dist-info/RECORD +0 -29
- {kerykeion-4.0.6.dist-info → kerykeion-4.8.1.dist-info}/LICENSE +0 -0
- {kerykeion-4.0.6.dist-info → kerykeion-4.8.1.dist-info}/entry_points.txt +0 -0
|
@@ -1,30 +1,39 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
"""
|
|
3
|
-
This is part of Kerykeion (C)
|
|
3
|
+
This is part of Kerykeion (C) 2024 Giacomo Battaglia
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
import
|
|
7
|
+
import logging
|
|
8
8
|
|
|
9
|
-
from
|
|
10
|
-
from kerykeion.settings.kerykeion_settings import get_settings_dict
|
|
9
|
+
from kerykeion.settings.kerykeion_settings import get_settings
|
|
11
10
|
from kerykeion.aspects.synastry_aspects import SynastryAspects
|
|
12
11
|
from kerykeion.aspects.natal_aspects import NatalAspects
|
|
13
12
|
from kerykeion.astrological_subject import AstrologicalSubject
|
|
14
13
|
from kerykeion.kr_types import KerykeionException, ChartType
|
|
15
|
-
from kerykeion.kr_types
|
|
16
|
-
from kerykeion.
|
|
17
|
-
from
|
|
14
|
+
from kerykeion.kr_types import ChartTemplateDictionary
|
|
15
|
+
from kerykeion.kr_types.settings_models import KerykeionSettingsCelestialPointModel
|
|
16
|
+
from kerykeion.charts.charts_utils import (
|
|
17
|
+
degreeDiff,
|
|
18
|
+
sliceToX,
|
|
19
|
+
sliceToY,
|
|
20
|
+
draw_zodiac_slice,
|
|
21
|
+
convert_latitude_coordinate_to_string,
|
|
22
|
+
convert_longitude_coordinate_to_string,
|
|
23
|
+
draw_aspect_line,
|
|
24
|
+
draw_elements_percentages,
|
|
25
|
+
convert_decimal_to_degree_string,
|
|
26
|
+
draw_transit_ring_degree_steps,
|
|
27
|
+
draw_degree_ring,
|
|
28
|
+
draw_transit_ring,
|
|
29
|
+
draw_first_circle,
|
|
30
|
+
draw_second_circle
|
|
31
|
+
)
|
|
18
32
|
from pathlib import Path
|
|
33
|
+
from scour.scour import scourString
|
|
19
34
|
from string import Template
|
|
20
|
-
from typing import Union
|
|
21
|
-
|
|
35
|
+
from typing import Union, List
|
|
22
36
|
|
|
23
|
-
logger = getLogger(__name__)
|
|
24
|
-
basicConfig(
|
|
25
|
-
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
|
26
|
-
level="INFO"
|
|
27
|
-
)
|
|
28
37
|
|
|
29
38
|
|
|
30
39
|
class KerykeionChartSVG:
|
|
@@ -40,7 +49,13 @@ class KerykeionChartSVG:
|
|
|
40
49
|
- lang: language settings (default: "EN")
|
|
41
50
|
- new_settings_file: Set the settings file (default: kr.config.json)
|
|
42
51
|
"""
|
|
52
|
+
|
|
53
|
+
# Constants
|
|
54
|
+
_DEFAULT_HEIGHT = 546.0
|
|
55
|
+
_DEFAULT_FULL_WIDTH = 1200
|
|
56
|
+
_DEFAULT_NATAL_WIDTH = 772.2
|
|
43
57
|
|
|
58
|
+
# Set at init
|
|
44
59
|
first_obj: AstrologicalSubject
|
|
45
60
|
second_obj: Union[AstrologicalSubject, None]
|
|
46
61
|
chart_type: ChartType
|
|
@@ -48,6 +63,44 @@ class KerykeionChartSVG:
|
|
|
48
63
|
new_settings_file: Union[Path, None]
|
|
49
64
|
output_directory: Path
|
|
50
65
|
|
|
66
|
+
# Internal properties
|
|
67
|
+
fire: float
|
|
68
|
+
earth: float
|
|
69
|
+
air: float
|
|
70
|
+
water: float
|
|
71
|
+
c1: float
|
|
72
|
+
c2: float
|
|
73
|
+
c3: float
|
|
74
|
+
homedir: Path
|
|
75
|
+
xml_svg: Path
|
|
76
|
+
width: Union[float, int]
|
|
77
|
+
language_settings: dict
|
|
78
|
+
chart_colors_settings: dict
|
|
79
|
+
planets_settings: dict
|
|
80
|
+
aspects_settings: dict
|
|
81
|
+
planet_in_zodiac_extra_points: int
|
|
82
|
+
chart_settings: dict
|
|
83
|
+
user: AstrologicalSubject
|
|
84
|
+
available_planets_setting: List[KerykeionSettingsCelestialPointModel]
|
|
85
|
+
transit_ring_exclude_points_names: List[str]
|
|
86
|
+
points_deg_ut: list
|
|
87
|
+
points_deg: list
|
|
88
|
+
points_sign: list
|
|
89
|
+
points_retrograde: list
|
|
90
|
+
houses_sign_graph: list
|
|
91
|
+
t_points_deg_ut: list
|
|
92
|
+
t_points_deg: list
|
|
93
|
+
t_points_sign: list
|
|
94
|
+
t_points_retrograde: list
|
|
95
|
+
t_houses_sign_graph: list
|
|
96
|
+
height: float
|
|
97
|
+
location: str
|
|
98
|
+
geolat: float
|
|
99
|
+
geolon: float
|
|
100
|
+
zoom: int
|
|
101
|
+
zodiac: tuple
|
|
102
|
+
template: str
|
|
103
|
+
|
|
51
104
|
def __init__(
|
|
52
105
|
self,
|
|
53
106
|
first_obj: AstrologicalSubject,
|
|
@@ -68,56 +121,59 @@ class KerykeionChartSVG:
|
|
|
68
121
|
|
|
69
122
|
self.xml_svg = DATA_DIR / "templates/chart.xml"
|
|
70
123
|
|
|
71
|
-
# SVG Width
|
|
72
|
-
self.natal_width = 772.2
|
|
73
|
-
self.full_width = 1200
|
|
74
|
-
|
|
75
124
|
self.parse_json_settings(new_settings_file)
|
|
76
125
|
self.chart_type = chart_type
|
|
77
126
|
|
|
78
127
|
# Kerykeion instance
|
|
79
128
|
self.user = first_obj
|
|
80
129
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
self.
|
|
130
|
+
self.available_planets_setting = []
|
|
131
|
+
for body in self.planets_settings:
|
|
132
|
+
if body['is_active'] == False:
|
|
133
|
+
continue
|
|
134
|
+
|
|
135
|
+
self.available_planets_setting.append(body)
|
|
136
|
+
|
|
137
|
+
# House cusp points are excluded from the transit ring.
|
|
138
|
+
self.transit_ring_exclude_points_names = [
|
|
139
|
+
"First_House",
|
|
140
|
+
"Second_House",
|
|
141
|
+
"Third_House",
|
|
142
|
+
"Fourth_House",
|
|
143
|
+
"Fifth_House",
|
|
144
|
+
"Sixth_House",
|
|
145
|
+
"Seventh_House",
|
|
146
|
+
"Eighth_House",
|
|
147
|
+
"Ninth_House",
|
|
148
|
+
"Tenth_House",
|
|
149
|
+
"Eleventh_House",
|
|
150
|
+
"Twelfth_House"
|
|
87
151
|
]
|
|
88
152
|
|
|
153
|
+
# Available bodies
|
|
154
|
+
available_celestial_points = []
|
|
155
|
+
for body in self.available_planets_setting:
|
|
156
|
+
available_celestial_points.append(body["name"].lower())
|
|
157
|
+
|
|
158
|
+
# Make a list for the absolute degrees of the points of the graphic.
|
|
159
|
+
self.points_deg_ut = []
|
|
160
|
+
for planet in available_celestial_points:
|
|
161
|
+
self.points_deg_ut.append(self.user.get(planet).abs_pos)
|
|
162
|
+
|
|
89
163
|
# Make a list of the relative degrees of the points in the graphic.
|
|
90
164
|
self.points_deg = []
|
|
91
|
-
for planet in
|
|
92
|
-
self.points_deg.append(planet
|
|
93
|
-
|
|
94
|
-
self.points_deg = self.points_deg + [
|
|
95
|
-
self.user.houses_list[0]["position"],
|
|
96
|
-
self.user.houses_list[9]["position"],
|
|
97
|
-
self.user.houses_list[6]["position"],
|
|
98
|
-
self.user.houses_list[3]["position"],
|
|
99
|
-
]
|
|
165
|
+
for planet in available_celestial_points:
|
|
166
|
+
self.points_deg.append(self.user.get(planet).position)
|
|
100
167
|
|
|
101
168
|
# Make list of the points sign
|
|
102
169
|
self.points_sign = []
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
self.points_sign.append(planet["sign_num"])
|
|
106
|
-
|
|
107
|
-
self.points_sign = self.points_sign + [
|
|
108
|
-
self.user.houses_list[0]["sign_num"],
|
|
109
|
-
self.user.houses_list[9]["sign_num"],
|
|
110
|
-
self.user.houses_list[6]["sign_num"],
|
|
111
|
-
self.user.houses_list[3]["sign_num"],
|
|
112
|
-
]
|
|
170
|
+
for planet in available_celestial_points:
|
|
171
|
+
self.points_sign.append(self.user.get(planet).sign_num)
|
|
113
172
|
|
|
114
173
|
# Make a list of points if they are retrograde or not.
|
|
115
174
|
self.points_retrograde = []
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
self.points_retrograde.append(planet["retrograde"])
|
|
119
|
-
|
|
120
|
-
self.points_retrograde = self.points_retrograde + [False, False, False, False]
|
|
175
|
+
for planet in available_celestial_points:
|
|
176
|
+
self.points_retrograde.append(self.user.get(planet).retrograde)
|
|
121
177
|
|
|
122
178
|
# Makes the sign number list.
|
|
123
179
|
|
|
@@ -127,7 +183,7 @@ class KerykeionChartSVG:
|
|
|
127
183
|
|
|
128
184
|
if self.chart_type == "Natal" or self.chart_type == "ExternalNatal":
|
|
129
185
|
natal_aspects_instance = NatalAspects(self.user, new_settings_file=self.new_settings_file)
|
|
130
|
-
self.aspects_list = natal_aspects_instance.
|
|
186
|
+
self.aspects_list = natal_aspects_instance.relevant_aspects
|
|
131
187
|
|
|
132
188
|
# TODO: If not second should exit
|
|
133
189
|
if self.chart_type == "Transit" or self.chart_type == "Synastry":
|
|
@@ -138,112 +194,46 @@ class KerykeionChartSVG:
|
|
|
138
194
|
self.t_user = second_obj
|
|
139
195
|
|
|
140
196
|
# Make a list for the absolute degrees of the points of the graphic.
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
self.t_user.
|
|
144
|
-
self.t_user.houses_degree_ut[9],
|
|
145
|
-
self.t_user.houses_degree_ut[6],
|
|
146
|
-
self.t_user.houses_degree_ut[3],
|
|
147
|
-
]
|
|
197
|
+
self.t_points_deg_ut = []
|
|
198
|
+
for planet in available_celestial_points:
|
|
199
|
+
self.t_points_deg_ut.append(self.t_user.get(planet).abs_pos)
|
|
148
200
|
|
|
149
201
|
# Make a list of the relative degrees of the points in the graphic.
|
|
150
|
-
|
|
151
202
|
self.t_points_deg = []
|
|
152
|
-
for planet in
|
|
153
|
-
self.t_points_deg.append(planet
|
|
154
|
-
|
|
155
|
-
self.t_points_deg = self.t_points_deg + [
|
|
156
|
-
self.t_user.houses_list[0]["position"],
|
|
157
|
-
self.t_user.houses_list[9]["position"],
|
|
158
|
-
self.t_user.houses_list[6]["position"],
|
|
159
|
-
self.t_user.houses_list[3]["position"],
|
|
160
|
-
]
|
|
203
|
+
for planet in available_celestial_points:
|
|
204
|
+
self.t_points_deg.append(self.t_user.get(planet).position)
|
|
161
205
|
|
|
162
206
|
# Make list of the poits sign.
|
|
163
|
-
|
|
164
207
|
self.t_points_sign = []
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
self.t_points_sign.append(planet["sign_num"])
|
|
168
|
-
|
|
169
|
-
self.t_points_sign = self.t_points_sign + [
|
|
170
|
-
self.t_user.houses_list[0]["sign_num"],
|
|
171
|
-
self.t_user.houses_list[9]["sign_num"],
|
|
172
|
-
self.t_user.houses_list[6]["sign_num"],
|
|
173
|
-
self.t_user.houses_list[3]["sign_num"],
|
|
174
|
-
]
|
|
208
|
+
for planet in available_celestial_points:
|
|
209
|
+
self.t_points_sign.append(self.t_user.get(planet).sign_num)
|
|
175
210
|
|
|
176
211
|
# Make a list of poits if they are retrograde or not.
|
|
177
|
-
|
|
178
212
|
self.t_points_retrograde = []
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
self.t_points_retrograde.append(planet["retrograde"])
|
|
182
|
-
|
|
183
|
-
self.t_points_retrograde = self.t_points_retrograde + [False, False, False, False]
|
|
213
|
+
for planet in available_celestial_points:
|
|
214
|
+
self.t_points_retrograde.append(self.t_user.get(planet).retrograde)
|
|
184
215
|
|
|
185
216
|
self.t_houses_sign_graph = []
|
|
186
217
|
for h in self.t_user.houses_list:
|
|
187
218
|
self.t_houses_sign_graph.append(h["sign_num"])
|
|
188
219
|
|
|
189
220
|
# screen size
|
|
190
|
-
|
|
191
|
-
|
|
221
|
+
|
|
222
|
+
self.height = self._DEFAULT_HEIGHT
|
|
223
|
+
if self.chart_type == "Synastry" or self.chart_type == "Transit":
|
|
224
|
+
self.width = self._DEFAULT_FULL_WIDTH
|
|
192
225
|
else:
|
|
193
|
-
self.
|
|
194
|
-
self.screen_height = 772.2
|
|
195
|
-
|
|
196
|
-
# check for home
|
|
197
|
-
self.home_location = self.user.city
|
|
198
|
-
self.home_geolat = self.user.lat
|
|
199
|
-
self.home_geolon = self.user.lng
|
|
200
|
-
self.home_countrycode = self.user.nation
|
|
201
|
-
self.home_timezonestr = self.user.tz_str
|
|
202
|
-
|
|
203
|
-
print(f"{self.user.name} birth location: {self.home_location}, {self.home_geolat}, {self.home_geolon}")
|
|
226
|
+
self.width = self._DEFAULT_NATAL_WIDTH
|
|
204
227
|
|
|
205
228
|
# default location
|
|
206
|
-
self.location = self.
|
|
207
|
-
self.geolat =
|
|
208
|
-
self.geolon =
|
|
209
|
-
|
|
210
|
-
self.
|
|
211
|
-
|
|
212
|
-
# current datetime
|
|
213
|
-
now = datetime.now()
|
|
214
|
-
|
|
215
|
-
# aware datetime object
|
|
216
|
-
dt_input = datetime(now.year, now.month, now.day, now.hour, now.minute, now.second)
|
|
217
|
-
dt = pytz.timezone(self.timezonestr).localize(dt_input)
|
|
218
|
-
|
|
219
|
-
# naive utc datetime object
|
|
220
|
-
dt_utc = dt.replace(tzinfo=None) - dt.utcoffset() # type: ignore
|
|
221
|
-
|
|
222
|
-
# Default
|
|
223
|
-
self.name = self.user.name
|
|
224
|
-
self.charttype = self.chart_type
|
|
225
|
-
self.year = self.user.utc.year
|
|
226
|
-
self.month = self.user.utc.month
|
|
227
|
-
self.day = self.user.utc.day
|
|
228
|
-
self.hour = self.user.utc.hour + self.user.utc.minute / 100
|
|
229
|
-
self.timezone = offsetToTz(dt.utcoffset())
|
|
230
|
-
self.altitude = 25
|
|
231
|
-
self.geonameid = None
|
|
232
|
-
|
|
233
|
-
# Transit
|
|
229
|
+
self.location = self.user.city
|
|
230
|
+
self.geolat = self.user.lat
|
|
231
|
+
self.geolon = self.user.lng
|
|
232
|
+
|
|
233
|
+
logging.info(f"{self.user.name} birth location: {self.location}, {self.geolat}, {self.geolon}")
|
|
234
234
|
|
|
235
235
|
if self.chart_type == "Transit":
|
|
236
|
-
self.t_geolon = self.geolon
|
|
237
|
-
self.t_geolat = self.geolat
|
|
238
|
-
self.t_altitude = self.altitude
|
|
239
236
|
self.t_name = self.language_settings["transit_name"]
|
|
240
|
-
self.t_year = dt_utc.year
|
|
241
|
-
self.t_month = dt_utc.month
|
|
242
|
-
self.t_day = dt_utc.day
|
|
243
|
-
self.t_hour = decHourJoin(dt_utc.hour, dt_utc.minute, dt_utc.second)
|
|
244
|
-
self.t_timezone = offsetToTz(dt.utcoffset())
|
|
245
|
-
self.t_altitude = 25
|
|
246
|
-
self.t_geonameid = None
|
|
247
237
|
|
|
248
238
|
# configuration
|
|
249
239
|
# ZOOM 1 = 100%
|
|
@@ -264,22 +254,20 @@ class KerykeionChartSVG:
|
|
|
264
254
|
{"name": "pisces", "element": "water"},
|
|
265
255
|
)
|
|
266
256
|
|
|
267
|
-
|
|
268
|
-
self.template = self.makeTemplate()
|
|
257
|
+
self.template = None
|
|
269
258
|
|
|
270
259
|
def set_output_directory(self, dir_path: Path) -> None:
|
|
271
260
|
"""
|
|
272
261
|
Sets the output direcotry and returns it's path.
|
|
273
262
|
"""
|
|
274
263
|
self.output_directory = dir_path
|
|
275
|
-
|
|
276
|
-
return print(dir_string)
|
|
264
|
+
logging.info(f"Output direcotry set to: {self.output_directory}")
|
|
277
265
|
|
|
278
266
|
def parse_json_settings(self, settings_file):
|
|
279
267
|
"""
|
|
280
268
|
Parse the settings file.
|
|
281
269
|
"""
|
|
282
|
-
settings =
|
|
270
|
+
settings = get_settings(settings_file)
|
|
283
271
|
|
|
284
272
|
language = settings["general_settings"]["language"]
|
|
285
273
|
self.language_settings = settings["language_settings"].get(language, "EN")
|
|
@@ -289,163 +277,30 @@ class KerykeionChartSVG:
|
|
|
289
277
|
self.planet_in_zodiac_extra_points = settings["general_settings"]["planet_in_zodiac_extra_points"]
|
|
290
278
|
self.chart_settings = settings["chart_settings"]
|
|
291
279
|
|
|
292
|
-
def
|
|
293
|
-
"""
|
|
294
|
-
Draws the transit ring.
|
|
295
|
-
"""
|
|
296
|
-
radius_offset = 18
|
|
297
|
-
|
|
298
|
-
out = f'<circle cx="{r}" cy="{r}" r="{r - radius_offset}" style="fill: none; stroke: {self.chart_colors_settings["paper_1"]}; stroke-width: 36px; stroke-opacity: .4;"/>'
|
|
299
|
-
out += f'<circle cx="{r}" cy="{r}" r="{r}" style="fill: none; stroke: {self.chart_colors_settings["zodiac_transit_ring_3"]}; stroke-width: 1px; stroke-opacity: .6;"/>'
|
|
300
|
-
|
|
301
|
-
return out
|
|
302
|
-
|
|
303
|
-
def _degreeRing(self, r) -> str:
|
|
280
|
+
def _draw_zodiac_circle_slices(self, r):
|
|
304
281
|
"""
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
out = ""
|
|
308
|
-
for i in range(72):
|
|
309
|
-
offset = float(i * 5) - self.user.houses_degree_ut[6]
|
|
310
|
-
if offset < 0:
|
|
311
|
-
offset = offset + 360.0
|
|
312
|
-
elif offset > 360:
|
|
313
|
-
offset = offset - 360.0
|
|
314
|
-
x1 = sliceToX(0, r - self.c1, offset) + self.c1
|
|
315
|
-
y1 = sliceToY(0, r - self.c1, offset) + self.c1
|
|
316
|
-
x2 = sliceToX(0, r + 2 - self.c1, offset) - 2 + self.c1
|
|
317
|
-
y2 = sliceToY(0, r + 2 - self.c1, offset) - 2 + self.c1
|
|
318
|
-
|
|
319
|
-
out += f'<line x1="{x1}" y1="{y1}" x2="{x2}" y2="{y2}" style="stroke: {self.chart_colors_settings["paper_0"]}; stroke-width: 1px; stroke-opacity:.9;"/>'
|
|
320
|
-
|
|
321
|
-
return out
|
|
322
|
-
|
|
323
|
-
def _degreeTransitRing(self, r):
|
|
324
|
-
out = ""
|
|
325
|
-
for i in range(72):
|
|
326
|
-
offset = float(i * 5) - self.user.houses_degree_ut[6]
|
|
327
|
-
if offset < 0:
|
|
328
|
-
offset = offset + 360.0
|
|
329
|
-
elif offset > 360:
|
|
330
|
-
offset = offset - 360.0
|
|
331
|
-
x1 = sliceToX(0, r, offset)
|
|
332
|
-
y1 = sliceToY(0, r, offset)
|
|
333
|
-
x2 = sliceToX(0, r + 2, offset) - 2
|
|
334
|
-
y2 = sliceToY(0, r + 2, offset) - 2
|
|
335
|
-
out += f'<line x1="{x1}" y1="{y1}" x2="{x2}" y2="{y2}" style="stroke: #F00; stroke-width: 1px; stroke-opacity:.9;"/>'
|
|
336
|
-
|
|
337
|
-
return out
|
|
338
|
-
|
|
339
|
-
def _lat2str(self, coord):
|
|
340
|
-
"""Converts a floating point latitude to string with
|
|
341
|
-
degree, minutes and seconds and the appropriate sign
|
|
342
|
-
(north or south). Eg. 52.1234567 -> 52°7'25" N
|
|
282
|
+
Generate the SVG string representing the zodiac circle
|
|
283
|
+
with the 12 slices for each zodiac sign.
|
|
343
284
|
|
|
344
285
|
Args:
|
|
345
|
-
|
|
346
|
-
Returns:
|
|
347
|
-
str: latitude in string format with degree, minutes,
|
|
348
|
-
seconds and sign (N/S)
|
|
349
|
-
"""
|
|
350
|
-
|
|
351
|
-
sign = self.language_settings["north"]
|
|
352
|
-
if coord < 0.0:
|
|
353
|
-
sign = self.language_settings["south"]
|
|
354
|
-
coord = abs(coord)
|
|
355
|
-
deg = int(coord)
|
|
356
|
-
min = int((float(coord) - deg) * 60)
|
|
357
|
-
sec = int(round(float(((float(coord) - deg) * 60) - min) * 60.0))
|
|
358
|
-
return f"{deg}°{min}'{sec}\" {sign}"
|
|
286
|
+
r (float): The radius of the zodiac slices.
|
|
359
287
|
|
|
360
|
-
def _lon2str(self, coord):
|
|
361
|
-
"""Converts a floating point longitude to string with
|
|
362
|
-
degree, minutes and seconds and the appropriate sign
|
|
363
|
-
(east or west). Eg. 52.1234567 -> 52°7'25" E
|
|
364
|
-
|
|
365
|
-
Args:
|
|
366
|
-
coord (float): longitude in floating point format
|
|
367
288
|
Returns:
|
|
368
|
-
str:
|
|
369
|
-
seconds and sign (E/W)
|
|
289
|
+
str: The SVG string representing the zodiac circle.
|
|
370
290
|
"""
|
|
371
291
|
|
|
372
|
-
sign = self.language_settings["east"]
|
|
373
|
-
if coord < 0.0:
|
|
374
|
-
sign = self.language_settings["west"]
|
|
375
|
-
coord = abs(coord)
|
|
376
|
-
deg = int(coord)
|
|
377
|
-
min = int((float(coord) - deg) * 60)
|
|
378
|
-
sec = int(round(float(((float(coord) - deg) * 60) - min) * 60.0))
|
|
379
|
-
return f"{deg}°{min}'{sec}\" {sign}"
|
|
380
|
-
|
|
381
|
-
def _dec2deg(self, dec, type="3"):
|
|
382
|
-
"""Coverts decimal float to degrees in format
|
|
383
|
-
a°b'c".
|
|
384
|
-
"""
|
|
385
|
-
|
|
386
|
-
dec = float(dec)
|
|
387
|
-
a = int(dec)
|
|
388
|
-
a_new = (dec - float(a)) * 60.0
|
|
389
|
-
b_rounded = int(round(a_new))
|
|
390
|
-
b = int(a_new)
|
|
391
|
-
c = int(round((a_new - float(b)) * 60.0))
|
|
392
|
-
if type == "3":
|
|
393
|
-
out = f"{a:02d}°{b:02d}'{c:02d}""
|
|
394
|
-
elif type == "2":
|
|
395
|
-
out = f"{a:02d}°{b_rounded:02d}'"
|
|
396
|
-
elif type == "1":
|
|
397
|
-
out = f"{a:02d}°"
|
|
398
|
-
else:
|
|
399
|
-
raise KerykeionException(f"Wrong type: {type}, it must be 1, 2 or 3.")
|
|
400
|
-
return str(out)
|
|
401
|
-
|
|
402
|
-
def _drawAspect(self, r, ar, degA, degB, color):
|
|
403
|
-
"""
|
|
404
|
-
Draws svg aspects: ring, aspect ring, degreeA degreeB
|
|
405
|
-
"""
|
|
406
|
-
offset = (int(self.user.houses_degree_ut[6]) / -1) + int(degA)
|
|
407
|
-
x1 = sliceToX(0, ar, offset) + (r - ar)
|
|
408
|
-
y1 = sliceToY(0, ar, offset) + (r - ar)
|
|
409
|
-
offset = (int(self.user.houses_degree_ut[6]) / -1) + int(degB)
|
|
410
|
-
x2 = sliceToX(0, ar, offset) + (r - ar)
|
|
411
|
-
y2 = sliceToY(0, ar, offset) + (r - ar)
|
|
412
|
-
out = f' <line x1="{x1}" y1="{y1}" x2="{x2}" y2="{y2}" style="stroke: {color}; stroke-width: 1; stroke-opacity: .9;"/>'
|
|
413
|
-
|
|
414
|
-
return out
|
|
415
|
-
|
|
416
|
-
def _zodiacSlice(self, num, r, style, type):
|
|
417
|
-
# pie slices
|
|
418
|
-
offset = 360 - self.user.houses_degree_ut[6]
|
|
419
|
-
# check transit
|
|
420
|
-
if self.chart_type == "Transit" or self.chart_type == "Synastry":
|
|
421
|
-
dropin = 0
|
|
422
|
-
else:
|
|
423
|
-
dropin = self.c1
|
|
424
|
-
slice = f'<path d="M{str(r)},{str(r)} L{str(dropin + sliceToX(num, r - dropin, offset))},{str(dropin + sliceToY(num, r - dropin, offset))} A{str(r - dropin)},{str(r - dropin)} 0 0,0 {str(dropin + sliceToX(num + 1, r - dropin, offset))},{str(dropin + sliceToY(num + 1, r - dropin, offset))} z" style="{style}"/>'
|
|
425
|
-
|
|
426
|
-
# symbols
|
|
427
|
-
offset = offset + 15
|
|
428
|
-
# check transit
|
|
429
|
-
if self.chart_type == "Transit" or self.chart_type == "Synastry":
|
|
430
|
-
dropin = 54
|
|
431
|
-
else:
|
|
432
|
-
dropin = 18 + self.c1
|
|
433
|
-
sign = f'<g transform="translate(-16,-16)"><use x="{str(dropin + sliceToX(num, r - dropin, offset))}" y="{str(dropin + sliceToY(num, r - dropin, offset))}" xlink:href="#{type}" /></g>'
|
|
434
|
-
|
|
435
|
-
return slice + "" + sign
|
|
436
|
-
|
|
437
|
-
def _makeZodiac(self, r):
|
|
438
292
|
output = ""
|
|
439
|
-
for i in
|
|
440
|
-
output
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
293
|
+
for i, zodiac_element in enumerate(self.zodiac):
|
|
294
|
+
output += draw_zodiac_slice(
|
|
295
|
+
c1=self.c1,
|
|
296
|
+
chart_type=self.chart_type,
|
|
297
|
+
seventh_house_degree_ut=self.user.houses_degree_ut[6],
|
|
298
|
+
num=i,
|
|
299
|
+
r=r,
|
|
300
|
+
style=f'fill:{self.chart_colors_settings[f"zodiac_bg_{i}"]}; fill-opacity: 0.5;',
|
|
301
|
+
type=zodiac_element["name"],
|
|
448
302
|
)
|
|
303
|
+
|
|
449
304
|
return output
|
|
450
305
|
|
|
451
306
|
def _makeHouses(self, r):
|
|
@@ -535,44 +390,50 @@ class KerykeionChartSVG:
|
|
|
535
390
|
|
|
536
391
|
return path
|
|
537
392
|
|
|
538
|
-
def
|
|
393
|
+
def _calculate_elements_points_from_planets(self):
|
|
539
394
|
"""
|
|
540
395
|
Calculate chart element points from a planet.
|
|
541
396
|
"""
|
|
397
|
+
|
|
398
|
+
for i in range(len(self.available_planets_setting)):
|
|
399
|
+
# element: get extra points if planet is in own zodiac sign.
|
|
400
|
+
related_zodiac_signs = self.available_planets_setting[i]["related_zodiac_signs"]
|
|
401
|
+
cz = self.points_sign[i]
|
|
402
|
+
extra_points = 0
|
|
403
|
+
if related_zodiac_signs != []:
|
|
404
|
+
for e in range(len(related_zodiac_signs)):
|
|
405
|
+
if int(related_zodiac_signs[e]) == int(cz):
|
|
406
|
+
extra_points = self.planet_in_zodiac_extra_points
|
|
542
407
|
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
extra_points = 0
|
|
547
|
-
if related_zodiac_signs != []:
|
|
548
|
-
for e in range(len(related_zodiac_signs)):
|
|
549
|
-
if int(related_zodiac_signs[e]) == int(cz):
|
|
550
|
-
extra_points = self.planet_in_zodiac_extra_points
|
|
551
|
-
|
|
552
|
-
ele = self.zodiac[self.points_sign[i]]["element"]
|
|
553
|
-
if ele == "fire":
|
|
554
|
-
self.fire = self.fire + self.planets_settings[i]["element_points"] + extra_points
|
|
408
|
+
ele = self.zodiac[self.points_sign[i]]["element"]
|
|
409
|
+
if ele == "fire":
|
|
410
|
+
self.fire = self.fire + self.available_planets_setting[i]["element_points"] + extra_points
|
|
555
411
|
|
|
556
|
-
|
|
557
|
-
|
|
412
|
+
elif ele == "earth":
|
|
413
|
+
self.earth = self.earth + self.available_planets_setting[i]["element_points"] + extra_points
|
|
558
414
|
|
|
559
|
-
|
|
560
|
-
|
|
415
|
+
elif ele == "air":
|
|
416
|
+
self.air = self.air + self.available_planets_setting[i]["element_points"] + extra_points
|
|
561
417
|
|
|
562
|
-
|
|
563
|
-
|
|
418
|
+
elif ele == "water":
|
|
419
|
+
self.water = self.water + self.available_planets_setting[i]["element_points"] + extra_points
|
|
564
420
|
|
|
565
421
|
def _make_planets(self, r):
|
|
566
422
|
planets_degut = {}
|
|
567
|
-
diff = range(len(self.
|
|
423
|
+
diff = range(len(self.available_planets_setting))
|
|
568
424
|
|
|
569
|
-
for i in range(len(self.
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
planets_degut[self.points_deg_ut[i]] = i
|
|
425
|
+
for i in range(len(self.available_planets_setting)):
|
|
426
|
+
# list of planets sorted by degree
|
|
427
|
+
logging.debug(f"planet: {i}, degree: {self.points_deg_ut[i]}")
|
|
428
|
+
planets_degut[self.points_deg_ut[i]] = i
|
|
574
429
|
|
|
575
|
-
|
|
430
|
+
"""
|
|
431
|
+
FIXME: The planets_degut is a dictionary like:
|
|
432
|
+
{planet_degree: planet_index}
|
|
433
|
+
It should be replaced bu points_deg_ut
|
|
434
|
+
print(self.points_deg_ut)
|
|
435
|
+
print(planets_degut)
|
|
436
|
+
"""
|
|
576
437
|
|
|
577
438
|
output = ""
|
|
578
439
|
keys = list(planets_degut.keys())
|
|
@@ -601,24 +462,24 @@ class KerykeionChartSVG:
|
|
|
601
462
|
diffb = degreeDiff(next, self.points_deg_ut[i])
|
|
602
463
|
planets_by_pos[e] = [i, diffa, diffb]
|
|
603
464
|
|
|
604
|
-
|
|
465
|
+
logging.debug(f'{self.available_planets_setting[i]["label"]}, {diffa}, {diffb}')
|
|
605
466
|
|
|
606
467
|
if diffb < planet_drange:
|
|
607
468
|
if group_open:
|
|
608
|
-
groups[-1].append([e, diffa, diffb, self.
|
|
469
|
+
groups[-1].append([e, diffa, diffb, self.available_planets_setting[planets_degut[keys[e]]]["label"]])
|
|
609
470
|
else:
|
|
610
471
|
group_open = True
|
|
611
472
|
groups.append([])
|
|
612
|
-
groups[-1].append([e, diffa, diffb, self.
|
|
473
|
+
groups[-1].append([e, diffa, diffb, self.available_planets_setting[planets_degut[keys[e]]]["label"]])
|
|
613
474
|
else:
|
|
614
475
|
if group_open:
|
|
615
|
-
groups[-1].append([e, diffa, diffb, self.
|
|
476
|
+
groups[-1].append([e, diffa, diffb, self.available_planets_setting[planets_degut[keys[e]]]["label"]])
|
|
616
477
|
group_open = False
|
|
617
478
|
|
|
618
479
|
def zero(x):
|
|
619
480
|
return 0
|
|
620
481
|
|
|
621
|
-
planets_delta = list(map(zero, range(len(self.
|
|
482
|
+
planets_delta = list(map(zero, range(len(self.available_planets_setting))))
|
|
622
483
|
|
|
623
484
|
# print groups
|
|
624
485
|
# print planets_by_pos
|
|
@@ -730,7 +591,7 @@ class KerykeionChartSVG:
|
|
|
730
591
|
y1 = sliceToY(0, (r - self.c3), trueoffset) + self.c3
|
|
731
592
|
x2 = sliceToX(0, (r - rplanet - 30), trueoffset) + rplanet + 30
|
|
732
593
|
y2 = sliceToY(0, (r - rplanet - 30), trueoffset) + rplanet + 30
|
|
733
|
-
color = self.
|
|
594
|
+
color = self.available_planets_setting[i]["color"]
|
|
734
595
|
output += (
|
|
735
596
|
'<line x1="%s" y1="%s" x2="%s" y2="%s" style="stroke-width:1px;stroke:%s;stroke-opacity:.3;"/>\n'
|
|
736
597
|
% (x1, y1, x2, y2, color)
|
|
@@ -748,20 +609,21 @@ class KerykeionChartSVG:
|
|
|
748
609
|
else:
|
|
749
610
|
scale = 1
|
|
750
611
|
# output planet
|
|
751
|
-
output += f'<g transform="translate(-{12 * scale},-{12 * scale})"><g transform="scale({scale})"><use x="{planet_x * (1/scale)}" y="{planet_y * (1/scale)}" xlink:href="#{self.
|
|
612
|
+
output += f'<g transform="translate(-{12 * scale},-{12 * scale})"><g transform="scale({scale})"><use x="{planet_x * (1/scale)}" y="{planet_y * (1/scale)}" xlink:href="#{self.available_planets_setting[i]["name"]}" /></g></g>'
|
|
752
613
|
|
|
753
614
|
# make transit degut and display planets
|
|
754
615
|
if self.chart_type == "Transit" or self.chart_type == "Synastry":
|
|
755
616
|
group_offset = {}
|
|
756
617
|
t_planets_degut = {}
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
else:
|
|
760
|
-
list_range = len(self.planets_settings)
|
|
618
|
+
list_range = len(self.available_planets_setting)
|
|
619
|
+
|
|
761
620
|
for i in range(list_range):
|
|
621
|
+
if self.chart_type == "Transit" and self.available_planets_setting[i]['name'] in self.transit_ring_exclude_points_names:
|
|
622
|
+
continue
|
|
623
|
+
|
|
762
624
|
group_offset[i] = 0
|
|
763
|
-
|
|
764
|
-
|
|
625
|
+
t_planets_degut[self.t_points_deg_ut[i]] = i
|
|
626
|
+
|
|
765
627
|
t_keys = list(t_planets_degut.keys())
|
|
766
628
|
t_keys.sort()
|
|
767
629
|
|
|
@@ -803,7 +665,12 @@ class KerykeionChartSVG:
|
|
|
803
665
|
group_offset[groups[i][3]] = 2.0
|
|
804
666
|
|
|
805
667
|
switch = 0
|
|
668
|
+
|
|
669
|
+
# Transit planets loop
|
|
806
670
|
for e in range(len(t_keys)):
|
|
671
|
+
if self.chart_type == "Transit" and self.available_planets_setting[e]["name"] in self.transit_ring_exclude_points_names:
|
|
672
|
+
continue
|
|
673
|
+
|
|
807
674
|
i = t_planets_degut[t_keys[e]]
|
|
808
675
|
|
|
809
676
|
if 22 < i < 27:
|
|
@@ -815,20 +682,21 @@ class KerykeionChartSVG:
|
|
|
815
682
|
rplanet = 26
|
|
816
683
|
switch = 1
|
|
817
684
|
|
|
685
|
+
# Transit planet name
|
|
818
686
|
zeropoint = 360 - self.user.houses_degree_ut[6]
|
|
819
687
|
t_offset = zeropoint + self.t_points_deg_ut[i]
|
|
820
688
|
if t_offset > 360:
|
|
821
689
|
t_offset = t_offset - 360
|
|
822
690
|
planet_x = sliceToX(0, (r - rplanet), t_offset) + rplanet
|
|
823
691
|
planet_y = sliceToY(0, (r - rplanet), t_offset) + rplanet
|
|
824
|
-
output += f'<g transform="translate(-6,-6)"><g transform="scale(0.5)"><use x="{planet_x*2}" y="{planet_y*2}" xlink:href="#{self.
|
|
692
|
+
output += f'<g class="transit-planet-name" transform="translate(-6,-6)"><g transform="scale(0.5)"><use x="{planet_x*2}" y="{planet_y*2}" xlink:href="#{self.available_planets_setting[i]["name"]}" /></g></g>'
|
|
825
693
|
|
|
826
|
-
#
|
|
694
|
+
# Transit planet line
|
|
827
695
|
x1 = sliceToX(0, r + 3, t_offset) - 3
|
|
828
696
|
y1 = sliceToY(0, r + 3, t_offset) - 3
|
|
829
697
|
x2 = sliceToX(0, r - 3, t_offset) + 3
|
|
830
698
|
y2 = sliceToY(0, r - 3, t_offset) + 3
|
|
831
|
-
output += f'<line x1="{str(x1)}" y1="{str(y1)}" x2="{str(x2)}" y2="{str(y2)}" style="stroke: {self.
|
|
699
|
+
output += f'<line class="transit-planet-line" x1="{str(x1)}" y1="{str(y1)}" x2="{str(x2)}" y2="{str(y2)}" style="stroke: {self.available_planets_setting[i]["color"]}; stroke-width: 1px; stroke-opacity:.8;"/>'
|
|
832
700
|
|
|
833
701
|
# transit planet degree text
|
|
834
702
|
rotate = self.user.houses_degree_ut[0] - self.t_points_deg_ut[i]
|
|
@@ -852,7 +720,7 @@ class KerykeionChartSVG:
|
|
|
852
720
|
degree = int(t_offset)
|
|
853
721
|
output += f'<g transform="translate({deg_x},{deg_y})">'
|
|
854
722
|
output += f'<text transform="rotate({rotate})" text-anchor="{textanchor}'
|
|
855
|
-
output += f'" style="fill: {self.
|
|
723
|
+
output += f'" style="fill: {self.available_planets_setting[i]["color"]}; font-size: 10px;">{convert_decimal_to_degree_string(self.t_points_deg[i], type="1")}'
|
|
856
724
|
output += "</text></g>"
|
|
857
725
|
|
|
858
726
|
# check transit
|
|
@@ -867,7 +735,7 @@ class KerykeionChartSVG:
|
|
|
867
735
|
x2 = sliceToX(0, (r - (dropin - 3)), offset) + (dropin - 3)
|
|
868
736
|
y2 = sliceToY(0, (r - (dropin - 3)), offset) + (dropin - 3)
|
|
869
737
|
|
|
870
|
-
output += f'<line x1="{x1}" y1="{y1}" x2="{x2}" y2="{y2}" style="stroke: {self.
|
|
738
|
+
output += f'<line x1="{x1}" y1="{y1}" x2="{x2}" y2="{y2}" style="stroke: {self.available_planets_setting[i]["color"]}; stroke-width: 2px; stroke-opacity:.6;"/>'
|
|
871
739
|
|
|
872
740
|
# check transit
|
|
873
741
|
if self.chart_type == "Transit" or self.chart_type == "Synastry":
|
|
@@ -879,7 +747,7 @@ class KerykeionChartSVG:
|
|
|
879
747
|
y1 = sliceToY(0, r - dropin, offset) + dropin
|
|
880
748
|
x2 = sliceToX(0, (r - (dropin - 3)), offset) + (dropin - 3)
|
|
881
749
|
y2 = sliceToY(0, (r - (dropin - 3)), offset) + (dropin - 3)
|
|
882
|
-
output += f'<line x1="{x1}" y1="{y1}" x2="{x2}" y2="{y2}" style="stroke: {self.
|
|
750
|
+
output += f'<line x1="{x1}" y1="{y1}" x2="{x2}" y2="{y2}" style="stroke: {self.available_planets_setting[i]["color"]}; stroke-width: 2px; stroke-opacity:.6;"/>'
|
|
883
751
|
|
|
884
752
|
return output
|
|
885
753
|
|
|
@@ -897,7 +765,7 @@ class KerykeionChartSVG:
|
|
|
897
765
|
tr = {} # 6
|
|
898
766
|
qc = {} # 9
|
|
899
767
|
sext = {} # 3
|
|
900
|
-
for i in range(len(self.
|
|
768
|
+
for i in range(len(self.available_planets_setting)):
|
|
901
769
|
a = self.points_deg_ut[i]
|
|
902
770
|
qc[i] = {}
|
|
903
771
|
sext[i] = {}
|
|
@@ -906,14 +774,14 @@ class KerykeionChartSVG:
|
|
|
906
774
|
tr[i] = {}
|
|
907
775
|
conj[i] = {}
|
|
908
776
|
# skip some points
|
|
909
|
-
n = self.
|
|
777
|
+
n = self.available_planets_setting[i]["name"]
|
|
910
778
|
if n == "earth" or n == "True_Node" or n == "osc. apogee" or n == "intp. apogee" or n == "intp. perigee":
|
|
911
779
|
continue
|
|
912
780
|
if n == "Dsc" or n == "Ic":
|
|
913
781
|
continue
|
|
914
|
-
for j in range(len(self.
|
|
782
|
+
for j in range(len(self.available_planets_setting)):
|
|
915
783
|
# skip some points
|
|
916
|
-
n = self.
|
|
784
|
+
n = self.available_planets_setting[j]["name"]
|
|
917
785
|
if n == "earth" or n == "True_Node" or n == "osc. apogee" or n == "intp. apogee" or n == "intp. perigee":
|
|
918
786
|
continue
|
|
919
787
|
if n == "Dsc" or n == "Ic":
|
|
@@ -966,12 +834,12 @@ class KerykeionChartSVG:
|
|
|
966
834
|
for l, w in opp[k].items():
|
|
967
835
|
for a, b in sq.items():
|
|
968
836
|
if k in sq[a] and l in sq[a]:
|
|
969
|
-
|
|
837
|
+
logging.debug(f"Got tsquare {a} {k} {l}")
|
|
970
838
|
if k > l:
|
|
971
|
-
tsquare[f"{a},{l},{k}"] = f"{self.
|
|
839
|
+
tsquare[f"{a},{l},{k}"] = f"{self.available_planets_setting[a]['label']} => {self.available_planets_setting[l]['label']}, {self.available_planets_setting[k]['label']}"
|
|
972
840
|
|
|
973
841
|
else:
|
|
974
|
-
tsquare[f"{a},{k},{l}"] = f"{self.
|
|
842
|
+
tsquare[f"{a},{k},{l}"] = f"{self.available_planets_setting[a]['label']} => {self.available_planets_setting[k]['label']}, {self.available_planets_setting[l]['label']}"
|
|
975
843
|
|
|
976
844
|
stellium = {}
|
|
977
845
|
# check for 4 continuous conjunctions
|
|
@@ -1000,10 +868,10 @@ class KerykeionChartSVG:
|
|
|
1000
868
|
l = [k, n, p, r]
|
|
1001
869
|
l.sort()
|
|
1002
870
|
stellium["%s %s %s %s" % (l[0], l[1], l[2], l[3])] = "%s %s %s %s" % (
|
|
1003
|
-
self.
|
|
1004
|
-
self.
|
|
1005
|
-
self.
|
|
1006
|
-
self.
|
|
871
|
+
self.available_planets_setting[l[0]]["label"],
|
|
872
|
+
self.available_planets_setting[l[1]]["label"],
|
|
873
|
+
self.available_planets_setting[l[2]]["label"],
|
|
874
|
+
self.available_planets_setting[l[3]]["label"],
|
|
1007
875
|
)
|
|
1008
876
|
# print yots
|
|
1009
877
|
out = '<g transform="translate(-30,380)">'
|
|
@@ -1014,15 +882,15 @@ class KerykeionChartSVG:
|
|
|
1014
882
|
|
|
1015
883
|
# first planet symbol
|
|
1016
884
|
out += f'<g transform="translate(20,{y})">'
|
|
1017
|
-
out += f'<use transform="scale(0.4)" x="0" y="-20" xlink:href="#{self.
|
|
885
|
+
out += f'<use transform="scale(0.4)" x="0" y="-20" xlink:href="#{self.available_planets_setting[yot[k][0]]["name"]}" /></g>'
|
|
1018
886
|
|
|
1019
887
|
# second planet symbol
|
|
1020
888
|
out += f'<g transform="translate(30,{y})">'
|
|
1021
|
-
out += f'<use transform="scale(0.4)" x="0" y="-20" xlink:href="#{self.
|
|
889
|
+
out += f'<use transform="scale(0.4)" x="0" y="-20" xlink:href="#{self.available_planets_setting[yot[k][1]]["name"]}" /></g>'
|
|
1022
890
|
|
|
1023
891
|
# third planet symbol
|
|
1024
892
|
out += f'<g transform="translate(40,{y})">'
|
|
1025
|
-
out += f'<use transform="scale(0.4)" x="0" y="-20" xlink:href="#{self.
|
|
893
|
+
out += f'<use transform="scale(0.4)" x="0" y="-20" xlink:href="#{self.available_planets_setting[yot[k][2]]["name"]}" /></g>'
|
|
1026
894
|
|
|
1027
895
|
y = y + 14
|
|
1028
896
|
# finalize
|
|
@@ -1034,12 +902,13 @@ class KerykeionChartSVG:
|
|
|
1034
902
|
def _makeAspects(self, r, ar):
|
|
1035
903
|
out = ""
|
|
1036
904
|
for element in self.aspects_list:
|
|
1037
|
-
out +=
|
|
1038
|
-
r,
|
|
1039
|
-
ar,
|
|
1040
|
-
element["p1_abs_pos"],
|
|
1041
|
-
element["p2_abs_pos"],
|
|
1042
|
-
self.aspects_settings[element["aid"]]["color"],
|
|
905
|
+
out += draw_aspect_line(
|
|
906
|
+
r=r,
|
|
907
|
+
ar=ar,
|
|
908
|
+
degA=element["p1_abs_pos"],
|
|
909
|
+
degB=element["p2_abs_pos"],
|
|
910
|
+
color=self.aspects_settings[element["aid"]]["color"],
|
|
911
|
+
seventh_house_degree_ut=self.user.seventh_house.abs_pos
|
|
1043
912
|
)
|
|
1044
913
|
|
|
1045
914
|
return out
|
|
@@ -1050,29 +919,27 @@ class KerykeionChartSVG:
|
|
|
1050
919
|
xindent = 380
|
|
1051
920
|
yindent = 468
|
|
1052
921
|
box = 14
|
|
1053
|
-
revr = list(range(len(self.
|
|
922
|
+
revr = list(range(len(self.available_planets_setting)))
|
|
1054
923
|
revr.reverse()
|
|
1055
924
|
counter = 0
|
|
1056
925
|
for a in revr:
|
|
1057
926
|
counter += 1
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
if (element["p1"] == a and element["p2"] == b) or (element["p1"] == b and element["p2"] == a):
|
|
1075
|
-
out += f'<use x="{xorb-box+1}" y="{yorb+1}" xlink:href="#orb{element["aspect_degrees"]}" />'
|
|
927
|
+
out += f'<rect x="{xindent}" y="{yindent}" width="{box}" height="{box}" style="{style}"/>'
|
|
928
|
+
out += f'<use transform="scale(0.4)" x="{(xindent+2)*2.5}" y="{(yindent+1)*2.5}" xlink:href="#{self.available_planets_setting[a]["name"]}" />'
|
|
929
|
+
|
|
930
|
+
xindent = xindent + box
|
|
931
|
+
yindent = yindent - box
|
|
932
|
+
revr2 = list(range(a))
|
|
933
|
+
revr2.reverse()
|
|
934
|
+
xorb = xindent
|
|
935
|
+
yorb = yindent + box
|
|
936
|
+
for b in revr2:
|
|
937
|
+
out += f'<rect x="{xorb}" y="{yorb}" width="{box}" height="{box}" style="{style}"/>'
|
|
938
|
+
|
|
939
|
+
xorb = xorb + box
|
|
940
|
+
for element in self.aspects_list:
|
|
941
|
+
if (element["p1"] == a and element["p2"] == b) or (element["p1"] == b and element["p2"] == a):
|
|
942
|
+
out += f'<use x="{xorb-box+1}" y="{yorb+1}" xlink:href="#orb{element["aspect_degrees"]}" />'
|
|
1076
943
|
|
|
1077
944
|
return out
|
|
1078
945
|
|
|
@@ -1080,15 +947,16 @@ class KerykeionChartSVG:
|
|
|
1080
947
|
def _makeAspectsTransit(self, r, ar):
|
|
1081
948
|
out = ""
|
|
1082
949
|
|
|
1083
|
-
self.aspects_list = SynastryAspects(self.user, self.t_user, new_settings_file=self.new_settings_file).
|
|
950
|
+
self.aspects_list = SynastryAspects(self.user, self.t_user, new_settings_file=self.new_settings_file).relevant_aspects
|
|
1084
951
|
|
|
1085
952
|
for element in self.aspects_list:
|
|
1086
|
-
out +=
|
|
1087
|
-
r,
|
|
1088
|
-
ar,
|
|
1089
|
-
element["p1_abs_pos"],
|
|
1090
|
-
element["p2_abs_pos"],
|
|
1091
|
-
self.aspects_settings[element["aid"]]["color"],
|
|
953
|
+
out += draw_aspect_line(
|
|
954
|
+
r=r,
|
|
955
|
+
ar=ar,
|
|
956
|
+
degA=element["p1_abs_pos"],
|
|
957
|
+
degB=element["p2_abs_pos"],
|
|
958
|
+
color=self.aspects_settings[element["aid"]]["color"],
|
|
959
|
+
seventh_house_degree_ut=self.user.seventh_house.abs_pos
|
|
1092
960
|
)
|
|
1093
961
|
|
|
1094
962
|
return out
|
|
@@ -1126,55 +994,37 @@ class KerykeionChartSVG:
|
|
|
1126
994
|
line = 0
|
|
1127
995
|
|
|
1128
996
|
out += f'<g transform="translate({nl},{line})">'
|
|
997
|
+
|
|
1129
998
|
# first planet symbol
|
|
1130
|
-
|
|
1131
|
-
# TODO: (next((item for item in self.planets_settings if item["id"] == self.aspects_list[i]["p1"]))) It preventes the use ot numeric ID, but it is not working.
|
|
1132
999
|
out += f'<use transform="scale(0.4)" x="0" y="3" xlink:href="#{self.planets_settings[self.aspects_list[i]["p1"]]["name"]}" />'
|
|
1133
1000
|
|
|
1134
1001
|
# aspect symbol
|
|
1135
1002
|
out += f'<use x="15" y="0" xlink:href="#orb{self.aspects_settings[self.aspects_list[i]["aid"]]["degree"]}" />'
|
|
1003
|
+
|
|
1136
1004
|
# second planet symbol
|
|
1137
1005
|
out += '<g transform="translate(30,0)">'
|
|
1138
|
-
|
|
1139
|
-
# TODO: (next((item for item in self.planets_settings if item["id"] == self.aspects_list[i]["p3"])))
|
|
1140
1006
|
out += '<use transform="scale(0.4)" x="0" y="3" xlink:href="#%s" />' % (self.planets_settings[self.aspects_list[i]["p2"]]["name"])
|
|
1141
1007
|
|
|
1142
1008
|
out += "</g>"
|
|
1143
1009
|
# difference in degrees
|
|
1144
|
-
out += f'<text y="8" x="45" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;">{
|
|
1010
|
+
out += f'<text y="8" x="45" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;">{convert_decimal_to_degree_string(self.aspects_list[i]["orbit"])}</text>'
|
|
1145
1011
|
# line
|
|
1146
1012
|
out += "</g>"
|
|
1147
1013
|
line = line + 14
|
|
1148
1014
|
out += "</g>"
|
|
1149
1015
|
return out
|
|
1150
1016
|
|
|
1151
|
-
def _makeElements(self, r):
|
|
1152
|
-
total = self.fire + self.earth + self.air + self.water
|
|
1153
|
-
pf = int(round(100 * self.fire / total))
|
|
1154
|
-
pe = int(round(100 * self.earth / total))
|
|
1155
|
-
pa = int(round(100 * self.air / total))
|
|
1156
|
-
pw = int(round(100 * self.water / total))
|
|
1157
|
-
|
|
1158
|
-
out = '<g transform="translate(-30,79)">'
|
|
1159
|
-
out += f'<text y="0" style="fill:#ff6600; font-size: 10px;">{self.language_settings["fire"]} {str(pf)}%</text>'
|
|
1160
|
-
out += f'<text y="12" style="fill:#6a2d04; font-size: 10px;">{self.language_settings["earth"]} {str(pe)}%</text>'
|
|
1161
|
-
out += f'<text y="24" style="fill:#6f76d1; font-size: 10px;">{self.language_settings["air"]} {str(pa)}%</text>'
|
|
1162
|
-
out += f'<text y="36" style="fill:#630e73; font-size: 10px;">{self.language_settings["water"]} {str(pw)}%</text>'
|
|
1163
|
-
out += "</g>"
|
|
1164
|
-
|
|
1165
|
-
return out
|
|
1166
|
-
|
|
1167
1017
|
def _makePlanetGrid(self):
|
|
1168
1018
|
li = 10
|
|
1169
1019
|
offset = 0
|
|
1170
1020
|
|
|
1171
1021
|
out = '<g transform="translate(500,-20)">'
|
|
1172
1022
|
out += '<g transform="translate(140, -15)">'
|
|
1173
|
-
out += f'<text text-anchor="end" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 14px;">{self.language_settings["planets_and_house"]} {self.name}:</text>'
|
|
1023
|
+
out += f'<text text-anchor="end" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 14px;">{self.language_settings["planets_and_house"]} {self.user.name}:</text>'
|
|
1174
1024
|
out += "</g>"
|
|
1175
1025
|
|
|
1176
1026
|
end_of_line = None
|
|
1177
|
-
for i in range(len(self.
|
|
1027
|
+
for i in range(len(self.available_planets_setting)):
|
|
1178
1028
|
offset_between_lines = 14
|
|
1179
1029
|
end_of_line = "</g>"
|
|
1180
1030
|
|
|
@@ -1183,30 +1033,29 @@ class KerykeionChartSVG:
|
|
|
1183
1033
|
li = 10
|
|
1184
1034
|
offset = -120
|
|
1185
1035
|
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
out += f'<g transform="translate({offset},{li})">'
|
|
1036
|
+
# start of line
|
|
1037
|
+
out += f'<g transform="translate({offset},{li})">'
|
|
1189
1038
|
|
|
1190
|
-
|
|
1191
|
-
|
|
1039
|
+
# planet text
|
|
1040
|
+
out += f'<text text-anchor="end" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;">{self.language_settings["celestial_points"][self.available_planets_setting[i]["label"]]}</text>'
|
|
1192
1041
|
|
|
1193
|
-
|
|
1194
|
-
|
|
1042
|
+
# planet symbol
|
|
1043
|
+
out += f'<g transform="translate(5,-8)"><use transform="scale(0.4)" xlink:href="#{self.available_planets_setting[i]["name"]}" /></g>'
|
|
1195
1044
|
|
|
1196
|
-
|
|
1197
|
-
|
|
1045
|
+
# planet degree
|
|
1046
|
+
out += f'<text text-anchor="start" x="19" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;">{convert_decimal_to_degree_string(self.points_deg[i])}</text>'
|
|
1198
1047
|
|
|
1199
|
-
|
|
1200
|
-
|
|
1048
|
+
# zodiac
|
|
1049
|
+
out += f'<g transform="translate(60,-8)"><use transform="scale(0.3)" xlink:href="#{self.zodiac[self.points_sign[i]]["name"]}" /></g>'
|
|
1201
1050
|
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1051
|
+
# planet retrograde
|
|
1052
|
+
if self.points_retrograde[i]:
|
|
1053
|
+
out += '<g transform="translate(74,-6)"><use transform="scale(.5)" xlink:href="#retrograde" /></g>'
|
|
1205
1054
|
|
|
1206
|
-
|
|
1207
|
-
|
|
1055
|
+
# end of line
|
|
1056
|
+
out += end_of_line
|
|
1208
1057
|
|
|
1209
|
-
|
|
1058
|
+
li = li + offset_between_lines
|
|
1210
1059
|
|
|
1211
1060
|
if self.chart_type == "Transit" or self.chart_type == "Synastry":
|
|
1212
1061
|
if self.chart_type == "Transit":
|
|
@@ -1221,32 +1070,31 @@ class KerykeionChartSVG:
|
|
|
1221
1070
|
t_li = 10
|
|
1222
1071
|
t_offset = 250
|
|
1223
1072
|
|
|
1224
|
-
for i in range(len(self.
|
|
1073
|
+
for i in range(len(self.available_planets_setting)):
|
|
1225
1074
|
if i == 27:
|
|
1226
1075
|
t_li = 10
|
|
1227
1076
|
t_offset = -120
|
|
1228
1077
|
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
out += f'<g transform="translate({t_offset},{t_li})">'
|
|
1078
|
+
# start of line
|
|
1079
|
+
out += f'<g transform="translate({t_offset},{t_li})">'
|
|
1232
1080
|
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1081
|
+
# planet text
|
|
1082
|
+
out += f'<text text-anchor="end" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;">{self.language_settings["celestial_points"][self.available_planets_setting[i]["label"]]}</text>'
|
|
1083
|
+
# planet symbol
|
|
1084
|
+
out += f'<g transform="translate(5,-8)"><use transform="scale(0.4)" xlink:href="#{self.available_planets_setting[i]["name"]}" /></g>'
|
|
1085
|
+
# planet degree
|
|
1086
|
+
out += f'<text text-anchor="start" x="19" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;">{convert_decimal_to_degree_string(self.t_points_deg[i])}</text>'
|
|
1087
|
+
# zodiac
|
|
1088
|
+
out += f'<g transform="translate(60,-8)"><use transform="scale(0.3)" xlink:href="#{self.zodiac[self.t_points_sign[i]]["name"]}" /></g>'
|
|
1241
1089
|
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1090
|
+
# planet retrograde
|
|
1091
|
+
if self.t_points_retrograde[i]:
|
|
1092
|
+
out += '<g transform="translate(74,-6)"><use transform="scale(.5)" xlink:href="#retrograde" /></g>'
|
|
1245
1093
|
|
|
1246
|
-
|
|
1247
|
-
|
|
1094
|
+
# end of line
|
|
1095
|
+
out += end_of_line
|
|
1248
1096
|
|
|
1249
|
-
|
|
1097
|
+
t_li = t_li + offset_between_lines
|
|
1250
1098
|
|
|
1251
1099
|
if end_of_line is None:
|
|
1252
1100
|
raise KerykeionException("End of line not found")
|
|
@@ -1254,7 +1102,13 @@ class KerykeionChartSVG:
|
|
|
1254
1102
|
out += end_of_line
|
|
1255
1103
|
return out
|
|
1256
1104
|
|
|
1257
|
-
def
|
|
1105
|
+
def _draw_house_grid(self):
|
|
1106
|
+
"""
|
|
1107
|
+
Generate SVG code for a grid of astrological houses.
|
|
1108
|
+
|
|
1109
|
+
Returns:
|
|
1110
|
+
str: The SVG code for the grid of houses.
|
|
1111
|
+
"""
|
|
1258
1112
|
out = '<g transform="translate(600,-20)">'
|
|
1259
1113
|
|
|
1260
1114
|
li = 10
|
|
@@ -1266,7 +1120,7 @@ class KerykeionChartSVG:
|
|
|
1266
1120
|
out += f'<g transform="translate(0,{li})">'
|
|
1267
1121
|
out += f'<text text-anchor="end" x="40" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;">{self.language_settings["cusp"]} {cusp}:</text>'
|
|
1268
1122
|
out += f'<g transform="translate(40,-8)"><use transform="scale(0.3)" xlink:href="#{self.zodiac[self.houses_sign_graph[i]]["name"]}" /></g>'
|
|
1269
|
-
out += f'<text x="53" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;"> {
|
|
1123
|
+
out += f'<text x="53" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;"> {convert_decimal_to_degree_string(self.user.houses_list[i]["position"])}</text>'
|
|
1270
1124
|
out += "</g>"
|
|
1271
1125
|
li = li + 14
|
|
1272
1126
|
|
|
@@ -1283,14 +1137,14 @@ class KerykeionChartSVG:
|
|
|
1283
1137
|
out += '<g transform="translate(0,' + str(li) + ')">'
|
|
1284
1138
|
out += f'<text text-anchor="end" x="40" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;">{self.language_settings["cusp"]} {cusp}:</text>'
|
|
1285
1139
|
out += f'<g transform="translate(40,-8)"><use transform="scale(0.3)" xlink:href="#{self.zodiac[self.t_houses_sign_graph[i]]["name"]}" /></g>'
|
|
1286
|
-
out += f'<text x="53" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;"> {
|
|
1140
|
+
out += f'<text x="53" style="fill:{self.chart_colors_settings["paper_0"]}; font-size: 10px;"> {convert_decimal_to_degree_string(self.t_user.houses_list[i]["position"])}</text>'
|
|
1287
1141
|
out += "</g>"
|
|
1288
1142
|
li = li + 14
|
|
1289
1143
|
out += "</g>"
|
|
1290
1144
|
|
|
1291
1145
|
return out
|
|
1292
1146
|
|
|
1293
|
-
def _createTemplateDictionary(self):
|
|
1147
|
+
def _createTemplateDictionary(self) -> ChartTemplateDictionary:
|
|
1294
1148
|
# self.chart_type = "Transit"
|
|
1295
1149
|
# empty element points
|
|
1296
1150
|
self.fire = 0.0
|
|
@@ -1298,12 +1152,8 @@ class KerykeionChartSVG:
|
|
|
1298
1152
|
self.air = 0.0
|
|
1299
1153
|
self.water = 0.0
|
|
1300
1154
|
|
|
1301
|
-
#
|
|
1302
|
-
|
|
1303
|
-
if ratio < 1.3: # 1280x1024
|
|
1304
|
-
wm_off = 130
|
|
1305
|
-
else: # 1024x768, 800x600, 1280x800, 1680x1050
|
|
1306
|
-
wm_off = 100
|
|
1155
|
+
# Calculate the elements points
|
|
1156
|
+
self._calculate_elements_points_from_planets()
|
|
1307
1157
|
|
|
1308
1158
|
# Viewbox and sizing
|
|
1309
1159
|
svgHeight = "100%"
|
|
@@ -1318,7 +1168,7 @@ class KerykeionChartSVG:
|
|
|
1318
1168
|
viewbox = self.chart_settings["wide_chart_viewBox"]
|
|
1319
1169
|
|
|
1320
1170
|
# template dictionary
|
|
1321
|
-
td:
|
|
1171
|
+
td: ChartTemplateDictionary = dict() # type: ignore
|
|
1322
1172
|
r = 240
|
|
1323
1173
|
|
|
1324
1174
|
if self.chart_type == "ExternalNatal":
|
|
@@ -1332,14 +1182,12 @@ class KerykeionChartSVG:
|
|
|
1332
1182
|
|
|
1333
1183
|
# transit
|
|
1334
1184
|
if self.chart_type == "Transit" or self.chart_type == "Synastry":
|
|
1335
|
-
td["transitRing"] = self.
|
|
1336
|
-
td["degreeRing"] = self.
|
|
1185
|
+
td["transitRing"] = draw_transit_ring(r, self.chart_colors_settings["paper_1"], self.chart_colors_settings["zodiac_transit_ring_3"])
|
|
1186
|
+
td["degreeRing"] = draw_transit_ring_degree_steps(r, self.user.seventh_house.abs_pos)
|
|
1337
1187
|
|
|
1338
1188
|
# circles
|
|
1339
|
-
td["
|
|
1340
|
-
td["
|
|
1341
|
-
td["c2"] = 'cx="' + str(r) + '" cy="' + str(r) + '" r="' + str(r - 72) + '"'
|
|
1342
|
-
td["c2style"] = f"fill: {self.chart_colors_settings['paper_1']}; fill-opacity:.4; stroke: {self.chart_colors_settings['zodiac_transit_ring_1']}; stroke-opacity:.4; stroke-width: 1px"
|
|
1189
|
+
td["first_circle"] = draw_first_circle(r, self.chart_colors_settings["zodiac_transit_ring_2"], self.chart_type)
|
|
1190
|
+
td["second_circle"] = draw_second_circle(r, self.chart_colors_settings['zodiac_transit_ring_1'], self.chart_colors_settings['paper_1'], self.chart_type)
|
|
1343
1191
|
|
|
1344
1192
|
td["c3"] = 'cx="' + str(r) + '" cy="' + str(r) + '" r="' + str(r - 160) + '"'
|
|
1345
1193
|
td["c3style"] = f"fill: {self.chart_colors_settings['paper_1']}; fill-opacity:.8; stroke: {self.chart_colors_settings['zodiac_transit_ring_0']}; stroke-width: 1px"
|
|
@@ -1347,23 +1195,23 @@ class KerykeionChartSVG:
|
|
|
1347
1195
|
td["makeAspects"] = self._makeAspectsTransit(r, (r - 160))
|
|
1348
1196
|
td["makeAspectGrid"] = self._makeAspectTransitGrid(r)
|
|
1349
1197
|
td["makePatterns"] = ""
|
|
1350
|
-
td["chart_width"] = self.full_width
|
|
1351
1198
|
else:
|
|
1352
1199
|
td["transitRing"] = ""
|
|
1353
|
-
td["degreeRing"] = self.
|
|
1200
|
+
td["degreeRing"] = draw_degree_ring(r, self.c1, self.user.seventh_house.abs_pos, self.chart_colors_settings["paper_0"])
|
|
1354
1201
|
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
td["
|
|
1358
|
-
|
|
1359
|
-
td["c2style"] = f'fill: {self.chart_colors_settings["paper_1"]}; fill-opacity:.2; stroke: {self.chart_colors_settings["zodiac_radix_ring_1"]}; stroke-opacity:.4; stroke-width: 1px'
|
|
1202
|
+
td['first_circle'] = draw_first_circle(r, self.chart_colors_settings["zodiac_radix_ring_2"], self.chart_type, self.c1)
|
|
1203
|
+
|
|
1204
|
+
td["second_circle"] = draw_second_circle(r, self.chart_colors_settings["zodiac_radix_ring_1"], self.chart_colors_settings["paper_1"], self.chart_type, self.c2)
|
|
1205
|
+
|
|
1360
1206
|
td["c3"] = f'cx="{r}" cy="{r}" r="{r - self.c3}"'
|
|
1361
1207
|
td["c3style"] = f'fill: {self.chart_colors_settings["paper_1"]}; fill-opacity:.8; stroke: {self.chart_colors_settings["zodiac_radix_ring_0"]}; stroke-width: 1px'
|
|
1208
|
+
|
|
1362
1209
|
td["makeAspects"] = self._makeAspects(r, (r - self.c3))
|
|
1363
1210
|
td["makeAspectGrid"] = self._makeAspectGrid(r)
|
|
1364
1211
|
td["makePatterns"] = self._makePatterns()
|
|
1365
|
-
|
|
1366
|
-
|
|
1212
|
+
|
|
1213
|
+
td["chart_height"] = self.height
|
|
1214
|
+
td["chart_width"] = self.width
|
|
1367
1215
|
td["circleX"] = str(0)
|
|
1368
1216
|
td["circleY"] = str(0)
|
|
1369
1217
|
td["svgWidth"] = str(svgWidth)
|
|
@@ -1371,17 +1219,17 @@ class KerykeionChartSVG:
|
|
|
1371
1219
|
td["viewbox"] = viewbox
|
|
1372
1220
|
|
|
1373
1221
|
if self.chart_type == "Synastry":
|
|
1374
|
-
td["stringTitle"] = f"{self.name} {self.language_settings['and_word']} {self.t_user.name}"
|
|
1222
|
+
td["stringTitle"] = f"{self.user.name} {self.language_settings['and_word']} {self.t_user.name}"
|
|
1375
1223
|
|
|
1376
1224
|
elif self.chart_type == "Transit":
|
|
1377
1225
|
td["stringTitle"] = f"{self.language_settings['transits']} {self.t_user.day}/{self.t_user.month}/{self.t_user.year}"
|
|
1378
1226
|
|
|
1379
1227
|
else:
|
|
1380
|
-
td["stringTitle"] = self.name
|
|
1228
|
+
td["stringTitle"] = self.user.name
|
|
1381
1229
|
|
|
1382
1230
|
# Tipo di carta
|
|
1383
|
-
if self.chart_type == "Synastry" or self.
|
|
1384
|
-
td["stringName"] = f"{self.name}:"
|
|
1231
|
+
if self.chart_type == "Synastry" or self.chart_type == "Transit":
|
|
1232
|
+
td["stringName"] = f"{self.user.name}:"
|
|
1385
1233
|
else:
|
|
1386
1234
|
td["stringName"] = f'{self.language_settings["info"]}:'
|
|
1387
1235
|
|
|
@@ -1465,9 +1313,20 @@ class KerykeionChartSVG:
|
|
|
1465
1313
|
td["stringPosition"] = f"{self.t_user.year}-{self.t_user.month}-{self.t_user.day} {self.t_user.hour:02d}:{self.t_user.minute:02d}"
|
|
1466
1314
|
|
|
1467
1315
|
else:
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1316
|
+
latitude_string = convert_latitude_coordinate_to_string(
|
|
1317
|
+
self.geolat,
|
|
1318
|
+
self.language_settings['north'],
|
|
1319
|
+
self.language_settings['south']
|
|
1320
|
+
)
|
|
1321
|
+
longitude_string = convert_longitude_coordinate_to_string(
|
|
1322
|
+
self.geolon,
|
|
1323
|
+
self.language_settings['east'],
|
|
1324
|
+
self.language_settings['west']
|
|
1325
|
+
)
|
|
1326
|
+
|
|
1327
|
+
td["stringLat"] = f"{self.language_settings['latitude']}: {latitude_string}"
|
|
1328
|
+
td["stringLon"] = f"{self.language_settings['longitude']}: {longitude_string}"
|
|
1329
|
+
td["stringPosition"] = f"{self.language_settings['type']}: {self.chart_type}"
|
|
1471
1330
|
|
|
1472
1331
|
# paper_color_X
|
|
1473
1332
|
td["paper_color_0"] = self.chart_colors_settings["paper_0"]
|
|
@@ -1491,48 +1350,68 @@ class KerykeionChartSVG:
|
|
|
1491
1350
|
td["cfgRotate"] = rotate
|
|
1492
1351
|
td["cfgTranslate"] = translate
|
|
1493
1352
|
|
|
1494
|
-
#
|
|
1495
|
-
|
|
1353
|
+
# ---
|
|
1354
|
+
# Drawing Functions
|
|
1355
|
+
#---
|
|
1356
|
+
|
|
1357
|
+
td["makeZodiac"] = self._draw_zodiac_circle_slices(r)
|
|
1358
|
+
td["makeHousesGrid"] = self._draw_house_grid()
|
|
1359
|
+
# TODO: Add the rest of the functions
|
|
1496
1360
|
td["makeHouses"] = self._makeHouses(r)
|
|
1497
1361
|
td["makePlanets"] = self._make_planets(r)
|
|
1498
|
-
td["
|
|
1362
|
+
td["elements_percentages"] = draw_elements_percentages(
|
|
1363
|
+
self.language_settings['fire'],
|
|
1364
|
+
self.fire,
|
|
1365
|
+
self.language_settings['earth'],
|
|
1366
|
+
self.earth,
|
|
1367
|
+
self.language_settings['air'],
|
|
1368
|
+
self.air,
|
|
1369
|
+
self.language_settings['water'],
|
|
1370
|
+
self.water,
|
|
1371
|
+
)
|
|
1499
1372
|
td["makePlanetGrid"] = self._makePlanetGrid()
|
|
1500
|
-
td["makeHousesGrid"] = self._makeHousesGrid()
|
|
1501
1373
|
|
|
1502
1374
|
return td
|
|
1503
1375
|
|
|
1504
|
-
def makeTemplate(self):
|
|
1376
|
+
def makeTemplate(self, minify: bool = False) -> str:
|
|
1505
1377
|
"""Creates the template for the SVG file"""
|
|
1506
1378
|
td = self._createTemplateDictionary()
|
|
1507
1379
|
|
|
1508
1380
|
# read template
|
|
1509
|
-
with open(self.xml_svg, "r", encoding="utf-8", errors="ignore") as
|
|
1510
|
-
f = open(self.xml_svg)
|
|
1381
|
+
with open(self.xml_svg, "r", encoding="utf-8", errors="ignore") as f:
|
|
1511
1382
|
template = Template(f.read()).substitute(td)
|
|
1512
1383
|
|
|
1513
1384
|
# return filename
|
|
1514
1385
|
|
|
1515
|
-
|
|
1386
|
+
logging.debug(f"Template dictionary keys: {td.keys()}")
|
|
1516
1387
|
|
|
1517
1388
|
self._createTemplateDictionary()
|
|
1518
|
-
return template.replace('"', "'")
|
|
1519
1389
|
|
|
1520
|
-
|
|
1390
|
+
if minify:
|
|
1391
|
+
template = scourString(template).replace('"', "'").replace("\n", "").replace("\t","").replace(" ", "").replace(" ", "")
|
|
1392
|
+
|
|
1393
|
+
else:
|
|
1394
|
+
template = template.replace('"', "'")
|
|
1395
|
+
|
|
1396
|
+
return template
|
|
1397
|
+
|
|
1398
|
+
def makeSVG(self, minify: bool = False):
|
|
1521
1399
|
"""Prints out the SVG file in the specifide folder"""
|
|
1522
1400
|
|
|
1523
1401
|
if not (self.template):
|
|
1524
|
-
self.template = self.makeTemplate()
|
|
1402
|
+
self.template = self.makeTemplate(minify)
|
|
1525
1403
|
|
|
1526
|
-
self.chartname = self.output_directory / f"{self.name}{self.chart_type}Chart.svg"
|
|
1404
|
+
self.chartname = self.output_directory / f"{self.user.name}{self.chart_type}Chart.svg"
|
|
1527
1405
|
|
|
1528
1406
|
with open(self.chartname, "w", encoding="utf-8", errors="ignore") as output_file:
|
|
1529
1407
|
output_file.write(self.template)
|
|
1530
1408
|
|
|
1531
|
-
|
|
1409
|
+
logging.info(f"SVG Generated Correctly in: {self.chartname}")
|
|
1532
1410
|
|
|
1533
1411
|
|
|
1534
1412
|
if __name__ == "__main__":
|
|
1535
|
-
|
|
1413
|
+
from kerykeion.utilities import setup_logging
|
|
1414
|
+
setup_logging(level="debug")
|
|
1536
1415
|
|
|
1537
1416
|
first = AstrologicalSubject("John Lennon", 1940, 10, 9, 10, 30, "Liverpool", "GB")
|
|
1538
1417
|
second = AstrologicalSubject("Paul McCartney", 1942, 6, 18, 15, 30, "Liverpool", "GB")
|
|
@@ -1547,8 +1426,9 @@ if __name__ == "__main__":
|
|
|
1547
1426
|
|
|
1548
1427
|
# Synastry Chart
|
|
1549
1428
|
synastry_chart = KerykeionChartSVG(first, "Synastry", second)
|
|
1550
|
-
synastry_chart.makeSVG()
|
|
1429
|
+
synastry_chart.makeSVG(minify=True)
|
|
1551
1430
|
|
|
1552
1431
|
# Transits Chart
|
|
1553
1432
|
transits_chart = KerykeionChartSVG(first, "Transit", second)
|
|
1554
|
-
transits_chart.makeSVG()
|
|
1433
|
+
transits_chart.makeSVG(minify=True)
|
|
1434
|
+
|