MapViewController.swift 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. //
  2. // MapViewController.swift
  3. // Runner
  4. //
  5. // Created by Groot on 2025/5/7.
  6. //
  7. import UIKit
  8. import MapKit
  9. import Combine
  10. class MapViewController: UIViewController {
  11. required init?(coder: NSCoder) {
  12. fatalError("init(coder:) has not been implemented")
  13. }
  14. let viewModel: MapViewModel
  15. let mapView = MKMapView()
  16. private var cancellables = Set<AnyCancellable>()
  17. init(viewModel: MapViewModel) {
  18. self.viewModel = viewModel
  19. super.init(nibName: nil, bundle: nil)
  20. mapView.showsUserLocation = false
  21. }
  22. override func viewDidLoad() {
  23. super.viewDidLoad()
  24. setupView()
  25. setupMap()
  26. bindViewModel()
  27. }
  28. private func setupView() {
  29. mapView.translatesAutoresizingMaskIntoConstraints = false
  30. view.addSubview(mapView)
  31. NSLayoutConstraint.activate([
  32. mapView.topAnchor.constraint(equalTo: view.topAnchor),
  33. mapView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
  34. mapView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
  35. mapView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
  36. ])
  37. }
  38. private func setupMap() {
  39. mapView.delegate = self
  40. mapView.showsUserLocation = false
  41. mapView.mapType = .mutedStandard
  42. }
  43. private func bindViewModel() {
  44. viewModel.$currentRegion
  45. .compactMap { $0 }
  46. .receive(on: DispatchQueue.main)
  47. .sink { [weak self] region in
  48. self?.mapView.setRegion(region, animated: true)
  49. }
  50. .store(in: &cancellables)
  51. viewModel.$markers
  52. .receive(on: DispatchQueue.main)
  53. .sink { [weak self] markers in
  54. self?.mapView.removeAnnotations(self?.mapView.annotations ?? [])
  55. UIView.animate(withDuration: 0.3) {
  56. self?.mapView.addAnnotations(markers)
  57. }
  58. }
  59. .store(in: &cancellables)
  60. viewModel.$polylines
  61. .receive(on: DispatchQueue.main)
  62. .sink { [weak self] polylines in
  63. self?.mapView.removeOverlays(self?.mapView.overlays ?? [])
  64. var polyinesList = [MKPolyline]();
  65. for polyline in polylines {
  66. let polylineItem : MKPolyline = polyline.polyline
  67. polylineItem.associatedLineId = polyline.id
  68. polylineItem.associatedLineType = polyline.lineType
  69. polylineItem.associatedColor = polyline.color
  70. polylineItem.associatedWidth = polyline.width
  71. polyinesList.append(polylineItem)
  72. }
  73. self?.mapView.addOverlays(polyinesList)
  74. //self?.mapView.addOverlays(polylines.map({ $0.polyline }))
  75. if let padding = polylines.last?.mapPadding {
  76. self?.mapView.fitsAllPoints(
  77. points: polylines.last?.points.compactMap({ MKMapPoint($0) }) ?? [],
  78. padding: padding.padding,
  79. animated: true
  80. )
  81. }
  82. }
  83. .store(in: &cancellables)
  84. //移动至多个点的位置,并提供设置padding距离
  85. viewModel.$suitableLocation
  86. .receive(on: DispatchQueue.main)
  87. .sink{ [weak self] polylines in
  88. if let padding = polylines.last?.mapPadding {
  89. if let atMapPoint : [CLLocationCoordinate2D] = polylines.last?.points {
  90. self?.mapView.moveToSuitableLocation(points: atMapPoint, padding: padding)
  91. }
  92. }
  93. }
  94. .store(in: &cancellables)
  95. }
  96. }
  97. extension MapViewController: MKMapViewDelegate {
  98. func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
  99. guard let marker = annotation as? ATMapMarker else {
  100. return nil
  101. }
  102. print("markerTypesfdsdfs---\(marker.markerType.markType)");
  103. if marker.markerType.isMapAchorPoint {
  104. let annotationView = (mapView.dequeueReusableAnnotationView(withIdentifier: MapAnnotationAnchorPointView.identifier) as? MapAnnotationAnchorPointView) ?? MapAnnotationAnchorPointView(annotation: marker, reuseIdentifier: MapAnnotationAnchorPointView.identifier)
  105. annotationView.marker = marker
  106. annotationView.prepareForDisplay()
  107. return annotationView
  108. } else if (marker.markerType.isTracePopup) {
  109. let annotationBubbleView = (mapView.dequeueReusableAnnotationView(withIdentifier: MapAnotationBubbleView.identifier) as? MapAnotationBubbleView) ?? MapAnotationBubbleView(annotation: marker, reuseIdentifier: MapAnotationBubbleView.identifier)
  110. annotationBubbleView.marker = marker
  111. annotationBubbleView.prepareForDisplay()
  112. return annotationBubbleView
  113. }
  114. let annotationView = (mapView.dequeueReusableAnnotationView(withIdentifier: MapAnnotationView.identifier) as? MapAnnotationView) ?? MapAnnotationView(annotation: marker, reuseIdentifier: MapAnnotationView.identifier)
  115. annotationView.marker = marker
  116. annotationView.prepareForDisplay()
  117. return annotationView
  118. }
  119. func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
  120. guard var marker = view.annotation as? ATMapMarker else {
  121. return
  122. }
  123. viewModel.handleMarkerTap(marker: &marker)
  124. }
  125. func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
  126. guard let polyline = overlay as? MKPolyline else {
  127. return MKOverlayRenderer(overlay: overlay)
  128. }
  129. let renderer = ArrowPolylineRenderer(polyline: polyline)
  130. renderer.lineWidth = 6
  131. //rgba(123, 125, 255, 1)
  132. 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)
  133. renderer.lineCap = .round
  134. renderer.lineJoin = .round
  135. // 设置箭头样式
  136. renderer.arrowColor = UIColor.white // 箭头颜色
  137. renderer.arrowSize = 12 // 增大箭头大小
  138. renderer.arrowSpacing = 50 // 减小箭头间距
  139. renderer.borderWidth = 1
  140. renderer.borderColor = UIColor(red: 0.35, green: 0.36, blue: 0.99, alpha: 1)
  141. //normal error selected color
  142. if polyline.associatedLineType == "normal" {
  143. renderer.strokeColor = UIColor(red: 0.27, green: 0.46, blue: 1, alpha: 1)
  144. } else if polyline.associatedLineType == "error" {
  145. renderer.strokeColor = UIColor(red: 1, green: 0.43, blue: 0.43, alpha: 1)
  146. } else if polyline.associatedLineType == "selected" {
  147. renderer.strokeColor = UIColor(red: 0.08, green: 0.8, blue: 0.63, alpha: 1)
  148. } else if polyline.associatedLineType == "color" {
  149. renderer.strokeColor = UIColor(hex: polyline.associatedColor ?? "#4476FF")
  150. renderer.lineWidth = polyline.associatedWidth ?? 0
  151. }
  152. return renderer
  153. }
  154. }