Swift 高德地图集成 自定义大头针及气泡

1. 注册应用,及项目部署
  • 高德开放平台
  • 注册应用,获取Key流程
  • cocoapods自动部署 / 手动部署

cocoapods部署,Podfile 文件中:

target 'MapTest' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  #3D地图 SDK
  pod 'AMap3DMap'
  #地图SDK 搜索功能
  pod 'AMapSearch'
  #定位 SDK
  pod 'AMapLocation'

end

swift与OC桥接MapTest-Bridging-Header.h

#ifndef MapTest_Bridging_Header_h
#define MapTest_Bridging_Header_h

#import 
#import 
#import 

#endif 
2. 配置权限及白名单

info.plist 文件中

定位权限: Privacy - Location When In Use Usage Description

白名单:LSApplicationQueriesSchemes

  • 高德: iosamap
  • 百度地图: baidumap
截屏2021-02-24 下午4.49.19.png
3. 开发流程
  • 2.1 添加高德Key

AppDelegatedidFinishLaunchingWithOptions添加:

  //注册的ApiKey
  let MapApiKey = "62f94b16b702635ff9ad3aba0f461bc4"

  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        AMapServices.shared()?.apiKey = MapApiKey

        return true
    }
  • 2.2 初始化视图

自定义一个CustomPointAnnotation ,代码如下:

enum PointAnotationType {
    case none, type1, type2, type3
}
class CustomPointAnnotation: MAPointAnnotation {
    // 用来设置不同类型的大头针
    var anotationType : PointAnotationType = .none
}

定义一个 MapViewController 控制器,控制器中完整代码,如下:

import UIKit

let kScreenWidth = UIScreen.main.bounds.width
let kScreenHeight = UIScreen.main.bounds.height

class MapViewController: UIViewController, MAMapViewDelegate, AMapLocationManagerDelegate {
    //初始化,用以定位
    private lazy var locationManager: AMapLocationManager = {
        let mapManager = AMapLocationManager()
        mapManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
        mapManager.locationTimeout = 2
        mapManager.reGeocodeTimeout = 2
        mapManager.delegate = self

        return mapManager
    }()
    
    //初始化MAMapView
    lazy var mapView: MAMapView = {
        let mapView = MAMapView(frame: self.view.bounds)
        mapView.delegate = self
        mapView.showsUserLocation = false
        mapView.showsScale = true
        mapView.userTrackingMode = .follow
        mapView.compassOrigin = CGPoint(x: 20, y: 100)
        mapView.update(currentLocation)

        return mapView
    }()
    
    //当前位置
    lazy var currentLocation: MAUserLocationRepresentation = {
        let r = MAUserLocationRepresentation()
        r.showsAccuracyRing = true//精度圈是否显示
        //r.fillColor = UIColor.red//精度圈填充颜色
        //r.strokeColor = UIColor.blue//调整精度圈边线颜色
        r.showsHeadingIndicator = false//是否显示蓝点方向指向
        r.image = UIImage(named: "selected") //定位图标, 与蓝色原点互斥
        return r
    }()
    
    //当前位置坐标
    var coordinate: CLLocationCoordinate2D?{
        didSet{
            //
            let span = MACoordinateSpanMake(0.00423, 0.00425)
            //设置地图中心点
            self.mapView.setCenter(coordinate!, animated: true)
            //设置比例尺大小
            self.mapView.region = MACoordinateRegionMake(coordinate!, span)

        }
    }
    
    //选中的大头针对应的位置。这里可以
    var selectedAddress: CLLocationCoordinate2D?
    
    lazy var relocationBtn: UIButton = {
        let btn = UIButton(frame: CGRect(x: kScreenWidth-60, y: kScreenHeight-80, width: 40, height: 40))
        btn.setImage(UIImage(named: "relocation"), for: .normal)
        btn.addTarget(self, action: #selector(relocationButtonClick), for: .touchUpInside)
        return btn
    }()
    
    
    
    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = .lightGray
        
        //添加视图
        self.view.addSubview(mapView)
        self.view.addSubview(relocationBtn)

        getAddressInfo()
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
        addPins()

    }
    
    // MARK: - 获取当前定位地址
    func getAddressInfo()  {
        locationManager.requestLocation(withReGeocode: true, completionBlock: {(location: CLLocation?, reGeocode: AMapLocationReGeocode?, error: Error?) in
            
            if let error = error {
                let error = error as NSError
                
                if error.code == AMapLocationErrorCode.locateFailed.rawValue {
                    //定位错误:此时location和regeocode没有返回值,不进行annotation的添加
                    print("定位错误:{\(error.code) - \(error.localizedDescription)};")
                    return
                }
                else if error.code == AMapLocationErrorCode.reGeocodeFailed.rawValue
                            || error.code == AMapLocationErrorCode.timeOut.rawValue
                            || error.code == AMapLocationErrorCode.cannotFindHost.rawValue
                            || error.code == AMapLocationErrorCode.badURL.rawValue
                            || error.code == AMapLocationErrorCode.notConnectedToInternet.rawValue
                            || error.code == AMapLocationErrorCode.cannotConnectToHost.rawValue {
                    
                    print("逆地理错误:{\(error.code) - \(error.localizedDescription)};")
                }
                else {
                }
            }else{
                self.coordinate = location?.coordinate
            }

               
        })
    }
    
    //添加标记点(模拟从服务器获取标记点)
    func addPins()  {
        DispatchQueue.main.asyncAfter(deadline: .now()+0.5) {
            let points = [
                CLLocationCoordinate2D(latitude: 31.219508332510877, longitude: 121.35972071117797),
                CLLocationCoordinate2D(latitude: 31.219120295773077, longitude: 121.3599475828693),
                CLLocationCoordinate2D(latitude: 31.21882938769735, longitude: 121.35981538203056),
                CLLocationCoordinate2D(latitude: 31.219792336930784, longitude: 121.36028033900023),
                CLLocationCoordinate2D(latitude: 31.21913916829347, longitude: 121.35948185014595),
                CLLocationCoordinate2D(latitude: 31.219575135389295, longitude: 121.36009213683282),
                CLLocationCoordinate2D(latitude: 31.2189172773082, longitude: 121.36011040897215),
                CLLocationCoordinate2D(latitude: 31.22092501502548, longitude: 121.3594207337901),
            ]
            
            let type : [PointAnotationType] = [.type1, .type2, .type3, .type1, .type1, .type2, .type1, .type1, .type3, .type2, .type1, .type1]
            
            var index: Int = 0
            
            for point in points {
                let pointAnnotation = CustomPointAnnotation()
                pointAnnotation.coordinate = point
                pointAnnotation.title = "标题\(index)"
                pointAnnotation.subtitle = "详细信息\(index)"
                pointAnnotation.anotationType = type[index]
                self.mapView.addAnnotation(pointAnnotation)
                index += 1

            }
        }
       
        
    }
    
    //绘制标记点 类似于tableview - cellForRow
    func mapView(_ mapView: MAMapView!, viewFor annotation: MAAnnotation!) -> MAAnnotationView! {
        print("----------add annotation--------------")
        // 自身位置图标,不再设置
        if annotation.isKind(of: MAUserLocation.self) {
            return nil
            //annotation.isKind(of: CustomPointAnnotation.self)
        }else if annotation is CustomPointAnnotation {
            let pointReuseIndetifier = "pointReuseIndetifier"
            let customAnnotation = annotation as! CustomPointAnnotation

            var annotationView: MAAnnotationView? = mapView.dequeueReusableAnnotationView(withIdentifier: pointReuseIndetifier)

            if annotationView == nil {
                annotationView = MAAnnotationView(annotation: customAnnotation, reuseIdentifier: pointReuseIndetifier)
            }
            //根据anotationType类型不同,设置不同对应的图表
            if customAnnotation.anotationType == .type1{
                annotationView!.image = UIImage(named: "map_icon1")

            }else if customAnnotation.anotationType == .type2{
                annotationView!.image = UIImage(named: "map_icon2")

            }else if customAnnotation.anotationType == .type3{
                annotationView!.image = UIImage(named: "map_icon3")
            }
            //设置中心点偏移,使得标注底部中间点成为经纬度对应点
            annotationView!.centerOffset = CGPoint(x: 0, y: -18);

            annotationView?.canShowCallout = true

            let btn = UIButton(frame: CGRect(x: 0, y: 0, width: 50, height: 55))
            btn.setTitle("导航", for: .normal)
            btn.addTarget(self, action: #selector(gotoDestination), for: .touchUpInside)
            btn.backgroundColor = .red
            annotationView?.rightCalloutAccessoryView = btn
            
            
            return annotationView!
        }

        return nil
    }
    

    //点击标记回调
    func mapView(_ mapView: MAMapView!, didSelect view: MAAnnotationView!) {
        if view.annotation .isKind(of: CustomPointAnnotation.self){
            let cusAnn = view.annotation as! CustomPointAnnotation
            print(cusAnn.title!,cusAnn.anotationType)
            selectedAddress = cusAnn.coordinate
        }
    }
    
    //点击地图,获取点击位置的经纬度
    func mapView(_ mapView: MAMapView!, didSingleTappedAt coordinate: CLLocationCoordinate2D) {
        print("\(coordinate)")

}


extension MapViewController{
    @objc func relocationButtonClick()  {
        //重新定位
        getAddressInfo()
    }
    
    //导航点击
    @objc func gotoDestination()  {
        
        let alertVC = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
        let gaode_url = URL.init(string: "iosamap://")
        let baidu_url = URL.init(string: "baidumap://")
        let apple_url = URL.init(string: "http://maps.apple.com/")

        if UIApplication.shared.canOpenURL(gaode_url!) {
            //iosamap://navi?sourceApplication=applicationName&poiname=fangheng&poiid=BGVIS&lat=36.547901&lon=104.258354&dev=1&style=2
            let action1 = UIAlertAction(title: "高德地图", style: .default) { (action) in
                let urlStr = "iosamap://poi?sourceApplication=MapTest&name=\("虹桥火车站")&dev=0"
                let encodStr = urlStr.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
                let url = URL.init(string: encodStr!)
                UIApplication.shared.open(url!, options: [:]) { (bl) in
                    print("高德:\(bl)")
                }
            }
            alertVC.addAction(action1)

        }
        
        if UIApplication.shared.canOpenURL(baidu_url!) {
            let action1 = UIAlertAction(title: "百度地图", style: .default) { (action) in
                print("百度")
            }
            alertVC.addAction(action1)

        }
        if UIApplication.shared.canOpenURL(apple_url!) {
            let action1 = UIAlertAction(title: "苹果地图", style: .default) { (action) in
                let urlStr = "http://maps.apple.com/?q=上海火车站"
                let encodStr = urlStr.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
                let url = URL.init(string: encodStr!)
                UIApplication.shared.open(url!, options: [:]) { (bl) in
                    print("苹果:\(bl)")
                }

            }
            alertVC.addAction(action1)
        }
        
        let action2 = UIAlertAction(title: "取消", style: .cancel) { (action) in
            print("取消")
        }
        alertVC.addAction(action2)
        self.present(alertVC, animated: true, completion: nil)
    }
}


  • 呈现样式


    1.png
  • 点击导航


    2.png

你可能感兴趣的:(Swift 高德地图集成 自定义大头针及气泡)