Skip to content

Repository files navigation

Garmin Activity Toolkit

Parse Garmin FIT files and visualize your outdoor activities as interactive maps, health dashboards, and high-resolution printable posters.

What it does

  • Interactive Map -- self-contained HTML map (Leaflet.js) with sport/person filters and a timeline slider
  • Print Generator -- 300 DPI poster-quality PNGs in 4 visual themes, ready for print shops
  • Health Dashboard -- Chart.js dashboard with heart rate, distance, elevation, and training load trends

Quick start

# 1. Install dependencies
pip install -r requirements.txt

# 2. Place your .fit files in fit_files/ (subfolders per person work too)
mkdir -p fit_files
#    fit_files/
#    |-- alice/
#    |   |-- 2024-01-15_running.fit
#    |   +-- ...
#    +-- bob/
#        +-- ...

# 3. (Optional) Create a .env file for device-to-person mapping
cp .env.example .env
# Edit .env with your device serial numbers

# 4. Generate the interactive map
python garmin_map_builder.py

# 5. Generate a printable poster
python garmin_print_generator.py --theme dark --size A3 --city "MY CITY"

Setup

pip install -r requirements.txt

Dependencies: fitparse, Pillow, requests, numpy, scipy

Where to get FIT files

Export your activities from Garmin Connect:

  1. Go to Activities > select an activity > gear icon > Export Original
  2. Or use garmin-connect-export for bulk export

Place .fit files in the fit_files/ directory. Subdirectories per person are supported.

Device owner mapping

Create a .env file in the project root to map Garmin device serial numbers to names:

DEVICE_OWNERS=1234567890:Alice,9876543210:Bob

You can find your device serial in Garmin Connect or by inspecting the file_id message in any FIT file. If no .env is provided, activities are labeled "Unknown" unless organized into named subfolders under fit_files/.

Scripts

garmin_map_builder.py -- Interactive HTML map

Generates a self-contained HTML file with a dark-themed Leaflet map showing all GPS activities.

python garmin_map_builder.py           # build from cache
python garmin_map_builder.py --force   # re-parse all FIT files

Features:

  • Filter by sport type and person
  • Timeline slider with cumulative/monthly playback
  • Click any route for details (distance, duration, elevation, heart rate, speed, calories)
  • GPS track simplification for compact file size (~2 MB for 500+ activities)

garmin_print_generator.py -- Printable posters

Generates high-resolution PNG images suitable for printing at A3, A2, or A1 sizes.

# Basic usage
python garmin_print_generator.py

# Choose a theme
python garmin_print_generator.py --theme dark          # map tiles + colored routes + glow
python garmin_print_generator.py --theme light         # light map tiles + muted routes
python garmin_print_generator.py --theme routes_only   # black background, glowing routes, no map
python garmin_print_generator.py --theme heatmap       # black background, warm color intensity map

# Crop to a specific area
python garmin_print_generator.py --bbox 46.0 10.0 48.5 13.0

# Filter by person or sport
python garmin_print_generator.py --person Alice --sport Running Hiking

# Large poster
python garmin_print_generator.py --theme routes_only --size A1 --orientation landscape

# Quick preview (72 DPI, much faster)
python garmin_print_generator.py --preview

# Customize text overlay
python garmin_print_generator.py --city "BAVARIAN ALPS" --no-stats

All options:

Flag Description Default
--theme dark, light, routes_only, heatmap dark
--size A3, A2, A1 A3
--orientation portrait, landscape portrait
--dpi DPI override 300
--bbox Crop: LAT_S LON_W LAT_N LON_E auto-fit
--center / --zoom Center point + zoom level (8-18) auto-fit
--sport Filter by sport(s) all
--person Filter by person name all
--city City name in overlay MY CITY
--no-text Disable all text overlays
--no-legend Disable sport legend
--no-stats Disable stats line
--preview Fast 72 DPI preview
--force Re-parse all FIT files
--output Custom output path auto-generated

Output goes to output/ (gitignored).

garmin_health_dashboard.py -- Health dashboard

Generates an HTML dashboard from all FIT files (including indoor/no-GPS activities).

python garmin_health_dashboard.py

Charts include: activity calendar, heart rate trends, weekly training volume, stress levels, daily steps, HR zone distribution, training load (TRIMP), seasonal sport mix, and recovery gap patterns.

garmin_data.py -- Shared data module

Shared FIT parsing, sport classification, track simplification, and caching used by all other scripts. Not run directly.

organize_fit_files.py -- File organizer

One-time utility to sort a flat directory of FIT files into per-person subfolders based on device serial numbers or filename patterns.

How it works

  1. FIT parsing -- reads binary Garmin FIT files via fitparse, extracts GPS tracks, session metadata (distance, HR, elevation, calories), and device serial numbers
  2. Sport classification -- maps Garmin sport/sub_sport/name fields to display categories (Road Cycling, Trail Running, Hiking, etc.) with support for German sport names
  3. GPS cleanup -- filters GPS spikes, then applies Douglas-Peucker simplification for the interactive map (raw tracks are preserved for print quality)
  4. Caching -- parsed results are cached in .garmin_cache.json (keyed by file path, mtime, and size) so repeat runs are instant
  5. Tile fetching -- print generator downloads CartoDB map tiles and stitches them into a base image using Web Mercator projection
  6. Route rendering -- Pillow draws anti-aliased polylines (2x supersampling + LANCZOS downscale) with optional glow effect
  7. Heatmap -- numpy float32 accumulator with Gaussian blur, mapped to a warm color gradient

Project structure

garmin-activity-toolkit/
|-- garmin_data.py               # Shared: FIT parsing, caching, constants
|-- garmin_map_builder.py        # Interactive Leaflet HTML map
|-- garmin_print_generator.py    # 300 DPI printable poster PNGs
|-- garmin_health_dashboard.py   # Chart.js health dashboard
|-- organize_fit_files.py        # One-time: sort FIT files into subfolders
|-- requirements.txt
|-- .env.example                 # Template for device serial -> person mapping
|-- fit_files/                   # Your FIT files go here (not tracked)
+-- output/                      # Generated print PNGs (not tracked)

Map tiles

The print generator uses free CartoDB basemap tiles (dark_nolabels and light_nolabels variants with @2x retina resolution). No API key required. Tiles are fetched on demand with concurrent downloads and cached locally in .tile_cache/.

License

MIT

About

Parse Garmin FIT files and visualize activities as interactive maps, health dashboards, and printable posters

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages