iOS - 地图定位以及坐标系转化WGS-84 转 GCJ-02等

 

定位转换

 //WGS-84:是国际标准,GPS坐标(Google Earth使用、或者GPS模块)
 //GCJ-02:中国坐标偏移标准,Google Map、高德、腾讯使用
 //BD-09: 百度坐标偏移标准,Baidu Map使用

 

国际共识:WGS84的坐标系统,以经纬度的形式来表示地球平面上的某一个位置;

中国:GCJ-02的坐标系统。在我国,出于国家安全考虑,国内所有导航电子地图必须使用国家测绘局制定的加密坐标系统,即将一个真实的经纬度坐标加密成一个不正确的经纬度坐标,称之为火星坐标;

百度:BD-09的坐标系统,百度坐标是在国测局制定的GCJ-02,对地理位置进行首次加密的基础上,进行了BD-09二次加密措施,更加保护了个人隐私。

 

分别用系统定位和高德打印

//高德

location:<+40.03449463,+116.42152886> +/- 65.00m (speed -1.00 mps / course -1.00) 

reGeocode:AMapLocationReGeocode:{formattedAddress:北京市**区**路靠近**家居(北京**店);

  //系统

 打印内容:北京市**区**路**号**楼1号楼*层********有限公司**分公司

 打印内容:CLLocationCoordinate2D(latitude: 40.034520484928365, longitude: 116.42152212016788)

高德SDK

精度不如系统提供的精确(说明苹果花钱买的精确度比公开的高)

 

转换坐标系 gps -> 火星

RALog("amap转换:\(AMapLocationCoordinateConvert(location.coordinate, .GPS))")

RALog("算法转换:" + "\(RAlLocation().wgs84(toGcj02: location.coordinate))")
[文件名:**]打印内容:北京市**区**路**号**楼*号楼*层**有限公司**分公司
[文件名:**]打印内容:amap转换:CLLocationCoordinate2D(latitude: **.034504123263886, longitude: ***.42154568142361)
[文件名:**]打印内容: 算法转换:CLLocationCoordinate2D(latitude: **.03450393676758, longitude: ***.42154693603516)
[文件名:**]打印内容:amap转换:CLLocationCoordinate2D(latitude: **.034503123263886, longitude: ***.42154568142361)
[文件名:**]打印内容: 算法转换:CLLocationCoordinate2D(latitude: **.03450393676758, longitude: ***.42154693603516)

小数点前几位几乎相同。

 

 

//
//  RALocationManager.swift
//  Radio
//
//  Created by baitogntong on 2020/9/16.
//  Copyright © 2020 hq. All rights reserved.
//

import CoreLocation

class RALocationManager: NSObject {
    
    static let shared = RALocationManager()
    
    var callBack:((CLPlacemark, CLLocationCoordinate2D)->())?
    private var locationManager : CLLocationManager?
    
    public func startLocation() {
        /// 未授权
        if locationManager != nil && (CLLocationManager.authorizationStatus() == .denied) {
            showAlert()
        }else {
            requestLocationAuthorization()
        }
        
    }
    
    /// 初始化定位服务
    private func requestLocationAuthorization() {
        
        if locationManager == nil {
            locationManager = CLLocationManager()
            locationManager?.delegate = self
        }
        
        
        
        if (CLLocationManager.authorizationStatus() == CLAuthorizationStatus.notDetermined) {
            locationManager?.requestWhenInUseAuthorization()
        }
        
        if (CLLocationManager.authorizationStatus() == CLAuthorizationStatus.authorizedWhenInUse) {
            locationManager?.desiredAccuracy = kCLLocationAccuracyBest
            let distance : CLLocationDistance = 10.0
            locationManager?.distanceFilter = distance
            locationManager?.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
            locationManager?.startUpdatingLocation()
        }else {
            locationManager?.requestWhenInUseAuthorization()
            locationManager?.startUpdatingLocation()
        }
        
    }
    
    // 获取定位代理返回状态进行处理
    private func reportLocationServicesAuthorizationStatus(status: CLAuthorizationStatus) {
        
        if status == .notDetermined {
            // 未决定,继续请求授权
            requestLocationAuthorization()
        } else if (status == .restricted) {
            // 受限制,尝试提示然后进入设置页面进行处理
            showAlert()
        } else if (status == .denied) {
            // 受限制,尝试提示然后进入设置页面进行处理
            showAlert()
        }
    }
    
    
    private func showAlert() {
        RATool.showAlert(title: "定位服务未开启,是否前往开启?", message: "请进入系统[设置]->[隐私]->[定位服务]中打开开关,并允许使用定位服务", cancel: "取消", confirm: "确定") {
            let url = URL(fileURLWithPath: UIApplication.openSettingsURLString)
            if UIApplication.shared.canOpenURL(url){
                UIApplication.shared.open(url, options: [:], completionHandler: nil)
            }
            
        }
    }
}

extension RALocationManager: CLLocationManagerDelegate {
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        self.locationManager?.stopUpdatingLocation()
        
        let location = locations.last ?? CLLocation()
        let geocoder = CLGeocoder()
        geocoder.reverseGeocodeLocation(location) { (placemarks, error) in
            
            if error != nil {
                RALog(error?.localizedDescription ?? "")
                return
            }
            
            if let place = placemarks?[0]{
                // 国家 省  市  区  街道  名称  国家编码  邮编
                let administrativeArea = place.administrativeArea ?? ""
                let locality = place.locality ?? "-"
                let subLocality = place.subLocality ?? "-"
                let thoroughfare = place.thoroughfare ?? "-"
                let name = place.name ?? "-"
                
                let addressLines =  administrativeArea + locality + subLocality + thoroughfare + name
                RALog(addressLines)
                
                if RALocationChange.shard.isLocationInChina(location.coordinate) { //中国境内
                    /*
                    RALog("amap转换:\(AMapLocationCoordinateConvert(location.coordinate, .GPS))")
                    RALog("算法1转换:" + "\(RAlLocation().wgs84(toGcj02: location.coordinate))")
                    RALog("算法2转换:" + "\(RALocationChange.shard.transformFromWGSToGCJ(wgsLoc: location.coordinate))")
                    
                    打印内容:北京市朝阳区**路*号**研究所***有限公司**分公司
                    打印内容:amap转换:CLLocationCoordinate2D(latitude: *0.03451388888889, longitude: 1*.42153591579861)
                    打印内容:算法1转换:CLLocationCoordinate2D(latitude: *0.034515380859375, longitude: 1*.42153930664062)
                    打印内容:算法2转换:CLLocationCoordinate2D(latitude: *0.03451365425698, longitude: 1*.42153584827392)
                    */
                    self.callBack?(place,RALocationChange.shard.transformFromWGSToGCJ(wgsLoc: location.coordinate))
                    
                } else {
                    self.callBack?(place,location.coordinate)
                    RALog( location.coordinate)
                }
            } else {
                RALog(error?.localizedDescription ?? "")
            }
        }
    }
    
    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        reportLocationServicesAuthorizationStatus(status: status)
    }
    
    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        self.locationManager?.stopUpdatingLocation()
    }
    
}
///高德
/*
extension RALocationManager: AMapLocationManagerDelegate {
 
    let AmaplocationManager = AMapLocationManager()

    func aMapLocation(_ callBack: ((AMapLocationReGeocode, CLLocationCoordinate2D)->())?) {
        
        AmaplocationManager.delegate = self
        /*
         //高德
         2020-11-25 11:15:17.377562+0800 zhuliyinyu[3237:906379] location:<+40.03449463,+116.42152886> +/- 65.00m (speed -1.00 mps / course -1.00) @ 2020/11/25 中国标准时间 上午11:14:54
         2020-11-25 11:15:17.378037+0800 zhuliyinyu[3237:906379] reGeocode:AMapLocationReGeocode:{formattedAddress:北京市朝阳**(北京**店); country:中国;province:北京市; city:北京市; district:朝阳区; citycode:010; adcode:110105; street:北苑路; number:7号; POIName:集美家居(北京北苑店); AOIName:北苑五号院4区;}
         //系统
         [文件名:RALocationManager.swift]    [行数:109]    打印内容:北京市朝***北京分公司
         [文件名:RALocationManager.swift]    [行数:111]    打印内容:CLLocationCoordinate2D(latitude: 40.034520484928365, longitude: 116.42152212016788)
         */
        AmaplocationManager.desiredAccuracy = 10
        AmaplocationManager.locationTimeout = 10
        AmaplocationManager.reGeocodeTimeout = 5
        
        AmaplocationManager.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的添加
                    NSLog("定位错误:{\(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 {
                    
                    //逆地理错误:在带逆地理的单次定位中,逆地理过程可能发生错误,此时location有返回值,regeocode无返回值,进行annotation的添加
                    NSLog("逆地理错误:{\(error.code) - \(error.localizedDescription)};")
                }
                else {
                    if let back = callBack {
                        print(reGeocode ?? AMapLocationReGeocode())
                        print(location?.coordinate ?? CLLocationCoordinate2D() )
                        let coordiante = CLLocationCoordinate2D(latitude: 39.948691, longitude: 116.492479)
                        let flag = AMapLocationDataAvailableForCoordinate(coordiante)
                        if flag {  //中国境内
                            back(reGeocode ?? AMapLocationReGeocode(),AMapLocationCoordinateConvert(location?.coordinate ?? CLLocationCoordinate2D(), .GPS) )
                        } else {
                            back(reGeocode ?? AMapLocationReGeocode(),location?.coordinate ?? CLLocationCoordinate2D() )
                        }
                        
                    }
                    //没有错误:location有返回值,regeocode是否有返回值取决于是否进行逆地理操作,进行annotation的添加
                }
            }
            
            if let location = location {
                NSLog("location:%@", location)
            }
            
            if let reGeocode = reGeocode {
                NSLog("reGeocode:%@", reGeocode)
            }
        })
    }
}
*/

 

posted @ 2020-11-25 15:00  M·emor·Y  阅读(1250)  评论(0编辑  收藏  举报