extension ViewController: MKMapViewDelegate{
func mapView(_ mapView: MKMapView, didSelect annotation: MKAnnotation) {
}
}
extension ViewController: MKMapViewDelegate{
func mapView(_ mapView: MKMapView, didSelect annotation: MKAnnotation) {
let start = mapView.userLocation.coordinate
let dest = annotation.coordinate //선택한 어노테이션
//지점의 placemark 생성
let startPlacemark = MKPlacemark(coordinate: start)
let destPlacemark = MKPlacemark(coordinate: dest)
//mapItem 생성
let startMapItem = MKMapItem(placemark: startPlacemark)
let destMapItem = MKMapItem(placemark: destPlacemark)
//경로는 애플 서버로 요청을 보내서 생성한다.
let request = MKDirections.Request()
request.source = startMapItem
request.destination = destMapItem
//경로를 이동하는 수단 설정
request.transportType = .walking
let directions = MKDirections(request: request)
}
}
func mapView(_ mapView: MKMapView, didSelect annotation: MKAnnotation) {
let start = mapView.userLocation.coordinate
let dest = annotation.coordinate //선택한 어노테이션
//지점의 placemark 생성
let startPlacemark = MKPlacemark(coordinate: start)
let destPlacemark = MKPlacemark(coordinate: dest)
//mapItem 생성
let startMapItem = MKMapItem(placemark: startPlacemark)
let destMapItem = MKMapItem(placemark: destPlacemark)
//경로는 애플 서버로 요청을 보내서 생성한다.
let request = MKDirections.Request()
request.source = startMapItem
request.destination = destMapItem
//경로를 이동하는 수단 설정
request.transportType = .walking
let directions = MKDirections(request: request)
directions.calculate { response, error in //응답 객체, 에러
guard let response else {
if let error {
print(error)
}
return
}
let route = response.routes.first //routes는 배열로, 여러 경로가 나올 수 있기 때문.
}
}
func mapView(_ mapView: MKMapView, didSelect annotation: MKAnnotation) {
let start = mapView.userLocation.coordinate
let dest = annotation.coordinate //선택한 어노테이션
//지점의 placemark 생성
let startPlacemark = MKPlacemark(coordinate: start)
let destPlacemark = MKPlacemark(coordinate: dest)
//mapItem 생성
let startMapItem = MKMapItem(placemark: startPlacemark)
let destMapItem = MKMapItem(placemark: destPlacemark)
//경로는 애플 서버로 요청을 보내서 생성한다.
let request = MKDirections.Request()
request.source = startMapItem
request.destination = destMapItem
//경로를 이동하는 수단 설정
request.transportType = .walking
let directions = MKDirections(request: request)
directions.calculate { response, error in //응답 객체, 에러
guard let response else {
if let error {
print(error)
}
return
}
let route = response.routes[0] //routes는 배열로, 여러 경로가 나올 수 있기 때문.
mapView.addOverlay(route.polyline, level: .aboveRoads)
}
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
switch overlay{
case is MKPolyline:
let r = MKPolylineRenderer(overlay: overlay)
r.strokeColor = .systemRed //색
r.lineWidth = 10 //라인 두께
return r
...
경로로 인식되는 부분이 없다면, 기본으로 제공하는 기능은 사용 불가능하고 직접 경로를 계산해야 한다.
let start = mapView.userLocation.coordinate
let dest = CLLocationCoordinate2D(latitude: 37.294259, longitude: 127.2030509) //선택한 어노테이션
//지점의 placemark 생성
let startPlacemark = MKPlacemark(coordinate: start)
let destPlacemark = MKPlacemark(coordinate: dest)
//mapItem 생성
let startMapItem = MKMapItem(placemark: startPlacemark)
let destMapItem = MKMapItem(placemark: destPlacemark)
//경로는 애플 서버로 요청을 보내서 생성한다.
let request = MKDirections.Request()
request.source = startMapItem
request.destination = destMapItem
//경로를 이동하는 수단 설정
request.transportType = .automobile
request.requestsAlternateRoutes = true
let directions = MKDirections(request: request)
//비동기 방식으로 경로 설정하기. 반드시 각 GeoCoder마다 다른 객체를 사용해주어야한다.
Task{
do{
async let calculateResponse = directions.calculate()
async let placemarkOfStart = CLGeocoder().reverseGeocodeLocation(CLLocation(latitude: start.latitude, longitude: start.longitude), preferredLocale: Locale(identifier: "ko_kr"))
async let placemarksOfDest = CLGeocoder().reverseGeocodeLocation(CLLocation(latitude: dest.latitude, longitude: dest.longitude), preferredLocale: Locale(identifier: "ko_kr"))
//모든 결과가 반환될때까지 대기
let (routes, reverseGeocodedStart, reverseGeocodedDest) = try await (calculateResponse.routes, placemarkOfStart.first, placemarksOfDest.first)
let route = routes[0] //routes는 배열로, 여러 경로가 나올 수 있기 때문.
mapView.addOverlay(route.polyline, level: .aboveRoads)
let region = MKCoordinateRegion(route.polyline.boundingMapRect)
mapView.setRegion(region, animated: true)
performSegue(withIdentifier: "routeSegue", sender: routes)
} catch {
print(error)
}