Search code examples
iosobjective-cmkmapviewmkdirection

Multiple Routes Between two Locations in Mkmapview


  • How to get one or more possible routes between two points? If anybody has worked on this can you please tell me?

Want like this


Solution

  • Using MapKit

    You need to make your [directionRequest setRequestsAlternateRoutes:YES]then in response.routes you will get the available routes

    As is defined in MKDirectionsRequest declaration

    open var requestsAlternateRoutes: Bool // if YES and there is more than one reasonable way to route from source to destination, allow the route server to return multiple routes. Default is NO.

    Full code

    Objective-C

     - (void)createRouteFrom:(CLLocationCoordinate2D)from to:(CLLocationCoordinate2D)destination{
        if(CLLocationCoordinate2DIsValid(from) && CLLocationCoordinate2DIsValid(destination))
        {
            MKDirectionsRequest * directionRequest = [[MKDirectionsRequest alloc]init];
            [directionRequest setSource:[[MKMapItem alloc] initWithPlacemark:[[MKPlacemark alloc] initWithCoordinate:from]]];
            [directionRequest setSource:[[MKMapItem alloc] initWithPlacemark:[[MKPlacemark alloc] initWithCoordinate:destination]]];
            [directionRequest setTransportType:MKDirectionsTransportTypeAutomobile];
            [directionRequest setRequestsAlternateRoutes:YES];
            
            MKDirections * directions = [[MKDirections alloc] initWithRequest:directionRequest];
            
            [directions calculateDirectionsWithCompletionHandler:^(MKDirectionsResponse * _Nullable response, NSError * _Nullable error) {
                if(error == nil)
                {
                    for (MKRoute * rute in response.routes) {
                        //DO WHAT YOU NEED WITH ROUTE
                    }
                    
                    //here I add the first route
                    MKRoute * firstOne = response.routes.firstObject;
                    [self.map addOverlay:firstOne.polyline level:MKOverlayLevelAboveRoads];
                    
                    MKMapRect rect = [firstOne.polyline boundingMapRect];
                    [self.map setRegion:MKCoordinateRegionForMapRect(rect) animated:YES];
                }
            }];
        }
    }
    

    Swift

    func createRouteTo(from: CLLocationCoordinate2D,to: CLLocationCoordinate2D) {
            
            if(CLLocationCoordinate2DIsValid(from) && CLLocationCoordinate2DIsValid(to))
            {
                self.showLoading(message: "Creando Ruta...")
                let directionRequest = MKDirectionsRequest()
                directionRequest.source = MKMapItem(placemark: MKPlacemark(coordinate: from, addressDictionary: nil))
                directionRequest.destination = MKMapItem(placemark: MKPlacemark(coordinate: to, addressDictionary: nil))
                directionRequest.transportType = .automobile
                //THIS MAKE the request for multiple routes if possible
                directionRequest.requestsAlternateRoutes = true
                
                // Calculate the direction
                let directions = MKDirections(request: directionRequest)
                
                directions.calculate { [unowned self] (directionResponse, error) in
                    self.hideLoading(withDelay: 0.1)
                    guard let response = directionResponse else {
                        if let error = error {
                            print("Error: \(error)")
                            let alert = UIAlertController.init(title:"Error Creando Ruta",
                                                               message:error.localizedDescription, preferredStyle: .alert)
                            alert.addAction(UIAlertAction.init(title: "Aceptar", style: .destructive, handler:nil))
                            self.present(alert, animated:true , completion:nil)
                        }
                        
                        return
                    }
                    
                    if(self.currentRouteOverlay != nil)
                    {
                        self.mapView.remove(self.currentRouteOverlay!)
                    }
                    
                    
                    //in response.routes you will get the routes avaiables
                    for route in response.routes
                    {
                        //Do what you need with the routes
                        
                    } 
    
                    //here I add the first to the MapView
                    let route = response.routes[0]
                    self.currentRouteOverlay = route.polyline
                    self.mapView.add(route.polyline, level: .aboveRoads)
                    
                    let rect = route.polyline.boundingMapRect
                    self.mapView.setRegion(MKCoordinateRegionForMapRect(rect), animated: true)
                }
            }
            
        }
    

    Hope this helps