Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >iOS原生地图开发指南 原

iOS原生地图开发指南 原

作者头像
珲少
发布于 2018-08-16 03:26:20
发布于 2018-08-16 03:26:20
1.2K00
代码可运行
举报
文章被收录于专栏:一“技”之长一“技”之长
运行总次数:0
代码可运行

iOS原生地图开发详解

在上一篇博客中:http://my.oschina.net/u/2340880/blog/414760。对iOS中的定位服务进行了详细的介绍与参数说明,在开发中,地位服务往往与地图框架结合使用,这篇博客主要对iOS官方的地图框架MapKit.framework进行介绍。

一、初始化地图视图与相关属性方法介绍

1、初始化地图视图

地图视图的展示依赖于MKMapView这个类,这个类继承于UIView,因此和其他View的使用方法类似。在我们需要展现地图的地方:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
- (void)viewDidLoad {
    [super viewDidLoad];
    MKMapView * mapView =[[MKMapView alloc]initWithFrame:self.view.frame];
    [self.view addSubview:mapView];
}

运行发现,一张世界地图就在我们的设备上了,apple内置的地图数据是由高德提供的。

2、系统提供的三种地图样式

可以通过MKMapView的mapType这个属性设置地图的模式:

@property (nonatomic) MKMapType mapType;

枚举如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
typedef NS_ENUM(NSUInteger, MKMapType) {
    MKMapTypeStandard = 0,//标准式的行政地图(会显示城市,街道等)
    MKMapTypeSatellite,//标准的卫星地图
    MKMapTypeHybrid//混合地图(在卫星图上显示街道等名称)
};
3、设置地图的中心和比例尺

在百度地图等第三方地图服务的SDK中,都会提供一个类似zoomLevel比例尺的属性。通过官方的API设置这个属性有些麻烦,但是也更加灵活。首先,设置地图的中心位置和比例尺是通过region这个属性实现的。region结构体如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
typedef struct {
    CLLocationCoordinate2D center;//地图中心的经纬度
    MKCoordinateSpan span;//地图显示的经纬度范围
} MKCoordinateRegion;

这个结构体中包含了两个结构体,其中CLLocationCoordinate2D很好理解,就是简单的经纬度,解释如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
typedef struct {
    CLLocationDegrees latitude;//纬度,北纬为正,南纬为负
    CLLocationDegrees longitude;//经度,东经为正,西经为负
} CLLocationCoordinate2D;

MKCoordinateSpan这个结构体比较复杂,如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
typedef struct {
    CLLocationDegrees latitudeDelta;//纬度范围
    CLLocationDegrees longitudeDelta;//经度范围
} MKCoordinateSpan;

这个结构体定义的应该是一个范围,因为北纬南纬加起来180°,所以纬度范围的取值应为0-180。同理,经度范围的取值范围为0-360。

通过上面的介绍,我们举个例子,将北京市设为地图的中心区域,并且比例设置为显示北京大小。通过百度,首先知道北京市界的地理坐标为:北纬39”26’至41”03’,东经115”25’至 117”30’。北京市区坐标为:北纬39.9”,东经116. 3”。代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mapView.region=MKCoordinateRegionMake(CLLocationCoordinate2DMake(39.26, 116.3), MKCoordinateSpanMake(1.8, 2.05));

运行后可以看到,北京市基本上是在地图中心的,效果如下:

注意:MKCoordinateSpan的显示范围是取决于大的一边的,比如如果我们这样写:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
MKCoordinateSpanMake(1.8, 360);

最后依然会显示整个世界地图。

- (void)setRegion:(MKCoordinateRegion)region animated:(BOOL)animated;

这个方法可以在设置后给地图加上动画效果

@property (nonatomic) CLLocationCoordinate2D centerCoordinate;

设置地图的中心点位置

- (void)setCenterCoordinate:(CLLocationCoordinate2D)coordinate animated:(BOOL)animated;

设置地图的中心点位置,并附带动画效果

4、坐标转换方法

- (CGPoint)convertCoordinate:(CLLocationCoordinate2D)coordinate toPointToView:(UIView *)view;

将经纬度转换为视图上的坐标

- (CLLocationCoordinate2D)convertPoint:(CGPoint)point toCoordinateFromView:(UIView *)view;

将视图上的坐标转换为经纬度

- (CGRect)convertRegion:(MKCoordinateRegion)region toRectToView:(UIView *)view;

将地理显示的区域转换为视图上的坐标区域

- (MKCoordinateRegion)convertRect:(CGRect)rect toRegionFromView:(UIView *)view; 将视图上的坐标区域转换为地理区域

5、MKMapView常用方法和属性

@property (nonatomic, getter=isZoomEnabled) BOOL zoomEnabled;

设置是否允许捏合手势进行地图缩放

@property (nonatomic, getter=isScrollEnabled) BOOL scrollEnabled;

设置是否允许滑动

@property (nonatomic, getter=isRotateEnabled) BOOL rotateEnabled;

设置是否允许旋转地图

@property (nonatomic, getter=isPitchEnabled) BOOL pitchEnabled;

设置是否支持3D效果

@property (nonatomic) BOOL showsPointsOfInterest;

设置是否显示兴趣点,例如学校,医院等

@property (nonatomic) BOOL showsBuildings;

设置是否显示建筑物轮廓,只在标准的地图中有效

@property (nonatomic) BOOL showsUserLocation;

是否显示用户位置

@property (nonatomic) MKUserTrackingMode userTrackingMode;

- (void)setUserTrackingMode:(MKUserTrackingMode)mode animated:(BOOL)animated;

设置更新用户位置的模式,当显示用户位置设置为YES,这个方法也设置了后,地图框架为我们直接集成了定位,地图上就会显示我们的位置,模式的枚举如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
typedef NS_ENUM(NSInteger, MKUserTrackingMode) {
    MKUserTrackingModeNone = 0, // 不跟踪用户位置
    MKUserTrackingModeFollow, // 跟踪用户位置
    MKUserTrackingModeFollowWithHeading, // 当方向改变时跟踪用户位置
}

@property (nonatomic, readonly) MKUserLocation *userLocation;

获取用户位置的标注

@property (nonatomic, readonly, getter=isUserLocationVisible) BOOL userLocationVisible;

获取用户位置是否可见

- (void)addAnnotation:(id <MKAnnotation>)annotation;

在地图上添加一个标注

- (void)addAnnotations:(NSArray *)annotations; 在地图上添加一组标注 - (void)removeAnnotation:(id <MKAnnotation>)annotation;

移除一个标注

- (void)removeAnnotations:(NSArray *)annotations;

移除一组标注

@property (nonatomic, readonly) NSArray *annotations;

获取所有标注数组

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

获取标注的视图

- (MKAnnotationView *)dequeueReusableAnnotationViewWithIdentifier:(NSString *)identifier;

获取复用的标注

- (void)selectAnnotation:(id <MKAnnotation>)annotation animated:(BOOL)animated;

选中一个标注

- (void)deselectAnnotation:(id <MKAnnotation>)annotation animated:(BOOL)animated;

取消选中一个标注

@property (nonatomic, copy) NSArray *selectedAnnotations;

选中标注的数组

- (void)addOverlay:(id <MKOverlay>)overlay level:(MKOverlayLevel)level;

添加一个地图覆盖物,level是设置一个层级,枚举如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
typedef NS_ENUM(NSInteger, MKOverlayLevel) {
    MKOverlayLevelAboveRoads = 0, // 覆盖物位于道路之上
    MKOverlayLevelAboveLabels//覆盖物位于标签之上
}

- (void)addOverlays:(NSArray *)overlays level:(MKOverlayLevel)level;

添加一组地图覆盖物

- (void)removeOverlay:(id <MKOverlay>)overlay;

移除一个地图覆盖物

- (void)removeOverlays:(NSArray *)overlays;

移除一组地图覆盖物

- (void)insertOverlay:(id <MKOverlay>)overlay atIndex:(NSUInteger)index level:(MKOverlayLevel)level;

在索引处插入一个地图覆盖物

- (void)insertOverlay:(id <MKOverlay>)overlay aboveOverlay:(id <MKOverlay>)sibling;

将一个地图覆盖物插在到某个覆盖物之上

- (void)insertOverlay:(id <MKOverlay>)overlay belowOverlay:(id <MKOverlay>)sibling;

将一个地图覆盖物插入到某个覆盖物之下

- (void)exchangeOverlay:(id <MKOverlay>)overlay1 withOverlay:(id <MKOverlay>)overlay2;

替换一个地图覆盖物

@property (nonatomic, readonly) NSArray *overlays;

地图覆盖物数组

- (NSArray *)overlaysInLevel:(MKOverlayLevel)level;

层级属性下的东土覆盖物数组

二、MKMapViewDelegate相关方法解读

- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated;

地图显示位置将要改变时调用的方法

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated;

地图显示位置已经改变时调用的方法

- (void)mapViewWillStartLoadingMap:(MKMapView *)mapView;

地图将要加载时调用的方法

- (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView;

地图加载完成时执行的方法

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

地图加载失败时执行的方法

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

渲染标注视图时调用的方法,可以通过这个方法自定义标注视图

- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views;

标注添加完成后调用的方法

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

选中标注时调用的方法

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

取消选中标注时调用的方法

- (void)mapViewWillStartLocatingUser:(MKMapView *)mapView;

将要开始定位用户位置时调用的方法

- (void)mapViewDidStopLocatingUser:(MKMapView *)mapView;

停止定位用户位置时调用的方法

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

更新用户位置时调用的方法

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

更新用户位置失败时调用的方法

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view didChangeDragState:(MKAnnotationViewDragState)newState    fromOldState:(MKAnnotationViewDragState)oldState;

标注拖动状态改变调用的方法,MKAnnotationViewDragState的枚举如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
typedef NS_ENUM(NSUInteger, MKAnnotationViewDragState) {
    MKAnnotationViewDragStateNone = 0,      // 初始状态
    MKAnnotationViewDragStateStarting,      // 开始拖动时
    MKAnnotationViewDragStateDragging,      // 正在拖动
    MKAnnotationViewDragStateCanceling,     // 取消拖动
    MKAnnotationViewDragStateEnding         // 结束拖动
};

- (void)mapView:(MKMapView *)mapView didChangeUserTrackingMode:(MKUserTrackingMode)mode animated:(BOOL)animated;

定位用户位置模式改变时调用的方法

- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay;

渲染覆盖物视图时调用的方法,可以自定义覆盖物视图

- (void)mapView:(MKMapView *)mapView didAddOverlayViews:(NSArray *)overlayViews;

添加完成覆盖物数组执行的方法

备注:在iOS9中,地图类型的枚举又添加了两种:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
typedef NS_ENUM(NSUInteger, MKMapType) {
    MKMapTypeStandard = 0,//标准
    MKMapTypeSatellite,//卫星
    MKMapTypeHybrid,//混合
    MKMapTypeSatelliteFlyover NS_ENUM_AVAILABLE(10_11, 9_0),//立体卫星
    MKMapTypeHybridFlyover NS_ENUM_AVAILABLE(10_11, 9_0),//立体混合
} NS_ENUM_AVAILABLE(10_9, 3_0) __WATCHOS_PROHIBITED;

注:因篇幅限制,关于系统大头针和自定义标注的应用、地图覆盖物的应用将在下一篇博客中讨论。

疏漏之处 欢迎指正

专注技术,热爱生活,交流技术,也做朋友。 ——珲少 QQ群:203317592

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2015/05/15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
iOS地图----MapKit框架
1.MapKit框架使用前提 ①导入框架 ②导入主头文件 #import <MapKit/MapKit.h> ③MapKit框架使用须知 MapKit框架中所有数据类型的前缀都是MK MapKit有一
用户1941540
2018/05/11
1.5K0
iOS原生地图开发进阶——使用导航和附近兴趣点检索
iOS中的mapKit框架对国际化的支持非常出色。在前些篇博客中,对这个地图框架的基础用法和标注与覆盖物的添加进行了详细的介绍,这篇博客将介绍两个更加实用的功能的开发:线路导航与兴趣点搜索。前几篇博客的链接如下:
珲少
2018/08/16
9650
iOS原生地图开发进阶——使用导航和附近兴趣点检索
iOS iOS 地图与定位开发系列教程
iPhone SDK提供了三个类来管理位置信息:CLLocation CLLocationManager 和 CLLHeading(不常用)。除了使用GPS来获取当前的位置信息外,iPhone也可以基于WiFi基站和无线发射塔来获得位置信息。GPS的精度最高,可以精确到米级别,但是也最耗电。
全栈程序员站长
2022/09/17
2.3K0
iOS原生地图开发指南续——大头针与自定义标注
在上一篇博客中http://my.oschina.net/u/2340880/blog/415360系统总结了iOS原生地图框架MapKit中主体地图的设置与应用。这篇是上一篇的一个后续,总结了系统的大头针视图以及自定义标注视图的方法。
珲少
2018/08/16
1.1K0
iOS原生地图开发指南续——大头针与自定义标注
【IOS开发基础系列】地图开发专题
http://www.cnblogs.com/syxchina/archive/2012/10/14/2723522.html
江中散人_Jun
2023/10/16
3800
【IOS开发基础系列】地图开发专题
地图相关 MapKit框架介绍MKMapView控件对象的属性和方法MKAnnotation 大头针模型类大头针view显示类:MKPinAnnotationView 继承于 MKAnnotation
介绍 1.概念 导入头文件 #import <MapKit/MapKit.h> MapKit框架中所有数据类型的前缀都是MK MapKit有一个比较重要的UI控件 :MKMapView,专门用于地图显
用户2141756
2018/05/18
4.9K0
iOS开发之地图
在iOS开发中,地图也是很多App都需要使用的功能。本文主要对iOS中的地图知识点进行介绍。需要说明的是地图看似很复杂,其实它仅仅是一个控件,就和UIButton、UITableView等一样。本文代码环境为:Xcode 10.2。
YungFan
2019/05/10
1.2K0
iOS开发之地图
iOS原生地图开发指南再续——地图覆盖物的应用
在前两篇博客中,将iOS系统的地图框架MapKit中地图的设置与应用以及关于添加大头针和自定义大头针的相关操作做了详细的介绍。链接如下:http://my.oschina.net/u/2340880/blog/415360、http://my.oschina.net/u/2340880/blog/415441。这篇博客中将进一步讨论关于地图添加覆盖物的使用方法。
珲少
2018/08/16
5510
iOS原生地图开发指南再续——地图覆盖物的应用
iOS_系统自带地图圆形区域选择范围
5.聚集操作:删除原理的大头针,在新经纬度添加大头针,并将地图移动到新的经纬度(反地理编码获得位置信息)
mikimo
2022/07/20
2.3K0
iOS_系统自带地图圆形区域选择范围
ios地图小例子和手势的使用 供大家参考一下呦
最近做了一个小例子 做点笔记 供刚入职场的菜鸟学习,也供自己记忆。 目标:在地图上加上标记  同时复习一下手势的使用 效果图: 具体代码 导入框架:MapKit.framework 创建一个新类 继承NSObject  叫做MyAnnotation   并在后边加上<MKAnnotation> #import <Foundation/Foundation.h> #import <MapKit/MapKit.h> @interface MyAnnotation : NSObject<MKAnnotation>
用户1219438
2018/02/01
8510
Objective-C MapKit的使用-LBS简单的租车主界面demo效果分析代码demo地址
https://github.com/gongxiaokai/EasyCarDemo
gwk_iOS
2018/08/23
2K0
Objective-C MapKit的使用-LBS简单的租车主界面demo效果分析代码demo地址
iOS开发之地图与定位
  无论是QQ还是微信的移动客户端都少不了定位功能,之前在微信demo中没有添加定位功能,今天就写个定位的小demo来了解一下定位和地图的东西。地图和定位看上去是挺高大上一东西,其实用法比TableView简单多了,下面的Demo是用的iOS中自带的地图和定位,当然了也可以用第三方的来加载地图,比如百度地图啥的,在这就不赘述了。今天的博客主要是介绍MKMapView的使用,MapView的使用和其他组件的用法差不多,MapView用的是委托回调,在使用mapView的Controller中要实现MKMapV
lizelu
2018/01/11
1.5K0
iOS开发之地图与定位
iOS14开发-定位与地图
CoreLocation 是 iOS 中用于设备定位的框架。通过这个框架可以实现定位进而获取位置信息如经度、纬度、海拔信息等。
YungFan
2021/07/14
2.5K0
IOS定位服务的应用 原
在IOS8之后,IOS的定位服务做了优化,若要使用定位服务,必须先获取用户的授权。
珲少
2018/08/15
8850
IOS定位服务的应用
                                                                            原
iOS的高德地图标注特定位置
在开发时有时候遇到项目里面需要展示公司的位置,这时如果导入百度地图什么的就太浪费资源,而且还占内存
全栈程序员站长
2022/08/31
8580
IOS MapView 用法
// Copyright (c) 2012年 __MyCompanyName__. All rights reserved.
全栈程序员站长
2022/07/05
4390
IOS MapView 用法
地图| 高德地图源码级使用大全
高德地图提供包括:web前端、Android、iOS、服务器、小程序等平台的地图服务, 地图功能众多,本文记载的只是自己遇到的一些问题,绝大部分功能只要参照官方文档和Dome都可以实现出来。
進无尽
2018/09/12
4.5K0
地图| 高德地图源码级使用大全
iOS百度地图开发之路径规划
路线规划 示例程序 使用百度地图SDK版本为2.9.1。 需要将改 代码: #import <MapKit/MapKit.h> #import <BaiduMapAPI_Map/BMKMapView.h> #import <BaiduMapAPI_Location/BMKLocationService.h> #import <BaiduMapAPI_Search/BMKSearchComponent.h> #import <BaiduMapAPI_Map/BMKPolylineView.h> #impor
hrscy
2018/08/30
1.3K0
iOS百度地图开发之路径规划
iOS百度地图开发中遇到的问题
由于项目需要地图功能,公司决定使用百度地图,但是百度地图也有很多问题,现在总结一下在百度地图中遇到的坑,希望给各位看官一点参考,避免走一些弯路.我使用的百度地图SDK2.9.1.
hrscy
2018/08/30
9960
iOS百度地图开发中遇到的问题
iOS百度地图POI详情检索与路径规划(附Demo)
POI(Point of Interest)中文可以翻译为“兴趣点”。在地理信息系统中,一个POI可以是一栋房子、一个商铺、一个邮筒、一个公交站等。 写在前面:最近老是有朋友来问我这个检索怎么不行了,我今天看了下,果然,出了问题,似乎是百度地图的一个Bug。POI检索后调POI详情检索,但是详情检索出来的经纬度全部是0,这样自然是不能够成功添加大头针的。奇怪的是在POI检索中经纬度是有的,但是呢,详情中经纬度竟然丢失了。这个只能等百度那边修复了,当然我这里提供一个临时解决这个办法的方法。在文末我上
Raindew
2018/06/14
1.8K0
推荐阅读
相关推荐
iOS地图----MapKit框架
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验