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

#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>@interface ViewController : UIViewController<CLLocationManagerDelegate> {CLLocationManager* locationManager;
}@property (strong, nonatomic)    CLLocationManager* locationManager;
@property (retain, nonatomic) IBOutlet UILabel *longitudeText;
@property (retain, nonatomic) IBOutlet UILabel *latituduText;
@property (retain, nonatomic) IBOutlet UIActivityIndicatorView *activity;
- (IBAction)findMe:(id)sender;
- (IBAction)webMap:(id)sender;@end

CLLocationManagerDelegate是定位服务的委托,常用的位置变化回调方法是:

locationManager:didUpdateToLocation:fromLocation: locationManager:didFailWithError:

CLLocationManager 是定位服务管理类,通过它可以设置定位服务的参数、获取经纬度等。

m中加载方法

- (IBAction)findMe:(id)sender {self.locationManager = [[[CLLocationManager alloc] init] autorelease];self.locationManager.delegate = self;self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;self.locationManager.distanceFilter = 1000.0f;[self.locationManager startUpdatingLocation];[activity startAnimating];NSLog(@"start gps");
}

CLLocationManager 是的startUpdatingLocation方法启动所有定位硬件,对应的方法是stopUpdatingLocation,通过调用该方法关闭定位服务器更新,为了省电必须在不用的时候调用该方法关闭定位服务。

此外,我们还可以在这里设定定位服务的参数,包括:distanceFilter和desiredAccuracy。

distanceFilter,这个属性用来控制定位服务更新频率。单位是“米”。 desiredAccuracy,这个属性用来控制定位精度,精度

越高耗电量越大。

定位精度

desiredAccuracy精度参数可以iOS SDK通过常量实现:

kCLLocationAccuracyNearestTenMeters,10米

kCLLocationAccuracyHundredMeters ,100米

kCLLocationAccuracyKilometer ,1000米

kCLLocationAccuracyThreeKilometers,3000米

kCLLocationAccuracyBest ,最好的精度

kCLLocationAccuracyBestForNavigation,导航情况下最好精度,iOS 4 SDK新增加。一般要有外接电源时候才能使用。

委托方法用于实现位置的更新

-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {latituduText.text = [NSString stringWithFormat:@"%3.5f",newLocation.coordinate.latitude];longitudeText.text = [NSString stringWithFormat:@"%3.5f",newLocation.coordinate.longitude];[activity stopAnimating];[locationManager stopUpdatingLocation];NSLog(@"location ok");
}

该委托方法不仅可以获得当前位置(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

#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
#import "MapLocation.h"@interface ViewController : UIViewController<CLLocationManagerDelegate, MKReverseGeocoderDelegate, MKMapViewDelegate> {}@property (retain, nonatomic) IBOutlet MKMapView *mapView;
@property (retain, nonatomic) IBOutlet UIActivityIndicatorView *activity;
- (IBAction)findMe:(id)sender;
@end

CLLocationManagerDelegate是定位服务委托。

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

-mapView:viewForAnnotation:

-mapViewDidFailLoadingMap:withError:

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

– reverseGeocoder:didFindPlacemark:

– reverseGeocoder:didFailWithError:

m文件中的视图加载和卸载

- (void)viewDidLoad {[super viewDidLoad];mapView.mapType = MKMapTypeStandard;//mapView.mapType = MKMapTypeSatellite;//mapView.mapType = MKMapTypeHybrid;mapView.delegate = self;
}

mapView.mapType = MKMapTypeStandard;是指定地图的类型,iOS提供了三种风格的地图:

MKMapTypeStandard标准地图模式

MKMapTypeSatellite卫星地图模式

MKMapTypeHybrid具有街道等信息的卫星地图模式

mapView.delegate = self;是将委托对象指定为自身。

按钮事件

- (IBAction)findMe:(id)sender {CLLocationManager *lm = [[CLLocationManager alloc] init];lm.delegate = self;lm.desiredAccuracy = kCLLocationAccuracyBest;[lm startUpdatingLocation];activity.hidden = NO;[activity startAnimating];
}

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

通过lm.delegate = self;是将委托对象指定为自身。

因此,点击事件发生时候将会回调CLLocationManagerDelegate委托的

-locationManager:didUpdateToLocation:fromLocation:方法。

回调位置更新方法

#pragma mark CLLocationManagerDelegate Methods
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(newLocation.coordinate, 2000, 2000); //[mapView setRegion:viewRegion animated:YES];MKCoordinateRegion adjustedRegion = [mapView regionThatFits:viewRegion];[mapView setRegion:adjustedRegion animated:YES];manager.delegate = nil;[manager stopUpdatingLocation];MKReverseGeocoder *geocoder = [[MKReverseGeocoder alloc] initWithCoordinate:newLocation.coordinate];geocoder.delegate = self;[geocoder start];
}

MKCoordinateRegionMakeWithDistance(newLocation.coordinate, 2000, 2000); 该函数能够创建一个MKCoordinateRegion结构体,第一个参数是一个CLLocationCoordinate2D结构指定了目标区域的中心点,第二个是目标区域南北的跨度单位是米,第三个是目标区域东西的跨度单位是米。后两个参数的调整会影响地图缩放。

[[MKReverseGeocoder alloc] initWithCoordinate:newLocation.coordinate]; 创建地理编码对象geocoder,通过该对象可以把坐标转换成为地理信息的描述。

geocoder.delegate = self;指定编码的处理是自身对象。

[geocoder start];开始编码处理。

MKReverseGeocoderDelegate

是地理编码委托对象,该委托的方法:

成功时候调用-reverseGeocoder:didFindPlacemark:

失败时候调用-reverseGeocoder:didFailWithError:

成功编码回调方法

- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark {MapLocation *annotation = [[MapLocation alloc] init];annotation.streetAddress = placemark.thoroughfare;annotation.city = placemark.locality;annotation.state = placemark.administrativeArea;annotation.zip = placemark.postalCode;annotation.coordinate = geocoder.coordinate;[mapView addAnnotation:annotation];    [annotation release];    geocoder.delegate = nil;[geocoder autorelease];[activity stopAnimating];activity.hidden = YES;
}

成功编码后需要在该方法中创建标注对象(MapLocation)。MapLocation 是我们自定义的实现MKAnnotation协议标注对象。 该方法的placemark是MKPlacemark获得很多地理信息,详细见下表。

[mapView addAnnotation:annotation]; 为地图添加标注,该方法将会触发mapView:viewForAnnotation:方法回调。

MKPlacemark类属性

addressDictionary  地址信息的dictionary

thoroughfare  指定街道级别信息

subThoroughfare  指定街道级别的附加信息

locality  指定城市信息

subLocality  指定城市信息附加信息

administrativeArea  行政区域

subAdministrativeArea  行政区域附加信息

country  国家信息

countryCode  国家代号

postalCode  邮政编码

失败编码回调方法

- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error {UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"地理解码错误息"message:@"地理代码不能识别" delegate:nilcancelButtonTitle:@"Ok"otherButtonTitles:nil];[alert show];[alert release];geocoder.delegate = nil;[geocoder autorelease];[activity stopAnimating];
}

MKMapViewDelegate

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

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

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

地图标注回调方法

#pragma mark Map View Delegate Methods
- (MKAnnotationView *) mapView:(MKMapView *)theMapView viewForAnnotation:(id <MKAnnotation>) annotation {MKPinAnnotationView *annotationView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"PIN_ANNOTATION"];if(annotationView == nil) {annotationView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotationreuseIdentifier:@"PIN_ANNOTATION"] autorelease];}annotationView.canShowCallout = YES;annotationView.pinColor = MKPinAnnotationColorRed;annotationView.animatesDrop = YES;annotationView.highlighted = YES;annotationView.draggable = YES;return annotationView;
}

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

dequeueReusableAnnotationViewWithIdentifier方法可以查找可重复利用的标注对象,以达到节省内存的目的。

annotationView.canShowCallout = YES;指定标注上的插图,点击图钉有气泡显示。

annotationView.pinColor 设置图钉的颜色。

annotationView.animatesDrop动画效果。

地图加载失败回调方法

- (void)mapViewDidFailLoadingMap:(MKMapView *)theMapView withError:(NSError *)error {UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"地图加载错误"message:[error localizedDescription] delegate:nil cancelButtonTitle:@"Ok"otherButtonTitles:nil];[alert show];[alert release];
}

自定义地图标注对象

#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>@interface MapLocation : NSObject <MKAnnotation, NSCoding> {NSString *streetAddress;NSString *city;NSString *state;NSString *zip;CLLocationCoordinate2D coordinate;
}
@property (nonatomic, copy) NSString *streetAddress;
@property (nonatomic, copy) NSString *city;
@property (nonatomic, copy) NSString *state;
@property (nonatomic, copy) NSString *zip;
@property (nonatomic, readwrite) CLLocationCoordinate2D coordinate;
@end

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

MapLocation.m

- (NSString *)title {return @"您的位置!";
}
- (NSString *)subtitle {NSMutableString *ret = [NSMutableString string];if (streetAddress)[ret appendString:streetAddress]; if (streetAddress && (city || state || zip)) [ret appendString:@" • "];if (city)[ret appendString:city];if (city && state)[ret appendString:@", "];if (state)[ret appendString:state];if (zip)[ret appendFormat:@", %@", zip];return ret;
}

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

MapLocation.m

#pragma mark -
- (void)dealloc {[streetAddress release];[city release];[state release];[zip release];[super dealloc];
}
#pragma mark -
#pragma mark NSCoding Methods
- (void) encodeWithCoder: (NSCoder *)encoder {[encoder encodeObject: [self streetAddress] forKey: @"streetAddress"];[encoder encodeObject: [self city] forKey: @"city"];[encoder encodeObject: [self state] forKey: @"state"];[encoder encodeObject: [self zip] forKey: @"zip"];
}
- (id) initWithCoder: (NSCoder *)decoder  {if (self = [super init]) {[self setStreetAddress: [decoder decodeObjectForKey: @"streetAddress"]];[self setCity: [decoder decodeObjectForKey: @"city"]];[self setState: [decoder decodeObjectForKey: @"state"]];[self setZip: [decoder decodeObjectForKey: @"zip"]];}return self;
}

encodeWithCoder:和initWithCoder:是NSCoding协议要求实现方法。

11.3 Web地图

在iOS中我们还可以使用Web地图。

- (IBAction)webMap:(id)sender {CLLocation *lastLocation = [locationManager location];if(!lastLocation) {UIAlertView *alert;alert = [[UIAlertView alloc] initWithTitle:@"系统错误" message:@"还没有接收到数据!" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"OK", nil];[alert show];[alert release];return;}NSString *urlString = [NSString stringWithFormat:@"http://maps.google.com/maps?q=Here+I+Am!@%f,%f", lastLocation.coordinate.latitude, lastLocation.coordinate.longitude];NSURL *url = [NSURL URLWithString:urlString];[[UIApplication sharedApplication] openURL:url];
}

与iOS6的苹果didUpdateLocations代替didUpdateToLocation的释放。任何人都可以解释如何didUpdateLocations?
本文地址 :CodeGo.net/507856/

-------------------------------------------------------------------------------------------------------------------------

1. 我以下的委托,以获得最后一个位置?
- (void)locationManager:(CLLocationManager *)manager 
 didUpdateToLocation:(CLLocation *)newLocation 
   fromLocation:(CLLocation *)oldLocation

上述委托弃用的iOS 6。现在,下面应该
- (void)locationManager:(CLLocationManager *)manager 
  didUpdateLocations:(NSArray *)locations

为了获得最后的位置,只需获取数组的最后一个对象:
[locations lastObject]

换句话说,[locations lastObject](新代表)等于newLocation(老代表)。

2. 它给你的对象数组来访问最后一个位置你
[locations lastObject]

由此
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations

3. 这里没有其他的答案中解释了为什么有一个位置阵列,以及如何将新didUpdateLocations:提供的数组。 贬低的目的locationManager:didUpdateToLocation:fromLocation:和发送位置一个NSArray,而不是在后台运行时降低功耗。 与iPhone 5开始时,GPS芯片具有存储位置的一段,然后传送在一次阵列中的他们所有的能力。这被称为延迟的位置更新。这允许主CPU进入睡眠状态,而在背景中较长的时间。的iOS不具备启动主CPU的每个位置更新时,CPU可以睡,而GPS芯片集的位置。 您可以检查这个deferredLocationUpdatesAvailable方法。如果可用,您可以启用allowDeferredLocationUpdatesUntilTraveled:timeout:方法。条件适用,看到这个答案的细节。

4. 如果你支持的iOS 5和6,你应该叫
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations,

从旧
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation

功能,通过建立的位置的阵列。

本文标题 :didUpdateLocations代替didUpdateToLocation
本文地址 :CodeGo.net/507856/ 
继续浏览 :Maven的javadoc中,插件和故障安全maven的插件缺失时生成JBoss Seam的例子

您可以会感兴趣的文章:
1. EmberJS嵌套视图和控制器
2. listview与复选框,单选按钮,TextView的和按钮无法正常工作在Android
3. 使用自定义控制台为Visual Studio控制台应用程序调试
4. 升级到4.5的Xcode后的iOS 5 SDK中消失了
5. 从基本形式访问连接字符串会导致错误的设计师
6. 在小区的空值处理
7. 无法显示在欲望的格式报告[关闭]
8. Mysql的动态触发创建存储过程
9. NoClassDefFoundError的:android/support/v4/content/LocalBroadcastManager
10. 如何正确地安装mysqlconnecter java吗?
11. 可以选择的样式元素,以便选定的选项样式显示下拉列表时,'封闭'?
12. 在JavaEE的6子进程执行
13. R和矩阵1的行
14. 旋转和尺度不变性的模板匹配在OpenCV的[复制]
15. 在列表中创建使用数据填充的等高线图
16. 安卓+PhoneGap的拦截的URL(相当于iOS的shouldStartLoadWithRequest的)
17. 泛型类与约束访问问题
18. 什么是法律约束缓存事件意思?
19. SBT:添加依赖scalatest库。在哪里?
20. 什么是PK和FK我应该分配给我的桌子吗?

IOS定位核心与地图

               

Core Location以及Map框架包通常能给我们的应用程序添加定位和地图相关的服务。Core Location框架包通常是使用硬件设备来进行定位服务的,Map框架包通常能够使你的应用程序做一些地图展示与交互的相关功能。地图的定位服务一般需要依赖设备的硬件组成部分。如果有定位的硬件设备,那么肯定是可以利用地图框架包来进行地图的一些相关的操作。

为了能够在项目中使用到位置服务以及地图展示的相关功能,你必须要导入Core Location 和Map这两个框架包。如果你不知道怎么做,那么请参照如下步骤。

1.点击你的项目工程图标文件。

2.然后选择target选项,如图1所示。

3.然后选择Build Phase模块栏。

4.然后点开Link Binary With Libraries栏目,在点击+号按钮。

图1 添加相关的框架包

5.添加MapKit.framework和CoreLocation.framework这两个库

6.在使用地图和定位的地方,导入:

#import <CoreLocation/CoreLocation.h>

#import <MapKit/MapKit.h>

MKMapView是UIView的子类,所以可以像一个普通的View一样添加到ViewController的View当中。

以下是相关的代码

ViewController.h

  1. #import <UIKit/UIKit.h> 
  2. #import <CoreLocation/CoreLocation.h> 
  3. #import <MapKit/MapKit.h> 
  4. #import "MyAnnotation.h" 
  5. @interface ViewController : UIViewController <MKMapViewDelegate,CLLocationManagerDelegate> 
  6. // MapView
  7. @property (nonatomic,strong) MKMapView *myMapView;// 地图控件 
  8. // LocationManager
  9. @property (nonatomic,strong) CLLocationManager *myLocationManager;// 位置管理器 
  10. @property (nonatomic,strong) CLGeocoder *myGeoCoder ;// 地理位置和真实地址转换 
  11. @end 

ViewController.m

  1. #import "ViewController.h" 
  2. #import "MKMapView+ZoomLevel.h"
  3. @interface ViewController ()
  4. @end
  5. @implementation ViewController
  6. @synthesize myMapView;
  7. @synthesize myLocationManager; 
  8. @synthesize myGeoCoder;
  9. - (void)viewDidLoad 
  10. {
  11.     [super viewDidLoad]; 
  12.    // Do any additional setup after loading the view, typically from a nib.
  13.     // 设置根View的背景颜色
  14. self.view.backgroundColor = [UIColor colorWithRed:0x33 / 255.0f green:0x66 / 255.0f blue:0x99 / 255.0f alpha:0xFF / 255.0f];
  15.     // 初始化MapView并且设置MapView显示的边界
  16. self.myMapView = [[MKMapView alloc]initWithFrame:self.view.bounds];
  17. // self.myMapView.mapType = MKMapTypeSatellite;
  18. // self.myMapView.mapType = MKMapTypeHybrid;
  19.     self.myMapView.mapType = MKMapTypeStandard; 
  20. self.myMapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
  21.     self.myMapView.delegate = self; 
  22.     CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(40.034122, 116.289574); 
  23. MyAnnotation *annotation = [[MyAnnotation alloc]initWithCoordinate:coordinate title:@"我的位置" subTitle:@"这里就是寡人的位置,嘿嘿!"];
  24.     annotation.pinColor = MKPinAnnotationColorPurple; 
  25.     [self.myMapView addAnnotation:annotation]; 
  26. [self.myMapView setShowsUserLocation:YES];
  27.     [self.myMapView setCenterCoordinate:coordinate zoomLevel:15 animated:YES]; 
  28.     [self.view addSubview:myMapView]; 
  29. if([CLLocationManager locationServicesEnabled]){
  30.         self.myLocationManager = [[CLLocationManager alloc]init]; 
  31. self.myLocationManager.delegate = self;
  32. // // 提示用户是否允许当前应用使用地理位置,已过时,在Info.plist中使用NSLocationUsageDescription键值替换
  33. // self.myLocationManager.purpose = @"提示用户是否允许当前应用使用位置,已过时";
  34.         [self.myLocationManager startUpdatingLocation]; 
  35. }else{
  36.         NSLog(@">>>>>>>>>> 位置服务不可用 <<<<<<<<<<<<"); 
  37. UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"提示" message:@"您的位置服务当前不可用,请打开位置服务后重试" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
  38.         [alertView show]; 
  39. }
  40.     CLLocation *location = [[CLLocation alloc]initWithLatitude:40.034122 longitude:116.289574]; 
  41.     self.myGeoCoder = [[CLGeocoder alloc]init]; 
  42. [self.myGeoCoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks,NSError *error){
  43.         if(error == nil && [placemarks count] > 0){ 
  44. CLPlacemark *pm = [placemarks objectAtIndex:0];
  45.             NSLog(@"国家:%@" ,pm.country); 
  46. NSLog(@"邮编:%@",pm.postalCode);
  47.             NSLog(@"Locality:%@",pm.locality); 
  48. }else if(error == nil && [placemarks count] == 0){
  49.             NSLog(@"没有地址返回"); 
  50. }else if(error != nil){
  51.             NSLog(@"出错了:%@",error); 
  52. }
  53.     }]; 
  54.     [self.myGeoCoder geocodeAddressString:@"中国北京市海淀区花园东路10号高德大厦" completionHandler:^(NSArray *placemarks,NSError *error){ 
  55. if(nil == error && [placemarks count] > 0){
  56.             NSLog(@"placemarks count:%i",[placemarks count]); 
  57. CLPlacemark *pm = [placemarks objectAtIndex:0];
  58.             NSLog(@"longitude=%f",pm.location.coordinate.longitude); 
  59. NSLog(@"latitude=%f",pm.location.coordinate.latitude);
  60.         }else if([placemarks count] == 0 && error == nil){ 
  61. NSLog(@"找不到给定地址的经纬度");
  62.         }else if(nil != nil){ 
  63. NSLog(@"发生了错误:%@",error);
  64.         } 
  65. }];
  66. }
  67. - (void)didReceiveMemoryWarning
  68. [super didReceiveMemoryWarning];
  69.     // Dispose of any resources that can be recreated.
  70. -(void)viewDidUnload
  71. [super viewDidUnload];
  72.     self.myMapView = nil; 
  73. [self.myLocationManager stopUpdatingLocation];
  74.     self.myLocationManager = nil; 
  75. }
  76. -(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation 
  77. {
  78.     return YES; 
  79. }
  80. /*******************************************************************************************/
  81. /*******************************************************************************************/
  82. /*************************** MapView的Delegate的方法,全部都是Option的 *************************/
  83. /*******************************************************************************************/
  84. /*******************************************************************************************/
  85. /*******************************************************************************************/
  86. - (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated {
  87.     NSLog(@"mapView:regionWillChangeAnimated:方法被调用"); 
  88. }
  89. // 用户的地理位置发生改变的时候调用
  90. - (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
  91.     NSLog(@"mapView:regionDidChangeAnimated:方法被调用"); 
  92. }
  93. // 当地图界面将要加载的时候将会调用这个方法
  94. - (void)mapViewWillStartLoadingMap:(MKMapView *)mapView{
  95.     NSLog(@"mapViewWillStartLoadingMap:方法被调用"); 
  96. }
  97. // 当地图界面加载完成的时候将要调用这个方法
  98. - (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView{
  99.     NSLog(@"mapViewDidFinishLoadingMap:方法被调用"); 
  100. }
  101. // 当地图界面加载失败的时候调用这个方法
  102. - (void)mapViewDidFailLoadingMap:(MKMapView *)mapView withError:(NSError *)error{
  103.     NSLog(@"mapViewDidFailLoadingMap:withError:方法被调用,error is:%@" , [error description]); 
  104. }
  105. // 添加到地图的Annotation
  106. // mapView:viewForAnnotation: provides the view for each annotation.
  107. // This method may be called for all or some of the added annotations.
  108. // For MapKit provided annotations (eg. MKUserLocation) return nil to use the MapKit provided annotation view.
  109. - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation 
  110. {
  111.     MKAnnotationView *view = nil; 
  112. if([annotation isKindOfClass:[MyAnnotation class]] == NO){
  113.         return view; 
  114. }
  115.     if([mapView isEqual:self.myMapView] == NO){ 
  116. return view;
  117.     } 
  118.     MyAnnotation *senderAnnotation = (MyAnnotation*)annotation; 
  119. NSString *pinReusableIdentifier = [MyAnnotation reusableIdentifierForPinColor:senderAnnotation.pinColor];
  120.     MKPinAnnotationView *annotationView = (MKPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:pinReusableIdentifier]; 
  121. if(annotationView == nil){
  122.         annotationView = [[MKPinAnnotationView alloc]initWithAnnotation:senderAnnotation reuseIdentifier:pinReusableIdentifier]; 
  123. [annotationView setCanShowCallout:YES];
  124.     } 
  125. annotationView.pinColor = senderAnnotation.pinColor;
  126.     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
  127. NSString *documentPath = [paths objectAtIndex:0];
  128.     NSString *cachePath = [documentPath stringByAppendingString:@"/images"]; 
  129. NSString *cacheFile = [cachePath stringByAppendingString:@"icon.image"];
  130. if([[NSFileManager defaultManager]fileExistsAtPath:cacheFile]){
  131.         UIImage *image = [UIImage imageWithContentsOfFile:cacheFile]; 
  132. if(image != nil){
  133.             annotationView.image = image; 
  134. NSLog(@"通过本地设置图片");
  135.         }else{ 
  136. [self setAnnotionImageByUrl:annotationView cacheFile:cacheFile];
  137.         } 
  138. }else{
  139.         [self setAnnotionImageByUrl:annotationView cacheFile:cacheFile]; 
  140. }
  141.     view = annotationView; 
  142.     return view; 
  143. }
  144. -(void) setAnnotionImageByUrl:(MKPinAnnotationView *)annotationView cacheFile:(NSString *) cacheFile{
  145.     NSLog(@"通过网络设置文件"); 
  146. dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
  147.     dispatch_async(queue, ^{ 
  148.         NSURL *url = [NSURL URLWithString:@"http://www.baidu.com/img/duanwulogo_94a0060bda0885d1c2320ca0d7d7c342.gif"]; 
  149. NSData *data = [NSData dataWithContentsOfURL:url];
  150. if(data != nil){
  151. [data writeToFile:cacheFile atomically:YES];
  152. UIImage *image = [UIImage imageWithData:data];
  153.             dispatch_queue_t mainQueue = dispatch_get_main_queue(); 
  154. dispatch_async(mainQueue, ^{
  155.                 if(image != nil){ 
  156. annotationView.image = image;
  157.                 } 
  158. });
  159.         } 
  160. });
  161. }
  162. /**
  163. // mapView:didAddAnnotationViews: is called after the annotation views have been added and positioned in the map.
  164. // The delegate can implement this method to animate the adding of the annotations views. 
  165. // Use the current positions of the annotation views as the destinations of the animation.
  166. - (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views; 
  167. // mapView:annotationView:calloutAccessoryControlTapped: is called when the user taps on left & right callout accessory UIControls. 
  168. - (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control;
  169. - (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view NS_AVAILABLE(NA, 4_0);
  170. - (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view NS_AVAILABLE(NA, 4_0); 
  171. - (void)mapViewWillStartLocatingUser:(MKMapView *)mapView NS_AVAILABLE(NA, 4_0); 
  172. - (void)mapViewDidStopLocatingUser:(MKMapView *)mapView NS_AVAILABLE(NA, 4_0);
  173. - (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation NS_AVAILABLE(NA, 4_0); 
  174. - (void)mapView:(MKMapView *)mapView didFailToLocateUserWithError:(NSError *)error NS_AVAILABLE(NA, 4_0);
  175. - (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view didChangeDragState:(MKAnnotationViewDragState)newState
  176. fromOldState:(MKAnnotationViewDragState)oldState NS_AVAILABLE(NA, 4_0); 
  177. - (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay NS_AVAILABLE(NA, 4_0); 
  178. // Called after the provided overlay views have been added and positioned in the map. 
  179. - (void)mapView:(MKMapView *)mapView didAddOverlayViews:(NSArray *)overlayViews NS_AVAILABLE(NA, 4_0);
  180. - (void)mapView:(MKMapView *)mapView didChangeUserTrackingMode:(MKUserTrackingMode)mode animated:(BOOL)animated NS_AVAILABLE(NA, 5_0);
  181. */
  182. /*******************************************************************************************/
  183. /*******************************************************************************************/
  184. /*************************** 位置相关 *************************/
  185. /*******************************************************************************************/
  186. /*******************************************************************************************/
  187. /*******************************************************************************************/
  188. -(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation 
  189. {
  190.     NSLog(@"Latitude=%f",newLocation.coordinate.latitude); 
  191. NSLog(@"Longitude=%f",newLocation.coordinate.longitude);
  192. -(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
  193.     NSLog(@"获得位置失败"); 
  194. }
  195. @end

MKMapView+ZoomLevel.h

  1. #import <MapKit/MapKit.h> 
  2. @interface MKMapView (ZoomLevel) 
  3. - (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate
  4.                   zoomLevel:(NSUInteger)zoomLevel 
  5. animated:(BOOL)animated;
  6. @end 

MKMapView+ZoomLevel.m

  1. #import "MKMapView+ZoomLevel.h" 
  2. @implementation MKMapView (ZoomLevel) 
  3. #define MERCATOR_OFFSET 268435456
  4. #define MERCATOR_RADIUS 85445659.44705395 
  5. #pragma mark - 
  6. #pragma mark Map conversion methods
  7. - (double)longitudeToPixelSpaceX:(double)longitude
  8. return round(MERCATOR_OFFSET + MERCATOR_RADIUS * longitude * M_PI / 180.0);
  9. - (double)latitudeToPixelSpaceY:(double)latitude 
  10. {
  11.     return round(MERCATOR_OFFSET - MERCATOR_RADIUS * logf((1 + sinf(latitude * M_PI / 180.0)) / (1 - sinf(latitude * M_PI / 180.0))) / 2.0); 
  12. }
  13. - (double)pixelSpaceXToLongitude:(double)pixelX
  14. return ((round(pixelX) - MERCATOR_OFFSET) / MERCATOR_RADIUS) * 180.0 / M_PI;
  15. - (double)pixelSpaceYToLatitude:(double)pixelY 
  16. {
  17.     return (M_PI / 2.0 - 2.0 * atan(exp((round(pixelY) - MERCATOR_OFFSET) / MERCATOR_RADIUS))) * 180.0 / M_PI; 
  18. }
  19. #pragma mark -
  20. #pragma mark Helper methods 
  21. - (MKCoordinateSpan)coordinateSpanWithMapView:(MKMapView *)mapView 
  22. centerCoordinate:(CLLocationCoordinate2D)centerCoordinate
  23.                                  andZoomLevel:(NSUInteger)zoomLevel 
  24. {
  25.     // convert center coordiate to pixel space
  26. double centerPixelX = [self longitudeToPixelSpaceX:centerCoordinate.longitude];
  27.     double centerPixelY = [self latitudeToPixelSpaceY:centerCoordinate.latitude]; 
  28.     // determine the scale value from the zoom level
  29. NSInteger zoomExponent = 20 - zoomLevel;
  30.     double zoomScale = pow(2, zoomExponent); 
  31.     // scale the map's size in pixel space
  32. CGSize mapSizeInPixels = mapView.bounds.size;
  33.     double scaledMapWidth = mapSizeInPixels.width * zoomScale; 
  34. double scaledMapHeight = mapSizeInPixels.height * zoomScale;
  35.     // figure out the position of the top-left pixel
  36.     double topLeftPixelX = centerPixelX - (scaledMapWidth / 2); 
  37. double topLeftPixelY = centerPixelY - (scaledMapHeight / 2);
  38.     // find delta between left and right longitudes
  39.     CLLocationDegrees minLng = [self pixelSpaceXToLongitude:topLeftPixelX]; 
  40. CLLocationDegrees maxLng = [self pixelSpaceXToLongitude:topLeftPixelX + scaledMapWidth];
  41.     CLLocationDegrees longitudeDelta = maxLng - minLng; 
  42.     // find delta between top and bottom latitudes
  43. CLLocationDegrees minLat = [self pixelSpaceYToLatitude:topLeftPixelY];
  44.     CLLocationDegrees maxLat = [self pixelSpaceYToLatitude:topLeftPixelY + scaledMapHeight]; 
  45. CLLocationDegrees latitudeDelta = -1 * (maxLat - minLat);
  46.     // create and return the lat/lng span
  47.     MKCoordinateSpan span = MKCoordinateSpanMake(latitudeDelta, longitudeDelta); 
  48. return span;
  49. #pragma mark - 
  50. #pragma mark Public methods
  51. - (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate
  52.                   zoomLevel:(NSUInteger)zoomLevel 
  53. animated:(BOOL)animated
  54.     // clamp large numbers to 28
  55.     zoomLevel = MIN(zoomLevel, 28); 
  56.     // use the zoom level to compute the region
  57. MKCoordinateSpan span = [self coordinateSpanWithMapView:self centerCoordinate:centerCoordinate andZoomLevel:zoomLevel];
  58.     MKCoordinateRegion region = MKCoordinateRegionMake(centerCoordinate, span); 
  59.     // set the region like normal
  60. [self setRegion:region animated:animated];
  61. @end

MyAnnotation.h

  1. #import <Foundation/Foundation.h> 
  2. #import <CoreLocation/CoreLocation.h>
  3. #import <MapKit/MapKit.h> 
  4. #define REUSABLE_PIN_RED @"Red" 
  5. #define REUSABLE_PIN_GREEN @"Green"
  6. #define REUSABLE_PIN_PURPLE @"Purple" 
  7. @interface MyAnnotation : NSObject <MKAnnotation> 
  8. @property (nonatomic,readonly) CLLocationCoordinate2D coordinate; 
  9. @property (nonatomic, readonly, copy) NSString *title;
  10. @property (nonatomic, readonly, copy) NSString *subtitle; 
  11. @property (nonatomic,unsafe_unretained) MKPinAnnotationColor pinColor; 
  12. -(id) initWithCoordinate:(CLLocationCoordinate2D) coordinate 
  13. title:(NSString*) paramTitle
  14.                 subTitle:(NSString*) paramSubTitle; 
  15. // 得到颜色
  16. +(NSString *) reusableIdentifierForPinColor:(MKPinAnnotationColor) paramColor; 
  17. @end 

MyAnnotation.m

  1. #import "MyAnnotation.h" 
  2. @implementation MyAnnotation 
  3. @synthesize coordinate,title,subtitle,pinColor; 
  4. -(id) initWithCoordinate 
  5. :(CLLocationCoordinate2D) paramCoordinate title:(NSString *)paramTitle subTitle:(NSString *)paramSubTitle
  6. self = [super init];
  7.     if(self != nil){ 
  8. coordinate = paramCoordinate;
  9.         title = paramTitle; 
  10. subtitle = paramSubTitle;
  11.         pinColor = MKPinAnnotationColorGreen; 
  12. }
  13. return self;
  14. +(NSString *)reusableIdentifierForPinColor:(MKPinAnnotationColor)paramColor 
  15. {
  16.     NSString *result = nil; 
  17. switch (paramColor) {
  18.         case MKPinAnnotationColorRed: 
  19. result = REUSABLE_PIN_RED;
  20.             break; 
  21. case MKPinAnnotationColorGreen:
  22.             result = REUSABLE_PIN_GREEN; 
  23. break;
  24.         case MKPinAnnotationColorPurple: 
  25. result = REUSABLE_PIN_PURPLE;
  26.     } 
  27. return result;
  28. @end 

注意,在使用用户的位置的时候,系统会弹出是否允许应用使用位置的对话框,这个对话框中的提示文字,可以自己进行定义

在系统版本是6.0(包括6.0)以上的时候,在Info.plist文件中进行定义

<key>NSLocationUsageDescription</key>

<string>是否可以使用位置?如果需要使用本应用,是必须的!</string>

在6.0以下,这样进行定义

  1. // // 提示用户是否允许当前应用使用地理位置,已过时,在Info.plist中使用NSLocationUsageDescription键值替换
  2. // self.myLocationManager.purpose = @"提示用户是否允许当前应用使用位置,已过时";

iOS 定位和地图相关推荐

  1. iOS定位服务与地图应用开发:高德地图开发

    2019独角兽企业重金招聘Python工程师标准>>> 由于博客迁移至www.coderyi.com,文章请看http://www.coderyi.com/archives/419 ...

  2. IOS定位核心与地图

    本文转载至:http://www.cnblogs.com/xinye/archive/2013/06/13/3134746.html IOS定位核心与地图                 Core L ...

  3. 转-iOS开发系列--地图与定位

    来自: http://www.cnblogs.com/kenshincui/p/4125570.html#autoid-3-4-0 概览 现在很多社交.电商.团购应用都引入了地图和定位功能,似乎地图功 ...

  4. ios 持续获取定位 高德地图_概述-iOS 定位SDK | 高德地图API

    简介 高德 iOS 定位 SDK 提供了不依赖于地图定位的定位功能,开发者可以无地图显示的场景中便捷地为应用程序添加定位功能. iOS定位SDK提供了单次定位.连续定位.逆地理信息.地理围栏等功能. ...

  5. iOS开发中地图与定位

    不管是QQ还是微信的移动client都少不了定位功能,之前在微信demo中没有加入定位功能,今天就写个定位的小demo来了解一下定位和地图的东西. 地图和定位看上去是挺高大上一东西.其有使用方法比Ta ...

  6. iOS开发之地图与定位

    无论是QQ还是微信的移动客户端都少不了定位功能,之前在微信demo中没有添加定位功能,今天就写个定位的小demo来了解一下定位和地图的东西.地图和定位看上去是挺高大上一东西,其实用法比TableVie ...

  7. ios 高德获取定位_更新日志-iOS 定位SDK | 高德地图API

    高德地图iOS 定位 SDK V2.6.7            2020-08-28 1.适配iOS14定位权限:新增"模糊定位"权限下的兼容策略: 2.修复bug,提升性能和稳 ...

  8. ios 高德获取定位_概述-iOS 定位SDK | 高德地图API

    简介 高德 iOS 定位 SDK 提供了不依赖于地图定位的定位功能,开发者可以无地图显示的场景中便捷地为应用程序添加定位功能. iOS定位SDK提供了单次定位.连续定位.逆地理信息.地理围栏等功能. ...

  9. ios 持续获取定位 高德地图_iOS 定位 高德地图

    最近项目中有需求需要使用定位,上报经纬度和地址信息,还有可以在地图界面随意选择地点,因为和后台经纬度匹配的问题,所以选择了高德地图(百度地图经纬度是有自己算法的). 1.定位 iOS定位SDK提供后台 ...

最新文章

  1. Lampiao靶机渗透测试
  2. C#调用浏览器的原理及实现浅析
  3. 查看手机截图的坐标信息
  4. 23.C语言中#if 0,#if 1,#else,#endif的作用
  5. 2020年数学与计算机科学奖获得者,2020 数学与计算机科学奖 获奖人 —— 彭实戈 - 未来科学大奖...
  6. python与数据库交互的模块pymysql
  7. 常见文件、目录、路径操作函数
  8. selenium 状态码521_sqlmap对状态码404处理的bug
  9. matlab安装程序无法启动jvm_天呀!JVM居然还有2两种运行模式
  10. 关于cmake从GitHub上下载的源码启动时报错的问题
  11. 设计模式之——工厂方法模式
  12. sql server中扩展存储过程
  13. 近千人观看live,晚8点继续安排,2个CPU过高案例+1个文件数据删除案例-Oracle故障分析的方法论+DBA能力提升要领...
  14. CentOS7.5搭建k8s集群
  15. Linux下Apache、PHP、MySQL默认安装路径
  16. 3.3V升5V电流3A-5A同步整流升压芯片
  17. 什么是物联网(IoT)?
  18. .ldb文件到底派什么用场得?
  19. 天池比赛如何使用docker提交
  20. Linux 运维一些知识点

热门文章

  1. RTX 3090 与 Tesla P40与 Tesla M40 深度学习训练速度比较
  2. Jmeter自定义函数开发-------输入参数被分割
  3. 网页打开速度很慢,怎么解决?
  4. iPhone 8价格已破发!苹果无奈只能减产
  5. 【Alpha阶段】第五次scrum meeting
  6. linux网络编程面试题
  7. python判断手机号运营商_js判断手机号运营商的方法
  8. 【优化求解】基于NSGAII算法求解含约束多目标优化问题matlab代码
  9. 基于java后台微信图书商城小程序系统 开题报告
  10. 南京考公上岸经验分享