9.3 KiB
BGMountains Garmin IMG → native OSM → OsmAnd OBF — v0.92
v0.92 fixes the v0.8–v0.9 synthetic marker/marina fallback approach. It aims to create a native OsmAnd map without Garmin TYP icon PNGs or a custom .render.xml on the phone.
The only two user-editable translation files are:
config/poi-mapping.csv(Garmin point type → native OSM tag(s), Bulgarian naming prefix, legend, priority, historic icon pointer, example coordinates)config/line-mapping.csv(Garmin extended line type → OSM way tags, color-marked hiking relation policy andosmc:symbol)
Everything under the generated build/output directory is an intermediate or report, not a third configuration. You don't have to supply poi_types.xml, rendering_types.xml, an icons CSV or a custom rendering style.
Requirements
Ubuntu/Debian: sudo apt install build-essential cmake libpng-dev libsqlite3-dev python3 openjdk-21-jre-headless unzip
To compile an OBF, provide an official OsmAndMapCreator installation containing utilities.sh, or use the automatic download option (downloads from OsmAnd). Python, CMake and make by themselves do NOT build OBF.
Full map: one command
python3 scripts/build_bgmountains.py \
--img '/path/to/gmapsupp.img' \
--out './output' \
--creator '/path/to/OsmAndMapCreator'
If you don't have MapCreator:
python3 scripts/build_bgmountains.py \
--img '/path/to/gmapsupp.img' --out './output' --download-creator
It compiles C++, extracts the Garmin IMG to OSM, uses the two mapping files, assigns stable Bulgarian hashes to unnamed POIs, produces route relations, conservatively attaches matched overlays to actual highway=* ways, performs a semantic QA audit, and runs OsmAndMapCreator. The only file to copy onto your phone is the resulting .obf. Enable hiking routes and relevant POI filters in OsmAnd as necessary. No third-party icons or renderer file is included or required.
For a fast test that stops before the Java OBF stage:
python3 scripts/build_bgmountains.py \
--img '/path/to/gmapsupp.img' \
--out './vihren-test' --bbox '23.36,41.70,23.42,41.76' --prepare-only
Parallelism remains disabled by default (--jobs 1). For opt-in concurrent IMG extraction append --jobs 4. The Python mapping, relation, QA and Java steps are not parallelized by this switch.
Use --no-route-attachment to keep source overlay geometries as hiking-relation members instead of attaching matched real path/road ways. --keep-raw retains the intermediate IMG-native XML for debugging.
Editing the 2 CSV files
config/poi-mapping.csv
| Column | What it means |
|---|---|
code |
Garmin POI type, in hex; never changed in provenance |
source_count |
Count from source inventory; informational only |
legend_bg, legend_en |
Original BGMountains legend meaning (where verified) |
meaning_confidence |
legend / source_inferred; review unknowns |
osm_tags |
k=v;k=v for truthful standard OSM semantics; no fake category for icons |
label_bg |
Prefix for otherwise nameless objects, with deterministic alphanumeric suffix |
priority |
critical, normal or terrain; currently emits bgm:priority metadata |
zoom_hint |
Desirable zoom target for future style/QA work, not an OsmAnd override |
action |
replace removes earlier semantics, append keeps them, raw keeps provenance only, drop discards the POI |
legacy_icon |
TYP:<hex> reference for older Garmin icon, for auditing only |
example_lat, example_lon, example_name |
Sample place from original source inventory to inspect |
If a source code is known, edit osm_tags and set action=replace. Example: 0x6414 → amenity=drinking_water. If it isn't known, leave it as raw until you inspect the old legend and sample coordinates. Nothing will invent a marina, information board or drinking tap for an unknown symbol. You may append multiple compatible tags separated by semicolons.
Water/shelter priority rules already populated: 0x6414 drinking tap, 0x6511 spring, 0x6500 water intake, 0x6417 well, 0x6609 hut, 0x660a basic refuge, 0x661e shelter and 0x6402 building. For requested naming, unnamed 0x6402 uses the prefix „Заслон - Сграда“; its factual OSM classification stays building=yes (a generic building must not falsely be declared an actual lifesaving shelter). Verify shelter suitability on the ground before relying on it.
0x6600 numeric elevation labels preserve ele=* instead of being misclassified as peaks, buildings or missing POI categories. 0x650b winter waymarkers and 0x660b trail markers remain Garmin-sourced nodes rather than incorrect water/marina/guidepost POIs.
config/line-mapping.csv
| Column | Meaning |
|---|---|
code, source_count |
Garmin extended polyline code/count |
legend_bg, legacy_color |
Known description and source TYP base color |
osm_way_tags |
Additional truthful key=value;key=value tags on source ways |
route_mode |
relation builds OSM hiking routes; preserve keeps raw way without assuming it is a trail |
osmc_symbol |
Standard OSMC syntax, e.g. red:white:red_bar |
network |
lwn (local walking), change if there is evidence for a larger network |
route_confidence |
color_only means inferred from color but pattern not independently established |
priority |
Descriptive category only, not stock OsmAnd zoom control |
Colored candidate hiking overlays become type=route + route=hiking + osmc:symbol=* relations. All retain the original garmin:type and source line metadata. Matching route overlay lines to existing physical highway=* geometry avoids generating fake navigable duplicate paths. A physical road segment is used only if at least 90% of an overlay's segments match and the physical way extends at most 10% beyond it; unmatched overlays remain relation members, flagged in route-attachment.json.
A source color is not conclusive proof of a painted bar pattern. All automatic bar-style assignments from color-only evidence explicitly say route_confidence=color_only; check the original map and choose the right osmc_symbol for each code before treating that detail as verified. See OSM trail markings and OSMC symbol syntax.
New IMG / future map: generate blank templates
python3 scripts/build_bgmountains.py \
--img '/path/to/another-garmin.img' \
--out './new-map-template' --template
The result contains poi-mapping.TEMPLATE.csv with all discovered types, counts and sample POI coordinates, and line-mapping.TEMPLATE.csv with all discovered extended line types/counts. Unknowns start as action=raw, route_mode=preserve and without semantic tags. You must fill them based on that map's own legend and examples; BGMountains mappings must not be assumed to apply to another Garmin map. To build it, point --poi-config / --line-config to the new two reviewed files.
Outputs / validation
| Path | Purpose |
|---|---|
BGMountains-native.osm |
Final translated, standard-tagged OSM intermediate |
source-pois.csv |
Per-point source type, mapset, coordinates and name |
discovered-pois.csv |
Observed type inventory with up to 5 sample coordinates |
route-report.json |
Coloured overlays/route relation counts |
route-attachment.json |
Reused physical path vs unmatched overlay counts |
semantic-audit.json |
Detailed native category statistics, unknown types and example positions |
extract.log, translate.log, audit.log |
Pipeline logs |
mapcreator.log |
Java OBF build log when compilation is attempted |
obf-inspection.txt |
BinaryInspector POI summary (if inspector is installed) |
*.obf |
Final file for OsmAnd (only if MapCreator succeeds) |
Tests:
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j 2
ctest --test-dir build --output-on-failure
What native stock OsmAnd cannot guarantee
- OsmAnd's own rendering style controls icon selection, label collision and minimum zoom;
zoom_hint=12does not change it. To force all water/hut icons to zoom 11 or 12, a custom OsmAnd style/app configuration is unavoidable. v0.92 deliberately does not install one. - Not every valid OSM tag has a stock icon, especially water intakes, bridge points, elevation points and trail blazes. We prefer correct/metadata-only tags over false marinas/boards.
- A valid hiking relation is not a guarantee that stock OsmAnd renders every segment. Inspect
route-attachment.jsonand verify on-device. - The OSM file parser and XML/route structural tests do not establish that the POIs survived final OBF indexing. Use
mapcreator.log,obf-inspection.txtand actual OsmAnd app checks. We cannot claim a complete nationwide OBF was compiled/tested in this environment unless MapCreator is available. - Map-derived sample coordinates and legend crosswalk are subject to BGMountains data licensing; do not relicense or import them to public OSM automatically.
v0.92 does not use the Garmin icon PNGs or BGMountains-outdoor.render.xml. You may remove older BGMountains OBFS from OsmAnd to avoid duplicates before installing the new one.