BaiduMapManager.swift 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. //
  2. // BaiduMapManager.swift
  3. // RainbowPlanet
  4. //
  5. // Created by 南鑫林 on 2018/10/17.
  6. // Copyright © 2018 南鑫林. All rights reserved.
  7. //
  8. import UIKit
  9. import SwiftyJSON
  10. //MARK: - 百度地图
  11. let kBaiduMapAppKey = "v7wFjrAQdlaBVC50CjwuRESC3Lu0xkhj"
  12. public class BaiduMapManager: NSObject {
  13. static let shared : BaiduMapManager = BaiduMapManager()
  14. private override init() {} // 私有化init方法
  15. var locationModel = LocationModel.shared()
  16. typealias LocationSuccessBlock = () -> Void
  17. var locationSuccessBlock : LocationSuccessBlock?
  18. typealias LocationFalseBlock = () -> Void
  19. var locationFalseBlock : LocationFalseBlock?
  20. /// 初始化百度
  21. public func initBaiduMap() -> Void {
  22. BMKLocationAuth.sharedInstance()?.checkPermision(withKey: kBaiduMapAppKey, authDelegate: self)
  23. BMKMapManager().start(kBaiduMapAppKey, generalDelegate: self)
  24. }
  25. // ====================================定位========================================
  26. /// 定位管理
  27. private lazy var locationManager: BMKLocationManager = {
  28. let locationManager = BMKLocationManager.init()
  29. //设置delegate
  30. locationManager.delegate = self
  31. //设置返回位置的坐标系类型
  32. locationManager.coordinateType = BMKLocationCoordinateType.BMK09LL
  33. //设置距离过滤参数
  34. locationManager.distanceFilter = kCLDistanceFilterNone
  35. //设置预期精度参数
  36. locationManager.desiredAccuracy = kCLLocationAccuracyBest
  37. //设置应用位置类型
  38. locationManager.activityType = CLActivityType.automotiveNavigation
  39. //设置是否自动停止位置更新
  40. locationManager.pausesLocationUpdatesAutomatically = false
  41. //设置是否允许后台定位
  42. locationManager.allowsBackgroundLocationUpdates = true
  43. //设置位置获取超时时间
  44. locationManager.locationTimeout = 10
  45. //设置获取地址信息超时时间
  46. locationManager.reGeocodeTimeout = 10
  47. return locationManager
  48. }()
  49. /// 开始定位
  50. func startLocation() {
  51. initLocation(locationSuccessBlock: {
  52. if let locationSuccessBlock = self.locationSuccessBlock {
  53. locationSuccessBlock()
  54. }
  55. }, locationFalseBlock: {
  56. if let locationFalseBlock = self.locationFalseBlock {
  57. locationFalseBlock()
  58. }
  59. })
  60. }
  61. /// 单次定位
  62. func initLocation(locationSuccessBlock:@escaping LocationSuccessBlock,locationFalseBlock:@escaping LocationFalseBlock) -> Void {
  63. locationManager.requestLocation(withReGeocode: true, withNetworkState: true) { [weak self] location, state, error in
  64. if (error != nil) {
  65. locationFalseBlock()
  66. return
  67. } else {
  68. if let location = location {
  69. if let location = location.location {
  70. self?.locationModel.latitude = String(describing: location.coordinate.latitude)
  71. self?.locationModel.longitude = String(describing: location.coordinate.longitude)
  72. }
  73. if let rgcData = location.rgcData {
  74. self?.locationModel.cityCode = rgcData.cityCode ?? ""
  75. self?.locationModel.province = rgcData.province ?? ""
  76. self?.locationModel.city = rgcData.city ?? ""
  77. self?.locationModel.district = rgcData.district ?? ""
  78. self?.locationModel.street = rgcData.street ?? ""
  79. self?.locationModel.locationdescribe = rgcData.locationDescribe ?? ""
  80. // 存放BMKLocationPoi的Array不可直接转换为Json(暂不知具体原因),建立一个Swift对应的Model
  81. var poiList: Array<SwiftLocationPOIModel> = []
  82. let oriPoiList = rgcData.poiList ?? []
  83. for (_, locationPoi) in oriPoiList.enumerated() {
  84. let poiMdl: SwiftLocationPOIModel = SwiftLocationPOIModel()
  85. poiMdl.name = locationPoi.name
  86. poiMdl.uid = locationPoi.uid
  87. poiList.append(poiMdl)
  88. }
  89. self?.locationModel.poiList = poiList
  90. }
  91. LocationModel.shared().saveObject(locationModel: self?.locationModel ?? LocationModel())
  92. NXLLog(LocationModel.shared().object())
  93. locationSuccessBlock()
  94. }
  95. }
  96. }
  97. }
  98. /// 定位设置弹框
  99. func loacationAlertView() {
  100. AlertSheetView.alert(title: "定位服务未开启", detailTitle: "请进入系统设置「设置」「隐私」「定位服务」中打开开关,并允许彩虹星球使用定位服务", cancelTitle: "取消", sureTitle: "立即开启", cancelBlock: { (popupView, Int, string) in
  101. if let locationFalseBlock = self.locationFalseBlock {
  102. locationFalseBlock()
  103. }
  104. }, confirmBlock: { (popupView, Int, string) in
  105. if #available(iOS 10.0, *) {
  106. let url = URL(string: UIApplication.openSettingsURLString)
  107. if let url = url {
  108. if UIApplication.shared.canOpenURL(url) {
  109. UIApplication.shared.open(url, options: [:], completionHandler: { [weak self] success in
  110. self?.initLocation(locationSuccessBlock: {
  111. if let locationSuccessBlock = self?.locationSuccessBlock {
  112. locationSuccessBlock()
  113. }
  114. }, locationFalseBlock: { [weak self] in
  115. if let locationFalseBlock = self?.locationFalseBlock {
  116. locationFalseBlock()
  117. }
  118. })
  119. })
  120. }
  121. }
  122. } else {
  123. let url = URL(string: UIApplication.openSettingsURLString)
  124. if let url = url {
  125. if UIApplication.shared.canOpenURL(url) {
  126. UIApplication.shared.openURL(url)
  127. }
  128. }
  129. }
  130. })
  131. }
  132. //====================================POI检索===============================
  133. typealias SuggestionSearchSuccessBlock = (_ suggestionList:Array<BMKSuggestionInfo>) -> Void
  134. var suggestionSearchSuccessBlock : SuggestionSearchSuccessBlock?
  135. /// 初始化地点输入提示检索对象
  136. private lazy var suggestionSearcharch: BMKSuggestionSearch = {
  137. let suggestionSearcharch = BMKSuggestionSearch()
  138. suggestionSearcharch.delegate = self
  139. return suggestionSearcharch
  140. }()
  141. private lazy var suggestionSearchOption: BMKSuggestionSearchOption = {
  142. let suggestionSearchOption = BMKSuggestionSearchOption()
  143. suggestionSearchOption.cityLimit = true
  144. return suggestionSearchOption
  145. }()
  146. /// 地点输入提示检索(Sug检索)
  147. ///
  148. /// - Parameters:
  149. /// - cityname: 城市名
  150. /// - keyword:
  151. func suggestionSearchPoi(cityname:String = "西安市",keyword:String = "瓦胡同") {
  152. suggestionSearchOption.cityname = cityname
  153. suggestionSearchOption.keyword = keyword
  154. let flag = suggestionSearcharch.suggestionSearch(suggestionSearchOption)
  155. if flag {
  156. NXLLog("Sug检索发送成功");
  157. } else {
  158. NXLLog("Sug检索发送失败");
  159. }
  160. }
  161. }
  162. // MARK: - 定位授权
  163. extension BaiduMapManager: BMKLocationAuthDelegate {
  164. public func onCheckPermissionState(_ iError: BMKLocationAuthErrorCode) {
  165. if (0 == iError.rawValue) {
  166. NXLLog("授权成功");
  167. } else {
  168. NXLLog("授权失败 \(iError)");
  169. }
  170. }
  171. }
  172. // MARK: - 定位代理
  173. extension BaiduMapManager:BMKLocationManagerDelegate {
  174. /// 当定位发生错误时,会调用代理的此方法。
  175. public func bmkLocationManager(_ manager: BMKLocationManager, didFailWithError error: Error?) {
  176. NXLLog("定位错误");
  177. }
  178. /// 定位权限状态改变时回调函数
  179. public func bmkLocationManager(_ manager: BMKLocationManager, didChange status: CLAuthorizationStatus) {
  180. if status == .notDetermined {
  181. //用户尚未对此应用程序做出选择
  182. } else if status == .restricted {
  183. //此应用程序无权使用位置服务。到期
  184. //对于位置服务的活动限制,用户不能更改
  185. //此状态,可能未亲自拒绝授权
  186. } else if status == .denied {
  187. //用户已明确拒绝此应用程序的授权,或者
  188. //位置服务在设置中被禁用。
  189. startLocation()
  190. }else if status == .authorizedAlways {
  191. //用户已授予随时使用其位置的权限,
  192. //包括区域、访问或重大位置更改的监控。
  193. //该值应用于iOS、tvos和watchos。它在上有售
  194. //macos,但kclauthorizationstatusauthorized是同义词且首选。
  195. startLocation()
  196. }else if status == .authorizedWhenInUse {
  197. //只有在应用程序
  198. //对它们可见(如果继续在后台接收位置更新)。授权使用
  199. //尚未授予启动API。此值在MacOS上不可用。它应该在iOS、tvos和沃特克斯。
  200. startLocation()
  201. }
  202. }
  203. }
  204. // MARK: - 地图授权
  205. extension BaiduMapManager: BMKGeneralDelegate {
  206. /// 返回网络错误
  207. ///
  208. /// - Parameter iError: 错误号
  209. public func onGetNetworkState(_ iError: Int32) {
  210. }
  211. /// 返回授权验证错误
  212. ///
  213. /// - Parameter iError: 错误号 : 为0时验证通过,具体参加BMKPermissionCheckResultCode
  214. public func onGetPermissionState(_ iError: Int32) {
  215. if (0 == iError) {
  216. NXLLog("授权成功");
  217. } else {
  218. NXLLog("授权失败 \(iError)");
  219. }
  220. }
  221. }
  222. // MARK: - 地点输入提示检索(Sug检索)
  223. extension BaiduMapManager: BMKSuggestionSearchDelegate {
  224. public func onGetSuggestionResult(_ searcher: BMKSuggestionSearch!, result: BMKSuggestionSearchResult!, errorCode error: BMKSearchErrorCode) {
  225. switch error {
  226. //检索结果正常返回
  227. case BMK_SEARCH_NO_ERROR:
  228. if let suggestionSearchSuccessBlock = self.suggestionSearchSuccessBlock {
  229. if result.suggestionList.count > 0 {
  230. suggestionSearchSuccessBlock(result.suggestionList)
  231. }
  232. }
  233. break
  234. case BMK_SEARCH_AMBIGUOUS_KEYWORD:
  235. SwiftProgressHUD.shared().showText("检索词有岐义")
  236. break
  237. case BMK_SEARCH_AMBIGUOUS_ROURE_ADDR:
  238. SwiftProgressHUD.shared().showText("检索地址有岐义")
  239. break
  240. case BMK_SEARCH_NOT_SUPPORT_BUS:
  241. SwiftProgressHUD.shared().showText("该城市不支持公交搜索")
  242. break
  243. case BMK_SEARCH_NOT_SUPPORT_BUS_2CITY:
  244. SwiftProgressHUD.shared().showText("不支持跨城市公交")
  245. break
  246. case BMK_SEARCH_RESULT_NOT_FOUND:
  247. SwiftProgressHUD.shared().showText("没有找到检索结果")
  248. break
  249. case BMK_SEARCH_ST_EN_TOO_NEAR:
  250. SwiftProgressHUD.shared().showText("起终点太近")
  251. break
  252. case BMK_SEARCH_KEY_ERROR:
  253. SwiftProgressHUD.shared().showText("key错误")
  254. break
  255. case BMK_SEARCH_NETWOKR_ERROR:
  256. SwiftProgressHUD.shared().showText("网络连接错误")
  257. break
  258. case BMK_SEARCH_PERMISSION_UNFINISHED:
  259. SwiftProgressHUD.shared().showText("还未完成鉴权,请在鉴权通过后重试")
  260. break
  261. case BMK_SEARCH_INDOOR_ID_ERROR:
  262. SwiftProgressHUD.shared().showText("室内图ID错误")
  263. break
  264. case BMK_SEARCH_FLOOR_ERROR:
  265. SwiftProgressHUD.shared().showText("室内图检索楼层错误")
  266. break
  267. case BMK_SEARCH_INDOOR_ROUTE_NO_IN_BUILDING:
  268. SwiftProgressHUD.shared().showText("起终点不在支持室内路线的室内图内")
  269. break
  270. case BMK_SEARCH_INDOOR_ROUTE_NO_IN_SAME_BUILDING:
  271. SwiftProgressHUD.shared().showText("起终点不在同一个室内")
  272. break
  273. case BMK_SEARCH_PARAMETER_ERROR:
  274. SwiftProgressHUD.shared().showText("参数错误")
  275. break
  276. case BMK_SEARCH_SERVER_ERROR:
  277. SwiftProgressHUD.shared().showText("服务器错误")
  278. break
  279. default:
  280. SwiftProgressHUD.shared().showText("检索失败")
  281. break
  282. }
  283. }
  284. }