Skip to main content

gpx-poi-enricher

CLI tools and apps for finding OpenStreetMap POIs along a track or around a Google Maps place.

CI Python 3.10+ License: MIT PyPI


Table of Contents


The Pipeline

Google Maps directions ── maps-to-gpx ── routed GPX ─┐
                                                     ├─ gpx-poi-enricher ── POI waypoints
Track GPX ──────────────────────────────────────────┤
Google Maps place / coordinates ────────────────────┘
      │
      ▼
 waypoints.gpx        ← Garmin / OsmAnd / Google My Maps <https://www.google.com/mymaps>

All three commands install together and can be run alone or chained. Split and POI output are waypoints-only GPX (no <trk>) — import alongside the route file or merge externally. Files

5 MB? Try https://www.gpxtokml.com/.


Features

  • maps-to-gpx — Google Maps URL (incl. maps.app.goo.gl) → routed GPX via Nominatim + public OSRM; custom base URL via OSRM_BASE_URL or --osrm-base-url. No API keys for defaults.
  • gpx-split-waypoints — evenly spaced split <wpt> markers for waypoint-limited apps.
  • gpx-poi-enricher — OSM POIs along a track or around a point; 10 curated YAML profiles plus a POI catalog (~95 common types); --quick for sparse smoke tests.
  • GUI (gpx-poi-enricher-gui) — Easy: URL → GPX(s) → POIs; Expert: track or point search; Profiles: add POI types from the built-in catalog.
  • Android app — POI Enricher accepts a track GPX or a point/Maps link.
  • Country-aware terms (DE, FR, ES, EN); Overpass mirrors with retries; per-profile defaults overridable on the CLI; custom YAML via GPX_POI_PROFILES_DIR.

Installation

Python 3.10+. Use an isolated install — system Python is often externally managed on Linux. Recommended: venv + pip:

python3 -m venv .venv && source .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install gpx-poi-enricher              # CLI
pip install "gpx-poi-enricher[gui]"       # CLI + PyQt6 GUI

Alternatives: pipx install "gpx-poi-enricher[gui]" (no activate); or uv tool install "gpx-poi-enricher[gui]" with uv.

Development

git clone https://github.com/devmarkusb/gpx-poi-enricher.git && cd gpx-poi-enricher
uv sync --extra dev --extra gui   # .venv + editable install (matches CI)
./scripts/setup-pre-commit.sh
uv run pytest                     # uv run <cmd> works without activating .venv

Without uv: venv + pip install -e ".[dev,gui]". See CONTRIBUTING.md.


Quick Start

Google Maps URL → campsite waypoints:

maps-to-gpx "https://www.google.com/maps/dir/Paris/Lyon/Barcelona/" route.gpx
gpx-split-waypoints route.gpx route-split.gpx 10    # optional split markers
gpx-poi-enricher route.gpx camping.gpx --profile camping

GUI

gpx-poi-enricher-gui          # requires [gui] extra — see Installation
gpx-poi-enricher-gui --quick  # sparse enrichment ([quick] in title bar)

From a clone: uv run gpx-poi-enricher-gui.

macOS app bundle (Finder/Dock icon, double-click): after uv sync --extra gui, run uv run python scripts/build_macos_app.py → dist/GPX POI Enricher.app. Drag to Applications or Dock. Rebuild after upgrading the package in .venv.

Easy — one primary Maps URL (required), optional extra URLs per line → routed GPX(s), optional alternate/detour GPX files, then POI enrichment. Progress log + file list; cancel after current Overpass batch.

Expert — POI Enricher, Split Waypoints, Maps → GPX, and Profiles tabs (same CLIs; Maps tab supports multiple URLs like Easy). Profiles → Add from catalog… adds common OSM POI types (museums, pharmacies, viewpoints, …) as editable user profiles. POI Enricher accepts a track GPX or a point/Maps link. Long-running work is off the UI thread.


Environment variables

GPX_POI_PROFILES_DIR — existing directory of *.yaml replaces built-in profiles.

OSRM_BASE_URL — OSRM root ending in /route/v1 for maps-to-gpx (override with --osrm-base-url).


Command: maps-to-gpx

One Google Maps directions URL → routed GPX (<trk> + stopover <wpt>). Short links, path-style (/maps/dir/A/B/C), and query-style (?api=1&origin=…) URLs. Names → Nominatim; routing → public OSRM or your own stack. Multiple routes/detours: use the GUI.

Run maps-to-gpx --help for --mode, --name, --osrm-base-url.

maps-to-gpx "https://www.google.com/maps/dir/Paris/Lyon/Marseille/" route.gpx
maps-to-gpx "https://maps.app.goo.gl/ABC123" route.gpx
maps-to-gpx "https://www.google.com/maps/dir/Amsterdam/Utrecht/" route.gpx --mode cycling
maps-to-gpx "https://www.google.com/maps/dir/A/B/" route.gpx \
  --osrm-base-url "https://my-osrm.example.com/route/v1"   # must end with /route/v1

Command: gpx-split-waypoints

Track → segments − 1 evenly spaced waypoints (Split 1, …); description holds track position (e.g. 10.0% of track length). Waypoints only — companion file, not the original track. segments >= 2.

gpx-split-waypoints route.gpx route-split.gpx       # 10 segments → 9 waypoints (default)
gpx-split-waypoints route.gpx route-split.gpx 5   # 5 segments → 4 waypoints

Command: gpx-poi-enricher

Track GPX or point in → waypoints-only POI GPX out. A point may be LAT,LON or a Google Maps place link. Run gpx-poi-enricher --help for all flags.

  • --profile — required unless --list-profiles
  • --max-km — max distance from track, or radius around a point
  • --sample-km — sampling step along a track (unused for a point)
  • --output — output GPX path with --point
  • --batch-size — sample points per Overpass request
  • --country-sample-km — spacing between track country lookups (default 40; 500 with --quick)
  • --point — LAT,LON or a Google Maps place link; pair with --output
  • --progress-interval — stderr progress in seconds (0 off; default 5)
  • --verbose — verbose Overpass error bodies (track searches only)
  • --list-profiles — list profiles and defaults, then exit
  • --quick — sparse track defaults and a 1 km radius (including point searches), unless overridden
gpx-poi-enricher route.gpx camping.gpx --profile camping
gpx-poi-enricher route.gpx playgrounds.gpx --profile playground --max-km 5
gpx-poi-enricher --point '52.038993,13.748653' --output aquariums.gpx --profile aquarium
gpx-poi-enricher --point 'https://maps.app.goo.gl/JDocHptvdByZ1WZSA' \
  --output aquariums.gpx --profile aquarium
gpx-poi-enricher --list-profiles
gpx-poi-enricher route.gpx probe.gpx --profile camping --quick

Built-in Profiles

From profiles/. gpx-poi-enricher --list-profiles shows sample_km, batch_size, retries.

Profile Description (YAML) Default max_km
camping Campsite 10.0
playground Playground 3.0
outdoor_pool Outdoor Pool, Adventure Pool, Thermal Bath 10.0
beach Swimming Lake, Beach 20.0
theme_park Theme Park 12.0
zoo Zoo, Petting Zoo 12.0
aquarium Aquarium 15.0
mcdonalds McDonalds 5.0
restaurant Restaurant 2.0
kids_activities Children's Activities of All Kinds 15.0

kids_activities matches mainly via terms (regex on OSM name / description / operator); most others use tags, optionally plus terms.


POI catalog

Besides the curated built-ins above, the app ships a catalog of ~95 common OSM POI types (restaurants, museums, pharmacies, viewpoints, …) in src/gpx_poi_enricher/data/poi_catalog.yaml.

Desktop GUI: Expert → Profiles → Add from catalog… — searchable list by category. Android: Profiles tab → Add from catalog…

Choosing an entry writes a user profile YAML with:

  • OSM tags from the catalog entry
  • defaults from a preset bucket (urban_dense, regional_sparse, …) — e.g. tight radius for shops, wider radius for zoos
  • empty terms (tag-only search; edit later if you need name matching)

If the profile id already exists (e.g. built-in aquarium), saving from the catalog creates a user override with the same id. You can edit radius, symbols, or add terms afterward.

Programmatic use:

from gpx_poi_enricher.poi_catalog import save_catalog_entry

save_catalog_entry("museum")  # writes ~/.config/gpx-poi-enricher/profiles/museum.yaml (desktop)

Creating Custom Profiles

Easiest: use Add from catalog… in the GUI (see POI catalog) for standard OSM types, then edit the generated YAML if needed.

Manual: add a YAML file; id or filename (without .yaml) is the profile id. With PyPI installs, set GPX_POI_PROFILES_DIR to use only your profiles.

# profiles/my_profile.yaml
id: my_profile
description: "My custom POI type"
symbol: Flag, Blue          # Garmin symbol in output GPX

defaults:
  max_km: 8.0
  sample_km: 4.0
  batch_size: 5
  retries: 3

tags:                       # any tag line can match
  - key: tourism
    value: museum
  - key: amenity
    value: fast_food
    and:
      key: cuisine
      value: pizza

terms:                      # regex selectors (per country + EN)
  DE: ["Museum", "Schloss"]
  FR: ["musée", "château"]
  ES: ["museo", "castillo"]
  EN: ["museum", "castle"]

Need non-empty tags or terms for the current country plus EN (else query build fails). defaults keys are overridable on the CLI.


How It Works

maps-to-gpx: expand short URLs → parse path/query (geocode names, keep coords) → OSRM route → GPX <trk> + stopover <wpt>.

POI enrichment: sample every sample_km → reverse-geocode country every country_sample_km → Overpass per batch (tags = typed selectors; terms = regex on name/description/operator within max_km) → dedupe by OSM id → <wpt> only. Mirrors rotate; retries on failure.


Data Attribution

Map data © OpenStreetMap contributors — ODbL. Nominatim — OSM Foundation. Routing — OSRM public demo (ODbL).

Usage policies: Nominatim ~1 req/s + meaningful User-Agent (this project sends one); Overpass — no bulk scraping; OSRM demo — personal/non-commercial; use OSRM_BASE_URL / --osrm-base-url for heavy use.


Contributing

See CONTRIBUTING.md. Issues: GitHub.


License

MIT — LICENSE.

Metadata

Release files for gpx-poi-enricher 1.15.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for gpx-poi-enricher 1.15.1
File Size Uploaded
gpx_poi_enricher-1.15.1.tar.gz 710.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for gpx-poi-enricher 1.15.1
File Interpreter ABI Platform
gpx_poi_enricher-1.15.1-py3-none-any.whl Python 3 none any Details

Total release size: 779.6 kB

Release files / gpx_poi_enricher-1.15.1.tar.gz

Download URL gpx_poi_enricher-1.15.1.tar.gz
Size 710.6 kB
Tags Source
SHA-256 checksum
How to use checksums
30d2553430e0c573ccb6dafda2ab3aa4c899a7bd295304fb8d56606f5f911bac
BLAKE2b-256 checksum
How to use checksums
9fc88bb74847ebc5aabe391ff7880265a00a8fe8fdfd0c14f58424fcfc2afa67
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release files / gpx_poi_enricher-1.15.1-py3-none-any.whl

Download URL gpx_poi_enricher-1.15.1-py3-none-any.whl
Size 69.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2c58acaa5078682c41ea78f620c43fa1ccf23547aecf1a760f4a1eb77010d3d7
BLAKE2b-256 checksum
How to use checksums
c64dd73250eb98ab31cbfa3d41641c06e4d0c4c6a6da4652014c81f4e9ae8b1a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.15.1 This release

2 release files

1.15.0

2 release files

1.14.0

2 release files

1.13.0

2 release files

1.12.1

2 release files

1.12.0

2 release files

1.11.2

2 release files

1.11.1

2 release files

1.11.0

2 release files

1.10.1

2 release files

1.10.0

2 release files

1.9.0

2 release files

1.8.1

2 release files

1.8.0

2 release files

1.7.1

2 release files

1.7.0

2 release files

1.6.2

2 release files

1.6.1

2 release files

1.6.0

2 release files

1.5.7

2 release files

1.5.6

2 release files

1.5.5

2 release files

1.5.4

2 release files

1.5.3

2 release files

1.5.2

2 release files

1.5.1

2 release files

1.5.0

2 release files

1.4.0

2 release files

1.3.0

2 release files

1.2.2

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page