zoukankan      html  css  js  c++  java
  • iOS 地图开发MapKit和CLLocation

    1,iOS 定位服务

      现在对iOS下的定组件建进行如下分类:

      1>,无限蜂窝定位,根据移动设备距离基站的位置来实现定位的。

      2>,GPS定位,也就是所谓的卫星定位,定位精确度较高,但是受遮盖环境影响较大,

      3>,无线wifi定位,根据定位路由器的位置,实现定位,

      4>,蓝牙beacon定位,定位精确度高,但是要求在外设的覆盖区域内

    下面我们主要讲讲iOS下面的定位吧,主要框架CoreLocation.framework,主要对象CLLocationManager,主要代理CLLocationManagerDelegate,我们先插入一段代码看看,

    //  请求定位服务
        self.locationManager = [[CLLocationManager alloc] init];
        //  locationServicesEnabled 是否启用定位服务,通常如果用户没有启用定位服务可以提示用户打开定位服务
        
        
        //  authorizationStatus定位服务授权的状态,返回值为枚举类型,其中
        //1.kCLAuthorizationStatusNotDetermined尚未做出决定是否开启定位服务
        //2.kCLAuthorizationStatusRestricted没有获得用户授权使用定位服务,可能是用户没有自己禁止访问授权
        //3.kCLAuthorizationStatusDenied 用户已经明确禁止应用使用定位服务或者当前系统定位服务处于关闭状态
        //4.kCLAuthorizationStatusAuthorizedAlways 应用获得授权可以一直使用定位服务,即使应用不在使用状态(不建议使用,这样太费流量,和浪费电量)
        //5.kCLAuthorizationStatusAuthorizedWhenInUse使用此应用过程中允许访问定位服务 (建议使用,节省能源,符合用户体验)
        if (![CLLocationManager locationServicesEnabled] || [CLLocationManager authorizationStatus] != kCLAuthorizationStatusAuthorizedWhenInUse) {
            [self.locationManager requestWhenInUseAuthorization];
        } else if([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedWhenInUse){
            //  设置定位对象的代理
            self.locationManager.delegate = self;
            //  desiredAccuracy这个属性是用来定位精度,是枚举类型
            /*
             kCLLocationAccuracyBest:最精确定位 (没有特殊需求,不推荐使用,因为精度越高,设备耗电量越大, 亲,根据需求,大家进行自足选择)
             CLLocationAccuracy kCLLocationAccuracyNearestTenMeters:十米误差范围
             kCLLocationAccuracyHundredMeters:百米误差范围
             kCLLocationAccuracyKilometer:千米误差范围
             kCLLocationAccuracyThreeKilometers:三千米误差范围
             */
            
            //  设置当前的定位管理器的精度为最精确定位
            _locationManager.desiredAccuracy=kCLLocationAccuracyBest;
            //  设置定位频率,每隔多少米定位一次
            CLLocationDistance distance = 10.0;
            
            //  distanceFilter位置更新的最小距离,只有移动大于这个距离才更新位置信息,默认为kCLDistanceFilterNone,不进行距离限制
            self.locationManager.distanceFilter = distance;
            //  启动更新定位
            [self.locationManager startUpdatingLocation];

    当这些设置定位的属性都设置并且开启定位之后,将会毁掉到下面的代理方法中

    #pragma mark CoreLocation 代理
    //  跟踪定位代理方法,每次位置发生变化就会执行(只要定位到相应的位置)
    - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
    {   //  取出变化之前的位置,是一个CLLocation对象类型(大家可以按住command点击这个对象,看这个对象里边的属性和方法)
        CLLocation *location = [locations firstObject];
        //  查看改位置的详细坐标信息
        CLLocationCoordinate2D coordinate = location.coordinate;
        NSLog(@"经度:%f, 纬度:%f, 海拔:%f, 航向:%f, 行走速度:%f", coordinate.longitude, coordinate.latitude, location.altitude, location.course, location.speed);
        //如果不需要实时定位,使用完及时关闭地位服务
        [self.locationManager stopUpdatingLocation];
        
    }
    - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
    {
        //定位失败会调用这个方法
    }

    这就是我们地图开发中经常要用的定位,但是蓝牙定位不是这个代理方法,蓝牙后面继续给大家讲解

    基本定位这就OK了,那么我们还要什么尼,单单一个地图定位是满足不了我们的需求的,地图开发怎么能没有地图啊,下面我门就来接入实现地图的代码

     self.mapView = [[MKMapView alloc] initWithFrame:self.view.bounds];//初始化并给定位置
    _mapView.userTrackingMode = MKUserTrackingModeFollow;//设置跟踪模式
        _mapView.mapType = MKMapTypeStandard;//设置地图样式
        [self.view addSubview:_mapView];//添加地图

    就这样似乎很简单的就实现了地图,但是就一个地图一个定位似乎还差点什么似的,地图标注的使用,也就是我们所谓的大头针了,没有这个地图开发基本是没用了,下面来看看怎么实现标注的,实现标注就不是那么这么几行代码的问题

    我们先来分析一下定位和标注的真正价值吧,

      1>,标注的使用,给一个地址定位出大头针在地图上面,而标注的创建过程如下,

    CustomAnnotation *annotation = [[CustomAnnotation alloc] initWithCoordinate:   
                                        coords];  //这个cpprds里面需要的就是经纬度
        annotation.title = @"标题";  
        annotation.subtitle = @"子标题";  
        [map addAnnotation:annotation];  

      我们看出创建标注需要一个经纬度,但是给了我们一个地址,没有所谓的经纬度,这样我们又引入了一个新的知识点,地理编码,即将地址转化成经纬度,

     CLLocation *location = [[CLLocation alloc] initWithLatitude:12.999 longitude:44.000];
        
        [self.geocoder reverseGeocodeLocation:location  completionHandler:^(NSArray *placemarks, NSError *error) {
            if (placemarks.count != 0) {
                NSLog(@"地理编码失败!");
            } else {
                for (CLPlacemark *placemark in placemarks) {
                    NSLog(@"name=%@ locality=%@ country=%@ postalCode=%@",placemark.name,placemark.locality,placemark.country,placemark.postalCode);
                    }
                //取出获取的地理信息数组中的第一个显示在界面上
                CLPlacemark *firstPlacemark=[placemarks firstObject];
                //详细地址名称
                self.detailAddressLabel.text=firstPlacemark.name;
                //纬度
                CLLocationDegrees latitude=firstPlacemark.location.coordinate.latitude;
                //经度
                CLLocationDegrees longitude=firstPlacemark.location.coordinate.longitude;
                self.latitudeLabel.text=[NSString stringWithFormat:@"%.2f",latitude];
                self.longitudeLabel.text=[NSString stringWithFormat:@"%.2f",longitude];
            }
        }];

      2>,定位的时候代理里面能返回给我们的是经纬度,但是我们可能给用户的是所在详细地址,那么我们应该讲经纬度转变成详细地址,这个过程运用到了反地理编码过程

      地理反编码过程如下,

     CLLocation *location = [[CLLocation alloc] initWithLatitude:12.999 longitude:44.000];
        
        [self.geocoder reverseGeocodeLocation:location  completionHandler:^(NSArray *placemarks, NSError *error) {
            if (placemarks.count != 0) {
                NSLog(@"地理编码失败!");
            } else {
                for (CLPlacemark *placemark in placemarks) {
                    NSLog(@"name=%@ locality=%@ country=%@ postalCode=%@",placemark.name,placemark.locality,placemark.country,placemark.postalCode);
                    }
                //取出获取的地理信息数组中的第一个显示在界面上
                CLPlacemark *firstPlacemark=[placemarks firstObject];
                //详细地址名称
                self.detailAddressLabel.text=firstPlacemark.name;
                //纬度
                CLLocationDegrees latitude=firstPlacemark.location.coordinate.latitude;
                //经度
                CLLocationDegrees longitude=firstPlacemark.location.coordinate.longitude;
                self.latitudeLabel.text=[NSString stringWithFormat:@"%.2f",latitude];
                self.longitudeLabel.text=[NSString stringWithFormat:@"%.2f",longitude];
            }
        }];

    那么iOS地图里面主要的内容就到这里了,里面还有一些自定义图层什么的就留着大家满满研究了,谢谢各位的支持!

  • 相关阅读:
    ie6,ie7,ie8 css bug汇总以及兼容解决方法
    关于ie6下的双倍浮动
    团队合作,如何避免js冲突
    实例探索Class文件
    MFC获得本机的IP
    MessageBox英文显示OK/Cancel(适用于中英文界面)
    基于OpenCV的程序脱离动态链接库运行方法 (此方法也可用于将opencv源码编译成一个链接库)
    将摄像头原始RGB数据流编码成H.264文件
    在线程中创建非模态对话框——解决对话框创建一闪就消失问题
    .NET预处理器指令
  • 原文地址:https://www.cnblogs.com/zouhaoit/p/4441795.html
Copyright © 2011-2022 走看看