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: route or point → GPX + POIs; Expert: track or point search; Profiles: add POI types from the built-in catalog.
  • Android app — Easy and POI Enricher support point/Maps link searches.
  • 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 — choose Route for Maps directions → GPX(s) + POIs, or Point for coordinates/a Maps place link → POI-only GPX. Point radius comes from the profile. Route mode also supports alternates, detours, and milestones. Progress log + file list; cancel after the current 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.16.0

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.16.0
File Size Uploaded
gpx_poi_enricher-1.16.0.tar.gz 712.6 kB Details

Built distribution (wheel)

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

Total release size: 782.2 kB

Release files / gpx_poi_enricher-1.16.0.tar.gz

Download URL gpx_poi_enricher-1.16.0.tar.gz
Size 712.6 kB
Tags Source
SHA-256 checksum
How to use checksums
8c123aa21f6d609db9ea894d0451dc6a29b95068d30ac09b4a93340c8d9225cd
BLAKE2b-256 checksum
How to use checksums
7f002ee8a330a708787223be5bae224d9e86ba5ad458037ae62655a60f65908d
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.16.0-py3-none-any.whl

Download URL gpx_poi_enricher-1.16.0-py3-none-any.whl
Size 69.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
45f5f9fb7bb4531aad2e664ee6329ecd3952a8e4810a55a75db15665d0480e99
BLAKE2b-256 checksum
How to use checksums
961a66558c815d24fdca0f7994f599e6356799e8c98b41a2a4a1ffac949d0435
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.16.0 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