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

定位服务实例

wps_clip_image-13869

项目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类使用。

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

wps_clip_image-5334

地图开发一般过程

wps_clip_image-6593

wps_clip_image-616

添加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:nil
                          cancelButtonTitle:@"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:annotation
                                                          reuseIdentifier:@"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地图。

wps_clip_image-3276

 

 

复制代码
- (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栏目,在点击+号按钮。

添加相关的框架包

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.  
  6. @interface ViewController : UIViewController <MKMapViewDelegate,CLLocationManagerDelegate> 
  7.  
  8. // MapView
  9. @property (nonatomic,strong) MKMapView *myMapView;// 地图控件 
  10. // LocationManager
  11. @property (nonatomic,strong) CLLocationManager *myLocationManager;// 位置管理器 
  12. @property (nonatomic,strong) CLGeocoder *myGeoCoder ;// 地理位置和真实地址转换 
  13. @end 

 

ViewController.m

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

MKMapView+ZoomLevel.h

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

 

MKMapView+ZoomLevel.m

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

MyAnnotation.h

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

 

MyAnnotation.m

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

 

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

 

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

<key>NSLocationUsageDescription</key>

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

 

在6.0以下,这样进行定义

  1. // // 提示用户是否允许当前应用使用地理位置,已过时,在Info.plist中使用NSLocationUsageDescription键值替换
  2. // self.myLocationManager.purpose = @"提示用户是否允许当前应用使用位置,已过时";
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值