마커는 지도에서 단일 위치를 나타냅니다. 마커의 기본 색상을 변경하거나 마커 아이콘을 맞춤 이미지로 교체하여 맞춤설정할 수 있습니다. 정보 창에서 마커에 대한 추가 정보를 제공할 수 있습니다.
코드 샘플
GitHub의 ApiDemos 저장소에는 마커의 다양한 특징을 보여주는 샘플이 있습니다.
Kotlin
- MapWithMarker: 마커가 있는 간단한 지도. marker-kt가 있는 지도 추가하기 튜토리얼을 참고하세요.
- MarkerDemoActivity: 지도에서 옵션과 리스너를 포함하여 마커 사용하기
Java
- MapWithMarker: 마커가 있는 간단한 지도. 마커가 포함된 지도 추가 튜토리얼을 참고하세요.
- MarkerDemoActivity: 지도에서 옵션과 리스너를 포함하여 마커 사용하기
소개
마커는 지도에서 위치를 나타냅니다. 기본 마커는 Google 지도 디자인에
공통으로 사용되는 표준 아이콘을 사용합니다. API를 통해 아이콘의 색상,
이미지 또는 앵커 포인트를 변경할 수 있습니다. 마커는 Marker
유형의 객체이며, GoogleMap.addMarker(markerOptions)
메서드를 통해 지도에
추가됩니다.
마커는 상호작용이 가능하도록 만들어져 있습니다. 기본적으로 click
이벤트를
수신하며 보통 정보 창을 표시하기 위해 이벤트 리스너와 함께
사용됩니다. 마커의 draggable
속성을 true
로
설정하면 사용자가 마커의 위치를 변경할 수 있습니다. 마커 이동 기능을
활성화하려면 마커를 길게 누르세요.
기본적으로 사용자가 마커를 탭하면 지도의 오른쪽 하단에 지도 툴바가 표시되어 Google 지도 모바일 앱에 빠르게 액세스할 수 있습니다. 이 툴바는 사용 중지할 수 있습니다. 자세한 내용은 컨트롤 가이드를 참고하세요.
마커 사용하기
이 지도 라이브 에피소드에서는 Android용 Maps SDK를 사용하여 지도에 마커를 추가하는 기본 방법을 설명합니다.
마커 추가
다음 예에서는 지도에 마커를 추가하는 방법을 보여줍니다. -33.852,151.211
좌표(오스트레일리아 시드니)에 마커가 생성되고, 마커를 클릭하면 정보 창에 'Marker in Sydney' 문자열이 표시됩니다.
Kotlin
override fun onMapReady(googleMap: GoogleMap) { // Add a marker in Sydney, Australia, // and move the map's camera to the same location. val sydney = LatLng(-33.852, 151.211) googleMap.addMarker( MarkerOptions() .position(sydney) .title("Marker in Sydney") ) googleMap.moveCamera(CameraUpdateFactory.newLatLng(sydney)) }
Java
@Override public void onMapReady(GoogleMap googleMap) { // Add a marker in Sydney, Australia, // and move the map's camera to the same location. LatLng sydney = new LatLng(-33.852, 151.211); googleMap.addMarker(new MarkerOptions() .position(sydney) .title("Marker in Sydney")); googleMap.moveCamera(CameraUpdateFactory.newLatLng(sydney)); }
마커에 대한 추가 정보 표시
일반적인 요구사항은 사용자가 지도에서 마커를 탭하면 장소나 위치에 대한 추가 정보를 표시하는 것입니다. 정보 창 가이드를 참고하세요.
데이터를 마커와 연결
Marker.setTag()
를 사용하여 임의의 데이터 객체를 마커와 함께 저장하고 Marker.getTag()
를
사용하여 데이터 객체를 가져올 수 있습니다. 아래 샘플은 태그를 사용하여
마커가 클릭된 횟수를 계산하는 방법을 보여줍니다.
Kotlin
/** * A demo class that stores and retrieves data objects with each marker. */ class MarkerDemoActivity : AppCompatActivity(), OnMarkerClickListener, OnMapReadyCallback { private val PERTH = LatLng(-31.952854, 115.857342) private val SYDNEY = LatLng(-33.87365, 151.20689) private val BRISBANE = LatLng(-27.47093, 153.0235) private var markerPerth: Marker? = null private var markerSydney: Marker? = null private var markerBrisbane: Marker? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_markers) val mapFragment = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment? mapFragment!!.getMapAsync(this) } /** Called when the map is ready. */ override fun onMapReady(map: GoogleMap) { // Add some markers to the map, and add a data object to each marker. markerPerth = map.addMarker( MarkerOptions() .position(PERTH) .title("Perth") ) markerPerth?.tag = 0 markerSydney = map.addMarker( MarkerOptions() .position(SYDNEY) .title("Sydney") ) markerSydney?.tag = 0 markerBrisbane = map.addMarker( MarkerOptions() .position(BRISBANE) .title("Brisbane") ) markerBrisbane?.tag = 0 // Set a listener for marker click. map.setOnMarkerClickListener(this) } /** Called when the user clicks a marker. */ override fun onMarkerClick(marker: Marker): Boolean { // Retrieve the data from the marker. val clickCount = marker.tag as? Int // Check if a click count was set, then display the click count. clickCount?.let { val newClickCount = it + 1 marker.tag = newClickCount Toast.makeText( this, "${marker.title} has been clicked $newClickCount times.", Toast.LENGTH_SHORT ).show() } // Return false to indicate that we have not consumed the event and that we wish // for the default behavior to occur (which is for the camera to move such that the // marker is centered and for the marker's info window to open, if it has one). return false } }
Java
/** * A demo class that stores and retrieves data objects with each marker. */ public class MarkerDemoActivity extends AppCompatActivity implements GoogleMap.OnMarkerClickListener, OnMapReadyCallback { private final LatLng PERTH = new LatLng(-31.952854, 115.857342); private final LatLng SYDNEY = new LatLng(-33.87365, 151.20689); private final LatLng BRISBANE = new LatLng(-27.47093, 153.0235); private Marker markerPerth; private Marker markerSydney; private Marker markerBrisbane; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_markers); SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map); mapFragment.getMapAsync(this); } /** Called when the map is ready. */ @Override public void onMapReady(GoogleMap map) { // Add some markers to the map, and add a data object to each marker. markerPerth = map.addMarker(new MarkerOptions() .position(PERTH) .title("Perth")); markerPerth.setTag(0); markerSydney = map.addMarker(new MarkerOptions() .position(SYDNEY) .title("Sydney")); markerSydney.setTag(0); markerBrisbane = map.addMarker(new MarkerOptions() .position(BRISBANE) .title("Brisbane")); markerBrisbane.setTag(0); // Set a listener for marker click. map.setOnMarkerClickListener(this); } /** Called when the user clicks a marker. */ @Override public boolean onMarkerClick(final Marker marker) { // Retrieve the data from the marker. Integer clickCount = (Integer) marker.getTag(); // Check if a click count was set, then display the click count. if (clickCount != null) { clickCount = clickCount + 1; marker.setTag(clickCount); Toast.makeText(this, marker.getTitle() + " has been clicked " + clickCount + " times.", Toast.LENGTH_SHORT).show(); } // Return false to indicate that we have not consumed the event and that we wish // for the default behavior to occur (which is for the camera to move such that the // marker is centered and for the marker's info window to open, if it has one). return false; } }
다음은 마커와 함께 데이터를 저장하고 가져오는 것이 유용한 경우입니다.
- 앱에서 여러 유형의 마커를 지원하고 있으며 사용자가 각 마커를 클릭할 때마다
다르게 처리하고자 하는 경우. 이 작업을 처리하려면
String
을 해당 유형을 나타내는 마커와 함께 저장하세요. - 고유한 레코드 식별자가 있는 시스템과 연결하고 여기서 마커가 해당 시스템의 특정 레코드를 나타내는 경우
- 마커 데이터가 마커의 Z-색인을 결정할 때 사용되는 우선순위를 나타낼 수 있는 경우
마커를 드래그할 수 있도록 설정
draggable
속성이 true
로 설정된 경우라면 마커가 지도에 추가된 후 마커의 위치를 변경할 수 있습니다. 드래그 기능을 사용 설정하려면 마커를
길게 누르세요. 화면에서 손가락을 떼면 마커가 그 위치에 남아 있게 됩니다.
기본적으로 마커는 드래그할 수 없습니다. 마커를 지도에 추가하기 전에 MarkerOptions.draggable(boolean)
을 사용하거나 마커가 지도에 추가된 후 Marker.setDraggable(boolean)
을 사용하여 마커를 드래그할 수 있도록 명시적으로 설정해야 합니다.
마커 드래그 이벤트에 설명된 대로 마커에 대한 드래그 이벤트를
수신 대기할 수 있습니다.
아래 스니펫에서는 오스트레일리아 퍼스에 드래그 가능한 마커를 추가합니다.
Kotlin
val perthLocation = LatLng(-31.90, 115.86) val perth = map.addMarker( MarkerOptions() .position(perthLocation) .draggable(true) )
Java
final LatLng perthLocation = new LatLng(-31.90, 115.86); Marker perth = map.addMarker( new MarkerOptions() .position(perthLocation) .draggable(true));
마커 맞춤설정
이 동영상은 마커를 사용하여 지도에서 위치를 시각화하는 방법을 보여줍니다.
마커를 사용하여 기본 아이콘 대신 표시할 맞춤 이미지를 정의할 수도 있습니다. 아이콘을 정의하는 작업에는 마커의 시각적 동작에 영향을 미치는 여러 속성을 설정하는 작업이 포함됩니다.
마커는 다음 속성을 통한 맞춤설정을 지원합니다.
- position(필수)
- 지도 상의
마커 위치에 대한
LatLng
값입니다.Marker
객체의 유일한 필수 속성입니다. - anchor
- 마커의 LatLng(위도/경도) 위치에 배치되는 이미지의 지점입니다. 기본적으로 이미지의 중앙 하단에 배치됩니다.
- alpha
- 마커의 불투명도를 설정합니다. 기본값은 1.0입니다.
- title
- 사용자가 마커를 탭할 때 정보 창에 표시되는 문자열입니다.
- snippet
- 제목 아래 표시되는 추가 텍스트입니다.
- icon
- 기본 마커 이미지 대신 표시되는 비트맵입니다.
- draggable
- 사용자가 마커를 이동할 수 있도록 허용하려면
true
로 설정합니다. 기본값은false
입니다. - visible
- 마커를 표시하지 않으려면
false
로 설정합니다. 기본값은true
입니다. - flat(빌보드 방향)
- 기본적으로 마커에는 빌보드 방향이 사용됩니다. 즉, 지도의 표면이 아닌 기기 화면을 기준으로 마커의 방향이 정해집니다. 지도를 회전하거나 기울이거나 확대/축소해도 마커의 방향은 변하지 않습니다. 마커의 방향을 지면에 평행하도록 설정할 수 있습니다. 평면 마커는 지도 회전 시 함께 회전하며 지도를 기울이면 시점이 바뀝니다. 빌보드 마커와 마찬가지로 지도를 확대하거나 축소할 때 평면 마커의 크기가 유지됩니다.
- rotation
- 마커의 방향으로, 시계 방향의 각도로 지정됩니다. 마커가 평면인 경우 기본 위치가 변경됩니다. 평면 마커의 기본 위치는 북쪽으로 정렬됩니다. 마커가 평면이 아닌 경우 기본 위치는 위를 가리키며 마커는 항상 카메라를 향하도록 회전합니다.
아래 스니펫에서는 기본 아이콘을 사용한 간단한 마커를 만듭니다.
Kotlin
val melbourneLocation = LatLng(-37.813, 144.962) val melbourne = map.addMarker( MarkerOptions() .position(melbourneLocation) )
Java
final LatLng melbourneLocation = new LatLng(-37.813, 144.962); Marker melbourne = map.addMarker( new MarkerOptions() .position(melbourneLocation));
마커 색상 맞춤설정
BitmapDescriptor
객체를 icon() 메서드에 전달하여 기본 마커 이미지의 색상을 맞춤설정할 수 있습니다. BitmapDescriptorFactory
객체의
사전 정의된 색상 집합을
사용하거나 BitmapDescriptorFactory.defaultMarker(float hue)
메서드를 사용하여 맞춤 마커
색상을 설정할 수 있습니다. 색조는 색상환의 특정 지점을 나타내는 값으로, 범위는 0~360입니다.
Kotlin
val melbourneLocation = LatLng(-37.813, 144.962) val melbourne = map.addMarker( MarkerOptions() .position(melbourneLocation) .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE)) )
Java
final LatLng melbourneLocation = new LatLng(-37.813, 144.962); Marker melbourne = map.addMarker( new MarkerOptions() .position(melbourneLocation) .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE)));
마커 불투명도 맞춤설정
MarkerOptions.alpha() 메서드를 사용하여 마커의 불투명도를 조정할 수 있습니다. 알파는 0.0~1.0 범위의 부동 소수점 수로 지정해야 합니다. 완전히 투명하면 0, 완전히 불투명하면 1입니다.
Kotlin
val melbourneLocation = LatLng(-37.813, 144.962) val melbourne = map.addMarker( MarkerOptions() .position(melbourneLocation) .alpha(0.7f) )
Java
final LatLng melbourneLocation = new LatLng(-37.813, 144.962); Marker melbourne = map.addMarker(new MarkerOptions() .position(melbourneLocation) .alpha(0.7f));
마커 이미지 맞춤설정
기본 마커 이미지를 맞춤 마커 이미지(보통 아이콘이라고 부름)로
바꿀 수 있습니다. 맞춤 아이콘은 항상 BitmapDescriptor
로 설정되며
BitmapDescriptorFactory
클래스의 메서드 중 하나를
사용하여 정의됩니다.
fromAsset(String assetName)
- assets 디렉터리에 있는 비트맵 이미지 이름을 사용하여 맞춤 마커를 만듭니다.
fromBitmap(Bitmap image)
- 비트맵 이미지에서 맞춤 마커를 만듭니다.
fromFile(String fileName)
- 내부 저장소에 있는 비트맵 이미지 파일의 이름을 사용하여 맞춤 아이콘을 만듭니다.
fromPath(String absolutePath)
- 비트맵 이미지의 절대 파일 경로에서 맞춤 마커를 만듭니다.
fromResource(int resourceId)
- 비트맵 이미지의 리소스 ID를 사용하여 맞춤 마커를 만듭니다.
아래 스니펫에서는 맞춤 아이콘으로 마커를 만듭니다.
Kotlin
val melbourneLocation = LatLng(-37.813, 144.962) val melbourne = map.addMarker( MarkerOptions() .position(melbourneLocation) .title("Melbourne") .snippet("Population: 4,137,400") .icon(BitmapDescriptorFactory.fromResource(R.drawable.arrow)) )
Java
final LatLng melbourneLocation = new LatLng(-37.813, 144.962); Marker melbourne = map.addMarker( new MarkerOptions() .position(melbourneLocation) .title("Melbourne") .snippet("Population: 4,137,400") .icon(BitmapDescriptorFactory.fromResource(R.drawable.arrow)));
마커 평면화
마커 아이콘은 보통 화면을 기준으로 그려지며, 지도를 회전하거나 기울이거나 확대/축소해도 마커의 방향은 바뀌지 않습니다. 마커의 방향을 지면에 평행하도록 설정할 수 있습니다. 이런 식으로 방향이 설정된 마커는 지도를 회전하면 함께 회전하며 지도를 기울이면 시점이 바뀝니다. 평면 마커는 지도를 확대하거나 축소해도 크기가 유지됩니다.
마커의 방향을 변경하려면 마커의 flat
속성을
true
로 설정하세요.
Kotlin
val perthLocation = LatLng(-31.90, 115.86) val perth = map.addMarker( MarkerOptions() .position(perthLocation) .flat(true) )
Java
final LatLng perthLocation = new LatLng(-31.90, 115.86); Marker perth = map.addMarker( new MarkerOptions() .position(perthLocation) .flat(true));
마커 회전
Marker
.setRotation()
메서드를 사용하여 앵커 포인트를 중심으로 마커를 회전할 수 있습니다. 회전은 기본 위치로부터 시계 방향의 각도로
측정됩니다. 지도에서 마커가 평면인 경우 기본 위치는
북쪽입니다. 마커가 평면이 아닌 경우 기본 위치는 위를 가리키며
마커는 항상 카메라를 향하도록 회전합니다.
아래의 예에서는 마커가 90° 회전합니다. 앵커 포인트를 0.5,0.5
로 설정하면 마커가 하단이 아니라 가운데를 중심으로 회전합니다.
Kotlin
val perthLocation = LatLng(-31.90, 115.86) val perth = map.addMarker( MarkerOptions() .position(perthLocation) .anchor(0.5f, 0.5f) .rotation(90.0f) )
Java
final LatLng perthLocation = new LatLng(-31.90, 115.86); Marker perth = map.addMarker( new MarkerOptions() .position(perthLocation) .anchor(0.5f,0.5f) .rotation(90.0f));
마커 Z-색인
Z-색인은 지도의 다른 마커를 기준으로 이 마커의 스택 순서를
지정합니다. Z-색인이 높은 마커가 Z-색인이 낮은 마커 위에
그려집니다. 기본 Z-색인 값은 0
입니다.
다음 코드 스니펫에서와 같이 MarkerOptions.zIndex()
를 호출하여 마커의
옵션 객체에 Z-색인을 설정합니다.
Kotlin
map.addMarker( MarkerOptions() .position(LatLng(10.0, 10.0)) .title("Marker z1") .zIndex(1.0f) )
Java
map.addMarker(new MarkerOptions() .position(new LatLng(10, 10)) .title("Marker z1") .zIndex(1.0f));
Marker.getZIndex()
를 호출하여 마커의 Z-색인에 액세스할 수 있으며 Marker.setZIndex()
를 호출하여 변경할 수 있습니다.
마커는 다른 오버레이의 Z-색인과 관계없이 항상 타일 레이어 및 마커가 아닌 다른 오버레이(지면 오버레이, 다중선, 다각형, 기타 도형) 위에 그려집니다. 마커는 사실상 다른 오버레이와 별도의 Z-색인 그룹에 있는 것으로 간주됩니다.
아래의 클릭 이벤트에서 Z-색인의 효과에 대해 읽어보세요.
마커 이벤트 처리
지도 API를 사용하여 마커 이벤트를 수신 대기하고 이에 응답할 수 있습니다. 이러한
이벤트를 수신하려면 마커가 속한 GoogleMap
객체에서
해당 리스너를 설정해야 합니다. 지도의 마커 중 하나에서 이벤트가
발생하면 매개변수로 전달된 해당 Marker
객체와 함께
리스너의 콜백이 호출됩니다. 이
Marker
객체를 Marker
객체의 자체 참조와 비교하려면
==
이 아니라 equals()
를 사용해야 합니다.
다음 이벤트를 수신할 수 있습니다.
마커 클릭 이벤트
OnMarkerClickListener
를 사용하여 마커의 클릭 이벤트를 수신 대기할 수 있습니다. 지도에 이 리스너를 설정하려면
GoogleMap.setOnMarkerClickListener(OnMarkerClickListener)
를 호출하세요. 사용자가
마커를 클릭하면 onMarkerClick(Marker)
가 호출되고 마커가
인수로 전달됩니다. 이 메서드는 이벤트를 처리했는지(즉 기본 동작을
숨기려고 하는지) 여부를 나타내는 불리언을
반환합니다. false
가 반환되면 맞춤 동작 이외에 기본 동작이
발생합니다. 마커 클릭 이벤트의 기본 동작은
정보 창을 표시하고(사용 가능한 경우)
마커가 지도의 중앙에 오도록 카메라를 움직이는 것입니다.
- 사용자가 마커의 클러스터를 클릭하면 Z-색인이 가장 높은 마커에 대해 클릭 이벤트가 트리거됩니다.
- 클릭당 한 개 이하의 이벤트가 트리거됩니다. 즉 Z-색인 값이 낮은 마커 또는 다른 오버레이에는 클릭이 전달되지 않습니다.
- 마커의 클러스터를 클릭하면 후속 클릭이 클러스터를 순환하여 각 마커가 차례로 선택됩니다. 순환 순서는 Z-색인이 우선 적용된 다음 클릭 지점과의 근접도에 따라 적용됩니다.
- 사용자가 클러스터에서 가깝지 않은 지점을 클릭하면 API에서 클러스터를 다시 계산하고 처음부터 시작하도록 클릭 순환의 상태를 재설정합니다.
- 클릭 이벤트는 순환을 다시 시작하기 전에 마커 클러스터를 통해 다른 도형 및 오버레이에 적용됩니다.
- 마커는 사실상 다른 오버레이의 Z-색인과 관계없이 다른 오버레이 또는 도형(다중선, 다각형, 원, 지면 오버레이)과 별도의 Z-색인 그룹에 있는 것으로 간주됩니다. 여러 마커, 오버레이 또는 도형이 서로 오버레이된 경우 클릭 이벤트가 먼저 마커의 클러스터를 순환한 다음 Z-색인 값을 기준으로 클릭 가능한 다른 오버레이나 도형에 대해 트리거됩니다.
마커 드래그 이벤트
OnMarkerDragListener
를 사용하여 지도에서
드래그 이벤트를 수신할 수 있습니다. 지도에 이 리스너를 설정하려면
GoogleMap.setOnMarkerDragListener
를 호출하세요. 마커를 드래그하려면 사용자가 마커를 길게 눌러야 합니다. 사용자가 화면에서 손가락을 떼면 마커가 그 위치에 남아 있게 됩니다. 마커를 드래그하면 처음에 onMarkerDragStart(Marker)
가 호출됩니다. 마커를 드래그하는 동안
onMarkerDrag(Marker)
가 계속 호출됩니다. 드래그가 끝날 때
onMarkerDragEnd(Marker)
가 호출됩니다. 언제든지 Marker.getPosition()
을 호출하여 마커의
위치를 가져올 수 있습니다.