技术开发 频道

实战iPhone应用开发之:GPS定位系统

  【IT168 技术文档】如今,配备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文件中添加以下粗体字显示的代码:

#import <UIKit/UIKit.h>
#import
<CoreLocation/CoreLocation.h>
@interface LBSViewController : UIViewController
    
<CLLocationManagerDelegate> {
    IBOutlet UITextField
*latitudeTextField;
    IBOutlet UITextField
*longitudeTextField;
    IBOutlet UITextField
*accuracyTextField;
    CLLocationManager
*lm;
}
@property (retain, nonatomic) UITextField
*latitudeTextField;
@property (retain, nonatomic) UITextField
*longitudeTextField;
@property (retain, nonatomic) UITextField
*accuracyTextField;
@end

  若要使用CLLocationManager类,需要在你的视图控制器类中实现CLLocationManagerDelegate协议,还需要创建三个出口用于连接视图窗口中的三个TextFiled视图。

  回到界面编辑器,单击并拖动文档的所有者项目到三个TextField视图,然后分别选择latitudeTextField,longitudeTextField和accuracyTextField。

  在LBSViewController.m文件中查询以下代码中的粗体部分:

#import "LBSViewController.h"
@implementation LBSViewController
@synthesize latitudeTextField, longitudeTextField, accuracyTextField;
- (void) viewDidLoad {
    lm
= [[CLLocationManager alloc] init];
    
if ([lm locationServicesEnabled]) {
        lm.
delegate = self;
        lm.desiredAccuracy
= kCLLocationAccuracyBest;
        lm.distanceFilter
= 1000.0f;
        [lm startUpdatingLocation];
    }
}
- (void) locationManager: (CLLocationManager *) manager
    didUpdateToLocation: (CLLocation
*) newLocation
    fromLocation: (CLLocation
*) oldLocation{
    NSString
*lat = [[NSString alloc] initWithFormat:@"%g",
        newLocation.coordinate.latitude];
    latitudeTextField.text
= lat;
    
    NSString
*lng = [[NSString alloc] initWithFormat:@"%g",
        newLocation.coordinate.longitude];
    longitudeTextField.text
= lng;
    
    NSString
*acc = [[NSString alloc] initWithFormat:@"%g",
        newLocation.horizontalAccuracy];
    accuracyTextField.text
= acc;    
    
    [acc release];
    [lat release];
    [lng release];
}
- (void) locationManager: (CLLocationManager *) manager
    didFailWithError: (NSError
*) error {
    NSString
*msg = [[NSString alloc]
       initWithString:
@"Error obtaining location"];
    UIAlertView
*alert = [[UIAlertView alloc]
                          initWithTitle:
@"Error"
                          message:msg
                          
delegate:nil
                          cancelButtonTitle:
@"Done"
                          otherButtonTitles:nil];
    [alert show];    
    [msg release];
    [alert release];
}
- (void) dealloc{
    [lm release];
    [latitudeTextField release];
    [longitudeTextField release];
    [accuracyTextField release];
    [super dealloc];
}

  前面的代码创建了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模拟器上测试该示例程序时,总会显示这些固定的值

0
相关文章