![[TeamProject] CodeBase 카카오맵 _ 기초부터 차근차근](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFT92d%2FbtsJuUIiXd2%2FvsM9zzTPt90xLqH9cLtxv1%2Fimg.jpg)
카카오맵...api를 사용하면서 여러가지 트러블 슈팅들을 겪고 있다..
디버그를 아무리 찍어봐도 계속 도르마무 도르마무.. 하나를 해결하면 다른 하나가 안되는 그런 상황이라서
처음부터 다시 기초부터 차근차근 맵 구성부터 다시 해보려고 한다
1. 카카오맵 뷰 그리기
카카오 맵 초기화와 추가, api 오류 에러코드까지만 작업 한 내용
SDK 가이드라인에 스토리보드와 SwiftUI만 안내가 되어있음...
코딩 잘하시는분들은 뚝딱뚝딱 하겠지만
코드베이스로 처음 맵 작업해보시는 분들은 참고 하면 좋을듯
import UIKit
import KakaoMapsSDK
/**
-KakaoMapViewController : KakaoMap의 뷰트롤러 관리
*/
class KakaoMapViewController: UIViewController, MapControllerDelegate {
// MARK: - Properties
var mapViewContainer: KMViewContainer!
var mapController: KMController!
var kakaoMap: KakaoMap!
var auth: Bool = false
// MARK: - Lifecycle
override func loadView() {
mapViewContainer = KMViewContainer(frame: UIScreen.main.bounds)
self.view = mapViewContainer
mapController = KMController(viewContainer: mapViewContainer)
mapController?.delegate = self
}
override func viewDidLoad() {
super.viewDidLoad()
initializeMap()
}
/// 맵 엔진을 정리하는 작업
deinit {
mapController?.pauseEngine()
mapController?.resetEngine()
print("deinit")
}
// MARK: - Map Initializers
/// 맵 초기화 함수
func initializeMap() {
mapController?.prepareEngine()
mapController?.activateEngine()
}
/// 초기 위치 설정 및 뷰 추가 함수
func addViews() {
let defaultPosition = MapPoint(longitude: 126.977969, latitude: 37.566535)
let mapviewInfo: MapviewInfo = MapviewInfo(viewName: "mapview", defaultPosition: defaultPosition)
mapController?.addView(mapviewInfo)
}
// MARK: - MapControllerDelegate Methods
func addViewSucceeded(_ viewName: String, viewInfoName: String) {
print("맵 뷰 추가 성공: \(viewName)")
}
func addViewFailed(_ viewName: String, viewInfoName: String) {
print("맵 뷰 추가 실패: \(viewName)")
}
// MARK: - Authentication Handling
/// 인증 실패시 호출되는 함수
/// - Parameters:
/// - errorCode: api인증 오류 코드
/// - desc: 오류 코드에 대한 설명
func authenticationFailed(_ errorCode: Int, desc: String) {
print("error code: \(errorCode)")
print("desc: \(desc)")
auth = false
switch errorCode {
case 400:
showToast(self.view, message: "지도 종료(API인증 파라미터 오류)")
break;
case 401:
showToast(self.view, message: "지도 종료(API인증 키 오류)")
break;
case 403:
showToast(self.view, message: "지도 종료(API인증 권한 오류)")
break;
case 429:
showToast(self.view, message: "지도 종료(API 사용쿼터 초과)")
break;
case 499:
showToast(self.view, message: "지도 종료(네트워크 오류) 5초 후 재시도..")
// 인증 실패 delegate 호출 이후 5초뒤에 재인증 시도..
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
print("retry auth...")
self.mapController?.prepareEngine()
}
break;
default:
break;
}
}
/// 토스트 표시 함수
/// - Parameters:
/// - view: 토스트 메시지 뷰
/// - message: 사용자에게 표시되는 메시지
/// - duration: 토스트가 화면에 표시될 시간 ( 2초 )
func showToast(_ view: UIView, message: String, duration: TimeInterval = 2.0) {
let toastLabel = UILabel(frame: CGRect(x: view.frame.size.width/2 - 150, y: view.frame.size.height-100, width: 300, height: 35))
toastLabel.backgroundColor = UIColor.black
toastLabel.textColor = UIColor.white
toastLabel.textAlignment = NSTextAlignment.center;
view.addSubview(toastLabel)
toastLabel.text = message
toastLabel.alpha = 1.0
toastLabel.layer.cornerRadius = 10;
toastLabel.clipsToBounds = true
UIView.animate(withDuration: 0.4,
delay: duration - 0.4,
options: UIView.AnimationOptions.curveEaseOut,
animations: {
toastLabel.alpha = 0.0
},
completion: { (finished) in
toastLabel.removeFromSuperview()
})
}
}
2. POI마커 추가하기
여기서부터 고난 그 잡채... poi만 한 5번째 수정하면서 도전해 보는 중 인듯...
1. creatLabelLayer
lopPoi와 Poi 중 어떤걸 사용하는지에 따라서 달라지니까 사용하고자 하는게 어떤게 적합한지 확인하고 사용하는 게 좋음!
특징 | POI | LOD POI |
레이어 생성 | LabelLayerOptions | LodLabelLayerOptions |
가시성 조정 | 고정된 위치에서 항상 표시 | 줌 레벨 또는 반경에 따라 가시성 변경 |
주요 목적 | 소규모, 고정된 장소를 강조 | 대규모, 반경 기반 POI 관리 |
- 공통 옵션
- layerID: 레이어의 고유 ID
- competitionType: POI 간 경쟁 방식
- competitionUnit: 경쟁 단위
- orderType: 경쟁하는 기준
- zOrder: 레이어의 렌더링 순서(값이 클수록 위에 그려짐)
# LodPoi
- radius: LOD를 계산할 때 사용하는 반경.
- [ 사용자 가시성 반경을 지정해 주기 때문에 데이터 양이 많거나 광범위한 반경의 데이터를 관리해 줄때 좋은 것!]
- 1000이라고 설정하면 1,000미터(1km) 반경 내에서 POI가 표시되는 것
사용자가 해당 범위 내에 있을 때 POI가 활성화되어 보이게 됩니다.
func createLodLabelLayer() {
guard let labelManager = labelManager else { return }
let lodLayerOptions = LodLabelLayerOptions(
layerID: "lodPoiLayer",
competitionType: .none, // 경쟁 없음
competitionUnit: .symbolFirst, // 심볼 우선
orderType: .rank, // 우선 순위
zOrder: 10000, // 레이어 순서
radius: 2000 // 반경 2000미터
)
// 레이어 추가
_ = labelManager.addLodLabelLayer(option: lodLayerOptions)
}
# POI
- LODPOI와 달리 원하는 반경을 설정하지 못함
func createLabelLayer() {
guard let labelManager = labelManager else { return }
// POI가 위치할 레이어 생성
let poiLayerOptions = LabelLayerOptions(
layerID: "singlePoiLayer",
competitionType: .none, // 경쟁 없음
competitionUnit: .symbolFirst, // 심볼이 우선적으로 표시
orderType: .rank, // 우선 순위에 따라 표시
zOrder: 20000 // 레이어의 렌더링 순서 설정
)
// 레이어를 LabelManager에 추가
_ = labelManager.addLabelLayer(option: poiLayerOptions)
}
만약 LODPOI의 radius와 같은 값을 설정하고 싶다면,
지도 축척에 따라 레이어나 POI를 표시하거나 숨기는 등의 다른 방식으로 처리 할 수 있음
이런 방식은 주로
- 소규모 데이터: POI의 수가 적지만 넓은 범위에 걸쳐서 표시해야 할 때.
- 특정 범위 내 POI 표시: 사용자가 지도를 확대하면 특정 범위 내에서 POI가 활성화되도록 하고, 축소할 때는 숨기고 싶을 때.
- 동적으로 반경을 제어하고 싶을 때: radius가 동적으로 변하지 않기 때문에, 지도 축척을 통해 범위가 변경될 때만 POI를 표시할 수 있습니다.
아래 예시 코드를 참고하시면 됨
func mapView(_ mapView: KakaoMap, didChangeZoomLevel zoomLevel: Int) {
if zoomLevel > 5 {
// 줌 레벨이 5 이상일 때 POI를 표시
showAllPOIs()
} else {
// 줌 레벨이 5 이하일 때 POI 숨기기
hideAllPOIs()
}
}
2. creatPosStyle()
- 하나의 스타일 생성
func creatPoiStyle(styleID: String, imageName: String) {
guard let labelManager = labelManager else { return }
if let image = UIImage(named: imageName) {
let icon = PoiIconStyle(symbol: image, anchorPoint: CGPoint(x: 0, y: 0))
let perLevelStyle = PerLevelPoiStyle(iconStyle: icon, level: 0)
let poiStyle = PoiStyle(styleID: styleID, styles: [perLevelStyle])
labelManager.addPoiStyle(poiStyle)
}
}
- 여러가지 스타일 생성하는 방법
// 아이콘 스타일을 생성하는 함수
func setupPoiStyle(image: UIImage, anchorPoint: CGPoint, level: Int) -> PerLevelPoiStyle {
let iconStyle = PoiIconStyle(symbol: image, anchorPoint: anchorPoint)
return PerLevelPoiStyle(iconStyle: iconStyle, level: level)
}
// 여러 스타일을 생성하고 POI에 추가하는 함수
func createMultiPoiStyles(styleID: String, imageName: String) {
guard let labelManager = labelManager else { return }
if let image = UIImage(named: imageName) {
// 함수로 아이콘 스타일 생성
let Style1 = setupPoiStyle(image: image, anchorPoint: CGPoint(x: 0.5, y: 1.0), level: 0)
let Style2 = setupPoiStyle(image: image, anchorPoint: CGPoint(x: 0.5, y: 0.5), level: 10)
let Style3 = setupPoiStyle(image: image, anchorPoint: CGPoint(x: 1.0, y: 1.0), level: 15)
// 여러 스타일을 배열로 전달
let poiStyle = PoiStyle(styleID: styleID, styles: [Style1, Style2, Style3])
// 스타일 추가
labelManager.addPoiStyle(poiStyle)
}
}
'Project > Team Project' 카테고리의 다른 글
[TeamProject] Troubleshooting_AED API (3) | 2024.10.04 |
---|---|
[TeamProject] Troubleshooting_POI show/hide (0) | 2024.09.09 |
[TeamProject] troubleshooting_kakaomap관련 (4) | 2024.09.03 |
on / off 토글 버튼 만들기 (0) | 2024.08.28 |
[ TeamProject ] 프로젝트 준비 _ 카카오맵 api 공부하기! (8) | 2024.08.25 |
iOS Junior Developer를 위해 공부 또 공부
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!