Skip to content

Layouts: a publication layout's surrounds keep off the data; a decimal comma (#682, part 3) - #709

Draft
elpidioassinaturas wants to merge 2 commits into
opengeos:mainfrom
elpidioassinaturas:feat/682-placement
Draft

elpidioassinaturas wants to merge 2 commits into
opengeos:mainfrom
elpidioassinaturas:feat/682-placement

Conversation

@elpidioassinaturas

Copy link
Copy Markdown
Contributor

Summary

Part 3 of #682, the last.

This builds on #706 (part 2, the locator), and its first commit is #706's. It's a draft until #706 is in; then I'll merge main into it, so only this part's changes remain.

  • Surrounds by data coverage: the north arrow, the legend, the scale bar and the locator each take the corner where they cover the least of what the map draws.
    • The new render::layout::frame_coverage draws the frame's map on a coarse grid (about 96 cells across) with the basemap set to Blank. Where a layer or its labels drew is data, and the frame's background isn't.
    • Every way of giving the surrounds a corner each is tried (at most 24), and the one covering the least data, in mm², wins.
    • A surround off its own corner costs a hundredth of its area. So when it makes no difference (no data in the corners, or data under every corner alike), they keep part 1's corners: locator top left, arrow top right, legend bottom left, scale bottom right.
    • The legend still stops short of whatever is beside it and above or below it, in whichever corners they end up.
  • Warnings:
    • Crowding: with more surrounds than free corners, one warning names those left on the data ("the north arrow sits on what the map shows, the freer corners having gone to the others"). Data under every corner alike, such as a context layer filling the frame, has nothing better to offer and isn't warned about.
    • Overlap: two surrounds that overlap (a frame too small for them all) are said too.
  • Decimal comma: "decimal": "," on layout.publication, or on layout.page for any layout, sets a new Layout::decimal_comma.
    • The graticule labels, the scale bar's numbers, the colorbar ticks and {scale} then print with a decimal comma and points between thousands (0,05, 1:6.300.000).
    • Other text is left as it is.
    • The field is serialized only when on, so existing layout files don't change.
    • graphics::thousands is now public, for {scale}.
  • Docs: the publication layouts section of layouts.md, and the assistant's print-layout skill.

Testing

  • publication_surrounds_keep_off_the_data (engine) uses a polygon layer in three cases:
    • in the middle only: every surround keeps its corner, with no warnings;
    • filling the bottom left: the legend leaves that corner, the north arrow (smallest) takes it, and one warning names it;
    • filling the frame: nothing to warn about, and every surround keeps its corner.
  • The same test covers "decimal": ",", layout.page's decimal, and bad values refused.
  • a_decimal_comma_swaps_the_marks (render): the marks swap in numbers. With a decimal comma, {scale} reads 1:6.300.000 and the text around it keeps its own comma.
  • The part 1 and 2 tests now check that surrounds don't overlap, whichever corners they take, rather than fixed corners. Over the sample world's land, the surrounds now move to its one corner of sea.
  • I checked the exported A4s visually: the legend moved off a filled corner, and a decimal-comma scale reads 1:7.600.000.
  • cargo fmt --all --check, cargo clippy --workspace --all-targets -- -D warnings and cargo xtask layers are clean.
  • rustgis-engine 282 passed (3 ignored), rustgis-render 137, rustgis-map 126, rustgis-assistant 206 and rustgis-ui-egui 264 (unit tests).

🤖 Generated with Claude Code

elpidiofilho and others added 2 commits October 22, 2026 13:20
… area outlined (opengeos#682, part 2)

layout.publication takes "locator": "globe" (a sheet's default: a new map
of the map's polygon layers on the globe, unlabelled, in a round frame at
the map's top left, sized from the renderer's own globe disc), "inset" (the
surrounding region on the map itself) or "none" (a figure's default). The
map frame's extent indicator outlines the area on either; the legend stops
short of it; undo takes the globe's map away with the layout.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…l comma (opengeos#682, part 3)

The north arrow, the legend, the scale bar and the locator each take the corner
where they cover the least of what the map draws (render::layout::frame_coverage:
the frame drawn coarse on a blank basemap), keeping their own corners when it
makes no difference; one warning names those crowded onto the data. "decimal":
"," (layout.publication, layout.page) sets Layout::decimal_comma: graticule,
scale bar and colorbar numbers and {scale} print 0,05 and 1:6.300.000.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 22, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown

Code review

I found no blocking bugs in PR #709. I read the whole diff and checked publication, page, the render changes and the new tests against the surrounding code. I did not build the code or run the tests.

Bugs

  • None found. The locator map is added to project.maps only after the last ? or return Err in publication, so a refused command leaves no stray map behind. Confidence: medium-high.
  • The {scale} comma swap and the label swaps in decimal() only exchange . and , in numbers the layout itself prints, so surrounding text keeps its punctuation. a_decimal_comma_swaps_the_marks covers {scale}. Confidence: medium.

Security

  • None. The new decimal and locator parameters are validated against fixed values and return errors on junk. There are no new panics, unwraps or indexing in the non-test code; covered uses get() and clamped ranges. Confidence: medium-high.

Performance

  • frame_coverage clones the whole map and renders it once per layout.publication. The grid is capped at 8–512 cells, so this is acceptable. Confidence: low concern.

Quality

  • The corner search uses four hard-coded nested loops (see the inline comment). With fewer than four surrounds it repeats the same assignments, and a fifth surround would silently fall back to the default corners. A small permutation helper would fix both. Confidence: medium (nit).
  • publication_layouts_fit_their_pages now only requires that any warnings contain "on what the map shows". That is weaker than the old "no warnings" assertion, though the new placement tests make up for most of it. Confidence: low.

AGENTS.md

  • No unwraps or panics were added outside tests, and the decimal and locator parameters are documented in layouts.md, the SKILL.md file and the command param strings.
  • Nothing in the PR can break the wasm build: it uses no std::time, filesystem or other native-only APIs.
  • New UI strings: none, since all changes are in the engine, render and map crates.

Change size

The whole PR against main (merge base 60ae3e9 to PR head e2e1648).

Metric Value
Files changed 7 (0 added, 7 modified, 0 removed, 0 renamed)
Size before 1,065,904 B (1.02 MB)
Size after 1,091,532 B (1.04 MB)
Total size change +25,628 B (+25.0 KB)
File Before After Change
crates/engine/src/cmd/layout.rs 100.2 KB 110.5 KB +10.3 KB
crates/engine/src/tests.rs 758.2 KB 767.0 KB +8.9 KB
crates/render/src/layout.rs 96.7 KB 100.4 KB +3.7 KB
docs/user-guide/layouts.md 15.2 KB 16.6 KB +1.4 KB
crates/map/src/layout.rs 59.4 KB 59.8 KB +472 B
crates/assistant/skills/print-layout/SKILL.md 2.2 KB 2.4 KB +207 B
crates/map/src/graphics.rs 9.1 KB 9.2 KB +68 B

@github-actions

Copy link
Copy Markdown

📖 Docs preview

Item Value
Preview https://preview.rustgis.app/pr-709/
Web app https://preview.rustgis.app/pr-709/app/
Commit e2e1648

GitHub Pages takes a minute or two to publish a new commit.

This branch has not been deployed

No deployments
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.

2 participants