private fun setCameraOnPolyLine() {
/** 위도 경도의 최대값과 최소값을 통해 중심점을 찾아 카메라포지션을 잡기
* '위치 정보를 불러왔을때' 조건을 추가해주면 되겠다. */
if (locationList.isNotEmpty()) {
var latMin = locationList[0].latitude
var latMax = locationList[0].latitude
var lngMin = locationList[0].longitude
var lngMax = locationList[0].longitude
for (latLng in locationList) {
if (latLng.latitude < latMin) latMin = latLng.latitude
if (latLng.latitude > latMax) latMax = latLng.latitude
if (latLng.longitude < lngMin) lngMin = latLng.longitude
if (latLng.longitude > lngMax) lngMax = latLng.longitude
}
val distanceDiff = DistanceCalculator.getDistance(latMin, latMax, lngMin, lngMax)
// maxDiff를 기준으로 줌 레벨 조정
Log.d("distanceDiff", "$distanceDiff")
val zoomLevel = when {
distanceDiff > 2.5 -> 10.0
distanceDiff > 1.5 -> 12.5
distanceDiff > 0.5 -> 15.0
else -> 7.5 /** 500부터 2500으로 했었는데 거꾸로 바꿔주니까 when문을 잘 탄다!
다만 거리마다 적합한 줌 배율을 정해야 하는데 이건 테스트가 필요하다 */
}
val centerLat = (latMin + latMax) / 2
val centerLng = (lngMin + lngMax) / 2
val center = LatLng(centerLat, centerLng)
cameraPosition = CameraPosition(center, zoomLevel)
Log.d("cameraPosition", "$zoomLevel")
cameraUpdate = CameraUpdate.toCameraPosition(cameraPosition)
naverMap.moveCamera(cameraUpdate)
Log.d("setCameraOnPolyLine", "Camera moved to $center")
} else {
Log.d("setCameraOnPolyLine", "Location list is empty, cannot set camera")
}
}
폴리라인이 그려진 위치에 적합한 배율로 폴리라인을 보여주기 위함입니다.
private lateinit var locationList: List<LatLng>
locationList는 latlng을 가지고 있습니다.
초기 경계값 설정: 첫 번째 위치의 위도와 경도로 latMin
, latMax
, lngMin
, lngMax
값을 초기화합니다.
locationList
에 있는 모든 위치를 순회하면서 최소 및 최대 위도와 경도를 갱신합니다.
latMin
, latMax
, lngMin
, lngMax
값을 이용하여 거리 차이를 계산합니다.
계산된 거리 차이에 따라 줌 레벨을 결정합니다.
최소 및 최대 위도와 경도를 이용하여 중앙 위치를 계산합니다.
중앙 위치와 줌 레벨을 사용하여 카메라 위치를 설정하고, 네이버 지도에서 해당 위치로 카메라를 이동시킵니다.
locationList
가 비어 있을 경우, 로그 메시지를 출력하고 카메라 설정을 하지 않습니다.
마지막으로 작업했던 나의 로직이였다. 그런데 송두리째 바뀌었다.
private fun setCameraOnPolyLine() {
if (locationList.isNotEmpty()) {
val boundsBuilder = LatLngBounds.Builder()
for (latLng in locationList) {
boundsBuilder.include(latLng)
}
val bounds = boundsBuilder.build()
val padding = 100
val cameraUpdate = CameraUpdate.fitBounds(bounds, padding)
naverMap.moveCamera(cameraUpdate)
Log.d("setCameraOnPolyLine", "Camera moved to fit bounds")
} else {
Log.d("setCameraOnPolyLine", "Location list is empty, cannot set camera")
}
}
초기 경계값을 정하는 변수, 최소 및 최대 위도 경도를 찾는 변수, 거리 차이를 계산하는 변수, 거리 차이에 따른 줌 레벨을 결정하는 변수, 중앙 위치를 계산하는 변수, 카메라를 위치하는 변수까지 전부 다 바뀌었다.
LatLngBounds.Builder() : 네이버 맵에서 지원하고 있다.
include() : LatLng
객체를 인수로 받아들이며, latLng
객체를 coords
리스트에 추가합니다.
@NonNull
public Builder include(@Nullable LatLng latLng) {
if (latLng != null && latLng.isValid()) {
this.coords.add(latLng);
}
return this;
}
build() : 필요한 좌표 데이터가 부족할 경우 IllegalStateException
을 던져 예외 상황을 처리합니다. 이는 사용자가 include()
메서드를 통해 적절히 좌표를 추가했는지 확인하는 기능을 합니다.
@NonNull
public LatLngBounds build() {
LatLngBounds result = this.buildOrNull();
if (result == null) {
throw new IllegalStateException("coordinates are empty; call include() first");
} else {
return result;
}
}
fitBounds : 지도 카메라를 주어진 지도의 특정 영역(LatLngBounds
)에 맞게 업데이트하는 데 사용됩니다. 또한, 패딩 값을 이용해 지도 가장자리와 경계 사이에 여유 공간을 설정
@NonNull
public static CameraUpdate fitBounds(@NonNull LatLngBounds bounds, @Px int padding) {
return fitBounds(bounds, padding, padding, padding, padding);
}
결론 :
include()
메서드를 통해 적절히 좌표를 추가했는지 확인하는 예외 상황을 처리합니다.val cameraUpdate = CameraUpdate.fitBounds(bounds, padding)
naverMap.moveCamera(cameraUpdate)
최근에 런타임 권한 요청에 대해 찾아보면서도 느꼈지만 공식 문서를 잘 봐야겠다고 생각했다. 잘 봐야겠다고 잘 봐지는건 아니겠지만 일이 잘 안 풀릴때 환기하는 느낌으로 보면 접근이 훨씬 쉬워질 것 같다. 공식 문서 혹은 api 코드를 열심히 뜯어봐야 이상적인 코딩을 할 수 있겠구나!