文档章节

iphone开发 ---- GPS

fcsong000833
 fcsong000833
发布于 2013/02/11 21:02
字数 2244
阅读 2267
收藏 13

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

11.1 iOS定位服务
11.2 iOS地图
11.3 Web地图

来自:http://www.itboat.net/thread-55296-1-1.html

11.1 iOS定位服务
iOS中有三个定位服务组件:
   Wifi定位,通过查询一个Wifi路由器的地理位置的信息。比较省电,iPod touch和iPad也可以采用。
   蜂窝基站定位,通过移动运用商基站定位。也适合有3G版本的iPod touch和iPad。
   GPS卫星定位,通过3-4颗GPS定位位置定位,最为准确,但是耗电量大,不能遮挡。
Core Location
Core Location是iPhone、iPad等开发定位服务应用程序的框架。我们要在Xcode中添加"CoreLocation.framework"存在的框架。
主要使用的类是:CLLocationManager,通过CLLocationManager实现定位服务。
CoreLocation.framework
定位服务实例
201210142259195374.png 
项目WhereAmI:
WhereAmIViewController.h

  1. #import <UIKit/UIKit.h>
  2. #import <CoreLocation/CoreLocation.h>
  3. @interface ViewController : UIViewController<CLLocationManagerDelegate> {
  4.     CLLocationManager* locationManager;
  5. }
  6. @property (strong, nonatomic)    CLLocationManager* locationManager;
  7. @property (retain, nonatomic) IBOutlet UILabel *longitudeText;
  8. @property (retain, nonatomic) IBOutlet UILabel *latituduText;
  9. @property (retain, nonatomic) IBOutlet UIActivityIndicatorView *activity;
  10. - (IBAction)findMe:(id)sender;
  11. - (IBAction)webMap:(id)sender;
  12. @end
复制代码



CLLocationManagerDelegate是定位服务的委托,常用的位置变化回调方法是:
locationManager:didUpdateToLocation:fromLocation: locationManager:didFailWithError:
CLLocationManager 是定位服务管理类,通过它可以设置定位服务的参数、获取经纬度等。
m中加载方法

  1. - (IBAction)findMe:(id)sender {
  2.     self.locationManager = [[[CLLocationManager alloc] init] autorelease];
  3.     self.locationManager.delegate = self;
  4.     self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
  5.     self.locationManager.distanceFilter = 1000.0f;
  6.     [self.locationManager startUpdatingLocation];
  7.     [activity startAnimating];
  8.     NSLog(@"start gps");
  9. }
复制代码


CLLocationManager 是的startUpdatingLocation方法启动所有定位硬件,对应的方法是stopUpdatingLocation,通过调用该方法关闭定位服务器更新,为了省电必须在不用的时候调用该方法关闭定位服务。
此外,我们还可以在这里设定定位服务的参数,包括:distanceFilter和desiredAccuracy。
distanceFilter,这个属性用来控制定位服务更新频率。单位是"米"。 desiredAccuracy,这个属性用来控制定位精度,精度
越高耗电量越大。
定位精度 
desiredAccuracy精度参数可以iOS SDK通过常量实现:
  kCLLocationAccuracyNearestTenMeters,10米 
  kCLLocationAccuracyHundredMeters ,100米
  kCLLocationAccuracyKilometer ,1000米
  kCLLocationAccuracyThreeKilometers,3000米
  kCLLocationAccuracyBest ,最好的精度
  kCLLocationAccuracyBestForNavigation,导航情况下最好精度,iOS 4 SDK新增加。一般要有外接电源时候才能使用。
委托方法用于实现位置的更新

  1. -(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
  2.     latituduText.text = [NSString stringWithFormat:@"%3.5f",newLocation.coordinate.latitude];
  3.     longitudeText.text = [NSString stringWithFormat:@"%3.5f",newLocation.coordinate.longitude];
  4.     [activity stopAnimating];
  5.     [locationManager stopUpdatingLocation];
  6.     NSLog(@"location ok");
  7. }
复制代码



该委托方法不仅可以获得当前位置(newLocation),还可以获得上次的位置(oldLocation ),CLLocation 对象coordinate.latitude属性获得经度,coordinate.longitude属性获得纬度。
[NSString stringWithFormat:@"%3.5f", newLocation.coordinate.latitude]  中的%3.5f是输出整数部分是3位,小数部分是5位的浮点数。
11.2 iOS地图
iOS应用程序中使用Map Kit API开发地图应用程序。
其核心是MKMapView类使用。
多数情况下地图会与定位服务结合使用。
20121014225938918.png 
地图开发一般过程
20121014225939786.png 
201210142259435090.png 
添加MapKit类库
MapKit.framework
MapMeViewController.h

  1. #import <UIKit/UIKit.h>
  2. #import <MapKit/MapKit.h>
  3. #import <CoreLocation/CoreLocation.h>
  4. #import "MapLocation.h"
  5. @interface ViewController : UIViewController<CLLocationManagerDelegate, MKReverseGeocoderDelegate, MKMapViewDelegate> {
  6. }
  7. @property (retain, nonatomic) IBOutlet MKMapView *mapView;
  8. @property (retain, nonatomic) IBOutlet UIActivityIndicatorView *activity;
  9. - (IBAction)findMe:(id)sender;
  10. @end
复制代码



CLLocationManagerDelegate是定位服务委托。
MKMapViewDelegate是地图视图委托,主要方法:
   -mapView:viewForAnnotation:
   -mapViewDidFailLoadingMap:withError:
MKReverseGeocoderDelegate是给地理坐标获得标志点信息的委托,用于地理信息编码(即:从坐标获得地点获得信息),主要委托方法:
   &ndash; reverseGeocoder:didFindPlacemark:
   &ndash; reverseGeocoder:didFailWithError:
m文件中的视图加载和卸载

  1. - (void)viewDidLoad {
  2.     [super viewDidLoad];
  3.     mapView.mapType = MKMapTypeStandard;
  4.     //mapView.mapType = MKMapTypeSatellite;
  5.     //mapView.mapType = MKMapTypeHybrid;
  6.     mapView.delegate = self;    
  7. }
复制代码



mapView.mapType = MKMapTypeStandard;是指定地图的类型,iOS提供了三种风格的地图:
  MKMapTypeStandard标准地图模式
  MKMapTypeSatellite卫星地图模式
  MKMapTypeHybrid具有街道等信息的卫星地图模式
mapView.delegate = self;是将委托对象指定为自身。
按钮事件

  1. - (IBAction)findMe:(id)sender {
  2.     CLLocationManager *lm = [[CLLocationManager alloc] init];
  3.     lm.delegate = self;
  4.     lm.desiredAccuracy = kCLLocationAccuracyBest;
  5.     [lm startUpdatingLocation];
  6.     activity.hidden = NO;
  7.     [activity startAnimating];
  8. }
复制代码



点击按钮时候通过定位服务获取当前位置信息。
通过lm.delegate = self;是将委托对象指定为自身。
因此,点击事件发生时候将会回调CLLocationManagerDelegate委托的
-locationManager:didUpdateToLocation:fromLocation:方法。
回调位置更新方法

  1. #pragma mark CLLocationManagerDelegate Methods
  2. - (void)locationManager:(CLLocationManager *)manager 
  3.     didUpdateToLocation:(CLLocation *)newLocation 
  4.            fromLocation:(CLLocation *)oldLocation {
  5.     MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(newLocation.coordinate, 2000, 2000); 
  6.     //[mapView setRegion:viewRegion animated:YES];
  7.     MKCoordinateRegion adjustedRegion = [mapView regionThatFits:viewRegion];
  8.     [mapView setRegion:adjustedRegion animated:YES];
  9.     manager.delegate = nil;
  10.     [manager stopUpdatingLocation];
  11.     MKReverseGeocoder *geocoder = [[MKReverseGeocoder alloc] initWithCoordinate:newLocation.coordinate];
  12.     geocoder.delegate = self;
  13.     [geocoder start];
  14. }
复制代码



MKCoordinateRegionMakeWithDistance(newLocation.coordinate, 2000, 2000); 该函数能够创建一个MKCoordinateRegion结构体,第一个参数是一个CLLocationCoordinate2D结构指定了目标区域的中心点,第二个是目标区域南北的跨度单位是米,第三个是目标区域东西的跨度单位是米。后两个参数的调整会影响地图缩放。
[[MKReverseGeocoder alloc] initWithCoordinate:newLocation.coordinate]; 创建地理编码对象geocoder,通过该对象可以把坐标转换成为地理信息的描述。
geocoder.delegate = self;指定编码的处理是自身对象。
  [geocoder start];开始编码处理。
  MKReverseGeocoderDelegate
是地理编码委托对象,该委托的方法:
  成功时候调用-reverseGeocoder:didFindPlacemark:
  失败时候调用-reverseGeocoder:didFailWithError:
成功编码回调方法

  1. - (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark {
  2.     MapLocation *annotation = [[MapLocation alloc] init];
  3.     annotation.streetAddress = placemark.thoroughfare;
  4.     annotation.city = placemark.locality;
  5.     annotation.state = placemark.administrativeArea;
  6.     annotation.zip = placemark.postalCode;
  7.     annotation.coordinate = geocoder.coordinate;
  8.     [mapView addAnnotation:annotation];
  9.     [annotation release];    
  10.     geocoder.delegate = nil;
  11.     [geocoder autorelease];
  12.     [activity stopAnimating];
  13.     activity.hidden = YES;
  14. }
复制代码



成功编码后需要在该方法中创建标注对象(MapLocation)。MapLocation 是我们自定义的实现MKAnnotation协议标注对象。 该方法的placemark是MKPlacemark获得很多地理信息,详细见下表。
[mapView addAnnotation:annotation]; 为地图添加标注,该方法将会触发mapView:viewForAnnotation:方法回调。
MKPlacemark类属性
addressDictionary  地址信息的dictionary
thoroughfare  指定街道级别信息
subThoroughfare  指定街道级别的附加信息
locality  指定城市信息
subLocality  指定城市信息附加信息
administrativeArea  行政区域
subAdministrativeArea  行政区域附加信息
country  国家信息
countryCode  国家代号
postalCode  邮政编码
失败编码回调方法

  1. - (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error {
  2.     UIAlertView *alert = [[UIAlertView alloc] 
  3.                           initWithTitle:@"地理解码错误息"
  4.                           message:@"地理代码不能识别" 
  5.                           delegate:nil
  6.                           cancelButtonTitle:@"Ok"
  7.                           otherButtonTitles:nil];
  8.     [alert show];
  9.     [alert release];
  10.     geocoder.delegate = nil;
  11.     [geocoder autorelease];
  12.     [activity stopAnimating];
  13. }
复制代码



MKMapViewDelegate
是地图视图委托对象,本例子我们使用的方法:
  - mapView:viewForAnnotation:为地图设置标注时候回调方法。
  -mapViewDidFailLoadingMap:withError:地图加载错误时候回调方法。
地图标注回调方法

  1. #pragma mark Map View Delegate Methods
  2. - (MKAnnotationView *) mapView:(MKMapView *)theMapView viewForAnnotation:(id <MKAnnotation>) annotation {
  3.     MKPinAnnotationView *annotationView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"PIN_ANNOTATION"];
  4.     if(annotationView == nil) {
  5.         annotationView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation
  6.                                                           reuseIdentifier:@"PIN_ANNOTATION"] autorelease];
  7.     }
  8.     annotationView.canShowCallout = YES;
  9.     annotationView.pinColor = MKPinAnnotationColorRed;
  10.     annotationView.animatesDrop = YES;
  11.     annotationView.highlighted = YES;
  12.     annotationView.draggable = YES;
  13.     return annotationView;
  14. }
复制代码



与表格视图单元格处理类似,地图标注对象由于会很多,因此需要重复利用,通过
dequeueReusableAnnotationViewWithIdentifier方法可以查找可重复利用的标注对象,以达到节省内存的目的。
annotationView.canShowCallout = YES;指定标注上的插图,点击图钉有气泡显示。
annotationView.pinColor 设置图钉的颜色。
annotationView.animatesDrop动画效果。
地图加载失败回调方法

  1. - (void)mapViewDidFailLoadingMap:(MKMapView *)theMapView withError:(NSError *)error {
  2.     UIAlertView *alert = [[UIAlertView alloc] 
  3.                           initWithTitle:@"地图加载错误"
  4.                           message:[error localizedDescription] 
  5.                           delegate:nil 
  6.                           cancelButtonTitle:@"Ok"
  7.                           otherButtonTitles:nil];
  8.     [alert show];
  9.     [alert release];
  10. }
复制代码



自定义地图标注对象 

  1. #import <Foundation/Foundation.h>
  2. #import <MapKit/MapKit.h>
  3. @interface MapLocation : NSObject <MKAnnotation, NSCoding> {
  4.     NSString *streetAddress;
  5.     NSString *city;
  6.     NSString *state;
  7.     NSString *zip;
  8.     CLLocationCoordinate2D coordinate;
  9. }
  10. @property (nonatomic, copy) NSString *streetAddress;
  11. @property (nonatomic, copy) NSString *city;
  12. @property (nonatomic, copy) NSString *state;
  13. @property (nonatomic, copy) NSString *zip;
  14. @property (nonatomic, readwrite) CLLocationCoordinate2D coordinate;
  15. @end
复制代码



作为地图标注对象实现MKAnnotation协议是必须的,只有实现该协议才能使该类成为标注类。实现NSCoding协议是可选的,实现该协议可以使标注对象能够复制。 里面的属性有哪些要看你自己的需要。
MapLocation.m

  1. - (NSString *)title {
  2.     return @"您的位置!";
  3. }
  4. - (NSString *)subtitle {
  5.     NSMutableString *ret = [NSMutableString string];
  6.     if (streetAddress)
  7.         [ret appendString:streetAddress]; 
  8.     if (streetAddress && (city || state || zip)) 
  9.         [ret appendString:@" &bull; "];
  10.     if (city)
  11.         [ret appendString:city];
  12.     if (city && state)
  13.         [ret appendString:@", "];
  14.     if (state)
  15.         [ret appendString:state];
  16.     if (zip)
  17.         [ret appendFormat:@", %@", zip];
  18.     return ret;
  19. }
复制代码



title 和subtitle 是MKAnnotation协议要求实现的方法。
MapLocation.m

  1. #pragma mark -
  2. - (void)dealloc {
  3.     [streetAddress release];
  4.     [city release];
  5.     [state release];
  6.     [zip release];
  7.     [super dealloc];
  8. }
  9. #pragma mark -
  10. #pragma mark NSCoding Methods
  11. - (void) encodeWithCoder: (NSCoder *)encoder {
  12.     [encoder encodeObject: [self streetAddress] forKey: @"streetAddress"];
  13.     [encoder encodeObject: [self city] forKey: @"city"];
  14.     [encoder encodeObject: [self state] forKey: @"state"];
  15.     [encoder encodeObject: [self zip] forKey: @"zip"];
  16. }
  17. - (id) initWithCoder: (NSCoder *)decoder  {
  18.     if (self = [super init]) {
  19.         [self setStreetAddress: [decoder decodeObjectForKey: @"streetAddress"]];
  20.         [self setCity: [decoder decodeObjectForKey: @"city"]];
  21.         [self setState: [decoder decodeObjectForKey: @"state"]];
  22.         [self setZip: [decoder decodeObjectForKey: @"zip"]];
  23.     }
  24.     return self;
  25. }
复制代码



encodeWithCoder:和initWithCoder:是NSCoding协议要求实现方法。
11.3 Web地图
在iOS中我们还可以使用Web地图。
201210142300316417.png 



  1. - (IBAction)webMap:(id)sender {
  2.     CLLocation *lastLocation = [locationManager location];
  3.     if(!lastLocation) 
  4.     {
  5.         UIAlertView *alert;
  6.         alert = [[UIAlertView alloc] 
  7.                  initWithTitle:@"系统错误" 
  8.                  message:@"还没有接收到数据!" 
  9.                  delegate:nil cancelButtonTitle:nil 
  10.                  otherButtonTitles:@"OK", nil];
  11.         [alert show];
  12.         [alert release];
  13.         return;
  14.     }
  15.     NSString *urlString = [NSString stringWithFormat:
  16.                            @"http://maps.google.com/maps?q=Here+I+Am!@%f,%f", 
  17.                            lastLocation.coordinate.latitude, 
  18.                            lastLocation.coordinate.longitude];
  19.     NSURL *url = [NSURL URLWithString:urlString];
  20.     [[UIApplication sharedApplication] openURL:url];
  21. }
复制代码



http://maps.google.com/maps?q=Here+I+Am!@%f,%f是请求Web地图的网站,q后面上参数。 
[[UIApplication sharedApplication] openURL:url];打开iOS内置的浏览器,即在内置浏览器中打开地图。

注: 
1 本教程是基于关东升老师的教程      
2 基于黑苹果10.6.8和xcode4.2      
3 本人初学,有什么不对的望指教      
4 教程会随着本人学习,持续更新      
5 教程是本人从word笔记中拷贝出来了,所以格式请见谅

© 著作权归作者所有

fcsong000833

fcsong000833

粉丝 18
博文 68
码字总数 50889
作品 0
深圳
程序员
私信 提问
加载中

评论(2)

fcsong000833
fcsong000833 博主

引用来自“BUJIBUJI可”的评论

兄弟 请教个问题:GPS定位的时候遇到 startUpdatingLocation之后didUpdateToLocation 只调用了几次 然后就不调用了 我需要一直更新位置 模拟器上没问题 真机上就出现这种情况 知道怎么搞吗

我是通过一个线程专门来更新位置信息,因此不存在不调用的问题(无论在模拟机还是真机)。
还有就是:我只做过位置信息来自网络的情况,并没有做过来自本机的情况。
总是搞不懂
总是搞不懂
兄弟 请教个问题:GPS定位的时候遇到 startUpdatingLocation之后didUpdateToLocation 只调用了几次 然后就不调用了 我需要一直更新位置 模拟器上没问题 真机上就出现这种情况 知道怎么搞吗
iPhone开发进阶(10)--- 在程序中使用GPS

原文链接 : http://www.yifeiyang.net/iphone-developer-advanced-10-use-gps/ 转载请保留上面文字。 iPhone开发进阶(10)--- 在程序中使用GPS 这一回简单地介绍一下GPS的使用方法。使用GPS...

长平狐
2012/08/13
77
0
iPhone手机GPS时速表,里程表与海拔表

前段时间开发的iphone手机“GPS位置记录与分享”应用,不少用户觉得很实用。 一些户外用户提出希望加入海拔功能。 经过长时间的研究开发测试,完成了GPS时速表,里程表与海拔表功能。 也就是...

zhangjianwu
2013/09/22
1K
0
iPhone手机上的GPS位置信息采集与分享应用

去年给清华大学水利系设 计实现了一款iPhone手机上的校友会应用。由于需要通过iPhone手机上报校友的位置信息,需要在iPhone手机地图上显示世界各地的校友位置, 所以对iOS平台的GPS与地图功能...

zhangjianwu
2013/05/23
1K
0
iOS-定位服务与地图应用开发

iOS-定位服务与地图应用开发 Harries Blog™2017-12-192 阅读 maptaripAppIOScatAPIIOAndroid 一,定位服务 iOS设备能提供3种不同的定位途径: 1,WiFi定位,通过查询一个WiFi路由器的地理位...

Harries Blog™
2017/12/19
0
0
[北京]游戏公司招聘IOS开发人员(5k~15K)

公司介绍:游戏运营商 招聘职位:开发工程师 职位要求:岗位职责 1、基于iPhone平台的游戏开发; 2、研究手机程序运用中的增强实现,GPS,LBS,视频整合等其它相关技术; 3、评估和沟通技术风...

CharlesG
2012/02/24
377
3

没有更多内容

加载失败,请刷新页面

加载更多

数据结构(树)

树: 树是n个结点的有限集合,有且仅有一个根结点,其余结点可分为m个根结点的子树。 度: 指的是一个节点拥有子节点的个数。如二叉树的节点的最大度为2。 高度/深度: 数的层数,根节点为第...

潦草的犀牛
15分钟前
2
0
“同步”是什么意思?

我对synchronized关键字的用法和重要性有一些疑问。 synchronized关键字的意义是什么? 方法应何时synchronized ? 从程序上和逻辑上是什么意思? #1楼 据我了解,同步基本上意味着编译器在您...

javail
26分钟前
3
0
sed -i linux 批量替换命令

批量替换 /usr/local/rocketmq/conf 目录下 的 xml 里头的 ${user.home} 替换为 /usr/local/rocketmq # mkdir -p /usr/local/rocketmq/logs# cd /usr/local/rocketmq/conf && sed -i 's#${......

jxlgzwh
34分钟前
4
0
如何在嵌入式CSS中编写a:hover?

我有一种情况,我必须编写内联CSS代码,并且我想在锚点上应用悬停样式。 如何在HTML样式属性内的CSS中使用a:hover ? 例如,您不能在HTML电子邮件中可靠地使用CSS类。 #1楼 简短的答案:您不...

技术盛宴
41分钟前
4
0
一些常用工具下载

golang: https://dl.google.com/go/go1.13.5.window-amd64.zip https://dl.google.com/go/go1.13.5.linux-amd64.tar.gz 更换版本号可以下载其他版本。...

bobby2006
48分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部