天天看點

讀書筆記 --- 定位

現在的移動裝置很多都提供定位服務功能,使用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>
           

更多幹貨,請支援原作:http://item.jd.com/11436547.html