Metadata-Version: 2.4
Name: ocactivity-gen
Version: 1.0.14
Summary: Nástroj pro generování obrázků aktivity z GPX/FIT nebo dle vlastního zadání.
Author-email: Jiří Vik <mimic2300@gmail.com>
License-Expression: MIT
Project-URL: Repository, https://gitlab.com/OphiteCorp/pyactivity-generator
Keywords: mimic,ophitecorp,strava,garmin,fit,gpx,sport,activity,generator,gen,image,czech,analysis,visualization
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Intended Audience :: Healthcare Industry
Classifier: Intended Audience :: Developers
Classifier: Natural Language :: Czech
Classifier: Natural Language :: English
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Multimedia :: Graphics :: Viewers
Classifier: Topic :: Scientific/Engineering :: Information Analysis
Classifier: Topic :: Scientific/Engineering :: Visualization
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.14
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: Pillow>=10.4.0
Requires-Dist: fitparse>=1.2.0
Requires-Dist: numpy>=2.1.0
Requires-Dist: rich>=13.9.0
Dynamic: license-file

<p align="center">
  <img src="https://gitlab.com/OphiteCorp/pyactivity-generator/-/raw/main/logo.png" alt="logo" width="50%">
</p>

**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.).

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.

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.

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.

<p align="center">
  <img src="https://gitlab.com/OphiteCorp/pyactivity-generator/-/raw/main/donate.png" alt="donate" width="200px">
  <br/>
  <strong>❤️ <a href="https://www.paypal.com/donate/?hosted_button_id=BGUBNNAMCSHFL" target="_blank">Poděkuj | Donate | Buy me a coffee</a> ❤️</strong>
</p>

---

## 💪 Ukázky výstupu
<p align="center">
  <img src="https://gitlab.com/OphiteCorp/pyactivity-generator/-/raw/main/output/simple.jpg" alt="out1" width="45%">
  <img src="https://gitlab.com/OphiteCorp/pyactivity-generator/-/raw/main/output/full.jpg" alt="out2" width="45%">
</p>

---

## 🛠️ Hlavní funkce

- **Podpora Garmin FIT & GPX:** Automatické vytěžování telemetrie, GPS trasy a časových dat.
- **Inteligentní vyhlazování GPX:** Filtr GPS šumu pomocí 2D Kalmanova filtru.
- **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.
- **Generování výškového profilu:** Graf nadmořské výšky se zvýrazněním nejnižšího a nejvyššího bodu.
- **Flexibilní mapa:** Stahování a kešování mapových dlaždic (OSM / Mapy.com) s automatickým přizpůsobením zoomu.
- **Dynamic Element Stacking:** Zobrazované statistiky se řadí dynamicky bez mezer i v případě, že některé metriky chybí.
- **Podpora vlastních fotek:** Možnost nahradit mapu vlastním obrázkem na pozadí.
- **Vodoznak a EXIF metadata:** Vkládání loga / vodoznaku a zápis autorství do EXIF/PNG metadat.
- **Export obrázku:** Možnost exportovat do JPG nebo PNG.
- **Vlastní aktivita:** Možnost vytvoření úplně nové aktivity podle vstupních parametrů (bez trasy, ta vyžaduje min. GPX na vstupu).

---

## 📦 Instalace

Aplikaci lze nainstalovat přímo z PyPI pomocí `pip`:

```bash
pip install ocactivity-gen
```

---

## 🚀 Použití z příkazové řádky (CLI)
Po instalaci je ihned k dispozici příkaz `ocactivity-gen`.

Příklady použití:
1) Vygenerování obrázku z FIT souboru:
```bash
ocactivity-gen -file "aktivity/zavod.fit" -name "Horský Ultra Běh 🏔️"
```

2) Vygenerování z GPX souboru s vlastní fotkou na pozadí:
```bash
ocactivity-gen -file "vylet.gpx" -bg "moje_fotka.jpg" -name "Víkendová procházka" -out "vylet.png"
```

3) Ruční vytvoření aktivity bez datového souboru:
```bash
ocactivity-gen -type "Běh" -distance 10500 -pace "4:45" -avgspeed "12.6" -ascent 250 -time 2980 -name "Ranní desítka"
```

4) Přepsání načtených hodnot z FIT souboru a skrytí grafu a teploty:
```bash
ocactivity-gen -file "zavod.fit" -nograph -avgtemp -999 -name "Závod bez grafu a teploty"
```

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í).
```bash
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"
```

6) Výstupní obrázek z FIT souboru bude v EN a bude se ukládat do cílového úložiště, takže není žádoucí, aby se soubor přepisoval. Zároveň skryjeme typ aktivity.
```bash
ocactivity-gen -file "activity.fit" -lang "EN" -out "D:/activity/track.jpg" -outtime -type " "
```

7) Více příkladů v help:
```bash
ocactivity-gen -h
```

---

## 🎛️ Přehled parametrů CLI
Zde jsou nejčastější parametry. Pro více parametrů je potřeba se podívat do `-h` help.

| Parametr | Popis |
| :--- | :--- |
| -file | Cesta k FIT nebo GPX souboru. |
| -bg | Cesta k obrázku, která bude na pozadí místo mapy. |
| -name | Název nebo popis aktivity. |
| -type | Typ aktivity (např. "Chůze", "Běh", "Turistika", ...). |
| -distance | Vzdálenost v metrech. |
| -avgspeed | Průměrná rychlost v km/h (např. 7.5). |
| -maxspeed | Maximální rychlost v km/h. |
| -pace | Tempo v min/km (např. "4:30"). Musí být text, jinak se to bere jako m/s. |
| -ascent | Stoupání v metrech. |
| -descent | Klesání v metrech. |
| -time | Čas v pohybu v sekundách. |
| -avghr | Průměrná tepová frekvence (bpm). |
| -maxhr | Maximální tepová frekvence (bpm). |
| -avgtemp | Průměrná teplota (°C). |
| -maxtemp | Maximální teplota (°C). |
| -kcal | Spálené kalorie. |
| -steps | Počet kroků. |
| -cdate | Datum a čas spuštění aktivity ve formátu YYYY-MM-DD HH:MM:SS. |
| -fdate | Datum a čas zastavení aktivity ve formátu YYYY-MM-DD HH:MM:SS. |
| -elapsedtime | Celkový čas aktivity v sekundách včetně přestávek. |
| -idletime | Součet času odpočinku nebo čekání v sekundách. |
| -nograph | Vypne vykreslování grafu převýšení. |
| -nogpx | Vypne vykreslování trasy na mapě. |
| -grayscale | Použije na pozadí částečný (asi 25%) černobílý efekt, aby se snížila intenzita barev. |
| -kmstep | Nastaví vzdálenost v kilometrech mezi značkami na trase. |
| -lang | Nastaví lokalizaci popisků (CZ, EN). |
| -out | Cílová cesta pro uložení obrázku. Může být jen adresář nebo i celá cesta včetně názvu. |
| -mapurl | URL adresa pro mapové podklady. Výchozí je na OSM. |
| -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. |
| -ccache | Smaže mapové podklady z cache. |
| -outtime | Přidá do názvu výstupního souboru časové razítko ve formátu YYMMDD_HHMMSS. |

---

## 🔨 Nastavení trvalých parametrů
Může se stát, že bude potřeba některé parametry poslat vždy a není žádoucí je pokaždé vypisovat.
#### Windows
Spusťte tento příkaz v **PowerShell**. Následně se otevře editor, který buď bude prázdný nebo tam již něco bude.
```bash
if (!(Test-Path $PROFILE)) { New-Item -Type File -Force $PROFILE }; notepad $PROFILE
```
Následně na konec souboru vložte tuto funkci (kterou si upravte podle potřeby) a uložte. Tato funkce dělá to, že obalí volání aplikace a vloží vlastní parametry. Následně umožní předat parametry ze vstupu.
```bash
function ocactivity-gen {
    & ocactivity-gen.exe -lang "CZ" -mapurl "https://api.mapy.cz/v1/maptiles/outdoor/256/{z}/{x}/{y}?apikey={API_KEY}" -mapcache "mapy" -out "D:/activity.jpg" -outtime @args
}
```
Teď je potřeba ukončit všechny instance PowerShell a otevřít ho znovu. Nyní by se všechny nastavené parametry měli předat automaticky při zavolání.
Pokud není možné ukončit všechny okna PowerShell, tak stačí v konkrétním okně napsat `. $PROFILE`.

---

## 🐍 Použití v kódu (pro vývojáře)
Díky modularitě lze knihovnu importovat do vlastního python skriptu:
#### A) Podobný styl obrázku, který je generován nativně:
- Vlastní definice metrik (parametry aktivity).
```python
from pyactivity import (
    ActivityGenerator,
    ActivityMetrics,
    ActivityParser,
    ElementStyle,
    ElevationGraphConfig,
    GeneratorConfig,
    GPXConfig,
    WatermarkConfig,
    create_element,
    default_viewport_callback,
    format_activity_type,
)

# Vytvoření metrik
metrics = ActivityMetrics(
    name="Nedělní procházka",
    activity_type="Chůze",
    distance=12345,  # Metry (12.3 km)
    moving_time=7173  # Sekundy (1h 59m 33s)
)

# Sestavení konfigurace a generátoru
config = GeneratorConfig(
    # Vlastní konfigurace GPX trasy (ZDE není potřeba)
    gpx=GPXConfig(),
    # Konfigurace grafu převýšení (pouze pro FIT a ZDE též není potřeba)
    elevation=ElevationGraphConfig(),
    # Vlastní konfigurace vodoznaku
    watermark=WatermarkConfig(),
    # Vykreslení prvků na obrázek
    # Název klíče musí odpovídat atributu v metrice!
    # Pokud je potřeba vlastní element, tak musí začínat prefixem: custom_
    elements={
        # Název aktivity
        "name": ElementStyle(
            is_absolute=True,
            value_pos=(360, 1180),
            value_font_size=40,
            auto_shrink=True,  # Když bude text dlouhý, tak se začne změnšovat
            value_color=(255, 255, 255, 255)
        ),
        # Typ aktivity
        "activity_type": create_element("Aktivita"),
        # Ikonka pro typ
        "custom_activity_type_marker": create_element(
            "🎯",
            is_absolute=True,
            take_pos_y_from_prev_label=True
        ),
        # Vzdálenost
        "distance": create_element("Vzdálenost"),
        # Ikonka pro vzdálenost
        "custom_distance_marker": create_element(
            "📍",
            is_absolute=True,
            take_pos_y_from_prev_label=True
        ),
        # Čas pohybu
        "moving_time": create_element("Čas"),
        # Ikonka pro čas pohybu
        "custom_moving_time_marker": create_element(
            "🕒",
            is_absolute=True,
            take_pos_y_from_prev_label=True
        )
    }
)

# Uložení obrázku
generator = ActivityGenerator(metrics=metrics, config=config)
generator.save(output_path="vystup.jpg", quality=90)
```
#### B) Načtení vlastního FIT souboru:
- Bude použit stejný kód jako v bodě (A), ale musí se udělat několik úprav.
- Celý objekt s metrikami se vytvoří z FIT souboru, takže není ho potřeba vytvářet ručně.
##### Přidání mapování typu aktivity:
Protože FIT soubor má vlastní typy, tak se hodnoty musí přemapovat na vlastní název.
```python
ACTIVITY_MAPPING: dict[str | None, str] = {
    "walk": "Chůze",
    "walking": "Chůze",
    "run": "Běh",
    "running": "Běh"
}
```
##### Načtení FIT souboru a metrik:
Místo vytvoření vlastních metrik je načteme z FIT souboru.
```python
# Načtení FIT souboru a těžba dat
fit_file = Path("activity.fit")
fit_data = ActivityParser().parse_fit(fit_file)

# Získání metrik s možností je přepsat
metrics = fit_data.metrics
metrics.name = "Název aktivity"  # FIT neobsahuje název
```
##### Úprava konfigurace - GeneratorConfig:
Do `GeneratorConfig` přidáme následující konfiguraci. Pro ukázku obsahuje více věcí, které lze taky nastavit.
```python
# Obecná konfigurace
edge_vignette=False,  # Okraje obrázku nebudou mít gradient
elevation_graph_enabled=True,  # Vygeneruje graf převýšení
# Konfigurace GPX trasy
gpx=GPXConfig(
    gpx_enabled=True,  # Povolí vykreslení trasy
    gpx_path=fit_file,  # Může být GPX i FIT
    gpx_points=fit_data.gpx_points,  # Musí být vždy vyplněno
    gpx_points_with_elev=fit_data.gpx_points_with_elev,  # Tohle pouze pro FIT, protože GPX nemá převýšení
    # Pokud se generuje i graf převýšení, tak je dobré použít vlastní viewport, aby trasa nezasahovala do grafu
    viewport=default_viewport_callback,
    show_start_finish=True,  # Vykreslí začátek a konec trasy
    show_km_markers=True  # Vykreslí kilometrové značky na trase
),
# Konfigurace grafu převýšení (pouze pro FIT)
elevation=ElevationGraphConfig(
    show_bubble_interval=True,  # Značky každých N-km
    show_bubble_extreme=True  # Značka na nejvyšším a nejnižším místě
),
```
##### Úprava activity_type v elements:
Aby bylo možné použít vlastní mapování pro typ aktivity, tak musíme přidat mapper.
```python
"activity_type": create_element(
    "Aktivita",
    formatter=lambda _cfg, _met, val: format_activity_type(val, ACTIVITY_MAPPING),
),
```
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.
