Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clustering Marker 에 대한 Icon Custom Design 지원 #111

Open
easyhooon opened this issue Jul 2, 2024 · 1 comment
Open

Clustering Marker 에 대한 Icon Custom Design 지원 #111

easyhooon opened this issue Jul 2, 2024 · 1 comment

Comments

@easyhooon
Copy link

easyhooon commented Jul 2, 2024

우선 저번에 만들어주셨던 MarkerComposable 를 잘 사용하고 있습니다 감사합니다ㅎ

혹시 Clustering Marker 도 Composable 함수를 통해 커스텀이 가능한지, 지원이 가능한지 문의드립니다.

일반적은 마커의 경우 컴포저블 함수인 MarkerComposable 사용하여 원하는 형태의 마커를 구현할 수 있었으나,
클러스터링 마커의 경우 .cluserMarkerUpdate(), .leafMarkerUpdater 내에 updateClusterMarker 함수 혹은 updateLeafMarker 함수 내에서 marker 에 대한 설정을 할 수 있으므로, 컴포저블 함수인 MarkerComposable 함수를 사용할 수 없었습니다.

@OptIn(ExperimentalNaverMapApi::class)
@Composable
fun MapContent(
    uiState: MapUiState,
    cameraPositionState: CameraPositionState,
    rotationState: Float,
    pagerState: PagerState,
    onMapUiAction: (MapUiAction) -> Unit,
    onFestivalUiAction: (FestivalUiAction) -> Unit,
) {
    // val context = LocalContext.current
    Box {
        // TODO 같은 속성(주점, 이벤트)의 Marker 들만 클러스터링 되도록 구현
        // TODO 클러스터링 마커 커스텀
        NaverMap(
            cameraPositionState = cameraPositionState,
            locationSource = rememberFusedLocationSource(),
            uiSettings = MapUiSettings(
                isZoomControlEnabled = false,
                isScaleBarEnabled = false,
                isLogoClickEnabled = false,
            ),
            properties = MapProperties(
                locationTrackingMode = LocationTrackingMode.NoFollow,
            ),
        ) {
            PolygonOverlay(
                coords = uiState.outerCords,
                color = Color.Gray.copy(alpha = 0.3f),
                outlineColor = Color.Gray,
                outlineWidth = 1.dp,
                holes = persistentListOf(uiState.innerHole),
            )
            uiState.filteredBoothsList.forEach { booth ->
                Marker(
                    state = MarkerState(position = booth.position),
                    icon = MarkerCategory.fromString(booth.category).getMarkerIcon(booth.isSelected),
                    onClick = {
                        // onMapUiAction(MapUiAction.OnBoothMarkerClick(booth))
                        true
                    },
                )
                MarkerComposable {}
            }

            var clusterManager by remember { mutableStateOf<Clusterer<BoothMapModel>?>(null) }
            DisposableMapEffect(uiState.boothList) { map ->
                if (clusterManager == null) {
                    clusterManager = Clusterer.Builder<BoothMapModel>()
                        .clusterMarkerUpdater(
                            object : DefaultClusterMarkerUpdater() {
                                override fun updateClusterMarker(info: ClusterMarkerInfo, marker: Marker) {
                                    super.updateClusterMarker(info, marker)
                                    MarkerComposable {} // <- error - @Composable invocations can only happen from the context of a @Composable functio
                                }
                            },
                            MarkerComposable {} // <- error - @Composable invocations can only happen from the context of a @Composable functio
                        )
                      .leafMarkerUpdater(
                            object : DefaultLeafMarkerUpdater() {
                                override fun updateLeafMarker(info: LeafMarkerInfo, marker: Marker) {
                                    super.updateLeafMarker(info, marker)
                                    marker.apply {
                                        icon = MarkerCategory.fromString((info.key as BoothMapModel).category)
                                            .getMarkerIcon((info.key as BoothMapModel).isSelected)
                                        onClickListener = Overlay.OnClickListener {
                                            onMapUiAction(MapUiAction.OnBoothMarkerClick(listOf(info.key as BoothMapModel)))
                                            true
                                        }
                                    }
                                    MarkerComposable {} // error - @Composable invocations can only happen from the context of a @Composable function
                                }
                            },
                            MarkerComposable {} // error - @Composable invocations can only happen from the context of a @Composable function
                        )
                        .build()
                        .apply { this.map = map }
                }
                val boothListMap = buildMap(uiState.boothList.size) {
                    uiState.boothList.forEachIndexed { index, booth ->
                        put(booth, index)
                    }
                }
                clusterManager?.addAll(boothListMap)
                onDispose {
                    clusterManager?.clear()
                }
            }

//            var clusterManager by remember { mutableStateOf<TedNaverClustering<BoothMapModel>?>(null) }
//            DisposableMapEffect(uiState.filteredBoothsList) { map ->
//                if (clusterManager == null) {
//                    clusterManager = TedNaverClustering.with<BoothMapModel>(context, map)
//                        .customMarker {
//                            Marker().apply {
//                                icon = MarkerCategory.fromString(it.category).getMarkerIcon(it.isSelected)
//                            }
//                        }
//                        .markerClickListener { booth ->
//                            onMapUiAction(MapUiAction.OnBoothMarkerClick(listOf(booth)))
//                        }
//                        .clusterClickListener { booths ->
//                            onMapUiAction(MapUiAction.OnBoothMarkerClick(booths.items.toList()))
//                        }
//                        // 마커를 클릭 했을 경우 마커의 위치로 카메라 이동 비활성화
//                        .clickToCenter(false)
//                        .make()
//                }
//                clusterManager?.addItems(uiState.filteredBoothsList)
//                onDispose {
//                    clusterManager?.clearItems()
//                }
//            }
        }

목적은 아래의 사진과 같이 Clustering Marker 를 목적에 맞게 커스텀해서 구현하기 위함입니다.

image
(captionText 가 marker의 Design 내에 포함되는 경우, clustering marker 의 info.size 파라미터를 Marker View 의 파라미터로 추가해줘야하는 케이스)

읽어주셔서 감사합니다!

@fornewid
Copy link
Owner

fornewid commented Jul 2, 2024

기능 제안 감사합니다.
다만 제가 당분간은 작업이 어려울 것 같습니다.
여력이 생기면 검토해보겠습니다.

P.S. 지난 주말 행사에서 뵈서 반가웠습니다. 🙇

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

No branches or pull requests

2 participants