zoukankan      html  css  js  c++  java
  • 定位处理与地图

    一、定位处理

    定位管理主要是通过GPS、蜂窝基站三角网、WiFi三种方式实现。

    ios8系统下使用定位服务必须在info.plist中添加两条变量:

    分别用于描述程序始终使用和使用期间使用定位的说明。对应手机设置中定位服务中的始终和使用应用程序期间两个选项。

    1、在项目中引入框架CoreLoaction.framework。

    2、创建一个定位服务管理类CLLocationManager来创建一个位置管理器,提供位置信息和高度信息,也可以监控进入和离开某个区域,还可以获得设备的运行方向。遵循代理

    CLLocationManagerDelegate。

    //定义坐标坐标
        var currLocation : CLLocation!
    //创建位置管理器,用于定位服务管理类,它能够给我们提供位置信息和高度信息,也可以监控设备进入或离开某个区域,还可以获得设备的运行方向
        let locationManager : CLLocationManager = CLLocationManager()
    //指定代理
            locationManager.delegate = self
            
            //精确到1000米,距离过滤器,定义了设备移动后获得位置信息的最小距离
            locationManager.distanceFilter = kCLLocationAccuracyBest
            
            //通过数字设置距离
    //        locationManager.distanceFilter = 200
            
            //发出授权申请
            //NSLocationAlwaysUsageDescription 和 NSLocationWhenInUseUsageDescription 。至于在plist添加的方法,就是在plist中添加一个键值对,然后把请求允许对应的Key值复制粘贴进去就可以了。value值是什么都可以,这个值会在请求允许的对话框中显示出来给用户看。总之是你自己定的。
            locationManager.requestAlwaysAuthorization()
            
            //更新位置
            locationManager.startUpdatingLocation()
            
            //更新方向
            locationManager.startUpdatingHeading()
            
            print("定位开始")

    通过didChangeAuthorizationStatus代理方法,可以获得设备是否允许使用定位服务。

    //代理方法--判断是否可以使用定位服务
        func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus)
        {
            if status == CLAuthorizationStatus.NotDetermined || status == CLAuthorizationStatus.Denied
            {
                //允许使用定位服务
                //开始启动定位服务更新
                locationManager.startUpdatingLocation()
                //更新方向
                locationManager.startUpdatingHeading()
                print("定位开始")
            }
        }

    定位改变时委托会执行这个方法,通过定义一个CLLocation坐标对象来接收坐标值。

    //距离改变就会收到该委托方法,获取地理位置信息
        func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
        {
            //获取最新坐标
            currLocation = locations.last
            //获取经度
            longitudeTxt.text = "(currLocation.coordinate.longitude)"
            //获取纬度
            latitudeTxt.text = "(currLocation.coordinate.latitude)"
            //获取高度
            HeightTxt.text = "(currLocation.altitude)"
        }

    两个坐标之间的距离可以通过func distanceFromLocation(other:Double) ->Double方法得到:

    //计算两点之间距离
            let currentLocation = CLLocation(latitude: 53.204526, longitude: 50.111751)
            let targetLocation = CLLocation(latitude: 53.203715, longitude: 50.160374)
            let distance:CLLocationDistance  = currentLocation.distanceFromLocation(targetLocation);
            print("两点间距离是:(distance)")

    通过方法:func locationManager(manager: CLLocationManager, didUpdateHeading newHeading: CLHeading)可以获取设备移动的方向,通过一组属性提供航向读数:

    magneticHeading(磁场航向)和trueHeading(真实航向),如果航向为0.0,则前进方向为北;如果航向为90.0,则前进方向为东;如果航向为180.0,则前进方向为南;如果航向为270.0,则前进方向为西;只有打开定位服务才可以获得真实航向。

    代码实现:

    //获取方向
        func locationManager(manager: CLLocationManager, didUpdateHeading newHeading: CLHeading)
        {
            headingLabel.text = "(newHeading.trueHeading) degrees (true), (newHeading.magneticHeading)degrees (magnetic)"
            print( headingLabel.text)
        }

    定位出现错误时会调用下面的委托方法:

    func locationManager(manager: CLLocationManager, didFailWithError error: NSError)
        {
            print(error)
            if let clErr = CLError(rawValue: error.code){
                switch clErr {
                case .LocationUnknown:
                    print("位置不明")
                case .Denied:
                    print("允许检索位置被拒绝")
                case .Network:
                    print("用于检索位置的网络不可用")
                default:
                    print("未知的位置错误")
                }
            } else {
                print("其他错误")
                let alert = UIAlertView(title: "提示信息", message: "定位失败", delegate: nil, cancelButtonTitle: "确定")
                alert.show()
            }
        }

    对于得到的定位信息我们需要把经纬度信息,反编码成一个地址,这里需要用到CLGeocoder类来实现地理反编码。

    //地理信息反编码
        @IBAction func reverseGeocode(sender: AnyObject) {
            let geocoder = CLGeocoder()
            var p:CLPlacemark?
            geocoder.reverseGeocodeLocation(currLocation, completionHandler: { (placemarks, error) -> Void in
      
            // 强制 成 简体中文
            let array = NSArray(object: "zh-hans")
            NSUserDefaults.standardUserDefaults().setObject(array, forKey: "AppleLanguages")
            
            // 显示所有信息
            if error != nil {
                    print("reverse geodcode fail: (error!.localizedDescription)")
                    return
                }
                
                let pm = placemarks
                if (pm!.count > 0){
                    p = placemarks![0]
                    print(p)//输出反编码信息
                    
                     print("country = (p?.country)")
                    print("postalCode = (p?.postalCode)")
                    print("location = (p?.location)")
                    
                }else{
                    print("No Placemarks!")
                }
            })
        }
    //地理信息编码
        @IBAction func locationBianMa ()
        {
            //使用Google 服务进行地理编码
            let geocoder = CLGeocoder()
            var p:CLPlacemark?
            geocoder.geocodeAddressString("北京海淀区北三环西路39号", completionHandler: { (placemarks, error) -> Void in
                
                if error != nil {
                    print("reverse geodcode fail: (error!.localizedDescription)")
                    return
                }
                
                let pm = placemarks
                if (pm!.count > 0){
                    p = placemarks![0]
                    
                    print("Longitude = (p?.location!.coordinate.longitude)")
                    print("Latitude = (p?.location!.coordinate.latitude)")
                    
                    
                    print(p)
                }else{
                    print("No Placemarks!")
                }
                
            })
        }

    二、地图

    通过MapKit可以把地图嵌入到视图中,MapKit框架主要提供了四个功能:显示地图、CLLocation和地址之间的转换、支持在地图上做标记、把一个位置解析成地址。

    首先导入MapKit.framework框架,通过代码或者静态创建MKMapView对象,可以显示地图。

    // MARK: - Map
        @IBOutlet var mainMapView: MKMapView!
        @IBAction func showMap() {
    
            //使用代码创建地图
    //        let mapView: MKMapView =  MKMapView(frame: CGRectMake(0, 0, 320, 200))
    //        self.view.addSubview(mapView)
            
            //创建一个MKCoordinateSpan对象,设置地图的范围 越小越精确
            let latDelta = 0.05
            let longDelta = 0.05
            let currentLocationSpan: MKCoordinateSpan = MKCoordinateSpanMake(latDelta, longDelta)
    
            //定义一个区域,坐标使用定位获取的当前坐标locationManager.location.coordinate
            let currentRegion: MKCoordinateRegion = MKCoordinateRegionMake(locationManager.location!.coordinate, currentLocationSpan)
            
            //设置显示区域
            self.mainMapView.setRegion(currentRegion, animated: true)
            
            //设置地图显示类型,标准地图、卫星模式、混合模式。
            self.mainMapView.mapType = MKMapType.Standard //标准地图
            
            //设置代理
            self.mainMapView.delegate = self
            
            //创建一个大头针对象
            let objectAnnotation = MKPointAnnotation()
            
            //设置大头针显示位置,我们使用定位到的坐标
            objectAnnotation.coordinate = locationManager.location!.coordinate
            
            //设置点击大头针之后显示的标题
            objectAnnotation.title = "北京海淀"
            
            //设置点击大头针之后显示的描述
            objectAnnotation.subtitle = "北三环西路"
            
            //添加大头针
            self.mainMapView.addAnnotation(objectAnnotation)
        }

    代理方法:

    // MARK: - MKMapViewDelegate
        func mapView(mapView: MKMapView, regionWillChangeAnimated animated: Bool){
            //地图的缩放级别发生改变时,
        }
        
        func mapView(mapView: MKMapView, regionDidChangeAnimated animated: Bool){
            //地图的缩放完毕触发
        }
        
        func mapViewWillStartLoadingMap(mapView: MKMapView){
            //开始装载地图
        }
        
        func mapViewDidFinishLoadingMap(mapView: MKMapView){
            //结束装载地图
        }
        
        func mapViewDidFailLoadingMap(mapView: MKMapView, withError error: NSError){
            //装载失败
        }
        
        func mapViewWillStartRenderingMap(mapView: MKMapView){
            //开始渲染下载的地图块时调用
        }
        
        func mapViewDidFinishRenderingMap(mapView: MKMapView, fullyRendered: Bool){
            //渲染下载的地图结束时调用
        }
        
        
        //自定义大头针样式
        func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView?{
            if annotation is MKUserLocation {
                //return nil so map view draws "blue dot" for standard user location
                return nil
            }
            
            let reuseId = "pin"
            
            var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId) as? MKPinAnnotationView
            
            if pinView == nil {
                
                //创建一个大头针视图
                pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
                
                pinView!.canShowCallout = true
                
                pinView!.animatesDrop = true
                
                 //设置大头针颜色
                pinView!.pinColor = .Purple
                
                //设置大头针点注释视图的右侧按钮样式
                pinView!.rightCalloutAccessoryView = UIButton(type: UIButtonType.DetailDisclosure)
            }
            else {
                pinView!.annotation = annotation
            }
            return pinView
        }
        
        func mapView(mapView: MKMapView, didAddAnnotationViews views: [MKAnnotationView]){
            //添加注释视图
        }
        
        func mapView(mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl){
            
        }
        
        func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView){
            //点击大头针注释视图
        }
        
        func mapView(mapView: MKMapView, didDeselectAnnotationView view: MKAnnotationView){
            //取消点击大头针注释视图
        }
        
        func mapViewWillStartLocatingUser(mapView: MKMapView){
            //正在跟踪用户的位置
        }
        
        func mapViewDidStopLocatingUser(mapView: MKMapView){
            //停止跟踪用户的位置
        }
        
        func mapView(mapView: MKMapView, didUpdateUserLocation userLocation: MKUserLocation){
            //更新用户的位置
        }
        
        func mapView(mapView: MKMapView, didFailToLocateUserWithError error: NSError){
            //跟踪用户的位置 失败
        }
        
        func mapView(mapView: MKMapView, annotationView view: MKAnnotationView, didChangeDragState newState: MKAnnotationViewDragState, fromOldState oldState: MKAnnotationViewDragState){
            //移动annotation位置时调用。newState为宏,表示几个状态。是否能移动位置在annotation中设置。
        }
        
        func mapView(mapView: MKMapView, didChangeUserTrackingMode mode: MKUserTrackingMode, animated: Bool){
         
            //改变UserTrackingMode
        }
        
        func mapView(mapView: MKMapView, rendererForOverlay overlay: MKOverlay) -> MKOverlayRenderer{
            //设置overlay的渲染
            return MKOverlayRenderer()
        }
        
        func mapView(mapView: MKMapView, didAddOverlayRenderers renderers: [MKOverlayRenderer])
        {
            //地图上加上了overlayRenderers后调用
        }
  • 相关阅读:
    linux多线程学习笔记五--线程安全【转】
    linux多线程学习笔记六--一次性初始化和线程私有数据【转】
    【Linux】可重入函数和线程安全的区别与联系【转】
    【Linux】自主实现my_sleep【转】
    Linux/Unix编程中的线程安全问题【转】
    C语言字符串操作总结大全(超详细)【转】
    linux中的strip命令简介------给文件脱衣服【转】
    FTK应用程序编程接口(API)手册-1【转】
    python编程(python开发的三种运行模式)【转】
    ftk学习记(label篇)【转】
  • 原文地址:https://www.cnblogs.com/fengmin/p/5718414.html
Copyright © 2011-2022 走看看