美文网首页Swift
iOS:Swift关于地图: 绘制标记点,绘制线段,绘制圆形,绘

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

作者: Theendisthebegi | 来源:发表于2021-07-03 14:08 被阅读0次

    这里主要说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)
    

    相关文章

      网友评论

        本文标题:iOS:Swift关于地图: 绘制标记点,绘制线段,绘制圆形,绘

        本文链接:https://www.haomeiwen.com/subject/iwiuultx.html