Skip to content

refactor(map): migrate custom overlays to the maps-utils 5.0 data layer#6304

Merged
jamesarich merged 2 commits into
mainfrom
claude/agitated-newton-dda31e
Jul 16, 2026
Merged

refactor(map): migrate custom overlays to the maps-utils 5.0 data layer#6304
jamesarich merged 2 commits into
mainfrom
claude/agitated-newton-dda31e

Conversation

@jamesarich

@jamesarich jamesarich commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator

Follow-up to #6301. That bump pulled android-maps-utils 5.0.0, which deprecated the entire com.google.maps.android.data KML/GeoJSON stack ("Use the new platform-agnostic data layer and renderer instead"). The catch: in 5.0.0 the deprecated classes are no longer the battle-tested 4.x implementations — they are thin bridges over the new pipeline, and the bridges break this feature at runtime. This PR moves the google-flavor custom map overlays (Map Layers) directly onto the new public pipeline, which both clears the deprecation and fixes the regressions the bridges would ship.

🐛 Bug Fixes (regressions in the 5.0.0 legacy bridges, avoided by migrating)

  • GeoJSON/KML point features rendered invisible: the bridges map them to PointStyle(color = 0), which the renderer turns into marker alpha 0.
  • Per-feature MultiPolygon styles silently dropped at render time — Meshtastic Site Planner coverage contours would lose their dBm colors and draw as default black outlines.
  • Layer visibility toggling leaked MultiGeometry objects: MapViewRenderer.removeFeature keys rendered map objects by internal per-geometry copies in an IdentityHashMap, so removal no-ops and re-showing duplicates the geometry.

🛠️ Refactoring & Architecture

  • MapLayerOverlay now parses via the new GeoJsonParser / KmlParser / KmzParser (zip magic sniffed — LayerType.KML covers both .kml and .kmz) and maps into the immutable DataLayer model via toLayer().
  • applySimpleStyleSpec is reimplemented as a pass over the model features, preserving everything the upstream mapper misses: the legacy color fallback, rgb()/rgba() colors, the 0.35 default fill opacity that lets stacked contour bands read as a gradient, and PolygonStyle for MultiPolygon (upstream styles any multi-geometry as a line).
  • Rendering goes through a single-use MapViewRenderer per show, torn down with clear() — the only teardown that reliably removes MultiGeometry objects — re-wiring KMZ archive images via cacheImageData on each show.
  • Zero @Deprecated maps-utils usages remain in the map code.

Behavior preserved: KML/KMZ/GeoJSON custom layers, per-feature simplestyle colors for Site Planner coverage exports, layer visibility toggling, refresh re-parse, points keep the default marker.

The three bridge/renderer bugs above are candidates for upstream reports against googlemaps/android-maps-utils.

Testing Performed

  • ./gradlew spotlessApply spotlessCheck detekt assembleDebug test allTests — green.
  • :androidApp:compileGoogleDebugKotlin — no deprecation warnings remain in map code.
  • Draft until a device pass: loading a Site Planner coverage GeoJSON (per-band colors + opacity), a KMZ with icon images, and visibility toggle/refresh of each layer type.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Enhanced map-layer support for KML, KMZ, and GeoJSON, with smoother activation/deactivation of layers.
    • Updated styling for rendered map features, including improved handling of fill, stroke, transparency, and line widths.
  • Improvements
    • More robust color parsing (hex, named colors, and rgb/rgba) to produce consistent visual results and safer fallbacks when styles can’t be interpreted.

android-maps-utils 5.0.0 (pulled by maps-compose 8.4.0) deprecated the
com.google.maps.android.data KML/GeoJSON stack. Crucially, those deprecated
classes are no longer the battle-tested 4.x code: they are thin bridges over
the new platform-agnostic pipeline, and the bridges regress this feature —
GeoJSON/KML point markers render invisible (PointStyle(color=0) maps to
marker alpha 0), per-feature MultiPolygon styles are dropped at render time
(Site Planner coverage contours lose their dBm colors), and MultiGeometry
features cannot be removed (layer toggle-off leaks objects, re-show
duplicates them).

Rebuild the Map Layers region directly on the new public pipeline instead:

- Parse with GeoJsonParser / KmlParser / KmzParser (zip magic sniffed, since
  LayerType.KML covers both .kml and .kmz) and map via toLayer().
- Re-apply simplestyle-spec styling as a pass over the immutable model
  features, preserving everything the upstream mapper misses: the legacy
  `color` fallback, rgb()/rgba() colors, the 0.35 default fill opacity that
  makes stacked contour bands read as a gradient, and PolygonStyle for
  MultiPolygon (upstream styles any multi-geometry as a line).
- Render through a single-use MapViewRenderer per show, torn down with
  clear() — the only teardown that reliably removes MultiGeometry objects —
  re-wiring KMZ images via cacheImageData on each show.

Behavior preserved: KML/KMZ/GeoJSON custom layers, per-feature simplestyle
colors, visibility toggling, refresh re-parse, points keep default markers.

Verified: spotlessApply spotlessCheck detekt :androidApp:compileGoogleDebugKotlin
(zero deprecation warnings remain in map code).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 7b168f35-18fc-4dad-86b8-4c28be6f0b02

📥 Commits

Reviewing files that changed from the base of the PR and between c80d0eb and 310f11f.

📒 Files selected for processing (1)
  • androidApp/src/google/kotlin/org/meshtastic/app/map/MapView.kt
🚧 Files skipped from review as they are similar to previous changes (1)
  • androidApp/src/google/kotlin/org/meshtastic/app/map/MapView.kt

📝 Walkthrough

Walkthrough

MapView.kt replaces Google maps-utils layer objects with a DataLayer and MapViewRenderer pipeline. It adds KMZ detection, unified GeoJSON/KML/KMZ parsing, simplestyle CSS color handling, renderer lifecycle management, and safe visibility toggling.

Changes

Map rendering pipeline

Layer / File(s) Summary
DataLayer parsing and renderer lifecycle
androidApp/src/google/kotlin/org/meshtastic/app/map/MapView.kt
GeoJSON, KML, and KMZ inputs are converted to DataLayer objects, rendered with MapViewRenderer, and shown or hidden through managed renderer lifecycle methods.
Simplestyle styling and color parsing
androidApp/src/google/kotlin/org/meshtastic/app/map/MapView.kt
Features receive polygon and line styles from simplestyle properties, including CSS colors, opacity, and stroke width.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant MapLayerOverlay
  participant parseMapLayer
  participant MapViewRenderer
  MapLayerOverlay->>parseMapLayer: parse GeoJSON, KML, or KMZ
  parseMapLayer->>MapViewRenderer: provide DataLayer
  MapViewRenderer->>MapLayerOverlay: render or clear map layer
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly captures the main change: migrating custom map overlays to the maps-utils 5.0 data layer.
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.

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.

@jamesarich
jamesarich marked this pull request as ready for review July 16, 2026 18:09

@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: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@androidApp/src/google/kotlin/org/meshtastic/app/map/MapView.kt`:
- Around line 1432-1448: Update Feature.applySimpleStyleSpec() to parse the
stroke-opacity property and apply it to the resolved stroke color before
rebuilding styles. Use the alpha-adjusted stroke color for both
PolygonStyle.strokeColor and LineStyle.color, while preserving existing
fill-opacity and default-color behavior.
- Around line 1316-1324: Move the parseMapLayer call out of the MapEffect
execution context so KML/KMZ/GeoJSON parsing runs on the injected IO dispatcher.
Prefer exposing this through MapLayersManager or MapViewModel; otherwise wrap
only the inputStream.use { parseMapLayer(...) } step with the IO dispatcher,
while preserving the existing null and RenderedMapLayer handling.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: b7586055-bc2d-448b-b7f3-385de00b0902

📥 Commits

Reviewing files that changed from the base of the PR and between a0484e7 and c80d0eb.

📒 Files selected for processing (1)
  • androidApp/src/google/kotlin/org/meshtastic/app/map/MapView.kt

Comment thread androidApp/src/google/kotlin/org/meshtastic/app/map/MapView.kt
Comment thread androidApp/src/google/kotlin/org/meshtastic/app/map/MapView.kt
Address CodeRabbit review on #6304:
- Wrap the KML/KMZ/GeoJSON parse in Dispatchers.IO so large layers don't
  stall the main thread inside MapEffect (stream open already ran on IO;
  the parse itself did not).
- Carry simplestyle stroke-opacity through the rebuilt styles for both
  PolygonStyle.strokeColor and LineStyle.color, matching the upstream
  mapper's handling that the rebuild replaces.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@jamesarich

Copy link
Copy Markdown
Collaborator Author

The three upstream bugs this migration routes around are now filed with fix PRs against googlemaps/android-maps-utils:

If/when those land, the single-use-renderer workaround and part of the local simplestyle pass here can be slimmed down — tracked for a future bump.

🤖 Generated with Claude Code

@jamesarich
jamesarich enabled auto-merge July 16, 2026 18:52
@jamesarich
jamesarich disabled auto-merge July 16, 2026 18:53
@jamesarich
jamesarich merged commit 98159a7 into main Jul 16, 2026
3 checks passed
@jamesarich
jamesarich deleted the claude/agitated-newton-dda31e branch July 16, 2026 18:54
@github-actions github-actions Bot added the refactor no functional changes label Jul 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

refactor no functional changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant