iOS:Swift关于地图: 绘制标记点,绘制线段,绘制圆形,绘制多边形

这里主要说iOS原生地图
iOS原生地图很有意思,在国内是用的高德地图,在国外才是苹果地图~
就比如在国内你在手机上看国外地图,非常不详细,和国内街道、景观的详尽程度不可同日而语

一、MapKit里的MKMapView的一些主要属性和方法

/** 是否可以旋转 */
var isRotateEnabled: Bool { get set}

/** 是否可以捏和 */
var isPitchEnabled: Bool { get set}

/** 是否显示指南针 */
var showsCompass: Bool { get set}

/** 显示定位 */
var showsUserLocation: Bool { get set}

/** 地图类型 */
var mapType: MKMapType { get set}

/** 显示区域 */
var region: MKCoordinateRegion { get set}

/** 中心点 */
var centerCoordinate: CLLocationCoordinate2D { get}

/** 设置显示区域 */
func setRegion(_ region: MKCoordinateRegion, animated: Bool)

/** 坐标转经纬度 */
func convert(_ point: CGPoint, toCoordinateFrom view: UIView?) -> CLLocationCoordinate2D

/** 经纬度转坐标 */   
func convert(_ coordinate: CLLocationCoordinate2D, toPointTo view: UIView?) -> CGPoint


代理方法
/** 自定义标记点入口 */
(nullable MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation;

/** 自定义曲线入口 */
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer;

/** 地图显示区域改变 */
func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool);

二、自定义标记点Annotation

1、自定义class: CustomAnnotation: MKPointAnnotation
可以在里面添加一些自定义属性,该类可以理解为标记点的model

class CustomAnnotation: MKPointAnnotation {
    var index: Int = 0
    var annotationID: String?
    var title: String?
    ...
}

同时自定义class: CustomAnnotationView: MKAnnotationView
可以在里面自定义控件,该类可以理解为标记点View

class CustomAnnotationView: MKAnnotationView {
    override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
        super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
        ///自定义控件入口
    }
    override var annotation: MKAnnotation? {
        didSet {
            ///可以在这里去为自定义的控件填充数据
        }
    }
    ...
}

Annotation的增删改查API

///增
open func addAnnotation(_ annotation: MKAnnotation)

open func addAnnotations(_ annotations: [MKAnnotation])

///删
open func removeAnnotation(_ annotation: MKAnnotation)

open func removeAnnotations(_ annotations: [MKAnnotation])

///查
open var annotations: [MKAnnotation] { get }

///修改位置(如果要修改数据,只需自己添加入口即可)
open var coordinate: CLLocationCoordinate2D
然后,将Annotation和AnnotationView绑定起来
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        if annotation is CustomAnnotation {
            let identifier = "CustomAnnotationIdentifier"
            var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? CustomAnnotationView
            if annotationView == nil {
                annotationView = CustomAnnotationView(annotation: annotation, reuseIdentifier: identifier)
            }
       return annotationView
     }
  ...
}

这样就完成了一个自定义标记点,因为要自定义两个类,要去添加Annotation,还要在代理方法里绑定,流程很是繁琐,所以可以抽象封装一下

封装后简单的Annotation只需:

let options = AutelAnnotationOptions(coordinate: coordinate, "Img_map_mark".toImage(), nil, false)
let annotation = mapView.createAnnotation(options, nil)
mapView.addAnnotation(annotation)

*****************************************************************************************************
init(coordinate coord: CLLocationCoordinate2D, _ defaultImage: UIImage? = nil, _ selectedImage: UIImage? = nil, _ gestureEnabled: Bool = false)
func createAnnotation(_ options: AutelAnnotationOptions?, _ customView: AutelCustomAnnotationView?) -> AutelAnnotation

如果项目中地图占比较重,就非常有封装的必要性,具体怎么封装这里就不再说了

三、绘制线:直线、圆、多边形、自定义曲线

1.绘制直线

自定义class,CustomLine: MKPolyline

class CustomLine: MKPolyline {
    var strokeColor = UIColor.red
    var width: CGFloat = 5
}

添加线段到地图上

let line = CustomLine(coordinates:[coor1,coor2], count: 2)
line.strokeColor = .green
line.width = 10
mapView.addOverlay(line, level: .aboveRoads)

代理方法里设置MKPolylineRenderer

func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
    if let line = overlay as? CustomLine {
        let render:MKPolylineRenderer = MKPolylineRenderer(polyline: line)
        render.lineWidth = line.width
        render.strokeColor = line.strokeColor
        return render
    }
    ...
}

这样就完成了一条线段的绘制

如果想要自定义曲线呢?比如绘制贝塞尔曲线,曲线上加箭头等等

只需要自定义CustomLineRenderer: MKPolylineRenderer

重写其draw方法即可

override func draw(_ mapRect: MKMapRect,
                       zoomScale: MKZoomScale,
                       in context: CGContext) {
    ...
}
2.绘制圆、多边形

自定义class,CustomCircle: MKCircle
class CustomPolygon : MKPolygon

添加到地图上

let circle = CustomCircle(center: center, radius: radius)
mapView.addOverlay(circle)
let polygon = CustomPolygon.init(coordinates: coordinates, count: coordinates.count)
mapView.addOverlay(polygon)

在代理方法里设置render

func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
    let renderer = super.mapView(mapView, rendererFor: overlay)
    if let overlay = overlay as? CustomCircle {
        let render = MKCircleRenderer.init(circle: overlay)
        render.strokeColor = UIColor.red
        render.lineWidth = 1
        return render   
    } else if let overlay = overlay as? CustomPolygon {
        let render: MKPolygonRenderer = MKPolygonRenderer.init(polygon: overlay)
        render.fillColor = UIColor.blue
        return render
    }
}

这样就完成了圆、多边形的绘制

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

推荐阅读更多精彩内容