본문 바로가기
Android & Kotlin/Android

[Android Kotlin] 네이버 지도 마커 대량 정보에 대한 최적의 카메라 위치 선정 (+클라이언트 처리 이유)

by 말린밴댕이_공부 2024. 1. 5.
반응형

 

 

앞선 글에서 네이버 지도에서 마커를 찍을 때 카메라 이동에 대한 로직을 처리한 글을 보셨을겁니다.

 

https://bendeng-life.tistory.com/153

 

[Android Kotlin] 안드로이드 네이버 지도SDK 사용자 경험 개선 하기 (카메라 이동, 마커찍기)

네이버 지도에 마커들을 찍는 과정에 대해서 사용자 경험을 개선하기 위해 계속 발전시킨 과정에 대하여 정리하였습니다. 마커들을 찍는 과정의 발전 순서의 가장 큰 핵심은 zoom Level고정 값 →

bendeng-life.tistory.com

 

그럼 여기서 드는 의문이 하나

 

왜 서버에서 로직을 처리하지 않고 클라이언트에서 처리를 할까? 

라는 의문이 들으실 수 있다고 생각합니다.

 

우리에게는 굉장히 많은 상황이 존재합니다.

편의를 위해 (예시로 내가 가고 싶은 특정 지역의 정보) -> A라고 하겠습니다.

 

1. 사용자의 필터된 리스트 A가 적을 때 

2. 사용자의 필터된 리스트 A가 어느정도 있을 때 (여러개 ~ 수십개)

3. 사용자의 필터된 리스트 A가 굉장히 대량정보가 있을 때 (수백개)

 

사실 1,2번의 경우에는 고려할 수 는 있지만 서버와의 시간도 적으며 카메라의 이동에 대한 로직 처리를 서버와 클라이언트 어느 쪽에서 처리를 하던 문제가 생기지 않는다고 생각합니다.

 

하지만 3번의 경우에 대해서 클라이언트에서 처리를 해야하는 이유! (+ 왜 서버에서 하지 않아도 되는지) 에 대한 의견입니다. 

 

위의 사진을 보면 500개 정도의 마커들의 데이터를 요청하고 받아와 마커를 찍고 카메라를 이동하는데 소요되는 시간은 약 1.5초 입니다.

 

통신 요청을 시작후 500개에 필요한 데이터를 받는 시간이 1441밀리초(1.44초)로 전체 작업의 시간인 1498밀리초(1.49초)의 약 96%를 차지합니다.

카메라 최적의 위치에 계산을 하는 것은 약 9밀리초(0.009초)로 계산하는 것의 큰 비중을 차지하지 않습니다.

 

ViewModel

private fun myRestaurantList() {
        myRestaurantListUseCase(
            limit = 500
        ).onStart {
						Log.d("500개 통신 : 통신 요청시작", System.currentTimeMillis().toString())
            _events.emit(HomeEvents.ShowLoading)
        }.onEach {
						Log.d("500개 통신 : 통신 데이터 받음", System.currentTimeMillis().toString())
            _events.emit(HomeEvents.RemoveMarkers)
            when (it) {
                is BaseState.Success -> {
                    it.data.restaurantItemsData?.let { restaurants ->
                        val restaurantsList = restaurants.map { data ->
                            data.toUiRestaurantData()
                        }
                        _uiState.update { state ->
                            state.copy(
                                curFilter = MY_LIST,
                                markerList = restaurantsList
                            )
                        }
                    }
                    moveCamera()
                }

                is BaseState.Error -> _events.emit(HomeEvents.ShowSnackMessage(ERROR_MSG))
            }
            _events.emit(HomeEvents.SetNewMarkers)
        }.onCompletion {
            _events.emit(HomeEvents.DismissLoading)
            Log.d("500개 통신 : 전체 작업 종료", System.currentTimeMillis().toString())
        }.launchIn(viewModelScope)
    }

private fun moveCamera() {
        Log.d("500개 통신 : 카메라 로직 시작", System.currentTimeMillis().toString())
//카메라 계산 로직
// 거리계산 -> 응집도 계산 -> 거리와 응집도를 고려한 최적의 카메라 이동 추출
        Log.d("500개 통신 : 카메라 로직 종료", System.currentTimeMillis().toString())
    }

 

View

private fun handleMarkersEvent() {
        removeAllMarker()
        viewModel.trackingOff()
        val lat = viewModel.uiState.value.cameraLatitude
        val lng = viewModel.uiState.value.cameraLongitude
        val zoom = viewModel.uiState.value.cameraZoom

        val cameraPosition = CameraPosition(LatLng(lat, lng), zoom)
        val cameraUpdate = CameraUpdate.toCameraPosition(cameraPosition)
            .apply { animate(CameraAnimation.Fly, 500) }

        naverMap.moveCamera(cameraUpdate)

        Log.d("500개 통신 : 마커 찍기 시작", System.currentTimeMillis().toString())
        viewModel.uiState.value.markerList.forEach { data ->
            setMarker(data)
        }
        Log.d("500개 통신 : 마커 찍기 종료", System.currentTimeMillis().toString())
    }

 

 

그럼에도 왜 안드로이드에서 로직을 진행하였는가?

 

위의 통신 로그를 보면 500개 정도 밖에 되지 않았지만 서버와의 통신 시간이 95%이상을 차지하는 와중 만약 수천 개의 데이터를 통신을 한다고 가정을 한다면 통신 시간의 비중은 95%보다 압도적으로 늘어날 것으로 예상이 됩니다. (귀납적으로 150, 300, 500개 테스트 진행 완료)

 

위의 영상과 같이 사용자가 서버에 데이터를 요청을 하고 카메라의 위치를 이동을 하였다고 가정을 해보겠습니다.

 

이러한 상황에서 만약 서버가 카메라 최적의 위치를 계산하여 보내주게 된다면 통신 사이에 사용자가 지도를 이동을 한다고 가정한다면 현재 카메라의 위치와 관련 없는 곳으로 이동이 됩니다.

 

💡 정리

대량의 데이터를 서버와 통신을 진행할 때

  1. 서버의 통신 시간이 95%이상을 차지함
  2. 마커들의 위치를 기준으로 최적의 카메라 위치를계산할 때 모든 마커가 계산된다는 전제가 있어도 카메라 이동 시간은 매우 낮음 (카메라 이동 알고리즘 + 마커 찍기의 총 소요시간 : 30밀리초(0.03초))
  3.  1,2번의 이유로 서버의 통신 시간이 길면 길 수록 사용자가 마커 정보들을 요청 하고 지도를 이동하였을 때 전혀 관련 없는 위치로 이동하게 된다는 치명적인 결함 때문 클라이언트가 하는 것이 효율적으로 판단

 

결론

마커를 찍는 과정이나 카메라를 이동하는 부분에서 시간은 지극히 적습니다.

 

이를 통해 사용자가 대량의 데이터를 요청하여 통신 시간이 길어질 때 카메라를 이동하였을 때 서버의 위치를 기반으로 카메라의 위치 데이터를 제공한다면 사용자가 지도를 이동하여 보고 있을 때 사용자 경험을 굉장히 저해한다고 판단하여 클라이언트에서 로직 처리를 하는 것이 옳다고 판단되어 진행해보았습니다.

 

데이터의 송수신의 시간이 굉장히 많은 비중을 차지하고 사용자 경험을 위해 클라이언트 측에서 카메라 이동(500개 데이터 기준 9밀리 초 차지)을 하는 것이 효율적이라고 판단 되어 클라이언트에서 처리를 하는것이 오히려 좋다고 판단하였습니다.

 

반응형

댓글