How Waev Names Meshes: The MeshBuilder Logic
Waev clusters nodes into meshes and names them using geographic boundaries, IATA codes, and reverse geocoding, backed by hysteresis to prevent naming churn.
Your mesh doesn’t know its own name. Internally, nodes are public keys and UUIDs — exactly what the protocol needs, and exactly what a net control operator can’t use when they need to say which part of the network is performing well and which part isn’t.
TLDR: MeshBuilder assigns a human-readable label to every cluster by measuring the hull area to set a naming tier, then selecting a name from the best available source: a curated gazetteer polygon, an IATA airport code, Nominatim reverse geocoding, or a coordinate fallback. An admin override beats them all, and hysteresis keeps the name from flipping every time the cluster’s footprint grazes a boundary.
What MeshBuilder does
MeshBuilder is the clustering engine that runs on every recompute tick. It groups nodes into clusters by RF channel and geographic proximity, computes a convex hull for each cluster, and assigns a label. That label is what appears on the Live Map alongside node count, observer count, and activity figures.
Names serve a purpose beyond display. A cluster called “Portland Metro” can be referenced in a net control briefing, recorded in an after-action report, and compared week over week by operators who have never spoken to each other. A UUID can’t do any of that.
Waev only sees what enrolled observers report. The full ingest path from radio to map is covered in From Radio to Map.
Tiers: naming scope from the hull area
Before picking a name, MeshBuilder measures the cluster’s convex hull area in square kilometers. That area sets the naming tier:
- Tier 1 — local: up to 50 km². A single neighborhood or a small town.
- Tier 2 — metro: up to 1,000 km². A city and its near suburbs.
- Tier 3 — sub-regional: up to 50,000 km². A multi-county or single-state footprint.
- Tier 4 — regional: up to 500,000 km². A multi-state or large-country region.
- Tier 5 — national: over 500,000 km². A full country or continental rollup.
The tier sets the scope of the name. A cluster covering a few city blocks should carry a neighborhood or airport-code name, not a regional one. A cluster spanning several states should not be named after whichever city the centroid happens to fall in on a given day.
Sources: where the name comes from
MeshBuilder resolves names from four sources, checked in order of preference.
Gazetteer covers tiers 2 through 5. The gazetteer is a curated set of named polygons built from Geoboundaries admin boundaries. Matching is overlap scoring against the cluster’s footprint, weighted toward where members actually sit — the name follows the network’s dense core, not wherever the hull perimeter happens to bulge. When two polygons cover a cluster equally well, the tighter fit wins: a mesh that sits inside both “Willamette Valley” and “Pacific Northwest, USA” gets the valley. Every entry is maintained by hand, not inferred.
IATA covers tier 1 local clusters. MeshBuilder takes the airport code nearest the cluster centroid. Anyone who has pulled a METAR already reads airport identifiers as geography, and for a cluster a few kilometers across, the nearest major airport is a stable, unambiguous anchor.
Nominatim is the tier 1 fallback. If the cluster lands somewhere without a nearby IATA code, MeshBuilder sends the centroid to Nominatim for reverse geocoding against OpenStreetMap. The result is a place name from open data rather than a curated entry.
Override bypasses all automatic sources. An admin can set a displayNameOverride directly on any cluster record. This is how a specific callsign or local landmark gets assigned when the automatic label is not the right fit.
While a name resolves asynchronously, the cluster reports a resolving state with a null name. That state is transient, and it only happens to new clusters: a mesh that has ever held a real name keeps it through a cache miss rather than regressing to resolving while re-resolution is queued.
Hysteresis: why the name doesn’t flicker
A mesh cluster is not static. Nodes come online as operators power up and drop off when they shut down. The convex hull expands and contracts with membership. When the footprint shifts, the centroid shifts too, sometimes enough to cross a polygon boundary.
Without a mechanism to hold names steady, a cluster near a city boundary could acquire a different name several times in a single day as nodes on the fringe come and go. That would make the label useless as a community identifier.
Two fields on the MeshStability record do the damping, and each change has to clear two gates.
pendingTierTicks guards the tier. First gate: the hull area must clear the incumbent tier’s cutoff by a dead-band margin, so a cluster jittering between 990 and 1,010 km² stays metro instead of bouncing across the 1,000 km² line. Second gate: the new tier must then hold for a configured number of consecutive recompute ticks before it commits. A cluster does not drop a tier because a few nodes went offline for an hour.
pendingNameTicks guards the name the same way. A challenger polygon must beat the incumbent’s overlap score by more than a configured margin — sub-margin drift along a shared border doesn’t even start the clock — and then keep winning for a sustained run of consecutive ticks. A cluster whose footprint grazes a neighboring polygon at midnight does not wake up with a new name.
The result is stable community identity. You can track the signal quality of “Portland Metro” across weeks without the label swapping to “Beaverton” and back. For reading those signal patterns over time, Reading the Signal covers what SNR and link quality tell you about a specific mesh.
Fallbacks: the cluster at the edge of the map
Some clusters end up where no gazetteer polygon exists, no IATA airport is nearby, and Nominatim returns nothing useful. Ocean clusters, remote wilderness, and regions not yet in the curated data all land here.
When every other source fails, MeshBuilder uses the cluster’s centroid coordinates as the name: a string like 45.52,-122.68. This is the fallback source. It isn’t a place name, but it is precise — you know exactly where the cluster sits.
A fallback label on the Live Map is the system being honest about what it knows. The cluster exists. The data to name it does not.
See your mesh names on the Live Map, or check a specific node’s cluster assignment in Outpost.
Frequently asked
- How does Waev decide what to name a mesh?
- MeshBuilder measures the cluster's convex hull area to determine a naming tier, then picks from the highest-priority source that matches: a curated gazetteer polygon for larger clusters, the nearest IATA airport code or Nominatim reverse geocode for local ones, or an admin override. If none of those return a result, the name falls back to a centroid coordinate string.
- What happens when a mesh drifts across a geographic boundary?
- MeshBuilder applies hysteresis to prevent naming churn. A challenger name must beat the incumbent's overlap score by more than a configured margin, then keep winning for a configured number of consecutive recompute ticks before the committed name changes. A brief border-crossing during off-peak hours does not trigger a rename.
- What is the fallback when no place name is found?
- MeshBuilder uses the cluster's centroid as a coordinate string. A name like 45.52,-122.68 is unambiguous and pinpoints the cluster even when no gazetteer polygon or reverse-geocode result covers that location.
- Can a mesh name be changed manually?
- Yes. An admin can set a display name override on any cluster. The override takes precedence over all automatic naming sources and persists until it is cleared.