现在的移动设备很多都提供定位服务功能,使用iOS系统的iPhone,iPad,iPod touch都可以提供定位服务,iOS设备能提供4种不同途径进行定位.
Wifi定位: 通过查询一个Wifi路由器的地理位置的信息,比较省电.iPhone,iPad,iPod touch都可以采用.
蜂窝式移动电话基站定位: 通过移动运营商基站定位.只有iPhone,3G版本的iPod touch 和 iPad 采用.
GPS卫星定位:通过3~4颗GPS卫星位置定位最为准确,但是耗电量大,不能遮挡.iPhone,iPad,iPod touch都可以采用.
微定位:通过基于iBeacon技术实现.
iOS不想android系统在定位服务编程的时候,可以指定采用那种途径进行定位.iOS的API把这些底层细节屏蔽了,开发人员和用户并不知道现在设备采用哪种方式进行定位,iOS系统会根据设备的情况和周围的环境采用一套最佳的解决方案.这个方案是这样的:如果能接收GPS信息,那么设备优先采用GPS定位,否则采用WIFI或蜂窝基站定位,在WIFI和蜂窝基站之间优先使用WIFI,如果无法连接WIFI才使用蜂窝基站定位.
总体来说,GPS定位的优点是准确,覆盖面广阔,缺点是不能被遮挡,GPS开启后比较费电.蜂窝基站不仅误差比较大,而且会耗费用户流量费,而WIFI定位应该是最经济实惠的.
定位服务编程
主要使用CoreLocation框架,定位时主要使用CLLocationManager,CLLocationManagerDelegate和CLLocation.CLLocationManager是定位服务管理类,它能够获得设备的位置信息和高度信息,也可以监控设备进入或离开某个区域.他还可以帮助获得设备的运行方向等.CLLocation封装了位置和高度信息.
<span style="font-size:18px;">- (void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; [self.locationManager startUpdatingLocation]; } - (void)viewWillDisappear:(BOOL)animated{ [super viewWillDisappear:animated]; [self.locationManager stopUpdatingLocation]; } - (void)viewDidLoad { [super viewDidLoad]; self.locationManager = [[CLLocationManager alloc]init]; self.locationManager.delegate = self; self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;//确定精度 /** kCLLocationAccuracyBestForNavigation 最高精度,这种级别用于导航程序,一般要有外接电源时候才能使用 kCLLocationAccuracyBest 最高精度,设备使用电池供电的时候 kCLLocationAccuracyHundredMeters 精度为100米内 kCLLocationAccuracyKilometer 精度到公里范围内 kCLLocationAccuracyNearestTenMeters 精度到10米内 kCLLocationAccuracyThreeKilometers 精度到3公里范围内 */ self.locationManager.distanceFilter = 1000.0f; } - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{ CLLocation *currLocation = [locations lastObject];//获得当前设备位置 self.txtLat.text = [NSString stringWithFormat:@"%3.5f",currLocation.coordinate.latitude]; self.txtLng.text = [NSString stringWithFormat:@"%3.5f",currLocation.coordinate.longitude]; self.txtAlt.text = [NSString stringWithFormat:@"%3.5f",currLocation.altitude]; } - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{ NSLog(@"error : %@",error); } </span>
地理信息反编码就是根据给定地点的地理坐标,返回这个地点的相关文字描述信息,这些文字封装在CLPlacemark类中,这个类叫做"地标类",地标类有很多属性
1.addressDictionary 地址信息的字典,包含一些键值对,其中的键是在Address Book frameWork(地址簿框架)中定义好的
2.ISOcountryCode ISO国家代号
3.country 国家信息
4.postalCode 邮政编码
5.administrativeArea 行政区域信息
6.subAdministrativeArea 行政区域附加信息
7.locality 指定城市信息
8.subLocality 指定城市信息附加信息
9.thoroughfare 指定街道级别信息
10.subThoroughfare 指定街道级别的附加信息
地理信息反编码使用CLGeocoder类实现.这个类能够实现在地理坐标与地理文字描述信息之间的转换.
<span style="font-size:18px;"> - (IBAction)reverseGeocode:(UIButton *)sender { CLGeocoder *geocoder = [[CLGeocoder alloc]init]; [geocoder reverseGeocodeLocation:self.currLocation completionHandler:^(NSArray *placemakrs , NSError *error){ //placemakrs 是反编码成功的地标合集 if ([placemakrs count] > 0) { CLPlacemark *placemark = placemakrs[0]; NSDictionary *addressDict = placemark.addressDictionary; NSString *address = [addressDict objectForKey:(NSString *)kABPersonAddressStreetKey]; address = address == nil ? @"":address; NSString *state = [addressDict objectForKey:(NSString *)kABPersonAddressStateKey]; state = state == nil ? @"":state; NSString *city = [addressDict objectForKey:(NSString *)kABPersonAddressCityKey]; city = city == nil ? @"":city; self.txtView.text = [NSString stringWithFormat:@"%@\n%@\n%@",state,address,city]; } }]; } </span>
<span style="font-size:18px;"> //地理信息编码查询 - (IBAction)geocodeQuery:(id)sender { if (_txtQueryKey.text == nil || [_txtQueryKey.text length] == 0) { return; } CLGeocoder *geocoder = [[CLGeocoder alloc] init]; [geocoder geocodeAddressString:_txtQueryKey.text completionHandler:^(NSArray *placemarks, NSError *error) { NSLog(@"查询记录数:%i",[placemarks count]); if ([placemarks count] > 0) { CLPlacemark* placemark = placemarks[0]; CLLocationCoordinate2D coordinate = placemark.location.coordinate; NSString* strCoordinate = [NSString stringWithFormat:@"经度:%3.5f \n纬度:%3.5f",coordinate.latitude, coordinate.longitude]; NSDictionary *addressDictionary = placemark.addressDictionary; NSString *address = [addressDictionary objectForKey:(NSString *)kABPersonAddressStreetKey]; address = address == nil ? @"": address; NSString *state = [addressDictionary objectForKey:(NSString *)kABPersonAddressStateKey]; state = state == nil ? @"": state; NSString *city = [addressDictionary objectForKey:(NSString *)kABPersonAddressCityKey]; city = city == nil ? @"": city; _txtView.text = [NSString stringWithFormat:@"%@ \n %@ \n%@ \n%@",strCoordinate,state, address,city]; //关闭键盘 [_txtQueryKey resignFirstResponder]; } }]; } </span>