마커

플랫폼 선택: Android iOS JavaScript

마커는 지도에서 단일 위치를 나타냅니다. 마커의 기본 색상을 변경하거나 마커 아이콘을 맞춤 이미지로 교체하여 맞춤설정할 수 있습니다. 정보 창에서 마커에 대한 추가 정보를 제공할 수 있습니다.

코드 샘플

GitHub의 ApiDemos 저장소에는 마커의 다양한 특징을 보여주는 샘플이 있습니다.

Kotlin

Java

소개

마커는 지도에서 위치를 나타냅니다. 기본 마커는 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-색인 값이 낮은 마커 또는 다른 오버레이에는 클릭이 전달되지 않습니다.
  • 마커의 클러스터를 클릭하면 후속 클릭이 클러스터를 순환하여 각 마커가 차례로 선택됩니다. 순환 순서는 Z-색인이 우선 적용된 다음 클릭 지점과의 근접도에 따라 적용됩니다.
  • 사용자가 클러스터에서 가깝지 않은 지점을 클릭하면 API에서 클러스터를 다시 계산하고 처음부터 시작하도록 클릭 순환의 상태를 재설정합니다.
  • 클릭 이벤트는 순환을 다시 시작하기 전에 마커 클러스터를 통해 다른 도형 및 오버레이에 적용됩니다.
  • 마커는 사실상 다른 오버레이의 Z-색인과 관계없이 다른 오버레이 또는 도형(다중선, 다각형, 원, 지면 오버레이)과 별도의 Z-색인 그룹에 있는 것으로 간주됩니다. 여러 마커, 오버레이 또는 도형이 서로 오버레이된 경우 클릭 이벤트가 먼저 마커의 클러스터를 순환한 다음 Z-색인 값을 기준으로 클릭 가능한 다른 오버레이나 도형에 대해 트리거됩니다.

마커 드래그 이벤트

OnMarkerDragListener를 사용하여 지도에서 드래그 이벤트를 수신할 수 있습니다. 지도에 이 리스너를 설정하려면 GoogleMap.setOnMarkerDragListener를 호출하세요. 마커를 드래그하려면 사용자가 마커를 길게 눌러야 합니다. 사용자가 화면에서 손가락을 떼면 마커가 그 위치에 남아 있게 됩니다. 마커를 드래그하면 처음에 onMarkerDragStart(Marker)가 호출됩니다. 마커를 드래그하는 동안 onMarkerDrag(Marker)가 계속 호출됩니다. 드래그가 끝날 때 onMarkerDragEnd(Marker)가 호출됩니다. 언제든지 Marker.getPosition()을 호출하여 마커의 위치를 가져올 수 있습니다.