iOS_mapKit与Core Location
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
static NSString *ID = @"anno";
MKPinAnnotationView *annoView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:ID];
if (annoView == nil) {
annoView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:ID];
// 顯示氣泡
annoView.canShowCallout = YES;
// 設置綠色
annoView.pinColor = MKPinAnnotationColorGreen;
} return annoView;
}
#import "ViewController.h"
#import <MapKit/MapKit.h>
#import "MyAnnotation.h"
@interface ViewController ()<MKMapViewDelegate>
@property (weak, nonatomic) IBOutlet MKMapView *mapView; @property (weak, nonatomic) IBOutlet UITextField *latitude;
@property (weak, nonatomic) IBOutlet UITextField *longitude; @end @implementation ViewController - (void)viewDidLoad
{
[super viewDidLoad]; //設置地圖的顯示風格
self.mapView.mapType = MKMapTypeStandard;
//設置地圖可縮放
self.mapView.zoomEnabled = YES;
//設置地圖可滾動
self.mapView.scrollEnabled = YES;
//設置地圖可旋轉
self.mapView.rotateEnabled = YES;
//設置顯示用戶顯示位置
self.mapView.showsUserLocation = YES;
//為MKMapView設置delegate
self.mapView.delegate = self;
// [self locateToLatitude:23.12672 longtitude:113.395];
NSLog(@"用戶當前是否位于地圖中:%d",self.mapView.userLocationVisible); }
- (IBAction)goClicked:(UIButton *)sender
{
//關閉兩個文本框的虛擬鍵盤
// [self.latitude resignFirstResponder];
// [self.longitude resignFirstResponder];
//經度
NSString *latitudeStr = self.latitude.text;
//緯度
NSString *longtitudeStr = self.longitude.text;
//如果用戶輸入的經度、緯度為空
if (latitudeStr != nil && latitudeStr.length >
&& longtitudeStr!= nil && longtitudeStr.length > )
{
//設置經度、緯度
[self locateToLatitude:latitudeStr.floatValue longtitude:longtitudeStr.floatValue];
}
}
-(void)locateToLatitude:(CGFloat)latitude longtitude:(CGFloat)longitude
{
//設置地圖中的的經度、緯度
CLLocationCoordinate2D center = {latitude,longitude};
//也可以使用如下方式設置經度、緯度
//center.latitude = latitude;
//center.longitude = longitude;
//設置地圖顯示的范圍
MKCoordinateSpan span;
//地圖顯示范圍越小,細節越清楚;
span.latitudeDelta = 0.01;
span.longitudeDelta = 0.01;
//創建MKCoordinateRegion對象,該對象代表地圖的顯示中心和顯示范圍
MKCoordinateRegion region = {center,span};
//設置當前地圖的顯示中心和顯示范圍
[self.mapView setRegion:region animated:YES]; UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longPress:)];
[self.mapView addGestureRecognizer:longPress];
} -(void)longPress:(UILongPressGestureRecognizer *)sender
{
CGPoint location = [sender locationInView:self.mapView];
//轉換經緯度
CLLocationCoordinate2D coordinate = [self.mapView convertPoint:location toCoordinateFromView:self.mapView];
// 創建標注
MyAnnotation *annotation = [[MyAnnotation alloc]init];
annotation.coordinate = coordinate;
annotation.title = @"新的標注";
annotation.subtitle = @"開發...";
[self.mapView addAnnotation:annotation];
}
#pragma mark - mapView代理方法 #pragma mark 顯示標注視圖
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
static NSString *annotationID = @"annotation";
MKPinAnnotationView *view = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:annotationID];
if (!view)
{
view = [[MKPinAnnotationView alloc]init];
}
view.annotation = annotation;
// view.leftCalloutAccessoryView
view.pinColor = MKPinAnnotationColorGreen;
view.canShowCallout = YES;
return view;
}
#pragma mark 代理方法
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{ CLLocationCoordinate2D coordinate = userLocation.location.coordinate;
MKCoordinateSpan span = {0.001,0.001};
MKCoordinateRegion region = {coordinate,span};
//設置顯示區域
[self.mapView setRegion:region animated:YES]; MyAnnotation *annotation = [[MyAnnotation alloc]init];
annotation.coordinate = coordinate;
annotation.title = @"中國";
annotation.subtitle = @"好牛B的地方";
//讓地圖顯示標注的區域
[self.mapView setCenterCoordinate:annotation.coordinate animated:YES]; }
//當MKMapView顯示區域將要發生改變時激發該方法
-(void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated
{
NSLog(@"地圖控件的顯示區域要發生改變");
}
//當MKMapView顯示區域改變完成時激發該方法
-(void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
NSLog(@"地圖控件完成了改變");
}
//當地圖控件MKMapView開始加載數據時激發該方法
-(void)mapViewWillStartLoadingMap:(MKMapView *)mapView
{
NSLog(@"地圖控件開始加載地圖數據");
//創建MKCoordinateRegion對象,該對象代表地圖的顯示中心和顯示范圍
MKCoordinateRegion region = mapView.region;
self.latitude.text = [NSString stringWithFormat:@"%f",region.center.latitude];
self.longitude.text = [NSString stringWithFormat:@"%f",region.center.longitude]; }
//當MKMapView加載數據完成時激發該方法
-(void)mapViewDidFinishLoadingMap:(MKMapView *)mapView
{
NSLog(@"地圖控件加載地圖數據完成");
NSLog(@"%@",mapView);
}
//當MKMapView加載數據失敗時激發該方法
-(void)mapViewDidFailLoadingMap:(MKMapView *)mapView withError:(NSError *)error
{
NSLog(@"地圖控件加載地圖數據發生錯誤:錯誤信息:%@",error);
}
//當MKMapView開始渲染地圖時激發該方法
-(void)mapViewWillStartRenderingMap:(MKMapView *)mapView
{
NSLog(@"地圖控件開始渲染地圖");
}
//當MKMapView渲染地圖完成時激發該方法
-(void)mapViewDidFinishRenderingMap:(MKMapView *)mapView fullyRendered:(BOOL)fullyRendered
{
NSLog(@"地圖控件渲染完成");
}
@end
MyAnnotation.h文件內容
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
@interface MyAnnotation : NSObject<MKAnnotation>
@property(copy,nonatomic)NSString *title;
@property(copy,nonatomic)NSString *subtitle;
@property(assign,nonatomic)CLLocationCoordinate2D coordinate;
@end
程序運行結果如下:
程序中還為MKMapView指定了delegate,因此該delegate將會響應地圖位置改變、加載過程中的相關事件,所以大家可以看到Xcode的控制輸出消息。
二、根據地址定位
1.地址解析與反向地址解析
地址解析:把普通用戶能看懂的字符串地址轉換為經度、緯度。
反向地址解析:把經度、緯度轉換成普通的字符串地址。
iOS為地址解析提供了CLGeocoder工具類,該工具類提供了如下3種方法來進行地址解析和反向地址解析。
-geocodeAddressString:completionHandler: :根據給定的字符串地址進行解析,解析將會得到該地址對應的經度、緯度信息。
-geocodeAddressString:inRegion:completonHandler: :根據給定的字符串進行解析,解析將會得到該地址對應的經度、緯度信息。
-reverseGeocodeLocation:completionHandler: :根據給定的經度、緯度地址方向解析得到字符串地址。
一般來說:地址解析可能得到多個結果——這是因為全球完全可能有多個同名的地點;但反向地址解析一般只會得到一個結果——因為根據指定經度、緯度得到的地址通常是唯一的。
2.根據地址定位
根據地址定位的思路非常簡單,只要如下兩步即可。
(1)使用CLGeocoder根據字符串地址得到該地址的經度、緯度。
(2)根據解析得到的經度、緯度進行定位。
#import "ViewController.h"
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h> @interface ViewController ()<CLLocationManagerDelegate>
@property(strong,nonatomic)CLLocationManager *locationManager;
@end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad];
// 創建定位管理器
self.locationManager = [[CLLocationManager alloc]init];
//獲取用戶授權
[self.locationManager requestAlwaysAuthorization]; //獲取當前授權狀態
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
if (status == kCLAuthorizationStatusAuthorizedAlways || status == kCLAuthorizationStatusAuthorizedWhenInUse)
{
NSLog(@"授權通過");
}
else
{
NSLog(@"授權不通過");
}
//設置代理
self.locationManager.delegate = self;
//設置經度
self.locationManager.desiredAccuracy =kCLLocationAccuracyBest;
//開始定位
[self.locationManager startUpdatingLocation];
}
#pragma mark - 定位管理器的代理方法
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
// NSLog(@"%@",locations);
//取出位置信息
CLLocation *location = [locations lastObject]; //創建地理信息編解碼對象
CLGeocoder *geoCoder = [[CLGeocoder alloc]init]; //轉換位置信息
[geoCoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
// NSLog(@"%@",placemarks[0]);
CLPlacemark *placeMark = placemarks[];
NSLog(@"%@%@",placeMark.country,placeMark.locality);
}];
}
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(@"%@",error);
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
CLGeocoder *geoCoder = [[CLGeocoder alloc]init];
[geoCoder geocodeAddressString:@"西三旗" completionHandler:^(NSArray *placemarks, NSError *error) {
if ([placemarks count] == ) {
NSLog(@"沒有找到相應的地理信息");
}
else
{
CLPlacemark *placemark = [placemarks objectAtIndex:];
//NSLog(@"%@",placeMark);
// NSLog(@"%f,%f",placeMark.location.coordinate.latitude,placeMark.location.coordinate.longitude); MKMapItem *mapItem1 = [[MKMapItem alloc]initWithPlacemark:(MKPlacemark*)placemark];
[geoCoder geocodeAddressString:@"八達嶺長城" completionHandler:^(NSArray *placemarks, NSError *error) {
MKMapItem *mapItem2 = [[MKMapItem alloc]initWithPlacemark:(MKPlacemark*)placemarks[]];
//調用系統地圖打開一個位置
[MKMapItem openMapsWithItems:@[mapItem1,mapItem2] launchOptions:nil];
}];
}
}];
}
@end
三、在地圖上添加錨點
1.添加簡單地錨點
對于iOS的地圖而言,添加錨點只要調用MKMapView的-(void)addAnnotation:(id<MKAnnotation>)annotation方法即可,每調用一次,就像地圖添加一個錨點。MKAnnotation是一個協議,該協議中定義了3個屬性,用于設置和返回錨點的信息。
- coordinate:用于設置和返回錨點的位置。該屬性值必須是一個CLLocationCoordinate2D結構體變量,封裝了經度、緯度信息。
- title:用于設置和返回錨點的標題。
- subtitle:用于設置和返回錨點的副標題。
2.添加自定義錨點
錨點由兩部分組成。
錨點信息:錨點信息包括錨點的位置、標題、副標題等信息,這些信息有MKAnnotation對象代表。
錨點控件:錨點控件決定地圖上顯示的錨點外觀,包括錨點的圖片等。
iOS為錨點控件提供了MKAnnotationView和MKPinAnnotationView,其中MKPinAnnotationView是MKAnnotationView的子類,而MKAnnotationView繼承了UIView——也就是說,它只是一個可視化的UI控件。
為定制地圖上的錨點,需要完成如下兩步。
1.為MKMapView指定delegate對象。
2.重寫delegatede-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation方法,該方法的返回值將作為地圖上的錨點控件。
案例:在圖上添加錨點
#import "ViewController.h"
#import <MapKit/MapKit.h>
#import "MyAnnoation.h"
@interface ViewController ()<MKMapViewDelegate>
@property(strong,nonatomic)MKMapView *mapView; @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad];
// 創建mapView
self.mapView = [[MKMapView alloc]initWithFrame:self.view.frame];
//設置地圖的類型
self.mapView.mapType = MKMapTypeStandard;
[self.view addSubview:self.mapView]; self.mapView.delegate = self; //創建標注
MyAnnoation *annoation = [[MyAnnoation alloc]init];
annoation.coordinate= CLLocationCoordinate2DMake(, );
annoation.title = @"中國";
annoation.subtitle = @"好牛B的地方";
//添加標注
[self.mapView addAnnotation:annoation]; //讓地圖顯示標注的區域
[self.mapView setCenterCoordinate:annoation.coordinate animated:YES]; //添加手勢
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longPress:)];
[self.mapView addGestureRecognizer:longPress];
}
-(void)longPress:(UILongPressGestureRecognizer *)sender
{ //獲取當前位置
CGPoint location = [sender locationInView:self.view];
//轉換經緯度
CLLocationCoordinate2D coordinate =[self.mapView convertPoint:location toCoordinateFromView:self.mapView];
//創建標注
MyAnnoation *annotation = [[MyAnnoation alloc]init];
annotation.coordinate = coordinate;
annotation.title = @"新的標注";
annotation.subtitle = @"待開發。。";
//添加標注
[self.mapView addAnnotation:annotation]; }
#pragma mark - mapView代理方法
#pragma mark 顯示標注視圖
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
static NSString *annotationID =@"annotation";
//先從重用隊列中去找
MKPinAnnotationView *view = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:annotationID];
//如果找不到,自己創建
if (!view)
{
view = [[MKPinAnnotationView alloc]init];
}
//設置屬性
view.annotation = annotation;
view.canShowCallout = YES;//顯示氣泡視圖
view.pinColor = MKPinAnnotationColorPurple;//設置大頭針顏色
//顯示圖片(這種方式設置圖片會取代大頭針)
view.image = [UIImage imageNamed:@"0.png"];
//設置氣泡的輔助視圖(顯示圖片)
view.leftCalloutAccessoryView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"0.png"]];
return view;
}
#pragma mark 選中了標注后的處理 -(void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
NSLog(@"選中了標注");
}
-(void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view
{
NSLog(@"取消了標注");
}
@end
總結
以上是生活随笔為你收集整理的iOS_mapKit与Core Location的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 通过httplib2 探索的学习的最佳方
- 下一篇: BI三大服务知识点