MapAmapThemeControl.swift 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694
  1. //
  2. // MapAmapThemeControl.swift
  3. // map_amap_ios
  4. //
  5. // Created by 诺诺诺的言 on 2025/7/22.
  6. //
  7. import Foundation
  8. import MapKit
  9. import Combine
  10. import AMapFoundationKit
  11. import MAMapKit
  12. @available(iOS 13.0, *)
  13. class MapAmapThemeControl: UIViewController {
  14. required init?(coder: NSCoder) {
  15. fatalError("init(coder:) has not been implemented")
  16. }
  17. let viewModel: MapAmapViewAndDataExchange
  18. var autonaviMap : MAMapView!
  19. //let mapView = MKMapView()
  20. private var cancellables = Set<AnyCancellable>()
  21. init(viewModel: MapAmapViewAndDataExchange) {
  22. self.viewModel = viewModel
  23. super.init(nibName: nil, bundle: nil)
  24. //mapView.showsUserLocation = false
  25. }
  26. override func viewDidLoad() {
  27. super.viewDidLoad()
  28. // 1. 设置隐私(必须!)
  29. MAMapView.updatePrivacyShow(.didShow, privacyInfo: .didContain)
  30. MAMapView.updatePrivacyAgree(.didAgree)
  31. AMapServices.shared().enableHTTPS = true
  32. loadMainMapView()
  33. bindViewModel()
  34. }
  35. private func loadMainMapView() {
  36. guard AMapServices.shared().apiKey != nil else {
  37. fatalError("高德地图API Key未配置!")
  38. }
  39. autonaviMap = MAMapView(frame: view.bounds)
  40. print("地图初始化失败,请检查Key和Bundle ID--\(autonaviMap)")
  41. guard let map = autonaviMap else {
  42. print("地图初始化失败,请检查Key和Bundle ID--")
  43. return
  44. }
  45. map.delegate = self
  46. map.logoCenter = CGPointMake(-100, 0)
  47. map.isRotateCameraEnabled = false
  48. map.showsCompass = false
  49. map.isRotateEnabled = false
  50. map.mapType = .standard
  51. map.showsUserLocation = false
  52. map.userTrackingMode = .none
  53. view.addSubview(map)
  54. map.translatesAutoresizingMaskIntoConstraints = false
  55. view.addSubview(map)
  56. NSLayoutConstraint.activate([
  57. map.topAnchor.constraint(equalTo: view.topAnchor),
  58. map.bottomAnchor.constraint(equalTo: view.bottomAnchor),
  59. map.leadingAnchor.constraint(equalTo: view.leadingAnchor),
  60. map.trailingAnchor.constraint(equalTo: view.trailingAnchor)
  61. ])
  62. }
  63. private func bindViewModel() {
  64. viewModel.$markers
  65. .receive(on: DispatchQueue.main)
  66. .sink { [weak self] markers in
  67. if let annotationsList = self?.autonaviMap.annotations {
  68. print("annotationsListsdfsdfs---\(annotationsList)");
  69. self?.autonaviMap.removeAnnotations(self?.autonaviMap.annotations)
  70. }
  71. // UIView.animate(withDuration: 0.3) {
  72. // self?.autonaviMap.addAnnotations(markers)
  73. // }
  74. var mapMarkerList = [MAPointAnnotation]();
  75. for markerItem in markers {
  76. print("markerItemsfsfdsytp---\(markerItem.markerType)---\(String(describing: markerItem.markerName))---\(String(describing: markerItem.tags))")
  77. let annotationItem : MyMAPointAnnotation = MyMAPointAnnotation(itemMarker: markerItem)
  78. annotationItem.title = markerItem.markerName;
  79. annotationItem.coordinate = markerItem.coordinate;
  80. mapMarkerList.append(annotationItem)
  81. }
  82. self?.autonaviMap.addAnnotations(mapMarkerList)
  83. // self?.autonaviMap.selectAnnotation(mapMarkerList.first, animated: true)
  84. //self?.autonaviMap.setZoomLevel(20, animated: true)
  85. /*if !mapMarkerList.isEmpty {
  86. let selectIemt : MAPointAnnotation = mapMarkerList.first!
  87. self?.autonaviMap.setCenter(selectIemt.coordinate, animated: true)
  88. }*/
  89. }
  90. .store(in: &cancellables)
  91. ///移动到特定的位置
  92. viewModel.$currentRegion
  93. .compactMap { $0 }
  94. .receive(on: DispatchQueue.main)
  95. .sink { [weak self] region in
  96. self?.autonaviMap.setRegion(region, animated: true)
  97. //self?.mapView.setRegion(region, animated: true)
  98. }
  99. .store(in: &cancellables)
  100. viewModel.$polylines
  101. .receive(on: DispatchQueue.main)
  102. .sink { [weak self] polylines in
  103. self!.autonaviMap.removeOverlays(self!.autonaviMap.overlays)
  104. guard let self, !polylines.isEmpty else { return }
  105. // 清除旧覆盖物
  106. self.autonaviMap.removeOverlays(self.autonaviMap.overlays)
  107. var polyinesList = [MAPolyline]();
  108. for polyline in polylines {
  109. let polylineItem : MyMAPolyline = MyMAPolyline(coordinates: &polyline.points, count: UInt(polyline.points.count))
  110. print("polylinesfsfs---\(polyline.lineType)")
  111. polylineItem.itemPolyLine = polyline
  112. polyinesList.append(polylineItem)
  113. }
  114. // 添加新覆盖物
  115. self.autonaviMap.addOverlays(polyinesList)
  116. // 自动调整视野
  117. if let lastPolyline = polylines.last,
  118. let padding = lastPolyline.mapPadding {
  119. self.autonaviMap.showOverlays(
  120. polyinesList,
  121. edgePadding: UIEdgeInsets(
  122. top: padding.top,
  123. left: padding.left,
  124. bottom: padding.bottom,
  125. right: padding.right
  126. ),
  127. animated: true
  128. )
  129. }
  130. }
  131. .store(in: &cancellables)
  132. //移动至多个点的位置,并提供设置padding距离
  133. viewModel.$suitableLocation
  134. .receive(on: DispatchQueue.main)
  135. .sink{ [weak self] polylines in
  136. if let padding = polylines.last?.mapPadding {
  137. if let atMapPoint : [CLLocationCoordinate2D] = polylines.last?.points {
  138. self?.autonaviMap.moveToSuitableLocation(points: atMapPoint, padding: padding)
  139. //self?.mapView.moveToSuitableLocation(points: atMapPoint, padding: padding)
  140. }
  141. }
  142. }
  143. .store(in: &cancellables)
  144. /*viewModel.$polylines
  145. .receive(on: DispatchQueue.main)
  146. .sink { [weak self] polylines in
  147. guard let self else { return }
  148. // 清除旧覆盖物
  149. self.autonaviMap.removeOverlays(self.autonaviMap.overlays)
  150. // 空数据检查
  151. guard !polylines.isEmpty else {
  152. print("轨迹数据为空")
  153. return
  154. }
  155. // 处理每条轨迹
  156. var validPolylines: [MAPolyline] = []
  157. for polyline in polylines {
  158. // 坐标数量检查
  159. guard !polyline.points.isEmpty else {
  160. print("发现空坐标的轨迹: \(polyline.id)")
  161. continue
  162. }
  163. // 指针转换
  164. let creationResult = polyline.points.withUnsafeBufferPointer { bufferPointer -> MAPolyline? in
  165. guard let baseAddress = bufferPointer.baseAddress, bufferPointer.count > 0 else {
  166. return nil
  167. }
  168. let unsafePointer = UnsafeMutablePointer(mutating: baseAddress)
  169. return MAPolyline(
  170. coordinates: unsafePointer,
  171. count: UInt(bufferPointer.count)
  172. )
  173. }
  174. // 结果检查
  175. guard let mapPolyline = creationResult else {
  176. print("轨迹创建失败: \(polyline.id)")
  177. continue
  178. }
  179. // 绑定属性
  180. mapPolyline.associatedData = [
  181. "id": polyline.id,
  182. "color": polyline.color,
  183. "width": polyline.width
  184. ]
  185. validPolylines.append(mapPolyline)
  186. }
  187. // 添加有效轨迹
  188. guard !validPolylines.isEmpty else {
  189. print("没有有效的轨迹数据")
  190. return
  191. }
  192. self.autonaviMap.addOverlays(validPolylines)
  193. // 调整视野
  194. if let lastValid = validPolylines.last,
  195. let padding = polylines.last?.mapPadding {
  196. self.autonaviMap.showOverlays(
  197. validPolylines,
  198. edgePadding: UIEdgeInsets(
  199. top: padding.top,
  200. left: padding.left,
  201. bottom: padding.bottom,
  202. right: padding.right
  203. ),
  204. animated: true
  205. )
  206. }
  207. }
  208. .store(in: &cancellables)
  209. viewModel.$markers
  210. .receive(on: DispatchQueue.main)
  211. .sink { [weak self] markers in
  212. self?.mapView.removeAnnotations(self?.mapView.annotations ?? [])
  213. UIView.animate(withDuration: 0.3) {
  214. self?.mapView.addAnnotations(markers)
  215. }
  216. }
  217. .store(in: &cancellables)
  218. viewModel.$polylines
  219. .receive(on: DispatchQueue.main)
  220. .sink { [weak self] polylines in
  221. self?.mapView.removeOverlays(self?.mapView.overlays ?? [])
  222. var polyinesList = [MKPolyline]();
  223. for polyline in polylines {
  224. let polylineItem : MKPolyline = polyline.polyline
  225. polylineItem.associatedLineId = polyline.id
  226. polylineItem.associatedLineType = polyline.lineType
  227. polylineItem.associatedColor = polyline.color
  228. polylineItem.associatedWidth = polyline.width
  229. polyinesList.append(polylineItem)
  230. }
  231. self?.mapView.addOverlays(polyinesList)
  232. //self?.mapView.addOverlays(polylines.map({ $0.polyline }))
  233. if let padding = polylines.last?.mapPadding {
  234. self?.mapView.fitsAllPoints(
  235. points: polylines.last?.points.compactMap({ MKMapPoint($0) }) ?? [],
  236. padding: padding.padding,
  237. animated: true
  238. )
  239. }
  240. }
  241. .store(in: &cancellables)
  242. //移动至多个点的位置,并提供设置padding距离
  243. viewModel.$suitableLocation
  244. .receive(on: DispatchQueue.main)
  245. .sink{ [weak self] polylines in
  246. if let padding = polylines.last?.mapPadding {
  247. if let atMapPoint : [CLLocationCoordinate2D] = polylines.last?.points {
  248. self?.mapView.moveToSuitableLocation(points: atMapPoint, padding: padding)
  249. }
  250. }
  251. }
  252. .store(in: &cancellables)*/
  253. }
  254. /*var polyinesList = [MKPolyline]();
  255. for polyline in polylines {
  256. let polylineItem : MKPolyline = polyline.polyline
  257. polylineItem.associatedLineId = polyline.id
  258. polylineItem.associatedLineType = polyline.lineType
  259. polylineItem.associatedColor = polyline.color
  260. polylineItem.associatedWidth = polyline.width
  261. polyinesList.append(polylineItem)
  262. }
  263. self?.mapView.addOverlays(polyinesList)
  264. //self?.mapView.addOverlays(polylines.map({ $0.polyline }))
  265. if let padding = polylines.last?.mapPadding {
  266. self?.mapView.fitsAllPoints(
  267. points: polylines.last?.points.compactMap({ MKMapPoint($0) }) ?? [],
  268. padding: padding.padding,
  269. animated: true
  270. )
  271. }
  272. guard let self, !polylines.isEmpty else { return }
  273. // 清除旧覆盖物
  274. self.autonaviMap.removeOverlays(self.autonaviMap.overlays)
  275. // 创建自定义Polyline类数组
  276. let customPolylines = polylines.compactMap { polyline -> CustomPolyline? in
  277. // 创建高德地图Polyline
  278. let count = UInt(polyline.points.count)
  279. guard let mapPolyline = MAPolyline(coordinates: &polyline.points , count: count) else {
  280. return nil
  281. }
  282. // 使用自定义类包装
  283. return CustomPolyline(
  284. polyline: mapPolyline,
  285. id: polyline.id,
  286. color: polyline.color,
  287. width: polyline.width
  288. )
  289. }
  290. // 添加新覆盖物
  291. self.autonaviMap.addOverlays(customPolylines.map { $0.polyline })
  292. // 自动调整视野
  293. if let lastPolyline = polylines.last,
  294. let padding = lastPolyline.mapPadding {
  295. self.autonaviMap.showOverlays(
  296. customPolylines.map { $0.polyline },
  297. edgePadding: UIEdgeInsets(
  298. top: padding.top,
  299. left: padding.left,
  300. bottom: padding.bottom,
  301. right: padding.right
  302. ),
  303. animated: true
  304. )
  305. }*/
  306. /*private func bindViewModel() {
  307. viewModel.$markers
  308. .receive(on: DispatchQueue.main)
  309. .sink { [weak self] markers in
  310. self?.autonaviMap.removeAnnotations(self?.autonaviMap.annotations)
  311. var mapMarkerList = [MAPointAnnotation]();
  312. for markerItem in markers {
  313. let annotationItem : MAPointAnnotation = MAPointAnnotation()
  314. annotationItem.title = markerItem.markerName;
  315. annotationItem.coordinate = markerItem.coordinate;
  316. mapMarkerList.append(annotationItem)
  317. }
  318. self?.autonaviMap.addAnnotations(mapMarkerList)
  319. self?.autonaviMap.selectAnnotation(mapMarkerList.first, animated: true)
  320. self?.autonaviMap.setZoomLevel(15.1, animated: true)
  321. let selectIemt : MAPointAnnotation = mapMarkerList.first!
  322. self?.autonaviMap.setCenter(selectIemt.coordinate, animated: true)
  323. //self?.mapView.removeAnnotations(self?.mapView.annotations ?? [])
  324. // UIView.animate(withDuration: 0.3) {
  325. // self?.mapView.addAnnotations(markers)
  326. // }
  327. }
  328. .store(in: &cancellables)
  329. viewModel.$currentRegion
  330. .compactMap { $0 }
  331. .receive(on: DispatchQueue.main)
  332. .sink { [weak self] region in
  333. self?.mapView.setRegion(region, animated: true)
  334. }
  335. .store(in: &cancellables)
  336. viewModel.$markers
  337. .receive(on: DispatchQueue.main)
  338. .sink { [weak self] markers in
  339. self?.mapView.removeAnnotations(self?.mapView.annotations ?? [])
  340. UIView.animate(withDuration: 0.3) {
  341. self?.mapView.addAnnotations(markers)
  342. }
  343. }
  344. .store(in: &cancellables)
  345. viewModel.$polylines
  346. .receive(on: DispatchQueue.main)
  347. .sink { [weak self] polylines in
  348. self?.mapView.removeOverlays(self?.mapView.overlays ?? [])
  349. var polyinesList = [MKPolyline]();
  350. for polyline in polylines {
  351. let polylineItem : MKPolyline = polyline.polyline
  352. polylineItem.associatedLineId = polyline.id
  353. polylineItem.associatedLineType = polyline.lineType
  354. polylineItem.associatedColor = polyline.color
  355. polylineItem.associatedWidth = polyline.width
  356. polyinesList.append(polylineItem)
  357. }
  358. self?.mapView.addOverlays(polyinesList)
  359. //self?.mapView.addOverlays(polylines.map({ $0.polyline }))
  360. if let padding = polylines.last?.mapPadding {
  361. self?.mapView.fitsAllPoints(
  362. points: polylines.last?.points.compactMap({ MKMapPoint($0) }) ?? [],
  363. padding: padding.padding,
  364. animated: true
  365. )
  366. }
  367. }
  368. .store(in: &cancellables)
  369. //移动至多个点的位置,并提供设置padding距离
  370. viewModel.$suitableLocation
  371. .receive(on: DispatchQueue.main)
  372. .sink{ [weak self] polylines in
  373. if let padding = polylines.last?.mapPadding {
  374. if let atMapPoint : [CLLocationCoordinate2D] = polylines.last?.points {
  375. self?.mapView.moveToSuitableLocation(points: atMapPoint, padding: padding)
  376. }
  377. }
  378. }
  379. .store(in: &cancellables)
  380. }*/
  381. }
  382. // 自定义Polyline包装类
  383. private class CustomPolyline {
  384. let polyline: MAPolyline
  385. let id: String
  386. let color: String
  387. let width: Double
  388. init(polyline: MAPolyline, id: String, color: String, width: Double) {
  389. self.polyline = polyline
  390. self.id = id
  391. self.color = color
  392. self.width = width
  393. }
  394. }
  395. private class MyMAPointAnnotation : MAPointAnnotation {
  396. let itemMarker : ATMapMarker
  397. init(itemMarker: ATMapMarker) {
  398. self.itemMarker = itemMarker
  399. }
  400. }
  401. private class MyMAPolyline : MAPolyline {
  402. var itemPolyLine : ATMapPolyline! = nil
  403. }
  404. @available(iOS 13.0, *)
  405. extension MapAmapThemeControl : MAMapViewDelegate {
  406. //根据anntation生成对应的View。
  407. func mapView(_ mapView: MAMapView!, viewFor annotation: MAAnnotation!) -> MAAnnotationView! {
  408. // guard let marker = annotation as? ATMapMarker else {
  409. // return nil
  410. // }
  411. if let myitemAnnotation = annotation as? MyMAPointAnnotation {
  412. print("markerItemsfsfdsytp--AT-\(myitemAnnotation.itemMarker.markerType)---\(String(describing: myitemAnnotation.itemMarker.markerName))---\(String(describing: myitemAnnotation.itemMarker.tags))--")
  413. if myitemAnnotation.itemMarker.markerType.isMapAchorPoint {
  414. let annotationView = (mapView.dequeueReusableAnnotationView(withIdentifier: MapAnnotationAnchorPointView.identifier) as? MapAnnotationAnchorPointView) ?? MapAnnotationAnchorPointView(annotation: (myitemAnnotation as MAAnnotation), reuseIdentifier: MapAnnotationAnchorPointView.identifier)
  415. annotationView!.marker = myitemAnnotation.itemMarker
  416. return annotationView
  417. } else if (myitemAnnotation.itemMarker.markerType.isTracePopup) {
  418. let annotationBubbleView = (mapView.dequeueReusableAnnotationView(withIdentifier: MapAmapPopUpWindowView.identifier) as? MapAmapPopUpWindowView) ?? MapAmapPopUpWindowView(annotation: (myitemAnnotation as MAAnnotation), reuseIdentifier: MapAmapPopUpWindowView.identifier)
  419. annotationBubbleView!.marker = myitemAnnotation.itemMarker
  420. return annotationBubbleView
  421. }
  422. let annotationView = (mapView.dequeueReusableAnnotationView(withIdentifier: MapAmapMarkerNormalView.identifier) as? MapAmapMarkerNormalView) ?? MapAmapMarkerNormalView(annotation: (myitemAnnotation as MAAnnotation), reuseIdentifier: MapAmapMarkerNormalView.identifier)
  423. annotationView!.marker = myitemAnnotation.itemMarker
  424. return annotationView
  425. }
  426. return nil
  427. }
  428. func mapView(_ mapView: MAMapView!, rendererFor overlay: MAOverlay!) -> MAOverlayRenderer! {
  429. guard let polyline = overlay as? MyMAPolyline else {
  430. return MAPolylineRenderer(polyline: overlay as? MAPolyline)
  431. }
  432. // 外层边框(粗线)
  433. // let borderRenderer = MAPolylineRenderer(polyline: polyline)
  434. // borderRenderer?.lineWidth = 8
  435. // borderRenderer?.strokeColor = UIColor(red: 0.35, green: 0.36, blue: 0.99, alpha: 1)
  436. //
  437. let renderer = MAPolylineRenderer(polyline: polyline)
  438. renderer?.lineWidth = 12
  439. renderer?.lineCapType = kMALineCapRound//kMALineCapArrow
  440. renderer?.lineJoinType = kMALineJoinRound
  441. print("lineTypesfsdfsdf---\(polyline.itemPolyLine.lineType)----\(polyline.itemPolyLine.lineId)")
  442. // 设置箭头样式
  443. // 加载箭头纹理图片
  444. //normal error selected color
  445. if polyline.itemPolyLine.lineType == "normal" {
  446. renderer?.strokeImage = readImageContentFrom(imageName: "com.shishi.dingwei_bluearrow")
  447. //renderer?.strokeColor = UIColor(red: 0.27, green: 0.46, blue: 1, alpha: 1)
  448. } else if polyline.itemPolyLine.lineType == "error" {
  449. //renderer?.strokeColor = UIColor(red: 1, green: 0.43, blue: 0.43, alpha: 1)
  450. renderer?.strokeImage = readImageContentFrom(imageName: "com.shishi.dingwei_redarrow")
  451. } else if polyline.itemPolyLine.lineType == "selected" {
  452. //renderer?.strokeColor = UIColor(red: 0.08, green: 0.8, blue: 0.63, alpha: 1)
  453. renderer?.strokeImage = readImageContentFrom(imageName: "com.shishi.dingwei_greetarrow")
  454. } else if polyline.itemPolyLine.lineType == "color" {
  455. renderer?.strokeColor = UIColor(red: 0.27, green: 0.46, blue: 1, alpha: 1)
  456. renderer?.lineWidth = polyline.itemPolyLine.width
  457. renderer?.sideColor = UIColor(red: 0.35, green: 0.36, blue: 0.99, alpha: 1)
  458. renderer?.is3DArrowLine = true
  459. renderer?.fillColor = UIColor(hex: polyline.itemPolyLine.color)//UIColor.init(hex: "#4476FF");//UIColor(red: 123 / 255, green: 125 / 255, blue: 255 / 255, alpha: 1)
  460. }
  461. return renderer
  462. }
  463. func mapView(_ mapView: MAMapView, didFailToLocateUserWithError error: Error?) {
  464. guard let error = error else { return }
  465. // 打印错误信息,便于调试
  466. print("定位失败: \(error.localizedDescription)")
  467. // 根据错误类型处理黑屏问题
  468. handleLocationError(error: error as NSError)
  469. // 即使定位失败,也显示默认地图(避免黑屏)
  470. mapView.showsUserLocation = true // 显示用户位置(即使定位失败)
  471. mapView.userTrackingMode = .follow // 设置跟踪模式
  472. }
  473. private func handleLocationError(error: NSError) {
  474. switch error.code {
  475. case CLError.denied.rawValue:
  476. // 权限被拒绝
  477. showPermissionAlert()
  478. print("权限被拒绝")
  479. case CLError.locationUnknown.rawValue:
  480. // 位置未知(临时错误)
  481. print("位置未知(临时错误)")
  482. case CLError.network.rawValue:
  483. // 网络错误
  484. print("网络错误")
  485. case CLError.headingFailure.rawValue:
  486. // 方向获取失败(不影响定位,可忽略)
  487. print("方向获取失败,但位置可能正常")
  488. default:
  489. // 其他错误
  490. print("其他错误")
  491. }
  492. }
  493. private func readImageContentFrom(imageName : String) -> UIImage {
  494. if let image = UIImage(named: imageName) {
  495. return image
  496. }
  497. // 尝试从插件资源束加载
  498. let bundleURL = Bundle(for: MapAmapMarkerNormalView.self).url(forResource: "map_amap_ios_image_source", withExtension: "bundle")
  499. if let bundleURL = bundleURL, let resourceBundle = Bundle(url: bundleURL) {
  500. return UIImage(named: imageName, in: resourceBundle, compatibleWith: nil) ?? UIImage()
  501. }
  502. return UIImage()
  503. }
  504. private func showPermissionAlert() {
  505. let alert = UIAlertController(
  506. title: "定位权限被拒绝",
  507. message: "请在设置中为高德地图开启位置权限",
  508. preferredStyle: .alert
  509. )
  510. alert.addAction(UIAlertAction(title: "取消", style: .cancel))
  511. alert.addAction(UIAlertAction(title: "去设置", style: .default) { _ in
  512. // 打开系统设置中的应用权限页面
  513. if let url = URL(string: UIApplication.openSettingsURLString) {
  514. UIApplication.shared.open(url)
  515. }
  516. })
  517. present(alert, animated: true)
  518. }
  519. private func showDefaultMap() {
  520. // 如果有历史位置,使用历史位置
  521. if let lastLocation = self.autonaviMap.userLocation.location {
  522. let region = MACoordinateRegion(
  523. center: lastLocation.coordinate,
  524. span: MACoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1)
  525. )
  526. autonaviMap.setRegion(region, animated: true)
  527. } else {
  528. // 没有历史位置,使用默认区域(如北京)
  529. let defaultLocation = CLLocationCoordinate2D(latitude: 39.9042, longitude: 116.4074)
  530. let region = MACoordinateRegion(
  531. center: defaultLocation,
  532. span: MACoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1)
  533. )
  534. autonaviMap.setRegion(region, animated: true)
  535. }
  536. // 确保地图可见元素正常显示
  537. autonaviMap.isShowsBuildings = true
  538. autonaviMap.isShowTraffic = false // 根据需要显示交通
  539. }
  540. }
  541. /*
  542. @available(iOS 13.0, *)
  543. extension MapAmapThemeControl: MKMapViewDelegate {
  544. func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
  545. guard let marker = annotation as? ATMapMarker else {
  546. return nil
  547. }
  548. print("markerTypesfdsdfs---\(marker.markerType.markType)");
  549. if marker.markerType.isMapAchorPoint {
  550. let annotationView = (mapView.dequeueReusableAnnotationView(withIdentifier: MapAnnotationAnchorPointView.identifier) as? MapAnnotationAnchorPointView) ?? MapAnnotationAnchorPointView(annotation: marker, reuseIdentifier: MapAnnotationAnchorPointView.identifier)
  551. annotationView.marker = marker
  552. annotationView.prepareForDisplay()
  553. return annotationView
  554. } else if (marker.markerType.isTracePopup) {
  555. let annotationBubbleView = (mapView.dequeueReusableAnnotationView(withIdentifier: MapAmapPopUpWindowView.identifier) as? MapAmapPopUpWindowView) ?? MapAmapPopUpWindowView(annotation: marker, reuseIdentifier: MapAmapPopUpWindowView.identifier)
  556. annotationBubbleView.marker = marker
  557. annotationBubbleView.prepareForDisplay()
  558. return annotationBubbleView
  559. }
  560. let annotationView = (mapView.dequeueReusableAnnotationView(withIdentifier: MapAmapMarkerNormalView.identifier) as? MapAmapMarkerNormalView) ?? MapAmapMarkerNormalView(annotation: marker, reuseIdentifier: MapAmapMarkerNormalView.identifier)
  561. annotationView.marker = marker
  562. annotationView.prepareForDisplay()
  563. return annotationView
  564. }
  565. func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
  566. guard var marker = view.annotation as? ATMapMarker else {
  567. return
  568. }
  569. viewModel.handleMarkerTap(marker: &marker)
  570. }
  571. func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
  572. guard let polyline = overlay as? MKPolyline else {
  573. return MKOverlayRenderer(overlay: overlay)
  574. }
  575. let renderer = MapAmapArrowPolylineRenderer(polyline: polyline)
  576. renderer.lineWidth = 6
  577. //rgba(123, 125, 255, 1)
  578. renderer.strokeColor = UIColor(red: 0.27, green: 0.46, blue: 1, alpha: 1)//UIColor.init(hex: "#4476FF");//UIColor(red: 123 / 255, green: 125 / 255, blue: 255 / 255, alpha: 1)
  579. renderer.lineCap = .round
  580. renderer.lineJoin = .round
  581. // 设置箭头样式
  582. renderer.arrowColor = UIColor.white // 箭头颜色
  583. renderer.arrowSize = 12 // 增大箭头大小
  584. renderer.arrowSpacing = 50 // 减小箭头间距
  585. renderer.borderWidth = 1
  586. renderer.borderColor = UIColor(red: 0.35, green: 0.36, blue: 0.99, alpha: 1)
  587. //normal error selected color
  588. if polyline.associatedLineType == "normal" {
  589. renderer.strokeColor = UIColor(red: 0.27, green: 0.46, blue: 1, alpha: 1)
  590. } else if polyline.associatedLineType == "error" {
  591. renderer.strokeColor = UIColor(red: 1, green: 0.43, blue: 0.43, alpha: 1)
  592. } else if polyline.associatedLineType == "selected" {
  593. renderer.strokeColor = UIColor(red: 0.08, green: 0.8, blue: 0.63, alpha: 1)
  594. } else if polyline.associatedLineType == "color" {
  595. renderer.strokeColor = UIColor(hex: polyline.associatedColor ?? "#4476FF")
  596. renderer.lineWidth = polyline.associatedWidth ?? 0
  597. }
  598. return renderer
  599. }
  600. }*/