Skip to content

Handle open way centroids as lines#890

Open
Symmetricity wants to merge 1 commit into
systemed:masterfrom
Symmetricity:fix/open-way-centroids
Open

Handle open way centroids as lines#890
Symmetricity wants to merge 1 commit into
systemed:masterfrom
Symmetricity:fix/open-way-centroids

Conversation

@Symmetricity
Copy link
Copy Markdown

@Symmetricity Symmetricity commented May 13, 2026

This PR is AI generated.

Handle open way centroids as lines

LayerAsCentroid() defaults to the polylabel algorithm for 2D geometries.
That is appropriate for polygonal areas, but open ways are linestrings. The
current code assigns every way into a polygon before calculating the
representative point, so open ways can be passed through polygon/polylabel
logic even though they are not closed areas.

This change keeps the existing polygon path for closed ways, but handles open
ways from the cached linestring directly:

  • empty open ways keep the existing error path by throwing
    geom::centroid_exception
  • single-point open ways use that point
  • multi-point open ways use Boost.Geometry's linestring centroid

Closed ways and relations still use the existing polygon/polylabel behavior.
The stored output is still a point, so this changes how the point is calculated
for open ways without changing output layers, attributes, or geometry storage.

This also avoids a temporary polygon conversion for open ways, but the intent
is correctness rather than a performance optimization.

Reproduce

Generate OpenMapTiles-compatible output for an extract that contains open ways
which are emitted through LayerAsCentroid(), for example named POI-like ways
handled by WritePOI() or the catch-all poi_detail path in
process-openmaptiles.lua.

Before this change, those open ways are assigned into a polygon and labeled via
polygon logic. That can produce representative points that depend on polygon
handling for invalid/open rings.

After this change, open ways use line geometry for their representative point,
while closed ways continue to use polygon labeling.

In the generated-tile CI investigation, the focused open-way centroid patch
changed only poi geometry in the local Liechtenstein debug output. Tile
counts, feature counts, attributes, and polygon layers were unchanged in that
run.

Testing

  • git diff --check origin/master..HEAD
  • cmake --build build -j2

Related Issues And PRs

I did not find an existing upstream issue or PR that directly reports open ways
being labeled through polygon/polylabel handling.

Related centroid/polylabel context:

LayerAsCentroid defaults to polylabel, but polylabel operates on polygon geometry. Open ways such as barriers and gates were being assigned into a polygon before calculating their label point, which can produce platform-dependent representative points.

Use the cached linestring directly for open ways and keep the existing polygon/polylabel path for closed ways. This keeps area labeling behavior unchanged while making open-way label placement match the geometry type being processed.
@Symmetricity
Copy link
Copy Markdown
Author

I also checked the change visually against the OSM source geometry from the same
Liechtenstein PBF fixture.

Legend in the screenshots:

  • red point: upstream master
  • green point: this PR
  • blue line: the OSM source way from the PBF
  • OSM raster tiles: background context only

For the visual check I used a temporary debug process file with stable POI
ordering and a debug_osm_id attribute, so the comparison isolates this C++
change from Lua table-order noise. With that setup, only poi point placement
changed; global layer counts stayed the same, and no polygon/line/building/
housenumber layers changed.

The largest example is Finnenbahn, where upstream places some labels away
from the source way after treating an open way as polygon input. This PR places
those labels on the corresponding OSM line geometry:

Finnenbahn open-way centroid comparison

Measured against the source way in the PBF:

  • OSM way 424087004: upstream 26.1 m from the source line, PR 0.3 m
  • OSM way 424087005: upstream 5.1 m from the source line, PR 0.1 m
  • OSM way 424087003: upstream 0.3 m from the source line, PR 0.0 m

Two smaller examples:

Climbing open-way centroid comparison

Bollard open-way centroid comparison

Overview of the checked examples:

Open-way centroid comparison overview

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant