首页 > 代码库 > 地图(基本应用,location管理器,注解)

地图(基本应用,location管理器,注解)

#import "ViewController.h"
#import <MapKit/MapKit.h>

@interface ViewController () <CLLocationManagerDelegate,MKMapViewDelegate>

//这里为什么要把它设置成为属性?为了就是解决强引用的问题,如果不设置,locationManger会在花括号之后,就会释放掉,这样就看不到了我们想要的地址改变信息,arc情况下,解决办法只有把它设置为成员属性
@property (retain,nonatomic) CLLocationManager *locationManger;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    
//   创建显示地图的视图MKMapView
    MKMapView *map = [[MKMapView alloc]initWithFrame:self.view.bounds];
   

//    这里打了一个tag,用于以后识别要显示的地图试图
    map.tag = 1000;
    

//    设置span
//    span 指的是显示地图精确度,值越小显示的地图数据越精确,越详细,如果值越大, 则显示的区域越大
    MKCoordinateSpan span ={0.1,0.1};
    //    结构体的第二种赋值方法
    //    MKCoordinateSpan span2;
    //    span2.latitudeDelta = 100;
    //    span2.longitudeDelta = 100;
    
    //    采用C函数来创建结构体的具体数据
    //    MKCoordinateSpan span3;
    //    span3 = MKCoordinateSpanMake(100, 100);
    
    /*
     *在OC环境下 对于结构体变量的赋值,有三种方式:
     1?初始化的时候, 直接采用花括号语法, 在花括里,按结构体声明的顺序依次赋值
     2?先声明结构体变量,可以使用点语法,来指定相对应的成员变量的值
     3?采用SDK的C 函数直接完成设置
     */

    
//    设置经纬度————是地图当前显示位置的地理坐标
    CLLocationCoordinate2D coordinate = {34.7568711,113.663221};
    
    
//    设置题图上显示的区域,这里需要设置两个参数————CLLocationCoordinate2D还有MKCoordinateSpan
    MKCoordinateRegion region = {coordinate,span};
    
//    设置显示界面的region就是上面的MKCoordinateRegion
    map.region = region;
   
//    显示当前位置
    map.showsUserLocation =YES;
//     可放大缩小
    map.zoomEnabled = YES;
//     可滑动
    map.scrollEnabled = YES;
   
//    设置显示的地图的类型————————三种类型
    //    显示卫星地图
//        map.mapType = MKMapTypeSatellite;
    //    显示卫星地图和标准地图的混合
    //    map.mapType = MKMapTypeHybrid;
    //    显示标准也就是普通地图,这是默认地图类型
        map.mapType = MKMapTypeStandard;
    
    [self.view addSubview:map];
    
//    添加地图的地址管理器————CLLocationManager
   self.locationManger = [[CLLocationManager alloc] init];
    
//    当设备移动每超过distanceFilter设置的米数时,就会更新一次位置信息。
//    理解为地图的位置移动一定距离,地图的信息就会更新
    self.locationManger.distanceFilter = 100;

//   地图位置信息的精确度,这里设置为best,精确度就是意味着在10米之内
//    extern const CLLocationAccuracy kCLLocationAccuracyBestForNavigation;
//    extern const CLLocationAccuracy kCLLocationAccuracyBest;
//    extern const CLLocationAccuracy kCLLocationAccuracyNearestTenMeters;
//    extern const CLLocationAccuracy kCLLocationAccuracyHundredMeters;
//    extern const CLLocationAccuracy kCLLocationAccuracyKilometer;
//    extern const CLLocationAccuracy kCLLocationAccuracyThreeKilometers;
    
    self.locationManger.desiredAccuracy = kCLLocationAccuracyBest;
    
//    设置代理
    
    self.locationManger.delegate = self;
    
//    这一句不能忘,只有设置了startUpdatingLocation,才能运行
    [self.locationManger startUpdatingLocation];
 
//   注解类很重要,如果想自定义地图上的一些文本和图标,就必须用到——————注解
//  注解类,用于提供注解数据,真正用于显示注解视图,需要在委托方法去创建
    MKPointAnnotation *pointAnnotation = [[MKPointAnnotation alloc]init];
    
    
    pointAnnotation.title = @"河南省";
    pointAnnotation.subtitle = @"郑州市";

    //   设置注解的位置,这里就需要用到————coordinate
    pointAnnotation.coordinate =CLLocationCoordinate2DMake(34.7568711,113.663221);
    
//    把注解加到地图视图上
    [map addAnnotation:pointAnnotation];

}

#pragma mark -
#pragma mark CLLocationManagerDelegate
//第一个参数,表示是哪个地址管理器
//第二个参数,表示当位置更新的时候, 新位置信息。
//第三个参数,表示位置更新时, 老的位置信息。


//   这里要做到的效果是——————做到位置的改变,地图显示随着位置的改变,转变视图的界面
- (void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
           fromLocation:(CLLocation *)oldLocation
{
    NSLog(@"newLocation‘s lat is :%f, long is :%f",newLocation.coordinate.latitude,newLocation.coordinate.longitude);
    NSLog(@"oldLocation‘s lat is :%f, long is :%f",oldLocation.coordinate.latitude,oldLocation.coordinate.longitude);
    
//    设置span
//    span 指的是显示地图精确度,值越小显示的地图数据越精确,越详细,如果值越大, 则显示的区域越大
//    这里调用了c语言的方法进行赋值------c赋值
    MKCoordinateSpan span = MKCoordinateSpanMake(1, 1);

//    设置地图上的显示区域
    MKCoordinateRegion region = {newLocation.coordinate,span};
    
//    这里用tag,表示修改后现实的界面还是以前我们创建的map
//    另一种方法是把它设置成为成员属性,也可以答到效果
    MKMapView *map = (MKMapView *)[self.view viewWithTag:1000];
    
//  设置地图界面的显示区域,同时再加上一个动画效果,
//    类似于map.region = region
    [map setRegion:region animated:YES];
 
    
//   计算两个位置之间的相隔距离, 单位是米----CLLocationDistance
    
    CLLocationDistance distance  = [newLocation distanceFromLocation:oldLocation];
    NSLog(@"两地之间的距离是:%f",distance/1000);
    
    
//    调用此方法, 是终止位置管理器更新位置信息,在实际应用中, 一定调用这个方法, 解决设备耗电量问题。
//    [self.locationMgr stopUpdatingLocation];

}

#if 0
//  这个和上面的方法其实是一个方法,6.0以后,系统推荐使用这种方法,同时存在,上面的方法无效
- (void)locationManager:(CLLocationManager *)manager
     didUpdateLocations:(NSArray *)locations
{
//    打印当面方法
    NSLog(@"%@",NSStringFromSelector(_cmd));
    NSLog(@"%@",NSStringFromSelector(@selector(locationManager:didUpdateLocations:)));
    
//   数组locations的最后一个元素, 是最新的位置信息
//    通过地址管理器的地址数组,取最新地址
    CLLocation *newLocation = locations[0];

//  设置span
    MKCoordinateSpan span = MKCoordinateSpanMake(1, 1);
 
//  设置region
    MKCoordinateRegion region = MKCoordinateRegionMake(newLocation.coordinate, span);
    
//    这里用tag,表示修改后现实的界面还是以前我们创建的map
//    另一种方法是把它设置成为成员属性,也可以答到效果
    MKMapView *map = (MKMapView *)[self.view viewWithTag:1000];
 
//  设置地图界面的显示区域,同时再加上一个动画效果,
//    类似于map.region = region
    [map setRegion:region animated:YES];
    
}
#endif
-(void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error
{
    NSLog(@"%s",__func__);
    
    NSLog(@"%@",error);

}

#pragma mark -
#pragma mark MKMapViewDelegate
// 这里是实现注解的具体的代理方法
//这里有两个参数————————MKMapView还有——————————annotation
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
//    如果是系统默认的用户当前地址,返回默认的注解,
    if ([annotation isKindOfClass:[MKUserLocation class]]) {
        return nil;
    }
    
//   注解创建的方法和tabelview很像
//    都是先创建一个标识
    static NSString *pinViewIndentifier =@"pinViewIndentifier";
    
//    从可重用队列里取出来
    MKPinAnnotationView *pinView =(MKPinAnnotationView *) [mapView dequeueReusableAnnotationViewWithIdentifier:pinViewIndentifier];
 
//    如果为空,创建pinview;
    if (pinView == nil) {
        pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:pinViewIndentifier];
    }

//        修改大头针的显示颜色
    pinView.pinColor =MKPinAnnotationColorGreen;

//        让大头针出现的时候, 展现从天而降的效果
    pinView.animatesDrop =YES;

//        如果想要展示上述效果, 需要设置canShowCallout为yes
    pinView.canShowCallout =YES;
    
    return pinView;
}
@end