Bonjour les codeurs.
J’ai réussi à implémenter MapKit dans mon projet.Je réussis à localiser l’utilisateur sans problème.Par contre,je voudrais trouver une solution pour produire des itinéraires vers une destination fixe.
Quelqu’un aurait une idée?
import UIKit
import MapKit
import CoreLocation
class MapScreenViewController: UIViewController {
@IBOutlet weak var mapView: MKMapView!
@IBOutlet weak var addressLabel: UILabel!
@IBOutlet weak var goButton: UIButton!
let locationManager = CLLocationManager()
let regionInMeters: Double = 50000
var previousLocation: CLLocation?
let geoCoder = CLGeocoder()
var directionsArray: [MKDirections] = []
override func viewDidLoad() {
super.viewDidLoad()
goButton.layer.cornerRadius = goButton.frame.size.height/2
checkLocationServices()
}
func setupLocationManager() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
}
func centerViewOnUserLocation() {
if let location = locationManager.location?.coordinate {
let region = MKCoordinateRegion.init(center: location, latitudinalMeters: regionInMeters, longitudinalMeters: regionInMeters)
mapView.setRegion(region, animated: true)
}
}
func checkLocationServices() {
if CLLocationManager.locationServicesEnabled() {
setupLocationManager()
checkLocationAuthorization()
} else {
}
}
func checkLocationAuthorization() {
switch CLLocationManager.authorizationStatus() {
case .authorizedWhenInUse:
startTackingUserLocation()
case .denied:
break
case .notDetermined:
locationManager.requestWhenInUseAuthorization()
case .restricted:
break
case .authorizedAlways:
break
@unknown default:
break
}
}
func startTackingUserLocation() {
mapView.showsUserLocation = true
centerViewOnUserLocation()
locationManager.startUpdatingLocation()
previousLocation = getCenterLocation(for: mapView)
}
func getCenterLocation(for mapView: MKMapView) → CLLocation {
let latitude = mapView.centerCoordinate.latitude
let longitude = mapView.centerCoordinate.longitude
return CLLocation(latitude: latitude, longitude: longitude)
}
func getDirections() {
guard let location = locationManager.location?.coordinate else {
//TODO: Inform user we don’t have their current location
return
}
let request = createDirectionsRequest(from: location)
let directions = MKDirections(request: request)
resetMapView(withNew: directions)
directions.calculate { [unowned self] (response, error) in
//TODO: Handle error if needed
guard let response = response else { return } //TODO: Show response not available in an alert
for route in response.routes {
self.mapView.addOverlay(route.polyline)
self.mapView.setVisibleMapRect(route.polyline.boundingMapRect, animated: true)
}
}
}
func createDirectionsRequest(from coordinate: CLLocationCoordinate2D) → MKDirections.Request {
let destinationCoordinate = getCenterLocation(for: mapView).coordinate
let startingLocation = MKPlacemark(coordinate: coordinate)
let destination = MKPlacemark(coordinate: destinationCoordinate)
let request = MKDirections.Request()
request.source = MKMapItem(placemark: startingLocation)
request.destination = MKMapItem(placemark: destination)
request.transportType = .any
request.requestsAlternateRoutes = true
return request
}
func resetMapView(withNew directions: MKDirections) {
mapView.removeOverlays(mapView.overlays)
directionsArray.append(directions)
let _ = directionsArray.map { $0.cancel() }
}
@IBAction func goButtonTapped(_ sender: UIButton) { getDirections()
}
}
extension MapScreenViewController: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
checkLocationAuthorization()
}
}
extension MapScreenViewController: MKMapViewDelegate {
func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
let center = getCenterLocation(for: mapView)
guard let previousLocation = self.previousLocation else { return }
guard center.distance(from: previousLocation) > 50 else { return }
self.previousLocation = center
geoCoder.cancelGeocode()
geoCoder.reverseGeocodeLocation(center) { [weak self] (placemarks, error) in
guard let self = self else { return }
if let _ = error {
return
}
guard let placemark = placemarks?.first else {
return
}
let streetNumber = placemark.subThoroughfare ?? « »
let streetName = placemark.thoroughfare ?? « »
DispatchQueue.main.async {
self.addressLabel.text = « (streetNumber) (streetName) »
}
}
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) → MKOverlayRenderer {
let renderer = MKPolylineRenderer(overlay: overlay as! MKPolyline)
renderer.strokeColor = .blue
return renderer
}
}