生活随笔
收集整理的這篇文章主要介紹了
IOS定位核心与地图
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
?
本文轉載至:http://www.cnblogs.com/xinye/archive/2013/06/13/3134746.html
?
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 = [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 = @"提示用戶是否允許當前應用使用位置,已過時";
總結
以上是生活随笔為你收集整理的IOS定位核心与地图的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。