마커
마커는 지도상의 한 지점을 나타내기 위한 오버레이로, 지도에서 가장 널리 사용되는 요소입니다. 마커를 사용하면 특정 지도상 좌표에 아이콘과 캡션을 표시할 수 있습니다. 마커의 아이콘과 캡션은 지도와 함께 움직이지만 지도를 확대 또는 축소하더라도 일정한 형태를 유지합니다. 또한 마커는 클릭 이벤트를 받을 수 있으며 이벤트를 소비하거나 지도로 전파할 수도 있습니다.
추가 및 삭제
Marker
는 일반적인 자바 객체처럼 생성할 수 있습니다. 객체를 생성하고, position
속성에 좌표를 지정한 후, map
속성에 지도 객체를 지정하면 마커가 나타납니다. 단, map
을 지정하기 전에는 반드시 position
을 지정해야 하며, 그렇지 않으면 예외가 발생합니다.
다음은 마커 객체를 생성하고 지도에 추가하는 예제입니다.
Marker marker = new Marker();
marker.setPosition(new LatLng(37.5670135, 126.9783740));
marker.setMap(naverMap);
Java
Marker marker = new Marker();
marker.setPosition(new LatLng(37.5670135, 126.9783740));
marker.setMap(naverMap);
Kotlin
val marker = Marker()
marker.position = LatLng(37.5670135, 126.9783740)
marker.map = naverMap
map
에 null
을 지정하면 지도에서 마커가 사라집니다.
다음은 마커를 지도에서 제거하는 예제입니다.
좌표
position
속성을 사용해 좌표를 지정할 수 있습니다. 좌표는 필수적인 속성으로, 좌표를 지정하지 않은 마커를 지도에 추가하면 예외가 발생합니다. 이미 지도에 추가된 마커의 좌표를 변경하면 마커가 해당하는 좌표로 이동합니다.
다음은 마커의 좌표를 지정하는 예제입니다.
marker.setPosition(new LatLng(37.5670135, 126.9783740));
Java
marker.setPosition(new LatLng(37.5670135, 126.9783740));
Kotlin
marker.position = LatLng(37.5670135, 126.9783740)
아이콘
아이콘은 마커에서 시각적으로 가장 중요한 요소입니다. 지도상의 한 지점을 나타내는 핀의 역할을 하므로 생략할 수 없습니다. 이미지, 크기 등을 지정할 수 있습니다.
이미지
icon
속성을 사용해 아이콘을 지정할 수 있습니다. 아이콘을 지정하려면 먼저 OverlayImage
객체를 만들어야 합니다. OverlayImage
는 오버레이에서 사용할 수 있는 비트맵 이미지를 나타내는 클래스로, 팩토리 메서드를 이용해 리소스, 에셋, 비트맵, 뷰 등으로부터 인스턴스를 생성할 수 있습니다. 마커 아이콘으로 사용할 이미지는 사용자 단말의 DPI(Dots Per Inch)별로 대응해야 하므로 드로어블 리소스를 사용해 만드는 것이 좋습니다.
다음은 마커에 아이콘을 지정하는 예제입니다.
marker.setIcon(OverlayImage.fromResource(R.drawable.marker_icon));
Java
marker.setIcon(OverlayImage.fromResource(R.drawable.marker_icon));
Kotlin
marker.icon = OverlayImage.fromResource(R.drawable.marker_icon)
네이버 지도 SDK는 다양한 마커 아이콘을 빌트인으로 제공합니다. 제공되는 아이콘의 목록은 MarkerIcons
를 참조하십시오.
덧입힐 색상
iconTintColor
속성을 지정하면 아이콘 이미지에 색상을 덧입힐 수 있습니다. 색상을 덧입히면 덧입힐 색상이 아이콘 이미지의 색상과 가산 혼합됩니다. 단, 덧입힐 색상의 알파는 무시되고 아이콘 이미지의 알파만이 사용됩니다.
두 색상이 혼합되므로 회색조인 이미지를 아이콘으로 사용해야 선명한 색상을 낼 수 있습니다. 네이버 지도 SDK는 색상을 덧입히기에 적합한 이미지인 MarkerIcons.BLACK
를 빌트인으로 제공합니다.
다음은 마커의 아이콘을 MarkerIcons.BLACK
으로 지정하고 빨간색을 덧입히는 예제입니다.
marker.setIcon(MarkerIcons.BLACK);
marker.setIconTintColor(Color.RED);
Java
marker.setIcon(MarkerIcons.BLACK);
marker.setIconTintColor(Color.RED);
Kotlin
marker.icon = MarkerIcons.BLACK
marker.iconTintColor = Color.RED
크기
width
와 height
속성을 지정해 아이콘의 크기를 변경할 수 있습니다.
다음은 마커의 아이콘 너비를 50픽셀, 높이를 80픽셀로 지정하는 예제입니다.
marker.setWidth(50);
marker.setHeight(80);
Java
marker.setWidth(50);
marker.setHeight(80);
Kotlin
marker.width = 50
marker.height = 80
width
또는 height
를 기본값인 SIZE_AUTO
로 지정할 경우 너비 또는 높이가 이미지의 크기에 맞춰집니다. 안드로이드의 WRAP_CONTENT
와 유사합니다.
다음은 마커의 아이콘 크기를 자동으로 지정하는 예제입니다.
marker.setWidth(Marker.SIZE_AUTO);
marker.setHeight(Marker.SIZE_AUTO);
Java
marker.setWidth(Marker.SIZE_AUTO);
marker.setHeight(Marker.SIZE_AUTO);
Kotlin
marker.width = Marker.SIZE_AUTO
marker.height = Marker.SIZE_AUTO
앵커
anchor
속성을 지정하면 이미지가 가리키는 지점과 마커가 위치한 지점을 일치시킬 수 있습니다. 앵커는 아이콘 이미지에서 기준이 되는 지점을 의미하는 값으로, 아이콘에서 앵커로 지정된 지점이 마커의 좌표에 위치하게 됩니다. 왼쪽 위가 (0, 0)
, 오른쪽 아래가 (1, 1)
인 비율로 표현합니다.
앵커 속성은 기본 마커 이미지를 사용하지 않을 때 유용합니다. 예를 들어 다음 그림과 같이 오른쪽 아래에 꼬리가 달려 있는 이미지를 마커의 아이콘으로 지정하면, 이미지에서 가리키는 지점은 오른쪽 아래이지만 마커는 중앙 아래를 기준으로 지도에 붙어 있으므로 이미지와 마커의 좌표 간에 이격이 발생합니다.
이 경우 앵커를 오른쪽 아래를 의미하는 (1, 1)
로 지정하면 이미지와 마커의 좌표 간 이격을 해소할 수 있습니다.
다음은 마커의 앵커를 아이콘의 오른쪽 아래로 지정하는 예제입니다.
marker.setAnchor(new PointF(1, 1));
Java
marker.setAnchor(new PointF(1, 1));
Kotlin
marker.anchor = PointF(1f, 1f)
회전
angle
속성을 지정하면 아이콘을 회전시킬 수 있습니다. 각도는 화면의 위쪽 방향을 기준으로 시계 방향으로 커집니다. 즉, 0도일 경우 화면의 위쪽, 90도일 경우 오른쪽, 180도일 경우 아래쪽을 향하게 됩니다.
다음은 마커의 아이콘을 시계 방향으로 90도 회전하는 예제입니다.
다음 그림은 위 코드를 실행해 아이콘을 시계 방향으로 90도 회전한 결과입니다.
이미지는 앵커로 지정한 지점을 중심으로 회전합니다. 따라서 이미지를 회전하더라도 앵커를 변경할 필요가 없습니다.
다음은 마커의 아이콘을 오른쪽 아래를 기준으로 시계 방향으로 90도 회전하는 예제입니다.
marker.setAnchor(new PointF(1, 1));
marker.setAngle(90);
Java
marker.setAnchor(new PointF(1, 1));
marker.setAngle(90);
Kotlin
marker.anchor = PointF(1f, 1f)
marker.angle = 90f
플랫
마커는 기본적으로 다음 그림처럼 사용자가 지도를 기울이거나 회전하더라도 모양을 유지합니다.
그러나 isFlat
속성을 true
로 지정하면 아이콘이 지도에 눕게 됩니다. 누운 아이콘은 지도가 회전하거나 기울어지면 함께 회전하고 기울어집니다.
다음은 마커의 아이콘을 눕히는 예제입니다.
누운 아이콘에 angle
속성을 지정하면 아이콘이 지도를 기준으로 회전합니다. 0도일 경우 북쪽, 90도일 경우 동쪽, 180도일 경우 남쪽을 향하게 됩니다.
다음은 마커의 아이콘을 눕히고 북쪽을 기준으로 시계방향으로 90도 회전하는 예제입니다.
marker.setAngle(90);
marker.setFlat(true);
Java
marker.setAngle(90);
marker.setFlat(true);
Kotlin
marker.angle = 90f
marker.isFlat = true
원근 효과
마커에는 기본적으로 원근 효과가 적용되지 않으므로, 다음 그림처럼 지도를 기울이더라도 멀리 있는 마커와 가까이 있는 마커의 크기는 동일하게 나타납니다.
그러나 isIconPerspectiveEnabled
속성을 true
로 지정하면 아이콘에 원근 효과가 부여됩니다. 원근 효과가 부여된 아이콘은 화면의 아래쪽에 가까워질수록 커지고 멀어질수록 작아집니다.
다음은 마커의 아이콘에 원근 효과를 부여하는 예제입니다.
marker.setIconPerspectiveEnabled(true);
Java
marker.setIconPerspectiveEnabled(true);
Kotlin
marker.isIconPerspectiveEnabled = true
캡션
캡션은 마커 이미지와 함께 노출되는 텍스트입니다. 마커가 가리키는 지점에 대한 정보를 텍스트로 표현하고자 할 때 사용할 수 있습니다.
텍스트
captionText
속성을 이용해 캡션으로 표시할 텍스트를 지정할 수 있습니다. 빈 문자열이나 null
을 지정하면 캡션이 나타나지 않습니다.
다음은 마커의 캡션 텍스트를 "Hello"
로 지정하는 예제입니다.
marker.setCaptionText("Hello");
Java
marker.setCaptionText("Hello");
Kotlin
marker.captionText = "Hello"
텍스트 줄바꿈
captionRequestedWidth
속성을 이용하면 캡션 텍스트의 너비를 제한할 수 있습니다. 캡션의 한 줄이 지정된 너비보다 길어지면 적당한 위치에서 자동으로 줄바꿈이 일어납니다. 단, 공백 없이 모든 텍스트를 붙여쓴 경우 줄바꿈이 일어나지 않을 수도 있습니다. 0
을 지정하면 자동 줄바꿈이 일어나지 않습니다.
다음은 마커의 캡션 너비를 200픽셀로 제한하는 예제입니다.
marker.setCaptionText("아주아주아주아주아주 아주아주아주아주 긴 캡션");
marker.setCaptionRequestedWidth(200);
Java
marker.setCaptionText("아주아주아주아주아주 아주아주아주아주 긴 캡션");
marker.setCaptionRequestedWidth(200);
Kotlin
marker.captionText = "아주아주아주아주아주 아주아주아주아주 긴 캡션"
marker.captionRequestedWidth = 200
방향
캡션은 기본적으로 아이콘의 아래쪽에 배치되나, captionAligns
속성을 이용해 배치되는 방향을 변경할 수 있습니다. 위, 아래, 왼쪽, 오른쪽, 각 대각선, 중앙 등 Align
열거형에 정의된 9곳에 배치할 수 있습니다.
다음은 마커의 캡션을 아이콘의 위에 배치하는 예제입니다.
marker.setCaptionAligns(Align.Top);
Java
marker.setCaptionAligns(Align.Top);
Kotlin
marker.setCaptionAligns(Align.Top)
또한 captionOffset
속성을 지정하면 아이콘과 캡션 간의 거리를 지정할 수 있습니다. 단, captionAlign
이 CENTER
인 경우 captionOffset
은 무시됩니다.
다음은 마커의 아이콘과 캡션 사이에 30픽셀의 간격을 지정하는 예제입니다.
marker.setCaptionOffset(30);
Java
marker.setCaptionOffset(30);
Kotlin
marker.captionOffset = 30
색상
captionColor
속성으로 캡션의 색상을, captionHaloColor
속성으로 캡션의 외곽 색상을 지정할 수 있습니다.
다음은 마커의 캡션을 파란색, 외곽선을 연한 녹색으로 지정하는 예제입니다.
marker.setCaptionColor(Color.BLUE);
marker.setCaptionHaloColor(Color.rgb(200, 255, 200));
Java
marker.setCaptionColor(Color.BLUE);
marker.setCaptionHaloColor(Color.rgb(200, 255, 200));
Kotlin
marker.captionColor = Color.BLUE
marker.captionHaloColor = Color.rgb(200, 255, 200)
크기
captionTextSize
속성을 이용하면 캡션의 텍스트 크기를 지정할 수 있습니다.
다음은 마커의 캡션 텍스트 크기를 16dp로 지정하는 예제입니다.
marker.setCaptionTextSize(16);
Java
marker.setCaptionTextSize(16);
Kotlin
marker.captionTextSize = 16f
최소 및 최대 줌 레벨
captionMinZoom
및 captionMaxZoom
속성을 이용하면 특정 줌 레벨에서만 캡션이 나타나도록 지정할 수 있습니다. 카메라의 줌 레벨이 captionMinZoom
과 captionMaxZoom
범위를 벗어나면 캡션이 숨겨지고 아이콘만 나타납니다.
다음은 캡션이 12~16레벨 사이에서만 나타나도록 지정하는 예제입니다.
marker.setCaptionMinZoom(12);
marker.setCaptionMaxZoom(16);
Java
marker.setCaptionMinZoom(12);
marker.setCaptionMaxZoom(16);
Kotlin
marker.captionMinZoom = 12.0
marker.captionMaxZoom = 16.0
보조 캡션
보조 캡션은 주 캡션과 함께 표현할 수 있는 또 다른 캡션입니다. 주 캡션과 별개로 텍스트, 색상, 크기 등을 지정할 수 있어 보조적인 정보를 나타내는 데 유용하게 사용할 수 있습니다. 단, 위치와 오프셋은 별도로 지정할 수 없고 무조건 주 캡션의 아래쪽에 위치하게 됩니다.
보조 캡션의 속성명은 주 캡션과 대부분 동일하나 subCaptionText
, subCaptionColor
, subCaptionHaloColor
, subCaptionTextSize
, subCaptionRequestedWidth
, subCaptionMinZoom
, subCaptionMaxZoom
과 같이 sub
로 시작합니다.
다음은 마커에 보조 캡션을 지정하는 예제입니다.
marker.setSubCaptionText("보조 캡션\n(sub caption)");
marker.setSubCaptionColor(Color.BLUE);
marker.setSubCaptionHaloColor(Color.rgb(200, 255, 200));
marker.setSubCaptionTextSize(10);
Java
marker.setSubCaptionText("보조 캡션\n(sub caption)");
marker.setSubCaptionColor(Color.BLUE);
marker.setSubCaptionHaloColor(Color.rgb(200, 255, 200));
marker.setSubCaptionTextSize(10);
Kotlin
marker.subCaptionText = "보조 캡션\n(sub caption)"
marker.subCaptionColor = Color.BLUE
marker.subCaptionHaloColor = Color.rgb(200, 255, 200)
marker.subCaptionTextSize = 10f
불투명도
alpha
속성을 이용하면 마커의 불투명도를 지정할 수 있습니다. 불투명도는 아이콘과 캡션 모두에 적용됩니다. 값의 범위는 0
~1
이며, 0
일 경우 완전히 투명, 1
일 경우 완전히 불투명한 상태가 됩니다. 불투명도가 0
일 경우 visible
이 false
인 경우와 달리 여전히 화면에 나타나 있는 것으로 간주됩니다. 따라서 겹침, 이벤트 처리의 대상이 됩니다.
다음은 마커를 반투명으로 지정하는 예제입니다.
겹침
마커는 지도의 한 지점을 나타내는 오버레이이므로 지도를 축소하면 여러 마커가 겹쳐지게 됩니다. 여러 마커가 겹쳐지면 마커가 가리키는 지점을 알아보기 어려워집니다. 이때 특정 마커를 우선시하도록 지정하거나 캡션 또는 지도 심벌을 숨기면 정보의 집중도를 높이고 복잡도를 완화할 수 있습니다.
Z 인덱스
여러 마커가 겹쳐질 경우 기본적으로 화면의 아래쪽에 가까이 있는 마커가 멀리 있는 마커를 덮습니다. 따라서 다음 그림처럼 카메라가 회전할 때마다 상위에 노출되는 마커가 달라집니다.
globalZIndex
및 zIndex
속성을 이용하면 어떤 마커가 상위에 노출되어야 하는지를 의미하는 Z 인덱스를 지정할 수 있습니다. 여러 마커가 겹치면 Z 인덱스가 큰 마커가 작은 마커를 덮습니다.
다음은 세 마커의 노출 순서를 노란색 -> 녹색 -> 파란색 순으로 지정하는 예제입니다.
yellowMarker.setZIndex(100);
greenMarker.setZIndex(0);
blueMarker.setZIndex(-10);
Java
yellowMarker.setZIndex(100);
greenMarker.setZIndex(0);
blueMarker.setZIndex(-10);
Kotlin
yellowMarker.zIndex = 100
greenMarker.zIndex = 0
blueMarker.zIndex = -10
노란색 마커가 화면의 아래쪽으로부터 멀리 있지만 Z 인덱스가 크므로 상위에 노출됩니다.
마커와 지도 심벌 간 겹침
다음 그림처럼 마커와 지도상의 심벌이 겹칠 경우 화면이 복잡해져 시인성이 떨어질 수 있습니다.
이때 isHideCollidedSymbols
속성을 true
로 지정하면 마커가 지도 심벌과 겹칠 경우 겹치는 심벌이 숨겨집니다.
다음은 마커와 겹치는 지도 심벌을 자동으로 숨기도록 지정하는 예제입니다.
marker.setHideCollidedSymbols(true);
Java
marker.setHideCollidedSymbols(true);
Kotlin
marker.isHideCollidedSymbols = true
마커와 다른 마커 간 겹침
마커는 다음 그림처럼 지도상의 심벌뿐만 아니라 다른 마커와도 겹칠 수 있으며, 이 또한 시인성 저하의 원인이 됩니다.
이때 isHideCollidedMarkers
속성을 true
로 지정하면 마커가 다른 마커와 겹칠 경우 겹치는 마커가 숨겨집니다. 즉, 다른 마커와 겹치지 않는 마커만이 노출됩니다. 두 마커가 서로 겹칠 경우 Z 인덱스가 큰 마커가 우선합니다.
다음은 마커와 겹치는 다른 마커를 자동으로 숨기도록 지정하는 예제입니다.
marker.setHideCollidedMarkers(true);
Java
marker.setHideCollidedMarkers(true);
Kotlin
marker.isHideCollidedMarkers = true
또한 isHideCollidedCaptions
속성을 true
로 지정하면 마커와 다른 마커가 겹칠 경우 겹치는 마커의 아이콘은 유지되고 캡션만이 숨겨집니다. 겹치는 마커의 captionAligns
에 둘 이상의 방향을 지정했다면 겹치지 않는 첫 번째 방향에 캡션이 나타나며, 어느 방향으로 위치시켜도 겹칠 경우에만 캡션이 숨겨집니다. 즉, 다른 마커와 겹치지 않는 캡션만이 노출됩니다. 단, hideCollidedMarkers
가 true
로 지정된 경우 hideCollidedCaptions
는 무시됩니다.
다음은 마커와 겹치는 다른 마커의 캡션을 자동으로 숨기도록 지정하는 예제입니다.
marker.setHideCollidedCaptions(true);
Java
marker.setHideCollidedCaptions(true);
Kotlin
marker.isHideCollidedCaptions = true
겹침을 무시하고 무조건 표시
isForceShowIcon
속성을 true
로 지정하면 마커가 isHideCollidedMarkers
가 true
인 다른 마커와 겹치더라도 아이콘이 무조건 표시됩니다. isForceShowIcon
속성을 활용하면 겹치는 마커를 숨기되 중요한 마커는 무조건 표시할 수 있습니다. 중요한 마커는 zIndex
를 높이고 isHideCollidedMarkers
와 isForceShowIcon
를 true
로 지정하고, 덜 중요한 마커는 zIndex
를 낮추고 isHideCollidedMarkers
를 true
로 지정하면 됩니다.
다음은 겹치는 마커는 숨기되 중요한 마커는 무조건 표시하는 예제입니다.
List<Marker> importantMarkers = ... // 중요한 마커들
List<Marker> normalMarkers = ... // 덜 중요한 마커들
for (Marker marker : importantMarkers) {
marker.setZIndex(1);
marker.setHideCollidedMarkers(true);
marker.setForceShowIcon(true);
}
for (Marker marker : normalMarkers) {
marker.setZIndex(0);
marker.setHideCollidedMarkers(true);
marker.setForceShowIcon(false);
}
Java
List<Marker> importantMarkers = ... // 중요한 마커들
List<Marker> normalMarkers = ... // 덜 중요한 마커들
for (Marker marker : importantMarkers) {
marker.setZIndex(1);
marker.setHideCollidedMarkers(true);
marker.setForceShowIcon(true);
}
for (Marker marker : normalMarkers) {
marker.setZIndex(0);
marker.setHideCollidedMarkers(true);
marker.setForceShowIcon(false);
}
Kotlin
val importantMarkers: List<Marker> = ... // 중요한 마커들
val normalMarkers: List<Marker> = ... // 덜 중요한 마커들
importantMarkers.forEach { marker ->
marker.zIndex = 1
marker.isHideCollidedMarkers = true
marker.isForceShowIcon = true
}
normalMarkers.forEach { marker ->
marker.zIndex = 0
marker.isHideCollidedMarkers = true
marker.isForceShowIcon = false
}