| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- //
- // MapViewController.swift
- // Runner
- //
- // Created by Groot on 2025/5/7.
- //
- import UIKit
- import MapKit
- import Combine
- class MapViewController: UIViewController {
-
- required init?(coder: NSCoder) {
- fatalError("init(coder:) has not been implemented")
- }
-
- let viewModel: MapViewModel
- let mapView = MKMapView()
- private var cancellables = Set<AnyCancellable>()
-
- init(viewModel: MapViewModel) {
- self.viewModel = viewModel
- super.init(nibName: nil, bundle: nil)
- mapView.showsUserLocation = false
- }
- override func viewDidLoad() {
- super.viewDidLoad()
- setupView()
- setupMap()
- bindViewModel()
- }
- private func setupView() {
- mapView.translatesAutoresizingMaskIntoConstraints = false
- view.addSubview(mapView)
- NSLayoutConstraint.activate([
- mapView.topAnchor.constraint(equalTo: view.topAnchor),
- mapView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
- mapView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
- mapView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
- ])
- }
- private func setupMap() {
- mapView.delegate = self
- mapView.showsUserLocation = false
- mapView.mapType = .mutedStandard
- }
-
- private func bindViewModel() {
- viewModel.$currentRegion
- .compactMap { $0 }
- .receive(on: DispatchQueue.main)
- .sink { [weak self] region in
- self?.mapView.setRegion(region, animated: true)
- }
- .store(in: &cancellables)
- viewModel.$markers
- .receive(on: DispatchQueue.main)
- .sink { [weak self] markers in
- self?.mapView.removeAnnotations(self?.mapView.annotations ?? [])
- UIView.animate(withDuration: 0.3) {
- self?.mapView.addAnnotations(markers)
- }
- }
- .store(in: &cancellables)
- viewModel.$polylines
- .receive(on: DispatchQueue.main)
- .sink { [weak self] polylines in
- self?.mapView.removeOverlays(self?.mapView.overlays ?? [])
- var polyinesList = [MKPolyline]();
- for polyline in polylines {
- let polylineItem : MKPolyline = polyline.polyline
- polylineItem.associatedLineId = polyline.id
- polylineItem.associatedLineType = polyline.lineType
- polylineItem.associatedColor = polyline.color
- polylineItem.associatedWidth = polyline.width
- polyinesList.append(polylineItem)
- }
- self?.mapView.addOverlays(polyinesList)
- //self?.mapView.addOverlays(polylines.map({ $0.polyline }))
- if let padding = polylines.last?.mapPadding {
- self?.mapView.fitsAllPoints(
- points: polylines.last?.points.compactMap({ MKMapPoint($0) }) ?? [],
- padding: padding.padding,
- animated: true
- )
- }
- }
- .store(in: &cancellables)
-
- //移动至多个点的位置,并提供设置padding距离
- viewModel.$suitableLocation
- .receive(on: DispatchQueue.main)
- .sink{ [weak self] polylines in
- if let padding = polylines.last?.mapPadding {
- if let atMapPoint : [CLLocationCoordinate2D] = polylines.last?.points {
- self?.mapView.moveToSuitableLocation(points: atMapPoint, padding: padding)
- }
- }
- }
- .store(in: &cancellables)
- }
- }
- extension MapViewController: MKMapViewDelegate {
- func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
- guard let marker = annotation as? ATMapMarker else {
- return nil
- }
- print("markerTypesfdsdfs---\(marker.markerType.markType)");
- if marker.markerType.isMapAchorPoint {
- let annotationView = (mapView.dequeueReusableAnnotationView(withIdentifier: MapAnnotationAnchorPointView.identifier) as? MapAnnotationAnchorPointView) ?? MapAnnotationAnchorPointView(annotation: marker, reuseIdentifier: MapAnnotationAnchorPointView.identifier)
- annotationView.marker = marker
- annotationView.prepareForDisplay()
- return annotationView
- } else if (marker.markerType.isTracePopup) {
- let annotationBubbleView = (mapView.dequeueReusableAnnotationView(withIdentifier: MapAnotationBubbleView.identifier) as? MapAnotationBubbleView) ?? MapAnotationBubbleView(annotation: marker, reuseIdentifier: MapAnotationBubbleView.identifier)
- annotationBubbleView.marker = marker
- annotationBubbleView.prepareForDisplay()
- return annotationBubbleView
- }
- let annotationView = (mapView.dequeueReusableAnnotationView(withIdentifier: MapAnnotationView.identifier) as? MapAnnotationView) ?? MapAnnotationView(annotation: marker, reuseIdentifier: MapAnnotationView.identifier)
- annotationView.marker = marker
- annotationView.prepareForDisplay()
- return annotationView
- }
- func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
- guard var marker = view.annotation as? ATMapMarker else {
- return
- }
-
- viewModel.handleMarkerTap(marker: &marker)
- }
- func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
-
- guard let polyline = overlay as? MKPolyline else {
- return MKOverlayRenderer(overlay: overlay)
- }
- let renderer = ArrowPolylineRenderer(polyline: polyline)
- renderer.lineWidth = 6
- //rgba(123, 125, 255, 1)
- 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)
- renderer.lineCap = .round
- renderer.lineJoin = .round
-
- // 设置箭头样式
- renderer.arrowColor = UIColor.white // 箭头颜色
- renderer.arrowSize = 12 // 增大箭头大小
- renderer.arrowSpacing = 50 // 减小箭头间距
- renderer.borderWidth = 1
- renderer.borderColor = UIColor(red: 0.35, green: 0.36, blue: 0.99, alpha: 1)
-
- //normal error selected color
- if polyline.associatedLineType == "normal" {
- renderer.strokeColor = UIColor(red: 0.27, green: 0.46, blue: 1, alpha: 1)
- } else if polyline.associatedLineType == "error" {
- renderer.strokeColor = UIColor(red: 1, green: 0.43, blue: 0.43, alpha: 1)
- } else if polyline.associatedLineType == "selected" {
- renderer.strokeColor = UIColor(red: 0.08, green: 0.8, blue: 0.63, alpha: 1)
- } else if polyline.associatedLineType == "color" {
- renderer.strokeColor = UIColor(hex: polyline.associatedColor ?? "#4476FF")
- renderer.lineWidth = polyline.associatedWidth ?? 0
- }
- return renderer
- }
- }
|