[Norway] nvdb-incline: NVDB-based incline suggestions + snow-chain advisory points (JOSM plugin, tested and working)

Hi all,

Because Norwegian roads in OSM almost never have incline=* set, even though the underlying data exists: the original Elveg/NVDB road import only ever carried geometry, names, speed limits and height restrictions into OSM — gradient was never part of that workflow, and nobody’s gone back to add it since. NVDB’s road-link geometry has elevation (Z-values) along every link, so it’s derivable, it just hadn’t been extracted before.

I built this as an actual JOSM plugin, and it’s now tested and working.

Repo: GitHub - Supermagnum/josm-elevation: A JOSM plugin adding incline=* from NVDB (Nasjonal vegdatabank, run by Statens vegvesen) · GitHub

What it does

Inside JOSM, on your currently loaded/downloaded data:

NVDB 3D links → match to loaded OSM ways (nvdb:id + geometry) → gradient → chain heuristics → review dialog → accept/reject per item → applied as normal undoable edits

  • Fetches matching NVDB road-link geometry (with elevation) for your current working area via the NVDB API.
  • Matches OSM ways to NVDB links — using the existing nvdb:id tags left over from the original import where present, geometry matching otherwise, with a confidence score per match.
  • Computes gradient along each matched segment and produces a suggested incline=* value.
  • Flags candidate snow-chain fitting/removal points, based on sustained steep grade over a minimum distance, combined with context like mountain passes and tunnel portals.
  • Shows every suggestion in a review dialog before touching anything — nothing is applied silently.

Outputs

  • Accepted suggestions become ordinary tag changes / new nodes in your current edit layer, fully undoable with Ctrl+Z like any other edit
  • A confidence/summary view in the review dialog
  • Unmatched ways/links listed for manual follow-up
  • Nothing is uploaded — that only happens if and when you press Upload in JOSM yourself, same as any other edit

Important design decision: no automatic uploads

As a JOSM plugin, this is actually simpler to guarantee than in a separate tool: the plugin never calls JOSM’s upload action or the OSM API’s changeset endpoints itself. Every accepted suggestion becomes a normal Command on the local edit layer via JOSM’s own undo/redo system — exactly like typing a tag by hand — so it only ever reaches osm.org if and when you upload it yourself through JOSM’s regular Upload dialog. There’s also a regression test that fails the build if any upload/OAuth code path ever gets added. Every machine-suggested tag is marked as such (source:incline=nvdb_estimate plus a fixme=*/note=*) so nobody mistakes a computed value for a surveyed one.

Repo layout

core/     # gradient calc, matching, chain heuristics — plain JVM, no JOSM dependency
plugin/   # JOSM Plugin subclass, menu entry, review dialog, HTTP fetching
build.gradle
README.md

Status: tested and working

It’s been tested — test/output files are in the repo. Open to requested changes if something’s off or could be better; this is very much still a young project and I’d rather fix real problems now than after more people are relying on it.

A bigger suggestion: redo the NVDB import itself

Rather than this staying a bolt-on plugin people have to remember to run separately, I think there’s a case for redoing the original NVDB/Elveg import and merging elevation-derived data (incline, and potentially the sign-backed hazard/junction data) into the existing Norway road data directly, the same way geometry, names, speed limits and height restrictions were merged the first time round. A plugin is a good way to prototype and validate the approach locally, way by way, but if the matching and gradient logic proves reliable at scale, folding it into a proper coordinated import means every mapper benefits without needing this plugin installed at all. Happy to discuss what that would take — I’d guess the usual import-process requirements (community consultation, accuracy verification, gradual rollout) apply here just as they did before.

Where I’d still like input

  1. incline=* conventions — I know this tag is already a bit contested (see the wiki’s own note about disagreement on how seriously to treat it). Is a machine-generated starting point, clearly marked as unverified and requiring field confirmation before final upload, something this community finds useful, or is that the wrong approach for this tag?
  2. Snow-chain advisory points — there’s still no established OSM tag for “put on/take off snow chains here.” Current approach is a non-authoritative note=* + a custom chain_advisory=fit/remove tag, purely as a mapper hint, not something meant to go on the map as-is. Prior art or reasons this is a bad idea, welcome.
  3. Matching accuracy — geometry matching against NVDB where nvdb:id is missing is the trickiest part, and the part most relevant if an import-merge (above) is worth pursuing. If anyone’s done conflation work between OSM and NVDB before and has lessons learned, I’d love to hear them.
  4. Testers — I’d really appreciate a few more people trying it on a mountain-pass area they know well (Sogn, Valdres, Saltfjellet, etc.) and sanity-checking the review dialog’s suggestions against imagery and local knowledge before accepting anything.

Data source is NVDB (Statens Vegvesen), same as the original road import, released under NLOD with attribution required — that’s handled automatically in the output.

Will post progress updates in this thread. Feedback and criticism both very welcome.

Repo again: GitHub - Supermagnum/josm-elevation: A JOSM plugin adding incline=* from NVDB (Nasjonal vegdatabank, run by Statens vegvesen) · GitHub

Edit: It has been tested, and output test files can be found in the repo.

It now has the possibility to do: per-kommune download with real boundary clipping, local completion tracking.

Why suggestions can be negative (e.g. -5%)

Norwegian steep-grade road signs show a positive percent for how steep the road is in the direction you are driving. They do not display values like -5%.

OSM incline=* is different. It is defined relative to the way’s node order (first node → last node):

Suggested tag Meaning along the OSM way
incline=5% About 5% uphill from first node toward last node
incline=-5% About 5% downhill from first node toward last node

The plugin follows that OSM convention on purpose. Emitting only positive percentages (as on skilt) would drop direction and produce incorrect OSM data when the way is drawn downhill in node order. If the way were reversed in JOSM, the sign of incline=* should flip and the magnitude should stay the same.

Screenshots:

A compiled jar file is here for those who do not want to compile it:

Jeg synes ikke vi skal legge til dette i OSM.

  • Gode routere bruker heller terrengmodeller for å finne høydeforskjeller på veien. Terrengmodellene brukes i mange biler til å beregne strømforbruk på en rute, slik at forbruket tar hensyn til både stigning og fall samlet over ruten.
  • Veisegmenter i OSM slås ofte sammen, og da blir det fort rot med incline=*, som skal gjelde en bestemt strekning.
  • Taggen nvdb:id=* ble importert noen steder for mange år siden, men identifikatoren er i mellomtiden endret i NVDB, slik at taggen ikke kan brukes lenger. I tillegg stemmer ikke den gamle identifikatoren dersom en way har blitt endret i lengde i OSM etter importen. Jeg fjerner denne taggene der jeg ser den.
3 Likes

Denne kan gjøre det, den bruker høydedata fra Mapterhorn: GitHub - Supermagnum/Navi at dev · GitHub