GPX Utility Analyzer

A full-stack platform for analyzing, processing and visualizing GPX activity files. Combines a .NET CLI for track statistics, AI-powered analysis for intelligent reports, and a web application with an interactive sport dashboard.
Published online documentation: https://jchable.github.io/gpx-utility-analyzer/
Projects
cli/ — gpx-analyzer (.NET)
.NET CLI tool for analyzing GPX files: distance, elevation gain/loss, speed, stop detection, biometrics (heart rate, power, cadence, temperature from GPX extensions), time-based splitting, file merging. Includes altitude correction using a digital elevation model (SRTM). Built as a Native AOT single-file executable with no runtime dependency.
Install (Windows) — available on winget:
winget install Coderise.gpx-analyzer
Or build and run from source:
cd cli
dotnet build src/GpxAnalyzer.Cli/
dotnet run --project src/GpxAnalyzer.Cli/ -- analyze my-hike.gpx
See cli/README.md for build, publish and test instructions.
ai-analyzer/ — gpx-ai-analyzer (.NET)
.NET CLI tool using Microsoft.Extensions.AI to produce intelligent analysis reports (difficulty, key segments, recommendations) from GPX statistics. Supports multiple AI providers (Azure OpenAI, OpenAI, Anthropic, Mistral, Ollama, Gemini).
# Pipeline: CLI statistics → .NET AI analysis
cli/gpx-analyzer analyze --format json track.gpx | ai-analyzer/gpx-ai-analyzer analyze --provider azure-openai
See ai-analyzer/README.md for complete documentation.
ui/ — Web Application
Full-stack web application with a sport dashboard UI inspired by Garmin Connect.
API — ui/api/ (ASP.NET Core)
REST API that orchestrates GPX analysis and AI reports with background processing.
- Multi-user: ASP.NET Identity, JWT Bearer auth, role-based access (Admin, Premium, User)
- Activity management: upload GPX, list/view/delete activities, download GPX files, re-analyze
- Dashboard: aggregated statistics (total distance, elevation, time, activity breakdown)
- Background processing: async pipeline via
Channel — GPX analysis then AI report generation
- Storage abstraction: local filesystem (dev) or RustFS/S3-compatible object storage (prod)
- Email service: NoOp (dev) or SMTP via MailKit (prod)
- External integrations: Strava / Garmin + webhook for automatic activity import
- Dual database: SQLite (development) / PostgreSQL (production) via EF Core
dotnet run --project ui/api/GpxAnalyzer.Api.csproj # http://localhost:5000
Local configuration
appsettings.json is committed without secrets. For local development, copy the example and fill in your own values:
cp ui/api/appsettings.Development.json.example ui/api/appsettings.Development.json
Required values:
Jwt:Secret — random string ≥32 characters (used to sign JWTs)
AiProvider:ApiKey — API key for the chosen provider (Gemini, OpenAI, Anthropic, etc.)
Integrations:Strava:ClientId / ClientSecret — only if you use Strava import
appsettings.Development.json is gitignored. In production, prefer environment variables (Jwt__Secret, AiProvider__ApiKey, …) over a file.
For Docker, create a .env file at the repo root:
JWT_SECRET=
AI_API_KEY=
AI_MODEL=gemini-2.5-flash
STRAVA_CLIENT_ID=
STRAVA_CLIENT_SECRET=
Single-page application built with React 19, TypeScript 5.9, Vite 7 and TailwindCSS v4.
- Dashboard: summary stats with radial gauges, activity type breakdown (donut chart), recent activities
- Activity detail: interactive 3D map (MapLibre GL JS), elevation/speed/GAP profile chart (Recharts), AI analysis panel, biometric stats
- Map views: 3D terrain, 3D satellite, 2D OpenTopo — with DEM terrain exaggeration
- Elevation chart: elevation area + speed line + GAP (Grade Adjusted Pace via Minetti model), togglable layers
- Live status: auto-refresh during processing (Pending → Analyzing → AI Processing → Completed)
- Activity types: run, trail, hike, cycle, walk, swim — each with dedicated color and icon
cd ui/client
npm install
npm run dev # http://localhost:5173 (proxies /api → :5000)
npm run build # Production build
docs/ — Documentation (Docusaurus)
Project documentation deployed to GitHub Pages. Content synced from sub-project READMEs.
cd docs
npm install
npm run start
Docker
Development (SQLite + local storage):
docker compose up --build
# API on :5000, client on :8081, RustFS console on :9001
Production (PostgreSQL):
docker compose -f docker-compose.yml -f docker-compose.prod.yml up --build -d
# API on :5000, client on :80, PostgreSQL on :5432
To enable RustFS S3 object storage, add these env vars to the api service in docker-compose.yml:
- Storage__Type=s3
- Storage__S3__Endpoint=http://rustfs:9000
- Storage__S3__AccessKey=rustfsadmin
- Storage__S3__SecretKey=rustfsadmin
- Storage__S3__BucketName=gpx-files
The API image is a 2-stage build: .NET publish → ASP.NET runtime.
See Web App docs for the full deployment and configuration reference.
Tech Stack
| Layer | Technologies |
|---|
| CLI | .NET 9, Native AOT, System.CommandLine, SRTM/HGT |
| AI Analysis | .NET 9, Microsoft.Extensions.AI, multi-provider (Azure OpenAI, OpenAI, Anthropic, Mistral, Ollama, Gemini) |
| API | ASP.NET Core 9, EF Core (SQLite/PostgreSQL), ASP.NET Identity + JWT, AWSSDK.S3, MailKit |
| Frontend | React 19, TypeScript 5.9, Vite 7, TailwindCSS v4, MapLibre GL JS, Recharts, TanStack Query |
| Storage | Local filesystem (dev) / RustFS S3-compatible (prod) |
| Infra | Docker Compose, nginx, GitHub Actions |
Contributing
Contributions are welcome! Please read the Contributing Guide to get
started — it covers the development setup, build/test commands, coding and commit
conventions, and the DCO sign-off (git commit -s) required on every commit.
By participating you agree to abide by our Code of Conduct.
Community & Support
Changes are tracked in the CHANGELOG.
License
This project is licensed under the GNU Affero General Public License v3.0 — see the
LICENSE file for details.