博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
IOS之地图和定位应用开发
阅读量:4982 次
发布时间:2019-06-12

本文共 12247 字,大约阅读时间需要 40 分钟。

11.1 iOS定位服务

11.2 iOS地图

11.3 Web地图

 

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

定位服务实例

项目WhereAmI:

WhereAmIViewController.h

1 #import 
2 #import
3 4 @interface ViewController : UIViewController
{ 5 CLLocationManager* locationManager; 6 } 7 8 @property (strong, nonatomic) CLLocationManager* locationManager; 9 @property (retain, nonatomic) IBOutlet UILabel *longitudeText;10 @property (retain, nonatomic) IBOutlet UILabel *latituduText;11 @property (retain, nonatomic) IBOutlet UIActivityIndicatorView *activity;12 - (IBAction)findMe:(id)sender;13 - (IBAction)webMap:(id)sender;14 15 @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类使用。

多数情况下地图会与定位服务结合使用。

地图开发一般过程

添加MapKit类库

MapKit.framework

MapMeViewController.h

1 #import 
2 #import
3 #import
4 #import "MapLocation.h" 5 6 @interface ViewController : UIViewController
{ 7 8 } 9 10 @property (retain, nonatomic) IBOutlet MKMapView *mapView;11 @property (retain, nonatomic) IBOutlet UIActivityIndicatorView *activity;12 - (IBAction)findMe:(id)sender;13 @end

CLLocationManagerDelegate是定位服务委托。

MKMapViewDelegate是地图视图委托,主要方法:

   -mapView:viewForAnnotation:

   -mapViewDidFailLoadingMap:withError:

MKReverseGeocoderDelegate是给地理坐标获得标志点信息的委托,用于地理信息编码(即:从坐标获得地点获得信息),主要委托方法:

   – reverseGeocoder:didFindPlacemark:

   – 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     7     activity.hidden = NO;8     [activity startAnimating];9 }

点击按钮时候通过定位服务获取当前位置信息。

通过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      6     MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(newLocation.coordinate, 2000, 2000);  7     //[mapView setRegion:viewRegion animated:YES]; 8     MKCoordinateRegion adjustedRegion = [mapView regionThatFits:viewRegion]; 9     [mapView setRegion:adjustedRegion animated:YES];10     11     manager.delegate = nil;12     [manager stopUpdatingLocation];13     14     MKReverseGeocoder *geocoder = [[MKReverseGeocoder alloc] initWithCoordinate:newLocation.coordinate];15     geocoder.delegate = self;16     [geocoder start];17 }

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      3     MapLocation *annotation = [[MapLocation alloc] init]; 4     annotation.streetAddress = placemark.thoroughfare; 5     annotation.city = placemark.locality; 6     annotation.state = placemark.administrativeArea; 7     annotation.zip = placemark.postalCode; 8     annotation.coordinate = geocoder.coordinate; 9     [mapView addAnnotation:annotation];    10     11     [annotation release];    12     geocoder.delegate = nil;13     [geocoder autorelease];14     15     [activity stopAnimating];16     activity.hidden = YES;17 }

成功编码后需要在该方法中创建标注对象(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     11     geocoder.delegate = nil;12     [geocoder autorelease];13     14     [activity stopAnimating];15 }

MKMapViewDelegate

是地图视图委托对象,本例子我们使用的方法:

  - mapView:viewForAnnotation:为地图设置标注时候回调方法。

  -mapViewDidFailLoadingMap:withError:地图加载错误时候回调方法。

地图标注回调方法

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

与表格视图单元格处理类似,地图标注对象由于会很多,因此需要重复利用,通过

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 
2 #import
3 4 @interface MapLocation : NSObject
{ 5 NSString *streetAddress; 6 NSString *city; 7 NSString *state; 8 NSString *zip; 9 10 CLLocationCoordinate2D coordinate;11 }12 @property (nonatomic, copy) NSString *streetAddress;13 @property (nonatomic, copy) NSString *city;14 @property (nonatomic, copy) NSString *state;15 @property (nonatomic, copy) NSString *zip;16 @property (nonatomic, readwrite) CLLocationCoordinate2D coordinate;17 @end

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

MapLocation.m

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

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 Methods11 - (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地图。

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         12         [alert show];13         [alert release];14         return;15     }16     17     NSString *urlString = [NSString stringWithFormat:18                            @"http://maps.google.com/maps?q=Here+I+Am!@%f,%f", 19                            lastLocation.coordinate.latitude, 20                            lastLocation.coordinate.longitude];21     NSURL *url = [NSURL URLWithString:urlString];22     23     [[UIApplication sharedApplication] openURL:url];24 }

http://maps.google.com/maps?q=Here+I+Am!@%f,%f是请求Web地图的网站,q后面上参数。 

[[UIApplication sharedApplication] openURL:url];打开iOS内置的浏览器,即在内置浏览器中打开地图。

 

转载于:https://www.cnblogs.com/ubersexual/p/3277935.html

你可能感兴趣的文章
关于.NET编程中各种事务的实现
查看>>
spring Boot加载bean
查看>>
学习笔记 UpdateXml() MYSQL显错注入
查看>>
51nod1455(dp)
查看>>
正则:校验名字,不严格校验手机号
查看>>
软件测试作业二 —— 对于Faults,Errors,Failures的认识的习题
查看>>
.net 给前台元素设置样式
查看>>
WPF学习:控件的模板
查看>>
小数据池 深浅拷贝 集合
查看>>
Hash_Map 原理
查看>>
mysql函数大全pdf
查看>>
Asp.net 2.0在Windows 2003 Server 上配置Microsoft Excel、Microsoft Word应用程序权限时 error: 8000401a 的解决方法!...
查看>>
SDUT 识别浮点常量问题 编译原理作业
查看>>
BZOJ 2819: Nim dfs序维护树状数组,倍增
查看>>
WinRAR(5.21)-0day漏洞-始末分析
查看>>
终端检测HTTPS服务端
查看>>
证件照换底色
查看>>
Candies
查看>>
EAS部署:linux 下安装EAS后启动不了服务
查看>>
[BZOJ3244][NOI2013] 树的计数
查看>>