Reputation: 391
So I am creating an app to track a user's running routes. I am to show a polyline that represents where a user has ran, between a start annotation that is dropped when user begins and a end annotation that is dropped when user clicks a finish button. Seeing as how someone can run pretty much anywhere, is there a way to draw a polyline that is Not limited to just main roads and streets? For example if someone runs somewhere that does not have main roads/streets, how would I show the polyline going through that area on the map? (See Image) Or is that not even possible in swift?
In addition, is it possible to fix these gaps?
Here is my code for rendering the polyline:
func drawPolyline() {
guard let startingCoordinate = self.startingCoordinate, let endingCoordinate = self.endingCoordinate else { return }
let request = MKDirections.Request()
request.source = MKMapItem(placemark: MKPlacemark(coordinate: startingCoordinate))
request.destination = MKMapItem(placemark: MKPlacemark(coordinate: endingCoordinate))
request.transportType = .walking
let directions = MKDirections(request: request)
directions.calculate { [weak self] (response, error) in
guard let self = self else { return }
guard error == nil else { return }
guard response != nil else { return }
if let route = response?.routes.first {
self.mapView.addOverlay(route.polyline)
self.mapView.setVisibleMapRect(route.polyline.boundingMapRect, edgePadding: UIEdgeInsets(top: 15, left: 15, bottom: 15, right: 15), animated: true)
}
}
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
let renderer = MKPolylineRenderer(overlay: overlay
renderer.strokeColor = .systemBlue
renderer.lineWidth = 3
return renderer
}
// code to get coordinate for annotations
guard let coordinate = locationManager.location?.coordinate else { return }
let annotation = MapAnnotation(title: title, coordinate: coordinate)
mapView.addAnnotation(annotation)
Upvotes: 0
Views: 584
Reputation: 5554
You will get an updated location every time it changes, and you can either build up an array of locations, or store them in a database for later retrieval.
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
{
// the last location presented here is the current position of the runner
self.locations.append(locations.last)
// store this in a database, or as a class variable
}
You can set the desired accuracy when you initialise your location manager
locationManager.desiredAccuracy = kCLLocationAccuracyBest
and then when you're creating the map, create a line showing the runner's route
let polyline = MKPolyline(coordinates: self.locations, count: self.locations.count)
self.mapView.addOverlay(polyline)
Here's an example of the output - looks like the finish is in the middle of the run, but that's because I was heading back home
Upvotes: 1