마커
마커는 상태 객체를 하나 만들어 지도 뷰에 놓기만 하면 됩니다. 렌더링은 SDK 내부의 렌더링 엔진이 담당하고, 건수에 따라 그리는 방식을 자동으로 전환합니다. 기본으로는 2,000개까지가 각 지도 SDK의 표준 마커, 그것을 넘으면 래스터 타일입니다. 이 기준값은 지도 뷰에 타일 렌더링 옵션을 넘겨 변경할 수 있습니다.
01 · 마커의 상태
MarkerState가 하나의 마커를 나타냅니다. 위치・아이콘・이벤트・임의의 부수 데이터를 가지고, 프로퍼티를 바꿔 쓰면 즉시 반영됩니다. 프로바이더마다의 타입은 없습니다.
val marker =
MarkerState(
position = GeoPoint.fromLatLong(21.3069, -157.8583),
icon = DefaultMarkerIcon(fillColor = Color.Red, label = "A"),
extra = postOffice,
onClick = { clicked -> viewModel.onMarkerClick(clicked) },
)
// Assigning to a property is all it takes to redraw
marker.position = nextPointlet marker = MarkerState(
position: GeoPoint.fromLatLong(latitude: 21.3069, longitude: -157.8583),
icon: DefaultMarkerIcon(fillColor: .red, label: "A"),
extra: postOffice,
onClick: { clicked in viewModel.onMarkerClick(clicked) }
)
content.markers = markerStates.map { Marker(state: $0) }const marker = createMarkerState({
id: 'post-office-1',
position: createGeoPoint({ latitude: 21.3069, longitude: -157.8583 }),
icon: new ColorDefaultIcon({ fillColor: '#e74c3c', label: 'A' }),
extra: postOffice,
onClick: setSelected,
});
<Markers states={markerStates} />02 · 아이콘
기본 핀에 색이나 라벨을 얹기만 하는 지정부터, 이미지・캔버스, 말풍선형 아이콘까지 마련되어 있습니다. 어느 아이콘이든 프로바이더를 넘어 같은 겉모습이 됩니다.
03 · 내부의 렌더링 엔진
마커의 렌더링은 SDK 내부의 렌더링 엔진에 맡기고 있습니다. 건수가 적을 동안은 각 지도 SDK의 표준 마커를 그대로 쓰고, 네이티브의 탭 판정이나 애니메이션을 그대로 살립니다.
마커가 2,000개를 넘으면, 엔진은 그리는 방식을 전환합니다. 마커 무리를 타일 이미지로 렌더링하고, 래스터 레이어로 겹침으로써, 네이티브 SDK로의 1건씩의 추가・갱신 비용을 없앱니다. 앱 쪽의 코드는 아무것도 달라지지 않습니다.
표준 마커로 그리기
래스터 타일로 그리기

// On by default; pass it to the map view to change the threshold
// (the Android parameter is called markerTiling)
val markerTiling =
MarkerTilingOptions.Default.copy(
minMarkerCount = 500, // switch to tile rendering from 500 markers
iconScaleCallback = { _, zoom ->
if (zoom > 10) 0.8 else if (zoom > 5) 0.5 else 0.2
},
)
GoogleMapView(state = mapViewState, markerTiling = markerTiling) { /* markers */ }
// Disable it to keep native markers at any count
val plain = MarkerTilingOptions.Disabledvar content = MapViewContent()
content.markerTilingOptions = MarkerTilingOptions(
minMarkerCount: 500, // switch to tile rendering from 500 markers
iconScaleCallback: { _, zoom in
PostOfficeViewModel.iconScale(zoom: zoom)
}
)
content.markers = markers.map { Marker(state: $0) }const MARKER_TILING_OPTIONS: MarkerTilingOptions = {
...MarkerTilingOptions.Default,
minMarkerCount: 500, // switch to tile rendering from 500 markers
iconScaleCallback: (_state, zoom) => (zoom > 10 ? 0.8 : zoom > 5 ? 0.5 : 0.2),
};
<PostOfficeMapProvider markerTilingOptions={MARKER_TILING_OPTIONS}>
<Markers states={markerStates} />
</PostOfficeMapProvider>04 · 애니메이션
간이적인 애니메이션을 표준으로 마련하고 있습니다. 생성 시에 지정하거나, 나중에 animate()를 호출하기만 하면 됩니다. 시작・종료는 핸들러로 받을 수 있습니다.
// Set one at creation, or call animate() later
MarkerState(position = point, animation = MarkerAnimation.Bounce)
override fun onMarkerClick(clicked: MarkerState) {
clicked.animate(clicked.extra as? MarkerAnimation)
}if let animation = clicked.extra as? MarkerAnimation {
clicked.animate(animation)
}const marker = createMarkerState({
id: 'animated-marker',
position: HONOLULU,
animation,
onClick: state => state.animate(MarkerAnimation.Bounce),
});애니메이션 중인 마커는 전용 오버레이로 렌더링되기 때문에, 타일 렌더링으로 전환되어 있는 상태에서도 움직입니다. 소요 시간은 SDK의 설정으로 변경할 수 있습니다.