MapKit et itinéraire

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

}

}

Hello,

Pour Apple Maps, tu peux regarder ce code que j’utilise dans une de mes applications
let placemark = MKPlacemark(coordinate: self.location!, addressDictionary: nil)
let mapItem = MKMapItem(placemark: placemark)
mapItem.name = name (ça c’est si tu veux nommer le pin qui viendra se placer sur la carte)
mapItem.openInMaps(launchOptions: [MKLaunchOptionsDirectionsModeKey : MKLaunchOptionsDirectionsModeWalking])

Et pour Google Maps :
UIApplication.shared.open(URL(string: "comgooglemaps://?saddr=&daddr=\(latitude),\(longitude)&directionsmode=walking")!, options: convertToUIApplicationOpenExternalURLOptionsKeyDictionary([:]), completionHandler: nil )

J’utilise le temps et trajet de marche donc à toi d’adapter en conséquence :wink: