iOS 定位和地图
2019独角兽企业重金招聘Python工程师标准>>> 
一、定位
1.1 定位概要
要实现地图、导航功能,往往需要先熟悉定位功能,在iOS中通过Core Location框架进行定位操作。Core Location自⾝可以单独使用,和地图开发框架MapKit完全是独立的,但是往往地图开发要配合定位框架使用。在Core Location 中主要包含了定位、地理编码(包括反编码)功能。
Core Location的主要功能:
1.获取经纬度
2.地理编码(根据给定的地名,获得具体的位置信息(如经纬度、地址的全称等))
3.反地理编码(根据给定的经纬度,获得具体的位置信息)
1.2 iOS 定位功能的实现
导入MapKit框架
#import
签订MKMapViewDelegate协议 ,添加成员变量
@interface ViewController () @property (nonatomic, strong) CLLocationManager* locationManager;@end
设置地图的样式
MKMapTypeStandard = 0, 平面地图MKMapTypeSatellite :卫星云图 (中图)MKMapTypeHybrid :混合模式(普通地图覆盖于卫星云图之上 )MKMapTypeSatelliteFlyover: 3D立体卫星 (iOS9.0)MKMapTypeHybridFlyover: 3D立体混合 (iOS9.0)self.mapView.mapType = MKMapTypeStandard;
是否显示用户位置
self.mapView.showsUserLocation = YES; 授权定位用户的位置,需要在info.plist文件中添加(以下二选一,两个都添加默认使用NSLocationWhenInUseUsageDescription):
- NSLocationWhenInUseUsageDescription 允许在前台使用时获取GPS的描述
- NSLocationAlwaysUsageDescription 允许永远可获取GPS的描述
if ([CLLocationManager instanceMethodForSelector:@selector(requestWhenInUseAuthorization)]) {[self.locationManager requestWhenInUseAuthorization];}
}
定位的精确度
kCLLocationAccuracyBestForNavigation // 最适合导航kCLLocationAccuracyBest; // 最好的kCLLocationAccuracyNearestTenMeters; // 10mkCLLocationAccuracyHundredMeters; // 100mkCLLocationAccuracyKilometer; // 1000mkCLLocationAccuracyThreeKilometers; // 3000m// 精确度越高, 越耗电, 定位时间越长_locationManager.desiredAccuracy = kCLLocationAccuracyBest; 每个多少米定位一次
_locationManager.distanceFilter = 10; 1.3 地理位置编码
地理编码(根据给定的地名,获得具体的位置信息(如经纬度、地址的全称等))
对应方法
- 地理编码方法-(void)geocodeAddressString:(NSString *)addressString completionHandler:(CLGeocodeCompletionHandler)completionHandler
创建编码对象
@property (strong, nonatomic) CLGeocoder *geocoder;
创建一个block作为参数传递的方式
@property (strong, nonatomic) void(^geocodeComplatHandle)(NSString *name);
在手势方法里面调用[self geocoder:coordinate2D]方法传递一个经纬度进去
- (void)geocoder:(CLLocationCoordinate2D)coordinate2D {// 创建一个经纬度位置 CLLocationCLLocation *location = [[CLLocation alloc] initWithLatitude:coordinate2D.latitude longitude:coordinate2D.longitude];// 1、通过经纬度获取对应的地理位置,查询位置是一个异步操作[self.geocoder reverseGeocodeLocation:location completionHandler:^(NSArray * _Nullable placemarks, NSError * _Nullable error) {CLPlacemark *placemark = [placemarks lastObject];NSLog(@"%@ %@ %@",placemark.name, placemark.thoroughfare,placemark.subThoroughfare);// 将地理位置名称显示在标注视图上if (self.geocodeComplatHandle) {self.geocodeComplatHandle(placemark.name,placemark.thoroughfare);}}];
} 1.4 地理位置反编码
对应方法
- 反地理编码方法-(void)reverseGeocodeLocation:(CLLocation *)location completionHandler:(CLGeocodeCompletionHandler)completionHandler
反地理编码(根据给定的经纬度,获得具体的位置信息)
- (IBAction)search:(id)sender {[self.geocoder geocodeAddressString:self.searchText.text completionHandler:^(NSArray * _Nullable placemarks, NSError * _Nullable error) {CLPlacemark *placemark = placemarks[0];//创建并添加一个标注视图到mapView上MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];annotation.coordinate = placemark.location.coordinate;//将标注添加到地图上[self.mapView addAnnotation:annotation];}];
} 二、地图
2.1 地图(MapKit的基本概念)
在iOS6以后,苹果不再使用苹果地图,⽽是使用苹果⾃己的地图。我们使用Core Location来获取⽤户的位置信息,MapKit则是⽤来显⽰具体的信息。其核心是MKMapView类的使用,我们可以设置地图显示方式,控制地图,可以在地图上添加标注。
2.2 地图类型
- MKMapTypeStandard : 平面地图
- MKMapTypeSatellite :卫星云图 (中图)
- MKMapTypeHybrid :混合模式(普通地图覆盖于卫星云图之上 )
- MKMapTypeSatelliteFlyover: 3D立体卫星 (iOS9.0)
- MKMapTypeHybridFlyover: 3D立体混合 (iOS9.0)
MKMapViewDelegate协议方法
#pragma mark - // 地图加载完成
- (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView {NSLog(@"%s %f, %f",__func__, mapView.userLocation.coordinate.longitude, mapView.userLocation.coordinate.latitude);}// 用户位置更新后调用
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {//设置中心点CLLocationCoordinate2D center = userLocation.location.coordinate;// 设置跨度MKCoordinateSpan span = {0.01,0.01};// 设置地图显示的范围[self.mapView setRegion:MKCoordinateRegionMake(center, span) animated:YES];NSLog(@"用户位置发生改变");
}
2.3 MKMapView添加标注视图
使用长按手势添加标注,创建一个长按手势,添加到mapView上面
UILongPressGestureRecognizer *longGest = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longGestAction:)];[self.mapView addGestureRecognizer:longGest];
手势方法实现
- (void)longGestAction:(UILongPressGestureRecognizer *)longGest {// 获取触摸点所在地图上的CGPoint坐标CGPoint point = [longGest locationInView:self.mapView];// 将地图所在触摸点的坐标 CGPoint 转为对应的经纬度 CLLocationCoordinate2DCLLocationCoordinate2D coordinate2D = [self.mapView convertPoint:point toCoordinateFromView:self.mapView];if (longGest.state == UIGestureRecognizerStateBegan) {// 创建并添加一个标注视图到mapView上MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];annotation.title = @"XXXX";annotation.coordinate = coordinate2D;annotation.subtitle = [NSString stringWithFormat:@"%f, %f",annotation.coordinate.latitude, annotation.coordinate.longitude];[self setGeocodeComplatHandle:^(NSString *locationName1,NSString *locationName2) {annotation.title = loationName1;annotation.subtitle = locationName2;}];// 地理位置编码方法[self geocoder:coordinate2D];// 将标注添加到地图上[self.mapView addAnnotation:annotation];}} 三、自定义标注视图
3.1 步骤:
1.⾃定义实现MKAnnotation的类并重新coordinate,title,subtitle属性。
2.实现MKMapViewDelegate的- mapView:viewForAnnotation: 方法。
自定义标注视图功能实现:
用户位置发生改变后调用
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {CLLocationCoordinate2D center = userLocation.location.coordinate;MKCoordinateSpan span = {0.05,0.05};[mapView setRegion:MKCoordinateRegionMake(center, span) animated:YES];
}
添加了标注视图后调用
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views {NSLog(@"添加了标注视图后调用");
} 添加标注视图时调用,这里可以自定义标注视图
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id)annotation {NSLog(@"viewForAnnotation");// 判断是否是用户当前的位置标注if (![annotation isKindOfClass:[MKPointAnnotation class]]) {return nil;}//设置重用标示符static NSString *identifer = @"annotation";//先从重用的队列中找MKAnnotationView *annatationView = [mapView dequeueReusableAnnotationViewWithIdentifier:identifer]; 大头针样式
// MKPinAnnotationView *annatationView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:identifer]; 是否显示辅助标注视图
annatationView.canShowCallout = YES; 设置大头针的颜色,前提是为MKPinAnnotationView类型
annatationView.pinTintColor = [UIColor orangeColor]; 设置大头针出现的动画,前提是为MKPinAnnotationView类型
annatationView.animatesDrop = YES;
使用图片作为标注
annatationView.image = [UIImage imageNamed:@"icon"]; 是否可以拖拽
annatationView.draggable = YES; 设置标注视图的偏移
annatationView.centerOffset = CGPointMake(0, -25); 设置辅助视图的偏移
annatationView.calloutOffset = CGPointMake(0, -10);UIButton *leftView = [UIButton buttonWithType:UIButtonTypeCustom];[leftView setImage:[UIImage imageNamed:@"头像"] forState:UIControlStateNormal];leftView.tag = 100;leftView.frame = CGRectMake(0, 0, 50, 50); 设置左边的辅助视图
annatationView.leftCalloutAccessoryView = leftView; 设置右边的辅助视图
annatationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeContactAdd]; 点击标注视图时调用
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view {NSLog(@"didSelectAnnotationView");
}
点击左右辅助视图时调用
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control {NSLog(@"%@",control);
}
地图开始加载时调用
- (void)mapViewWillStartLoadingMap:(MKMapView *)mapView {NSLog(@"地图开始加载时调用");
}
地图加载完成时调用
- (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView {NSLog(@"地图加载完成时调用");
}
地图加载失败时调用
- (void)mapViewDidFailLoadingMap:(MKMapView *)mapView withError:(NSError *)error {NSLog(@"地图加载失败时调用");
}
地图显示的范围将要发生改变时调用
- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated {NSLog(@"地图显示的范围将要发生改变时调用");
}
地图显示的范围改变后调用
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {NSLog(@"地图显示的范围改变后调用");
}
定位用户的位置失败
- (void)mapView:(MKMapView *)mapView didFailToLocateUserWithError:(NSError *)error {NSLog(@"定位用户的位置失败");
}
标注视图拖拽后调用
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view didChangeDragState:(MKAnnotationViewDragState)newStatefromOldState:(MKAnnotationViewDragState)oldState {/** 拖拽的状态MKAnnotationViewDragStateNone = 0, 没有拖拽MKAnnotationViewDragStateStarting, 开始拖拽MKAnnotationViewDragStateDragging, 正在拖拽MKAnnotationViewDragStateCanceling, 取消拖拽MKAnnotationViewDragStateEnding 结束拖拽**/NSLog(@"didChangeDragState");
}
转载于:https://my.oschina.net/nieqing/blog/744068
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
