iOS地图和定位服务(自定义大头针)

来源:互联网 发布:百分浏览器 知乎 编辑:程序博客网 时间:2024/06/06 05:45


#import "ViewController.h"

//使用地图需导入MapKit

#import <MapKit/MapKit.h>

#import <CoreLocation/CoreLocation.h>

#import "MyAnnotationView.h"


@interface ViewController ()<MKMapViewDelegate,CLLocationManagerDelegate>

{

    CLLocationManager *manage;

    MKMapView *myMapView;

}

@end


@implementation ViewController


- (void)viewDidLoad {

    [super viewDidLoad];

    

    

    if (![CLLocationManager locationServicesEnabled]) {

        NSLog(@"没打开");

        return;

    }

    //

    //   不管是定位还是使用地图 都需要用户授权

    manage = [[CLLocationManager alloc]init];

    manage.desiredAccuracy = kCLLocationAccuracyBest;

//    manage.pausesLocationUpdatesAutomatically = YES;

    //   多少米  去更新一次(出了设置的范围就会更新location)位置 location

    manage.distanceFilter = 100;

    manage.delegate = self;

    [manage requestWhenInUseAuthorization];

    

    myMapView = [[MKMapView alloc]initWithFrame:self.view.frame];

    

    //   挂上代理

    myMapView.delegate =self;

    

    

    //   设置地图的样式

    /*

     MKMapTypeStandard = 0,(默认普通样式)

     MKMapTypeSatellite,卫星样式

     MKMapTypeHybrid鸟瞰

     */

    myMapView.mapType =MKMapTypeStandard;

    //   设置是否允许用户允许旋转地图

    myMapView.rotateEnabled =YES;

    

    //   是否允许方法缩小地图

    myMapView.zoomEnabled =YES;

    

    //   是否允许地图滚动

    myMapView.scrollEnabled = YES;

    

    //   是否允许有3D效果

    myMapView.pitchEnabled =YES;

    //   射中是否显示用户的位置

    myMapView.showsUserLocation =YES;

    

    //   设置是否显示附近的建筑物(必须是普通样式才有效)

    myMapView.showsBuildings =YES;

    

    //   是否显示兴趣点(也是必须是 普通样式或则鸟瞰样式 有效)

    myMapView.showsPointsOfInterest =YES;

    [self.view addSubview:myMapView];

    

    

    UILongPressGestureRecognizer *addPoint = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(addpointView:)];

    

    [myMapView addGestureRecognizer:addPoint];

    

    

    

    

    

    

}

//长按手势 的方法

-(void)addpointView:(UILongPressGestureRecognizer *)sender

{

    //   解决长按手势触发两次

    //   在手势开始的时候 执行

    if (sender.state==UIGestureRecognizerStateBegan) {

        CGPoint point = [sender locationInView:myMapView];

        NSLog(@"%f %f",point.x,point.y);

        CLLocationCoordinate2D coodinate =  [myMapView convertPoint:point toCoordinateFromView:myMapView];

        NSLog(@"%f %f",coodinate.latitude,coodinate.longitude);

         MKPointAnnotation *pointAnnotation = [[MKPointAnnotation alloc]init];

        pointAnnotation.coordinate =coodinate;

        CLGeocoder *geocoder = [[CLGeocoder alloc]init];

        CLLocation *location = [[CLLocation alloc]initWithLatitude:coodinate.latitude longitude:coodinate.longitude];

        //       地理编码和范地理编码都是异步操作

        [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {

            CLPlacemark *placemark = [placemarks lastObject];

            pointAnnotation.title = placemark.locality;

            pointAnnotation.subtitle = placemark.name;

            [myMapView addAnnotation:pointAnnotation];

        }];

        

        

    }

    

    

}



#pragma mark  地图代理方法


- (void)mapViewDidFailLoadingMap:(MKMapView *)mapView withError:(NSError *)error

{

    NSLog(@"加载失败");

}



//已经更新完成 用户位置的时候调用

- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation

{

    NSLog(@"已经更新完成 用户位置的时候调用");

    

   

    

    MKCoordinateSpan span = MKCoordinateSpanMake(0.1, 0.1);

    MKCoordinateRegion regin = MKCoordinateRegionMake(userLocation.location.coordinate,span);

    //   如果使用Region的时候用户移动 出现不断跳动的效果可以屏蔽动画

    [myMapView setRegion:regin animated:YES];

    

    

    

    

    //   把地理位置 转换成名字

    //   大头针

    //    1.数据  MKPointAnnoTation  <MKAnnotation>

    //    2、视图  MKPinAnnotationView  MKAnnotationView

    //   大头针 可以理解为 表视图 cell

    

    

    //   使用大头针(标记数据) 可以使用系统提供的MKPointAnnoTation  也可以自定义MKAnnotation

    //   地图添加大头针数据 addAnnotation

    

    MKPointAnnotation *annotation = [[MKPointAnnotation alloc]init];

    //   setCoordinate设置大头针的经纬度

    [annotation setCoordinate:userLocation.location.coordinate];

    

    

    //   把定位到用户的位置 转换成地名

    CLGeocoder *geocoder = [[CLGeocoder alloc]init];

    [geocoder reverseGeocodeLocation:userLocation.location completionHandler:^(NSArray *placemarks, NSError *error) {

        

        CLPlacemark *placeMake = [placemarks lastObject];

        NSLog(@"城市名:%@街道名:%@",placeMake.locality,placeMake.name);

        //       给大头针 添加标题

        annotation.title = placeMake.locality;

        

        //       给大头针添加副标题

        annotation.subtitle =placeMake.name;

        //       把大头针数据 添加到地图

        [mapView addAnnotation:annotation];

       

        

        

    }];

    

}


- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation

{

    if ([annotation isKindOfClass:[MKPointAnnotation class]]) {

        NSString *annotationID = @"ID";

        MyAnnotationView *annotationView = (MyAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:annotationID];

        if (!annotationView) {

            annotationView = [[ MyAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:annotationID];

        }

        return annotationView;

    }

    return nil;

}

//选中大头针的方法

- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view

{

    if ([view.annotation isKindOfClass:[MKPointAnnotation class]]) {

        view.image = [UIImage imageNamed:@"2.jpg"];

    }

    

}

//取消大头针的方法

- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view

{

    if ([view.annotation isKindOfClass:[MKPointAnnotation class]]) {

        view.image = [UIImage imageNamed:@"1.jpg"];

    }


}

//定位失败

- (void)mapView:(MKMapView *)mapView didFailToLocateUserWithError:(NSError *)error

{

    NSLog(@"定位失败时候调用");

}

#pragma mark ---更新位置的代理方法-------

- (void)locationManager:(CLLocationManager *)manager

     didUpdateLocations:(NSArray *)locations

{

    //    locations数组里面包含了我们更新的位置

    NSLog(@"%@",locations);

    //   获得最新的位置

    CLLocation *curLocation = [locations lastObject];

    //   通过location  或得到当前位置的经纬度

    CLLocationCoordinate2D curCoordinate2D = curLocation.coordinate;

    //    curCoordinate2D.latitude纬度

    //    curCoordinate2D.longitude经度

    NSLog(@"纬度:%f经度:%f",curCoordinate2D.latitude,curCoordinate2D.longitude);

    

    //  获得 更新位置的时间(nsdate)可以通过更新时间计算行驶的速度

    NSDate *updateTime = curLocation.timestamp;

    NSLog(@"%@",updateTime);

    

    //  获得当前的行驶速度

    double speed = curLocation.speed;

    NSLog(@"speed:%f",speed);

    

    //   如果在室内  可以定位是在几楼

    CLFloor *curFloor = curLocation.floor;

    NSLog(@"%ld",curFloor.level);

    

    //   获得当前的航向

    //    CLLocationDirection curDirection = curLocation.course;

    

    //   获得当前的海拔的精准度

    CLLocationAccuracy curAccuracy = curLocation.verticalAccuracy;

    NSLog(@"%f",curAccuracy);

    

    //   获得海拔的高度

    double altitude = curLocation.altitude;

    NSLog(@"海拔:%f",altitude);

    

    //获得行驶的平均速度  得到两次更新的速度  / 更新的次数

    

}

- (void)viewWillAppear:(BOOL)animated

{

    //   开启定位

    [manage startUpdatingLocation];

}

- (void)viewWillDisappear:(BOOL)animated

{

    [manage stopUpdatingLocation];

}

- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}


@end


0 0
原创粉丝点击