Skip to main content

Merge multiple GPX files into one continuous route, removing duplicates and bridging gaps

Project description

smart-gpx-merge

Merge multiple overlapping GPX files into a single continuous route — no straight lines, no duplicates.

Most GPX merge approaches draw straight lines between disconnected segments. smart-gpx-merge bridges gaps by retracing existing trail, producing a clean map you can load in offline GPX apps or print with topo contour lines.

Built for combining trail running / hiking GPS tracks from the same area (e.g., a mountain with many trails) into one unified map.

use with claude code

Features

  • Duplicate removal — detects overlapping trail segments using spatial proximity and keeps only unique coverage
  • Straight-line artifact removal — splits segments where GPS jumped (large gaps between consecutive points)
  • Gap bridging — connects disjoint segments by retracing existing trail instead of drawing straight lines
  • Downsampling — reduces point density from high-frequency GPS recordings while preserving trail shape
  • Zero dependencies — pure Python 3, uses only the standard library

How It Works

Input: Multiple GPX files with overlapping routes
                    │
     1. Parse all track segments from all files
     2. Split segments at GPS jumps (straight-line artifacts)
     3. Downsample dense GPS recordings
     4. Deduplicate — keep segments that add new trail coverage
     5. Build a trail graph with junction connections
     6. Order segments to minimize gaps
     7. Bridge gaps via shortest path through existing trail
                    │
Output: One continuous GPX track covering all unique routes

Installation

# Using uv (recommended)
uv tool install smart-gpx-merge    # from PyPI
uv tool install .                   # from source

# Using pip
pip install smart-gpx-merge        # from PyPI
pip install .                       # from source

# Or run directly without installing
python3 smart_gpx_merge.py [args]

Usage

# Merge all .gpx files in a directory
smart-gpx-merge ./my_tracks/

# Merge specific files
smart-gpx-merge track1.gpx track2.gpx track3.gpx

# Custom output file and track name
smart-gpx-merge *.gpx -o merged.gpx --name "My Trail Map"

# Tune thresholds
smart-gpx-merge *.gpx --dup-radius 20 --gap-threshold 150

# Crop to a specific area and drop isolated segments
smart-gpx-merge *.gpx --bbox 10.505,107.10,10.56,107.155 --drop-isolated

Options

Flag Default Description
-o, --output merged_all_routes.gpx Output file path
--name Merged Mountain Routes Track name in the output GPX
--dup-radius 15 Radius (m) to consider two points as the same location
--gap-threshold 100 Max gap (m) between consecutive points before splitting a segment
--junction-radius 25 Radius (m) to connect trail junctions across different segments
--min-points 5 Minimum points for a segment to be kept
--downsample 8 Minimum spacing (m) between points after downsampling
--bbox none Crop to bounding box: south,west,north,east
--drop-isolated off Drop segments that can't be bridged through existing trail

Example

Merging 4 GPX files with overlapping trail runs on the same mountain:

smart-gpx-merge ./tracks/ -o merged.gpx --name "Mountain Trails"
📂 route_a.gpx:          1 segment, 58,000 points
📂 route_b.gpx:          1 segment, 10,000 points
📂 route_c.gpx:          1 segment, 16,000 points
📂 previous_merged.gpx:  7 segments,  3,800 points

→ Deduplicated to 4 unique segments (6 discarded)
→ Bridged 2 gaps via existing trail
→ Output: 1 continuous track, ~7,200 points

Tips

  • Duplicate radius (--dup-radius): Increase if parallel trails are being kept as separate segments. Decrease if distinct nearby trails are being merged incorrectly.
  • Gap threshold (--gap-threshold): Lower this if you see GPS jumps that aren't being caught. Raise if legitimate trail sections are being split.
  • Junction radius (--junction-radius): Controls how far apart two points from different segments can be and still be considered the same trail junction. Affects gap bridging quality.

Use with AI Agents

Option A: Claude Code Skill (no install needed)

Copy the skills/merge-gpx folder into your Claude Code skills directory:

mkdir -p ~/.claude/skills
cp -r skills/merge-gpx ~/.claude/skills/merge-gpx

Then use /merge-gpx in Claude Code. The skill bundles the Python script — no pip install required.

Option B: Any AI Agent

Install the CLI tool:

pip install smart-gpx-merge

Then add the following to your agent's instruction file (CLAUDE.md, AGENTS.md, .cursorrules, etc.):

## GPX Merge Tool

`smart-gpx-merge` is installed as a CLI tool for merging multiple GPX files.

Usage: smart-gpx-merge <inputs> [options]

Key flags:
- `-o, --output` — output file (default: merged_all_routes.gpx)
- `--dup-radius` — dedup radius in meters (default: 15)
- `--gap-threshold` — max gap before splitting (default: 100)
- `--bbox south,west,north,east` — crop to area
- `--drop-isolated` — remove unbridgeable segments
- `--name` — track name in output

Examples:
  smart-gpx-merge ./tracks/ -o merged.gpx
  smart-gpx-merge *.gpx --bbox 10.5,107.1,10.55,107.15 --drop-isolated

Works with any AI agent that has shell access (Claude Code, Cursor, Windsurf, Cline, etc.).

Requirements

  • Python 3.8+
  • No external dependencies

Acknowledgements

Built with Claude Code by Anthropic.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

smart_gpx_merge-0.1.1.tar.gz (9.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

smart_gpx_merge-0.1.1-py3-none-any.whl (10.4 kB view details)

Uploaded Python 3

File details

Details for the file smart_gpx_merge-0.1.1.tar.gz.

File metadata

  • Download URL: smart_gpx_merge-0.1.1.tar.gz
  • Upload date:
  • Size: 9.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.10

File hashes

Hashes for smart_gpx_merge-0.1.1.tar.gz
Algorithm Hash digest
SHA256 d445e3ac516d36bac3eecabb3e98ff9ce0a68342af906d9f69cd4a37c0572584
MD5 ecdeb33afaae7aed5db99f6324f580d3
BLAKE2b-256 8dd9237663125e6b7ae1f44f881f18f7cb3ec9732e4a0202d5928032875dfa59

See more details on using hashes here.

File details

Details for the file smart_gpx_merge-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for smart_gpx_merge-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 04f8fee15750aa217deae2e96215e03fc4645565c9026f1e26d84a08440023a5
MD5 3508463556db52563a534a68e521d85a
BLAKE2b-256 13ee23abe4ca088cf10b21fbbf3328967ce91565c3d4629a9617f8ab235640cf

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page