ocactivity-gen 0.0.0__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.
@@ -0,0 +1,272 @@
1
+ Metadata-Version: 2.4
2
+ Name: ocactivity-gen
3
+ Version: 0.0.0
4
+ Summary: Nástroj pro generování obrázků aktivity z GPX/FIT nebo dle vlastního zadání.
5
+ Author-email: Jiří Vik <mimic2300@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Repository, https://gitlab.com/OphiteCorp/pyactivity-generator
8
+ Keywords: mimic,ophitecorp,strava,garmin,fit,gpx,sport,activity,generator,gen,image
9
+ Classifier: Programming Language :: Python :: 3.14
10
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
11
+ Requires-Python: >=3.14
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: Pillow>=10.4.0
15
+ Requires-Dist: fitparse>=1.2.0
16
+ Requires-Dist: numpy>=2.1.0
17
+ Requires-Dist: rich>=13.9.0
18
+ Dynamic: license-file
19
+
20
+ # ocactivity-gen 🏃‍♂️🚴‍♀️🏔️
21
+
22
+ **ocactivity-gen** je Python nástroj a konzolová aplikace pro generování estetických grafických kartogramů a vizualizací sportovních aktivit (běh, chůze, turistika, cyklistika apod.).
23
+
24
+ Dokáže zpracovat soubory **Garmin FIT** a **GPX**, extrahovat z nich metriky (vzdálenost, čas, tempo, rychlost, stoupání, klesání, tep, teplotu, kalorie, kroky) a vykreslit trasy na mapové podklady z OpenStreetMap / Mapy.com nebo jiné společně s výškovým profilem a statistikami.
25
+
26
+ Testováno na Garmin FIT souborech z hodinek, ale mělo by to fungovat i od jiných. Jen pozor na to, že ne každý FIT soubor obsahuje všechny informace. Takže výsledek se může lišit.
27
+
28
+ V případě vlastní implementace jde hodně věcí přizpůsobit na míru, ale ve výchozím nastavení jsou obrázky vždy 1440x1440 a mají levý zatmavený panel kam se vkládají statistiky.
29
+
30
+ ---
31
+
32
+ ## 💪 Ukázky výstupu
33
+ <p align="center">
34
+ <img src="output/simple.jpg" alt="Výstup" width="45%">
35
+ <img src="output/full.jpg" alt="Výstup" width="45%">
36
+ </p>
37
+
38
+ ---
39
+
40
+ ## 🛠️ Hlavní funkce
41
+
42
+ - **Podpora Garmin FIT & GPX:** Automatické vytěžování telemetrie, GPS trasy a časových dat.
43
+ - **Inteligentní vyhlazování GPX:** Filtr GPS šumu pomocí 2D Kalmanova filtru.
44
+ - **Rychlá analýza dat:** Adaptivní prahy pohybů a hysterézní filtr převýšení pro přesný výpočet stoupání a času v pohybu.
45
+ - **Generování výškového profilu:** Graf nadmořské výšky se zvýrazněním nejnižšího a nejvyššího bodu.
46
+ - **Flexibilní mapa:** Stahování a kešování mapových dlaždic (OSM / Mapy.com) s automatickým přizpůsobením zoomu.
47
+ - **Dynamic Element Stacking:** Zobrazované statistiky se řadí dynamicky bez mezer i v případě, že některé metriky chybí.
48
+ - **Podpora vlastních fotek:** Možnost nahradit mapu vlastním obrázkem na pozadí.
49
+ - **Vodoznak a EXIF metadata:** Vkládání loga / vodoznaku a zápis autorství do EXIF/PNG metadat.
50
+ - **Export obrázku:** Možnost exportovat do JPG nebo PNG.
51
+ - **Vlastní aktivita:** Možnost vytvoření úplně nové aktivity podle vstupních parametrů (bez trasy, ta vyžaduje min. GPX na vstupu).
52
+
53
+ ---
54
+
55
+ ## 📦 Instalace
56
+
57
+ Aplikaci lze nainstalovat přímo z PyPI pomocí `pip`:
58
+
59
+ ```bash
60
+ pip install ocactivity-gen
61
+ ```
62
+
63
+ ---
64
+
65
+ ## 🚀 Použití z příkazové řádky (CLI)
66
+ Po instalaci je ihned k dispozici příkaz `ocactivity-gen`.
67
+
68
+ Příklady použití:
69
+ 1) Vygenerování obrázku z FIT souboru:
70
+ ```bash
71
+ ocactivity-gen -file "aktivity/zavod.fit" -name "Horský Ultra Běh 🏔️"
72
+ ```
73
+
74
+ 2) Vygenerování z GPX souboru s vlastní fotkou na pozadí:
75
+ ```bash
76
+ ocactivity-gen -file "vylet.gpx" -bg "moje_fotka.jpg" -name "Víkendová procházka" -out "vylet.png"
77
+ ```
78
+
79
+ 3) Ruční vytvoření aktivity bez datového souboru:
80
+ ```bash
81
+ ocactivity-gen -type "Běh" -distance 10500 -pace "4:45" -avgspeed "12.6" -ascent 250 -time 2980 -name "Ranní desítka"
82
+ ```
83
+
84
+ 4) Přepsání načtených hodnot z FIT souboru a skrytí grafu a teploty:
85
+ ```bash
86
+ ocactivity-gen -file "zavod.fit" -nograph -avgtemp -999 -name "Závod bez grafu a teploty"
87
+ ```
88
+
89
+ 5) Pokud je potřeba použít jiné mapové podklady, třeba mapy.com. Je dobré změnit i cache, aby se nepoužívali staré podklady pro OSM (výchozí).
90
+ ```bash
91
+ ocactivity-gen -file "activity.fit" -mapcache "mapy" -mapurl "https://api.mapy.cz/v1/maptiles/basic/256/{z}/{x}/{y}?apikey={YOUR_API_KEY}" -name "Nedělní výlet"
92
+ ```
93
+
94
+ 6) Více příkladů v help:
95
+ ```bash
96
+ ocactivity-gen -h
97
+ ```
98
+
99
+ ---
100
+
101
+ ## 🎛️ Přehled parametrů CLI
102
+ Zde jsou nejčastější parametry. Pro více parametrů je potřeba se podívat do `-h` help.
103
+
104
+ | Parametr | Popis |
105
+ | :--- | :--- |
106
+ | -file | Cesta k FIT nebo GPX souboru. |
107
+ | -bg | Cesta k obrázku, která bude na pozadí místo mapy. |
108
+ | -name | Název nebo popis aktivity. |
109
+ | -type | Typ aktivity (např. "Chůze", "Běh", "Turistika", ...). |
110
+ | -distance | Vzdálenost v metrech. |
111
+ | -avgspeed | Průměrná rychlost v km/h (např. 7.5). |
112
+ | -maxspeed | Maximální rychlost v km/h. |
113
+ | -pace | Tempo v min/km (např. "4:30"). Musí být text, jinak se to bere jako m/s. |
114
+ | -ascent | Stoupání v metrech. |
115
+ | -descent | Klesání v metrech. |
116
+ | -time | Čas v pohybu v sekundách. |
117
+ | -avghr | Průměrná tepová frekvence (bpm). |
118
+ | -maxhr | Maximální tepová frekvence (bpm). |
119
+ | -avgtemp | Průměrná teplota (°C). |
120
+ | -maxtemp | Maximální teplota (°C). |
121
+ | -kcal | Spálené kalorie. |
122
+ | -steps | Počet kroků. |
123
+ | -cdate | Datum a čas spuštění aktivity ve formátu YYYY-MM-DD HH:MM:SS. |
124
+ | -fdate | Datum a čas zastavení aktivity ve formátu YYYY-MM-DD HH:MM:SS. |
125
+ | -elapsedtime | Celkový čas aktivity v sekundách včetně přestávek. |
126
+ | -idletime | Součet času odpočinku nebo čekání v sekundách. |
127
+ | -nograph | Vypne vykreslování grafu převýšení. |
128
+ | -nogpx | Vypne vykreslování trasy na mapě. |
129
+ | -grayscale | Použije na pozadí částečný (asi 25%) černobílý efekt, aby se snížila intenzita barev. |
130
+ | -kmstep | Nastaví vzdálenost v kilometrech mezi značkami na trase. |
131
+ | -lang | Nastaví lokalizaci popisků (CZ, EN). |
132
+ | -out | Cílová cesta pro uložení obrázku. Může být jen adresář nebo i celá cesta včetně názvu. |
133
+ | -mapurl | URL adresa pro mapové podklady. Výchozí je na OSM. |
134
+ | -mapcache | Název cache adresáře, do kterého se budou ukládat mapové dlaždice. Pokud se změní URL, tak změnit i toto nebo prvně smazat cache. |
135
+ | -ccache | Smaže mapové podklady z cache. |
136
+
137
+ ---
138
+
139
+ ## 🐍 Použití v kódu (pro vývojáře)
140
+ Díky modularitě lze knihovnu importovat do vlastního Python skriptu:
141
+ #### A) Podobný styl obrázku, který je generován nativně:
142
+ - Vlastní definice metrik (parametry aktivity).
143
+ ```python
144
+ from pyactivity import (
145
+ ActivityGenerator,
146
+ ActivityMetrics,
147
+ ActivityParser,
148
+ ElementStyle,
149
+ ElevationGraphConfig,
150
+ GeneratorConfig,
151
+ GPXConfig,
152
+ WatermarkConfig,
153
+ create_element,
154
+ default_viewport_callback,
155
+ format_activity_type,
156
+ )
157
+
158
+ # Vytvoření metrik
159
+ metrics = ActivityMetrics(
160
+ name="Nedělní procházka",
161
+ activity_type="Chůze",
162
+ distance=12345, # Metry (12.3 km)
163
+ moving_time=7173 # Sekundy (1h 59m 33s)
164
+ )
165
+
166
+ # Sestavení konfigurace a generátoru
167
+ config = GeneratorConfig(
168
+ # Vlastní konfigurace GPX trasy (ZDE není potřeba)
169
+ gpx=GPXConfig(),
170
+ # Konfigurace grafu převýšení (pouze pro FIT a ZDE též není potřeba)
171
+ elevation=ElevationGraphConfig(),
172
+ # Vlastní konfigurace vodoznaku
173
+ watermark=WatermarkConfig(),
174
+ # Vykreslení prvků na obrázek
175
+ # Název klíče musí odpovídat atributu v metrice!
176
+ # Pokud je potřeba vlastní element, tak musí začínat prefixem: custom_
177
+ elements={
178
+ # Název aktivity
179
+ "name": ElementStyle(
180
+ is_absolute=True,
181
+ value_pos=(360, 1180),
182
+ value_font_size=40,
183
+ auto_shrink=True, # Když bude text dlouhý, tak se začne změnšovat
184
+ value_color=(255, 255, 255, 255)
185
+ ),
186
+ # Typ aktivity
187
+ "activity_type": create_element("Aktivita"),
188
+ # Ikonka pro typ
189
+ "custom_activity_type_marker": create_element(
190
+ "🎯",
191
+ is_absolute=True,
192
+ take_pos_y_from_prev_label=True
193
+ ),
194
+ # Vzdálenost
195
+ "distance": create_element("Vzdálenost"),
196
+ # Ikonka pro vzdálenost
197
+ "custom_distance_marker": create_element(
198
+ "📍",
199
+ is_absolute=True,
200
+ take_pos_y_from_prev_label=True
201
+ ),
202
+ # Čas pohybu
203
+ "moving_time": create_element("Čas"),
204
+ # Ikonka pro čas pohybu
205
+ "custom_moving_time_marker": create_element(
206
+ "🕒",
207
+ is_absolute=True,
208
+ take_pos_y_from_prev_label=True
209
+ )
210
+ }
211
+ )
212
+
213
+ # Uložení obrázku
214
+ generator = ActivityGenerator(metrics=metrics, config=config)
215
+ generator.save(output_path="vystup.jpg", quality=90)
216
+ ```
217
+ #### B) Načtení vlastního FIT souboru:
218
+ - Bude použit stejný kód jako v bodě (A), ale musí se udělat několik úprav.
219
+ - Celý objekt s metrikami se vytvoří z FIT souboru, takže není ho potřeba vytvářet ručně.
220
+ ##### Přidání mapování typu aktivity:
221
+ Protože FIT soubor má vlastní typy, tak se hodnoty musí přemapovat na vlastní název.
222
+ ```python
223
+ ACTIVITY_MAPPING: dict[str | None, str] = {
224
+ "walk": "Chůze",
225
+ "walking": "Chůze",
226
+ "run": "Běh",
227
+ "running": "Běh"
228
+ }
229
+ ```
230
+ ##### Načtení FIT souboru a metrik:
231
+ Místo vytvoření vlastních metrik je načteme z FIT souboru.
232
+ ```python
233
+ # Načtení FIT souboru a těžba dat
234
+ fit_file = Path("activity.fit")
235
+ fit_data = ActivityParser().parse_fit(fit_file)
236
+
237
+ # Získání metrik s možností je přepsat
238
+ metrics = fit_data.metrics
239
+ metrics.name = "Název aktivity" # FIT neobsahuje název
240
+ ```
241
+ ##### Úprava konfigurace - GeneratorConfig:
242
+ Do `GeneratorConfig` přidáme následující konfiguraci. Pro ukázku obsahuje více věcí, které lze taky nastavit.
243
+ ```python
244
+ # Obecná konfigurace
245
+ edge_vignette=False, # Okraje obrázku nebudou mít gradient
246
+ elevation_graph_enabled=True, # Vygeneruje graf převýšení
247
+ # Konfigurace GPX trasy
248
+ gpx=GPXConfig(
249
+ gpx_enabled=True, # Povolí vykreslení trasy
250
+ gpx_path=fit_file, # Může být GPX i FIT
251
+ gpx_points=fit_data.gpx_points, # Musí být vždy vyplněno
252
+ gpx_points_with_elev=fit_data.gpx_points_with_elev, # Tohle pouze pro FIT, protože GPX nemá převýšení
253
+ # Pokud se generuje i graf převýšení, tak je dobré použít vlastní viewport, aby trasa nezasahovala do grafu
254
+ viewport=default_viewport_callback,
255
+ show_start_finish=True, # Vykreslí začátek a konec trasy
256
+ show_km_markers=True # Vykreslí kilometrové značky na trase
257
+ ),
258
+ # Konfigurace grafu převýšení (pouze pro FIT)
259
+ elevation=ElevationGraphConfig(
260
+ show_bubble_interval=True, # Značky každých N-km
261
+ show_bubble_extreme=True # Značka na nejvyšším a nejnižším místě
262
+ ),
263
+ ```
264
+ ##### Úprava activity_type v elements:
265
+ Aby bylo možné použít vlastní mapování pro typ aktivity, tak musíme přidat mapper.
266
+ ```python
267
+ "activity_type": create_element(
268
+ "Aktivita",
269
+ formatter=lambda _cfg, _met, val: format_activity_type(val, ACTIVITY_MAPPING),
270
+ ),
271
+ ```
272
+ Celkové toho nastavení je mnoho. Tady je použit pouze nutný výčet a nějaké nice-to-have. Často je možné nastavit vše, od pozice, barvy, různých hodnot. Stačí projít konfigurační objekty.
@@ -0,0 +1,24 @@
1
+ ocactivity_gen-0.0.0.dist-info/licenses/LICENSE,sha256=ewGU6UKUCqOv_fc1OHOlKMTyZw0G-id1xFGIGxvRuy8,1066
2
+ pyactivity/__init__.py,sha256=LjsbyWC6JkMWGSlOrjdyPYbI11Q8ZE7ytv-mvD0W9dU,754
3
+ pyactivity/activity_generator.py,sha256=k3rgijagkIsciz-R1CYZUZL5LCLdzggWmIXhU6b5HtM,120917
4
+ pyactivity/cli.py,sha256=guDn4H2FElGBvNpIjAgfAZBORAlsxL0D7tGS-ybuUvI,114
5
+ pyactivity/default_template.py,sha256=uxQN4xx02rKw2Hk1qVazmjNy1SEGoOh1qR673hcQlJk,37843
6
+ pyactivity/fonts/DejaVuSans.ttf,sha256=faGVp0xVvvmI0NSPlQi9XYSUJcF3Dbpde_xs6e2EiVQ,757076
7
+ pyactivity/fonts/NotoColorEmoji.ttf,sha256=f7OXOKsY8QYS1vRZXi6OR6Cv3zRzhGBELZnNDDRKTZA,25111640
8
+ pyactivity/fonts/NotoSansSymbols-Regular.ttf,sha256=rt7sHNBRSTCu6vxKiKbe_4PNoea1gIbwubucfdAVdXg,185152
9
+ pyactivity/fonts/Oxanium-Regular.ttf,sha256=fDASR0eg8tpvyvecRoOZ5CebnbnVBxgjyiSya2PtxyA,29468
10
+ pyactivity/fonts/arial.ttf,sha256=ybdiIKW-QurUczYR5BfNZcX9iuqjPrVldqw3ijfRMKE,1036584
11
+ pyactivity/fonts/seguiemj.ttf,sha256=fAJE3Y7rfGvezfw_nlmDNSf8GKZtApXORzOQaWkqK08,2072388
12
+ pyactivity/fonts/seguisb.ttf,sha256=mFMoNGa9Q5k7mBMhUoH7nHCQy9jptUU_bQ0EBiLhF-I,971080
13
+ pyactivity/fonts/seguisym.ttf,sha256=0vgyajVEVtk-eLBTfFh5PnByw2F699nuGH8Q1tWV9RA,2454728
14
+ pyactivity/fonts/toxigenesis_bd.ttf,sha256=qW14Wm8KzUgBBGOg5KnLM5WgDCk3W5FeGaqLiQzI3Nw,150444
15
+ pyactivity/modules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
+ pyactivity/modules/elevation_graph.py,sha256=mIToZ7QRSEpvhL2MT6qvoE3wYPfbuLXNsU9Wyv9XDf4,27627
17
+ pyactivity/modules/file_analyzer.py,sha256=TjDCgeiUnM4wcRBnL7UakUvqVISSesBuzJjpvDMGJGQ,25187
18
+ pyactivity/static/background.jpg,sha256=xIH5Rghp_EPUboBh999wkMsZvmYZY6G1Av-_2mrcRR0,251632
19
+ pyactivity/static/watermark.png,sha256=kp2rJ3hXpgwtMC1vmwwpyrNgecstArMvxRUdxuwFYvg,102529
20
+ ocactivity_gen-0.0.0.dist-info/METADATA,sha256=7DSriub32X9tk8qlHkwNWqrBZfBwoUuOJLdlh9VQx8Y,11278
21
+ ocactivity_gen-0.0.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
22
+ ocactivity_gen-0.0.0.dist-info/entry_points.txt,sha256=MxtyXCKc0OWDzaOhnV5NfbBsZfefKBRspCkwnWxnxt0,55
23
+ ocactivity_gen-0.0.0.dist-info/top_level.txt,sha256=Vj9gpnlCdoYTYzbU-m50V9l1T5Xf-_vWCQYyZXMhQ7s,11
24
+ ocactivity_gen-0.0.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ ocactivity-gen = pyactivity.cli:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jiří Vik
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ pyactivity
pyactivity/__init__.py ADDED
@@ -0,0 +1,34 @@
1
+ from .activity_generator import (
2
+ ActivityGenerator,
3
+ ActivityMetrics,
4
+ ActivityParser,
5
+ ElementStyle,
6
+ GeneratorConfig,
7
+ GPXConfig,
8
+ WatermarkConfig,
9
+ can_display,
10
+ clean_map_cache,
11
+ create_element,
12
+ default_viewport_callback,
13
+ format_activity_type,
14
+ )
15
+ from .default_template import main as cli_main
16
+ from .modules.elevation_graph import ElevationGraphConfig
17
+
18
+ __version__ = "1.0.8"
19
+ __all__ = [
20
+ "ActivityGenerator",
21
+ "ActivityMetrics",
22
+ "ActivityParser",
23
+ "ElementStyle",
24
+ "ElevationGraphConfig",
25
+ "GPXConfig",
26
+ "GeneratorConfig",
27
+ "WatermarkConfig",
28
+ "can_display",
29
+ "clean_map_cache",
30
+ "cli_main",
31
+ "create_element",
32
+ "default_viewport_callback",
33
+ "format_activity_type",
34
+ ]