地图

地图的显示

  • MapKit框架的使用:

  • 导入框架(iOS5之后不在需要程序员自己导入)

  • 导入主头文件 #import<MapKit/MapKit.h>

  • MapKit框架使用须知:

  • MapKit框架中所有数据类型的前缀都是MK

  • MapKit有一个比较重要的UI控件:MKMapView,专门用于地图显示.
    跟踪显示用户的位置: 设置MKMapViewuserTrackingMode属性可以跟踪显示用户的当前位置.

MKUserTrackingModelNone:不跟踪用户的位置
MKUserTrackingModelFollow:跟踪并在地图上显示用户的当前位置
MKUserTrackingModelFollowWithHeading:跟踪并在地图上显示用户的当前位置,地图会跟随用户的前进方向进行旋转

先创建两个类,一个Annotation,CustomAnnotation声明一样的属性,用于自定义大头针用

#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>

@interface Annotation : NSObject<MKAnnotation>//遵循协议

@property (nonatomic)CLLocationCoordinate2D coordinate;
//标题
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy)NSString *subtitle;
//大头针的详情描述
@property (nonatomic, copy)NSString *detail;
//星际评价
@property (nonatomic, strong) UIImage *star;

@end

再创建一个CustomAnnotationView,用于取出自定义的大头针视图


#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
#import "CustomAnnotation.h"


@interface CustomAnnotationView : MKAnnotationView
@property (nonatomic, strong)CustomAnnotation *customAnnotation;

#pragma mark----从缓存中取出大头针-----------
+(instancetype)calloutViewWithMapView:(MKMapView *)mapView;
@end
#import "CustomAnnotationView.h"

@interface CustomAnnotationView ()

//展示详情
@property (nonatomic, strong) UILabel *detaillabel;
//展示星级评价
@property (nonatomic, strong) UIImageView *startView;

@end


@implementation CustomAnnotationView

- (instancetype)initWithFrame:(CGRect)frame{
    if (self = [super initWithFrame:frame]) {
        _detaillabel = [[UILabel alloc]init];
        _detaillabel.backgroundColor = [UIColor whiteColor];
        
        _startView = [[UIImageView alloc]init];
        _startView.backgroundColor = [UIColor whiteColor];
        [self addSubview:_detaillabel];
        [self addSubview:_startView];
    }
    return self;

}

#pragma mark-----当给大头针视图设置大头针模型时,可在此根据模型设置视图内容------
- (void)setAnnotation:(CustomAnnotation *)annotation{

    [super setAnnotation:annotation];
    //根据模型调整布局
    //详情
    self.detaillabel.text = annotation.detail;
    self.detaillabel.frame = CGRectMake(0, 0, 100, 15);
    self.detaillabel.font = [UIFont systemFontOfSize:12];
    //星级
    _startView.image = annotation.star;
    _startView.frame = CGRectMake(0, 14, 100, 15);

}


+(instancetype)calloutViewWithMapView:(MKMapView *)mapView{
    static NSString *callout = @"callkey";
    CustomAnnotationView *calloutview = (CustomAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:callout];
    if (!calloutview) {
        calloutview = [[CustomAnnotationView alloc]init];
    }
    return calloutview;
}

@end

地图,系统大头针,自定义大头针

#import "FirstViewController.h"
#import <MapKit/MapKit.h>//引入头文件
#import "Annotation.h"
#import "CustomAnnotation.h"
#import "CustomAnnotationView.h"

@interface FirstViewController ()<MKMapViewDelegate>
@property (nonatomic, strong) MKMapView *mapview;
@property (nonatomic) CLLocationCoordinate2D center;
@property (nonatomic, strong)MKPointAnnotation *pointAnnotation;
@end

@implementation FirstViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
#pragma mark------自带地图-------
    _mapview = [[MKMapView alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
    //触摸缩放
    _mapview.zoomEnabled = YES;
    //可移动的
    self.mapview.scrollEnabled = YES;
    //设置地图形式
    self.mapview.mapType = MKMapTypeHybrid;
    
    //设置代理
    self.mapview.delegate = self;
    
    //显示用户位置
    self.mapview.showsUserLocation = YES;
    [self.view addSubview:_mapview];
    
    [self addAnnotation];
    
    //添加一个长按手势
    UILongPressGestureRecognizer *longshow = [[UILongPressGestureRecognizer alloc ]initWithTarget:self action:@selector(longclick:)];
    
    
    [self.mapview addGestureRecognizer:longshow];
}

- (void)longclick:(UILongPressGestureRecognizer *)sender{
//判断在长按的起始点落下大头针
    if (sender.state == UIGestureRecognizerStateBegan) {
        //首先获取这个点
        CGPoint point = [sender locationInView:self.mapview];
        //将这个点转换为经纬度坐标
        self.center = [self.mapview convertPoint:point toCoordinateFromView:self.mapview];
        //初始化大头针坐标点对象
        self.pointAnnotation = [[MKPointAnnotation alloc]init];
        //将转换后的经纬度赋值给此对象
        self.pointAnnotation.coordinate = self.center;
        self.pointAnnotation.title = @"长按";
        [self.mapview addAnnotation:self.pointAnnotation];
    }
}


#pragma mark------------------添加大头针----------------
- (void)addAnnotation{
    
    CLLocationCoordinate2D location2 = CLLocationCoordinate2DMake(39.9200225351, 116.3968733177);
    Annotation *annotationGG = [[Annotation alloc]init];
    annotationGG.title = @"Start";
    annotationGG.subtitle = @"故宫";
    //设置坐标
    annotationGG.coordinate = location2;
    annotationGG.detail = @"前门";
    annotationGG.star = [UIImage imageNamed:@"star"];
    
    //添加大头针
    [self.mapview addAnnotation:annotationGG];

}

#pragma mark--- 显示大头针调用此方法---------
//表示即将要显示的大头针
- (nullable MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation{
    if ([annotation isKindOfClass:[CustomAnnotation class]]) {
        //自定义大头针弹出视图详情本身没有弹出交互功能,(canShowCallout = false,默认值)可在有弹出交互的大头针里添加其他视图
        CustomAnnotationView *custom = [CustomAnnotationView calloutViewWithMapView:mapView];
        custom.annotation = annotation;
        return custom;
    }
    return nil;//返回值为nil,显示是默认的大头针
}



#pragma mark-----选中大头针时触发-----
//点击一般大头针Annotation,添加一个自定义大头针视图作为所点大头针弹出的视图详情
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view{
    Annotation *annotation = view.annotation;
    if ([view.annotation isKindOfClass:[Annotation class]]) {
        [self removeCustomAnnotation];
        CustomAnnotation *annotation1 = [[CustomAnnotation alloc]init];
        annotation1.detail = annotation.detail;
        annotation1.star = annotation.star;
        annotation1.coordinate = view.annotation.coordinate;
        [mapView addAnnotation:annotation1];
    }
}

#pragma mark----移除大头针的自定义视图------------
- (void)removeCustomAnnotation{
[self.mapview.annotations enumerateObjectsUsingBlock:^(id<MKAnnotation>  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
    if ([obj isKindOfClass:[CustomAnnotation class]]) {
        
        [self.mapview removeAnnotation:obj];
    }
}];

}


#pragma mark----点击空白区域移除大头针的自定义视图------------
- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view{
    [self removeCustomAnnotation];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


@end

CoreLocation框架的使用(iOS5之后不再使用)

  • CoreLocation框架使用须知:
  • CoreLocation框架中所有数据类型的前缀都是CL
  • CoreLocation中使用CLLocationManager对象来做用户定位
  • 地理编码,反地理编码
//地理编码.根据给定的位置(通常是地名)确定地理坐标
//反地理编码:根据给定的地理位置,确定位置信息(街道,门牌)
#import "SecondViewController.h"
//引入定位头文件
#import <CoreLocation/CoreLocation.h>
#import <MapKit/MapKit.h>

@interface SecondViewController ()
@property (nonatomic, strong) CLGeocoder *geocoder;

@end

@implementation SecondViewController

- (void)viewDidLoad {
    [super viewDidLoad];
   //初始化编码对象
    _geocoder = [[CLGeocoder alloc]init];
//    [self getCoordinateByAddress:@"北京市"];
    
    [self getAddressByLatLong:39.9200225351 Longitude:116.3968733177];
}

#pragma mark----地理编码------------
- (void)getCoordinateByAddress:(NSString *)address{
[self.geocoder geocodeAddressString:address completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
    //获取第一个地标,地标中存储了详细的地址信息(一个地名可能搜索出多个地址)
    CLPlacemark *placemark = [placemarks firstObject];
    //获取位置
    CLLocation *location = placemark.location;
    //获取区域
    CLRegion *region = placemark.region;
    //地名
    NSString *name = placemark.name;
    //街道
//    NSString *thoroughFare = placemark.thoroughfare;
//    //街道相关信息
//    NSString *subthoroughFare = placemark.subThoroughfare;
//    //城市
//    NSString *locatity = placemark.locality;
//    //州
//    NSString *administrativeArea = placemark.administrativeArea;
    //其他行政区信息
    NSString *subadministrativeArea = placemark.subAdministrativeArea;
    //邮编
//    NSString *postalCode = placemark.postalCode;
//    //国家编码
//    NSString *ISOcountryCode = placemark.ISOcountryCode;
    //国家
//    NSString *country = placemark.country;
    //水源
//    NSString *inlandWater = placemark.inlandWater;
    //海洋
//    NSString *ocean = placemark.ocean;
    //关联或者利益相关的地标
//    NSArray *areasOfInterest = placemark.areasOfInterest;
//    NSDictionary *dic = placemark.addressDictionary;
    NSLog(@"位置%@,区域%@,详细信息%@,name%@",location,region,subadministrativeArea,name);
    
}];
    
}


#pragma mark----地理编码确定两个城市------------
- (void)Location_2{
    //地理编码一次只能定位一个城市,可通过嵌套形式实现定位多个地名
[self.geocoder geocodeAddressString:@"北京市" completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
    //获取地标
    CLPlacemark *placemake = [placemarks firstObject];
    MKPlacemark *clplacemark = [[MKPlacemark alloc]initWithPlacemark:placemake];
//嵌套使用
    [self.geocoder geocodeAddressString:@"石家庄" completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
        //获取地标
        CLPlacemark *placemake1 = [placemarks firstObject];
        MKPlacemark *clplacemark1 = [[MKPlacemark alloc]initWithPlacemark:placemake1];
        MKMapItem *mapitem = [[MKMapItem alloc]initWithPlacemark:clplacemark];
        MKMapItem *mapitem1 = [[MKMapItem alloc]initWithPlacemark:clplacemark1];
        //字典中放一个地图类型
/*
        MKMapTypeStandard,普通地图
        MKMapTypeSatellite,卫星云图
        MKMapTypeHybrid,普通地图覆盖于卫星云图之上
        MKMapTypeSatelliteFlyover 地形和建筑物的三维模型
        MKMapTypeHybridFlyover 显示道路和附加元素的Flyover
        */
        NSDictionary *option = @{MKLaunchOptionsMapTypeKey:@(MKMapTypeStandard)};
      [MKMapItem openMapsWithItems:@[mapitem, mapitem1] launchOptions:option];
}];

}];
}

#pragma mark---反地理编码---------
- (void)getAddressByLatLong:(CLLocationDegrees) latitude  Longitude:
(CLLocationDegrees) longitude{
    //初始化位置信息
    CLLocation *location = [[CLLocation alloc]initWithLatitude:latitude longitude:longitude];
[self.geocoder reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
    CLPlacemark *placeMark = [placemarks firstObject];
    MKPlacemark *clplacemark1 = [[MKPlacemark alloc]initWithPlacemark:placeMark];
    MKMapItem *mapitem = [[MKMapItem alloc]initWithPlacemark:clplacemark1];
    MKMapItem *mapitem1 = [[MKMapItem alloc]initWithPlacemark:clplacemark1];
    //字典中放一个地图类型
    NSDictionary *option = @{MKLaunchOptionsMapTypeKey:@(MKMapTypeStandard)};
    [MKMapItem openMapsWithItems:@[mapitem, mapitem1] launchOptions:option];
//    NSLog(@"%@",placeMark.addressDictionary);
}];
}

  • 计算两地之间距离
#import "ViewController.h"
#import <CoreLocation/CoreLocation.h>

@interface ViewController ()
@property (nonatomic,strong)CLLocationManager *locationManager;
@end
@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    //创建位置管理器
    CLLocationManager *locationManager=[[CLLocationManager alloc]init];
    self.locationManager=locationManager;
    
    //判断当前设备版本是否大于或等于8.0
    if ([UIDevice currentDevice].systemVersion.floatValue >=8.0) {
        //持续授权
        //[locationManager requestAlwaysAuthorization];
        //使用期间授权
        [locationManager requestWhenInUseAuthorization];
    }
 
    //开始定位
    [locationManager startUpdatingLocation];
    //比较两点距离
    [self compareDistance];
}

//比较两地之间距离(直线距离)
- (void)compareDistance{
    //北京
    
    CLLocation *location1=[[CLLocation alloc]initWithLatitude:39.9 longitude:116.3];
    //郑州
    CLLocation *location2=[[CLLocation alloc]initWithLatitude:34.44 longitude:113.42];
    //比较郑州距离北京的距离
    /*
     distanceFromLocation:用户当前位置
     */
    CLLocationDistance locationDistance=[location1 distanceFromLocation:location2];
    //单位是m/s 所以这里需要除以1000
    NSLog(@"郑北的距离为:%f",locationDistance/1000);
    
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
两地距离输出结果.png
  • 位置管理器
#import "ForthViewController.h"
#import <CoreLocation/CoreLocation.h>


@interface ForthViewController ()<CLLocationManagerDelegate>//遵循协议
//声明位置管理属性
@property (nonatomic, strong)CLLocationManager *locationManager;
//保存获取到的位置信息
@property (nonatomic, strong) CLLocation *checkinLocation;
@end

@implementation ForthViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.locationManager = [[CLLocationManager alloc]init];
    //判断你是否打开定位服务
    if (![CLLocationManager locationServicesEnabled]) {
        NSLog(@"定位服务尚未打开,请开启");
        return;
    }
    /*
     [CLLocationManager authorizationStatus]指的是当前应用的定位服务授权状态,返回枚举类型
     kCLAuthorizationStatusNotDetermined:用户尚未做出决定是否启用定位服务
     kCLAuthorizationStatusRestricted:没有获得用户授权使用定位服务,可能用户没有自己禁止访问授权
     kCLAuthorizationStatusDenied:用户已经明确禁止应用使用定位服务或者当前系统定位服务处于关闭状态
     kCLAuthorizationStatusAuthorizedAlways:应用获得授权可以一直使用定位服务,即使应用不在使用状态
     kCLAuthorizationStatusAuthorizedWhenInUse:使用此应用过程中允许访问定位服务
     */
    
    //如果没有授权定位服务,就请求用户授权
    if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined) {
#pragma mark--- ---在info.plist中添加下边两个字段单独拿中的任一个:
       /*
         ①NSLocationWhenInUseUsageDescription  YES
         ②NSLocationAlwaysUsageDescription  YES
         如果两个同时添加,则默认为第一个,但如果只添加第二个
         */
        [self.locationManager requestAlwaysAuthorization];//请求前台和后台定位
  }//如果被授权
    else if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedAlways){
    
    //设置代理
        self.locationManager.delegate = self;
        //定位精度
        
        /*
        kCLLocationAccuracyBestForNavigation;
         kCLLocationAccuracyBest;最精确
         kCLLocationAccuracyNearestTenMeters;十米误差
         kCLLocationAccuracyHundredMeters;百米误差
         kCLLocationAccuracyKilometer;千米误差
         kCLLocationAccuracyThreeKilometers;三千米误差

         */
        self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
        //定位频率(每隔多少米定位一次,单位:米)
        CLLocationDistance distance = 10.0;
        self.locationManager.distanceFilter = distance;
      
        //启动定位符
        [self.locationManager startUpdatingLocation];

    }
 
}


- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
{
    // 取出位置
    CLLocation *location = [locations firstObject];
    // 位置坐标
    CLLocationCoordinate2D coordinate = location.coordinate;
    NSLog(@"经度:%f,纬度:%f,海拔:%f,航向:%f,行走速度:%f",coordinate.longitude,coordinate.latitude,location.altitude,location.course,location.speed);
    
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


@end

定位系统在模拟器上不能显示,可真机测试

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容