I'm trying to create a map that will show the route of a workout, but I can't find anywhere in MapKit documentation as to how to customize the background, i.e. here I want the map itself to be transparent so that only the route (annotations) are visible. How can I do this?
struct MapOverlay: View {
@ObservedObject var workoutDetailViewModel: WorkoutDetailViewModel
var body: some View {
if let unwrappedWorkoutLocations = workoutDetailViewModel.fullyLoadedWorkout?.workoutLocations {
Map(
coordinateRegion: .constant(
MKCoordinateRegion(
center: unwrappedWorkoutLocations.map {$0.coordinate}.center(), // Use the midpoint of the workout as the centre of the map.
span: MKCoordinateSpan(latitudeDelta: 0.02, longitudeDelta: 0.02)
)
),
annotationItems: unwrappedWorkoutLocations.map {$0.coordinate}
) { routeLocation in
MapAnnotation(coordinate: routeLocation) {
Circle().fill(TrackerConstants.AppleFitnessOrange)
}
}
.cornerRadius(10)
}
}
}
struct MapOverlay_Previews: PreviewProvider {
static var previews: some View {
MapOverlay(workoutDetailViewModel: WorkoutDetailViewModel())
}
}
CodePudding user response:
Don't use MKMapView. You want to take the coordinates and make a UIBezierPath from them, and render that into your own view, or a UIImage. Something like this playground:
import CoreLocation
import MapKit
let myCoords: [CLLocationCoordinate2D] = [
.init(latitude: 42.42, longitude: 42.42),
.init(latitude: 42.43, longitude: 42.425),
.init(latitude: 42.425, longitude: 42.427),
.init(latitude: 42.422, longitude: 42.426),
]
let r = MKPolylineRenderer(polyline: .init(coordinates: myCoords, count: myCoords.count))
let path = r.path!
let bezier = UIBezierPath(cgPath: path)
bezier.apply(.init(scaleX: 0.05, y: 0.05))
let renderer = UIGraphicsImageRenderer(bounds: .init(x: 0, y: 0, width: 640, height: 480))
let image = renderer
.image { context in
let size = renderer.format.bounds.size
UIColor.darkGray.setFill()
context.fill(CGRect(x: 0, y: 0, width: size.width, height: size.height))
UIColor.black.setStroke()
bezier.lineWidth = 5
bezier.stroke()
}