首页 > 代码库 > IOS定位核心与地图
IOS定位核心与地图
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
- #import <UIKit/UIKit.h>
- #import <CoreLocation/CoreLocation.h>
- #import <MapKit/MapKit.h>
- #import "MyAnnotation.h"
- @interface ViewController : UIViewController <MKMapViewDelegate,CLLocationManagerDelegate>
- // MapView
- @property (nonatomic,strong) MKMapView *myMapView;// 地图控件
- // LocationManager
- @property (nonatomic,strong) CLLocationManager *myLocationManager;// 位置管理器
- @property (nonatomic,strong) CLGeocoder *myGeoCoder ;// 地理位置和真实地址转换
- @end
ViewController.m
- #import "ViewController.h"
- #import "MKMapView+ZoomLevel.h"
- @interface ViewController ()
- @end
- @implementation ViewController
- @synthesize myMapView;
- @synthesize myLocationManager;
- @synthesize myGeoCoder;
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- // Do any additional setup after loading the view, typically from a nib.
- // 设置根View的背景颜色
- self.view.backgroundColor = [UIColor colorWithRed:0x33 / 255.0f green:0x66 / 255.0f blue:0x99 / 255.0f alpha:0xFF / 255.0f];
- // 初始化MapView并且设置MapView显示的边界
- self.myMapView = [[MKMapView alloc]initWithFrame:self.view.bounds];
- // self.myMapView.mapType = MKMapTypeSatellite;
- // self.myMapView.mapType = MKMapTypeHybrid;
- self.myMapView.mapType = MKMapTypeStandard;
- self.myMapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
- self.myMapView.delegate = self;
- CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(40.034122, 116.289574);
- MyAnnotation *annotation = [[MyAnnotation alloc]initWithCoordinate:coordinate title:@"我的位置" subTitle:@"这里就是寡人的位置,嘿嘿!"];
- annotation.pinColor = MKPinAnnotationColorPurple;
- [self.myMapView addAnnotation:annotation];
- [self.myMapView setShowsUserLocation:YES];
- [self.myMapView setCenterCoordinate:coordinate zoomLevel:15 animated:YES];
- [self.view addSubview:myMapView];
- if([CLLocationManager locationServicesEnabled]){
- self.myLocationManager = [[CLLocationManager alloc]init];
- self.myLocationManager.delegate = self;
- // // 提示用户是否允许当前应用使用地理位置,已过时,在Info.plist中使用NSLocationUsageDescription键值替换
- // self.myLocationManager.purpose = @"提示用户是否允许当前应用使用位置,已过时";
- [self.myLocationManager startUpdatingLocation];
- }else{
- NSLog(@">>>>>>>>>> 位置服务不可用 <<<<<<<<<<<<");
- UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"提示" message:@"您的位置服务当前不可用,请打开位置服务后重试" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
- [alertView show];
- }
- CLLocation *location = [[CLLocation alloc]initWithLatitude:40.034122 longitude:116.289574];
- self.myGeoCoder = [[CLGeocoder alloc]init];
- [self.myGeoCoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks,NSError *error){
- if(error == nil && [placemarks count] > 0){
- CLPlacemark *pm = [placemarks objectAtIndex:0];
- NSLog(@"国家:%@" ,pm.country);
- NSLog(@"邮编:%@",pm.postalCode);
- NSLog(@"Locality:%@",pm.locality);
- }else if(error == nil && [placemarks count] == 0){
- NSLog(@"没有地址返回");
- }else if(error != nil){
- NSLog(@"出错了:%@",error);
- }
- }];
- [self.myGeoCoder geocodeAddressString:@"中国北京市海淀区花园东路10号高德大厦" completionHandler:^(NSArray *placemarks,NSError *error){
- if(nil == error && [placemarks count] > 0){
- NSLog(@"placemarks count:%i",[placemarks count]);
- CLPlacemark *pm = [placemarks objectAtIndex:0];
- NSLog(@"longitude=%f",pm.location.coordinate.longitude);
- NSLog(@"latitude=%f",pm.location.coordinate.latitude);
- }else if([placemarks count] == 0 && error == nil){
- NSLog(@"找不到给定地址的经纬度");
- }else if(nil != nil){
- NSLog(@"发生了错误:%@",error);
- }
- }];
- }
- - (void)didReceiveMemoryWarning
- {
- [super didReceiveMemoryWarning];
- // Dispose of any resources that can be recreated.
- }
- -(void)viewDidUnload
- {
- [super viewDidUnload];
- self.myMapView = nil;
- [self.myLocationManager stopUpdatingLocation];
- self.myLocationManager = nil;
- }
- -(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
- {
- return YES;
- }
- /*******************************************************************************************/
- /*******************************************************************************************/
- /*************************** MapView的Delegate的方法,全部都是Option的 *************************/
- /*******************************************************************************************/
- /*******************************************************************************************/
- /*******************************************************************************************/
- - (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated {
- NSLog(@"mapView:regionWillChangeAnimated:方法被调用");
- }
- // 用户的地理位置发生改变的时候调用
- - (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
- NSLog(@"mapView:regionDidChangeAnimated:方法被调用");
- }
- // 当地图界面将要加载的时候将会调用这个方法
- - (void)mapViewWillStartLoadingMap:(MKMapView *)mapView{
- NSLog(@"mapViewWillStartLoadingMap:方法被调用");
- }
- // 当地图界面加载完成的时候将要调用这个方法
- - (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView{
- NSLog(@"mapViewDidFinishLoadingMap:方法被调用");
- }
- // 当地图界面加载失败的时候调用这个方法
- - (void)mapViewDidFailLoadingMap:(MKMapView *)mapView withError:(NSError *)error{
- NSLog(@"mapViewDidFailLoadingMap:withError:方法被调用,error is:%@" , [error description]);
- }
- // 添加到地图的Annotation
- // mapView:viewForAnnotation: provides the view for each annotation.
- // This method may be called for all or some of the added annotations.
- // For MapKit provided annotations (eg. MKUserLocation) return nil to use the MapKit provided annotation view.
- - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
- {
- MKAnnotationView *view = nil;
- if([annotation isKindOfClass:[MyAnnotation class]] == NO){
- return view;
- }
- if([mapView isEqual:self.myMapView] == NO){
- return view;
- }
- MyAnnotation *senderAnnotation = (MyAnnotation*)annotation;
- NSString *pinReusableIdentifier = [MyAnnotation reusableIdentifierForPinColor:senderAnnotation.pinColor];
- MKPinAnnotationView *annotationView = (MKPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:pinReusableIdentifier];
- if(annotationView == nil){
- annotationView = [[MKPinAnnotationView alloc]initWithAnnotation:senderAnnotation reuseIdentifier:pinReusableIdentifier];
- [annotationView setCanShowCallout:YES];
- }
- annotationView.pinColor = senderAnnotation.pinColor;
- NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
- NSString *documentPath = [paths objectAtIndex:0];
- NSString *cachePath = [documentPath stringByAppendingString:@"/images"];
- NSString *cacheFile = [cachePath stringByAppendingString:@"icon.image"];
- if([[NSFileManager defaultManager]fileExistsAtPath:cacheFile]){
- UIImage *image = [UIImage imageWithContentsOfFile:cacheFile];
- if(image != nil){
- annotationView.image = image;
- NSLog(@"通过本地设置图片");
- }else{
- [self setAnnotionImageByUrl:annotationView cacheFile:cacheFile];
- }
- }else{
- [self setAnnotionImageByUrl:annotationView cacheFile:cacheFile];
- }
- view = annotationView;
- return view;
- }
- -(void) setAnnotionImageByUrl:(MKPinAnnotationView *)annotationView cacheFile:(NSString *) cacheFile{
- NSLog(@"通过网络设置文件");
- dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
- dispatch_async(queue, ^{
- NSURL *url = [NSURL URLWithString:@"http://www.baidu.com/img/duanwulogo_94a0060bda0885d1c2320ca0d7d7c342.gif"];
- NSData *data = http://www.mamicode.com/[NSData dataWithContentsOfURL:url];
- if(data != nil){
- [data writeToFile:cacheFile atomically:YES];
- UIImage *image = [UIImage imageWithData:data];
- dispatch_queue_t mainQueue = dispatch_get_main_queue();
- dispatch_async(mainQueue, ^{
- if(image != nil){
- annotationView.image = image;
- }
- });
- }
- });
- }
- /**
- // mapView:didAddAnnotationViews: is called after the annotation views have been added and positioned in the map.
- // The delegate can implement this method to animate the adding of the annotations views.
- // Use the current positions of the annotation views as the destinations of the animation.
- - (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views;
- // mapView:annotationView:calloutAccessoryControlTapped: is called when the user taps on left & right callout accessory UIControls.
- - (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control;
- - (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view NS_AVAILABLE(NA, 4_0);
- - (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view NS_AVAILABLE(NA, 4_0);
- - (void)mapViewWillStartLocatingUser:(MKMapView *)mapView NS_AVAILABLE(NA, 4_0);
- - (void)mapViewDidStopLocatingUser:(MKMapView *)mapView NS_AVAILABLE(NA, 4_0);
- - (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation NS_AVAILABLE(NA, 4_0);
- - (void)mapView:(MKMapView *)mapView didFailToLocateUserWithError:(NSError *)error NS_AVAILABLE(NA, 4_0);
- - (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view didChangeDragState:(MKAnnotationViewDragState)newState
- fromOldState:(MKAnnotationViewDragState)oldState NS_AVAILABLE(NA, 4_0);
- - (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay NS_AVAILABLE(NA, 4_0);
- // Called after the provided overlay views have been added and positioned in the map.
- - (void)mapView:(MKMapView *)mapView didAddOverlayViews:(NSArray *)overlayViews NS_AVAILABLE(NA, 4_0);
- - (void)mapView:(MKMapView *)mapView didChangeUserTrackingMode:(MKUserTrackingMode)mode animated:(BOOL)animated NS_AVAILABLE(NA, 5_0);
- */
- /*******************************************************************************************/
- /*******************************************************************************************/
- /*************************** 位置相关 *************************/
- /*******************************************************************************************/
- /*******************************************************************************************/
- /*******************************************************************************************/
- -(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
- {
- NSLog(@"Latitude=%f",newLocation.coordinate.latitude);
- NSLog(@"Longitude=%f",newLocation.coordinate.longitude);
- }
- -(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
- {
- NSLog(@"获得位置失败");
- }
- @end
MKMapView+ZoomLevel.h
- #import <MapKit/MapKit.h>
- @interface MKMapView (ZoomLevel)
- - (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate
- zoomLevel:(NSUInteger)zoomLevel
- animated:(BOOL)animated;
- @end
MKMapView+ZoomLevel.m
- #import "MKMapView+ZoomLevel.h"
- @implementation MKMapView (ZoomLevel)
- #define MERCATOR_OFFSET 268435456
- #define MERCATOR_RADIUS 85445659.44705395
- #pragma mark -
- #pragma mark Map conversion methods
- - (double)longitudeToPixelSpaceX:(double)longitude
- {
- return round(MERCATOR_OFFSET + MERCATOR_RADIUS * longitude * M_PI / 180.0);
- }
- - (double)latitudeToPixelSpaceY:(double)latitude
- {
- return round(MERCATOR_OFFSET - MERCATOR_RADIUS * logf((1 + sinf(latitude * M_PI / 180.0)) / (1 - sinf(latitude * M_PI / 180.0))) / 2.0);
- }
- - (double)pixelSpaceXToLongitude:(double)pixelX
- {
- return ((round(pixelX) - MERCATOR_OFFSET) / MERCATOR_RADIUS) * 180.0 / M_PI;
- }
- - (double)pixelSpaceYToLatitude:(double)pixelY
- {
- return (M_PI / 2.0 - 2.0 * atan(exp((round(pixelY) - MERCATOR_OFFSET) / MERCATOR_RADIUS))) * 180.0 / M_PI;
- }
- #pragma mark -
- #pragma mark Helper methods
- - (MKCoordinateSpan)coordinateSpanWithMapView:(MKMapView *)mapView
- centerCoordinate:(CLLocationCoordinate2D)centerCoordinate
- andZoomLevel:(NSUInteger)zoomLevel
- {
- // convert center coordiate to pixel space
- double centerPixelX = [self longitudeToPixelSpaceX:centerCoordinate.longitude];
- double centerPixelY = [self latitudeToPixelSpaceY:centerCoordinate.latitude];
- // determine the scale value from the zoom level
- NSInteger zoomExponent = 20 - zoomLevel;
- double zoomScale = pow(2, zoomExponent);
- // scale the map‘s size in pixel space
- CGSize mapSizeInPixels = mapView.bounds.size;
- double scaledMapWidth = mapSizeInPixels.width * zoomScale;
- double scaledMapHeight = mapSizeInPixels.height * zoomScale;
- // figure out the position of the top-left pixel
- double topLeftPixelX = centerPixelX - (scaledMapWidth / 2);
- double topLeftPixelY = centerPixelY - (scaledMapHeight / 2);
- // find delta between left and right longitudes
- CLLocationDegrees minLng = [self pixelSpaceXToLongitude:topLeftPixelX];
- CLLocationDegrees maxLng = [self pixelSpaceXToLongitude:topLeftPixelX + scaledMapWidth];
- CLLocationDegrees longitudeDelta = maxLng - minLng;
- // find delta between top and bottom latitudes
- CLLocationDegrees minLat = [self pixelSpaceYToLatitude:topLeftPixelY];
- CLLocationDegrees maxLat = [self pixelSpaceYToLatitude:topLeftPixelY + scaledMapHeight];
- CLLocationDegrees latitudeDelta = -1 * (maxLat - minLat);
- // create and return the lat/lng span
- MKCoordinateSpan span = MKCoordinateSpanMake(latitudeDelta, longitudeDelta);
- return span;
- }
- #pragma mark -
- #pragma mark Public methods
- - (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate
- zoomLevel:(NSUInteger)zoomLevel
- animated:(BOOL)animated
- {
- // clamp large numbers to 28
- zoomLevel = MIN(zoomLevel, 28);
- // use the zoom level to compute the region
- MKCoordinateSpan span = [self coordinateSpanWithMapView:self centerCoordinate:centerCoordinate andZoomLevel:zoomLevel];
- MKCoordinateRegion region = MKCoordinateRegionMake(centerCoordinate, span);
- // set the region like normal
- [self setRegion:region animated:animated];
- }
- @end
MyAnnotation.h
- #import <Foundation/Foundation.h>
- #import <CoreLocation/CoreLocation.h>
- #import <MapKit/MapKit.h>
- #define REUSABLE_PIN_RED @"Red"
- #define REUSABLE_PIN_GREEN @"Green"
- #define REUSABLE_PIN_PURPLE @"Purple"
- @interface MyAnnotation : NSObject <MKAnnotation>
- @property (nonatomic,readonly) CLLocationCoordinate2D coordinate;
- @property (nonatomic, readonly, copy) NSString *title;
- @property (nonatomic, readonly, copy) NSString *subtitle;
- @property (nonatomic,unsafe_unretained) MKPinAnnotationColor pinColor;
- -(id) initWithCoordinate:(CLLocationCoordinate2D) coordinate
- title:(NSString*) paramTitle
- subTitle:(NSString*) paramSubTitle;
- // 得到颜色
- +(NSString *) reusableIdentifierForPinColor:(MKPinAnnotationColor) paramColor;
- @end
MyAnnotation.m
- #import "MyAnnotation.h"
- @implementation MyAnnotation
- @synthesize coordinate,title,subtitle,pinColor;
- -(id) initWithCoordinate
- :(CLLocationCoordinate2D) paramCoordinate title:(NSString *)paramTitle subTitle:(NSString *)paramSubTitle
- {
- self = [super init];
- if(self != nil){
- coordinate = paramCoordinate;
- title = paramTitle;
- subtitle = paramSubTitle;
- pinColor = MKPinAnnotationColorGreen;
- }
- return self;
- }
- +(NSString *)reusableIdentifierForPinColor:(MKPinAnnotationColor)paramColor
- {
- NSString *result = nil;
- switch (paramColor) {
- case MKPinAnnotationColorRed:
- result = REUSABLE_PIN_RED;
- break;
- case MKPinAnnotationColorGreen:
- result = REUSABLE_PIN_GREEN;
- break;
- case MKPinAnnotationColorPurple:
- result = REUSABLE_PIN_PURPLE;
- }
- return result;
- }
- @end
注意,在使用用户的位置的时候,系统会弹出是否允许应用使用位置的对话框,这个对话框中的提示文字,可以自己进行定义
在系统版本是6.0(包括6.0)以上的时候,在Info.plist文件中进行定义
<key>NSLocationUsageDescription</key>
<string>是否可以使用位置?如果需要使用本应用,是必须的!</string>
在6.0以下,这样进行定义
- // // 提示用户是否允许当前应用使用地理位置,已过时,在Info.plist中使用NSLocationUsageDescription键值替换
- // self.myLocationManager.purpose = @"提示用户是否允许当前应用使用位置,已过时";
- 原文:http://www.cnblogs.com/xinye/archive/2013/06/13/3134746.html
IOS定位核心与地图