Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
70b8541
TempSave
KouTsukigase Aug 2, 2025
77aa1ee
TempSave2
KouTsukigase Aug 4, 2025
19257b4
TempSave3
KouTsukigase Aug 4, 2025
5fe366c
WIP: In-progress implementation of GroundImage feature for HERE Map; …
KouTsukigase Aug 4, 2025
5a87a98
Resolve merge conflicts.
KouTsukigase Aug 4, 2025
81d8645
WIP: GroundImage bounds change detection in progress.
KouTsukigase Aug 5, 2025
1acf8a3
WIP: GroundImage rendered; modification handling not yet done.
KouTsukigase Aug 7, 2025
4d515a4
Add support for swapping GroundImage (Google Maps API GroundOverlay) …
KouTsukigase Aug 10, 2025
e255ab8
Impliment edit opacity slider'.
KouTsukigase Aug 11, 2025
49eacd2
Merge: the latest main branch into ground_overlay
wf9a5m75 Aug 14, 2025
1b1e051
update README.md
KouTsukigase Aug 14, 2025
69c9757
Changes groundImageState.opacity following the slider value
KouTsukigase Aug 14, 2025
2892c26
Merge branch 'main' into ground_overlay
wf9a5m75 Aug 15, 2025
24a5226
Initial implementation of GroundImage (GroundOverlay). NE and SW mark…
KouTsukigase Aug 17, 2025
2e47320
Resolve merge conflicts during rebase on ground_overlay.
KouTsukigase Aug 17, 2025
d705245
WIP: GroundImage feature implementation. Known issue: recomposition d…
KouTsukigase Aug 17, 2025
8b87864
Fix: GroundImage does not update by following markers
wf9a5m75 Aug 17, 2025
5ae8472
Fix: GeoRectBounds.extend is incorrect
wf9a5m75 Aug 17, 2025
82daee1
Update: Marker labels based on the relative positions
wf9a5m75 Aug 17, 2025
98f03ae
Prepared initial implementation setup of MapDesignType for Google Map…
KouTsukigase Aug 20, 2025
5a2bde3
Prepared initial implementation setup of MapDesignType for Google Map…
KouTsukigase Aug 20, 2025
9c5c7d2
Resolve conflicts and add MapDesign demo with Google Maps SDK.
KouTsukigase Aug 21, 2025
b6f67ef
Add MapDesign change demo for Google Maps API and initial Here Map su…
KouTsukigase Aug 22, 2025
9183548
feat(here): add MapDesign support for HereMap with runtime style swit…
KouTsukigase Aug 23, 2025
88e104d
feat(Mapbox): add MapDesign support for Mapbox with runtime style swi…
KouTsukigase Aug 23, 2025
fa0898e
feat(ArcGIS): add MapDesign support for ArcGIS with runtime style swi…
KouTsukigase Aug 23, 2025
6892edd
Refactor MapDesign selection UI: replace button controls with dropdow…
KouTsukigase Aug 24, 2025
bcdf42f
Refactor: update variable names to match dropdown list usage.
KouTsukigase Aug 24, 2025
d0f0131
Update MapDesign list handling to show all available designs instead …
KouTsukigase Aug 24, 2025
5075d88
Refactor: move design data definition out of onMapViewChanged() and d…
KouTsukigase Aug 24, 2025
e61fe0f
Merge branch 'main' into map_design
KouTsukigase Aug 26, 2025
cf9e701
Refactored code based on review feedback.(1st)
KouTsukigase Aug 26, 2025
ac65430
Merge branch 'map_design' of https://github.com/MapConductor/android-…
KouTsukigase Aug 26, 2025
c7a734c
Refactored code based on review feedback.(2nd)
KouTsukigase Aug 26, 2025
0fe31fa
Refactored code based on review feedback.(3rd)
KouTsukigase Aug 27, 2025
29a7473
Refactored code based on review feedback.(4th)
KouTsukigase Aug 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ KtLintに従います。ローカルで実行する場合は、下記コマン
| Map | ☑ | ☑ | ☑ | ☑ |
| Marker | ☑ | ☑ | ☑ | ☑ |
| Circle | ☑ | ☑ | ☐ | ☐ (wip) |
| Polyline | ☐ | ☐ | ☐ | ☐ |
| Polygon | ☐ | ☐ | ☐ | ☐ |
| GroundOverlay | ☐ | ☐ | ☐ | ☐ |
| RasterTileLayer | ☐ | ☐ | ☐ | ☐ |
| VectorTileLayer | ☐ | ☐ | ☐ | ☐ |
| Polyline | ☑ | ☑ | ☑ | ☑ |
| Polygon | ☐ | ☐ | ☐ | ☐ |
| GroundOverlay | ☐ | ☐ | ☐ | ☐ |
| RasterTileLayer | ☐ | ☐ | ☐ | ☐ |
| VectorTileLayer | ☐ | ☐ | ☐ | ☐ |
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ package com.mapconductor.example
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Build
import androidx.compose.material.icons.filled.CheckCircle
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.material.icons.filled.Home
import androidx.compose.material.icons.filled.PlayArrow
import androidx.compose.material3.Text
Expand All @@ -17,8 +19,11 @@ import androidx.core.content.ContextCompat
import androidx.lifecycle.viewmodel.compose.viewModel
import com.mapconductor.example.navigation.NavigationViewModel
import com.mapconductor.example.pages.circle.CircleMapPage
import com.mapconductor.example.pages.groundimage.GroundImageMapPage
import com.mapconductor.example.pages.groundimage.GroundImageResources
import com.mapconductor.example.pages.map.flyto.FlyToMapIcons
import com.mapconductor.example.pages.map.flyto.FlyToMapPage
import com.mapconductor.example.pages.mapDesign.MapDesignMapPage
import com.mapconductor.example.pages.polyline.PolylineMapPage
import com.mapconductor.example.pages.stores.StoreMapPage
import com.mapconductor.example.ui.sidebar.Sidebar
Expand All @@ -42,6 +47,14 @@ fun DemoAppScreen() {
)
}

val groundImageResources =
remember {
GroundImageResources(
image = ContextCompat.getDrawable(context, R.drawable.newark_nj_1922_0)!!,
clickedImage = ContextCompat.getDrawable(context, R.drawable.newark_nj_1922_1)!!,
)
}

val sidebarItems =
listOf(
SidebarItem(
Expand All @@ -62,12 +75,24 @@ fun DemoAppScreen() {
icon = Icons.Default.CheckCircle,
route = "circle",
),
SidebarItem(
id = "groundImage",
title = "GroundImage",
icon = Icons.Default.Favorite,
route = "groundImage",
),
SidebarItem(
id = "polyline",
title = "Polyline ",
icon = Icons.Default.PlayArrow,
route = "polyline",
),
SidebarItem(
id = "mapDesign",
title = "MapDesign Demo",
icon = Icons.Default.Build,
route = "mapDesign",
),
// SidebarItem(
// id = "examples",
// title = "Map Examples",
Expand Down Expand Up @@ -108,6 +133,17 @@ fun DemoAppScreen() {
onToggleSidebar = navigationViewModel::toggleSidebar,
)
}
"groundImage" -> {
GroundImageMapPage(
groundImageResources = groundImageResources,
onToggleSidebar = navigationViewModel::toggleSidebar,
)
}
"mapDesign" -> {
MapDesignMapPage(
onToggleSidebar = navigationViewModel::toggleSidebar,
)
}
"settings" -> {
// Placeholder for settings page
Box(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.mapconductor.arcgis.ArcGISMapView
import com.mapconductor.arcgis.ArcGISMapViewState
import com.mapconductor.core.MapViewScope
import com.mapconductor.core.circle.OnCircleEventHandler
import com.mapconductor.core.groundimage.OnGroundImageEventHandler
import com.mapconductor.core.map.MapViewState
import com.mapconductor.core.map.OnMapEventHandler
import com.mapconductor.core.marker.OnMarkerEventHandler
Expand All @@ -30,6 +31,7 @@ fun MapViewContainer(
onMarkerAnimateEnd: OnMarkerEventHandler? = null,
onCircleClick: OnCircleEventHandler? = null,
onPolylineClick: OnPolylineEventHandler? = null,
onGroundImageClick: OnGroundImageEventHandler? = null,
content: @Composable MapViewScope.() -> Unit,
) {
when (state) {
Expand All @@ -46,6 +48,7 @@ fun MapViewContainer(
onMarkerAnimateEnd = onMarkerAnimateEnd,
onCircleClick = onCircleClick,
onPolylineClick = onPolylineClick,
onGroundImageClick = onGroundImageClick,
content = content,
)

Expand All @@ -60,6 +63,7 @@ fun MapViewContainer(
onMarkerDragEnd = onMarkerDragEnd,
onMarkerAnimateStart = onMarkerAnimateStart,
onMarkerAnimateEnd = onMarkerAnimateEnd,
onGroundImageClick = onGroundImageClick,
onCircleClick = onCircleClick,
onPolylineClick = onPolylineClick,
content = content,
Expand All @@ -78,6 +82,7 @@ fun MapViewContainer(
onMarkerAnimateEnd = onMarkerAnimateEnd,
onCircleClick = onCircleClick,
onPolylineClick = onPolylineClick,
onGroundImageClick = onGroundImageClick,
content = content,
)

Expand All @@ -93,6 +98,7 @@ fun MapViewContainer(
onMarkerAnimateStart = onMarkerAnimateStart,
onMarkerAnimateEnd = onMarkerAnimateEnd,
onCircleClick = onCircleClick,
onGroundImageClick = onGroundImageClick,
onPolylineClick = onPolylineClick,
content = content,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel

class NavigationViewModel : ViewModel() {
private val _currentPage = mutableStateOf("flyTo")
private val _currentPage = mutableStateOf("groundImage")
val currentPage: State<String> = _currentPage

private val _isSidebarExpanded = mutableStateOf(false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,7 @@ fun CircleMapComponent(
onMarkerDrag = onMarkerDrag,
) {
// Circle
key(viewModel.circleState.id) {
Circle(viewModel.circleState)
}
Circle(viewModel.circleState)

// Center marker (not draggable)
key(viewModel.centerMarker.id) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.mapconductor.example.pages.groundimage

import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.mapconductor.core.groundimage.GroundImage
import com.mapconductor.core.groundimage.OnGroundImageEventHandler
import com.mapconductor.core.map.MapViewState
import com.mapconductor.core.marker.Marker
import com.mapconductor.core.marker.OnMarkerEventHandler
import com.mapconductor.example.MapViewContainer

@Composable
fun GroundImageMapComponent(
mapViewState: MapViewState<*>?,
viewModel: GroundImageMapPageViewModel,
modifier: Modifier = Modifier,
onGroundImageClick: OnGroundImageEventHandler = {},
onMarkerDrag: OnMarkerEventHandler = {},
) {
mapViewState?.let { mapViewState ->
MapViewContainer(
modifier = modifier,
state = mapViewState,
onGroundImageClick = onGroundImageClick,
onMarkerDrag = onMarkerDrag,
) {
// GroundImage
GroundImage(viewModel.groundImageState)

// BoundsMarkers
viewModel.markers.forEach { marker ->
Marker(marker)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package com.mapconductor.example.pages.groundimage

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.calculateEndPadding
import androidx.compose.foundation.layout.calculateStartPadding
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Slider
import androidx.compose.material3.SliderDefaults
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewmodel.compose.viewModel
import com.mapconductor.example.toast.ToastHost
import com.mapconductor.example.ui.DemoMapPageScaffold
import com.mapconductor.example.ui.MessageCard

@Composable
fun GroundImageMapPage(
groundImageResources: GroundImageResources,
onToggleSidebar: () -> Unit = {},
) {
val viewModel: GroundImageMapPageViewModel =
viewModel<GroundImageMapPageViewModelImpl>(
factory =
object : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(GroundImageMapPageViewModelImpl::class.java)) {
@Suppress("UNCHECKED_CAST")
return GroundImageMapPageViewModelImpl(groundImageResources) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
},
)

DemoMapPageScaffold(
initCameraPosition = viewModel.initCameraPosition,
onToggleSidebar = onToggleSidebar,
onMapViewStateChanged = viewModel::onMapViewChanged,
) { paddingValues ->
val mapViewState = viewModel.mapViewState.collectAsState()

GroundImageMapComponent(
mapViewState = mapViewState.value,
viewModel = viewModel,
onGroundImageClick = viewModel::onGroundImageClick,
onMarkerDrag = viewModel::onMarkerDrag,
)

// Message Card
MessageCard(
modifier =
Modifier
.align(Alignment.BottomStart)
.padding(
bottom = paddingValues.calculateBottomPadding() + 16.dp,
start = paddingValues.calculateStartPadding(LayoutDirection.Ltr) + 16.dp,
end = paddingValues.calculateEndPadding(LayoutDirection.Ltr) + 16.dp,
),
title = "Messages",
) {
Column {
Text("opacity: ${"%.2f".format(viewModel.opacity)}", color = Color.Black)
Slider(
value = viewModel.opacity,
onValueChange = { newValue ->
viewModel.opacity = newValue
},
valueRange = 0.0f..1.0f, // スライダー範囲
steps = 0,
colors =
SliderDefaults.colors(
thumbColor = Color.Black, // つまみの色
activeTrackColor = Color.DarkGray, // 値までのトラック
inactiveTrackColor = Color.LightGray, // 残りのトラック
activeTickColor = Color.Black, // 有効ステップの目盛り
inactiveTickColor = Color.White, // 無効ステップの目盛り
),
)
}
}

ToastHost(
messages = viewModel.messages.collectAsState().value,
onDismiss = { viewModel.removeToast(it) },
)
}
}
Loading
Loading