지도의 카메라를 변경하여 사용자가 바라보는 뷰 시점의 지도를 자유롭게 움직일 수 있는 기능을 설명합니다. 카메라 이동, 줌 레벨 변경, 기울기 조정, 화면 회전 등이 가능합니다.
카메라의 위치
CameraPosition은 카메라의 위치를 나타내는 클래스입니다. 카메라의 위치는 카메라가 놓여 있는 대상 지점의 좌표와 줌 레벨, 기울기 각도, 베어링 각도로 구성됩니다.
대상 지점
현재 지도가 표출되고 있는 지점을 의미합니다. target 속성으로 대상 지점을 설정할 수 있습니다.
줌 레벨
현재 지도의 축척을 의미합니다. zoom 속성으로 줌 레벨을 설정할 수 있습니다. 줌 레벨이 작을수록 화면에 보이는 지역이 넓어집니다. 반대로 줌 레벨이 클수록 지도에 상세한 정보가 표출됩니다.
기울기 각도
카메라가 위에서 지도를 바라보는 수직적 각도를 의미합니다. tilt 속성으로 기울기 각도를 설정할 수 있습니다. 기울기 각도가 0일 때 카메라는 지도를 수직으로 내려다보며, 값이 증가할수록 카메라의 시점이 수평에 가까워집니다. 기울기 각도가 클수록 더 먼 지점을 볼 수 있고, 지도에 원근감 효과가 크게 적용됩니다.
베어링 각도
카메라가 지도를 바라보는 수평적 각도, 즉 방향을 의미합니다. bearing 속성으로 베어링 각도를 설정할 수 있습니다. 베어링 각도가 0일 때 지도는 정북 방향을 바라보며, 값이 증가할 수록 시계 방향으로 회전합니다. 값이 360이 되면 지도는 다시 정북 방향을 바라보게 됩니다.
CameraPosition 객체
CameraPosition의 모든 속성은 final이므로 생성자로만 설정할 수 있으며, 한 번 생성된 객체의 속성은 변경할 수 없습니다.
animationType 속성으로 카메라 이동 시 적용할 애니메이션의 유형을 가져오거나 새로 설정할 수 있습니다. 카메라 애니메이션의 종류는 CameraAnimationType 열거형에 정의되어 있습니다. 카메라 이동에 적용할 수 있는 애니메이션 유형은 다음과 같습니다.
진행 중인 카메라 이동 애니메이션은 다양한 이유로 취소되거나 취소할 수 있습니다. InaviMap#moveCamera() 함수를 호출하여 새로운 카메라 이동을 시작하면 이전에 진행 중이던 카메라 이동은 자동으로 취소됩니다.
InaviMap#cancelTransitions() 함수를 호출하여 명시적으로 카메라 애니메이션을 취소할 수도 있습니다. 이 함수를 호출하면 현재 진행 중인 카메라 애니메이션이 취소되고 카메라가 현재 위치에 멈춥니다. 애니메이션 도중 사용자가 지도를 탭했을 경우에도 동일한 결과가 일어납니다.
콜백과 이벤트
CameraUpdate 객체에 콜백을 설정하는 함수를 사용하면 특정 카메라 이동의 결과에 대한 이벤트를 감지할 수 있습니다. 또한 InaviMap 객체에 이벤트 리스너를 추가하면 지도에서 일어나는 모든 카메라 이동에 대한 이벤트를 감지할 수 있습니다.
onCameraChange() 콜백 함수에는 reason 파라미터가 전달되며, 이는 이벤트를 발생시킨 카메라 이동의 원인을 의미합니다. CameraUpdate 객체의 reason 속성으로 카메라 이동의 원인을 가져오거나 새로 설정할 수 있습니다. 콜백 함수에서 이 값을 이용하여 어떤 원인에 의해 발생한 이벤트인지를 판단할 수 있습니다.
제스처, 컨트롤 등 아이나비 지도 SDK의 내장 기능에 의해 카메라가 이동한 경우 미리 정의된 음숫값을 가지며, 개발자가 임의의 양숫값을 설정할 수도 있습니다. 카메라 이동의 원인은 CameraUpdate 클래스에 상수로 정의되어 있으며, 상세 내용은 다음과 같습니다.
// 대상 지점, 줌 레벨을 지정하여 CameraPosition 객체 생성
// 기울기 각도와 베어링 각도는 0으로 설정된다.
val cameraPosition = CameraPosition(LatLng(36.99473, 127.81832), 16.0)
// 카메라의 위치 설정
inaviMap.cameraPosition = cameraPosition
// 카메라의 위치 가져오기
val myCameraPosition = inaviMap.cameraPosition
// 하단 패딩을 200px로 설정
inaviMap.setPadding(0, 0, 0, 200)
val projection = inaviMap.projection // Projection 인스턴스 가져오기
// 화면상 (100, 100) 지점의 좌표를 지도상의 좌표로 변환
val mapCoords = projection.getLatLngFromPoint(PointF(100f, 100f))
// 지도상 (37.40219, 127.11077) 지점의 좌표를 화면상의 좌표로 변환
val screenCoords = projection.getPointFromLatLng(LatLng(37.40219, 127.11077))
// 현재 카메라의 축척을 미터/픽셀 단위로 가져오기
val metersPerPixel = projection.metersPerPixel
// 현재 카메라의 축척을 미터/DP 단위 단위로 가져오기
val metersPerDp = projection.metersPerDp
// 적도, 줌 레벨 10
val metersPerPixel1 = projection.getMetersPerPixel(0.0, 10.0)
// 위도 35도, 줌 레벨 10: 적도보다 축척이 커짐
val metersPerPixel2 = projection.getMetersPerPixel(35.0, 10.0)
// 위도 35도, 줌 레벨 15: 줌 레벨 10보다 축척이 커짐
val metersPerPixel3 = projection.getMetersPerPixel(35.0, 15.0)
// 적도, 줌 레벨 10, 미터/DP 단위
val metersPerDp1 = projection.getMetersPerDp(0.0, 10.0)
// 대상 지점을 (36.99473, 127.81832)로 설정하여 카메라 이동
val cameraUpdate = CameraUpdate.targetTo(LatLng(36.99473, 127.81832))
inaviMap.moveCamera(cameraUpdate)
// 카메라 이동에 Fly 애니메이션 적용
cameraUpdate.animationType = CameraAnimationType.Fly
// 카메라 애니메이션 소요시간을 5초로 설정
cameraUpdate.durationMs = 5000
val POSITION1 = LatLng(36.99473, 127.81832)
val POSITION2 = LatLng(37.40219, 127.11077)
// 5초간 카메라 애니메이션
inaviMap.moveCamera(CameraUpdate.targetTo(POSITION1)
.setAnimationType(CameraAnimationType.Easing, 5000))
// 3초 후 새로운 카메라 이동이 시작되면서 기존 카메라 애니메이션이 취소됨
Handler().postDelayed({
inaviMap.moveCamera(CameraUpdate.targetTo(POSITION2)
.setAnimationType(CameraAnimationType.Fly, 3000))
}, 3000)
// 5초간 카메라 애니메이션
inaviMap.moveCamera(CameraUpdate.targetTo(LatLng(36.99473, 127.81832))
.setAnimationType(CameraAnimationType.Easing, 5000))
// 3초 후 cancelTransitions()가 호출되어 기존 카메라 애니메이션이 취소됨
Handler().postDelayed({
inaviMap.cancelTransitions()
}, 3000)
val cameraUpdate = CameraUpdate.targetTo(LatLng(36.99473, 127.81832))
.setAnimationType(CameraAnimationType.Fly, 5000)
.durationMs = 5000
.setFinishCallback {
Toast.makeText(context, "카메라 이동 완료", Toast.LENGTH_SHORT).show()
}
.setCancelCallback {
Toast.makeText(context, "카메라 이동 취소", Toast.LENGTH_SHORT).show()
}
inaviMap.moveCamera(cameraUpdate)
// 카메라 변경 발생 시 이벤트 처리
inaviMap.addOnCameraChangeListener { reason ->
Toast.makeText(context, "카메라 변경 / reason : $reason",
Toast.LENGTH_SHORT).show()
}
// reason을 임의의 값으로 설정하여 CameraUpdate 객체 생성
val cameraUpdate = CameraUpdate.targetTo(LatLng(36.99473, 127.81832))
.setAnimationType(CameraAnimationType.Fly, 5000)
.setReason(1000)
inaviMap.moveCamera(cameraUpdate)