이번 글에서는 osmdroid에서 지도를 사용하는 방법에 대해 소개하려 한다. 회사에서 개발할 때 사용한 기능 위주로 소개돼서 없는 기능도 있는데, 공식 문서에서 대부분의 기능을 찾을 수 있다.
현재 보고있는 지도의 중심 좌표를 가져올 수 있다.
mapView.mapCenter
❗ osmdroid는 설정된 지도 좌표계에 해당하는 좌표를 반환해준다.
예를 들어 UTM 좌표계를 사용하면 UTM 좌표로 값을 반환한다.
지도를 움직일 때 사용하는 코드이다.
// 줌
mapView.controller.setZoom(12.0)
// 이동
mapView.controller.setCenter(GeoPoint(37.5665, 126.9780))
// 회전
mapView.mapOrientation = 90f
// 새로고침
mapView.invalidate()
❗ 이동과 줌을 동시에 하는 경우, 이동을 먼저하고 줌을 하면 위치가 다른 경우가 있어서 줌을 먼저하고 이동을 하는 편이 좋다.
osmdroid를 실행하면 화면을 채울때 까지 이미지를 반복하는데, 해당 속성을 false로 설정하면 반복되지 않는다.
mapView.isHorizontalMapRepetitionEnabled = false
mapView.isVerticalMapRepetitionEnabled = false
지도 이미지가 없으면 지도에 빈칸이 생기는데, 빈칸을 색상이나 그리드 색상을 지정할 수 있다.
mapView.overlayManager.tilesOverlay.loadingBackgroundColor = Color.YELLOW
mapView.overlayManager.tilesOverlay.loadingLineColor = Color.GREEN
❗ 색상을 Color.TRANSPARENT로 지정하면 투명으로 만들 수 있다.
osmdroid는 기본 설정이 터치를 사용해서 줌을 못한다. 터치를 사용하려면 setMultiTouchControls를 true로 설정해야 한다.
터치를 사용하는 대신 줌 컨트롤러를 사용할 수도 있는데, 컨트롤러 UI가 예쁘지는 않아서 버튼을 따로 만들어서 사용하는 것을 추천한다.
// 줌 컨트롤러 표시/숨김 설정
mapView.zoomController.setVisibility(CustomZoomButtonsController.Visibility.NEVER)
// 멀티 터치 설정
mapView.setMultiTouchControls(true)
기기에 따라 같은 지도 이미지가 크거나 작게 보일 수 있는데, 다음 설정으로 어느 정도 조절할 수 있다.
isTilesScaledToDpi가 true면 기기 화면 DPI에 따라 지도 이미지가 변한다. 기본은 false
tileScaleFactor는 배율을 직접 조정할 수 있는데, 1보다 크면 확대되고 작으면 축소된다.
두 설정은 동시에 적용이 가능하다.
// 스케일 DPI 적용
mapView.isTilesScaledToDpi = false
// 스케일 배율 설정
mapView.tilesScaleFactor = 2f
지도가 움직이는 영역을 제한할 때 사용한다.
val box = BoundingBox(max.latitude, max.longitude, min.latitude, min.longitude)
mapView.setScrollableAreaLimitDouble(box)
❗ 이 기능은 화면이 정해진 영역 안에서만 움직이게 하는 기능인데, 줌/회전을 하는 경우, 정해진 영역 밖이 화면에 보일 수 있다.
❗ 쉽게 말하면 화면에 보이는 영역을 정하는 기능이 아니라 화면이 이동할 수 있는 영역을 정하는 기능이다. 따라서 서버가 정해진 영역만 이미지를 만들고 보내주면 지도가 이상하게 보일 수 있다.
지도 이동 제한을 응용한 기능이다. 지도는 고정되지만 지도 위에 있는 것들을 터치할 수 있다.
val center = mapView.mapCenter
val box = BoundingBox(center.latitude, center.longitude, center.latitude, center.longitude)
mapView.setScrollableAreaLimitDouble(box)
❗ MapView는 View를 상속하고 있어서 터치를 막으면 지도 이동도 막힌다. 하지만 이렇게 설정하면 지도 위에 있는 것들도 터치가 안되기 때문에 문제가 생길 수 있다.
예를 들어 지도를 고정시켰는데 마커를 누르고 싶은 경우, 터치를 막으면 마커도 터치가 되지 않는다.
osmdroid는 타일 이미지를 받으면 다시 사용하기 위해서 로컬에 저장한다. 만약에 로컬에 저장된 이미지가 있으면 서버에 요청을 하지 않기 때문에 서버에 이미지가 업데이트 된 경우, 기존 이미지를 지워야 한다.
// 메모리 캐시 삭제
mapView.tileProvider.clearTileCache()
mapView.tileProvider.tileCache.garbageCollection()
// 로컬에 저장된 캐시 삭제
val writer = SqlTileWriter()
writer.purgeCache(mapView.tileProvider.tileSource.name())
// 새로 고침
mapView.invalidate()
❗ 사실 로컬에 저장된 이미지를 지울 일은 거의 없다. 내 경우 개발 편의성을 위해 추가했고 실제 앱에는 해당 기능이 없다.
일단 내가 사용하고 있는 기능만 정리했지만 그외에도 여러 기능을 사용하거나 만들 수 있다. 오래된 라이브러리다 보니 구글이나 깃허브 이슈를 찾아보면 여러 기능을 찾을 수 있다.