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. Built for combining trail running / hiking GPS tracks from the same area (e.g., a mountain with many trails) into one unified map.
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
Claude Code
Add a CLAUDE.md to your project (see CLAUDE.md for an example). Claude Code reads this file at the start of every conversation, so it will know smart-gpx-merge is available and how to use it.
# Install the tool
pip install smart-gpx-merge
# Claude Code will then call it via Bash when working with GPX files
Other AI Agents
Any AI agent that can run shell commands can use it:
smart-gpx-merge ./tracks/ -o merged.gpx --drop-isolated
The CLAUDE.md file documents the CLI interface, flags, and common patterns for AI agent discoverability.
Requirements
- Python 3.8+
- No external dependencies
Acknowledgements
Built with Claude Code by Anthropic.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file smart_gpx_merge-0.1.0.tar.gz.
File metadata
- Download URL: smart_gpx_merge-0.1.0.tar.gz
- Upload date:
- Size: 9.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
708388b2a334d817113e928d9be52b8a61ce6336f816ad3b01f076d0e7ce40ff
|
|
| MD5 |
5255590d0d07a37903a767794b679b97
|
|
| BLAKE2b-256 |
5735b7adfe84b79163650bb717fb48262dce8915db97eb679c65620768ebc457
|
File details
Details for the file smart_gpx_merge-0.1.0-py3-none-any.whl.
File metadata
- Download URL: smart_gpx_merge-0.1.0-py3-none-any.whl
- Upload date:
- Size: 10.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b162f7ec1e6f0306b036e6c7b4c4065dc559c3ee73facb536a7b8542ced953c5
|
|
| MD5 |
b675fe0f59d4591d4acc938e23b58d6a
|
|
| BLAKE2b-256 |
ab8b9b2577b64f896167594f01bb23f38dca548fafb70b5049ae4c22b175cba8
|