實戰iPhone GPS定位系統

來源:互聯網
上載者:User

如今,配備GPS功能的行動裝置越來越普遍了,使用GPS定位系統,可以精確地定位你當前所在的地理位置,但由於GPS接收機需要對準天空才能工作,因此在室內環境基本無用。

 

  另一個找到自己所在位置的有效方法是使用手機基站,手機開機時,它會與周圍的基站保持聯絡,如果你知道這些基站的身份,就可以使用各種資料庫(包含基站的身份和它們的確切地理位置)計算出手機的物理位置。基站不需要衛星,和GPS不同,它對室內環境一樣管用。但它沒有GPS那樣精確,它的精度取決於基站的密度,它在基站密集型地區的準確度最高。

  提示:第一代iPhone並沒有配置GPS接收器,基站方式不能應用到iPod Touch上,因為它不是手機。

  第三種方法是依賴Wi-Fi,使用這種方法時,裝置串連到Wi-Fi網路,通過檢查服務提供者的資料確定位置,它既不依賴衛星,也不依賴基站,因此這個方法對於可以串連到Wi-Fi網路的地區有效,但它的精確度也是這三個方法中最差的。

  定位架構核心

  在iPhone上,蘋果提供了定位架構核心,以協助你確定你的物理位置,這個架構的美妙之處在於它使用了前面提到的所有三種方法,具體使用的是哪種方法對於開發人員來說是透明的,開發人員只需要指定所需要的精度,定位核心將會以最佳方式確定定位結果。

  你一定感到很吃驚吧?!本文其餘部分將向你展示這是如何做到的。

  擷取位置座標

  使用Xcode,建立一個新的基於視圖的應用程式項目,取名為LBS,在新項目中,雙擊LBSViewController.xib檔案,在介面設計工具中編輯它。使用下面的組件填充視圖視窗,1所示。

  l Label

  l TextField

   
  圖 1 位置視圖執行個體:用Label和TextFiled填充這個視窗

  在Xcode中架構組上點擊右鍵,選擇“添加”*“現有架構”,選擇 “Framework/CoreLocation.framework”,向LBSViewController.h檔案中添加以下粗體字顯示的代碼:

Java代碼
  1. #import <UIKit/UIKit.h>  
  2. #import <CoreLocation/CoreLocation.h>  
  3. @interface LBSViewController : UIViewController  
  4.     <CLLocationManagerDelegate> {  
  5.     IBOutlet UITextField *latitudeTextField;  
  6.     IBOutlet UITextField *longitudeTextField;  
  7.     IBOutlet UITextField *accuracyTextField;  
  8.     CLLocationManager *lm;  
  9. }  
  10. @property (retain, nonatomic) UITextField *latitudeTextField;  
  11. @property (retain, nonatomic) UITextField *longitudeTextField;  
  12. @property (retain, nonatomic) UITextField *accuracyTextField;  
  13. @end  


  若要使用CLLocationManager類,需要在你的視圖控制器類中實現CLLocationManagerDelegate協議,還需要建立三個出口用於串連視圖視窗中的三個TextFiled視圖。

 

  回到介面編輯器,單擊並拖動文檔的所有者項目到三個TextField視圖,然後分別選擇latitudeTextField,longitudeTextField和accuracyTextField。

  在 LBSViewController.m檔案中查詢以下代碼中的粗體部分:

Java代碼
  1. #import "LBSViewController.h"  
  2. @implementation LBSViewController  
  3. @synthesize latitudeTextField, longitudeTextField, accuracyTextField;  
  4. - (void) viewDidLoad {  
  5.     lm = [[CLLocationManager alloc] init];  
  6.     if ([lm locationServicesEnabled]) {  
  7.         lm.delegate = self;  
  8.         lm.desiredAccuracy = kCLLocationAccuracyBest;  
  9.         lm.distanceFilter = 1000.0f;  
  10.         [lm startUpdatingLocation];  
  11.     }  
  12. }  
  13.   
  14. - (void) locationManager: (CLLocationManager *) manager  
  15.     didUpdateToLocation: (CLLocation *) newLocation  
  16.     fromLocation: (CLLocation *) oldLocation{  
  17.     NSString *lat = [[NSString alloc] initWithFormat:@"%g",  
  18.         newLocation.coordinate.latitude];  
  19.     latitudeTextField.text = lat;  
  20.       
  21.     NSString *lng = [[NSString alloc] initWithFormat:@"%g",  
  22.         newLocation.coordinate.longitude];  
  23.     longitudeTextField.text = lng;  
  24.       
  25.     NSString *acc = [[NSString alloc] initWithFormat:@"%g",  
  26.         newLocation.horizontalAccuracy];  
  27.     accuracyTextField.text = acc;      
  28.       
  29.     [acc release];  
  30.     [lat release];  
  31.     [lng release];  
  32. }  
  33. - (void) locationManager: (CLLocationManager *) manager  
  34.     didFailWithError: (NSError *) error {  
  35.     NSString *msg = [[NSString alloc]  
  36.        initWithString:@"Error obtaining location"];  
  37.     UIAlertView *alert = [[UIAlertView alloc]  
  38.                           initWithTitle:@"Error"  
  39.                           message:msg  
  40.                           delegate:nil  
  41.                           cancelButtonTitle: @"Done"  
  42.                           otherButtonTitles:nil];  
  43.     [alert show];      
  44.     [msg release];  
  45.     [alert release];  
  46. }  
  47. - (void) dealloc{  
  48.     [lm release];  
  49.     [latitudeTextField release];  
  50.     [longitudeTextField release];  
  51.     [accuracyTextField release];  
  52.     [super dealloc];  
  53. }  


  前面的代碼建立了 CLLocationManager類的一個執行個體,在使用對象之前,你應該檢查使用者是否開啟了裝置的定位服務,如果開啟了,你可以使用 desiredAccuracy屬性指定想要的精度,使用下面的常量指定想要的精度:

 

  l kCLLocationAccuracyBest

  l kCLLocationAccuracyNearestTenMeters

  l kCLLocationAccuracyHundredMeters

  l kCLLocationAccuracyKilometer

  l kCLLocationAccuracyThreeKilometers

  distanceFilter屬性讓你指定裝置必須移動多少距離位置資訊才會更新,這個屬性的單位是米。如果你想得到所有移動的通知,可以使用kCLDistanceFilterNone常量,最後,使用 startUpdatingLocation方法啟動位置管理器。

  要獲得位置資訊,需處理下面兩個事件:

  l locationManager:didUpdateToLocation:fromLocation:

  l locationManager:didFailWithError:

  當獲得一個新的定位值時,裝置觸發 locationManager:didUpdateToLocation:fromLocation:事件,如果位置管理器不能確定位置資訊,就會觸發 locationManager:didFailWithError:事件。

  當裝置可以確定位置時,你可能想顯示經緯度值和精度,這時你可以使用CLLocation對象,它的horizontalAccuracy屬性可以指定精度範圍,單位是米。

  按Command- r在iPhone模擬器上測試該程式,圖2顯示了模擬器顯示的位置經緯度值,同時顯示了精度。

   
  圖 2 定位測試:當你在iPhone模擬器上測試該樣本程式時,總會顯示這些固定的值

 

顯示地圖

  如果能將位置座標定位到地圖上顯示將會更有趣,幸運的是,iPhone 3.0 SDK包括了Map Kit API,它可以讓你在程式中顯示Google Map,下面以一個例子進行說明。

  還是使用前面建立的項目,在 LBSViewController.xib檔案中視圖視窗上增加一個按鈕,3所示。

   
  圖 3 View Map按鈕:增加按鈕後的樣子

  在Xcode中架構組上點擊右鍵,增加一個新的架構MapKit.framework。在 LBSViewController.h檔案中添加下列代碼中的粗體部分:

 

Java代碼
  1. #import <UIKit/UIKit.h>  
  2. #import <CoreLocation/CoreLocation.h>  
  3. #import <MapKit/MapKit.h>  
  4. @interface LBSViewController : UIViewController  
  5.     <CLLocationManagerDelegate> {  
  6.     IBOutlet UITextField *accuracyTextField;  
  7.     IBOutlet UITextField *latitudeTextField;  
  8.     IBOutlet UITextField *longitudeTextField;  
  9.     CLLocationManager *lm;  
  10.     
  11.     MKMapView *mapView;  
  12. }  
  13. @property (retain, nonatomic) UITextField *accuracyTextField;  
  14. @property (retain, nonatomic) UITextField *latitudeTextField;  
  15. @property (retain, nonatomic) UITextField *longitudeTextField;  
  16.   
  17. -(IBAction) btnViewMap: (id) sender;  
  18.   
  19. @end  

 

  回到介面編輯器,拖動按鈕到檔案的所有者項目上,然後選擇btnViewMap:。

  在LBSViewController.m檔案中,添加下列代碼中的粗體部分:

 

Java代碼
  1. -(IBAction) btnViewMap: (id) sender {  
  2.     [self.view addSubview:mapView];  
  3. }  
  4. - (void) viewDidLoad {  
  5.     lm = [[CLLocationManager alloc] init];  
  6.     lm.delegate = self;  
  7.     lm.desiredAccuracy = kCLLocationAccuracyBest;  
  8.     lm.distanceFilter = 1000.0f;  
  9.     [lm startUpdatingLocation];  
  10.       
  11.     mapView = [[MKMapView alloc] initWithFrame:self.view.bounds];  
  12.     mapView.mapType = MKMapTypeHybrid;  
  13. }  
  14. - (void) locationManager: (CLLocationManager *) manager  
  15.     didUpdateToLocation: (CLLocation *) newLocation  
  16.     fromLocation: (CLLocation *) oldLocation{  
  17.     NSString *lat = [[NSString alloc] initWithFormat:@"%g",  
  18.         newLocation.coordinate.latitude];  
  19.     latitudeTextField.text = lat;  
  20.       
  21.     NSString *lng = [[NSString alloc] initWithFormat:@"%g",  
  22.         newLocation.coordinate.longitude];  
  23.     longitudeTextField.text = lng;  
  24.       
  25.     NSString *acc = [[NSString alloc] initWithFormat:@"%g",  
  26.         newLocation.horizontalAccuracy];  
  27.     accuracyTextField.text = acc;      
  28.       
  29.     [acc release];  
  30.     [lat release];  
  31.     [lng release];  
  32.       
  33.     MKCoordinateSpan span;  
  34.     span.latitudeDelta=.005;  
  35.     span.longitudeDelta=.005;  
  36.       
  37.     MKCoordinateRegion region;  
  38.     region.center = newLocation.coordinate;  
  39.     region.span=span;  
  40.       
  41.     [mapView setRegion:region animated:TRUE];  
  42. }  
  43. - (void) dealloc{  
  44.     [mapView release];  
  45.     [lm release];  
  46.     [latitudeTextField release];  
  47.     [longitudeTextField release];  
  48.     [accuracyTextField release];  
  49.     [super dealloc];  
  50. }  


  代碼解釋:

 

  l 當視圖載入時建立一個MKMapView類的執行個體,設定顯示的地圖類型。

  l 當使用者點擊View Map按鈕時,在當前視圖上增加mapView對象。

  l 當位置資訊得到更新時,使用mapView對象的setRegion:方法放大地圖。

  在iPhone模擬器中按Command-r測試該程式,點擊View Map按鈕將會顯示一個包含位置管理器返回位置的地圖。4所示。

   
  圖 4 地圖位置:通過定位核心架構顯示地圖位置

  因為模擬器始終顯示的是相同的位置,如果你有一部iPhone手機也可以真實地感受一下,當你移動位置時,你會看到地圖會自動更新。將 distanceFilter屬性設定得小一點,這樣可以增強跟蹤體驗。

http://ming-fanglin.javaeye.com/blog/703744

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.