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;
// 設(shè)置綠色
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]; //設(shè)置地圖的顯示風格
self.mapView.mapType = MKMapTypeStandard;
//設(shè)置地圖可縮放
self.mapView.zoomEnabled = YES;
//設(shè)置地圖可滾動
self.mapView.scrollEnabled = YES;
//設(shè)置地圖可旋轉(zhuǎn)
self.mapView.rotateEnabled = YES;
//設(shè)置顯示用戶顯示位置
self.mapView.showsUserLocation = YES;
//為MKMapView設(shè)置delegate
self.mapView.delegate = self;
// [self locateToLatitude:23.12672 longtitude:113.395];
NSLog(@"用戶當前是否位于地圖中:%d",self.mapView.userLocationVisible); }
- (IBAction)goClicked:(UIButton *)sender
{
//關(guān)閉兩個文本框的虛擬鍵盤
// [self.latitude resignFirstResponder];
// [self.longitude resignFirstResponder];
//經(jīng)度
NSString *latitudeStr = self.latitude.text;
//緯度
NSString *longtitudeStr = self.longitude.text;
//如果用戶輸入的經(jīng)度、緯度為空
if (latitudeStr != nil && latitudeStr.length >
&& longtitudeStr!= nil && longtitudeStr.length > )
{
//設(shè)置經(jīng)度、緯度
[self locateToLatitude:latitudeStr.floatValue longtitude:longtitudeStr.floatValue];
}
}
-(void)locateToLatitude:(CGFloat)latitude longtitude:(CGFloat)longitude
{
//設(shè)置地圖中的的經(jīng)度、緯度
CLLocationCoordinate2D center = {latitude,longitude};
//也可以使用如下方式設(shè)置經(jīng)度、緯度
//center.latitude = latitude;
//center.longitude = longitude;
//設(shè)置地圖顯示的范圍
MKCoordinateSpan span;
//地圖顯示范圍越小,細節(jié)越清楚;
span.latitudeDelta = 0.01;
span.longitudeDelta = 0.01;
//創(chuàng)建MKCoordinateRegion對象,該對象代表地圖的顯示中心和顯示范圍
MKCoordinateRegion region = {center,span};
//設(shè)置當前地圖的顯示中心和顯示范圍
[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];
//轉(zhuǎn)換經(jīng)緯度
CLLocationCoordinate2D coordinate = [self.mapView convertPoint:location toCoordinateFromView:self.mapView];
// 創(chuàng)建標注
MyAnnotation *annotation = [[MyAnnotation alloc]init];
annotation.coordinate = coordinate;
annotation.title = @"新的標注";
annotation.subtitle = @"開發(fā)...";
[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};
//設(shè)置顯示區(qū)域
[self.mapView setRegion:region animated:YES]; MyAnnotation *annotation = [[MyAnnotation alloc]init];
annotation.coordinate = coordinate;
annotation.title = @"中國";
annotation.subtitle = @"好牛B的地方";
//讓地圖顯示標注的區(qū)域
[self.mapView setCenterCoordinate:annotation.coordinate animated:YES]; }
//當MKMapView顯示區(qū)域?qū)⒁l(fā)生改變時激發(fā)該方法
-(void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated
{
NSLog(@"地圖控件的顯示區(qū)域要發(fā)生改變");
}
//當MKMapView顯示區(qū)域改變完成時激發(fā)該方法
-(void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
NSLog(@"地圖控件完成了改變");
}
//當?shù)貓D控件MKMapView開始加載數(shù)據(jù)時激發(fā)該方法
-(void)mapViewWillStartLoadingMap:(MKMapView *)mapView
{
NSLog(@"地圖控件開始加載地圖數(shù)據(jù)");
//創(chuàng)建MKCoordinateRegion對象,該對象代表地圖的顯示中心和顯示范圍
MKCoordinateRegion region = mapView.region;
self.latitude.text = [NSString stringWithFormat:@"%f",region.center.latitude];
self.longitude.text = [NSString stringWithFormat:@"%f",region.center.longitude]; }
//當MKMapView加載數(shù)據(jù)完成時激發(fā)該方法
-(void)mapViewDidFinishLoadingMap:(MKMapView *)mapView
{
NSLog(@"地圖控件加載地圖數(shù)據(jù)完成");
NSLog(@"%@",mapView);
}
//當MKMapView加載數(shù)據(jù)失敗時激發(fā)該方法
-(void)mapViewDidFailLoadingMap:(MKMapView *)mapView withError:(NSError *)error
{
NSLog(@"地圖控件加載地圖數(shù)據(jù)發(fā)生錯誤:錯誤信息:%@",error);
}
//當MKMapView開始渲染地圖時激發(fā)該方法
-(void)mapViewWillStartRenderingMap:(MKMapView *)mapView
{
NSLog(@"地圖控件開始渲染地圖");
}
//當MKMapView渲染地圖完成時激發(fā)該方法
-(void)mapViewDidFinishRenderingMap:(MKMapView *)mapView fullyRendered:(BOOL)fullyRendered
{
NSLog(@"地圖控件渲染完成");
}
@end
MyAnnotation.h文件內(nèi)容
#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
程序運行結(jié)果如下:
程序中還為MKMapView指定了delegate,因此該delegate將會響應(yīng)地圖位置改變、加載過程中的相關(guān)事件,所以大家可以看到Xcode的控制輸出消息。
二、根據(jù)地址定位
1.地址解析與反向地址解析
地址解析:把普通用戶能看懂的字符串地址轉(zhuǎn)換為經(jīng)度、緯度。
反向地址解析:把經(jīng)度、緯度轉(zhuǎn)換成普通的字符串地址。
iOS為地址解析提供了CLGeocoder工具類,該工具類提供了如下3種方法來進行地址解析和反向地址解析。
-geocodeAddressString:completionHandler: :根據(jù)給定的字符串地址進行解析,解析將會得到該地址對應(yīng)的經(jīng)度、緯度信息。
-geocodeAddressString:inRegion:completonHandler: :根據(jù)給定的字符串進行解析,解析將會得到該地址對應(yīng)的經(jīng)度、緯度信息。
-reverseGeocodeLocation:completionHandler: :根據(jù)給定的經(jīng)度、緯度地址方向解析得到字符串地址。
一般來說:地址解析可能得到多個結(jié)果——這是因為全球完全可能有多個同名的地點;但反向地址解析一般只會得到一個結(jié)果——因為根據(jù)指定經(jīng)度、緯度得到的地址通常是唯一的。
2.根據(jù)地址定位
根據(jù)地址定位的思路非常簡單,只要如下兩步即可。
(1)使用CLGeocoder根據(jù)字符串地址得到該地址的經(jīng)度、緯度。
(2)根據(jù)解析得到的經(jīng)度、緯度進行定位。
#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];
// 創(chuàng)建定位管理器
self.locationManager = [[CLLocationManager alloc]init];
//獲取用戶授權(quán)
[self.locationManager requestAlwaysAuthorization]; //獲取當前授權(quán)狀態(tài)
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
if (status == kCLAuthorizationStatusAuthorizedAlways || status == kCLAuthorizationStatusAuthorizedWhenInUse)
{
NSLog(@"授權(quán)通過");
}
else
{
NSLog(@"授權(quán)不通過");
}
//設(shè)置代理
self.locationManager.delegate = self;
//設(shè)置經(jīng)度
self.locationManager.desiredAccuracy =kCLLocationAccuracyBest;
//開始定位
[self.locationManager startUpdatingLocation];
}
#pragma mark - 定位管理器的代理方法
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
// NSLog(@"%@",locations);
//取出位置信息
CLLocation *location = [locations lastObject]; //創(chuàng)建地理信息編解碼對象
CLGeocoder *geoCoder = [[CLGeocoder alloc]init]; //轉(zhuǎn)換位置信息
[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(@"沒有找到相應(yīng)的地理信息");
}
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[]];
//調(diào)用系統(tǒng)地圖打開一個位置
[MKMapItem openMapsWithItems:@[mapItem1,mapItem2] launchOptions:nil];
}];
}
}];
}
@end
三、在地圖上添加錨點
1.添加簡單地錨點
對于iOS的地圖而言,添加錨點只要調(diào)用MKMapView的-(void)addAnnotation:(id<MKAnnotation>)annotation方法即可,每調(diào)用一次,就像地圖添加一個錨點。MKAnnotation是一個協(xié)議,該協(xié)議中定義了3個屬性,用于設(shè)置和返回錨點的信息。
- coordinate:用于設(shè)置和返回錨點的位置。該屬性值必須是一個CLLocationCoordinate2D結(jié)構(gòu)體變量,封裝了經(jīng)度、緯度信息。
- title:用于設(shè)置和返回錨點的標題。
- subtitle:用于設(shè)置和返回錨點的副標題。
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];
// 創(chuàng)建mapView
self.mapView = [[MKMapView alloc]initWithFrame:self.view.frame];
//設(shè)置地圖的類型
self.mapView.mapType = MKMapTypeStandard;
[self.view addSubview:self.mapView]; self.mapView.delegate = self; //創(chuàng)建標注
MyAnnoation *annoation = [[MyAnnoation alloc]init];
annoation.coordinate= CLLocationCoordinate2DMake(, );
annoation.title = @"中國";
annoation.subtitle = @"好牛B的地方";
//添加標注
[self.mapView addAnnotation:annoation]; //讓地圖顯示標注的區(qū)域
[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];
//轉(zhuǎn)換經(jīng)緯度
CLLocationCoordinate2D coordinate =[self.mapView convertPoint:location toCoordinateFromView:self.mapView];
//創(chuàng)建標注
MyAnnoation *annotation = [[MyAnnoation alloc]init];
annotation.coordinate = coordinate;
annotation.title = @"新的標注";
annotation.subtitle = @"待開發(fā)。。";
//添加標注
[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];
//如果找不到,自己創(chuàng)建
if (!view)
{
view = [[MKPinAnnotationView alloc]init];
}
//設(shè)置屬性
view.annotation = annotation;
view.canShowCallout = YES;//顯示氣泡視圖
view.pinColor = MKPinAnnotationColorPurple;//設(shè)置大頭針顏色
//顯示圖片(這種方式設(shè)置圖片會取代大頭針)
view.image = [UIImage imageNamed:@"0.png"];
//設(shè)置氣泡的輔助視圖(顯示圖片)
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
總結(jié)
以上是生活随笔為你收集整理的iOS_mapKit与Core Location的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 通过httplib2 探索的学习的最佳方
- 下一篇: 《精通C#》十四章-.NET程序集入门