kerykeion 3.1.1__py3-none-any.whl → 5.1.9__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.

Files changed (75) hide show
  1. kerykeion/__init__.py +58 -141
  2. kerykeion/aspects/__init__.py +14 -0
  3. kerykeion/aspects/aspects_factory.py +568 -0
  4. kerykeion/aspects/aspects_utils.py +164 -0
  5. kerykeion/astrological_subject_factory.py +1901 -0
  6. kerykeion/backword.py +820 -0
  7. kerykeion/chart_data_factory.py +552 -0
  8. kerykeion/charts/__init__.py +5 -0
  9. kerykeion/charts/chart_drawer.py +2794 -0
  10. kerykeion/charts/charts_utils.py +1840 -0
  11. kerykeion/charts/draw_planets.py +658 -0
  12. kerykeion/charts/templates/aspect_grid_only.xml +596 -0
  13. kerykeion/charts/templates/chart.xml +741 -0
  14. kerykeion/charts/templates/wheel_only.xml +653 -0
  15. kerykeion/charts/themes/black-and-white.css +148 -0
  16. kerykeion/charts/themes/classic.css +113 -0
  17. kerykeion/charts/themes/dark-high-contrast.css +159 -0
  18. kerykeion/charts/themes/dark.css +160 -0
  19. kerykeion/charts/themes/light.css +160 -0
  20. kerykeion/charts/themes/strawberry.css +158 -0
  21. kerykeion/composite_subject_factory.py +408 -0
  22. kerykeion/ephemeris_data_factory.py +443 -0
  23. kerykeion/fetch_geonames.py +105 -61
  24. kerykeion/house_comparison/__init__.py +6 -0
  25. kerykeion/house_comparison/house_comparison_factory.py +103 -0
  26. kerykeion/house_comparison/house_comparison_utils.py +126 -0
  27. kerykeion/kr_types/__init__.py +70 -0
  28. kerykeion/kr_types/chart_template_model.py +20 -0
  29. kerykeion/kr_types/kerykeion_exception.py +20 -0
  30. kerykeion/kr_types/kr_literals.py +20 -0
  31. kerykeion/kr_types/kr_models.py +20 -0
  32. kerykeion/kr_types/settings_models.py +20 -0
  33. kerykeion/planetary_return_factory.py +805 -0
  34. kerykeion/relationship_score_factory.py +301 -0
  35. kerykeion/report.py +779 -0
  36. kerykeion/schemas/__init__.py +106 -0
  37. kerykeion/schemas/chart_template_model.py +367 -0
  38. kerykeion/schemas/kerykeion_exception.py +20 -0
  39. kerykeion/schemas/kr_literals.py +181 -0
  40. kerykeion/schemas/kr_models.py +603 -0
  41. kerykeion/schemas/settings_models.py +188 -0
  42. kerykeion/settings/__init__.py +20 -0
  43. kerykeion/settings/chart_defaults.py +444 -0
  44. kerykeion/settings/config_constants.py +152 -0
  45. kerykeion/settings/kerykeion_settings.py +51 -0
  46. kerykeion/settings/translation_strings.py +1499 -0
  47. kerykeion/settings/translations.py +74 -0
  48. kerykeion/sweph/README.md +3 -0
  49. kerykeion/sweph/ast136/s136108s.se1 +0 -0
  50. kerykeion/sweph/ast136/s136199s.se1 +0 -0
  51. kerykeion/sweph/ast136/s136472s.se1 +0 -0
  52. kerykeion/sweph/ast28/se28978s.se1 +0 -0
  53. kerykeion/sweph/ast50/se50000s.se1 +0 -0
  54. kerykeion/sweph/ast90/se90377s.se1 +0 -0
  55. kerykeion/sweph/ast90/se90482s.se1 +0 -0
  56. kerykeion/sweph/seas_18.se1 +0 -0
  57. kerykeion/sweph/sefstars.txt +1602 -0
  58. kerykeion/transits_time_range_factory.py +302 -0
  59. kerykeion/utilities.py +762 -130
  60. kerykeion-5.1.9.dist-info/METADATA +1793 -0
  61. kerykeion-5.1.9.dist-info/RECORD +63 -0
  62. {kerykeion-3.1.1.dist-info → kerykeion-5.1.9.dist-info}/WHEEL +1 -2
  63. kerykeion-5.1.9.dist-info/licenses/LICENSE +661 -0
  64. kerykeion/aspects.py +0 -331
  65. kerykeion/charts/charts_svg.py +0 -1607
  66. kerykeion/charts/templates/basic.xml +0 -285
  67. kerykeion/charts/templates/extended.xml +0 -294
  68. kerykeion/kr.config.json +0 -464
  69. kerykeion/main.py +0 -595
  70. kerykeion/print_all_data.py +0 -44
  71. kerykeion/relationship_score.py +0 -219
  72. kerykeion/types.py +0 -190
  73. kerykeion-3.1.1.dist-info/METADATA +0 -204
  74. kerykeion-3.1.1.dist-info/RECORD +0 -17
  75. kerykeion-3.1.1.dist-info/top_level.txt +0 -1
@@ -1,1607 +0,0 @@
1
- #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
-
4
- # * TODO: Change the label for language in 2 objects, one for IT and one for ENG.
5
- # * Then change the label for planets like this: planet["label"] => planet[language]
6
-
7
- import json
8
- import math
9
- import pytz
10
-
11
- from datetime import datetime
12
- from kerykeion.aspects import NatalAspects, CompositeAspects
13
- from kerykeion.main import KrInstance
14
- from kerykeion.types import KerykeionException, ChartType
15
- from pathlib import Path
16
- from string import Template
17
- from typing import Union
18
-
19
- # calculation and svg drawing class
20
-
21
-
22
- class MakeSvgInstance:
23
- """
24
- Creates the instance that can genearte the chart with the
25
- function makeSVG().
26
-
27
- There are 2 templates, the extended (default) which has all the
28
- information and the basic, which has just the chart.
29
-
30
- Parameters:
31
- - first_obj: First kerykeion object
32
- - chart_type: Natal, Transit, Composite (Default: Type="Natal")
33
- - second_obj: Second kerykeion object (Not required if type is Natal)
34
- - new_output_directory: Set the output directory (default: output_directory)
35
- - template_type: set the template type to include or not the aspects grid, default: extended)
36
- - lang: language settings (default: "EN")
37
- - new_settings_file: Set the settings file (default: kr.config.json)
38
- """
39
-
40
- def __init__(
41
- self,
42
- first_obj: KrInstance,
43
- chart_type: ChartType = "Natal",
44
- second_obj: Union[KrInstance, None] = None,
45
- new_output_directory: Union[str, None] = None,
46
- template_type: str = "extended",
47
- lang: str = "EN",
48
- new_settings_file: Union[str, Path, None] = None
49
- ):
50
-
51
- # Directories:
52
- DATADIR = Path(__file__).parent
53
- self.homedir = Path.home()
54
-
55
- if new_output_directory:
56
- self.output_directory = Path(new_output_directory)
57
- else:
58
- self.output_directory = self.homedir
59
-
60
- # Template types:
61
- if template_type == "basic":
62
- self.xml_svg = DATADIR / 'templates/basic.xml'
63
- else:
64
- self.xml_svg = DATADIR / 'templates/extended.xml'
65
-
66
- # SVG Width
67
- self.natal_width = 772.2
68
- self.full_width = 1200
69
-
70
- # Settings file:
71
- if not new_settings_file:
72
- self.settings_file = DATADIR.parent / 'kr.config.json'
73
- else:
74
- self.settings_file = Path(new_settings_file)
75
-
76
- self.parse_json_settings(self.settings_file, lang)
77
- self.chart_type = chart_type
78
-
79
- # Kerykeion instance
80
- self.user = first_obj
81
- if not hasattr(self.user, "sun"):
82
- print(f"Generating kerykeion object for {self.user.name}...")
83
- self.user.__get_all()
84
-
85
- # Make a list for the absolute degrees of the points of the graphic.
86
-
87
- self.points_deg_ut = self.user.planets_degrees + [self.user.houses_degree_ut[0],
88
- self.user.houses_degree_ut[9], self.user.houses_degree_ut[6],
89
- self.user.houses_degree_ut[3]]
90
-
91
- # Make a list of the relative degrees of the points in the graphic.
92
-
93
- self.points_deg = []
94
- for planet in self.user.planets_list:
95
- self.points_deg.append(planet["position"])
96
-
97
- self.points_deg = self.points_deg + [
98
- self.user.houses_list[0]["position"],
99
- self.user.houses_list[9]["position"],
100
- self.user.houses_list[6]["position"],
101
- self.user.houses_list[3]["position"]
102
- ]
103
-
104
- # Make list of the poits sign.
105
-
106
- self.points_sign = []
107
-
108
- for planet in self.user.planets_list:
109
- self.points_sign.append(planet["sign_num"])
110
-
111
- self.points_sign = self.points_sign + [
112
- self.user.houses_list[0]["sign_num"],
113
- self.user.houses_list[9]["sign_num"],
114
- self.user.houses_list[6]["sign_num"],
115
- self.user.houses_list[3]["sign_num"]
116
- ]
117
-
118
- # Make a list of poits if they are retrograde or not.
119
-
120
- self.points_retrograde = []
121
-
122
- for planet in self.user.planets_list:
123
- self.points_retrograde.append(planet["retrograde"])
124
-
125
- self.points_retrograde = self.points_retrograde + [
126
- False,
127
- False,
128
- False,
129
- False
130
- ]
131
-
132
- # Makes the sign number list.
133
-
134
- self.houses_sign_graph = []
135
- for h in self.user.houses_list:
136
- self.houses_sign_graph.append(h['sign_num'])
137
-
138
- if self.chart_type == "Natal":
139
- natal_aspects_instance = NatalAspects(
140
- self.user, new_settings_file=self.settings_file)
141
- self.aspects_list = natal_aspects_instance.get_relevant_aspects()
142
-
143
- if (self.chart_type == "Transit" or self.chart_type == "Composite"): # TODO: If not second should exit
144
-
145
- if not second_obj:
146
- raise KerykeionException(
147
- "Second object is required for Transit or Composite charts.")
148
-
149
- # Kerykeion instance
150
- self.t_user = second_obj
151
-
152
- if not hasattr(self.t_user, "sun"):
153
- print(f"Generating kerykeion object for {self.t_user.name}...")
154
- self.t_user.__get_all()
155
-
156
- # Make a list for the absolute degrees of the points of the graphic.
157
-
158
- self.t_points_deg_ut = self.t_user.planets_degrees + [
159
- self.t_user.houses_degree_ut[0],
160
- self.t_user.houses_degree_ut[9],
161
- self.t_user.houses_degree_ut[6],
162
- self.t_user.houses_degree_ut[3]
163
- ]
164
-
165
- # Make a list of the relative degrees of the points in the graphic.
166
-
167
- self.t_points_deg = []
168
- for planet in self.t_user.planets_list:
169
- self.t_points_deg.append(planet["position"])
170
-
171
- self.t_points_deg = self.t_points_deg + [
172
- self.t_user.houses_list[0]["position"],
173
- self.t_user.houses_list[9]["position"],
174
- self.t_user.houses_list[6]["position"],
175
- self.t_user.houses_list[3]["position"]
176
- ]
177
-
178
- # Make list of the poits sign.
179
-
180
- self.t_points_sign = []
181
-
182
- for planet in self.t_user.planets_list:
183
- self.t_points_sign.append(planet["sign_num"])
184
-
185
- self.t_points_sign = self.t_points_sign + [
186
- self.t_user.houses_list[0]["sign_num"],
187
- self.t_user.houses_list[9]["sign_num"],
188
- self.t_user.houses_list[6]["sign_num"],
189
- self.t_user.houses_list[3]["sign_num"]
190
- ]
191
-
192
- # Make a list of poits if they are retrograde or not.
193
-
194
- self.t_points_retrograde = []
195
-
196
- for planet in self.t_user.planets_list:
197
- self.t_points_retrograde.append(planet["retrograde"])
198
-
199
- self.t_points_retrograde = self.t_points_retrograde + [False,
200
- False, False, False]
201
-
202
- self.t_houses_sign_graph = []
203
- for h in self.t_user.houses_list:
204
- self.t_houses_sign_graph.append(h['sign_num'])
205
-
206
- # screen size
207
- if self.chart_type == "Natal":
208
- self.screen_width = 772.2
209
- else:
210
- self.screen_width = 1200
211
- self.screen_height = 772.2
212
-
213
- # check for home
214
- self.home_location = self.user.city
215
- self.home_geolat = self.user.lat
216
- self.home_geolon = self.user.lng
217
- self.home_countrycode = self.user.nation
218
- self.home_timezonestr = self.user.tz_str
219
-
220
- print(f'{self.user.name} birth location: {self.home_location}, {self.home_geolat}, {self.home_geolon}')
221
-
222
- # default location
223
- self.location = self.home_location
224
- self.geolat = float(self.home_geolat)
225
- self.geolon = float(self.home_geolon)
226
- self.countrycode = self.home_countrycode
227
- self.timezonestr = self.home_timezonestr
228
-
229
- # current datetime
230
- now = datetime.now()
231
-
232
- # aware datetime object
233
- dt_input = datetime(
234
- now.year, now.month, now.day, now.hour, now.minute, now.second)
235
- dt = pytz.timezone(self.timezonestr).localize(dt_input)
236
-
237
- # naive utc datetime object
238
- dt_utc = dt.replace(tzinfo=None) - dt.utcoffset()
239
-
240
- # Default
241
- self.name = self.user.name
242
- self.charttype = self.chart_type
243
- self.year = self.user.utc.year
244
- self.month = self.user.utc.month
245
- self.day = self.user.utc.day
246
- self.hour = self.user.utc.hour + self.user.utc.minute/100
247
- self.timezone = self.offsetToTz(dt.utcoffset())
248
- self.altitude = 25
249
- self.geonameid = None
250
-
251
- # Transit
252
-
253
- if self.chart_type == "Transit":
254
- self.t_geolon = self.geolon
255
- self.t_geolat = self.geolat
256
- self.t_altitude = self.altitude
257
- self.t_name = self.language_settings['transit_name']
258
- self.t_year = dt_utc.year
259
- self.t_month = dt_utc.month
260
- self.t_day = dt_utc.day
261
- self.t_hour = self.decHourJoin(
262
- dt_utc.hour, dt_utc.minute, dt_utc.second)
263
- self.t_timezone = self.offsetToTz(dt.utcoffset())
264
- self.t_altitude = 25
265
- self.t_geonameid = None
266
-
267
- # configuration
268
- # ZOOM 1 = 100%
269
- self.zoom = 1
270
-
271
- # 12 zodiacs
272
- self.zodiac = ['aries', 'taurus', 'gemini', 'cancer', 'leo', 'virgo',
273
- 'libra', 'scorpio', 'sagittarius', 'capricorn', 'aquarius', 'pisces']
274
- self.zodiac_short = ['Ari', 'Tau', 'Gem', 'Cnc', 'Leo',
275
- 'Vir', 'Lib', 'Sco', 'Sgr', 'Cap', 'Aqr', 'Psc']
276
- self.zodiac_color = ['#482900', '#6b3d00', '#5995e7', '#2b4972', '#c54100',
277
- '#2b286f', '#69acf1', '#ffd237', '#ff7200', '#863c00', '#4f0377', '#6cbfff']
278
- self.zodiac_element = ['fire', 'earth', 'air', 'water', 'fire',
279
- 'earth', 'air', 'water', 'fire', 'earth', 'air', 'water']
280
-
281
- # get color configuration
282
-
283
- # Immediately generate template.
284
- self.template = self.makeTemplate()
285
-
286
- def parse_json_settings(self, settings_file, lang: str):
287
- """
288
- Parse the settings file.
289
- """
290
- with open(settings_file, 'r', encoding="utf-8", errors='ignore') as f:
291
- settings = json.load(f)
292
-
293
- self.language_settings = settings['language_settings'].get(
294
- lang, "EN")
295
- self.colors_settings = settings['colors']
296
- self.planets_settings = settings['planets']
297
- self.aspects_settings = settings['aspects']
298
-
299
- def makeTemplate(self, printing=None):
300
- # self.chart_type = "Transit"
301
- # empty element points
302
- self.fire = 0.0
303
- self.earth = 0.0
304
- self.air = 0.0
305
- self.water = 0.0
306
-
307
- # Transit module data
308
- if self.chart_type == "Transit" or self.chart_type == "Composite":
309
- # grab transiting module data
310
-
311
- self.t_planets_sign = self.t_points_sign
312
- self.t_planets_degree = self.t_points_deg
313
- self.t_planets_degree_ut = self.t_points_deg_ut
314
- self.t_planets_retrograde = self.t_points_retrograde
315
- self.t_houses_list = self.t_user.houses_list
316
- self.t_houses_sign = self.t_houses_sign_graph
317
- self.t_houses_degree_ut = self.t_user.houses_degree_ut
318
-
319
- # grab normal module data
320
- self.planets_sign = self.points_sign
321
- self.planets_degree = self.points_deg
322
- self.planets_degree_ut = self.points_deg_ut
323
- self.planets_retrograde = self.points_retrograde
324
- self.houses_list = self.user.houses_list
325
- self.houses_sign = self.houses_sign_graph
326
- self.houses_degree_ut = self.user.houses_degree_ut
327
- self.lunar_phase = self.user.lunar_phase
328
- #
329
-
330
- # width and height from screen
331
- ratio = float(self.screen_width) / float(self.screen_height)
332
- if ratio < 1.3: # 1280x1024
333
- wm_off = 130
334
- else: # 1024x768, 800x600, 1280x800, 1680x1050
335
- wm_off = 100
336
-
337
- # Viewbox and sizing
338
- svgHeight = "100%" # self.screen_height-wm_off
339
- svgWidth = "100%" #  self.screen_width-5.0
340
- # svgHeight=self.screen_height-wm_off
341
- # svgWidth=(770.0*svgHeight)/540.0
342
- # svgWidth=float(self.screen_width)-25.0
343
- rotate = "0"
344
- translate = "0"
345
- # Defoult:
346
- # viewbox = '0 0 772.2 546.0' #297mm * 2.6 + 210mm * 2.6
347
- if self.chart_type == "Natal":
348
- viewbox = '0 0 772.2 546.0' # 297mm * 2.6 + 210mm * 2.6
349
- else:
350
- viewbox = '0 0 1000 546.0'
351
-
352
- # template dictionary
353
- td = dict()
354
- r = 240
355
- self.c1 = 0
356
- self.c2 = 36
357
- self.c3 = 120
358
-
359
- # transit
360
- if self.chart_type == "Transit" or self.chart_type == "Composite":
361
- td['transitRing'] = self.transitRing(r)
362
- td['degreeRing'] = self.degreeTransitRing(r)
363
- # circles
364
- td['c1'] = 'cx="' + str(r) + '" cy="' + \
365
- str(r) + '" r="' + str(r-36) + '"'
366
- td['c1style'] = 'fill: none; stroke: %s; stroke-width: 1px; stroke-opacity:.4;' % (
367
- self.colors_settings['zodiac_transit_ring_2'])
368
- td['c2'] = 'cx="' + str(r) + '" cy="' + \
369
- str(r) + '" r="' + str(r-72) + '"'
370
- td['c2style'] = 'fill: %s; fill-opacity:.4; stroke: %s; stroke-opacity:.4; stroke-width: 1px' % (
371
- self.colors_settings['paper_1'], self.colors_settings['zodiac_transit_ring_1'])
372
- td['c3'] = 'cx="' + str(r) + '" cy="' + \
373
- str(r) + '" r="' + str(r-160) + '"'
374
- td['c3style'] = 'fill: %s; fill-opacity:.8; stroke: %s; stroke-width: 1px' % (
375
- self.colors_settings['paper_1'], self.colors_settings['zodiac_transit_ring_0'])
376
- td['makeAspects'] = self.makeAspectsTransit(r, (r-160))
377
- td['makeAspectGrid'] = self.makeAspectTransitGrid(r)
378
- td['makePatterns'] = ''
379
- td['chart_width'] = self.full_width
380
- else:
381
- td['transitRing'] = ""
382
- td['degreeRing'] = self.degreeRing(r)
383
- # circles
384
- td['c1'] = 'cx="' + str(r) + '" cy="' + \
385
- str(r) + '" r="' + str(r-self.c1) + '"'
386
- td['c1style'] = 'fill: none; stroke: %s; stroke-width: 1px; ' % (
387
- self.colors_settings['zodiac_radix_ring_2'])
388
- td['c2'] = 'cx="' + str(r) + '" cy="' + \
389
- str(r) + '" r="' + str(r-self.c2) + '"'
390
- td['c2style'] = 'fill: %s; fill-opacity:.2; stroke: %s; stroke-opacity:.4; stroke-width: 1px' % (
391
- self.colors_settings['paper_1'], self.colors_settings['zodiac_radix_ring_1'])
392
- td['c3'] = 'cx="' + str(r) + '" cy="' + \
393
- str(r) + '" r="' + str(r-self.c3) + '"'
394
- td['c3style'] = 'fill: %s; fill-opacity:.8; stroke: %s; stroke-width: 1px' % (
395
- self.colors_settings['paper_1'], self.colors_settings['zodiac_radix_ring_0'])
396
- td['makeAspects'] = self.makeAspects(r, (r-self.c3))
397
- td['makeAspectGrid'] = self.makeAspectGrid(r)
398
- td['makePatterns'] = self.makePatterns()
399
- td['chart_width'] = self.natal_width
400
-
401
- td['circleX'] = str(0)
402
- td['circleY'] = str(0)
403
- td['svgWidth'] = str(svgWidth)
404
- td['svgHeight'] = str(svgHeight)
405
- td['viewbox'] = viewbox
406
- if self.chart_type == "Composite":
407
- td['stringTitle'] = f"{self.name} {self.language_settings['&']} {self.t_user.name}"
408
- elif self.chart_type == "Transit":
409
- td['stringTitle'] = f"{self.language_settings['transits']} {self.t_user.day}/{self.t_user.month}/{self.t_user.year}"
410
- else:
411
- td['stringTitle'] = self.name
412
-
413
- # Tipo di carta
414
- if self.chart_type == "Composite" or self.name == "Transit":
415
- td['stringName'] = f"{self.name}:"
416
- else:
417
- td['stringName'] = f'{self.language_settings["info"]}:'
418
-
419
- # bottom left
420
-
421
- td['bottomLeft1'] = ''
422
- td['bottomLeft2'] = ''
423
- td['bottomLeft3'] = f'{self.language_settings.get("lunar_phase", "Lunar Phase")}: {self.language_settings.get("day", "Day")} {self.lunar_phase.get("moon_phase", "")}'
424
- td['bottomLeft4'] = ''
425
-
426
- # lunar phase
427
- deg = self.lunar_phase['degrees_between_s_m']
428
-
429
- if(deg < 90.0):
430
- maxr = deg
431
- if(deg > 80.0):
432
- maxr = maxr*maxr
433
- lfcx = 20.0+(deg/90.0)*(maxr+10.0)
434
- lfr = 10.0+(deg/90.0)*maxr
435
- lffg, lfbg = self.colors_settings["lunar_phase_0"], self.colors_settings["lunar_phase_1"]
436
-
437
- elif(deg < 180.0):
438
- maxr = 180.0-deg
439
- if(deg < 100.0):
440
- maxr = maxr*maxr
441
- lfcx = 20.0+((deg-90.0)/90.0*(maxr+10.0))-(maxr+10.0)
442
- lfr = 10.0+maxr-((deg-90.0)/90.0*maxr)
443
- lffg, lfbg = self.colors_settings["lunar_phase_1"], self.colors_settings["lunar_phase_0"]
444
-
445
- elif(deg < 270.0):
446
- maxr = deg-180.0
447
- if(deg > 260.0):
448
- maxr = maxr*maxr
449
- lfcx = 20.0+((deg-180.0)/90.0*(maxr+10.0))
450
- lfr = 10.0+((deg-180.0)/90.0*maxr)
451
- lffg, lfbg = self.colors_settings["lunar_phase_1"], self.colors_settings["lunar_phase_0"]
452
-
453
- elif(deg < 361):
454
- maxr = 360.0-deg
455
- if(deg < 280.0):
456
- maxr = maxr*maxr
457
- lfcx = 20.0+((deg-270.0)/90.0*(maxr+10.0))-(maxr+10.0)
458
- lfr = 10.0+maxr-((deg-270.0)/90.0*maxr)
459
- lffg, lfbg = self.colors_settings["lunar_phase_0"], self.colors_settings["lunar_phase_1"]
460
-
461
- td['lunar_phase_fg'] = lffg
462
- td['lunar_phase_bg'] = lfbg
463
- td['lunar_phase_cx'] = lfcx
464
- td['lunar_phase_r'] = lfr
465
- td['lunar_phase_outline'] = self.colors_settings["lunar_phase_2"]
466
-
467
- # rotation based on latitude
468
- td['lunar_phase_rotate'] = (-90.0-self.geolat)
469
-
470
- # stringlocation
471
- if len(self.location) > 35:
472
- split = self.location.split(",")
473
- if len(split) > 1:
474
- td['stringLocation'] = split[0]+", "+split[-1]
475
- if len(td['stringLocation']) > 35:
476
- td['stringLocation'] = td['stringLocation'][:35]+"..."
477
- else:
478
- td['stringLocation'] = self.location[:35]+"..."
479
- else:
480
- td['stringLocation'] = self.location
481
-
482
- # td['stringDateTime']= str(self.user.year)+'-%(#1)02d-%(#2)02d %(#3)02d:%(#4)02d:%(#5)02d' % {'#1':self.user.month,'#2':self.user.day,'#3':self.user.hour,'#4':self.user.minute,'#5':00} + self.decTzStr(self.timezone)
483
- td['stringDateTime'] = f'{self.user.year}-{self.user.month}-{self.user.day} {self.user.hour:02d}:{self.user.minute:02d}'
484
-
485
- if self.chart_type == "Composite":
486
- td['stringLat'] = f'{self.t_user.name}: '
487
- td['stringLon'] = self.t_user.city
488
- 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}'
489
-
490
- else:
491
- td['stringLat'] = "%s: %s" % (
492
- self.language_settings['latitude'], self.lat2str(self.geolat))
493
- td['stringLon'] = "%s: %s" % (
494
- self.language_settings['longitude'], self.lon2str(self.geolon))
495
- td['stringPosition'] = f"{self.language_settings['type']}: {self.charttype}"
496
-
497
- # paper_color_X
498
- td['paper_color_0'] = self.colors_settings["paper_0"]
499
- td['paper_color_1'] = self.colors_settings["paper_1"]
500
-
501
- # planets_color_X
502
- for i in range(len(self.planets_settings)):
503
- td['planets_color_%s' %
504
- (i)] = self.colors_settings["planet_%s" % (i)]
505
-
506
- # zodiac_color_X
507
- for i in range(12):
508
- td['zodiac_color_%s' %
509
- (i)] = self.colors_settings["zodiac_icon_%s" % (i)]
510
-
511
- # orb_color_X
512
- for i in range(len(self.aspects_settings)):
513
- td['orb_color_%s' % (self.aspects_settings[i]['degree'])] = self.colors_settings["aspect_%s" % (
514
- self.aspects_settings[i]['degree'])]
515
-
516
- # config
517
- td['cfgZoom'] = str(self.zoom)
518
- td['cfgRotate'] = rotate
519
- td['cfgTranslate'] = translate
520
-
521
- # functions
522
- td['makeZodiac'] = self.makeZodiac(r)
523
- td['makeHouses'] = self.makeHouses(r)
524
- td['makePlanets'] = self.makePlanets(r)
525
- td['makeElements'] = self.makeElements(r)
526
- td['makePlanetGrid'] = self.makePlanetGrid()
527
- td['makeHousesGrid'] = self.makeHousesGrid()
528
-
529
- # read template
530
- with open(self.xml_svg, "r", encoding="utf-8", errors='ignore') as output_file:
531
- f = open(self.xml_svg)
532
- template = Template(f.read()).substitute(td)
533
-
534
- # return filename
535
-
536
- return template
537
-
538
- def makeSVG(self):
539
- """Prints out the SVG file in the specifide folder"""
540
-
541
- if not (self.template):
542
- self.template = self.makeTemplate()
543
-
544
- self.chartname = self.output_directory / \
545
- f'{self.name}{self.chart_type}Chart.svg'
546
-
547
- with open(self.chartname, "w", encoding='utf-8', errors='ignore') as output_file:
548
- output_file.write(self.template)
549
-
550
- return print(f"SVG Generated Correctly in: {self.chartname}")
551
-
552
- # draw transit ring
553
- def transitRing(self, r):
554
- out = '<circle cx="%s" cy="%s" r="%s" style="fill: none; stroke: %s; stroke-width: 36px; stroke-opacity: .4;"/>' % (
555
- r, r, r-18, self.colors_settings['paper_1'])
556
- out += '<circle cx="%s" cy="%s" r="%s" style="fill: none; stroke: %s; stroke-width: 1px; stroke-opacity: .6;"/>' % (
557
- r, r, r, self.colors_settings['zodiac_transit_ring_3'])
558
- return out
559
-
560
- # draw degree ring
561
- def degreeRing(self, r):
562
- out = ''
563
- for i in range(72):
564
- offset = float(i*5) - self.houses_degree_ut[6]
565
- if offset < 0:
566
- offset = offset + 360.0
567
- elif offset > 360:
568
- offset = offset - 360.0
569
- x1 = self.sliceToX(0, r-self.c1, offset) + self.c1
570
- y1 = self.sliceToY(0, r-self.c1, offset) + self.c1
571
- x2 = self.sliceToX(0, r+2-self.c1, offset) - 2 + self.c1
572
- y2 = self.sliceToY(0, r+2-self.c1, offset) - 2 + self.c1
573
- out += '<line x1="%s" y1="%s" x2="%s" y2="%s" style="stroke: %s; stroke-width: 1px; stroke-opacity:.9;"/>\n' % (
574
- x1, y1, x2, y2, self.colors_settings['paper_0'])
575
- return out
576
-
577
- def degreeTransitRing(self, r):
578
- out = ''
579
- for i in range(72):
580
- offset = float(i*5) - self.houses_degree_ut[6]
581
- if offset < 0:
582
- offset = offset + 360.0
583
- elif offset > 360:
584
- offset = offset - 360.0
585
- x1 = self.sliceToX(0, r, offset)
586
- y1 = self.sliceToY(0, r, offset)
587
- x2 = self.sliceToX(0, r+2, offset) - 2
588
- y2 = self.sliceToY(0, r+2, offset) - 2
589
- out += '<line x1="%s" y1="%s" x2="%s" y2="%s" style="stroke: #F00; stroke-width: 1px; stroke-opacity:.9;"/>\n' % (
590
- x1, y1, x2, y2)
591
- return out
592
-
593
- # floating latitude an longitude to string
594
- def lat2str(self, coord):
595
- sign = self.language_settings["north"]
596
- if coord < 0.0:
597
- sign = self.language_settings["south"]
598
- coord = abs(coord)
599
- deg = int(coord)
600
- min = int((float(coord) - deg) * 60)
601
- sec = int(round(float(((float(coord) - deg) * 60) - min) * 60.0))
602
- return "%s°%s'%s\" %s" % (deg, min, sec, sign)
603
-
604
- def lon2str(self, coord):
605
- sign = self.language_settings["east"]
606
- if coord < 0.0:
607
- sign = self.language_settings["west"]
608
- coord = abs(coord)
609
- deg = int(coord)
610
- min = int((float(coord) - deg) * 60)
611
- sec = int(round(float(((float(coord) - deg) * 60) - min) * 60.0))
612
- return "%s°%s'%s\" %s" % (deg, min, sec, sign)
613
-
614
- # decimal hour to minutes and seconds
615
- def decHour(self, input):
616
- hours = int(input)
617
- mands = (input-hours)*60.0
618
- mands = round(mands, 5)
619
- minutes = int(mands)
620
- seconds = int(round((mands-minutes)*60))
621
- return [hours, minutes, seconds]
622
-
623
- # join hour, minutes, seconds, timezone integere to hour float
624
- def decHourJoin(self, inH, inM, inS):
625
- dh = float(inH)
626
- dm = float(inM)/60
627
- ds = float(inS)/3600
628
- output = dh + dm + ds
629
- return output
630
-
631
- # Datetime offset to float in hours
632
- def offsetToTz(self, dtoffset):
633
- dh = float(dtoffset.days * 24)
634
- sh = float(dtoffset.seconds / 3600.0)
635
- output = dh + sh
636
- return output
637
-
638
- # decimal timezone string
639
- def decTzStr(self, tz):
640
- if tz > 0:
641
- h = int(tz)
642
- m = int((float(tz)-float(h))*float(60))
643
- return " [+%(#1)02d:%(#2)02d]" % {'#1': h, '#2': m}
644
- else:
645
- h = int(tz)
646
- m = int((float(tz)-float(h))*float(60))/-1
647
- return " [-%(#1)02d:%(#2)02d]" % {'#1': h/-1, '#2': m}
648
-
649
- # degree difference
650
- def degreeDiff(self, a, b):
651
- out = float()
652
- if a > b:
653
- out = a - b
654
- if a < b:
655
- out = b-a
656
- if out > 180.0:
657
- out = 360.0-out
658
- return out
659
-
660
- # decimal to degrees (a°b'c")
661
- def dec2deg(self, dec, type="3"):
662
- dec = float(dec)
663
- a = int(dec)
664
- a_new = (dec-float(a)) * 60.0
665
- b_rounded = int(round(a_new))
666
- b = int(a_new)
667
- c = int(round((a_new-float(b))*60.0))
668
- if type == "3":
669
- out = '%(#1)02d&#176;%(#2)02d&#39;%(#3)02d&#34;' % {
670
- '#1': a, '#2': b, '#3': c}
671
- elif type == "2":
672
- out = '%(#1)02d&#176;%(#2)02d&#39;' % {'#1': a, '#2': b_rounded}
673
- elif type == "1":
674
- out = '%(#1)02d&#176;' % {'#1': a}
675
- return str(out)
676
-
677
- # draw svg aspects: ring, aspect ring, degreeA degreeB
678
- def drawAspect(self, r, ar, degA, degB, color):
679
- offset = (int(self.houses_degree_ut[6]) / -1) + int(degA)
680
- x1 = self.sliceToX(0, ar, offset) + (r-ar)
681
- y1 = self.sliceToY(0, ar, offset) + (r-ar)
682
- offset = (int(self.houses_degree_ut[6]) / -1) + int(degB)
683
- x2 = self.sliceToX(0, ar, offset) + (r-ar)
684
- y2 = self.sliceToY(0, ar, offset) + (r-ar)
685
- out = ' <line x1="'+str(x1)+'" y1="'+str(y1)+'" x2="'+str(x2)+'" y2="'+str(
686
- y2)+'" style="stroke: '+color+'; stroke-width: 1; stroke-opacity: .9;"/>\n'
687
- return out
688
-
689
- def sliceToX(self, slice, r, offset):
690
- plus = (math.pi * offset) / 180
691
- radial = ((math.pi/6) * slice) + plus
692
- return r * (math.cos(radial)+1)
693
-
694
- def sliceToY(self, slice, r, offset):
695
- plus = (math.pi * offset) / 180
696
- radial = ((math.pi/6) * slice) + plus
697
- return r * ((math.sin(radial)/-1)+1)
698
-
699
- def zodiacSlice(self, num, r, style, type):
700
- # pie slices
701
- offset = 360 - self.houses_degree_ut[6]
702
- # check transit
703
- if self.chart_type == "Transit" or self.chart_type == "Composite":
704
- dropin = 0
705
- else:
706
- dropin = self.c1
707
- slice = '<path d="M' + str(r) + ',' + str(r) + ' L' + str(dropin + self.sliceToX(num, r-dropin, offset)) + ',' + str(dropin + self.sliceToY(num, r-dropin, offset)) + ' A' + str(
708
- r-dropin) + ',' + str(r-dropin) + ' 0 0,0 ' + str(dropin + self.sliceToX(num+1, r-dropin, offset)) + ',' + str(dropin + self.sliceToY(num+1, r-dropin, offset)) + ' z" style="' + style + '"/>'
709
- # symbols
710
- offset = offset + 15
711
- # check transit
712
- if self.chart_type == "Transit" or self.chart_type == "Composite":
713
- dropin = 54
714
- else:
715
- dropin = 18+self.c1
716
- sign = '<g transform="translate(-16,-16)"><use x="' + str(dropin + self.sliceToX(num, r-dropin, offset)) + '" y="' + str(
717
- dropin + self.sliceToY(num, r-dropin, offset)) + '" xlink:href="#' + type + '" /></g>\n'
718
- return slice + '\n' + sign
719
-
720
- def makeZodiac(self, r):
721
- output = ""
722
- for i in range(len(self.zodiac)):
723
- output = output + self.zodiacSlice(i, r, "fill:" + self.colors_settings["zodiac_bg_%s" % (
724
- i)] + "; fill-opacity: 0.5;", self.zodiac[i]) + '\n'
725
- return output
726
-
727
- def makeHouses(self, r):
728
- path = ""
729
-
730
- xr = 12
731
- for i in range(xr):
732
- # check transit
733
- if self.chart_type == "Transit" or self.chart_type == "Composite":
734
- dropin = 160
735
- roff = 72
736
- t_roff = 36
737
- else:
738
- dropin = self.c3
739
- roff = self.c1
740
-
741
- # offset is negative desc houses_degree_ut[6]
742
- offset = (
743
- int(self.houses_degree_ut[int(xr/2)]) / -1) + int(self.houses_degree_ut[i])
744
- x1 = self.sliceToX(0, (r-dropin), offset) + dropin
745
- y1 = self.sliceToY(0, (r-dropin), offset) + dropin
746
- x2 = self.sliceToX(0, r-roff, offset) + roff
747
- y2 = self.sliceToY(0, r-roff, offset) + roff
748
-
749
- if i < (xr-1):
750
- text_offset = offset + \
751
- int(self.degreeDiff(self.houses_degree_ut[(
752
- i+1)], self.houses_degree_ut[i]) / 2)
753
- else:
754
- text_offset = offset + \
755
- int(self.degreeDiff(
756
- self.houses_degree_ut[0], self.houses_degree_ut[(xr-1)]) / 2)
757
-
758
- # mc, asc, dsc, ic
759
- if i == 0:
760
- linecolor = self.planets_settings[12]['color']
761
- elif i == 9:
762
- linecolor = self.planets_settings[13]['color']
763
- elif i == 6:
764
- linecolor = self.planets_settings[14]['color']
765
- elif i == 3:
766
- linecolor = self.planets_settings[15]['color']
767
- else:
768
- linecolor = self.colors_settings['houses_radix_line']
769
-
770
- # Transit houses lines.
771
- if self.chart_type == "Transit" or self.chart_type == "Composite":
772
-
773
- # Degrees for point zero.
774
-
775
- zeropoint = 360 - self.houses_degree_ut[6]
776
- t_offset = zeropoint + self.t_houses_degree_ut[i]
777
- if t_offset > 360:
778
- t_offset = t_offset - 360
779
- t_x1 = self.sliceToX(0, (r-t_roff), t_offset) + t_roff
780
- t_y1 = self.sliceToY(0, (r-t_roff), t_offset) + t_roff
781
- t_x2 = self.sliceToX(0, r, t_offset)
782
- t_y2 = self.sliceToY(0, r, t_offset)
783
- if i < 11:
784
- t_text_offset = t_offset + \
785
- int(self.degreeDiff(self.t_houses_degree_ut[(
786
- i+1)], self.t_houses_degree_ut[i]) / 2)
787
- else:
788
- t_text_offset = t_offset + \
789
- int(self.degreeDiff(
790
- self.t_houses_degree_ut[0], self.t_houses_degree_ut[11]) / 2)
791
- # linecolor
792
- if i == 0 or i == 9 or i == 6 or i == 3:
793
- t_linecolor = linecolor
794
- else:
795
- t_linecolor = self.colors_settings['houses_transit_line']
796
- xtext = self.sliceToX(0, (r-8), t_text_offset) + 8
797
- ytext = self.sliceToY(0, (r-8), t_text_offset) + 8
798
-
799
- if self.chart_type == "Transit":
800
- path = path + '<text style="fill: #00f; fill-opacity: 0; font-size: 14px"><tspan x="' + \
801
- str(xtext-3)+'" y="'+str(ytext+3) + \
802
- '">'+str(i+1)+'</tspan></text>\n'
803
- path = path + '<line x1="'+str(t_x1)+'" y1="'+str(t_y1)+'" x2="'+str(t_x2)+'" y2="'+str(
804
- t_y2)+'" style="stroke: '+t_linecolor+'; stroke-width: 2px; stroke-opacity:0;"/>\n'
805
-
806
- else:
807
- path = path + '<text style="fill: #00f; fill-opacity: .4; font-size: 14px"><tspan x="' + \
808
- str(xtext-3)+'" y="'+str(ytext+3) + \
809
- '">'+str(i+1)+'</tspan></text>\n'
810
- path = path + '<line x1="'+str(t_x1)+'" y1="'+str(t_y1)+'" x2="'+str(t_x2)+'" y2="'+str(
811
- t_y2)+'" style="stroke: '+t_linecolor+'; stroke-width: 2px; stroke-opacity:.3;"/>\n'
812
-
813
- # if transit
814
- if self.chart_type == "Transit" or self.chart_type == "Composite":
815
- dropin = 84
816
-
817
- dropin = 48
818
-
819
- xtext = self.sliceToX(
820
- 0, (r-dropin), text_offset) + dropin # was 132
821
- ytext = self.sliceToY(
822
- 0, (r-dropin), text_offset) + dropin # was 132
823
- path = path + '<line x1="'+str(x1)+'" y1="'+str(y1)+'" x2="'+str(x2)+'" y2="'+str(
824
- y2)+'" style="stroke: '+linecolor+'; stroke-width: 2px; stroke-dasharray:3,2; stroke-opacity:.4;"/>\n'
825
- path = path + '<text style="fill: #f00; fill-opacity: .6; font-size: 14px"><tspan x="' + \
826
- str(xtext-3)+'" y="'+str(ytext+3) + \
827
- '">'+str(i+1)+'</tspan></text>\n'
828
-
829
- return path
830
-
831
- def makePlanets(self, r):
832
-
833
- planets_degut = {}
834
-
835
- diff = range(len(self.planets_settings))
836
- for i in range(len(self.planets_settings)):
837
- if self.planets_settings[i]['visible'] == 1:
838
- # list of planets sorted by degree
839
- planets_degut[self.planets_degree_ut[i]] = i
840
-
841
- # element: get extra points if planet is in own zodiac
842
- pz = self.planets_settings[i]['zodiac_relation']
843
- cz = self.planets_sign[i]
844
- extrapoints = 0
845
- if pz != -1:
846
- for e in range(len(pz.split(','))):
847
- if int(pz.split(',')[e]) == int(cz):
848
- extrapoints = 10
849
-
850
- # calculate element points for all planets
851
- ele = self.zodiac_element[self.planets_sign[i]]
852
- if ele == "fire":
853
- self.fire = self.fire + \
854
- self.planets_settings[i]['element_points'] + extrapoints
855
- elif ele == "earth":
856
- self.earth = self.earth + \
857
- self.planets_settings[i]['element_points'] + extrapoints
858
- elif ele == "air":
859
- self.air = self.air + \
860
- self.planets_settings[i]['element_points'] + extrapoints
861
- elif ele == "water":
862
- self.water = self.water + \
863
- self.planets_settings[i]['element_points'] + extrapoints
864
-
865
- output = ""
866
- keys = list(planets_degut.keys())
867
- keys.sort()
868
- switch = 0
869
-
870
- planets_degrouped = {}
871
- groups = []
872
- planets_by_pos = list(range(len(planets_degut)))
873
- planet_drange = 3.4
874
- # get groups closely together
875
- group_open = False
876
- for e in range(len(keys)):
877
- i = planets_degut[keys[e]]
878
- # get distances between planets
879
- if e == 0:
880
- prev = self.planets_degree_ut[planets_degut[keys[-1]]]
881
- next = self.planets_degree_ut[planets_degut[keys[1]]]
882
- elif e == (len(keys)-1):
883
- prev = self.planets_degree_ut[planets_degut[keys[e-1]]]
884
- next = self.planets_degree_ut[planets_degut[keys[0]]]
885
- else:
886
- prev = self.planets_degree_ut[planets_degut[keys[e-1]]]
887
- next = self.planets_degree_ut[planets_degut[keys[e+1]]]
888
- diffa = self.degreeDiff(prev, self.planets_degree_ut[i])
889
- diffb = self.degreeDiff(next, self.planets_degree_ut[i])
890
- planets_by_pos[e] = [i, diffa, diffb]
891
- # print "%s %s %s" % (self.planets_settings[i]['label'],diffa,diffb)
892
- if (diffb < planet_drange):
893
- if group_open:
894
- groups[-1].append([e, diffa, diffb,
895
- self.planets_settings[planets_degut[keys[e]]]["label"]])
896
- else:
897
- group_open = True
898
- groups.append([])
899
- groups[-1].append([e, diffa, diffb,
900
- self.planets_settings[planets_degut[keys[e]]]["label"]])
901
- else:
902
- if group_open:
903
- groups[-1].append([e, diffa, diffb,
904
- self.planets_settings[planets_degut[keys[e]]]["label"]])
905
- group_open = False
906
-
907
- def zero(x): return 0
908
- planets_delta = list(map(zero, range(len(self.planets_settings))))
909
-
910
- # print groups
911
- # print planets_by_pos
912
- for a in range(len(groups)):
913
- # Two grouped planets
914
- if len(groups[a]) == 2:
915
- next_to_a = groups[a][0][0]-1
916
- if groups[a][1][0] == (len(planets_by_pos)-1):
917
- next_to_b = 0
918
- else:
919
- next_to_b = groups[a][1][0]+1
920
- # if both planets have room
921
- if (groups[a][0][1] > (2*planet_drange)) & (groups[a][1][2] > (2*planet_drange)):
922
- planets_delta[groups[a][0][0]] = - \
923
- (planet_drange-groups[a][0][2])/2
924
- planets_delta[groups[a][1][0]] = + \
925
- (planet_drange-groups[a][0][2])/2
926
- # if planet a has room
927
- elif (groups[a][0][1] > (2*planet_drange)):
928
- planets_delta[groups[a][0][0]] = -planet_drange
929
- # if planet b has room
930
- elif (groups[a][1][2] > (2*planet_drange)):
931
- planets_delta[groups[a][1][0]] = +planet_drange
932
-
933
- # if planets next to a and b have room move them
934
- elif (planets_by_pos[next_to_a][1] > (2.4*planet_drange)) & (planets_by_pos[next_to_b][2] > (2.4*planet_drange)):
935
- planets_delta[(next_to_a)] = (
936
- groups[a][0][1]-planet_drange*2)
937
- planets_delta[groups[a][0][0]] = -planet_drange*.5
938
- planets_delta[next_to_b] = - \
939
- (groups[a][1][2]-planet_drange*2)
940
- planets_delta[groups[a][1][0]] = +planet_drange*.5
941
-
942
- # if planet next to a has room move them
943
- elif (planets_by_pos[next_to_a][1] > (2*planet_drange)):
944
- planets_delta[(next_to_a)] = (
945
- groups[a][0][1]-planet_drange*2.5)
946
- planets_delta[groups[a][0][0]] = -planet_drange*1.2
947
-
948
- # if planet next to b has room move them
949
- elif (planets_by_pos[next_to_b][2] > (2*planet_drange)):
950
- planets_delta[next_to_b] = - \
951
- (groups[a][1][2]-planet_drange*2.5)
952
- planets_delta[groups[a][1][0]] = +planet_drange*1.2
953
-
954
- # Three grouped planets or more
955
- xl = len(groups[a])
956
- if xl >= 3:
957
-
958
- available = groups[a][0][1]
959
- for f in range(xl):
960
- available += groups[a][f][2]
961
- need = (3*planet_drange)+(1.2*(xl-1)*planet_drange)
962
- leftover = available - need
963
- xa = groups[a][0][1]
964
- xb = groups[a][(xl-1)][2]
965
-
966
- # center
967
- if (xa > (need*.5)) & (xb > (need*.5)):
968
- startA = xa - (need*.5)
969
- # position relative to next planets
970
- else:
971
- startA = (leftover/(xa+xb))*xa
972
- startB = (leftover/(xa+xb))*xb
973
-
974
- if available > need:
975
- planets_delta[groups[a][0][0]] = startA - \
976
- groups[a][0][1]+(1.5*planet_drange)
977
- for f in range(xl-1):
978
- planets_delta[groups[a][(
979
- f+1)][0]] = 1.2*planet_drange+planets_delta[groups[a][f][0]]-groups[a][f][2]
980
-
981
- for e in range(len(keys)):
982
- i = planets_degut[keys[e]]
983
-
984
- # coordinates
985
- if self.chart_type == "Transit" or self.chart_type == "Composite":
986
- if 22 < i < 27:
987
- rplanet = 76
988
- elif switch == 1:
989
- rplanet = 110
990
- switch = 0
991
- else:
992
- rplanet = 130
993
- switch = 1
994
- else:
995
- # if 22 < i < 27 it is asc,mc,dsc,ic (angles of chart)
996
- # put on special line (rplanet is range from outer ring)
997
- amin, bmin, cmin = 0, 0, 0
998
-
999
- if 22 < i < 27:
1000
- rplanet = 40-cmin
1001
- elif switch == 1:
1002
- rplanet = 74-amin
1003
- switch = 0
1004
- else:
1005
- rplanet = 94-bmin
1006
- switch = 1
1007
-
1008
- rtext = 45
1009
-
1010
- offset = (int(self.houses_degree_ut[6]) / -1) + \
1011
- int(self.planets_degree_ut[i]+planets_delta[e])
1012
- trueoffset = (
1013
- int(self.houses_degree_ut[6]) / -1) + int(self.planets_degree_ut[i])
1014
-
1015
- planet_x = self.sliceToX(0, (r-rplanet), offset) + rplanet
1016
- planet_y = self.sliceToY(0, (r-rplanet), offset) + rplanet
1017
- if self.chart_type == "Transit" or self.chart_type == "Composite":
1018
- scale = 0.8
1019
-
1020
- scale = 1
1021
- # output planet
1022
- output = output + '<g transform="translate(-'+str(12*scale)+',-'+str(12*scale)+')"><g transform="scale('+str(scale)+')"><use x="' + str(
1023
- planet_x*(1/scale)) + '" y="' + str(planet_y*(1/scale)) + '" xlink:href="#' + self.planets_settings[i]['name'] + '" /></g></g>\n'
1024
-
1025
- # make transit degut and display planets
1026
- if self.chart_type == "Transit" or self.chart_type == "Composite":
1027
- group_offset = {}
1028
- t_planets_degut = {}
1029
- if self.chart_type == "Transit":
1030
- list_range = len(self.planets_settings)-4
1031
- else:
1032
- list_range = len(self.planets_settings)
1033
- for i in range(list_range):
1034
- group_offset[i] = 0
1035
- if self.planets_settings[i]['visible'] == 1:
1036
- t_planets_degut[self.t_planets_degree_ut[i]] = i
1037
- t_keys = list(t_planets_degut.keys())
1038
- t_keys.sort()
1039
-
1040
- # grab closely grouped planets
1041
- groups = []
1042
- in_group = False
1043
- for e in range(len(t_keys)):
1044
- i_a = t_planets_degut[t_keys[e]]
1045
- if e == (len(t_keys)-1):
1046
- i_b = t_planets_degut[t_keys[0]]
1047
- else:
1048
- i_b = t_planets_degut[t_keys[e+1]]
1049
-
1050
- a = self.t_planets_degree_ut[i_a]
1051
- b = self.t_planets_degree_ut[i_b]
1052
- diff = self.degreeDiff(a, b)
1053
- if diff <= 2.5:
1054
- if in_group:
1055
- groups[-1].append(i_b)
1056
- else:
1057
- groups.append([i_a])
1058
- groups[-1].append(i_b)
1059
- in_group = True
1060
- else:
1061
- in_group = False
1062
- # loop groups and set degrees display adjustment
1063
- for i in range(len(groups)):
1064
- if len(groups[i]) == 2:
1065
- group_offset[groups[i][0]] = -1.0
1066
- group_offset[groups[i][1]] = 1.0
1067
- elif len(groups[i]) == 3:
1068
- group_offset[groups[i][0]] = -1.5
1069
- group_offset[groups[i][1]] = 0
1070
- group_offset[groups[i][2]] = 1.5
1071
- elif len(groups[i]) == 4:
1072
- group_offset[groups[i][0]] = -2.0
1073
- group_offset[groups[i][1]] = -1.0
1074
- group_offset[groups[i][2]] = 1.0
1075
- group_offset[groups[i][3]] = 2.0
1076
-
1077
- switch = 0
1078
- for e in range(len(t_keys)):
1079
- i = t_planets_degut[t_keys[e]]
1080
-
1081
- if 22 < i < 27:
1082
- rplanet = 9
1083
- elif switch == 1:
1084
- rplanet = 18
1085
- switch = 0
1086
- else:
1087
- rplanet = 26
1088
- switch = 1
1089
-
1090
- zeropoint = 360 - self.houses_degree_ut[6]
1091
- t_offset = zeropoint + self.t_planets_degree_ut[i]
1092
- if t_offset > 360:
1093
- t_offset = t_offset - 360
1094
- planet_x = self.sliceToX(0, (r-rplanet), t_offset) + rplanet
1095
- planet_y = self.sliceToY(0, (r-rplanet), t_offset) + rplanet
1096
- output = output + '<g transform="translate(-6,-6)"><g transform="scale(0.5)"><use x="' + str(
1097
- planet_x*2) + '" y="' + str(planet_y*2) + '" xlink:href="#' + self.planets_settings[i]['name'] + '" /></g></g>\n'
1098
- # transit planet line
1099
- x1 = self.sliceToX(0, r+3, t_offset) - 3
1100
- y1 = self.sliceToY(0, r+3, t_offset) - 3
1101
- x2 = self.sliceToX(0, r-3, t_offset) + 3
1102
- y2 = self.sliceToY(0, r-3, t_offset) + 3
1103
- output = output + '<line x1="'+str(x1)+'" y1="'+str(y1)+'" x2="'+str(x2)+'" y2="'+str(
1104
- y2)+'" style="stroke: '+self.planets_settings[i]['color']+'; stroke-width: 1px; stroke-opacity:.8;"/>\n'
1105
-
1106
- # transit planet degree text
1107
- rotate = self.houses_degree_ut[0] - self.t_planets_degree_ut[i]
1108
- textanchor = "end"
1109
- t_offset += group_offset[i]
1110
- rtext = -3.0
1111
-
1112
- if -90 > rotate > -270:
1113
- rotate = rotate + 180.0
1114
- textanchor = "start"
1115
- if 270 > rotate > 90:
1116
- rotate = rotate - 180.0
1117
- textanchor = "start"
1118
-
1119
- if textanchor == "end":
1120
- xo = 1
1121
- else:
1122
- xo = -1
1123
- deg_x = self.sliceToX(0, (r-rtext), t_offset + xo) + rtext
1124
- deg_y = self.sliceToY(0, (r-rtext), t_offset + xo) + rtext
1125
- degree = int(t_offset)
1126
- output += '<g transform="translate(%s,%s)">' % (deg_x, deg_y)
1127
- output += '<text transform="rotate(%s)" text-anchor="%s' % (
1128
- rotate, textanchor)
1129
- output += '" style="fill: ' + \
1130
- self.planets_settings[i]['color']+'; font-size: 10px;">' + \
1131
- self.dec2deg(self.t_planets_degree[i], type="1")
1132
- output += '</text></g>\n'
1133
-
1134
- # check transit
1135
- if self.chart_type == "Transit" or self.chart_type == "Composite":
1136
- dropin = 36
1137
- else:
1138
- dropin = 0
1139
-
1140
- # planet line
1141
- x1 = self.sliceToX(0, r-(dropin+3), offset) + (dropin+3)
1142
- y1 = self.sliceToY(0, r-(dropin+3), offset) + (dropin+3)
1143
- x2 = self.sliceToX(0, (r-(dropin-3)), offset) + (dropin-3)
1144
- y2 = self.sliceToY(0, (r-(dropin-3)), offset) + (dropin-3)
1145
- output = output + '<line x1="'+str(x1)+'" y1="'+str(y1)+'" x2="'+str(x2)+'" y2="'+str(
1146
- y2)+'" style="stroke: '+self.planets_settings[i]['color']+'; stroke-width: 2px; stroke-opacity:.6;"/>\n'
1147
-
1148
- # check transit
1149
- if self.chart_type == "Transit" or self.chart_type == "Composite":
1150
- dropin = 160
1151
- else:
1152
- dropin = 120
1153
-
1154
- x1 = self.sliceToX(0, r-dropin, offset) + dropin
1155
- y1 = self.sliceToY(0, r-dropin, offset) + dropin
1156
- x2 = self.sliceToX(0, (r-(dropin-3)), offset) + (dropin-3)
1157
- y2 = self.sliceToY(0, (r-(dropin-3)), offset) + (dropin-3)
1158
- output = output + '<line x1="'+str(x1)+'" y1="'+str(y1)+'" x2="'+str(x2)+'" y2="'+str(
1159
- y2)+'" style="stroke: '+self.planets_settings[i]['color']+'; stroke-width: 2px; stroke-opacity:.6;"/>\n'
1160
-
1161
- return output
1162
-
1163
- def makePatterns(self):
1164
- """
1165
- * Stellium: At least four planets linked together in a series of continuous conjunctions.
1166
- * Grand trine: Three trine aspects together.
1167
- * Grand cross: Two pairs of opposing planets squared to each other.
1168
- * T-Square: Two planets in opposition squared to a third.
1169
- * Yod: Two qunicunxes together joined by a sextile.
1170
- """
1171
- conj = {} # 0
1172
- opp = {} # 10
1173
- sq = {} # 5
1174
- tr = {} # 6
1175
- qc = {} # 9
1176
- sext = {} # 3
1177
- for i in range(len(self.planets_settings)):
1178
- a = self.planets_degree_ut[i]
1179
- qc[i] = {}
1180
- sext[i] = {}
1181
- opp[i] = {}
1182
- sq[i] = {}
1183
- tr[i] = {}
1184
- conj[i] = {}
1185
- # skip some points
1186
- n = self.planets_settings[i]['name']
1187
- if n == 'earth' or n == 'True_Node' or n == 'osc. apogee' or n == 'intp. apogee' or n == 'intp. perigee':
1188
- continue
1189
- if n == 'Dsc' or n == 'Ic':
1190
- continue
1191
- for j in range(len(self.planets_settings)):
1192
- # skip some points
1193
- n = self.planets_settings[j]['name']
1194
- if n == 'earth' or n == 'True_Node' or n == 'osc. apogee' or n == 'intp. apogee' or n == 'intp. perigee':
1195
- continue
1196
- if n == 'Dsc' or n == 'Ic':
1197
- continue
1198
- b = self.planets_degree_ut[j]
1199
- delta = float(self.degreeDiff(a, b))
1200
- # check for opposition
1201
- xa = float(self.aspects_settings[10]['degree']) - \
1202
- float(self.aspects_settings[10]['orb'])
1203
- xb = float(self.aspects_settings[10]['degree']) + \
1204
- float(self.aspects_settings[10]['orb'])
1205
- if(xa <= delta <= xb):
1206
- opp[i][j] = True
1207
- # check for conjunction
1208
- xa = float(self.aspects_settings[0]['degree']) - \
1209
- float(self.aspects_settings[0]['orb'])
1210
- xb = float(self.aspects_settings[0]['degree']) + \
1211
- float(self.aspects_settings[0]['orb'])
1212
- if(xa <= delta <= xb):
1213
- conj[i][j] = True
1214
- # check for squares
1215
- xa = float(self.aspects_settings[5]['degree']) - \
1216
- float(self.aspects_settings[5]['orb'])
1217
- xb = float(self.aspects_settings[5]['degree']) + \
1218
- float(self.aspects_settings[5]['orb'])
1219
- if(xa <= delta <= xb):
1220
- sq[i][j] = True
1221
- # check for qunicunxes
1222
- xa = float(self.aspects_settings[9]['degree']) - \
1223
- float(self.aspects_settings[9]['orb'])
1224
- xb = float(self.aspects_settings[9]['degree']) + \
1225
- float(self.aspects_settings[9]['orb'])
1226
- if(xa <= delta <= xb):
1227
- qc[i][j] = True
1228
- # check for sextiles
1229
- xa = float(self.aspects_settings[3]['degree']) - \
1230
- float(self.aspects_settings[3]['orb'])
1231
- xb = float(self.aspects_settings[3]['degree']) + \
1232
- float(self.aspects_settings[3]['orb'])
1233
- if(xa <= delta <= xb):
1234
- sext[i][j] = True
1235
-
1236
- yot = {}
1237
- # check for double qunicunxes
1238
- for k, v in qc.items():
1239
- if len(qc[k]) >= 2:
1240
- # check for sextile
1241
- for l, w in qc[k].items():
1242
- for m, x in qc[k].items():
1243
- if m in sext[l]:
1244
- if l > m:
1245
- yot['%s,%s,%s' % (k, m, l)] = [k, m, l]
1246
- else:
1247
- yot['%s,%s,%s' % (k, l, m)] = [k, l, m]
1248
- tsquare = {}
1249
- # check for opposition
1250
- for k, v in opp.items():
1251
- if len(opp[k]) >= 1:
1252
- # check for square
1253
- for l, w in opp[k].items():
1254
- for a, b in sq.items():
1255
- if k in sq[a] and l in sq[a]:
1256
- # print 'got tsquare %s %s %s' % (a,k,l)
1257
- if k > l:
1258
- tsquare['%s,%s,%s' % (a, l, k)] = '%s => %s, %s' % (
1259
- self.planets_settings[a]['label'], self.planets_settings[l]['label'], self.planets_settings[k]['label'])
1260
- else:
1261
- tsquare['%s,%s,%s' % (a, k, l)] = '%s => %s, %s' % (
1262
- self.planets_settings[a]['label'], self.planets_settings[k]['label'], self.planets_settings[l]['label'])
1263
- stellium = {}
1264
- # check for 4 continuous conjunctions
1265
- for k, v in conj.items():
1266
- if len(conj[k]) >= 1:
1267
- # first conjunction
1268
- for l, m in conj[k].items():
1269
- if len(conj[l]) >= 1:
1270
- for n, o in conj[l].items():
1271
- # skip 1st conj
1272
- if n == k:
1273
- continue
1274
- if len(conj[n]) >= 1:
1275
- # third conjunction
1276
- for p, q in conj[n].items():
1277
- # skip first and second conj
1278
- if p == k or p == n:
1279
- continue
1280
- if len(conj[p]) >= 1:
1281
- # fourth conjunction
1282
- for r, s in conj[p].items():
1283
- # skip conj 1,2,3
1284
- if r == k or r == n or r == p:
1285
- continue
1286
-
1287
- l = [k, n, p, r]
1288
- l.sort()
1289
- stellium['%s %s %s %s' % (l[0], l[1], l[2], l[3])] = '%s %s %s %s' % (
1290
- self.planets_settings[l[0]
1291
- ]['label'], self.planets_settings[l[1]]['label'],
1292
- self.planets_settings[l[2]]['label'], self.planets_settings[l[3]]['label'])
1293
- # print yots
1294
- out = '<g transform="translate(-30,380)">'
1295
- if len(yot) >= 1:
1296
- y = 0
1297
- for k, v in yot.items():
1298
- out += '<text y="%s" style="fill:%s; font-size: 12px;">%s</text>\n' % (
1299
- y, self.colors_settings['paper_0'], ("Yot"))
1300
-
1301
- # first planet symbol
1302
- out += '<g transform="translate(20,%s)">' % (y)
1303
- out += '<use transform="scale(0.4)" x="0" y="-20" xlink:href="#%s" /></g>\n' % (
1304
- self.planets_settings[yot[k][0]]['name'])
1305
-
1306
- # second planet symbol
1307
- out += '<g transform="translate(30,%s)">' % (y)
1308
- out += '<use transform="scale(0.4)" x="0" y="-20" xlink:href="#%s" /></g>\n' % (
1309
- self.planets_settings[yot[k][1]]['name'])
1310
-
1311
- # third planet symbol
1312
- out += '<g transform="translate(40,%s)">' % (y)
1313
- out += '<use transform="scale(0.4)" x="0" y="-20" xlink:href="#%s" /></g>\n' % (
1314
- self.planets_settings[yot[k][2]]['name'])
1315
-
1316
- y = y+14
1317
- # finalize
1318
- out += '</g>'
1319
- # return out
1320
- return ''
1321
-
1322
- # Aspect and aspect grid functions for natal type charts.
1323
-
1324
- def makeAspects(self, r, ar):
1325
- out = ""
1326
- for element in self.aspects_list:
1327
- out += self.drawAspect(r, ar, element['p1_abs_pos'], element['p2_abs_pos'],
1328
- self.colors_settings[f"aspect_{element['aspect_degrees']}"])
1329
-
1330
- return out
1331
-
1332
- def makeAspectGrid(self, r):
1333
-
1334
- out = ""
1335
- style = 'stroke:%s; stroke-width: 1px; stroke-opacity:.6; fill:none' % (
1336
- self.colors_settings['paper_0'])
1337
- xindent = 380
1338
- yindent = 468
1339
- box = 14
1340
- revr = list(range(len(self.planets_settings)))
1341
- revr.reverse()
1342
- counter = 0
1343
- for a in revr:
1344
- counter += 1
1345
- if self.planets_settings[a]['visible'] == 1:
1346
- out += '<rect x="'+str(xindent)+'" y="'+str(yindent)+'" width="'+str(
1347
- box)+'" height="'+str(box)+'" style="'+style+'"/>\n'
1348
- out += '<use transform="scale(0.4)" x="'+str((xindent+2)*2.5)+'" y="'+str(
1349
- (yindent+1)*2.5)+'" xlink:href="#'+self.planets_settings[a]['name']+'" />\n'
1350
- xindent = xindent + box
1351
- yindent = yindent - box
1352
- revr2 = list(range(a))
1353
- revr2.reverse()
1354
- xorb = xindent
1355
- yorb = yindent + box
1356
- for b in revr2:
1357
- if self.planets_settings[b]['visible'] == 1:
1358
- out += '<rect x="'+str(xorb)+'" y="'+str(yorb)+'" width="'+str(
1359
- box)+'" height="'+str(box)+'" style="'+style+'"/>\n'
1360
- xorb = xorb+box
1361
- for element in self.aspects_list:
1362
- if (element['p1'] == a and element['p2'] == b) or (element['p1'] == b and element['p2'] == a):
1363
- out += '<use x="'+str(xorb-box+1)+'" y="'+str(
1364
- yorb+1)+'" xlink:href="#orb'+str(element['aspect_degrees'])+'" />\n'
1365
-
1366
- return out
1367
-
1368
- # Aspect and aspect grid functions for transit type charts.
1369
-
1370
- def makeAspectsTransit(self, r, ar):
1371
- out = ""
1372
-
1373
- self.aspects_list = CompositeAspects(
1374
- self.user, self.t_user, new_settings_file=self.settings_file
1375
- ).get_relevant_aspects()
1376
-
1377
- for element in self.aspects_list:
1378
- out += self.drawAspect(r, ar, element['p1_abs_pos'], element['p2_abs_pos'],
1379
- self.colors_settings[f"aspect_{element['aspect_degrees']}"])
1380
-
1381
- return out
1382
-
1383
- def makeAspectTransitGrid(self, r):
1384
- out = '<g transform="translate(500,310)">'
1385
- out += '<text y="-15" x="0" style="fill:%s; font-size: 14px;">%s</text>\n' % (
1386
- self.colors_settings['paper_0'], (f"{self.language_settings['aspects']}:"))
1387
- line = 0
1388
- nl = 0
1389
- for i in range(len(self.aspects_list)):
1390
- if i == 12:
1391
- nl = 100
1392
- # if len(self.aspects_list) > 24:
1393
- # line = -1 * ( len(self.aspects_list) - 24) * 14
1394
- # else:
1395
- # line = 0
1396
-
1397
- # temporary:
1398
- line = 0
1399
-
1400
- if i == 24:
1401
- nl = 200
1402
- # if len(self.aspects_list) > 36:
1403
- # line = -1 * ( len(self.aspects_list) - 36) * 14
1404
- # else:
1405
- # line = 0
1406
- line = 0
1407
-
1408
- if i == 36:
1409
- nl = 300
1410
- if len(self.aspects_list) > 48:
1411
- line = -1 * (len(self.aspects_list) - 48) * 14
1412
- else:
1413
- line = 0
1414
- out += '<g transform="translate(%s,%s)">' % (nl, line)
1415
- # first planet symbol
1416
- out += '<use transform="scale(0.4)" x="0" y="3" xlink:href="#%s" />\n' % (
1417
- self.planets_settings[self.aspects_list[i]['p1']]['name'])
1418
- # aspect symbol
1419
- out += '<use x="15" y="0" xlink:href="#orb%s" />\n' % (
1420
- self.aspects_settings[self.aspects_list[i]['aid']]['degree'])
1421
- # second planet symbol
1422
- out += '<g transform="translate(30,0)">'
1423
- out += '<use transform="scale(0.4)" x="0" y="3" xlink:href="#%s" />\n' % (
1424
- self.planets_settings[self.aspects_list[i]['p2']]['name'])
1425
- out += '</g>'
1426
- # difference in degrees
1427
- out += '<text y="8" x="45" style="fill:%s; font-size: 10px;">%s</text>' % (
1428
- self.colors_settings['paper_0'],
1429
- self.dec2deg(self.aspects_list[i]['orbit']))
1430
- # line
1431
- out += '</g>'
1432
- line = line + 14
1433
- out += '</g>'
1434
- return out
1435
-
1436
- def makeElements(self, r):
1437
- total = self.fire + self.earth + self.air + self.water
1438
- pf = int(round(100*self.fire/total))
1439
- pe = int(round(100*self.earth/total))
1440
- pa = int(round(100*self.air/total))
1441
- pw = int(round(100*self.water/total))
1442
- out = '<g transform="translate(-30,79)">\n'
1443
- out += '<text y="0" style="fill:#ff6600; font-size: 10px;">' + \
1444
- self.language_settings['fire']+' '+str(pf)+'%</text>\n'
1445
- out += '<text y="12" style="fill:#6a2d04; font-size: 10px;">' + \
1446
- self.language_settings['earth']+' '+str(pe)+'%</text>\n'
1447
- out += '<text y="24" style="fill:#6f76d1; font-size: 10px;">' + \
1448
- self.language_settings['air']+' '+str(pa)+'%</text>\n'
1449
- out += '<text y="36" style="fill:#630e73; font-size: 10px;">' + \
1450
- self.language_settings['water']+' '+str(pw)+'%</text>\n'
1451
- out += '</g>\n'
1452
- return out
1453
-
1454
- def makePlanetGrid(self):
1455
- out = '<g transform="translate(500,-20)">'
1456
-
1457
- # loop over all planets
1458
- li = 10
1459
- offset = 0
1460
-
1461
- out += '<g transform="translate(140, -15)">'
1462
- out += \
1463
- f'<text text-anchor="end" style="fill:{self.colors_settings["paper_0"]}; font-size: 14px;">{self.language_settings["planets_and_house"]} {self.name}:</text>'
1464
- out += '</g>\n'
1465
-
1466
- for i in range(len(self.planets_settings)):
1467
-
1468
- # Guarda qui !!
1469
- if i == 27:
1470
- li = 10
1471
- offset = -120
1472
- if self.planets_settings[i]['visible'] == 1:
1473
- # start of line
1474
- out += '<g transform="translate(%s,%s)">' % (offset, li)
1475
- # planet text
1476
- out += f'<text text-anchor="end" style="fill:{self.colors_settings["paper_0"]}; font-size: 10px;">{self.language_settings["planets"][self.planets_settings[i]["label"]]}</text>'
1477
- # planet symbol
1478
- out += \
1479
- '<g transform="translate(5,-8)"><use transform="scale(0.4)" xlink:href="#' + \
1480
- self.planets_settings[i]['name']+'" /></g>'
1481
- # planet degree
1482
- out += '<text text-anchor="start" x="19" style="fill:%s; font-size: 10px;">%s</text>' % (
1483
- self.colors_settings['paper_0'], self.dec2deg(self.planets_degree[i]))
1484
- # zodiac
1485
- out += '<g transform="translate(60,-8)"><use transform="scale(0.3)" xlink:href="#' + \
1486
- self.zodiac[self.planets_sign[i]]+'" /></g>'
1487
- # planet retrograde
1488
- if self.planets_retrograde[i]:
1489
- out += \
1490
- '<g transform="translate(74,-6)"><use transform="scale(.5)" xlink:href="#retrograde" /></g>'
1491
-
1492
- # end of line
1493
- out += '</g>\n'
1494
- # offset between lines
1495
- li = li + 14
1496
-
1497
- # ----------
1498
-
1499
- if self.chart_type == "Transit" or self.chart_type == "Composite":
1500
-
1501
- if self.chart_type == "Transit":
1502
- out += '<g transform="translate(320, -15)">'
1503
- out += \
1504
- f'<text text-anchor="end" style="fill:{self.colors_settings["paper_0"]}; font-size: 14px;">{self.t_name}:</text>'
1505
- else:
1506
- out += '<g transform="translate(380, -15)">'
1507
- out += \
1508
- f'<text text-anchor="end" style="fill:{self.colors_settings["paper_0"]}; font-size: 14px;">{self.language_settings["planets_and_house"]} {self.t_user.name}:</text>'
1509
- out += '</g>\n'
1510
-
1511
- t_li = 10
1512
- t_offset = 250
1513
-
1514
- for i in range(len(self.planets_settings)):
1515
- if i == 27:
1516
- t_li = 10
1517
- t_offset = -120
1518
- if self.planets_settings[i]['visible'] == 1:
1519
- # start of line
1520
- out += f'<g transform="translate({t_offset},{t_li})">'
1521
-
1522
- # planet text
1523
- out += f'<text text-anchor="end" style="fill:{self.colors_settings["paper_0"]}; font-size: 10px;">{self.language_settings["planets"][self.planets_settings[i]["label"]]}</text>'
1524
- # planet symbol
1525
- out += f'<g transform="translate(5,-8)"><use transform="scale(0.4)" xlink:href="# {self.planets_settings[i]["name"]}" /></g>'
1526
- # planet degree
1527
- out += '<text text-anchor="start" x="19" style="fill:%s; font-size: 10px;">%s</text>' % (
1528
- self.colors_settings['paper_0'], self.dec2deg(self.t_planets_degree[i]))
1529
- # zodiac
1530
- out += '<g transform="translate(60,-8)"><use transform="scale(0.3)" xlink:href="#' + \
1531
- self.zodiac[self.t_planets_sign[i]]+'" /></g>'
1532
- # planet retrograde
1533
- if self.t_planets_retrograde[i]:
1534
- out += \
1535
- '<g transform="translate(74,-6)"><use transform="scale(.5)" xlink:href="#retrograde" /></g>'
1536
-
1537
- # end of line
1538
- out += '</g>\n'
1539
- # offset between lines
1540
- t_li = t_li + 14
1541
- out += '</g>\n'
1542
-
1543
- return out
1544
-
1545
- def makeHousesGrid(self):
1546
-
1547
- out = '<g transform="translate(600,-20)">'
1548
- li = 10
1549
- for i in range(12):
1550
- if i < 9:
1551
- cusp = '&#160;&#160;'+str(i+1)
1552
- else:
1553
- cusp = str(i+1)
1554
- out += '<g transform="translate(0,'+str(li)+')">'
1555
- out += '<text text-anchor="end" x="40" style="fill:%s; font-size: 10px;">%s %s:</text>' % (
1556
- self.colors_settings['paper_0'], self.language_settings['cusp'], cusp)
1557
- out += '<g transform="translate(40,-8)"><use transform="scale(0.3)" xlink:href="#' + \
1558
- self.zodiac[self.houses_sign[i]]+'" /></g>'
1559
- out += '<text x="53" style="fill:%s; font-size: 10px;"> %s</text>' % (
1560
- self.colors_settings['paper_0'], self.dec2deg(self.houses_list[i]["position"]))
1561
- out += '</g>\n'
1562
- li = li + 14
1563
- out += '</g>\n'
1564
-
1565
- # ----------
1566
-
1567
- if self.chart_type == "Composite":
1568
- out += '<g transform="translate(840, -20)">'
1569
- li = 10
1570
- for i in range(12):
1571
- if i < 9:
1572
- cusp = '&#160;&#160;'+str(i+1)
1573
- else:
1574
- cusp = str(i+1)
1575
- out += '<g transform="translate(0,'+str(li)+')">'
1576
- out += '<text text-anchor="end" x="40" style="fill:%s; font-size: 10px;">%s %s:</text>' % (
1577
- self.colors_settings['paper_0'], self.language_settings['cusp'], cusp)
1578
- out += '<g transform="translate(40,-8)"><use transform="scale(0.3)" xlink:href="#' + \
1579
- self.zodiac[self.t_houses_sign[i]]+'" /></g>'
1580
- out += '<text x="53" style="fill:%s; font-size: 10px;"> %s</text>' % (
1581
- self.colors_settings['paper_0'], self.dec2deg(self.t_houses_list[i]["position"]))
1582
- out += '</g>\n'
1583
- li = li + 14
1584
- out += '</g>\n'
1585
-
1586
- return out
1587
-
1588
- def set_output_directory(self, dir_path):
1589
- """
1590
- Sets the output direcotry and returns it's path.
1591
- """
1592
- self.output_directory = Path(dir_path)
1593
- dir_string = f"Output direcotry set to: {self.output_directory}"
1594
- return (print(dir_string))
1595
-
1596
-
1597
- if __name__ == "__main__":
1598
-
1599
- first = KrInstance("Jack", 1990, 6, 15, 15, 15, "Roma")
1600
- second = KrInstance("Jane", 1991, 10, 25, 21, 00, "Roma")
1601
-
1602
- name = MakeSvgInstance(first, chart_type="Composite",
1603
- second_obj=second, lang="IT")
1604
- # name.output_directory = Path.home() / "charts"
1605
- template = name.makeTemplate()
1606
- name.makeSVG()
1607
- print(name.aspects_list[-1])