클러스터링은 머신러닝에서 사용되는 용어로 클러스터링이란 유사한 테이터셋들 중 서로서로 찾아내고 묶어내는 것입니다
네이버 지도에서는 클러스터링 기능을 제공하고 있습니다. 지도에서 클러스터링이란 예를 들어 숙박어플 같은 경우 지도에 마커를 사용하여 모든 숙소의 정보를 보여주면 지도에 매우 지져분해 읽기 힘들 것입니다. 하지만 실제로 구현되는 경우에는 지도를 축소하게 되는 경우에 아래 그림처럼 비슷한 위치에 있는 숙소들끼리 합쳐저서 보여지는데 이렇게 합쳐지는, 하나로 묶어지는 것을 클러스터링이라고 합니다.
클러스터링이 안되는 문제
API 문서를 찾아보면서 제작을 진행했는데 시행착오가 있었습니다. 분명 문서대로 코드를 만든 것 같은데 클러스터링이 안되는 것입니다.
클러스터링을 하기 위한 객체를 만들어야 한다길래 NMCClusterer 객체를 만들었습니다.
하지만 문제는 NMCClusterer 객체를 만들어서 진행하였지만 클러스터링이 진행되지 않는 것입니다.
func makeClusterer() {
var clusterer: NMCClusterer<ItemKey>?
let builder = NMCBuilder<ItemKey>()
clusterer = builder.build()
let keyTagMap = [
ItemKey(identifier: 1, position: NMGLatLng(lat: 37.372, lng: 127.113)): NSNull(),
ItemKey(identifier: 2, position: NMGLatLng(lat: 37.366, lng: 127.106)): NSNull(),
ItemKey(identifier: 3, position: NMGLatLng(lat: 37.365, lng: 127.157)): NSNull(),
ItemKey(identifier: 4, position: NMGLatLng(lat: 37.361, lng: 127.105)): NSNull(),
ItemKey(identifier: 5, position: NMGLatLng(lat: 37.368, lng: 127.110)): NSNull(),
ItemKey(identifier: 6, position: NMGLatLng(lat: 37.360, lng: 127.106)): NSNull(),
ItemKey(identifier: 7, position: NMGLatLng(lat: 37.363, lng: 127.111)): NSNull(),
ItemKey(identifier: 8, position: NMGLatLng(lat: 37.36301, lng: 127.111)): NSNull()
]
clusterer?.addAll(keyTagMap)
clusterer?.mapView = self.view.mapView
}
해결 방법
구글링과 삽질을 하다가 결국 네이버 측에 문의를 넣은 결과 데모 버전을 확인해보라는 답변을 받고 데모 버전을 확인해보았습니다.
데모 버전을 확인해본 결과 NMCClusterer를 메서드 내부에서 선언하지 않고 클래스의 지역변수로 선언을 해줬다는 것을 확인한 후 바로 시도해보았습니다.
var clusterer: NMCClusterer<ItemKey>?
func makeClusterer() {
let builder = NMCBuilder<ItemKey>()
self.clusterer = builder.build()
let keyTagMap = [
ItemKey(identifier: 1, position: NMGLatLng(lat: 37.372, lng: 127.113)): NSNull(),
ItemKey(identifier: 2, position: NMGLatLng(lat: 37.366, lng: 127.106)): NSNull(),
ItemKey(identifier: 3, position: NMGLatLng(lat: 37.365, lng: 127.157)): NSNull(),
ItemKey(identifier: 4, position: NMGLatLng(lat: 37.361, lng: 127.105)): NSNull(),
ItemKey(identifier: 5, position: NMGLatLng(lat: 37.368, lng: 127.110)): NSNull(),
ItemKey(identifier: 6, position: NMGLatLng(lat: 37.360, lng: 127.106)): NSNull(),
ItemKey(identifier: 7, position: NMGLatLng(lat: 37.363, lng: 127.111)): NSNull(),
]
self.clusterer?.addAll(keyTagMap)
self.clusterer?.mapView = self.view.mapView
}
이렇게 메서드 밖으로 선언하여 사용하였더니 클러스터링이 정상적으로 동작하는 것을 확인할 수 있었습니다.
전체 코드
class Coordinator: NSObject, NMFMapViewOptionDelegate {
static let shared = Coordinator()
var mapType: NMFMapType = .basic
var mapDetail: [String:Bool] = [NMF_LAYER_GROUP_BICYCLE:false,
NMF_LAYER_GROUP_TRAFFIC:false,
NMF_LAYER_GROUP_TRANSIT:false,
NMF_LAYER_GROUP_BUILDING:false,
NMF_LAYER_GROUP_MOUNTAIN:false,
NMF_LAYER_GROUP_CADASTRAL:false]
let view = NMFNaverMapView(frame: .infinite)
class ItemKey: NSObject, NMCClusteringKey {
let identifier: Int
let position: NMGLatLng
init(identifier: Int, position: NMGLatLng) {
self.identifier = identifier
self.position = position
}
static func markerKey(withIdentifier identifier: Int, position: NMGLatLng) -> ItemKey {
return ItemKey(identifier: identifier, position: position)
}
override func isEqual(_ o: Any?) -> Bool {
guard let o = o as? ItemKey else {
return false
}
if self === o {
return true
}
return o.identifier == self.identifier
}
override var hash: Int {
return self.identifier
}
func copy(with zone: NSZone? = nil) -> Any {
return ItemKey(identifier: self.identifier, position: self.position)
}
}
class ItemData: NSObject {
let name: String
let gu: String
init(name: String, gu: String) {
self.name = name
self.gu = gu
}
}
class MarkerManager: NMCDefaultMarkerManager {
override func createMarker() -> NMFMarker {
let marker = super.createMarker()
marker.subCaptionTextSize = 10
marker.subCaptionColor = UIColor.white
marker.subCaptionHaloColor = UIColor.clear
return marker
}
}
var clusterer: NMCClusterer<ItemKey>?
override init() {
super.init()
makeClusterer()
}
func setMarker(lat : Double, lng:Double, title: String) {
let marker = NMFMarker()
marker.iconImage = NMF_MARKER_IMAGE_PINK
marker.position = NMGLatLng(lat: lat, lng: lng)
marker.mapView = view.mapView
let infoWindow = NMFInfoWindow()
let dataSource = NMFInfoWindowDefaultTextSource.data()
dataSource.title = "\(lat.description), \(lng.description)"
infoWindow.dataSource = dataSource
infoWindow.open(with: marker)
}
func makeClusterer() {
let builder = NMCBuilder<ItemKey>()
self.clusterer = builder.build()
let keyTagMap = [
ItemKey(identifier: 1, position: NMGLatLng(lat: 37.372, lng: 127.113)): NSNull(),
ItemKey(identifier: 2, position: NMGLatLng(lat: 37.366, lng: 127.106)): NSNull(),
ItemKey(identifier: 3, position: NMGLatLng(lat: 37.365, lng: 127.157)): NSNull(),
ItemKey(identifier: 4, position: NMGLatLng(lat: 37.361, lng: 127.105)): NSNull(),
ItemKey(identifier: 5, position: NMGLatLng(lat: 37.368, lng: 127.110)): NSNull(),
ItemKey(identifier: 6, position: NMGLatLng(lat: 37.360, lng: 127.106)): NSNull(),
ItemKey(identifier: 7, position: NMGLatLng(lat: 37.363, lng: 127.111)): NSNull(),
]
self.clusterer?.addAll(keyTagMap)
self.clusterer?.mapView = self.view.mapView
}
}
'SwiftUI' 카테고리의 다른 글
카메라를 이용하여 QR code 스캔하기 (0) | 2024.05.07 |
---|---|
네이버 지도 (마커 눌렀을 때 데이터 정보 불러오기 with 클러스터링) (0) | 2024.05.04 |
네이버 지도 시작하기 (0) | 2024.05.01 |
커스텀 원형 테두리 만들기 (1) | 2024.05.01 |
Cocoapods (0) | 2024.05.01 |