Skip to content

fix(coverage): Mapterhorn credit on MapLibre and antimeridian regions - #7759

Merged
jamesarich merged 4 commits into
mainfrom
fix/coverage-followups
Oct 24, 2026
Merged

jamesarich merged 4 commits into
mainfrom
fix/coverage-followups

Conversation

@jamesarich

@jamesarich jamesarich commented Oct 24, 2026 •

Copy link
Copy Markdown
Collaborator

Two follow-ups from #7758. The MapLibre map didn't credit Mapterhorn under a coverage layer, because a GeoJSON source has no attribution field. And an offline region that crosses the antimeridian never matched the ground it holds.

🐛 Bug Fixes

  • A coverage layer carries the Mapterhorn credit, and the main MapLibre map adds it to the attribution button while the layer is visible. It is deduplicated against the hillshade credit, and shows even when the basemap credits nobody.
  • GeoBounds.intersects splits a region whose west is east of its east at ±180°, so the estimate reads that region's terrain on both sides of the line.

Testing Performed

  • RegionTerrainTest: a wrapped region meets ground on both sides of the line, misses ground between its ends, and boxes that only touch do not intersect.

Summary by CodeRabbit

  • Bug Fixes
    • Map regions that cross the International Date Line now correctly intersect areas on either side. Areas that only touch a boundary remain non-intersecting.
  • Improvements
    • Map overlays display relevant attribution for coverage layers alongside other map credits.
    • Duplicate credits are shown only once when multiple layers share them, and layer-specific credits appear when available.

A coverage estimate is a GeoJSON source, which carries no attribution, so the
MapLibre map credited Mapterhorn only while hillshade drew. A coverage layer now
carries the credit and the main map adds it to the attribution button,
deduplicated against the hillshade credit.
A region whose west is east of its east crosses the 180th meridian, and the
overlap check rejected ground on both sides of it, so the estimate went to the
network for terrain the region holds.
@github-actions github-actions Bot added the bugfix PR tag label Oct 24, 2026
@coderabbitai

coderabbitai Bot commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Walkthrough

The change adds antimeridian support to coverage-bound intersection checks. It also passes coverage-layer attribution through the MapLibre view and displays it with map credits.

Changes: Coverage Bounds

Layer / File(s) Summary
Antimeridian intersection behavior
feature/coverage/src/commonMain/.../RegionTerrain.kt, feature/coverage/src/commonTest/.../RegionTerrainTest.kt
GeoBounds.intersects splits wrapped longitude ranges into spans and retains strict overlap checks. Tests cover intersections on both sides of the antimeridian, the gap between endpoints, and touching boundaries.

Map Attribution

Layer / File(s) Summary
Coverage layer attribution metadata
feature/map-maplibre/src/commonMain/.../layers/CustomLayer.kt, feature/map-maplibre/src/commonMain/.../layers/TerrainLayers.kt, feature/map-maplibre/src/commonMain/.../layers/RenderableLayers.kt
CustomLayer adds optional attribution HTML. Non-KML coverage layers receive the MapTiler attribution string.
Map attribution display
feature/map-maplibre/src/commonMain/.../MapLibreMapViewProvider.kt, feature/map-maplibre/src/commonMain/.../MeshMap.kt, feature/map-maplibre/src/commonMain/.../component/MapOrnaments.kt, feature/map-maplibre/src/commonMain/.../NodeTrackMap.kt, feature/map-maplibre/src/commonMain/.../SecondaryMaps.kt, feature/map-maplibre/src/commonMain/.../component/ZoomControls.kt
MapView evaluates custom layers once and passes their attribution to MeshMap. Map ornaments combine and deduplicate extra credits with style credits when extras exist. Otherwise, attribution rendering uses AttributionOnly. KDoc references use the meshMapOrnaments name.

Priority: Normal

Merge Risk: Low · up to 18ffa

Dragging over expanded map credits can move the map and close the credits. This is a bounded interaction issue that can be fixed before merge or accepted with owner awareness.

Pre-merge checks: Passed 6 · Failed 2

Failed Failed checks: 2 warnings

Check name Status Explanation Resolution
Tests Prove The Path, Not The End State Warning Two added tests do not prove the antimeridian change. Against the base implementation (west < other.east && other.west < east), aWrappedRegionMissesGroundBetweenItsEnds is already false for longit… Remove the two redundant tests, or make each test include an assertion that fails with the base implementation. Retain the two-sided wrapped-overlap assertion as the regression check, and fold non-overlap and boundary assertions into a test…
Regression Coverage For Changed Behavior Warning The antimeridian path has regression coverage, but the Mapterhorn attribution path still has no test. RenderableLayers.kt:80-88 assigns MAPTERHORN_ATTRIBUTION_HTML only to coverage layers. `MapLib… Add regression tests in the MapLibre test source, or extract and test a pure attribution-assembly helper. Test that a URI-backed LayerType.COVERAGE produces MAPTERHORN_ATTRIBUTION_HTML and that a non-coverage layer does not. Test that s…
Passed Passed checks: 6 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly summarizes both main changes: Mapterhorn attribution on MapLibre and antimeridian support for coverage regions.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Sibling Call Sites And Presence Semantics Passed PASS. The only changed absent-value field is CustomLayer.attributionHtml: String? = null. All CustomLayer construction sites were checked: coverage layers set Mapterhorn attribution, other non-KML…
Moved Code Diffed Against Its Original Passed PASS — The PR does not move a type or function to another file or module. MeshMapOrnaments becomes meshMapOrnaments in the same file, and CollapsedAttributionButton becomes CreditButton in the…
Full details: Sibling Call Sites And Presence Semantics

Explanation

PASS. The only changed absent-value field is CustomLayer.attributionHtml: String? = null. All CustomLayer construction sites were checked: coverage layers set Mapterhorn attribution, other non-KML layers use null, and converted KML layers correctly have no attribution. The only consumer collects it with layers.mapNotNull { it.attributionHtml }. No sibling call site is unfixed. The diff adds no new field with a default of 0 for RSSI, temperature, current, voltage, particulate concentration, or SNR.

Full details: Moved Code Diffed Against Its Original

Explanation

PASS — The PR does not move a type or function to another file or module. MeshMapOrnaments becomes meshMapOrnaments in the same file, and CollapsedAttributionButton becomes CreditButton in the same file. The diff adds intentional credit parameters and preserves the old collapsed call through startExpanded = false; no moved declaration loses validation, annotations, or required defaults. The other changes modify existing code or add tests.

Full details: Tests Prove The Path, Not The End State

Explanation

Two added tests do not prove the antimeridian change. Against the base implementation (west &lt; other.east &amp;&amp; other.west &lt; east), aWrappedRegionMissesGroundBetweenItsEnds is already false for longitudes 177..-178 versus 0..1, and boxesThatOnlyTouchDoNotIntersect is already false because the comparisons are strict. Only aWrappedRegionMeetsGroundOnBothSidesOfTheLine fails when the production change is reverted.

Resolution

Remove the two redundant tests, or make each test include an assertion that fails with the base implementation. Retain the two-sided wrapped-overlap assertion as the regression check, and fold non-overlap and boundary assertions into a test that also exercises a positive wrapped overlap or replace them with cases that distinguish the antimeridian implementation.

Full details: Regression Coverage For Changed Behavior

Explanation

The antimeridian path has regression coverage, but the Mapterhorn attribution path still has no test. RenderableLayers.kt:80-88 assigns MAPTERHORN_ATTRIBUTION_HTML only to coverage layers. MapLibreMapViewProvider.kt:150-175 forwards visible-layer credits to MeshMap, and MapOrnaments.kt:95-104,150-161 merges them with style credits and handles basemaps with no style attribution. This shared Compose UI path runs in both the F-Droid provider and the desktop provider. The only changed test is RegionTerrainTest; the existing tile AttributionTest does not exercise this path.

Resolution

Add regression tests in the MapLibre test source, or extract and test a pure attribution-assembly helper. Test that a URI-backed LayerType.COVERAGE produces MAPTERHORN_ATTRIBUTION_HTML and that a non-coverage layer does not. Test that style and extra credits are both retained, duplicate Mapterhorn credits occur once, and an extra credit is shown when the style has no attribution. Also test the empty-extra-credits path still uses the normal attribution overlay. These tests must fail against the pre-change implementation.

  • 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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


Review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between bb78b38 and a7d3107.

Files selected for processing: 11
  • feature/coverage/src/commonMain/kotlin/org/meshtastic/feature/coverage/RegionTerrain.kt
  • feature/coverage/src/commonTest/kotlin/org/meshtastic/feature/coverage/RegionTerrainTest.kt
  • feature/map-maplibre/src/commonMain/kotlin/org/meshtastic/feature/map/maplibre/MapLibreMapViewProvider.kt
  • feature/map-maplibre/src/commonMain/kotlin/org/meshtastic/feature/map/maplibre/MeshMap.kt
  • feature/map-maplibre/src/commonMain/kotlin/org/meshtastic/feature/map/maplibre/NodeTrackMap.kt
  • feature/map-maplibre/src/commonMain/kotlin/org/meshtastic/feature/map/maplibre/SecondaryMaps.kt
  • feature/map-maplibre/src/commonMain/kotlin/org/meshtastic/feature/map/maplibre/component/MapOrnaments.kt
  • feature/map-maplibre/src/commonMain/kotlin/org/meshtastic/feature/map/maplibre/component/ZoomControls.kt
  • feature/map-maplibre/src/commonMain/kotlin/org/meshtastic/feature/map/maplibre/layers/CustomLayer.kt
  • feature/map-maplibre/src/commonMain/kotlin/org/meshtastic/feature/map/maplibre/layers/RenderableLayers.kt
  • feature/map-maplibre/src/commonMain/kotlin/org/meshtastic/feature/map/maplibre/layers/TerrainLayers.kt

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 3 remain after this review.

The library button draws nothing for a style with no attribution, as a custom
raster basemap may have, which dropped the Mapterhorn credit with it. The main
map now uses the same held-state button as the small maps, fed the extra credit.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


Review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between a7d3107 and 18ffa4a.

Files selected for processing: 1
  • feature/map-maplibre/src/commonMain/kotlin/org/meshtastic/feature/map/maplibre/component/MapOrnaments.kt

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 2 remain after this review.

@jamesarich
jamesarich added this pull request to the merge queue Oct 24, 2026
Merged via the queue into main with commit 1bedc5d Oct 24, 2026
14 checks passed
@jamesarich
jamesarich deleted the fix/coverage-followups branch October 24, 2026 15:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix PR tag

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant