kakaomap SDK 2.9.2 버전에서 LodLabel에 클릭후 해당 LodLabel style 변경하려고 합니다만 해당 가이드를 찾아봐도 확인이 어렵습니다.
아이폰의 경우에는 LodLabelLayerOptions을 활용하여 처리가 가능한것으로 확인되었습니다만
안드로이드의 경우에는 해당 LodLabelLayerOptions 기능이 없는것으로 보입니다.
안드로이드의 경우 LodLabel의 경우 클릭시 LodLabel의 style을 변경하는 방법 문의 드립니다.
혹시 안드로이드의 경우 LodLabel의 경우 지원이 안되는 기능이라면 Label의 경우 다수개를 지도에 남길수 있나요? 그리고 Label의 경우 클릭시 style을 변경할수 있는지 문의합니다.
참고로 아래는 현재까지 시도했던 코드입니다.
========================================================
package com.pairplay.pairplay.presentation.course
import com.kakao.vectormap.KakaoMap
import com.kakao.vectormap.KakaoMapReadyCallback
import com.kakao.vectormap.MapView
import com.kakao.vectormap.camera.CameraUpdateFactory
import com.kakao.vectormap.label.Label
import com.kakao.vectormap.label.LabelLayerOptions
import com.kakao.vectormap.label.LabelOptions
import com.kakao.vectormap.label.LabelStyle
import com.kakao.vectormap.label.LabelStyles
import com.kakao.vectormap.label.LodLabel
import com.kakao.vectormap.label.LodLabelLayer
import com.kakao.vectormap.route.RouteLineOptions
import com.kakao.vectormap.route.RouteLineSegment
import com.pairplay.pairplay.R
import com.pairplay.pairplay.base.BaseActivityWithBinding
import com.pairplay.pairplay.databinding.ActGpxMapCourseBinding
import com.pairplay.pairplay.domain.model.LatLng
import com.pairplay.pairplay.domain.model.course.Course
import com.pairplay.pairplay.domain.model.course.CourseGPX
import com.pairplay.pairplay.extension.getBitmapVectorDrawable
import com.pairplay.pairplay.utils.MapUtil
import com.pairplay.pairplay.utils.extension.parcelable
import dagger.hilt.android.AndroidEntryPoint
import timber.log.Timber
@AndroidEntryPoint
class GPXMapCourseAct : BaseActivityWithBinding() {
companion object {
private const val SIGN_POST_LAYER_ID = "SignPostLodLabelLayer"
private const val SIGN_POST_SELECTED_LAYER_ID = "SignPostLodLabelLayer/selected"
}
override fun layoutId() = R.layout.act_gpx_map_course
private var map: KakaoMap? = null
private var mapView: MapView? = null
private var currentSelectedLabel: String? = null
private var courseGPX: CourseGPX? = null
private var course: Course? = null
private val defaultMarkerStyle by lazy {
LabelStyle.from(getBitmapVectorDrawable(this, R.drawable.ic_map_marker_signpost, width=50, height=50))
}
private val selectedMarkerStyle by lazy {
LabelStyle.from(getBitmapVectorDrawable(this, R.drawable.ic_certification_on, width=100, height=100))
}
override fun onBindingCreated(binding: ActGpxMapCourseBinding) {
initialize()
}
override fun onResume() {
super.onResume()
mapView?.resume()
mapView = null
}
override fun onPause() {
super.onPause()
mapView = binding.mapView
binding.mapView.pause()
}
override fun onDestroy() {
mapView = null
binding.mapView.finish()
super.onDestroy()
}
private fun initialize() {
course = intent.parcelable<Course>(Course.EXTRA_COURSE) ?: return
courseGPX = intent.parcelable<CourseGPX>(CourseGPX.EXTRA_COURSE_GPX) ?: return
binding.layoutActionBar.titleText = course?.courseName
initializeMap(course)
}
private fun initializeMap(course: Course?) {
course?.signPosts?.firstOrNull()?.let { signPost ->
binding.mapView.start(object : KakaoMapReadyCallback() {
override fun onMapReady(kakaoMap: KakaoMap) {
map = kakaoMap
map?.setPoiClickable(true)
setupMapListeners()
drawPath()
}
override fun getPosition() = LatLng(
signPost.signpostLat,
signPost.signpostLng
).toKakaoLatLng()
override fun getZoomLevel(): Int = 12
})
}
}
private fun setupMapListeners() {
map?.setOnLodLabelClickListener { kakaoMap, layer, label ->
handleMarkerClick(label)
true
}
}
private fun drawPath() {
course?.signPosts?.let { signPosts ->
drawRoutePoints()
addMarkers(signPosts)
fitMapToSignPosts(signPosts)
}
}
private fun drawRoutePoints() {
courseGPX?.trackPoints
?.mapNotNull { point ->
if (point.latitude != null && point.longitude != null) {
com.kakao.vectormap.LatLng.from(point.latitude, point.longitude)
} else null
}
?.toTypedArray()
?.takeIf { it.isNotEmpty() }
?.let { routePoints ->
// 경로 분할 처리
val segments = mutableListOf<RouteLineSegment>()
val maxPointsPerSegment = 1000 // 세그먼트당 최대 포인트 수
routePoints.toList()
.chunked(maxPointsPerSegment)
.forEach { points ->
val segment = RouteLineSegment.from(points.toTypedArray())
.setStyles(MapUtil.setRoutePathStyleRed(this))
segments.add(segment)
}
// 모든 세그먼트를 지도에 추가
map?.routeLineManager?.layer?.apply {
segments.forEach { segment ->
addRouteLine(RouteLineOptions.from(segment))?.show()
}
}
}
}
private fun fitMapToSignPosts(signPosts: List<Course.SignPost>) {
val points = signPosts.map {
com.kakao.vectormap.LatLng.from(it.signpostLat, it.signpostLng)
}.toTypedArray()
map?.moveCamera(CameraUpdateFactory.fitMapPoints(points, 200))
}
private fun addMarkers(signPosts: List<Course.SignPost>) {
signPosts.forEachIndexed { index, signPost ->
addMarker(signPost, index)
}
}
private fun addMarker(signPost: Course.SignPost, index: Int) {
val position = com.kakao.vectormap.LatLng.from(
signPost.signpostLat,
signPost.signpostLng
)
val options = LabelOptions.from("marker_$index", position)
.setStyles(LabelStyles.from(defaultMarkerStyle))
.setClickable(true)
.setTag(index)
map?.labelManager?.lodLayer?.addLodLabel(options)
}
private fun handleMarkerClick(label: LodLabel) {
Timber.i("rrobbie : handleMarkerClick ")
try {
currentSelectedLabel?.let { previousId ->
map?.labelManager?.lodLayer?.getLabel(previousId)?.let { prevLabel ->
val prevStyle = LabelStyles.from(defaultMarkerStyle)
prevLabel.changeStyles(prevStyle)
}
}
// 새 마커 선택
val newStyle = LabelStyles.from(selectedMarkerStyle)
label.changeStyles(newStyle)
currentSelectedLabel = label.labelId
} catch (e: Exception) {
Timber.e(e, "rrobbie Style change failed")
}
// 선택된 마커의 정보 찾기 및 처리
label.labelId.substringAfter("marker_").toIntOrNull()?.let { index ->
course?.signPosts?.getOrNull(index)?.let { signPost ->
// 선택된 마커에 대한 추가 처리
Timber.d("rrobbie : Selected SignPost: ${signPost.signpostName}")
}
}
/*
// UI 업데이트
label.labelId.substringAfter("marker_").toIntOrNull()?.let { index ->
binding.rvCourseDetail.scrollToPosition(index)
}
*/
}
}