美文网首页
初识iOS 定位

初识iOS 定位

作者: gale_小米 | 来源:发表于2022-05-05 09:47 被阅读0次
    1. CClocationManager 用于启动和停止向应用程序传递位置相关事件的对象。
    2. CCLocation 表示地理坐标以及精度和时间戳信息。
        override func viewDidLoad() {
            super.viewDidLoad()
           if CLLocationManager.locationServicesEnabled() { //判断设备是否支持定位服务
                self.loationManager = CLLocationManager()
                //设置定位到精确度
                self.loationManager?.desiredAccuracy = kCLLocationAccuracyBest 
                self.loationManager?.distanceFilter = 50  //设置定位距离
                if #available(iOS 8.0, *){
                    print("\(UIDevice.current.systemVersion)")
                    //self.loationManager?.requestWhenInUseAuthorization()  // 设置启用时间
                    self.loationManager?.requestAlwaysAuthorization()  //一直启用
                }
                self.loationManager?.delegate = self
                self.loationManager?.startUpdatingLocation()    //开启定位
            }
     }
     //定位失败
        func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
            print("locationManager =\(error.localizedDescription)")
        }
    //定位成功
        func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
            if locations.count > 0 {
                //获取最新的定位信息
                let locationInfo:CLLocation = locations.last! as CLLocation
                let alertView = UIAlertController(title: "定位成功", message: "当前位置\(locationInfo.coordinate.longitude),\(locationInfo.coordinate.latitude)", preferredStyle: UIAlertController.Style.alert)
                            alertView.addAction(UIAlertAction(title: "确定", style: UIAlertAction.Style.cancel, handler: { alertView in
                                self.dismiss(animated: true, completion: nil)
                            }))
                            self.present(alertView, animated: true, completion: nil)
           }
       }
    

    3.CLPlacemark 表示地理位置的位置标记数据。地名数据可以是国家、州、城市和街道地址等信息。
    4.CLGeocoder 用于在地理坐标和地名之间转换的接口。

           //解析地理位置
                            let gl:CLGeocoder = CLGeocoder()
                            //根据经纬度编码当前位置信息
                            gl.reverseGeocodeLocation(locationInfo) { (array : [CLPlacemark]!, err : Error!) in
                                if array.count > 0 {
                                    //这里可能会存在多个位置需要根据实际需求选择
                                    let placmark:CLPlacemark = array.last! as CLPlacemark
                                    //print("placmarks = \(placmark.location) ,\(placmark.region)")
                                    let alertView = UIAlertController(title: "定位成功", message: "当前位置\(placmark.country!.description),\(placmark.administrativeArea!.description),\(placmark.locality!.description),\(placmark.thoroughfare!.description),\(placmark.timeZone!.description)", preferredStyle: UIAlertController.Style.alert)
                                    alertView.addAction(UIAlertAction(title: "确定", style: UIAlertAction.Style.cancel, handler: { alertView in
                                        self.dismiss(animated: true, completion: nil)
                                    }))
                                    self.present(alertView, animated: true, completion: nil)
                                }
                            }
    

    5.添加锚点,区域,水印

    /*设置精确位置*/
        func locationLatitudeAndLongitude(latitude:Double ,longitude:Double){
            let coordinate2d:CLLocationCoordinate2D = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
            //设置一个精确范围,值越小精确度越高
            let span :MKCoordinateSpan = MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta:0.01)
            let region:MKCoordinateRegion = MKCoordinateRegion(center: coordinate2d, span: span)
          //定位到点
            self.mapView?.setRegion(region, animated: true)
     //定位大致区域
    //        let mapRect:MKMapRect = MKMapRect(origin: MKMapPoint(coordinate2d), size: MKMapSize(width: 1000.0, height: 1000.0))
    //        self.mapView?.setVisibleMapRect(mapRect, animated: true)
            //添加锚点
        //        let annotaion:MKPointAnnotation = MKPointAnnotation()
        //        annotaion.coordinate = coordinate2d
        //        annotaion.title = "我在这"
        //        annotaion.subtitle = "i am gale"
        //        self.mapView?.addAnnotation(annotaion)
        }
    
        @objc func mapViewTap(gesture:UILongPressGestureRecognizer){
            if gesture.state == .began {
                //获取屏幕的物理坐标
                let point:CGPoint = gesture.location(in: self.mapView)
                //把物理坐标点转换为coor
                let coor:CLLocationCoordinate2D = self.mapView!.convert(point, toCoordinateFrom: self.mapView)
                //定义一个覆盖层
                let overLay:MKCircle = MKCircle(center: coor, radius: 100)
                self.mapView?.addOverlay(overLay)
                /*
                            // 添加水印
                            let url:URL = Bundle.main.url(forResource: "test", withExtension: "jpeg")!
                            let titleOverlay:MKTileOverlay = MKTileOverlay(urlTemplate: url.description)
                            self.mapView?.addOverlay(titleOverlay)
                            */
            }
        }
    
       //创建真正的图层
        func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
    //        //定义图层级
    //        let circle:MKCircleRenderer = MKCircleRenderer(circle: overlay as! MKCircle)
    //        circle.fillColor = UIColor.brown
    //        circle.strokeColor = UIColor.clear
    //        circle.alpha = 0.3
    //        return circle
            //定义水印图层
            let titleRenderer = MKTileOverlayRenderer(overlay: overlay as! MKTileOverlay)
            titleRenderer.alpha = 0.1
            return titleRenderer
        }
    

    6.开启方向识别

            let lineView = UIView(frame: CGRect(x: screenWidth/2, y:0, width: 0.5, height: screenHeight))
            lineView.backgroundColor = .black
            self.view.addSubview(lineView)
            
            
            self.compassLayer = CALayer()
            self.compassLayer?.frame = CGRect(x:( screenWidth - 50)/2, y: ( screenHeight - 50)/2, width: 50, height: 50)
            //把图片显示到layer上
            self.compassLayer?.contents = UIImage(named: "icon-info")?.cgImage
            self.view.layer.addSublayer(self.compassLayer!)
            if CLLocationManager.headingAvailable() {
                print("headingAvailable is ture")
                self.loationManager = CLLocationManager()
                self.loationManager?.delegate = self
                self.loationManager?.startUpdatingHeading()//开启方向识别
            }
    
     func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) {
            let heding:Double = -1 * M_1_PI * newHeading.magneticHeading / 180.0 //将设备方向转换为弧度
            //print("didUpdateHeading \(heding)")
            let rocationAnimation:CABasicAnimation = CABasicAnimation(keyPath: "transform")
            let fromValue:CATransform3D = self.compassLayer!.transform
            rocationAnimation.fromValue = NSValue(caTransform3D: fromValue)
            let toValue:CATransform3D = CATransform3DMakeRotation(CGFloat(heding), 0.0, 0.0, 1.0)
            rocationAnimation.toValue = NSValue(caTransform3D: toValue)
            rocationAnimation.duration = 0.2
            //动画结束后移除动画
            rocationAnimation.isRemovedOnCompletion = true
            self.compassLayer?.transform = toValue
            //添加动画
            self.compassLayer?.add(rocationAnimation, forKey: nil)
        }
        //允许开启定位方向识别
        func locationManagerShouldDisplayHeadingCalibration(_ manager: CLLocationManager) -> Bool {
            return true
        }
    

    7.简易导航系统

    import UIKit
    import CoreLocation
    import MapKit
    
    class ViewController: UIViewController,CLLocationManagerDelegate,MKMapViewDelegate{
        var loationManager:CLLocationManager?
        var mapView:MKMapView?
        //出发地
        var startTextFiled:UITextField?
        var endTextFiled:UITextField?
        var startButton:UIButton?
        var gl:CLGeocoder?
        //记录起始位置信息
        var startCLPlacemark:CLPlacemark?
        var mLocationInfo:CLLocation?
        //线路图
        var navigationPath: MKPolyline?
        //添加锚点
        var annotations = Array<MKAnnotation>()
        
        override func viewDidLoad() {
            super.viewDidLoad()
            if CLLocationManager.locationServicesEnabled() { //判断设备是否支持定位服务
                self.loationManager = CLLocationManager()
                self.loationManager?.desiredAccuracy = kCLLocationAccuracyBest //设置定位到精确度
                self.loationManager?.distanceFilter = 50  //设置定位距离
                if #available(iOS 8.0, *){
                    print("\(UIDevice.current.systemVersion)")
                    //self.loationManager?.requestWhenInUseAuthorization()  // 设置启用时间
                    self.loationManager?.requestAlwaysAuthorization()  //一直启用
                }
                self.loationManager?.delegate = self
                //是否开启定位
                let status: CLAuthorizationStatus = CLLocationManager.authorizationStatus()
                /**
                  * <key>NSLocationWhenInUseUsageDescription</key>
              *<string>应用程序在前台运行时请求访问用户位置信息</string>
              *<key>NSLocationAlwaysUsageDescription</key>
              *<string>应用程序总是请求访问用户的位置</string>
                  */
                if ( status == .authorizedAlways ||
                     status == .authorizedWhenInUse){
                    self.loationManager?.startUpdatingLocation()    //开启定位
                }
            }
             
            let screenWidth = UIScreen.main.bounds.width
            let screenHeight = UIScreen.main.bounds.height
            //初始化地图控件
            self.mapView = MKMapView(frame: CGRect(x: 0, y: 0, width: screenWidth, height: screenHeight))
            self.mapView?.mapType = .standard //标准导航
            self.mapView?.isScrollEnabled = true
            self.mapView?.isZoomEnabled = true
            self.mapView?.isRotateEnabled = true
            self.mapView?.delegate = self
            
            self.view.addSubview(self.mapView!)
            
            self.startTextFiled = UITextField(frame: CGRect(x: 10, y: 50, width: 120, height: 50))
            self.startTextFiled?.borderStyle = .roundedRect
            self.startTextFiled?.font = UIFont.systemFont(ofSize: CGFloat(12))
            self.startTextFiled?.textColor = UIColor.white
            self.startTextFiled?.placeholder = "出发地"
            
            self.endTextFiled = UITextField(frame: CGRect(x: 150, y: 50, width: 120, height: 50))
            self.endTextFiled?.borderStyle = .roundedRect
            self.endTextFiled?.font = UIFont.systemFont(ofSize: CGFloat(12))
            self.endTextFiled?.textColor = UIColor.white
            self.endTextFiled?.placeholder = "目的地"
            
            self.startButton = UIButton(frame: CGRect(x: 280, y: 50, width: 80, height: 50))
            self.startButton?.titleLabel?.font = UIFont.systemFont(ofSize: CGFloat(12))
            self.startButton?.layer.cornerRadius = 5.0
            self.startButton?.layer.borderWidth = 0.5
            self.startButton?.layer.borderColor = UIColor.black.cgColor
            self.startButton?.setTitle("开始导航", for: UIControl.State.normal)
            self.view.addSubview(self.startTextFiled!)
            self.view.addSubview(self.endTextFiled!)
            self.view.addSubview(self.startButton!)
            
            self.startButton?.addTarget(self, action: #selector(self.startGeocodeAddress(sender:)), for: UIControl.Event.touchUpInside)
            self.gl = CLGeocoder()
            
        }
    
     func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
            switch status {
            case .notDetermined:
                print("用户尚未对此应用程序做出选择")
            case .restricted:
                print("系统定位服务功能被限制")
            case .denied:
                print("用户禁止访问定位")
            case .authorizedAlways:
                self.loationManager?.startUpdatingLocation()    //开启定位
            case .authorizedWhenInUse:
                self.loationManager?.startUpdatingLocation()    //开启定位
            case .authorized:
                self.loationManager?.startUpdatingLocation()    //开启定位
            @unknown default:
                print("unknown")
            }
        }
        
        @objc func startGeocodeAddress(sender : AnyObject){
            self.startTextFiled?.resignFirstResponder()
            self.endTextFiled?.resignFirstResponder()
            if self.startTextFiled!.text!.isEmpty || self.endTextFiled!.text!.isEmpty {
                let alertView = UIAlertController(title: nil, message: "出发地或者目的地为空", preferredStyle: UIAlertController.Style.alert)
                alertView.addAction(UIAlertAction(title: "确定", style: UIAlertAction.Style.cancel, handler: { _ in
                    self.dismiss(animated: true, completion: nil)
                }))
                self.present(alertView, animated: true, completion: nil)
            }else {
                //print("startTextFiled=\(self.startTextFiled!.text!.description) ,endTextFiled=\(self.endTextFiled!.text!.description)")
                if self.startTextFiled!.text?.description == "我的位置" {
                    self.gl?.reverseGeocodeLocation(self.mLocationInfo!, completionHandler: {(placemarks:[CLPlacemark]!, err: Error! ) in
                        if placemarks.count > 0{
                            let startPlaceMark:CLPlacemark =  placemarks[0] as CLPlacemark
                            //print(" start locality= \(startPlaceMark.locality!.description)")
                            self.startCLPlacemark = startPlaceMark
                            //滚动到指定位置
                            self.locationLatitudeAndLongitude(latitude: self.startCLPlacemark!.location!.coordinate.latitude, longitude: self.startCLPlacemark!.location!.coordinate.longitude)
                            self.annotations.append(self.addMapViewAnnotaion(latitude: self.startCLPlacemark!.location!.coordinate.latitude, longitude: self.startCLPlacemark!.location!.coordinate.longitude, title: "出发地"))
                            //编码目的地
                            self.gl!.geocodeAddressString(self.endTextFiled!.text!.description, completionHandler: { (placemarks:[CLPlacemark]!, err: Error! ) in
                                if placemarks.count > 0{
                                    let endPlaceMark:CLPlacemark =  placemarks[0] as CLPlacemark
                                    //print(" end locality= \(endPlaceMark.locality!.description)")
                                    self.startNavigation(endPlaceMark: endPlaceMark)
                                }
                            })
                        }
                    })
                }else {
                    //编码出发地
                    self.gl!.geocodeAddressString(self.startTextFiled!.text!.description, completionHandler: {(placemarks:[CLPlacemark]!, err: Error! ) in
                        if placemarks.count > 0{
                            let startPlaceMark:CLPlacemark =  placemarks[0] as CLPlacemark
                            self.startCLPlacemark = startPlaceMark
                            self.locationLatitudeAndLongitude(latitude: self.startCLPlacemark!.location!.coordinate.latitude, longitude: self.startCLPlacemark!.location!.coordinate.longitude)
                            self.annotations.append(self.addMapViewAnnotaion(latitude: self.startCLPlacemark!.location!.coordinate.latitude, longitude: self.startCLPlacemark!.location!.coordinate.longitude, title: "出发地"))
                            //编码目的地
                            self.gl!.geocodeAddressString(self.endTextFiled!.text!.description, completionHandler: { (placemarks:[CLPlacemark]!, err: Error! ) in
                                if placemarks.count > 0{
                                    let endPlaceMark:CLPlacemark =  placemarks[0] as CLPlacemark
                                    self.startNavigation(endPlaceMark: endPlaceMark)
                                }
                            })
                        }
                    })
                }
            }
        }
        
        //正式启动导航
        func startNavigation(endPlaceMark:CLPlacemark){
            //移除上次定位地图
            if(self.navigationPath != nil){
                self.mapView?.removeOverlay(self.navigationPath!)
            }
            self.annotations.append(self.addMapViewAnnotaion(latitude: endPlaceMark.location!.coordinate.latitude, longitude: endPlaceMark.location!.coordinate.longitude, title: "目的地"))
            self.mapView?.addAnnotations(self.annotations)
            //设置出发地和目的地
            let request:MKDirections.Request  = MKDirections.Request()
            let mkPlacemark:MKPlacemark = MKPlacemark(placemark: self.startCLPlacemark!)
            request.source = MKMapItem(placemark: mkPlacemark)
            let endMkPlacemark:MKPlacemark = MKPlacemark(placemark: endPlaceMark)
            request.destination = MKMapItem(placemark: endMkPlacemark)
            
            let direction:MKDirections = MKDirections(request: request)
            direction.calculate { (response:MKDirections.Response!, err:Error!) in
                print("------routes------\(response.routes.count)")
                //这里应该会有多条线路,测试时取其中一条
                let route:MKRoute = response.routes[0] as MKRoute
                self.navigationPath =  route.polyline
                //添加地图线路
                self.mapView!.addOverlay(self.navigationPath!, level: MKOverlayLevel.aboveLabels)
            }
        }
       
        //定位失败
        func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
            print("locationManager =\(error.localizedDescription)")
        }
    
        /*设置精确位置*/
        func locationLatitudeAndLongitude(latitude:Double ,longitude:Double){
            let coordinate2d:CLLocationCoordinate2D = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
            //设置一个精确范围,值越小精确度越高
            let span :MKCoordinateSpan = MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta:0.01)
            let region:MKCoordinateRegion = MKCoordinateRegion(center: coordinate2d, span: span)
            self.mapView?.setRegion(region, animated: true)
        }
        
        
        // 添加锚点
        func addMapViewAnnotaion(latitude:Double ,longitude:Double,title:String) -> MKPointAnnotation{
            let annotaion:MKPointAnnotation = MKPointAnnotation()
            let coordinate2d:CLLocationCoordinate2D = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
            annotaion.coordinate = coordinate2d
            annotaion.title = title
            return annotaion
        }
     
        func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
            let mkpolyLine = MKPolylineRenderer(overlay: overlay as! MKPolyline)
            mkpolyLine.lineWidth = 5
            mkpolyLine.strokeColor = UIColor.blue
            return mkpolyLine
        }
        
        //定位成功
        func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
            if locations.count > 0 {
                //获取最新的定位信息
                let locationInfo:CLLocation = locations.last! as CLLocation
                //设置到指定位置
                self.locationLatitudeAndLongitude(latitude: locationInfo.coordinate.latitude, longitude: locationInfo.coordinate.longitude)
                self.startTextFiled?.text = "我的位置"
                self.mLocationInfo = locationInfo
            }
        }
        
        func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
            print("viewFor annotation")
            let identy:String = "identy"
            var pinView:MKPinAnnotationView? = mapView.dequeueReusableAnnotationView(withIdentifier: identy) as? MKPinAnnotationView
            
            if pinView == nil {
                pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identy)
            }
            if annotation.title == "出发地" {
                pinView?.pinTintColor = UIColor.green
            }else {
                pinView?.pinTintColor = UIColor.red
            }
            return pinView
        }
    }
    
    image.png

    相关文章

      网友评论

          本文标题:初识iOS 定位

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