Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ 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.Place
import androidx.compose.material.icons.filled.PlayArrow
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
Expand All @@ -18,6 +19,7 @@ import androidx.compose.ui.platform.LocalContext
import androidx.core.content.ContextCompat
import androidx.lifecycle.viewmodel.compose.viewModel
import com.mapconductor.example.navigation.NavigationViewModel
import com.mapconductor.example.pages.animation.AnimationMapPage
import com.mapconductor.example.pages.circle.CircleMapPage
import com.mapconductor.example.pages.groundimage.GroundImageMapPage
import com.mapconductor.example.pages.groundimage.GroundImageResources
Expand Down Expand Up @@ -87,6 +89,12 @@ fun DemoAppScreen() {
icon = Icons.Default.PlayArrow,
route = "polyline",
),
SidebarItem(
id = "animation",
title = "Animation ",
icon = Icons.Default.Place,
route = "animation",
),
SidebarItem(
id = "mapDesign",
title = "MapDesign Demo",
Expand Down Expand Up @@ -133,6 +141,11 @@ fun DemoAppScreen() {
onToggleSidebar = navigationViewModel::toggleSidebar,
)
}
"animation" -> {
AnimationMapPage(
onToggleSidebar = navigationViewModel::toggleSidebar,
)
}
"groundImage" -> {
GroundImageMapPage(
groundImageResources = groundImageResources,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.mapconductor.example.pages.animation

import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.mapconductor.core.circle.OnCircleEventHandler
import com.mapconductor.core.map.MapViewState
import com.mapconductor.core.map.OnMapEventHandler
import com.mapconductor.core.marker.Marker
import com.mapconductor.core.marker.OnMarkerEventHandler
import com.mapconductor.example.MapViewContainer

@Composable
fun AnimationMapComponent(
mapViewState: MapViewState<*>?,
viewModel: AnimationPageViewModel,
modifier: Modifier = Modifier,
onMapClick: OnMapEventHandler = {},
onMarkerClick: OnMarkerEventHandler = {},
onCircleClick: OnCircleEventHandler = {},
onMarkerDrag: OnMarkerEventHandler = {},
) {
mapViewState?.let {
MapViewContainer(
modifier = modifier,
state = it,
onMapClick = onMapClick,
onMarkerClick = onMarkerClick,
onCircleClick = onCircleClick,
onMarkerDrag = onMarkerDrag,
) {
viewModel.allMarkers.forEach { marker ->
Marker(marker)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.mapconductor.example.pages.animation

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.calculateEndPadding
import androidx.compose.foundation.layout.calculateStartPadding
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
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.unit.LayoutDirection
import androidx.compose.ui.unit.dp
import com.mapconductor.example.ui.DemoMapPageScaffold
import com.mapconductor.example.ui.MessageCard

@Composable
fun AnimationMapPage(
viewModel: AnimationPageViewModel = AnimationPageViewModelImpl(),
onToggleSidebar: () -> Unit = {},
) {
DemoMapPageScaffold(
initCameraPosition = viewModel.initCameraPosition,
onToggleSidebar = onToggleSidebar,
onMapViewStateChanged = viewModel::onMapViewChanged,
) { paddingValues ->
val mapViewState = viewModel.mapViewState.collectAsState()

AnimationMapComponent(
mapViewState = mapViewState.value,
viewModel = viewModel,
onMarkerClick = viewModel::onMarkerClick,
)

// 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 = "Animation list",
) {
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.spacedBy(8.dp),
) {
viewModel.allMarkers.forEach { marker ->
Row {
Button(
modifier = Modifier.weight(1f),
onClick = { viewModel.onMarkerClick(marker) },
) {
Text(viewModel.getSpotName(marker.id))
}
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package com.mapconductor.example.pages.animation

import androidx.compose.runtime.getValue
import androidx.lifecycle.ViewModel
import com.mapconductor.core.features.GeoPoint
import com.mapconductor.core.map.MapCameraPosition
import com.mapconductor.core.map.MapViewState
import com.mapconductor.core.marker.DefaultIcon
import com.mapconductor.core.marker.MarkerAnimation
import com.mapconductor.core.marker.MarkerState
import com.mapconductor.example.toast.ToastMessage
import java.util.NoSuchElementException
import android.util.Log
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow

private data class Spot(
val id: String,
val name: String,
val animation: MarkerAnimation,
val point: GeoPoint,
)

private val exampleSpots =
listOf(
Spot(
id = "s1",
name = "Bounce",
animation = MarkerAnimation.Bounce,
point = GeoPoint.fromLatLong(21.3069, -157.8583),
),
Spot(
id = "s2",
name = "Drop",
animation = MarkerAnimation.Drop,
point = GeoPoint.fromLatLong(21.4513, -158.0152),
),
)

interface AnimationPageViewModel {
val initCameraPosition: MapCameraPosition
val mapViewState: StateFlow<MapViewState<*>?>
val messages: StateFlow<List<ToastMessage>>
val allMarkers: List<MarkerState>

val circleCenter: GeoPoint

fun getSpotName(markerId: String): String

fun onMapViewChanged(state: MapViewState<*>)

fun onMarkerClick(clicked: MarkerState)
}

class AnimationPageViewModelImpl :
ViewModel(),
AnimationPageViewModel {
private val _messages: MutableStateFlow<List<ToastMessage>> = MutableStateFlow(emptyList())
override val messages: StateFlow<List<ToastMessage>> = _messages.asStateFlow()

override val initCameraPosition =
MapCameraPosition(
position =
GeoPoint.fromLatLong(
latitude = 21.382314,
longitude = -157.933097,
),
zoom = 9.0,
bearing = 0.0,
tilt = 0.0,
paddings = null,
)

override val circleCenter = GeoPoint.fromLatLong(21.382314, -157.933097)

private val markers: Map<String, MarkerState> =
exampleSpots.associate { spot ->
spot.id to
MarkerState(
id = spot.id,
position = spot.point,
icon = DefaultIcon(label = spot.name),
animation = null,
)
}
override val allMarkers: List<MarkerState> get() = markers.values.toList()

private val _mapViewState = MutableStateFlow<MapViewState<*>?>(null)
override val mapViewState: StateFlow<MapViewState<*>?> = _mapViewState.asStateFlow()

override fun getSpotName(markerId: String): String =
exampleSpots.firstOrNull { it.id == markerId }?.name
?: throw NoSuchElementException("Spot not found: $markerId")

override fun onMapViewChanged(state: MapViewState<*>) {
this._mapViewState.value = state
}

override fun onMarkerClick(clicked: MarkerState) {
// When you want to activate the marker, set the animation for the marker.
Log.i("AnimationPageViewModelImpl", "onMarkerClick: ${clicked.id}")

val spot = exampleSpots.firstOrNull { it.id == clicked.id }
clicked.animation = spot?.animation
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -179,10 +179,16 @@ class MapDesignPageViewModelImpl :
MapDesignOptions(label = "HumanGeographyLabels", design = ArcGISDesign.Companion.HumanGeographyLabels),
MapDesignOptions(label = "HumanGeographyDark", design = ArcGISDesign.Companion.HumanGeographyDark),
MapDesignOptions(label = "HumanGeographyDarkBase", design = ArcGISDesign.Companion.HumanGeographyDarkBase),
MapDesignOptions(label = "HumanGeographyDarkDetail", design =
ArcGISDesign.Companion.HumanGeographyDarkDetail),
MapDesignOptions(label = "HumanGeographyDarkLabels", design =
ArcGISDesign.Companion.HumanGeographyDarkLabels),
MapDesignOptions(
label = "HumanGeographyDarkDetail",
design =
ArcGISDesign.Companion.HumanGeographyDarkDetail,
),
MapDesignOptions(
label = "HumanGeographyDarkLabels",
design =
ArcGISDesign.Companion.HumanGeographyDarkLabels,
),
MapDesignOptions(label = "Outdoor", design = ArcGISDesign.Companion.Outdoor),
MapDesignOptions(label = "OsmStandard", design = ArcGISDesign.Companion.OsmStandard),
MapDesignOptions(label = "OsmStandardRelief", design = ArcGISDesign.Companion.OsmStandardRelief),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,7 @@ interface MapViewState<ActualMapDesignType> {

fun resetInitState()

fun changeMapDesignType(
value: ActualMapDesignType
)
fun changeMapDesignType(value: ActualMapDesignType)

fun moveCameraTo(
cameraPosition: MapCameraPosition,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ abstract class AbstractMarkerRenderer<ActualMarker> : MarkerRenderer<ActualMarke
}
}.onEach { t ->
val startLatLng = holder.fromScreenOffset(startPoint) ?: return@onEach
val lng = target.longitude
val lng = t * target.longitude + (1f - t) * startLatLng.longitude
val lat = t * target.latitude + (1f - t) * startLatLng.latitude

// 現在の座標をマーカーに適用
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ sealed class Settings(
) {
object Default : Settings(
tapTolerance = 14.dp,
markerDropAnimateDuration = 100,
markerDropAnimateDuration = 300,
markerBounceAnimateDuration = 2000,
iconSize = MarkerIconSize.Regular,
iconStroke = 1.dp,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.mapconductor.arcgis

import com.arcgismaps.mapping.Basemap
import com.arcgismaps.mapping.view.Graphic
import com.arcgismaps.mapping.view.GraphicsOverlay
import com.arcgismaps.mapping.view.LongPressEvent
Expand Down Expand Up @@ -44,7 +45,6 @@ import android.view.MotionEvent
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import com.arcgismaps.mapping.Basemap

interface IArcGISMapViewController :
MapViewController<
Expand All @@ -53,9 +53,7 @@ interface IArcGISMapViewController :
ArcGISActualPolyline,
ArcGISActualPolygon,
> {
fun changeMapDesign(
value: String
)
fun changeMapDesign(value: String)

fun moveCamera(
dstPosition: MapCameraPosition,
Expand Down Expand Up @@ -344,16 +342,14 @@ class ArcGISMapViewController(

override suspend fun updateCircle(state: CircleState) = circleOverlayManager.updateCircle(state)

override fun changeMapDesign(
value: String
){
override fun changeMapDesign(value: String) {
coroutine.launch {
holder.map.scene!!.setBasemap(
Basemap(
ArcGISDesign.toBasemapStyle(
ArcGISDesign(value)
)
)
ArcGISDesign(value),
),
),
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import com.mapconductor.core.map.BaseMapViewSaver
import com.mapconductor.core.map.IMapCameraPosition
import com.mapconductor.core.map.InitState
import com.mapconductor.core.map.MapCameraPosition
import com.mapconductor.core.map.MapDesignType
import com.mapconductor.core.map.MapPaddings
import com.mapconductor.core.map.MapPaddingsImpl
import com.mapconductor.core.map.MapViewState
Expand All @@ -27,8 +26,7 @@ class ArcGISMapViewState(
override val id: String,
override val initCameraPosition: MapCameraPosition,
override var mapDesignType: ArcGISDesign,
) : MapViewStateImpl<ArcGISDesign>()
{
) : MapViewStateImpl<ArcGISDesign>() {
// Map padding
private val _padding = MutableStateFlow(MapPaddingsImpl.Zeros)
val padding: StateFlow<MapPaddings> = _padding.asStateFlow()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ class ArcGISMarkerRenderer(
markerEntity: MarkerEntity<Graphic>,
position: GeoPoint,
) {
markerEntity.marker.geometry = position.toPoint(holder.map.scene?.spatialReference)
coroutine.launch {
markerEntity.marker.geometry = position.toPoint(holder.map.scene?.spatialReference)
}
}

override suspend fun addIcons(newMarkers: List<Pair<MarkerState, BitmapIcon>>): List<Graphic?> {
Expand Down
Loading
Loading