测试效果
实现地图定位我们需要两个类
CLLocationManager 和CLLocation
1.首先需要一个位置管理器,CLLocationManager对象locationManager,CLLocationManager *locationManager;
设置委托 locationManager.delegate =self;
2.设置精度 locationManager.desiredAccuracy =kCLLocationAccuracyBest;
desiredAccuracy类型double,因此我们可以指定他的精度为一个确却数据比如10,但是事件不能计算那么准确,或者由于其他原因都达不到我们所设置进度,因此我们指定为kCLLocationAccuracyBest表示级别最高精度,还有其他精度
kCLLocationAccuracyBestForNavigation 最高精度,这种级别用于导航程序
kCLLocationAccuracyBest 最高精度
kCLLocationAccuracyHundredMeters 精度为100米内
kCLLocationAccuracyKilometer 精度到公里范围内
kCLLocationAccuracyNearestTenMeters 精度到10米内
kCLLocationAccuracyThreeKilometers 精度到3公里范围内
3.设置距离筛选器 locationManager.distanceFilter =100;
距离筛选器,作用是当你移动一段位移后,所以移动距离大于筛选器说设置100m时候,通知委托更新位置;
但是位置一段更新过于频繁就会消耗电池电量,我们可以返回它的默认的没有筛选器模式,使用常量kCLDistanceFilterNone;
locationManager.distanceFilterkCLDistanceFilterNone
4.然后就是启动 位置管理器进行定位[locationManagerstartUpdatingLocation]; 如果我们不需要继续轮询更新位置可以使用[locationManager stopUpdatingLocation];停止更新,否则应用程序打开会一直更新,这些都需要添加委托的,遵循
CLLocationManagerDelegate协议
5.为了显示确实却是进行了定位,我们获取定位的经纬度,显示到label上,然后就是用到了CLLocation类,他有五个属性
latitude经度 longitude纬度 horizontalAccuracy水平精度(map中显示的蓝色圆半径都是以它为半径的) altitude海拔高度
verticalAccuracy 竖直高度(为负值得时候表示无法确定高度)
6.显示定位的实况地图
需要设置显示区域和显示比例,他们是两个结构体,MKCoordinateSpan ,MKCoordinateRegion
MKCoordinateRegion定义
typedef struct{
CLLocationCoordinate2D center;//表示显示的中心
MKCoordinateSpan span; //表示比例
}MKCoordinateRegion;
MKCoordinateSpan定义:
typedef struct{
CLLocationDegrees latitudeDelta;//这类型在前一节中讲过了,是double型的
CLLocationDegrees longitudeDlta;
}MKCoordinateSpan;
7.通过 region.center = newLocation.coordinate;获取定位的经纬度,然后显示到MKMapView,通过
UISegmentedControl设计了一个按钮集合来切换三种不同地图
首先我们要在工程添加支持定位和显示地图的库
CoreLocation.framework 和 MapKit.framework 添加两个头文件,对应代码
- #import <UIKit/UIKit.h>
- #import <CoreLocation/CoreLocation.h>
- #import <MapKit/MapKit.h>
- @interface LocationViewController : UIViewController<CLLocationManagerDelegate>
- @property (strong,nonatomic) CLLocationManager *locationManager;
- @property (strong,nonatomic) CLLocation *startPoint;
- @property (strong, nonatomic) IBOutlet UILabel *latitudeLabel;
- @property (strong, nonatomic) IBOutlet UILabel *longitudeLabel;
- @property (strong, nonatomic) IBOutlet UILabel *horizontalAccuracyLabel;
- @property (strong, nonatomic) IBOutlet UILabel *altitudeLabel;
- @property (strong, nonatomic) IBOutlet UILabel *verticalAccuracyLabel;
- @property (strong, nonatomic) IBOutlet UILabel *distanceTraveledLabel;
- @property (strong, nonatomic) MKMapView *mapView;
- @property (strong, nonatomic) UISegmentedControl *mapSegmentedControl;
- - (IBAction)mapViewSwitcher:(id)sender;
- -(void) selectedMapType:(id)sender;
- @end
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- locationManager = [[CLLocationManager alloc] init];
- locationManager.delegate = self;
- // 设置位置精度
- locationManager.desiredAccuracy = kCLLocationAccuracyBest;
- // 距离过滤,表示在地图上每隔100更新一次定位
- locationManager.distanceFilter = 100;
- // 启动位置管理器,进行定位服务
- [locationManager startUpdatingLocation];
- // 设置mapSegmentedControl按钮样式和显示按钮显示文字
- NSArray *mapItems = [[NSArray alloc] initWithObjects:@"街道地图",@"卫星地图",@"混合地图", nil];
- mapSegmentedControl = [[UISegmentedControl alloc] initWithItems:mapItems];
- mapSegmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
- mapSegmentedControl.frame = CGRectMake(0, 430, 180, 30);
- // 根据索引值,表示mapSegmentedControl默认响应哪个
- mapSegmentedControl.selectedSegmentIndex = 0;
- // 给mapSegmentedContol添加响应方法
- [mapSegmentedControl addTarget:self action:@selector(selectedMapType:) forControlEvents:UIControlEventValueChanged];
- }
- #pragma mark -
- #pragma mark CLLocationManagerDelegate Methods
- //获取位置信息
- -(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
- {
- if (startPoint == nil) {
- startPoint=newLocation;
- }
- // %g表示浮点数 \u00B0表示是转换字符,度的表示
- // 显示经度,将经度信息显示到Label上
- latitudeLabel.text = [NSString stringWithFormat:@"%g\u00B0",newLocation.coordinate.latitude];
- //显示纬度
- longitudeLabel.text = [NSString stringWithFormat:@"%g\u00B0",newLocation.coordinate.longitude];
- // 水平经度,也就是显示经纬度的经度
- horizontalAccuracyLabel.text = [NSString stringWithFormat:@"%gm",newLocation.horizontalAccuracy];
- //表示海拔
- altitudeLabel.text = [NSString stringWithFormat:@"%gm",newLocation.altitude];
- // 垂直经度
- verticalAccuracyLabel.text = [NSString stringWithFormat:@"%gm",newLocation.verticalAccuracy];
- // CLLocation属性CLLocationDistance的对象计算两个位置间的距离
- CLLocationDistance distance = [newLocation distanceFromLocation:startPoint];
- // 将distance显示到Label上
- distanceTraveledLabel.text = [NSString stringWithFormat:@"%gm",distance];
- // 显示比例,MKCoordinateSpan类型的结构。 它有两个程序叫做 latitudeDelta and longitudeDelta。 这两个程序被用来设定地图的缩放级别——在center周围应该显示多大的区域。
- MKCoordinateSpan span;
- span.latitudeDelta=0.05;
- span.longitudeDelta=0.05;
- MKCoordinateRegion region;
- // 获取定位的经纬度
- region.center = newLocation.coordinate;
- // 显示区域
- region.span = span;
- [mapView setRegion:region animated:YES];
- }
- //当设备无法定位当前我位置时候调用此方法
- -(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
- {
- NSString *errorType = (error.code == kCLErrorDenied)?@"Access Denied" : @"Unknown Error";
- UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error getting Location"
- message:errorType
- delegate:nil
- cancelButtonTitle:@"oKay"
- otherButtonTitles: nil];
- [alert show];
- }
- - (IBAction)mapViewSwitcher:(id)sender {
- [UIView beginAnimations:@"Curl" context:nil];
- [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
- [UIView setAnimationDuration:1.25];
- [UIView setAnimationTransition:UIViewAnimationOptionTransitionCurlUp forView:self.view cache:YES];
- mapView = [[MKMapView alloc] initWithFrame:self.view.bounds];
- // 显示用户位置
- mapView.showsUserLocation = YES;
- // mapView.mapType = MKMapTypeSatellite;
- /*
- 设置地图类型
- mapView.mapType = MKMapTypeStandard; 标准街道地图
- mapView.mapType = MKMapTypeSatellite; 卫星地图
- mapView.mapType = MKMapTypeHybrid; 混合地图
- */
- [self.view addSubview:mapView];
- [mapView addSubview:mapSegmentedControl];
- [UIView commitAnimations];
- }
- -(void)selectedMapType:(id)sender
- {
- UISegmentedControl *control = (UISegmentedControl *)sender;
- if (mapSegmentedControl) {
- if (control.selectedSegmentIndex == 0) {
- [UIView beginAnimations:@"Curl" context:nil];
- [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
- [UIView setAnimationDuration:1.25];
- [UIView setAnimationTransition:UIViewAnimationOptionTransitionCurlUp forView:self.view cache:YES];
- mapView = [[MKMapView alloc] initWithFrame:self.view.bounds];
- // 显示用户位置
- mapView.showsUserLocation = YES;
- mapView.mapType = MKMapTypeStandard;
- [self.view addSubview:mapView];
- [mapView addSubview:mapSegmentedControl];
- [UIView commitAnimations];
- NSLog(@"----0-->%d",mapSegmentedControl.selectedSegmentIndex);
- }
- else if (control.selectedSegmentIndex==1) {
- [UIView beginAnimations:@"Curl" context:nil];
- [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
- [UIView setAnimationDuration:1.25];
- [UIView setAnimationTransition:UIViewAnimationOptionTransitionCurlUp forView:self.view cache:YES];
- mapView = [[MKMapView alloc] initWithFrame:self.view.bounds];
- // 显示用户位置
- mapView.showsUserLocation = YES;
- mapView.mapType = MKMapTypeSatellite;
- // mapView.mapType = MKMapTypeSatellite;
- [self.view addSubview:mapView];
- [mapView addSubview:mapSegmentedControl];
- [UIView commitAnimations];
- NSLog(@"----1-->%d",mapSegmentedControl.selectedSegmentIndex);
- }
- else if (control.selectedSegmentIndex == 2) {
- [UIView beginAnimations:@"Curl" context:nil];
- [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
- [UIView setAnimationDuration:1.25];
- [UIView setAnimationTransition:UIViewAnimationOptionTransitionCurlUp forView:self.view cache:YES];
- mapView = [[MKMapView alloc] initWithFrame:self.view.bounds];
- // 显示用户位置
- mapView.showsUserLocation = YES;
- mapView.mapType = MKMapTypeHybrid;
- // mapView.mapType = MKMapTypeSatellite;
- [self.view addSubview:mapView];
- [mapView addSubview:mapSegmentedControl];
- [UIView commitAnimations];
- NSLog(@"----2-->%d",mapSegmentedControl.selectedSegmentIndex);
- }
- }
- }