# 导航

方案一:使用的是系统APP的导航(高德地图)

  1. 根据用户输入的两个地点进行导航(或者是一个目的地,再获取用户的位置)
  • 所用到的技术点
    • 地理编码/反地理编码
    • 系统的MKMapItem类
  • 反向逆推发进行设计实现(缺什么补什么)
// MARK:- 懒加载
    private lazy var geoc : CLGeocoder = {
       return CLGeocoder()
    }()

    // 在touchesBegan中进行测试
    override func touchesBegan(touches: Set, 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

    }

你可能感兴趣的:(# 导航)