-
Notifications
You must be signed in to change notification settings - Fork 0
/
MainVC.swift
133 lines (109 loc) · 5.07 KB
/
MainVC.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
//
// MainVC.swift
//
//
// Created by Andre Albach on 13.02.22.
//
import MapKit
import UIKit
final class MainVC: UIViewController {
private var mapView: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
initMapView()
addButtonToCreateLayer()
addOverlayToMap()
}
private func initMapView() {
mapView = MKMapView()
view.addSubview(mapView)
mapView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
mapView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
mapView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
mapView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
mapView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
])
mapView.delegate = self
mapView.showsScale = false
mapView.showsCompass = false
mapView.showsTraffic = false
mapView.showsBuildings = false
mapView.mapType = .mutedStandard
mapView.pointOfInterestFilter = .excludingAll
}
private func addButtonToCreateLayer() {
let showStatsButton = UIButton()
showStatsButton.layer.cornerRadius = 8
showStatsButton.backgroundColor = .darkGray
let image = UIImage(systemName: "wrench", withConfiguration: UIImage.SymbolConfiguration(pointSize: 30, weight: .regular, scale: .medium))?.withTintColor(.white, renderingMode: .alwaysOriginal)
showStatsButton.setImage(image, for: .normal)
showStatsButton.addAction(UIAction(title: "", handler: { [weak self] _ in
self?.addViewWithRouteShape()
}), for: .touchUpInside)
view.addSubview(showStatsButton)
showStatsButton.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
showStatsButton.centerYAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerYAnchor, constant: 8),
showStatsButton.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -8),
showStatsButton.widthAnchor.constraint(equalToConstant: 40),
showStatsButton.heightAnchor.constraint(equalToConstant: 40)
])
}
private func addOverlayToMap() {
let coordinates = [
CLLocationCoordinate2D(latitude: 50.1234, longitude: 8.1234),
CLLocationCoordinate2D(latitude: 50.1234, longitude: 8.3456),
CLLocationCoordinate2D(latitude: 50.0000, longitude: 8.3456),
CLLocationCoordinate2D(latitude: 50.0000, longitude: 8.1234),
CLLocationCoordinate2D(latitude: 50.1234, longitude: 8.1234),
]
let polyline = MKPolyline(coordinates: coordinates, count: coordinates.count)
mapView.addOverlay(polyline)
}
private func addViewWithRouteShape() {
guard let workoutShape = createPolylinesLayer() else { return }
let layerView = UIView(frame: CGRect(x: 50, y: 50, width: workoutShape.frame.width, height: workoutShape.frame.height))
layerView.backgroundColor = .cyan.withAlphaComponent(0.5)
view.addSubview(layerView)
layerView.layer.addSublayer(workoutShape)
}
private func createPolylinesLayer() -> CAShapeLayer? {
/// Get all the visible route polylines and make sure there are actually some
guard let visiblePolyLines = mapView.visibleOverlays as? [MKPolyline],
!visiblePolyLines.isEmpty
else { return nil }
/// Transform the route polylines to their paths
let paths = visiblePolyLines.compactMap {
$0.calculatePath(using: mapView.region, and: mapView.bounds)
}
/// Append all single route paths to one path, which describes all the wourkouts
let workoutsPath = UIBezierPath()
for path in paths {
workoutsPath.append(path)
}
/// Create the shape layer which actually holds the route paths
let workoutShape = CAShapeLayer()
workoutShape.path = workoutsPath.cgPath
workoutShape.lineWidth = 2.0
workoutShape.fillColor = UIColor.clear.cgColor
workoutShape.strokeColor = UIColor.orange.cgColor
/// adapt the position
workoutShape.frame = CGRect(x: -workoutsPath.bounds.minX,
y: -workoutsPath.bounds.minY,
width: workoutsPath.bounds.width,
height: workoutsPath.bounds.height)
return workoutShape
}
}
extension MainVC: MKMapViewDelegate {
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
if let polyline = overlay as? MKPolyline {
let renderer = MKPolylineRenderer(polyline: polyline)
renderer.strokeColor = .red
renderer.lineWidth = 1
return renderer
}
return MKOverlayRenderer(overlay: overlay)
}
}