// // SportTrackView.swift // Lookfit // // Created by Sheldon on 2022/1/3. // Copyright © 2021 Sheldon. All rights reserved. // import Foundation import MapKit // MARK:- 常量 fileprivate struct Metric { static let startAnnotation = "sport_icon_start" static let endAnnotation = "sport_icon_end" static let animationDuration: TimeInterval = 3.0 static let lineWidth: CGFloat = 4.0 static let Transparent = "Transparent"//透明的覆盖 static let opaque = "opaque"//不透明的覆盖 } class SportTrackView: UIView { private var mapView = MKMapView() private var mapType: MKMapType = .standard private var tempCoordinateRegion: MKCoordinateRegion? lazy var scaleAdd: UIButton = { let view = UIButton() view.setImage(R.image.sport_icon_add(), for: .normal) return view }() lazy var scaleReduce: UIButton = { let view = UIButton() view.setImage(R.image.sport_icon_reduce(), for: .normal) return view }() var coordinateArr: [CLLocationCoordinate2D] = [] var polyline: MKPolyline? override init(frame: CGRect) { super.init(frame: frame) mapView.delegate = self addSubview(mapView) mapView.snp.makeConstraints { (make) in make.top.left.right.equalToSuperview() make.bottom.equalToSuperview() } addSubview(scaleAdd) addSubview(scaleReduce) scaleAdd.snp.makeConstraints { make in make.right.equalTo(mapView.snp.right).offset(-10) make.bottom.equalTo(mapView.snp.bottom).offset(-15 - 40) make.height.width.equalTo(40) } scaleReduce.snp.makeConstraints { make in make.right.equalTo(mapView.snp.right).offset(-10) make.bottom.equalTo(mapView.snp.bottom).offset(-15) make.height.width.equalTo(40) } scaleAdd.rx.tap .subscribe(onNext: { [weak self] in guard let `self` = self else { return } var region = self.mapView.region region.span.latitudeDelta = region.span.latitudeDelta * 0.5 region.span.longitudeDelta = region.span.longitudeDelta * 0.5 self.mapView.setRegion(region, animated: true) }) .disposed(by: rx.disposeBag) scaleReduce.rx.tap .subscribe(onNext: { [weak self] in guard let `self` = self else { return } var region = self.mapView.region region.span.latitudeDelta = region.span.latitudeDelta * 2 region.span.longitudeDelta = region.span.longitudeDelta * 2 self.mapView.setRegion(region, animated: true) }) .disposed(by: rx.disposeBag) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } /// 轨迹绘制 /// - Parameter coordinates: 经纬度数组 func drawTrajectory(coordinates: [CLLocationCoordinate2D]) { coordinateArr = coordinates // 轨迹线 let polyline = MKPolyline(coordinates: coordinates, count: coordinates.count) self.polyline = polyline mapView.addOverlay(polyline) // 起始点 addAnnotation(coordinateArr.first!, Metric.startAnnotation) addAnnotation(coordinateArr.last!, Metric.endAnnotation) // 轨迹线范围 let macRect = polyline.boundingMapRect let region = MKMapRect(x: macRect.origin.x, y: macRect.origin.y, width: macRect.width, height: macRect.height) tempCoordinateRegion = MKCoordinateRegion(region) tempCoordinateRegion!.span.latitudeDelta = tempCoordinateRegion!.span.latitudeDelta * 1.15 tempCoordinateRegion!.span.longitudeDelta = tempCoordinateRegion!.span.longitudeDelta * 1.15 mapView.setRegion(tempCoordinateRegion!, animated: true) } /// 回到中心 func position() { if let tempCoordinateRegion = tempCoordinateRegion { mapView.setRegion(tempCoordinateRegion, animated: false) } } } extension SportTrackView: MKMapViewDelegate { // 起始点 func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { let annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: "") let imageName = annotation.title!! annotationView.image = UIImage(named: imageName) return annotationView } // 轨迹 && 蒙版 func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer { // 轨迹 let polyline = overlay as! MKPolyline let polylineRenderer = MKPolylineRenderer(polyline: polyline) polylineRenderer.lineWidth = 4.0 polylineRenderer.strokeColor = kRGBA(67, 158, 238, 1) polylineRenderer.lineCap = .round polylineRenderer.lineJoin = .round return polylineRenderer as MKOverlayRenderer } private func addAnnotation(_ coordinate: CLLocationCoordinate2D, _ title: String?) { let annotation = MKPointAnnotation().then { $0.title = title ?? "" $0.coordinate = coordinate } mapView.addAnnotation(annotation) } }