Skip to content

feat(samples): add Cloud-Based Map Styling demo - #52

Draft
dkhawk wants to merge 1 commit into
feature/new_features_with_0.2.2_sdkfrom
feat/cloud-based-map-styling
Draft

feat(samples): add Cloud-Based Map Styling demo#52
dkhawk wants to merge 1 commit into
feature/new_features_with_0.2.2_sdkfrom
feat/cloud-based-map-styling

Conversation

@dkhawk

@dkhawk dkhawk commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator

Note

Stacked PR: This pull request is branched off of and based on PR #50 (feature/new_features_with_0.2.2_sdk). It should be merged after PR #50 is merged.

Summary

This draft PR introduces the Cloud-Based Map Styling showcase demo and automated visual testing suite across Java Views, Kotlin Views, and Jetpack Compose (ApiDemos and ComposeDemos).

This sample demonstrates configuring a Google Maps 3D view with a custom Cloud Map ID (mapId) both declaratively (via XML attributes in View-based samples) and programmatically (via Map3DInitConfig in Jetpack Compose).

Status / Current Behavior

  • Draft PR for Investigation: This demo was split out into a standalone draft PR for review with @LoyalAbbas and @kikoso because custom cloud styles associated with the Map ID currently render as default roadmap tiles rather than applying the cloud-customized style configuration in the Maps 3D SDK.
  • Once the upstream Maps 3D styling behavior is resolved, this demo will serve as the canonical sample for Cloud-Based Map Styling in Android Maps 3D.

Changes Included

  1. Java Views (ApiDemos):

    • CloudStylingActivity.java: Custom Map ID setup via dedicated layout, supporting dynamic mode toggling between Roadmap, Hybrid, and Satellite.
    • activity_cloud_styling.xml & control_panel_cloud_styling.xml: Declarative map3d:mapId="9a35234a36da44d2c47bf626" layout integration with interactive Map Mode selector card.
    • CloudStylingVisualTest.java: Automated UI Automator and Gemini visual regression test synchronized via MapSteady listener.
  2. Kotlin Views (ApiDemos):

    • CloudStylingActivity.kt: Idiomatic Kotlin View-based implementation with custom Map ID and mode controls.
    • CloudStylingVisualTest.kt: Kotlin UI Automator and Gemini visual regression test.
  3. Jetpack Compose (ComposeDemos):

    • CloudStylingActivity.kt: Full Compose 3D implementation utilizing GoogleMap3D and explicit Map3DInitConfig configured with mapId.
    • MainActivity.kt: Registered Cloud-Based Map Styling in the Compose Demos catalog screen.
  4. Tooling & Code Health:

    • Formatted strictly using ./gradlew spotlessApply with 4-space ktlint rules.
    • Verified via ./gradlew test assembleDebug and ./gradlew spotlessCheck.

@dkhawk
dkhawk requested review from LoyalAbbas and kikoso August 19, 2026 23:10

@github-advanced-security github-advanced-security AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Android Lint found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.

<activity android:name=".placedetails.PlaceDetailsActivity" android:exported="true" android:label="Place Details" android:theme="@style/Theme.AppCompat.DayNight.NoActionBar" />
<activity android:name=".advancedcameraanimation.AdvancedCameraAnimationActivity" android:exported="true" android:label="Advanced Camera Animation" />
<activity android:name=".datavisualization.DataVisualizationActivity" android:exported="true" android:label="Data Visualization" />
<activity android:name=".cloudstyling.CloudStylingActivity" android:exported="true" android:label="Cloud Map Styling" />

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This has been eliminated from the Manifest, is it intended?

super.onCreate(savedInstanceState);

// Set dedicated standalone layout with declarative mapId="9a35234a36da44d2c47bf626"
setContentView(R.layout.activity_cloud_styling);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We are extending SampleBaseActivity, and inside SampleBaseActivity we are already setting the content view.

import com.google.android.gms.maps3d.model.camera
import com.google.android.gms.maps3d.model.latLngAltitude
import com.google.maps.android.SphericalUtil
import com.google.maps.android.compose3d.GoogleMap3D

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We are importing two different GoogleMap3Ds here (the class from gms.maps3d and the composable from compose3d), is that intended? Might be worth aliasing one.


btnPlayPause = findViewById(R.id.btn_play_pause);
if (btnPlayPause != null) {
btnPlayPause.setOnClickListener(v -> {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Do we need a guard here? cumulativeDistances is only set in onMap3DViewReady, and Frame Dispatcher is the default approach, could tapping Play early NPE?

return normalized < 0.0 ? normalized + 360.0 : normalized;
}

private static double interpolateAngle(double start, double end, double fraction) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

startHeading is 105 and endHeading is 465 for the orbit step. Doesn't (465 - 105) % 360 give us 0 here? Wouldn't that pin the camera for the whole step instead of rotating it?

return if (normalized < 0.0) normalized + 360.0 else normalized
}

private fun interpolateAngle(start: Double, end: Double, fraction: Double): Double {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Same issue as the Java version. endHeading is startHeading + 360, so diff comes out as 0 and the orbit never actually rotates?

override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge()
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_cloud_styling)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Same as the Java version. We are extending SampleBaseActivity, and it already sets the content view before we call setContentView again here.

return if (normalized < 0.0) normalized + 360.0 else normalized
}

private fun interpolateAngle(start: Double, end: Double, fraction: Double): Double {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Same interpolateAngle issue as the other two flavors. Is the 360° orbit step actually rotating here?

val currentMax = floodSlider.valueTo.toDouble()
var newElevation = currentFloodElevation + 0.2
newElevation = Math.round(newElevation * 10.0) / 10.0
floodSlider.value = newElevation.toFloat()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Could this go over valueTo before we check it below? stepSize is 0.1, so if the slider isn't aligned to 0.2 we'd set a value above 100 and crash.

@dkhawk
dkhawk force-pushed the feat/cloud-based-map-styling branch from bc43579 to f817941 Compare August 20, 2026 18:02
@dkhawk
dkhawk changed the base branch from main to feature/new_features_with_0.2.2_sdk August 20, 2026 18:04
style="@style/TextAppearance.Material3.LabelLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Map Mode"
android:layout_height="wrap_content"
android:layout_weight="1"
android:checked="true"
android:text="Roadmap"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Hybrid"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Satellite"
@dkhawk
dkhawk force-pushed the feat/cloud-based-map-styling branch from f817941 to 0103ac7 Compare August 20, 2026 18:51
@dkhawk
dkhawk force-pushed the feat/cloud-based-map-styling branch from 0103ac7 to 9d16780 Compare August 20, 2026 20:03
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.

3 participants