官方文档:
解析:
1、从Apple服务得到导航服务,执行导航需要一个请求类——MKDirectionRequest(下面介绍);
2、每个实例只处理一次导航请求,如果处理多个请求,要创建多个实例;
3、不要在短时间内,请求过多次,否则触发MKErrorLoadingThrottled。
// request must not be nil.
init(request request: MKDirectionsRequest)
// 计算导航路线,在闭包handler里处理。
func calculateDirectionsWithCompletionHandler(_ completionHandler: MKDirectionsHandler)
// 闭包,response包含在Apple服务中,得到的route。
typealias MKDirectionsHandler = (MKDirectionsResponse?, NSError?) -> Void
注意:设置起点终点的时候,source的类型是MKMapItem。
转化示意:CLPlacemark -> MKPlacemark -> MKMapItem
实现:MKMapItem( placemark: MKPlacemark( placemark: CLPlacemark类型 ) )
// 导航的起点。
func setSource(source: MKMapItem!)
// 导航的终点。
func setDestination(destination: MKMapItem!)
// 导航方式MKDirectionsTransportType。
var transportType: MKDirectionsTransportType // Default is MKDirectionsTransportTypeAny
struct MKDirectionsTransportType : RawOptionSetType {
// 驾驶。
static var Automobile: MKDirectionsTransportType { get }
// 步行。
static var Walking: MKDirectionsTransportType { get }
// 所有。
static var Any: MKDirectionsTransportType { get }
}
这个类可以直接跳转到苹果自动的地图,完成导航功能。(好吧…)
这里只是做这样的转换:CLPlacemark -> MKPlacemark -> MKMapItem
这简单的界面就不用说了。
导包、代理那些简单的就不说了,前面的文章也提到。
import UIKit
import MapKit
class ViewController: UIViewController, MKMapViewDelegate{
// 地图
@IBOutlet weak var mapView: MKMapView!
// 起点输入框
@IBOutlet weak var srcString: UITextField!
// 终点输入框
@IBOutlet weak var dstString: UITextField!
// 开始导航按钮方法
@IBAction func navigatingButtonClick(sender: UIButton)
// 在geocode中,保留起点和终点各自的CLPlacemark。
var srcPlacemark: CLPlacemark!
var dstPlacemark: CLPlacemark!
//------------------------------------------------------------------------------
override func viewDidLoad() {
super.viewDidLoad()
self.mapView.delegate = self
}
//------------------------------------------------------------------------------
// 点击事件。
@IBAction func navigatingButtonClick(sender: UIButton) {
// 注销第一响应。
self.srcString.resignFirstResponder()
self.dstString.resignFirstResponder()
// 空输入处理。
if srcString.text.isEmpty || dstString.text.isEmpty {
UIAlertView(title: "Info empty", message: "Please enter completely", delegate: nil, cancelButtonTitle: "Ok").show()
return
}
// 移除原来的覆盖层。
self.mapView.removeAnnotations(self.mapView.annotations)
self.mapView.removeOverlays(self.mapView.overlays)
// 开始设置导航。
self.addAnnotations(self.srcString.text)
}
//------------------------------------------------------------------------------
// 添加大头针:根据参数address(将会传入“开始”或“终点”输入框内的文本),geocode得到相对应的CLPlacemarks.
func addAnnotations(address: String) {
// 解析字符串,得到相对应的信息。(参考本博客相关文章)
var geocoder = CLGeocoder()
geocoder.geocodeAddressString(address, completionHandler: { (placemarks: [AnyObject]!, error: NSError!) -> Void in
if error != nil && placemarks == nil{
println(error)
return
}else {
// 取第一个位置。
let firstPlacemark = placemarks.first as! CLPlacemark
// 添加大头针在位置上。
var pin = MKPointAnnotation()
pin.coordinate = firstPlacemark.location.coordinate
// 判断起点或终点。
if address == self.srcString.text {
// 保留CLPlacemark
self.srcPlacemark = firstPlacemark
// 设置大头针信息,并添加到地图。
pin.title = "起点"
pin.subtitle = self.srcPlacemark.name
self.mapView.addAnnotation(pin)
// 因为是异步,在此调用本方法,传入终点的字符串。
self.addAnnotations(self.dstString.text)
}else {
// 同上。
self.dstPlacemark = firstPlacemark
pin.title = "终点"
pin.subtitle = self.dstPlacemark.name、
self.mapView.addAnnotation(pin)
// 因为是异步,在此调用画导航线路的方法。
self.drawRoute()
}
}
})
}
//------------------------------------------------------------------------------
// 画导航线路。
func drawRoute() {
// 创建一个请求。
var request = MKDirectionsRequest()
// 设置请求的起点和终点(MKMapItem类型,用getMapItemByCLPlacemark转换)。
request.setSource(self.getMapItemByCLPlacemark(self.srcPlacemark))
request.setDestination(self.getMapItemByCLPlacemark(self.dstPlacemark))
// 根据request,创建一个导航类实例。
var direction = MKDirections(request: request)
// 计算路线。
direction.calculateDirectionsWithCompletionHandler { (response: MKDirectionsResponse!, error: NSError!) -> Void in
if error != nil && response == nil {
println(error)
return
}else {
// 默认只返回一条route。
var route = response.routes.first as! MKRoute
// 添加到地图上。
self.mapView.addOverlay(route.polyline)
}
}
}
//------------------------------------------------------------------------------
// 本文中,“类介绍”有提及。
func getMapItemByCLPlacemark(mark: CLPlacemark) -> MKMapItem {
return MKMapItem(placemark: MKPlacemark(placemark: mark))
}
//------------------------------------------------------------------------------
// 用Renderer在地图上显示覆盖层。(参考本博客相关文章)
func mapView(mapView: MKMapView!, rendererForOverlay overlay: MKOverlay!) -> MKOverlayRenderer! {
var polylineRenderer = MKPolylineRenderer(overlay: overlay as! MKPolyline)
polylineRenderer.strokeColor = UIColor.redColor()
polylineRenderer.lineWidth = 5.0
return polylineRenderer
}
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/c13232906050/article/details/47170903