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 )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)

你可能感兴趣的:(iOS:Swift关于地图: 绘制标记点,绘制线段,绘制圆形,绘制多边形)