Repository navigation
Conversation
fe00aef to
40dd1f9
Compare
40dd1f9 to
af6aad6
Compare
|
Rebased on #725 (af6aad6) and amended:
Each new test red with its line mutated. Web: 820 tests, eslint, |
|
Review of this PR's own commit (af6aad6): one point to change, the #734 dependency, one question, small ones. Found by reading the code, not run. 1. The title and file name can show a 2/3-byte relay id as a bare resolver name (change requested) 2. 3. Question: active type and hop filters 4. Small ones
|
af6aad6 to
b22cbd1
Compare
|
Pushed b22cbd1 for the review, rebuilt on #725 (94c0bd9). Per point:
Web: 832 tests, eslint, Playwright 304 passed. App ( |
What the map shows at a zoom is now a share the style eases, where it was a step in JS. App and website draw their cells by one rule, the server's. ## What was there Five rules changed the map in one frame when a zoom threshold was crossed: the hex resolution bands, the outlines of earlier rides, the cell names, and on the website the server's resolution per zoom level. Hex and points together was a manual view, `both`. The app binned in ten bands of a fixed size, the server in one size per zoom level. ## What this PR does The numbers are Kasper's. He picked them on 29 September 2026 in a mockup with 4559 receptions between Nijmegen and Arnhem, by pinching through it on a phone, in 2D and in 3D. They are recorded on #634 and in `docs/2026-09-29-zoom-transitions.md`. | | 2D | 3D | |---|---|---| | Points of this ride | fade in from zoom 13.25 to 18.25 | one step at zoom 19 | | Hex | stays at 100% | 95% of the bar height from zoom 19 | | Earlier rides (app) | fade in from zoom 11.25 to 18.75 | with the points, at zoom 19 | | Cell names (app) | fade in from zoom 15.5 to 16.5 | not drawn in 3D, as before | | Two cell sizes | blend over 0.95 zoom level | blend over 0.75 zoom level | - **One hex system.** `app/src/hexgrid.js` takes the server's sizes: one per zoom level, about 28 px tall. The ten bands in metres are gone. - **Two cell sizes at a time.** A size hands over to its neighbour around every change, and the two shares add up to 1. Two hex layers hold them, the even resolutions in one and the odd in the other. The pair moves up at a whole zoom, where the size that stays is at 100% and the other two are at 0. - **The website asks for two sizes**, one heatmap request each. Where the server answers both with the same size, that size is drawn once and stays in full. - **Auto replaces Both**, in the app's view cycle and in the website's segmented control. A stored view or a link that says `both` reads as auto. - **In 3D the pillars wait for zoom 19.** Up to there the hex is drawn as bars, also in auto. #266 drew it flat under the pillars. - **Nothing is built for a share of 0.** In auto the points are not built below their zoom, and the website does not fetch them. - **A cell names one node.** A cell is 28 px tall and about 24 wide at every zoom, which holds four characters. The label is the prefix of the node heard last, with the count of the others under it. It was three prefixes on one line. `zoomfade.js` holds the numbers and builds the expressions. It is one file on both surfaces, pinned in `web/parity.test.js`. ## Measured in MapLibre 4.7.1 - `['zoom']` is only accepted as the input of a top-level `interpolate` or `step`. The per-feature value (`['get', 'op']`, `['get', 'height']`) rides in each stop's output. - A `fill-extrusion` of height 0 still draws an opaque polygon on the ground. With several cell sizes stacked, the ones with nothing to show covered the one that had. A layer with nothing to show is switched off by a `step` on `fill-extrusion-opacity`. - In 3D a share is spent on the bar's height. Alpha dissolves toward black, as `docs/2026-09-04-new-versus-old-on-the-map.md` records. ## Verification - app vitest 1661 of 1661, web vitest 810 of 810, eslint clean in both, the app builds. - `zoomfade.test.js`: the shares at their ends and midpoints, the pair adding up to 1 at every 0.05 zoom for both widths, no third size anywhere, and stops that rise in every expression for every resolution and view. - `web/e2e/zoomfade.spec.js`: five cases. Two fail when the rule is taken out: asking for one size only, and fetching the points at every zoom. - The app's map, fed the 4559 receptions through a throwaway page: at zoom 13.3 two sizes are up (646 and 1042 cells), no points are built below 13.25, in 3D the pillars are built from zoom 19 (1882 after the collapse). No map errors. - Full e2e locally: 300 of 302 at a load average between 26 and 48. The two that failed, `targetpicker.spec.js:198` and `ui.spec.js:502`, depend on timing. The second passed 4 of 4 when run alone. - Two existing e2e cases changed with the rules: the click on a point inside a cell runs at a zoom where auto shows points, and the 3D case asserts bars and no pillars below zoom 19. Not verified: the motion itself. The browser pane was in the background, so the checks are still frames and measurements. ## Not in this PR - **The server is unchanged.** It stops at resolution 18. The app goes to 21, so a cell stays 28 px up to zoom 20 for the walk-in. On the website a cell grows past 28 px above zoom 17. Kasper chose this on 29 September 2026. - **The noise layer (#410) draws one size**, the one in full at the zoom, without a blend. - **The exports (#725, #726, #729) add `web/hexgrid.js`.** This PR does not touch that file. Whichever merges second has to check the cell sizes agree. Closes #634 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> Co-authored-by: efiten <erwin.fiten@gmail.com>
|
#724 and #725 are merged (15a6ada, d6186bc), and so is #734 (4c2a57b). This one needs a rebase onto master before it can go in. What happens when b22cbd1 is applied to master How #725 was merged, in case the same overlap shows up here (merge commit 4a661d6 on your branch):
Question: should the reach fixtures follow |
A hunter who wants to show how far one repeater reaches has only the map, which draws every repeater at once. A second item in the Export sheet, Reach of one repeater, draws the selected star on the res-8 grid: where it was heard, in the RSSI tiers, where the same hunters drove without hearing it, and where it likely reaches in between. What is filled in is thought from the repeater. Each heard cell gets a line from the repeater. A line is reached up to the next heard cell and not across a silent one: a shadow darkens it until it is heard again. Between neighbouring lines the area where both are reached is filled, when their ends are at most 2 km apart and no silent cell lies in it. The ground comes from the Terrarium tiles the 3D view draws, at zoom 10: a cell is filled only where a 30 m mast sees it over the ground and the earth's bulge. When the tiles cannot all be read, the lines alone decide. Both exports now shade the relief from the same tiles, at the exaggeration from Settings as the 3D view does, and say "relief 7× exaggerated" beside the scale bar. The Export sheet takes a list of items, and the two exports share the offscreen map and the band. Decided with Kasper on renders from real data; recorded in docs/2026-09-27-export-reach.md. Closes efiten#720 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
b22cbd1 to
957b144
Compare
|
Rebased onto master (957b144), as one commit on top of #725's merge. On the question: the fixtures follow
Web: 908 tests, eslint, Playwright 328 passed. App: 1707 tests, build. |
|
Review of 957b144 (base 77d4e5a). The four points of the earlier review are resolved and tested. The res-13 rebase holds: the 1. With a target picked, the subtitle does not report a cap or a failure of the fetch the picture is built from (change requested) 2. Small ones (found by reading; the title width was measured by the reviewer in Chromium)
Measured, for information only: |
Closes #720
Stacked on #724 and #725: the first two commits are those PRs, the last one is this PR.
What it is
A second item in the Export sheet, Reach of one repeater, draws the selected star as a 1200×1200 PNG. It shows where the repeater was heard (the export's cell of #725, res 8 today, in the RSSI tiers), where the same hunters drove without hearing it (grey), and where it likely reaches in between (lighter cells). You select a star by tapping its ▲ or picking it as target. Without a selection the item is disabled and says what to do. A merged target row whose hearings form two stars is one pick: the star with the most hearings is drawn. The cells follow the map's type and hop filters, so with a type filter on a grey cell means not heard as that packet type (both Kasper, 30 September).
What is filled in
Thought from the repeater, decided with Kasper on renders from real data:
RAY_ALT_M) sees 1.5 m above it, with the earth's radius times 4/3 and no Fresnel zone. When the tiles cannot all be read, the lines alone decide.The rules, the numbers and what was tried:
docs/2026-09-27-export-reach.md.Relief in both exports
Both exports shade the relief from the same tiles, at the exaggeration from Settings, as the 3D view does. Beside the scale bar they say "relief 7× exaggerated", and nothing at 1×, where the relief is true to scale. The tiles' attribution joins the map's. This touches the renderer from #725, so it lives here, with the terrain.
Measured on real data
Receptions around Nijmegen and Arnhem, 8 August to 8 September 2026:
Of the 29 stars with at least 20 hearings, the terrain removes cells for 4. The decoded ground matches known heights: the Waal at Nijmegen 6 m, the Valkhof 28 m, Berg en Dal 96 m.
Code
web/exportreach.js: the model, in small pure functions.web/exportterrain.js: fetches and reads the tiles. It returns nothing when a tile is missing, or when the browser alters what a canvas reads back (the check MapLibre does inisOffscreenCanvasDistorted).web/exportrender.js,web/exportsheet.js,web/map.js: the two exports share the offscreen map, the band and the sheet.Verification
signal.js): 1637 passed, eslint, build.Not in it
🤖 Generated with Claude Code