From 9ded49758278ecb9d660713937f2fd00c7a2ae09 Mon Sep 17 00:00:00 2001 From: Masashi Katsumata Date: Thu, 22 Oct 2026 18:53:56 -0700 Subject: [PATCH] Add a marker label position sample page --- .../com/mapconductor/example/DemoAppScreen.kt | 7 ++ .../labelposition/MarkerLabelPositionPage.kt | 106 ++++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 example-app/src/main/java/com/mapconductor/example/pages/marker/labelposition/MarkerLabelPositionPage.kt diff --git a/example-app/src/main/java/com/mapconductor/example/DemoAppScreen.kt b/example-app/src/main/java/com/mapconductor/example/DemoAppScreen.kt index a0586bff..82cce1ac 100644 --- a/example-app/src/main/java/com/mapconductor/example/DemoAppScreen.kt +++ b/example-app/src/main/java/com/mapconductor/example/DemoAppScreen.kt @@ -32,6 +32,7 @@ import com.mapconductor.example.pages.map.tilt.TiltMapPage import com.mapconductor.example.pages.map.uisettings.UISettingsMapPage import com.mapconductor.example.pages.map.visibleregion.VisibleRegionPage import com.mapconductor.example.pages.marker.animation.AnimationMapPage +import com.mapconductor.example.pages.marker.labelposition.MarkerLabelPositionPage import com.mapconductor.example.pages.marker.icons.MarkerBasicPage import com.mapconductor.example.pages.marker.postoffice.PostOfficePage import com.mapconductor.example.pages.marker.postofficecluster.MarkerClusterMapPage as PostOfficeClusterMapPage @@ -114,6 +115,7 @@ fun DemoAppScreen(initPage: String = "map") { items = listOf( SidebarItem(id = "marker-basic", title = "Marker"), + SidebarItem(id = "marker-label-position", title = "Marker Label Position"), SidebarItem(id = "marker-animation", title = "Marker Animation"), SidebarItem(id = "marker-postoffice", title = "Bunch of Markers"), SidebarItem(id = "marker-postoffice-cluster", title = "Marker Clustering"), @@ -247,6 +249,11 @@ fun DemoAppScreen(initPage: String = "map") { onToggleSidebar = navigationViewModel::toggleSidebar, ) } + "marker-label-position" -> { + MarkerLabelPositionPage( + onToggleSidebar = navigationViewModel::toggleSidebar, + ) + } "marker-animation" -> { AnimationMapPage( onToggleSidebar = navigationViewModel::toggleSidebar, diff --git a/example-app/src/main/java/com/mapconductor/example/pages/marker/labelposition/MarkerLabelPositionPage.kt b/example-app/src/main/java/com/mapconductor/example/pages/marker/labelposition/MarkerLabelPositionPage.kt new file mode 100644 index 00000000..cc93a17d --- /dev/null +++ b/example-app/src/main/java/com/mapconductor/example/pages/marker/labelposition/MarkerLabelPositionPage.kt @@ -0,0 +1,106 @@ +package com.mapconductor.example.pages.marker.labelposition + +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.font.FontFamily +import com.mapconductor.compose.info.InfoBubble +import com.mapconductor.compose.marker.Marker +import com.mapconductor.core.features.GeoPoint +import com.mapconductor.core.map.MapCameraPosition +import com.mapconductor.core.map.MapViewStateInterface +import com.mapconductor.core.marker.DefaultMarkerIcon +import com.mapconductor.core.marker.MarkerState +import com.mapconductor.core.marker.OnMarkerEventHandler +import com.mapconductor.example.MapViewContainer +import com.mapconductor.example.ui.DefaultMapViewItems +import com.mapconductor.example.ui.DemoMapPageScaffold + +// 信州大学(松本キャンパス)周辺に 3 × 3 で並べ、それぞれ違う labelPosition を付ける。 +// react-sdk の marker-label-position、ios-sdk の MarkerLabelPositionMapComponent と同じ配置。 +private val CENTER = GeoPoint.fromLatLong(36.2526, 137.9828) +private const val STEP_LATITUDE = 0.004 +private const val STEP_LONGITUDE = 0.007 + +private val POSITIONS = + listOf( + listOf("left top", "center top", "right top"), + listOf("left center", "center center", "right center"), + listOf("left bottom", "center bottom", "right bottom"), + ) + +@Composable +fun MarkerLabelPositionPage( + modifier: Modifier = Modifier, + onToggleSidebar: () -> Unit = {}, +) { + val initCameraPosition = + MapCameraPosition( + position = CENTER, + zoom = 14.0, + ) + var selectedId by remember { mutableStateOf(null) } + var mapViewState by remember { mutableStateOf?>(null) } + val onMarkerClick: OnMarkerEventHandler = { markerState -> selectedId = markerState.id } + val markerStates = + remember { + POSITIONS.flatMapIndexed { rowIndex, row -> + row.mapIndexed { columnIndex, labelPosition -> + MarkerState( + id = labelPosition, + position = + GeoPoint.fromLatLong( + CENTER.latitude + (1 - rowIndex) * STEP_LATITUDE, + CENTER.longitude + (columnIndex - 1) * STEP_LONGITUDE, + ), + icon = + DefaultMarkerIcon( + label = if (labelPosition == "center center") "信" else "信州大学", + labelPosition = labelPosition, + debug = true, + ), + extra = labelPosition, + onClick = onMarkerClick, + ) + } + } + } + + DemoMapPageScaffold( + menuItems = DefaultMapViewItems(initCameraPosition), + modifier = modifier, + onToggleSidebar = onToggleSidebar, + onMapViewStateChanged = { state -> + @Suppress("UNCHECKED_CAST") + mapViewState = state as MapViewStateInterface + }, + ) { + mapViewState?.let { + MapViewContainer( + state = mapViewState, + onMapClick = { selectedId = null }, + ) { + markerStates.forEach { markerState -> + Marker(markerState) + if (markerState.id == selectedId) { + InfoBubble( + marker = markerState, + bubbleColor = Color.White, + borderColor = Color.Black, + ) { + Text( + text = "labelPosition: \"${markerState.extra}\"", + fontFamily = FontFamily.Monospace, + ) + } + } + } + } + } + } +}