kerykeion 4.0.3__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 +392 -516
- 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 +35 -177
- kerykeion/settings/kr.config.json +13 -9
- kerykeion/utilities.py +153 -4
- {kerykeion-4.0.3.dist-info → kerykeion-4.8.1.dist-info}/METADATA +16 -2
- kerykeion-4.8.1.dist-info/RECORD +32 -0
- {kerykeion-4.0.3.dist-info → kerykeion-4.8.1.dist-info}/WHEEL +1 -1
- kerykeion-4.0.3.dist-info/RECORD +0 -29
- {kerykeion-4.0.3.dist-info → kerykeion-4.8.1.dist-info}/LICENSE +0 -0
- {kerykeion-4.0.3.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")
|
|
@@ -287,164 +275,32 @@ class KerykeionChartSVG:
|
|
|
287
275
|
self.planets_settings = settings["celestial_points"]
|
|
288
276
|
self.aspects_settings = settings["aspects"]
|
|
289
277
|
self.planet_in_zodiac_extra_points = settings["general_settings"]["planet_in_zodiac_extra_points"]
|
|
278
|
+
self.chart_settings = settings["chart_settings"]
|
|
290
279
|
|
|
291
|
-
def
|
|
280
|
+
def _draw_zodiac_circle_slices(self, r):
|
|
292
281
|
"""
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
radius_offset = 18
|
|
296
|
-
|
|
297
|
-
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;"/>'
|
|
298
|
-
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;"/>'
|
|
299
|
-
|
|
300
|
-
return out
|
|
301
|
-
|
|
302
|
-
def _degreeRing(self, r) -> str:
|
|
303
|
-
"""
|
|
304
|
-
Draws the degree ring.
|
|
305
|
-
"""
|
|
306
|
-
out = ""
|
|
307
|
-
for i in range(72):
|
|
308
|
-
offset = float(i * 5) - self.user.houses_degree_ut[6]
|
|
309
|
-
if offset < 0:
|
|
310
|
-
offset = offset + 360.0
|
|
311
|
-
elif offset > 360:
|
|
312
|
-
offset = offset - 360.0
|
|
313
|
-
x1 = sliceToX(0, r - self.c1, offset) + self.c1
|
|
314
|
-
y1 = sliceToY(0, r - self.c1, offset) + self.c1
|
|
315
|
-
x2 = sliceToX(0, r + 2 - self.c1, offset) - 2 + self.c1
|
|
316
|
-
y2 = sliceToY(0, r + 2 - self.c1, offset) - 2 + self.c1
|
|
317
|
-
|
|
318
|
-
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;"/>'
|
|
319
|
-
|
|
320
|
-
return out
|
|
321
|
-
|
|
322
|
-
def _degreeTransitRing(self, r):
|
|
323
|
-
out = ""
|
|
324
|
-
for i in range(72):
|
|
325
|
-
offset = float(i * 5) - self.user.houses_degree_ut[6]
|
|
326
|
-
if offset < 0:
|
|
327
|
-
offset = offset + 360.0
|
|
328
|
-
elif offset > 360:
|
|
329
|
-
offset = offset - 360.0
|
|
330
|
-
x1 = sliceToX(0, r, offset)
|
|
331
|
-
y1 = sliceToY(0, r, offset)
|
|
332
|
-
x2 = sliceToX(0, r + 2, offset) - 2
|
|
333
|
-
y2 = sliceToY(0, r + 2, offset) - 2
|
|
334
|
-
out += f'<line x1="{x1}" y1="{y1}" x2="{x2}" y2="{y2}" style="stroke: #F00; stroke-width: 1px; stroke-opacity:.9;"/>'
|
|
335
|
-
|
|
336
|
-
return out
|
|
337
|
-
|
|
338
|
-
def _lat2str(self, coord):
|
|
339
|
-
"""Converts a floating point latitude to string with
|
|
340
|
-
degree, minutes and seconds and the appropriate sign
|
|
341
|
-
(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.
|
|
342
284
|
|
|
343
285
|
Args:
|
|
344
|
-
|
|
345
|
-
Returns:
|
|
346
|
-
str: latitude in string format with degree, minutes,
|
|
347
|
-
seconds and sign (N/S)
|
|
348
|
-
"""
|
|
286
|
+
r (float): The radius of the zodiac slices.
|
|
349
287
|
|
|
350
|
-
sign = self.language_settings["north"]
|
|
351
|
-
if coord < 0.0:
|
|
352
|
-
sign = self.language_settings["south"]
|
|
353
|
-
coord = abs(coord)
|
|
354
|
-
deg = int(coord)
|
|
355
|
-
min = int((float(coord) - deg) * 60)
|
|
356
|
-
sec = int(round(float(((float(coord) - deg) * 60) - min) * 60.0))
|
|
357
|
-
return f"{deg}°{min}'{sec}\" {sign}"
|
|
358
|
-
|
|
359
|
-
def _lon2str(self, coord):
|
|
360
|
-
"""Converts a floating point longitude to string with
|
|
361
|
-
degree, minutes and seconds and the appropriate sign
|
|
362
|
-
(east or west). Eg. 52.1234567 -> 52°7'25" E
|
|
363
|
-
|
|
364
|
-
Args:
|
|
365
|
-
coord (float): longitude in floating point format
|
|
366
288
|
Returns:
|
|
367
|
-
str:
|
|
368
|
-
seconds and sign (E/W)
|
|
369
|
-
"""
|
|
370
|
-
|
|
371
|
-
sign = self.language_settings["east"]
|
|
372
|
-
if coord < 0.0:
|
|
373
|
-
sign = self.language_settings["west"]
|
|
374
|
-
coord = abs(coord)
|
|
375
|
-
deg = int(coord)
|
|
376
|
-
min = int((float(coord) - deg) * 60)
|
|
377
|
-
sec = int(round(float(((float(coord) - deg) * 60) - min) * 60.0))
|
|
378
|
-
return f"{deg}°{min}'{sec}\" {sign}"
|
|
379
|
-
|
|
380
|
-
def _dec2deg(self, dec, type="3"):
|
|
381
|
-
"""Coverts decimal float to degrees in format
|
|
382
|
-
a°b'c".
|
|
383
|
-
"""
|
|
384
|
-
|
|
385
|
-
dec = float(dec)
|
|
386
|
-
a = int(dec)
|
|
387
|
-
a_new = (dec - float(a)) * 60.0
|
|
388
|
-
b_rounded = int(round(a_new))
|
|
389
|
-
b = int(a_new)
|
|
390
|
-
c = int(round((a_new - float(b)) * 60.0))
|
|
391
|
-
if type == "3":
|
|
392
|
-
out = f"{a:02d}°{b:02d}'{c:02d}""
|
|
393
|
-
elif type == "2":
|
|
394
|
-
out = f"{a:02d}°{b_rounded:02d}'"
|
|
395
|
-
elif type == "1":
|
|
396
|
-
out = f"{a:02d}°"
|
|
397
|
-
else:
|
|
398
|
-
raise KerykeionException(f"Wrong type: {type}, it must be 1, 2 or 3.")
|
|
399
|
-
return str(out)
|
|
400
|
-
|
|
401
|
-
def _drawAspect(self, r, ar, degA, degB, color):
|
|
402
|
-
"""
|
|
403
|
-
Draws svg aspects: ring, aspect ring, degreeA degreeB
|
|
289
|
+
str: The SVG string representing the zodiac circle.
|
|
404
290
|
"""
|
|
405
|
-
offset = (int(self.user.houses_degree_ut[6]) / -1) + int(degA)
|
|
406
|
-
x1 = sliceToX(0, ar, offset) + (r - ar)
|
|
407
|
-
y1 = sliceToY(0, ar, offset) + (r - ar)
|
|
408
|
-
offset = (int(self.user.houses_degree_ut[6]) / -1) + int(degB)
|
|
409
|
-
x2 = sliceToX(0, ar, offset) + (r - ar)
|
|
410
|
-
y2 = sliceToY(0, ar, offset) + (r - ar)
|
|
411
|
-
out = f' <line x1="{x1}" y1="{y1}" x2="{x2}" y2="{y2}" style="stroke: {color}; stroke-width: 1; stroke-opacity: .9;"/>'
|
|
412
291
|
|
|
413
|
-
return out
|
|
414
|
-
|
|
415
|
-
def _zodiacSlice(self, num, r, style, type):
|
|
416
|
-
# pie slices
|
|
417
|
-
offset = 360 - self.user.houses_degree_ut[6]
|
|
418
|
-
# check transit
|
|
419
|
-
if self.chart_type == "Transit" or self.chart_type == "Synastry":
|
|
420
|
-
dropin = 0
|
|
421
|
-
else:
|
|
422
|
-
dropin = self.c1
|
|
423
|
-
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}"/>'
|
|
424
|
-
|
|
425
|
-
# symbols
|
|
426
|
-
offset = offset + 15
|
|
427
|
-
# check transit
|
|
428
|
-
if self.chart_type == "Transit" or self.chart_type == "Synastry":
|
|
429
|
-
dropin = 54
|
|
430
|
-
else:
|
|
431
|
-
dropin = 18 + self.c1
|
|
432
|
-
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>'
|
|
433
|
-
|
|
434
|
-
return slice + "" + sign
|
|
435
|
-
|
|
436
|
-
def _makeZodiac(self, r):
|
|
437
292
|
output = ""
|
|
438
|
-
for i in
|
|
439
|
-
output
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
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"],
|
|
447
302
|
)
|
|
303
|
+
|
|
448
304
|
return output
|
|
449
305
|
|
|
450
306
|
def _makeHouses(self, r):
|
|
@@ -534,44 +390,50 @@ class KerykeionChartSVG:
|
|
|
534
390
|
|
|
535
391
|
return path
|
|
536
392
|
|
|
537
|
-
def
|
|
393
|
+
def _calculate_elements_points_from_planets(self):
|
|
538
394
|
"""
|
|
539
395
|
Calculate chart element points from a planet.
|
|
540
396
|
"""
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
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
|
|
407
|
+
|
|
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
|
|
411
|
+
|
|
412
|
+
elif ele == "earth":
|
|
413
|
+
self.earth = self.earth + self.available_planets_setting[i]["element_points"] + extra_points
|
|
414
|
+
|
|
415
|
+
elif ele == "air":
|
|
416
|
+
self.air = self.air + self.available_planets_setting[i]["element_points"] + extra_points
|
|
417
|
+
|
|
418
|
+
elif ele == "water":
|
|
419
|
+
self.water = self.water + self.available_planets_setting[i]["element_points"] + extra_points
|
|
563
420
|
|
|
564
421
|
def _make_planets(self, r):
|
|
565
422
|
planets_degut = {}
|
|
566
|
-
diff = range(len(self.
|
|
423
|
+
diff = range(len(self.available_planets_setting))
|
|
567
424
|
|
|
568
|
-
for i in range(len(self.
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
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
|
|
573
429
|
|
|
574
|
-
|
|
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
|
+
"""
|
|
575
437
|
|
|
576
438
|
output = ""
|
|
577
439
|
keys = list(planets_degut.keys())
|
|
@@ -600,24 +462,24 @@ class KerykeionChartSVG:
|
|
|
600
462
|
diffb = degreeDiff(next, self.points_deg_ut[i])
|
|
601
463
|
planets_by_pos[e] = [i, diffa, diffb]
|
|
602
464
|
|
|
603
|
-
|
|
465
|
+
logging.debug(f'{self.available_planets_setting[i]["label"]}, {diffa}, {diffb}')
|
|
604
466
|
|
|
605
467
|
if diffb < planet_drange:
|
|
606
468
|
if group_open:
|
|
607
|
-
groups[-1].append([e, diffa, diffb, self.
|
|
469
|
+
groups[-1].append([e, diffa, diffb, self.available_planets_setting[planets_degut[keys[e]]]["label"]])
|
|
608
470
|
else:
|
|
609
471
|
group_open = True
|
|
610
472
|
groups.append([])
|
|
611
|
-
groups[-1].append([e, diffa, diffb, self.
|
|
473
|
+
groups[-1].append([e, diffa, diffb, self.available_planets_setting[planets_degut[keys[e]]]["label"]])
|
|
612
474
|
else:
|
|
613
475
|
if group_open:
|
|
614
|
-
groups[-1].append([e, diffa, diffb, self.
|
|
476
|
+
groups[-1].append([e, diffa, diffb, self.available_planets_setting[planets_degut[keys[e]]]["label"]])
|
|
615
477
|
group_open = False
|
|
616
478
|
|
|
617
479
|
def zero(x):
|
|
618
480
|
return 0
|
|
619
481
|
|
|
620
|
-
planets_delta = list(map(zero, range(len(self.
|
|
482
|
+
planets_delta = list(map(zero, range(len(self.available_planets_setting))))
|
|
621
483
|
|
|
622
484
|
# print groups
|
|
623
485
|
# print planets_by_pos
|
|
@@ -729,7 +591,7 @@ class KerykeionChartSVG:
|
|
|
729
591
|
y1 = sliceToY(0, (r - self.c3), trueoffset) + self.c3
|
|
730
592
|
x2 = sliceToX(0, (r - rplanet - 30), trueoffset) + rplanet + 30
|
|
731
593
|
y2 = sliceToY(0, (r - rplanet - 30), trueoffset) + rplanet + 30
|
|
732
|
-
color = self.
|
|
594
|
+
color = self.available_planets_setting[i]["color"]
|
|
733
595
|
output += (
|
|
734
596
|
'<line x1="%s" y1="%s" x2="%s" y2="%s" style="stroke-width:1px;stroke:%s;stroke-opacity:.3;"/>\n'
|
|
735
597
|
% (x1, y1, x2, y2, color)
|
|
@@ -747,20 +609,21 @@ class KerykeionChartSVG:
|
|
|
747
609
|
else:
|
|
748
610
|
scale = 1
|
|
749
611
|
# output planet
|
|
750
|
-
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>'
|
|
751
613
|
|
|
752
614
|
# make transit degut and display planets
|
|
753
615
|
if self.chart_type == "Transit" or self.chart_type == "Synastry":
|
|
754
616
|
group_offset = {}
|
|
755
617
|
t_planets_degut = {}
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
else:
|
|
759
|
-
list_range = len(self.planets_settings)
|
|
618
|
+
list_range = len(self.available_planets_setting)
|
|
619
|
+
|
|
760
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
|
+
|
|
761
624
|
group_offset[i] = 0
|
|
762
|
-
|
|
763
|
-
|
|
625
|
+
t_planets_degut[self.t_points_deg_ut[i]] = i
|
|
626
|
+
|
|
764
627
|
t_keys = list(t_planets_degut.keys())
|
|
765
628
|
t_keys.sort()
|
|
766
629
|
|
|
@@ -802,7 +665,12 @@ class KerykeionChartSVG:
|
|
|
802
665
|
group_offset[groups[i][3]] = 2.0
|
|
803
666
|
|
|
804
667
|
switch = 0
|
|
668
|
+
|
|
669
|
+
# Transit planets loop
|
|
805
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
|
+
|
|
806
674
|
i = t_planets_degut[t_keys[e]]
|
|
807
675
|
|
|
808
676
|
if 22 < i < 27:
|
|
@@ -814,20 +682,21 @@ class KerykeionChartSVG:
|
|
|
814
682
|
rplanet = 26
|
|
815
683
|
switch = 1
|
|
816
684
|
|
|
685
|
+
# Transit planet name
|
|
817
686
|
zeropoint = 360 - self.user.houses_degree_ut[6]
|
|
818
687
|
t_offset = zeropoint + self.t_points_deg_ut[i]
|
|
819
688
|
if t_offset > 360:
|
|
820
689
|
t_offset = t_offset - 360
|
|
821
690
|
planet_x = sliceToX(0, (r - rplanet), t_offset) + rplanet
|
|
822
691
|
planet_y = sliceToY(0, (r - rplanet), t_offset) + rplanet
|
|
823
|
-
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>'
|
|
824
693
|
|
|
825
|
-
#
|
|
694
|
+
# Transit planet line
|
|
826
695
|
x1 = sliceToX(0, r + 3, t_offset) - 3
|
|
827
696
|
y1 = sliceToY(0, r + 3, t_offset) - 3
|
|
828
697
|
x2 = sliceToX(0, r - 3, t_offset) + 3
|
|
829
698
|
y2 = sliceToY(0, r - 3, t_offset) + 3
|
|
830
|
-
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;"/>'
|
|
831
700
|
|
|
832
701
|
# transit planet degree text
|
|
833
702
|
rotate = self.user.houses_degree_ut[0] - self.t_points_deg_ut[i]
|
|
@@ -851,7 +720,7 @@ class KerykeionChartSVG:
|
|
|
851
720
|
degree = int(t_offset)
|
|
852
721
|
output += f'<g transform="translate({deg_x},{deg_y})">'
|
|
853
722
|
output += f'<text transform="rotate({rotate})" text-anchor="{textanchor}'
|
|
854
|
-
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")}'
|
|
855
724
|
output += "</text></g>"
|
|
856
725
|
|
|
857
726
|
# check transit
|
|
@@ -866,7 +735,7 @@ class KerykeionChartSVG:
|
|
|
866
735
|
x2 = sliceToX(0, (r - (dropin - 3)), offset) + (dropin - 3)
|
|
867
736
|
y2 = sliceToY(0, (r - (dropin - 3)), offset) + (dropin - 3)
|
|
868
737
|
|
|
869
|
-
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;"/>'
|
|
870
739
|
|
|
871
740
|
# check transit
|
|
872
741
|
if self.chart_type == "Transit" or self.chart_type == "Synastry":
|
|
@@ -878,7 +747,7 @@ class KerykeionChartSVG:
|
|
|
878
747
|
y1 = sliceToY(0, r - dropin, offset) + dropin
|
|
879
748
|
x2 = sliceToX(0, (r - (dropin - 3)), offset) + (dropin - 3)
|
|
880
749
|
y2 = sliceToY(0, (r - (dropin - 3)), offset) + (dropin - 3)
|
|
881
|
-
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;"/>'
|
|
882
751
|
|
|
883
752
|
return output
|
|
884
753
|
|
|
@@ -896,7 +765,7 @@ class KerykeionChartSVG:
|
|
|
896
765
|
tr = {} # 6
|
|
897
766
|
qc = {} # 9
|
|
898
767
|
sext = {} # 3
|
|
899
|
-
for i in range(len(self.
|
|
768
|
+
for i in range(len(self.available_planets_setting)):
|
|
900
769
|
a = self.points_deg_ut[i]
|
|
901
770
|
qc[i] = {}
|
|
902
771
|
sext[i] = {}
|
|
@@ -905,14 +774,14 @@ class KerykeionChartSVG:
|
|
|
905
774
|
tr[i] = {}
|
|
906
775
|
conj[i] = {}
|
|
907
776
|
# skip some points
|
|
908
|
-
n = self.
|
|
777
|
+
n = self.available_planets_setting[i]["name"]
|
|
909
778
|
if n == "earth" or n == "True_Node" or n == "osc. apogee" or n == "intp. apogee" or n == "intp. perigee":
|
|
910
779
|
continue
|
|
911
780
|
if n == "Dsc" or n == "Ic":
|
|
912
781
|
continue
|
|
913
|
-
for j in range(len(self.
|
|
782
|
+
for j in range(len(self.available_planets_setting)):
|
|
914
783
|
# skip some points
|
|
915
|
-
n = self.
|
|
784
|
+
n = self.available_planets_setting[j]["name"]
|
|
916
785
|
if n == "earth" or n == "True_Node" or n == "osc. apogee" or n == "intp. apogee" or n == "intp. perigee":
|
|
917
786
|
continue
|
|
918
787
|
if n == "Dsc" or n == "Ic":
|
|
@@ -965,12 +834,12 @@ class KerykeionChartSVG:
|
|
|
965
834
|
for l, w in opp[k].items():
|
|
966
835
|
for a, b in sq.items():
|
|
967
836
|
if k in sq[a] and l in sq[a]:
|
|
968
|
-
|
|
837
|
+
logging.debug(f"Got tsquare {a} {k} {l}")
|
|
969
838
|
if k > l:
|
|
970
|
-
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']}"
|
|
971
840
|
|
|
972
841
|
else:
|
|
973
|
-
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']}"
|
|
974
843
|
|
|
975
844
|
stellium = {}
|
|
976
845
|
# check for 4 continuous conjunctions
|
|
@@ -999,10 +868,10 @@ class KerykeionChartSVG:
|
|
|
999
868
|
l = [k, n, p, r]
|
|
1000
869
|
l.sort()
|
|
1001
870
|
stellium["%s %s %s %s" % (l[0], l[1], l[2], l[3])] = "%s %s %s %s" % (
|
|
1002
|
-
self.
|
|
1003
|
-
self.
|
|
1004
|
-
self.
|
|
1005
|
-
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"],
|
|
1006
875
|
)
|
|
1007
876
|
# print yots
|
|
1008
877
|
out = '<g transform="translate(-30,380)">'
|
|
@@ -1013,15 +882,15 @@ class KerykeionChartSVG:
|
|
|
1013
882
|
|
|
1014
883
|
# first planet symbol
|
|
1015
884
|
out += f'<g transform="translate(20,{y})">'
|
|
1016
|
-
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>'
|
|
1017
886
|
|
|
1018
887
|
# second planet symbol
|
|
1019
888
|
out += f'<g transform="translate(30,{y})">'
|
|
1020
|
-
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>'
|
|
1021
890
|
|
|
1022
891
|
# third planet symbol
|
|
1023
892
|
out += f'<g transform="translate(40,{y})">'
|
|
1024
|
-
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>'
|
|
1025
894
|
|
|
1026
895
|
y = y + 14
|
|
1027
896
|
# finalize
|
|
@@ -1033,12 +902,13 @@ class KerykeionChartSVG:
|
|
|
1033
902
|
def _makeAspects(self, r, ar):
|
|
1034
903
|
out = ""
|
|
1035
904
|
for element in self.aspects_list:
|
|
1036
|
-
out +=
|
|
1037
|
-
r,
|
|
1038
|
-
ar,
|
|
1039
|
-
element["p1_abs_pos"],
|
|
1040
|
-
element["p2_abs_pos"],
|
|
1041
|
-
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
|
|
1042
912
|
)
|
|
1043
913
|
|
|
1044
914
|
return out
|
|
@@ -1049,47 +919,44 @@ class KerykeionChartSVG:
|
|
|
1049
919
|
xindent = 380
|
|
1050
920
|
yindent = 468
|
|
1051
921
|
box = 14
|
|
1052
|
-
revr = list(range(len(self.
|
|
922
|
+
revr = list(range(len(self.available_planets_setting)))
|
|
1053
923
|
revr.reverse()
|
|
1054
924
|
counter = 0
|
|
1055
925
|
for a in revr:
|
|
1056
926
|
counter += 1
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
if (element["p1"] == a and element["p2"] == b) or (element["p1"] == b and element["p2"] == a):
|
|
1074
|
-
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"]}" />'
|
|
1075
943
|
|
|
1076
944
|
return out
|
|
1077
945
|
|
|
1078
|
-
# Aspect and aspect grid functions for transit type charts
|
|
1079
|
-
|
|
946
|
+
# Aspect and aspect grid functions for transit type charts
|
|
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
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
element["
|
|
1091
|
-
element["
|
|
1092
|
-
self.
|
|
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
|
|
1093
960
|
)
|
|
1094
961
|
|
|
1095
962
|
return out
|
|
@@ -1104,78 +971,60 @@ class KerykeionChartSVG:
|
|
|
1104
971
|
for i in range(len(self.aspects_list)):
|
|
1105
972
|
if i == 12:
|
|
1106
973
|
nl = 100
|
|
1107
|
-
|
|
1108
|
-
# line = -1 * ( len(self.aspects_list) - 24) * 14
|
|
1109
|
-
# else:
|
|
1110
|
-
# line = 0
|
|
1111
|
-
|
|
1112
|
-
# temporary:
|
|
974
|
+
|
|
1113
975
|
line = 0
|
|
1114
976
|
|
|
1115
|
-
|
|
977
|
+
elif i == 24:
|
|
1116
978
|
nl = 200
|
|
1117
|
-
|
|
1118
|
-
# line = -1 * ( len(self.aspects_list) - 36) * 14
|
|
1119
|
-
# else:
|
|
1120
|
-
# line = 0
|
|
979
|
+
|
|
1121
980
|
line = 0
|
|
1122
981
|
|
|
1123
|
-
|
|
982
|
+
elif i == 36:
|
|
1124
983
|
nl = 300
|
|
1125
|
-
|
|
1126
|
-
|
|
984
|
+
|
|
985
|
+
line = 0
|
|
986
|
+
|
|
987
|
+
elif i == 48:
|
|
988
|
+
nl = 400
|
|
989
|
+
|
|
990
|
+
# When there are more than 60 aspects, the text is moved up
|
|
991
|
+
if len(self.aspects_list) > 60:
|
|
992
|
+
line = -1 * (len(self.aspects_list) - 60) * 14
|
|
1127
993
|
else:
|
|
1128
994
|
line = 0
|
|
995
|
+
|
|
1129
996
|
out += f'<g transform="translate({nl},{line})">'
|
|
997
|
+
|
|
1130
998
|
# first planet symbol
|
|
1131
|
-
|
|
1132
|
-
# 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.
|
|
1133
999
|
out += f'<use transform="scale(0.4)" x="0" y="3" xlink:href="#{self.planets_settings[self.aspects_list[i]["p1"]]["name"]}" />'
|
|
1134
1000
|
|
|
1135
1001
|
# aspect symbol
|
|
1136
1002
|
out += f'<use x="15" y="0" xlink:href="#orb{self.aspects_settings[self.aspects_list[i]["aid"]]["degree"]}" />'
|
|
1003
|
+
|
|
1137
1004
|
# second planet symbol
|
|
1138
1005
|
out += '<g transform="translate(30,0)">'
|
|
1139
|
-
|
|
1140
|
-
# TODO: (next((item for item in self.planets_settings if item["id"] == self.aspects_list[i]["p3"])))
|
|
1141
1006
|
out += '<use transform="scale(0.4)" x="0" y="3" xlink:href="#%s" />' % (self.planets_settings[self.aspects_list[i]["p2"]]["name"])
|
|
1142
1007
|
|
|
1143
1008
|
out += "</g>"
|
|
1144
1009
|
# difference in degrees
|
|
1145
|
-
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>'
|
|
1146
1011
|
# line
|
|
1147
1012
|
out += "</g>"
|
|
1148
1013
|
line = line + 14
|
|
1149
1014
|
out += "</g>"
|
|
1150
1015
|
return out
|
|
1151
1016
|
|
|
1152
|
-
def _makeElements(self, r):
|
|
1153
|
-
total = self.fire + self.earth + self.air + self.water
|
|
1154
|
-
pf = int(round(100 * self.fire / total))
|
|
1155
|
-
pe = int(round(100 * self.earth / total))
|
|
1156
|
-
pa = int(round(100 * self.air / total))
|
|
1157
|
-
pw = int(round(100 * self.water / total))
|
|
1158
|
-
|
|
1159
|
-
out = '<g transform="translate(-30,79)">'
|
|
1160
|
-
out += f'<text y="0" style="fill:#ff6600; font-size: 10px;">{self.language_settings["fire"]} {str(pf)}%</text>'
|
|
1161
|
-
out += f'<text y="12" style="fill:#6a2d04; font-size: 10px;">{self.language_settings["earth"]} {str(pe)}%</text>'
|
|
1162
|
-
out += f'<text y="24" style="fill:#6f76d1; font-size: 10px;">{self.language_settings["air"]} {str(pa)}%</text>'
|
|
1163
|
-
out += f'<text y="36" style="fill:#630e73; font-size: 10px;">{self.language_settings["water"]} {str(pw)}%</text>'
|
|
1164
|
-
out += "</g>"
|
|
1165
|
-
|
|
1166
|
-
return out
|
|
1167
|
-
|
|
1168
1017
|
def _makePlanetGrid(self):
|
|
1169
1018
|
li = 10
|
|
1170
1019
|
offset = 0
|
|
1171
1020
|
|
|
1172
1021
|
out = '<g transform="translate(500,-20)">'
|
|
1173
1022
|
out += '<g transform="translate(140, -15)">'
|
|
1174
|
-
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>'
|
|
1175
1024
|
out += "</g>"
|
|
1176
1025
|
|
|
1177
1026
|
end_of_line = None
|
|
1178
|
-
for i in range(len(self.
|
|
1027
|
+
for i in range(len(self.available_planets_setting)):
|
|
1179
1028
|
offset_between_lines = 14
|
|
1180
1029
|
end_of_line = "</g>"
|
|
1181
1030
|
|
|
@@ -1184,30 +1033,29 @@ class KerykeionChartSVG:
|
|
|
1184
1033
|
li = 10
|
|
1185
1034
|
offset = -120
|
|
1186
1035
|
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
out += f'<g transform="translate({offset},{li})">'
|
|
1036
|
+
# start of line
|
|
1037
|
+
out += f'<g transform="translate({offset},{li})">'
|
|
1190
1038
|
|
|
1191
|
-
|
|
1192
|
-
|
|
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>'
|
|
1193
1041
|
|
|
1194
|
-
|
|
1195
|
-
|
|
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>'
|
|
1196
1044
|
|
|
1197
|
-
|
|
1198
|
-
|
|
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>'
|
|
1199
1047
|
|
|
1200
|
-
|
|
1201
|
-
|
|
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>'
|
|
1202
1050
|
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1051
|
+
# planet retrograde
|
|
1052
|
+
if self.points_retrograde[i]:
|
|
1053
|
+
out += '<g transform="translate(74,-6)"><use transform="scale(.5)" xlink:href="#retrograde" /></g>'
|
|
1206
1054
|
|
|
1207
|
-
|
|
1208
|
-
|
|
1055
|
+
# end of line
|
|
1056
|
+
out += end_of_line
|
|
1209
1057
|
|
|
1210
|
-
|
|
1058
|
+
li = li + offset_between_lines
|
|
1211
1059
|
|
|
1212
1060
|
if self.chart_type == "Transit" or self.chart_type == "Synastry":
|
|
1213
1061
|
if self.chart_type == "Transit":
|
|
@@ -1222,32 +1070,31 @@ class KerykeionChartSVG:
|
|
|
1222
1070
|
t_li = 10
|
|
1223
1071
|
t_offset = 250
|
|
1224
1072
|
|
|
1225
|
-
for i in range(len(self.
|
|
1073
|
+
for i in range(len(self.available_planets_setting)):
|
|
1226
1074
|
if i == 27:
|
|
1227
1075
|
t_li = 10
|
|
1228
1076
|
t_offset = -120
|
|
1229
1077
|
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
out += f'<g transform="translate({t_offset},{t_li})">'
|
|
1078
|
+
# start of line
|
|
1079
|
+
out += f'<g transform="translate({t_offset},{t_li})">'
|
|
1233
1080
|
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
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>'
|
|
1242
1089
|
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
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>'
|
|
1246
1093
|
|
|
1247
|
-
|
|
1248
|
-
|
|
1094
|
+
# end of line
|
|
1095
|
+
out += end_of_line
|
|
1249
1096
|
|
|
1250
|
-
|
|
1097
|
+
t_li = t_li + offset_between_lines
|
|
1251
1098
|
|
|
1252
1099
|
if end_of_line is None:
|
|
1253
1100
|
raise KerykeionException("End of line not found")
|
|
@@ -1255,7 +1102,13 @@ class KerykeionChartSVG:
|
|
|
1255
1102
|
out += end_of_line
|
|
1256
1103
|
return out
|
|
1257
1104
|
|
|
1258
|
-
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
|
+
"""
|
|
1259
1112
|
out = '<g transform="translate(600,-20)">'
|
|
1260
1113
|
|
|
1261
1114
|
li = 10
|
|
@@ -1267,7 +1120,7 @@ class KerykeionChartSVG:
|
|
|
1267
1120
|
out += f'<g transform="translate(0,{li})">'
|
|
1268
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>'
|
|
1269
1122
|
out += f'<g transform="translate(40,-8)"><use transform="scale(0.3)" xlink:href="#{self.zodiac[self.houses_sign_graph[i]]["name"]}" /></g>'
|
|
1270
|
-
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>'
|
|
1271
1124
|
out += "</g>"
|
|
1272
1125
|
li = li + 14
|
|
1273
1126
|
|
|
@@ -1284,14 +1137,14 @@ class KerykeionChartSVG:
|
|
|
1284
1137
|
out += '<g transform="translate(0,' + str(li) + ')">'
|
|
1285
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>'
|
|
1286
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>'
|
|
1287
|
-
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>'
|
|
1288
1141
|
out += "</g>"
|
|
1289
1142
|
li = li + 14
|
|
1290
1143
|
out += "</g>"
|
|
1291
1144
|
|
|
1292
1145
|
return out
|
|
1293
1146
|
|
|
1294
|
-
def _createTemplateDictionary(self):
|
|
1147
|
+
def _createTemplateDictionary(self) -> ChartTemplateDictionary:
|
|
1295
1148
|
# self.chart_type = "Transit"
|
|
1296
1149
|
# empty element points
|
|
1297
1150
|
self.fire = 0.0
|
|
@@ -1299,30 +1152,23 @@ class KerykeionChartSVG:
|
|
|
1299
1152
|
self.air = 0.0
|
|
1300
1153
|
self.water = 0.0
|
|
1301
1154
|
|
|
1302
|
-
#
|
|
1303
|
-
|
|
1304
|
-
if ratio < 1.3: # 1280x1024
|
|
1305
|
-
wm_off = 130
|
|
1306
|
-
else: # 1024x768, 800x600, 1280x800, 1680x1050
|
|
1307
|
-
wm_off = 100
|
|
1155
|
+
# Calculate the elements points
|
|
1156
|
+
self._calculate_elements_points_from_planets()
|
|
1308
1157
|
|
|
1309
1158
|
# Viewbox and sizing
|
|
1310
|
-
svgHeight = "100%"
|
|
1311
|
-
svgWidth = "100%"
|
|
1312
|
-
# svgHeight=self.screen_height-wm_off
|
|
1313
|
-
# svgWidth=(770.0*svgHeight)/540.0
|
|
1314
|
-
# svgWidth=float(self.screen_width)-25.0
|
|
1159
|
+
svgHeight = "100%"
|
|
1160
|
+
svgWidth = "100%"
|
|
1315
1161
|
rotate = "0"
|
|
1316
1162
|
translate = "0"
|
|
1317
|
-
|
|
1318
|
-
#
|
|
1319
|
-
if self.chart_type == "Natal":
|
|
1320
|
-
viewbox =
|
|
1163
|
+
|
|
1164
|
+
# To increase the size of the chart, change the viewbox
|
|
1165
|
+
if self.chart_type == "Natal" or self.chart_type == "ExternalNatal":
|
|
1166
|
+
viewbox = self.chart_settings["basic_chart_viewBox"]
|
|
1321
1167
|
else:
|
|
1322
|
-
viewbox =
|
|
1168
|
+
viewbox = self.chart_settings["wide_chart_viewBox"]
|
|
1323
1169
|
|
|
1324
1170
|
# template dictionary
|
|
1325
|
-
td:
|
|
1171
|
+
td: ChartTemplateDictionary = dict() # type: ignore
|
|
1326
1172
|
r = 240
|
|
1327
1173
|
|
|
1328
1174
|
if self.chart_type == "ExternalNatal":
|
|
@@ -1336,14 +1182,12 @@ class KerykeionChartSVG:
|
|
|
1336
1182
|
|
|
1337
1183
|
# transit
|
|
1338
1184
|
if self.chart_type == "Transit" or self.chart_type == "Synastry":
|
|
1339
|
-
td["transitRing"] = self.
|
|
1340
|
-
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)
|
|
1341
1187
|
|
|
1342
1188
|
# circles
|
|
1343
|
-
td["
|
|
1344
|
-
td["
|
|
1345
|
-
td["c2"] = 'cx="' + str(r) + '" cy="' + str(r) + '" r="' + str(r - 72) + '"'
|
|
1346
|
-
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)
|
|
1347
1191
|
|
|
1348
1192
|
td["c3"] = 'cx="' + str(r) + '" cy="' + str(r) + '" r="' + str(r - 160) + '"'
|
|
1349
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"
|
|
@@ -1351,23 +1195,23 @@ class KerykeionChartSVG:
|
|
|
1351
1195
|
td["makeAspects"] = self._makeAspectsTransit(r, (r - 160))
|
|
1352
1196
|
td["makeAspectGrid"] = self._makeAspectTransitGrid(r)
|
|
1353
1197
|
td["makePatterns"] = ""
|
|
1354
|
-
td["chart_width"] = self.full_width
|
|
1355
1198
|
else:
|
|
1356
1199
|
td["transitRing"] = ""
|
|
1357
|
-
td["degreeRing"] = self.
|
|
1200
|
+
td["degreeRing"] = draw_degree_ring(r, self.c1, self.user.seventh_house.abs_pos, self.chart_colors_settings["paper_0"])
|
|
1358
1201
|
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
td["
|
|
1362
|
-
|
|
1363
|
-
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
|
+
|
|
1364
1206
|
td["c3"] = f'cx="{r}" cy="{r}" r="{r - self.c3}"'
|
|
1365
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
|
+
|
|
1366
1209
|
td["makeAspects"] = self._makeAspects(r, (r - self.c3))
|
|
1367
1210
|
td["makeAspectGrid"] = self._makeAspectGrid(r)
|
|
1368
1211
|
td["makePatterns"] = self._makePatterns()
|
|
1369
|
-
|
|
1370
|
-
|
|
1212
|
+
|
|
1213
|
+
td["chart_height"] = self.height
|
|
1214
|
+
td["chart_width"] = self.width
|
|
1371
1215
|
td["circleX"] = str(0)
|
|
1372
1216
|
td["circleY"] = str(0)
|
|
1373
1217
|
td["svgWidth"] = str(svgWidth)
|
|
@@ -1375,17 +1219,17 @@ class KerykeionChartSVG:
|
|
|
1375
1219
|
td["viewbox"] = viewbox
|
|
1376
1220
|
|
|
1377
1221
|
if self.chart_type == "Synastry":
|
|
1378
|
-
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}"
|
|
1379
1223
|
|
|
1380
1224
|
elif self.chart_type == "Transit":
|
|
1381
1225
|
td["stringTitle"] = f"{self.language_settings['transits']} {self.t_user.day}/{self.t_user.month}/{self.t_user.year}"
|
|
1382
1226
|
|
|
1383
1227
|
else:
|
|
1384
|
-
td["stringTitle"] = self.name
|
|
1228
|
+
td["stringTitle"] = self.user.name
|
|
1385
1229
|
|
|
1386
1230
|
# Tipo di carta
|
|
1387
|
-
if self.chart_type == "Synastry" or self.
|
|
1388
|
-
td["stringName"] = f"{self.name}:"
|
|
1231
|
+
if self.chart_type == "Synastry" or self.chart_type == "Transit":
|
|
1232
|
+
td["stringName"] = f"{self.user.name}:"
|
|
1389
1233
|
else:
|
|
1390
1234
|
td["stringName"] = f'{self.language_settings["info"]}:'
|
|
1391
1235
|
|
|
@@ -1469,9 +1313,20 @@ class KerykeionChartSVG:
|
|
|
1469
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}"
|
|
1470
1314
|
|
|
1471
1315
|
else:
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
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}"
|
|
1475
1330
|
|
|
1476
1331
|
# paper_color_X
|
|
1477
1332
|
td["paper_color_0"] = self.chart_colors_settings["paper_0"]
|
|
@@ -1495,48 +1350,68 @@ class KerykeionChartSVG:
|
|
|
1495
1350
|
td["cfgRotate"] = rotate
|
|
1496
1351
|
td["cfgTranslate"] = translate
|
|
1497
1352
|
|
|
1498
|
-
#
|
|
1499
|
-
|
|
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
|
|
1500
1360
|
td["makeHouses"] = self._makeHouses(r)
|
|
1501
1361
|
td["makePlanets"] = self._make_planets(r)
|
|
1502
|
-
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
|
+
)
|
|
1503
1372
|
td["makePlanetGrid"] = self._makePlanetGrid()
|
|
1504
|
-
td["makeHousesGrid"] = self._makeHousesGrid()
|
|
1505
1373
|
|
|
1506
1374
|
return td
|
|
1507
1375
|
|
|
1508
|
-
def makeTemplate(self):
|
|
1376
|
+
def makeTemplate(self, minify: bool = False) -> str:
|
|
1509
1377
|
"""Creates the template for the SVG file"""
|
|
1510
1378
|
td = self._createTemplateDictionary()
|
|
1511
1379
|
|
|
1512
1380
|
# read template
|
|
1513
|
-
with open(self.xml_svg, "r", encoding="utf-8", errors="ignore") as
|
|
1514
|
-
f = open(self.xml_svg)
|
|
1381
|
+
with open(self.xml_svg, "r", encoding="utf-8", errors="ignore") as f:
|
|
1515
1382
|
template = Template(f.read()).substitute(td)
|
|
1516
1383
|
|
|
1517
1384
|
# return filename
|
|
1518
1385
|
|
|
1519
|
-
|
|
1386
|
+
logging.debug(f"Template dictionary keys: {td.keys()}")
|
|
1520
1387
|
|
|
1521
1388
|
self._createTemplateDictionary()
|
|
1522
|
-
return template.replace('"', "'")
|
|
1523
1389
|
|
|
1524
|
-
|
|
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):
|
|
1525
1399
|
"""Prints out the SVG file in the specifide folder"""
|
|
1526
1400
|
|
|
1527
1401
|
if not (self.template):
|
|
1528
|
-
self.template = self.makeTemplate()
|
|
1402
|
+
self.template = self.makeTemplate(minify)
|
|
1529
1403
|
|
|
1530
|
-
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"
|
|
1531
1405
|
|
|
1532
1406
|
with open(self.chartname, "w", encoding="utf-8", errors="ignore") as output_file:
|
|
1533
1407
|
output_file.write(self.template)
|
|
1534
1408
|
|
|
1535
|
-
|
|
1409
|
+
logging.info(f"SVG Generated Correctly in: {self.chartname}")
|
|
1536
1410
|
|
|
1537
1411
|
|
|
1538
1412
|
if __name__ == "__main__":
|
|
1539
|
-
|
|
1413
|
+
from kerykeion.utilities import setup_logging
|
|
1414
|
+
setup_logging(level="debug")
|
|
1540
1415
|
|
|
1541
1416
|
first = AstrologicalSubject("John Lennon", 1940, 10, 9, 10, 30, "Liverpool", "GB")
|
|
1542
1417
|
second = AstrologicalSubject("Paul McCartney", 1942, 6, 18, 15, 30, "Liverpool", "GB")
|
|
@@ -1551,8 +1426,9 @@ if __name__ == "__main__":
|
|
|
1551
1426
|
|
|
1552
1427
|
# Synastry Chart
|
|
1553
1428
|
synastry_chart = KerykeionChartSVG(first, "Synastry", second)
|
|
1554
|
-
synastry_chart.makeSVG()
|
|
1429
|
+
synastry_chart.makeSVG(minify=True)
|
|
1555
1430
|
|
|
1556
1431
|
# Transits Chart
|
|
1557
1432
|
transits_chart = KerykeionChartSVG(first, "Transit", second)
|
|
1558
|
-
transits_chart.makeSVG()
|
|
1433
|
+
transits_chart.makeSVG(minify=True)
|
|
1434
|
+
|