Skip to content

pick: hit-test the mark a symbol draws, at the size the view shows it - #43

Merged
beetlebugorg merged 2 commits into
mainfrom
fix/pick-symbol-extent
Aug 2, 2026
Merged

pick: hit-test the mark a symbol draws, at the size the view shows it#43
beetlebugorg merged 2 commits into
mainfrom
fix/pick-symbol-extent

Conversation

@beetlebugorg

Copy link
Copy Markdown
Owner

A pick tested a ~6 point radius around a symbol's anchor. Buoys and beacons draw almost their whole mark above the anchor, so clicking the topmark you can see missed the aid entirely and the report fell through to the areas underneath. Clicking Chesapeake Harbor Entrance Light 2 on its topmark, 7.95 points above the anchor, returned four features ending in M_NPUB and no aid.

QuerySurface now carries the symbol store and tests the box the symbol draws, unioned with the anchor radius so the radius stays a floor and the change can only add hits. At the anchor itself, before and after report the same 19 features in the same order.

The second commit fixes the units. The query replays the tile at a rounded, clamped zoom, and a tile shown above its level is stretched. Both the symbol box and the anchor radius were measured as if it were not. unitsPerPx returns the ratio at the view zoom; at a tile's own level it still yields 96 units, so picks there do not change.

The cursor pick tested a 96 tile-unit radius around a symbol's anchor. A
buoy or a beacon draws nearly all of its mark ABOVE the charted position,
so the mariner clicked the topmark that is visible and the pick missed the
aid. The report then fell through to the areas underneath.

QuerySurface now also tests the symbol's drawn box. symbols.bounds gives
the painted extent about the pivot, asymmetric and with the stroke
half-width included; QuerySurface.inSymbolExtent applies pushSymbol's
transform inverted, so the query point is compared in the symbol's own
upright frame. The two callers in chart.zig hand the surface the day
symbol store, which is enough because a palette supplies only fill and
stroke colours and not geometry.

Units: pushSymbol draws at k = scale * 100 * dev with dev carrying
px_per_tile / 256, and tile units convert to canvas px at
px_per_tile / EXTENT. The px_per_tile cancels, so a symbol's extent in
tile units is scale * 100 * EXTENT / 256, exact at any zoom. That makes
one reference pixel worth EXTENT / 256 = 16 tile units, which confirms the
existing radius of 96 as the 6 px it claims to be.

The box is UNIONED with that radius, so the radius stays a floor and this
can only add hits. A null store, an unknown symbol name, or a symbol with
no geometry all fall back to the radius alone. Areas and lines are
untouched.

A sounding and a label keep the anchor test. A sounding's digits sit
around the anchor by their baked pivots and stay inside the radius, and
reproducing either extent needs state the query path does not carry.

Checked against US5MD1MC at the reported click, 7.95 points above
Chesapeake Harbor Entrance Light 2: the pick reported 5 features and no
aid before, and now reports BCNLAT and DAYMAR. The pick at the anchor is
unchanged, feature for feature.
The query replays the tile at a rounded, clamped zoom, so the view is rarely at
that tile's own level. A tile shown above its level is stretched, and both terms
of the pick were measured as if it were not.

A symbol's drawn box used a fixed 4096/256 tile units per pixel. The box was
therefore 2^(view_zoom - tile_z) times too large, without bound once the view
runs past the archive's deepest zoom. The anchor radius held a fixed 96 tile
units and grew the same way, against a comment that promised a constant
on-screen distance.

unitsPerPx returns the ratio at the view zoom. Both terms use it. At a tile's
own level the radius is still 96 units, so a pick there does not change.

Measured on US5MD1MC (archive z0..16), the deepest click above a beacon's anchor
that still reports it:

  view zoom   before   after
       16      12 px   12 px
       17      24 px   12 px
       18      48 px   12 px
       19      96 px   12 px
@beetlebugorg
beetlebugorg merged commit 4198714 into main Aug 2, 2026
5 checks passed
@beetlebugorg
beetlebugorg deleted the fix/pick-symbol-extent branch August 2, 2026 01:49
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