Naver Map기능
마커 클러스터링
줌 레벨에 따라 근접 마커를 자동으로 클러스터링하는 기능
마커 클러스터링
대량의 마커가 화면에 표시될 때 성능 저하와 시인성 문제를 해결하기 위한 클러스터링 기능입니다. 카메라 줌 레벨에 따라 근접한 마커들을 하나의 클러스터 마커로 묶어 표시합니다.
클러스터링은 NaverMapMarkerOverlay를 개별 렌더링하는 방식이 아닌, NaverMapView의 clusters prop을 통해 설정합니다.
기본 사용법
import { NaverMapView, type ClusterMarkerProp } from '@boostbrothers/react-native-naver-map';const markers: ClusterMarkerProp[] = [{ identifier: 'hospital-1', latitude: 37.5000, longitude: 126.9000 },{ identifier: 'hospital-2', latitude: 37.5010, longitude: 126.9010 },{ identifier: 'hospital-3', latitude: 37.5020, longitude: 126.9020 },{ identifier: 'hospital-4', latitude: 37.5500, longitude: 126.9500 },];<NaverMapViewstyle={{ flex: 1 }}initialCamera={{ latitude: 37.525, longitude: 126.925, zoom: 12 }}clusters={[{markers,screenDistance: 200,minZoom: 0,maxZoom: 21,animate: true,width: 40,height: 40,},]}onTapClusterLeaf={({ markerIdentifier }) => {console.log('클러스터 리프 마커 탭:', markerIdentifier);}}/>
clusters 설정
clusters prop은 클러스터 그룹 배열입니다. 각 그룹은 독립적인 클러스터링 설정을 가질 수 있습니다.
| 속성 | 타입 | 기본값 | 설명 |
|---|---|---|---|
markers | ClusterMarkerProp[] | - | 클러스터링할 마커 배열 (필수) |
screenDistance | number | 200 | 화면상 클러스터링 기준 거리 (dp/pt) |
minZoom | number | 0 | 클러스터링할 최소 줌 레벨 |
maxZoom | number | 21 | 클러스터링할 최대 줌 레벨 |
animate | boolean | true | 클러스터 펼침/합침 애니메이션 |
width | number | - | 클러스터 마커 너비 |
height | number | - | 클러스터 마커 높이 |
ClusterMarkerProp
클러스터에 포함될 마커 속성입니다.
interface ClusterMarkerProp {identifier: string; // 고유 식별자 (필수)latitude: number; // 위도 (필수)longitude: number; // 경도 (필수)image?: MapImageProp; // 마커 이미지 (기본: { symbol: 'green' })width?: number; // 마커 너비height?: number; // 마커 높이}
identifier는 클러스터 내에서 각 마커를 구분하는 고유 식별자입니다. onTapClusterLeaf 이벤트에서 어떤 마커가 탭되었는지 식별하는 데 사용됩니다.
클러스터 이벤트
클러스터로 묶인 마커 중 개별 마커(리프)를 탭하면 onTapClusterLeaf가 호출됩니다.
<NaverMapViewclusters={[{ markers, screenDistance: 200 }]}onTapClusterLeaf={({ markerIdentifier }) => {// markerIdentifier로 어떤 마커가 탭되었는지 식별const tappedMarker = markers.find(m => m.identifier === markerIdentifier);if (tappedMarker) {console.log('탭된 마커:', tappedMarker);}}}/>
줌 레벨별 클러스터링 동작
minZoom과 maxZoom으로 클러스터링이 활성화되는 줌 범위를 조절합니다.
clusters={[{markers,minZoom: 4, // 줌 4 미만에서는 클러스터링 안 함maxZoom: 16, // 줌 17 이상에서는 모든 마커가 개별 표시screenDistance: 150,},]}
- 카메라 줌 < minZoom: 해당 줌의 클러스터가 더 이상 합쳐지지 않고 그대로 유지
- 카메라 줌 > maxZoom: 모든 마커가 개별 마커로 표시됨
여러 클러스터 그룹
서로 다른 카테고리의 마커를 별도 클러스터 그룹으로 관리할 수 있습니다.
const hospitalMarkers: ClusterMarkerProp[] = [{ identifier: 'h-1', latitude: 37.50, longitude: 126.90, image: { symbol: 'red' } },{ identifier: 'h-2', latitude: 37.51, longitude: 126.91, image: { symbol: 'red' } },];const pharmacyMarkers: ClusterMarkerProp[] = [{ identifier: 'p-1', latitude: 37.50, longitude: 126.95, image: { symbol: 'green' } },{ identifier: 'p-2', latitude: 37.51, longitude: 126.96, image: { symbol: 'green' } },];<NaverMapViewstyle={{ flex: 1 }}initialCamera={{ latitude: 37.51, longitude: 126.93, zoom: 12 }}clusters={[{markers: hospitalMarkers,screenDistance: 200,width: 40,height: 40,},{markers: pharmacyMarkers,screenDistance: 200,width: 40,height: 40,},]}onTapClusterLeaf={({ markerIdentifier }) => {if (markerIdentifier.startsWith('h-')) {console.log('병원 마커 탭');} else if (markerIdentifier.startsWith('p-')) {console.log('약국 마커 탭');}}}/>
성능 고려사항
- 클러스터링은 수천 개의 마커도 효율적으로 처리할 수 있습니다.
screenDistance를 너무 작게 설정하면 클러스터링 효과가 줄어들고 성능이 떨어질 수 있습니다.animate: false로 설정하면 클러스터 애니메이션을 비활성화하여 성능을 향상시킬 수 있습니다.- 마커 이미지로 커스텀 React 뷰 대신
symbol또는require이미지를 사용하면 성능이 훨씬 좋습니다.
자세한 성능 최적화는 성능 최적화 문서를 참고하세요.