定位转换
//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) } }) } } */