3.7 KiB
Route Packager — OsmAnd + Google KMZ
This package contains route_packager.py, a Python CLI for the scraped route archive tree in v4-scrape-675.tar.gz.
What it does
- Scans the canonical
downloads_by_hash/folder by default, avoiding retry/failure duplicate folders. - Extracts ZIP, RAR, 7Z payloads.
- Imports GPX, KML, KMZ routes directly.
- Converts Garmin GDB to GPX when
gpsbabelis installed. - Carries over scrape metadata from
*.source.jsoninto route descriptions and reports. - Carries over small text files into route descriptions.
- Embeds image files into the KMZ and OSF package under
media/...and references them from descriptions. - Writes machine-readable
report.jsonandroutes.csvfor validation/pre-push review.
Outputs
Default command creates all of these:
<name>.osmand-tracks.osf— OsmAnd package/zip containing normalized GPX tracks.<name>.all-routes.gpx— fallback aggregate GPX for OsmAnd if the OSF package import is not accepted by a particular build.<name>.google-earth-maps.kmz— binary zipped KML package for Google My Maps / Google Earth.<name>.google-earth-maps.kml— plain KML fallback.<name>.report.json— full import/skip/warning report.<name>.routes.csv— route list with source archive, point count, distance, bbox, etc.
Install extraction/conversion tools
The script itself is stdlib-only for ZIP/KML/KMZ/GPX. RAR and GDB need external tools:
sudo apt update
sudo apt install p7zip-full unrar-free gpsbabel
If unrar-free fails on some RAR versions, install one of unrar, unar, or bsdtar depending on your distro.
Full run
python3 route_packager.py \
--input ./v4-scrape-675.tar.gz \
--out ./route-out \
--target both \
--name bg-mountain-routes \
--verbose
Google My Maps one-file safe mode
Google My Maps has a small uncompressed KML/KMZ import ceiling. For a single importable KMZ, use safe mode. It simplifies only the Google output; OsmAnd keeps full GPX detail.
python3 route_packager.py \
--input ./v4-scrape-675.tar.gz \
--out ./route-out-google-safe \
--target google \
--name bg-mountain-routes \
--google-my-maps-safe
Manual geometry cap if needed:
python3 route_packager.py --input ./v4-scrape-675.tar.gz --out ./out --target google \
--google-max-points-per-route 500 --google-lean-descriptions
ZIP-only validation without RAR tooling
python3 route_packager.py \
--input ./v4-scrape-675.tar.gz \
--out ./route-out-zip-only \
--target both \
--skip-rar \
--name bg-mountain-routes-zip-only
Strict CI/pre-push mode
python3 route_packager.py \
--input ./v4-scrape-675.tar.gz \
--out ./route-out \
--target both \
--name bg-mountain-routes \
--strict
--strict exits non-zero if RARs/GDBs fail to import.
Validation commands
python3 -m py_compile route_packager.py
python3 route_packager.py --input ./v4-scrape-675.tar.gz --out ./out --target both --skip-rar --name smoke
python3 - <<'PY'
from pathlib import Path
import zipfile, xml.etree.ElementTree as ET
out = Path('./out')
for name in ['smoke.osmand-tracks.osf', 'smoke.google-earth-maps.kmz']:
with zipfile.ZipFile(out / name) as z:
assert z.testzip() is None, name
ET.parse(out / 'smoke.all-routes.gpx')
with zipfile.ZipFile(out / 'smoke.google-earth-maps.kmz') as z:
ET.fromstring(z.read('doc.kml'))
print('OK')
PY
Format note
There is no arbitrary custom binary route format for Google Maps imports. KMZ is the practical binary container because it is zipped KML and can include images/media. For OsmAnd, the script emits an OSF-style package plus a GPX fallback because GPX is OsmAnd's most predictable track import path.