美文网首页
地图和定位(五)

地图和定位(五)

作者: weyan | 来源:发表于2020-03-07 16:17 被阅读0次

一、导航

导航的三种方式:

1、使用系统APP导航

使用系统APP导航
import UIKit
import MapKit

class ViewController: UIViewController {
    
    lazy var geoCoder: CLGeocoder = {
        return CLGeocoder()
    }()
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        /**调用系统的APP进行导航**/
        //从北京到上海
        geoCoder.geocodeAddressString("北京") { (pls:[CLPlacemark]?, error:Error?) in
            //北京地标
            let gzpl = pls?.first
            self.geoCoder.geocodeAddressString("上海", completionHandler: { (place:[CLPlacemark]?, error: Error?) in
                //上海地标
                let shpl = place?.first
                self.beginNav(start: gzpl!, end: shpl!)
            })
        }
    }
    
    func beginNav(start: CLPlacemark, end: CLPlacemark) {
        //创建起点和终点
        let startMKPL:MKPlacemark = MKPlacemark(placemark: start)
        let startItem: MKMapItem = MKMapItem(placemark: startMKPL)
        
        let endMKPL:MKPlacemark = MKPlacemark(placemark: end)
        let endItem:MKMapItem = MKMapItem(placemark: endMKPL)
        
        let items:[MKMapItem] = [startItem,endItem]
        //根据起点和终点以及地图启动项,来调用系统APP进行导航
        let dic = [MKLaunchOptionsDirectionsModeKey:MKLaunchOptionsDirectionsModeDriving,MKLaunchOptionsMapTypeKey: MKMapType.standard.rawValue,MKLaunchOptionsShowsTrafficKey:true] as [String : Any]
        MKMapItem.openMaps(with: items, launchOptions: dic)
    }
}

2、发送网络请求给苹果服务器获取导航路线

2.1、获取导航路线

import UIKit
import MapKit

class ViewController: UIViewController {
    
    lazy var geoCoder: CLGeocoder = {
        return CLGeocoder()
    }()
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        geoCoder.geocodeAddressString("广州") { (pls:[CLPlacemark]?, error:Error?) in
            //广州地标
            let gzpl = pls?.first
            
            self.geoCoder.geocodeAddressString("上海") { (places:[CLPlacemark]?, error:Error?) in
                //上海地标
                let shpl = places?.first
                self.getRouteMessage(start: gzpl!, end: shpl!)
            }
        }
    }
    
    func getRouteMessage(start: CLPlacemark,end:CLPlacemark) {
        //1.发起请求,获取导航信息
        let request:MKDirectionsRequest = MKDirectionsRequest()
        //设置起点和终点
        let startMKPL: MKPlacemark = MKPlacemark(placemark: start)
        let startItem: MKMapItem = MKMapItem(placemark: startMKPL)
        request.source = startItem
        
        let endMKPL: MKPlacemark = MKPlacemark(placemark: end)
        let endItem: MKMapItem = MKMapItem(placemark: endMKPL)
        request.destination = endItem
        
        //2.根据一个导航请求,创建一个MKDirections导航对象
        let directions: MKDirections = MKDirections(request: request)
        //3.计算导航数据信息
        directions.calculate { (response:MKDirectionsResponse?, error:Error?) in
            print("已经获取到数据")
            //4.解析导航数据
            //routes: [MKRoute] 路线对象
            
            //MKRoute
            //name: 路线名称
            //advisoryNotices: [String]:提醒信息:前方雨雪路滑,注意安全
            //distance: CLLocationDistance: 距离
            //expectedTravelTime: 路线行走需要的时间
            //transportType: 同行方式
            //polyline: MKPolyline 路线数据模型
            //steps: [MKRouteStep] 每一步怎么走
            
            //MKRouteStep
            // instructions 导航提示
            //notice 警告信息
            //polyline 每一小段折线数据模型
            //distance 每一小段的距离
            //transportType 每一小段的通行方式
            if error == nil{
                for route in (response?.routes)!{
                    print("整条线路:\(route.name),\(route.distance)")
                    for step in route.steps{
                        print("step:\(step.instructions)")
                    }
                }
            }
        }
    }
}

2.2、绘制导航路线
1.绘制折线路线

绘制折线路线
import UIKit
import MapKit

//理论
//路线本身也属于一个覆盖层
//如果我们在地图上操作一个覆盖层视图,就等于操作覆盖层数据模型
//添加一个覆盖层 == 添加一个覆盖层数据模型
//删除一个覆盖层 == 删除一个覆盖层数据模型
class ViewController: UIViewController {
    
    @IBOutlet weak var mapView: MKMapView!
    lazy var geoCoder: CLGeocoder = {
        return CLGeocoder()
    }()
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        geoCoder.geocodeAddressString("广州") { (pls:[CLPlacemark]?, error:Error?) in
            //广州地标
            let gzpl = pls?.first
            
            self.geoCoder.geocodeAddressString("上海") { (places:[CLPlacemark]?, error:Error?) in
                //上海地标
                let shpl = places?.first
                self.getRouteMessage(start: gzpl!, end: shpl!)
            }
        }
    }
    
    func getRouteMessage(start: CLPlacemark,end:CLPlacemark) {
        //1.发起请求,获取导航信息
        let request:MKDirectionsRequest = MKDirectionsRequest()
        //设置起点和终点
        let startMKPL: MKPlacemark = MKPlacemark(placemark: start)
        let startItem: MKMapItem = MKMapItem(placemark: startMKPL)
        request.source = startItem
        
        let endMKPL: MKPlacemark = MKPlacemark(placemark: end)
        let endItem: MKMapItem = MKMapItem(placemark: endMKPL)
        request.destination = endItem
        
        //2.根据一个导航请求,创建一个MKDirections导航对象
        let directions: MKDirections = MKDirections(request: request)
        //3.计算导航数据信息
        directions.calculate { (response:MKDirectionsResponse?, error:Error?) in
            print("已经获取到数据")
            //4.解析导航数据
            //routes: [MKRoute] 路线对象
            
            //MKRoute
            //name: 路线名称
            //advisoryNotices: [String]:提醒信息:前方雨雪路滑,注意安全
            //distance: CLLocationDistance: 距离
            //expectedTravelTime: 路线行走需要的时间
            //transportType: 同行方式
            //polyline: MKPolyline 路线数据模型
            //steps: [MKRouteStep] 每一步怎么走
            
            //MKRouteStep
            // instructions 导航提示
            //notice 警告信息
            //polyline 每一小段折线数据模型
            //distance 每一小段的距离
            //transportType 每一小段的通行方式
            if error == nil{
                for route in (response?.routes)!{
                    print("整条线路:\(route.name),\(route.distance)")
                    //5.添加一个覆盖层数据模型
                    //如果调用了这个方法,地图就会查找对应的代理方法,获取对应的覆盖层视图
                    self.mapView.add(route.polyline)
                    for step in route.steps{
                        
                        print("step:\(step.instructions)")
                    }
                }
            }
        }
    }
}

extension ViewController: MKMapViewDelegate{
    //当外界添加一个覆盖层数据模型时,就会调用这个方法查找覆盖层视图(渲染层)
    //mapView 地图视图
    //overlay 覆盖层数据模型
    // 返回覆盖层视图(渲染图层)
    //提示:我们应该根据不同的”数据模型“返回不同的”覆盖层视图“
    func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
        //如果添加的是折线数据模型,应该返回折线渲染图层MKPolylineRenderer
//        let tempOverlay: MKPolyline! = overlay as! MKOverlay
        let render = MKPolylineRenderer(overlay: overlay)
        render.lineWidth = 10
        render.strokeColor = UIColor.red
        return render
    }
}

2.添加圆形覆盖层

圆形覆盖层
import UIKit
import MapKit

//理论
//路线本身也属于一个覆盖层
//如果我们在地图上操作一个覆盖层视图,就等于操作覆盖层数据模型
//添加一个覆盖层 == 添加一个覆盖层数据模型
//删除一个覆盖层 == 删除一个覆盖层数据模型
class ViewController: UIViewController {
    
    @IBOutlet weak var mapView: MKMapView!
    lazy var geoCoder: CLGeocoder = {
        return CLGeocoder()
    }()
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        //添加一个圆形的覆盖层 == 添加一个圆形的覆盖层数据模型
        //1.创建覆盖层数据模型
        let circle: MKCircle = MKCircle(center: mapView.centerCoordinate, radius: 1000000)
        //添加覆盖层数据模型(调用代理方法,查找覆盖层渲染图层来展示)
        mapView.add(circle)
    }
}

extension ViewController: MKMapViewDelegate{
    //当外界添加一个覆盖层数据模型时,就会调用这个方法查找覆盖层视图(渲染层)
    //mapView 地图视图
    //overlay 覆盖层数据模型
    // 返回覆盖层视图(渲染图层)
    //提示:我们应该根据不同的”数据模型“返回不同的”覆盖层视图“
    func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
        let render: MKCircleRenderer = MKCircleRenderer(overlay: overlay)
        render.fillColor = UIColor.yellow
        render.alpha = 0.5
        return render
    }
}

3、使用第三方导航

----------------------------使用百度地图----------------------------
具体使用参照百度地图SDK文档

<1>使用使用百度地图SDK

1.创建地图


代码如下:
import UIKit

class ViewController: UIViewController {
    lazy var mapView: BMKMapView = {
        let mapView: BMKMapView = BMKMapView(frame: self.view.bounds)
        //显示比例尺
        mapView.showMapScaleBar = true
        //设置upsideMapView的缩放等级(4-21)
        mapView.zoomLevel = 17
        //底图展示的地图类型
        mapView.mapType = .standard
        mapView.delegate = self
        return mapView
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.addSubview(mapView)
        
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        mapView.viewWillAppear()
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        mapView.viewWillDisappear()
    }
}

extension ViewController: BMKMapViewDelegate{
    
}

2.一些设置

一些设置

代码如下:

import UIKit

class ViewController: UIViewController {
    lazy var mapView: BMKMapView = {
        let mapView: BMKMapView = BMKMapView(frame: self.view.bounds)
        //1、显示比例尺
        mapView.showMapScaleBar = true
        //2、设置upsideMapView的缩放等级(4-21)
        mapView.zoomLevel = 17
        //3、底图展示的地图类型
        mapView.mapType = .standard
        //4、打开实时路况图层
        mapView.isTrafficEnabled = true
        //5、打开百度城市热力图图层(百度自有数据)
        mapView.isBaiduHeatMapEnabled = true
        /**6、
         自定义路况颜色。注意:如果需要自定义路况颜色,必须4种路况全都设置。4个参数全部合法时,自定义颜色才有效;否则全部使用默认的。
         
         @param smooth 路况畅通对应的颜色
         @param slow 路况缓行对应的颜色
         @param congestion 路况拥堵对应的颜色
         @param severeCongestion 路况严重拥堵对应的颜色
         @return 自定义颜色合法返回true,非法返回false
         */
        //Step2. 调用路况设置API,自定义颜色,其中颜色值如有一项为nil,则自定义无效,显示默认颜色样式;需要先关闭路况开关,设置自定义颜色,再打开路况打开
        mapView.isTrafficEnabled = false
        mapView.setCustomTrafficColorForSmooth(UIColor.gray, slow: UIColor.purple, congestion: UIColor.yellow, severeCongestion: UIColor.red)
        mapView.isTrafficEnabled = true
        mapView.delegate = self
        return mapView
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.addSubview(mapView)
        
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        mapView.viewWillAppear()
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        mapView.viewWillDisappear()
    }
}

extension ViewController: BMKMapViewDelegate{
    
}

2.POI检索
POI(Point of Interest),中文可以翻译为“兴趣点”。在地理信息系统中,一个POI可以是一栋房子、一个商铺、一个邮筒、一个公交站等。 百度地图SDK提供五种类型的POI检索:POI城市检索、POI周边检索、POI矩形区域检索、POI室内检索以及POI详情检索
(1)POI城市检索
城市检索是根据关键字检索适用于在「某个行政区划,如北京市、四川省等」搜索某个名称相关的POI,例如:查找北京市的“小吃”。

(1)POI城市检索
(2)POI周边(圆形区域)检索
周边检索是一个圆形范围,适用于以某个位置为中心点,自定义检索半径值,搜索某个位置附近的POI。例如:查找当前位置(40.051231, 116.282051)附近1000米范围内的“小吃”。
(2)POI周边检索
其他POI检索参考百度SDK开发指南
import UIKit

class ViewController: UIViewController {
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesBegan(touches, with: event)
        //1、POI城市检索
//        poiCitySearch()
        //2.POI周边检索对象
        poiNearbySearch()
    }
    
    ///1、POI城市检索
    func poiCitySearch() {
        //初始化POI城市检索对象
        let poiSearch:BMKPoiSearch = BMKPoiSearch()
        //设置POI城市检索代理
        //此处需要先遵循协议<BMKPoiSearchDelegate>
        poiSearch.delegate = self
        //构造POI城市检索参数
        let cityOption:BMKPOICitySearchOption = BMKPOICitySearchOption()
        //检索关键字,必选。举例:小吃
        cityOption.keyword = "小吃";
        //区域名称(市或区的名字,如北京市,海淀区),最长不超过25个字符,必选
        cityOption.city = "北京市";
        //检索分类,可选,与keyword字段组合进行检索,多个分类以","分隔。举例:美食,烧烤,酒店
        cityOption.tags = ["美食","烧烤"];
        //区域数据返回限制,可选,为YES时,仅返回city对应区域内数据
        cityOption.isCityLimit = true;
        //POI检索结果详细程度
        //cityOption.scope = BMK_POI_SCOPE_BASIC_INFORMATION;
        //检索过滤条件,scope字段为BMK_POI_SCOPE_DETAIL_INFORMATION时,filter字段才有效
        //cityOption.filter = filter;
        //分页页码,默认为0,0代表第一页,1代表第二页,以此类推
        cityOption.pageIndex = 0;
        //单次召回POI数量,默认为10条记录,最大返回20条
        cityOption.pageSize = 10;
        //发起POI城市检索请求
        let flag: Bool = poiSearch.poiSearch(inCity: cityOption)
        if flag {
            print("POI城市内检索成功")
        }else{
            print("POI城市内检索失败")
        }
    }
    ///2.POI周边检索对象
    func poiNearbySearch() {
        let poiSearch:BMKPoiSearch = BMKPoiSearch()
        poiSearch.delegate = self
        //初始化请求参数类BMKNearbySearchOption的实例
        let nearbyOption: BMKPOINearbySearchOption = BMKPOINearbySearchOption()
        //检索关键字,必选
        nearbyOption.keywords = ["小吃"];
        //检索中心点的经纬度,必选
        nearbyOption.location = CLLocationCoordinate2DMake(40.051231, 116.282051);
        //检索半径,单位是米。
        nearbyOption.radius = 1000;
        //检索分类,可选。
        nearbyOption.tags = ["美食"];
        //是否严格限定召回结果在设置检索半径范围内。默认值为false。
        nearbyOption.isRadiusLimit = false;
        //POI检索结果详细程度
        //nearbyOption.scope = BMK_POI_SCOPE_BASIC_INFORMATION;
        //检索过滤条件,scope字段为BMK_POI_SCOPE_DETAIL_INFORMATION时,filter字段才有效
        //nearbyOption.filter = filter;
        //分页页码,默认为0,0代表第一页,1代表第二页,以此类推
        nearbyOption.pageIndex = 0;
        //单次召回POI数量,默认为10条记录,最大返回20条。
        nearbyOption.pageSize = 10;
        let flag: Bool = poiSearch.poiSearchNear(by: nearbyOption)
        if flag {
            print("POI周边检索成功")
        }else{
            print("POI周边检索失败")
        }
    }
}

extension ViewController: BMKPoiSearchDelegate{
    /**
     *返回POI搜索结果
     *@param searcher 搜索对象
     *@param poiResult 搜索结果列表
     *@param errorCode 错误码,@see BMKSearchErrorCode
     */
    func onGetPoiResult(_ searcher: BMKPoiSearch!, result poiResult: BMKPOISearchResult!, errorCode: BMKSearchErrorCode) {
        if errorCode == BMK_SEARCH_NO_ERROR {
            //在此处理正常结果
            print("检索结果返回成功:\(poiResult.poiInfoList)")
        }else if errorCode == BMK_SEARCH_AMBIGUOUS_KEYWORD{
            print("检索词有歧义")
        }else{
            print("其他检索结果错误码相关处理")
        }
    }
}

相关文章

  • 地图和定位(五)

    一、导航 导航的三种方式: 1、使用系统APP导航 2、发送网络请求给苹果服务器获取导航路线 2.1、获取导航路线...

  • 定位和地图

    为了使用iOS中的地图和定位功能,我们需要使用Core Location和Map Kit,分别用于地理定位和地图展...

  • 自定义大头针

    定位和地图可以分开使用 配置时需要条件编译 //地图的头文件 #import //定位的头文件 #import /...

  • 集成百度地图遇到过的那些坑:(反geo检索发送失败)

    因为公司项目需求,需要集成百度地图实现定位功能和反地理编码功能。本人以前集成过百度地图完成过定位功能、地图显示和...

  • 高德API使用小结-定位和marker

    功能描述:实现一个普通的地图展示,地图上有当前定位小蓝点和门店定位Marker信息。当前定位需要从定位服务异步获取...

  • 基于fabric的地图定位,SVG热力地图

    基于fabric的地图定位,SVG热力地图 基于fabric的地图定位,SVG热力地图 基于 fabricjs v...

  • 地图定位的不显示

    苹果自带地图定位功能 地图定位 今天要做苹果自带地图定位功能,基于mapkit框架的。怎么也没有找到定位自己的位置...

  • 定位CoreLocation

    一、定位介绍 现在很多社交、电商、团购应用都引入了地图和定位功能,似乎地图功能不再是地图应用和导航应用所特有的。的...

  • iOS学习笔记19-地图(一)定位CoreLocation

    一、定位介绍 现在很多社交、电商、团购应用都引入了地图和定位功能,似乎地图功能不再是地图应用和导航应用所特有的。的...

  • iOS定位和地图

    一.定位 1.iOS8以后前台定位 A.代码 B.配置信息Info.plist 2.iOS8以后后台定位 A.代码...

网友评论

      本文标题:地图和定位(五)

      本文链接:https://www.haomeiwen.com/subject/tfmswqtx.html