iOS_mapKit与Core Location

来源:互联网 时间:1970-01-01

#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;@[email protected] 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设置delegateself.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 > 0&& longtitudeStr!= nil && longtitudeStr.length > 0){//设置经度、纬度[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.leftCalloutAccessoryViewview.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;@[email protected] 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[0];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] == 0) {NSLog(@"没有找到相应的地理信息");}else{CLPlacemark *placemark = [placemarks objectAtIndex:0];//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[0]];//调用系统地图打开一个位置[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;@[email protected] ViewController- (void)viewDidLoad {[super viewDidLoad];// 创建mapViewself.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(40, 100);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 [email protected]"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


相关阅读:
Top