Untagged and unconnected nodes

Nederland has cleaned out all its untagged + unconnected nodes. There were many, most were remainders of vey old landuse/natural imports. Also, the polygoncutout JOSM plugin leaves many untagged loose nodes, the idea is that JOSM validation finds them and you can remove them with a single click, but sometimes they are missed. And some versions of another tool for single building import appear to have left idle nodes. I looked around a bit, and other countries also have these idle nodes.

We did this in patches in a hands-on workflow, not a mass edit. We used the overpass-turbo query below, with JOSM. Note: this query uses an enormous amount of RAM, so the search area should not be wide. I’ll explain that below the query! If anyone can improve on this query, I would sure like to hear it!

The query (Updated 2026-03-23 20:04 (Dutch time) to also exclude untagged nodes with a role in a relation):

// Find unconnected nodes without tags within an area and within the map view.
// Settings
[out:xml][timeout:125];

// Find area with Nominatim

{{geocodeArea:Dortmund}}->.searchArea;

// Find nodes without tags

node(area.searchArea)({{bbox}}) (if: count_tags() == 0)->.candidates;

// Check if the candidates are in use by a parent way or relation, including long passing through ways.
// First, get the union of all the ways and relations for the candidate nodes, save to the parents set
(  way(bn.candidates); relation(bn.candidates); )->.parents;

// Get the union of the nodes of these ways and relations, save to the .used set
( node(w.parents); node(r.parents); )->.used;

// Select the .candidates that are not in the .used set
( .candidates; - .used; )->.unused;

// Output result
.unused out meta;

Explanation:
The main problem is to rule out nodes that are used by ways, including long ways. It’s easy to exclude ways that are actually in the search area, but long passing through ways are not present in the area, just a few nodes, which then appear to be unconnected. Pipelines, railways, highways, power lines, a lot actually.
So the query does a reverse lookup without bounds, to see which nodes belong to a way, any way. And that is the memory hungry part. I have tried doing it without intermediate sets, that is possible but then CPU is the bottle neck, which is worse than the RAM limit.

Our workflow, starting in overpass-turbo:

  • Zoom in
  • Run query
  • Export via remote control to a cleared JOSM
  • Select all (should not show any tags)
  • Get parents (should not produce any ways or relations)
  • Delete
  • Upload

(I tried Osmose first, but I couldn’t get it to export manageable chunks to JOSM).

2 Likes

you can use code block (``` before first line and after last one)

this will give you something like

.candidates;

* .used;
);
2 Likes

I’ve fixed that :smiley:

1 Like

it seems to miss nodes that are connected to relations for routing:

1 Like

You are right! I checked for relations in an earlier version, but in Nederland empty unattached nodes are not used in relations. I’ll fix it soon, it’s not that hard.
PS Fixed. Updated the first post.
I guess the extra check for parents in JOSM was necessary after all!

I can’t imagine this kind of relation-containing-only-one-unconnected-node actually works in any routing engines?

The enforcement relation is apparently intended to clarify the physical location of the traffic signal head. It’s quite an old relation. These days, I’d modify the currently untagged node to have man_made=traffic_signals. A router wouldn’t use this enforcement relation or man_made=traffic_signals node, but they could both be useful to a traffic simulator or hyperrealistic renderer.

Sorry, that enforcement one might be alright, but the other two linked were not enforcement, e.g. Node: 7380482720 | OpenStreetMap

Yeah, that one is leftover cruft from when the street was converted to a dual carriageway, making the turn restrictions along it redundant.

Since it requires detection of potential problems, followed by individual check and possible edit, I think Maproulette mission.

Osmose has a tool that identifies clusters of such nodes. I don’t think it will identify individual nodes.

So, for Drenthe, one can click on Osmose - Information - orphan nodes and find that there are three such clusters. Map view: Osmose This is on such node: Node: 1039534516 | OpenStreetMap

You can then use the dropdown list on the top left to go through each region / country.

I looked at Osmose, but I can’t find a way to export the nodes to JOSM in manageable batches for inspection and removal.

Fair enough, but there are other options.

Open the location in iD and click on the “Issues” button on the right. Ensure you have selected “Everything” and “Everywhere” and “Missing Tags”. It will then present you with a list that you can work through one-by-one.

If there are too many unrelated Issues, click on “Disable All” and re-click to enable “Missing Tags”.

I’m sorry, but this works very clumsy, and it doesn’t give me a list of unused and untagged nodes in a well defined area of my choice. Instead it gives me all elements which it thinks should have tags.
This functionality in Id is very useful for inspecting and fixing all errors in a limited area, comparable to JOSM’s coverall validation (before upload or on demand).