方案一:使用的是系统APP的导航(高德地图)
- 根据用户输入的两个地点进行导航(或者是一个目的地,再获取用户的位置)
- 所用到的技术点
- 地理编码/反地理编码
- 系统的MKMapItem类
- 反向逆推发进行设计实现(缺什么补什么)
// MARK:- 懒加载
private lazy var geoc : CLGeocoder = {
return CLGeocoder()
}()
// 在touchesBegan中进行测试
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
// 根据用户的输入的地点进行地理编码
geoc.geocodeAddressString("广州") { (clpls : [CLPlacemark]?, error : NSError?) -> Void in
if error == nil {
// 判断地标对象数组是否有值
guard let clpls = clpls else {return}
// 取出相关度最好的地标对象
guard let gzCLPL = clpls.first else {return}
self.geoc.geocodeAddressString("上海") { (clpls : [CLPlacemark]?, error : NSError?) -> Void in
if error == nil {
guard let clpls = clpls else {return}
guard let shCLPL = clpls.first else {return}
self.beginNavigation(gzCLPL, endCLPL: shCLPL)
}
}
}
}
}
// 参数两个地标对象
func beginNavigation(startCLPL : CLPlacemark, endCLPL : CLPlacemark) {
// 设置起点
// 转换为MKPlacemark的类型的地表对象
let startMKPL = MKPlacemark(placemark: startCLPL)
// 转化MKMapItem
let startItem = MKMapItem(placemark: startMKPL)
// 设置终点
let endMKPL = MKPlacemark(placemark: endCLPL)
let endItem = MKMapItem(placemark: endMKPL)
// 设置起点和终点(mapItems: [MKMapItem])
let mapItems : [MKMapItem] = [startItem, endItem]
// 设置启动项(launchOptions: )
let dict : [String : AnyObject] = [
// (键 : 值)的形式
// 方向模式 : 开车
MKLaunchOptionsDirectionsModeKey : MKLaunchOptionsDirectionsModeDriving,
// 地图类型 :普通(Standard)
MKLaunchOptionsMapTypeKey : MKMapType.Standard.rawValue,
// 交通 :true表示显示
MKLaunchOptionsShowsTrafficKey : true
]
// 通过设置的内容,打开系统的导航app进行导航
MKMapItem.openMapsWithItems(mapItems, launchOptions: dict)
MKMapItem.openMapsWithItems(<#T##mapItems: [MKMapItem]##[MKMapItem]#>, launchOptions: <#T##[String : AnyObject]?#>)
}
方案二:发送网络请求给苹果服务器获取导航路线(MKDirections)
其中也是要根据出发地和目的地来发送xing请求路线的,并根据出发地和目的地进行地理编码/反地理编码来得到最好的相关度的地标对象(CLPlacemark),然后将对应的地标对象转化为MKPlacemark类型的地标对象
// CLPlacemark类型的出发地和目的地的地标对象
func getRouteMessage(sourceCLPL : CLPlacemark, destinationCLPL : CLPlacemark ) {
// 创建路线请求对象
let request = MKDirectionsRequest()
// 设置起点
let sourceMKPL = MKPlacemark(placemark: sourceCLPL)
request.source = MKMapItem(placemark: sourceMKPL)
// 设置终点
let destinationMKPL = MKPlacemark(placemark: destinationCLPL)
request.destination = MKMapItem(placemark: destinationMKPL)
// 创建路线对象
let directions = MKDirections(request: request)
// 请求路线信息
directions.calculateDirectionsWithCompletionHandler { (response : MKDirectionsResponse?, error : NSError?) -> Void in
if error == nil {
// MKDirectionsResponse 响应对象
// routes: [MKRoute] 所有的路线
// MKRoute
// name 路线名称
// advisoryNotices 警告信息
// distance 整条路线的总距离
// expectedTravelTime 预期到达时间
// transportType 交通方式
// polyline : 折线数据模型,展示在地图上几何图形(覆盖层)
// steps: [MKRouteStep] :每个步骤应该怎么走
// [MKRouteStep]
// instructions : 每一步的描述 "前方500 左转"
// notice : 每个路线的警告
// polyline : 单个折线的数据模型
// distance : 每一步骤的距离
// transportType : 每一步骤的交通方式
guard let response = response else {return}
let routes : [MKRoute] = response.routes
for route in routes {
print(route.name,route.distance)
let steps = route.steps
for step in steps {
print(step.instructions)
}
}
}
}
- 渲染层描绘行走路线
/**
当向地图上添加覆盖层的时候就会调用这个代理方法,找到对应的渲染图层并返回
// 每一个覆盖层的渲染图层都是不一样的
- parameter mapView: 地图
- parameter overlay: 覆盖层
- returns: 渲染图层
*/
func mapView(mapView: MKMapView, rendererForOverlay overlay: MKOverlay) -> MKOverlayRenderer {
// 1.创建折线的渲染图层
let polylineRender = MKPolylineRenderer(overlay: overlay)
// 2.设置线宽以及颜色
polylineRender.lineWidth = 6
polylineRender.strokeColor = UIColor.redColor()
// 3.返回对应的渲染图层
return polylineRender
}
网友评论