1

I am trying to display a route using MGLPolylineFeature in Mapbox after having calculated it. The calculation works and my map resizes to the correct points, I just can't seem to display the Polyline because the way you get the coordinates seems to have changed. Here is my code

This calculates the route

func calculateRoute(from originCoor: CLLocationCoordinate2D, to destinationCoor: CLLocationCoordinate2D, completion: @escaping (Route?, Error?) -> Void ){
    let origin = Waypoint(coordinate: originCoor, coordinateAccuracy: -1, name: "Start")
    let destination = Waypoint(coordinate: destinationCoor, coordinateAccuracy: -1, name: "Finish")
    
    let options = NavigationRouteOptions(waypoints: [origin, destination], profileIdentifier: .automobileAvoidingTraffic)
            
    _ = Directions.shared.calculate(options, completionHandler: { (wayponts, result) in
        switch result {
        case .success(let response):
            guard let route = response.routes?.first else { return }
            self.directionsRoute = route
            self.drawRoute(route: self.directionsRoute!)
            let coordinateBounds = MGLCoordinateBounds(sw: destinationCoor, ne: originCoor)
            let insets = UIEdgeInsets(top: 50, left: 50, bottom: 50, right: 50)
            let routeCam = self.mapView.cameraThatFitsCoordinateBounds(coordinateBounds, edgePadding: insets)
            //self.mapView.setDirection( 00.00 , animated: true)
            
            self.mapView.setCamera(routeCam, animated: true)
            
        case .failure(let error): print(error)
        }
    })
}

And this should be displaying it, but as I said, it does not work because route has no coordinates

func drawRoute(route: Route) {
     
    //Schaut, ob route überhaupt koordinaten hat, um crashes zu vermeiden
    guard route.coordinateCount > 0 else {return}
    var routeCoordinates = route.coordinates!
    
    let polyline = MGLPolylineFeature(coordinates: &routeCoordinates, count: route.coordinateCount)
    
    //Create polyline
    if let source = mapView.style?.source(withIdentifier: "route-source") as? MGLShapeSource {
        source.shape = polyline
        //Else
    } else{
        let source = MGLShapeSource(identifier: "route-source", features: [polyline], options: nil)
        
        //Create Line Style to style it
        let lineStyle = MGLLineStyleLayer(identifier: "route-style", source: source)
        lineStyle.lineColor = MGLStyleConstantValue(rawValue: UIColor.blue)
        lineStyle.lineWidth = MGLStyleConstantValue(rawValue: 4.0)
        mapView.style?.addSource(source)
        mapView.style?.addLayer(lineStyle) 
    }    
}

The last bit with MGLStyleConstantValue seems to have issues also, but those ones are not as important. I should have all the correct imports and the correct pods. Still, Xcode tells me "Value of type 'Route' has no member 'coordinates'". How do I access them? Or: How do I draw a Polyline without them?

Jan L
  • 233
  • 1
  • 10

1 Answers1

3
func calculateRoute(from originCoor:CLLocationCoordinate2D, to destinationCoor:CLLocationCoordinate2D) {
    let origin = Waypoint(coordinate: originCoor, coordinateAccuracy: -1, name: "Start")
    let destination = Waypoint(coordinate: destinationCoor, coordinateAccuracy: -1, name: "End")
    
    let options = NavigationRouteOptions(waypoints: [origin, destination], profileIdentifier: .automobileAvoidingTraffic)
    
    _ = Directions.shared.calculate(options) { [weak self] (session, result) in
        switch result {
        case .failure(let error):
            print(error.localizedDescription)
        case .success(let response):
            guard let route = response.routes?.first, let strongSelf = self else {
                return
            }
            
        if let leg = route.legs.first {
            for step in leg.steps {
                    if let coordinates = step.shape?.coordinates {
                        for (index, point) in coordinates.enumerated() {
                            let source = point
                            if index <= coordinates.count - 2 {
                                let destination = coordinates[index + 1]
                                strongSelf.getPolylineArray(source: source, destination: destination)
                            }
                        }
                    }
                    
                }
            strongSelf.drowRoute()
            }
            let coordinateBounds = MGLCoordinateBounds(sw: destinationCoor, ne: originCoor)
            let insets = UIEdgeInsets(top: 50, left: 50, bottom: 50, right: 50)
            let routeCam = strongSelf.mapView.cameraThatFitsCoordinateBounds(coordinateBounds, edgePadding: insets)
            strongSelf.mapView.setCamera(routeCam, animated: true)
        }
    }
}

private func getPolylineArray(source: CLLocationCoordinate2D, destination: CLLocationCoordinate2D){
    addCordinatsArray(lat: source.latitude, lon: source.longitude)
    addCordinatsArray(lat: destination.latitude, lon: destination.longitude)
    
}

func drowRoute() {
    let polyline = MGLPolylineFeature(coordinates: allCoordinates, count: UInt(allCoordinates.count))
    if let sourcce = mapView.style?.source(withIdentifier: "route-source") as? MGLShapeSource {
        sourcce.shape = polyline
    }else {
        let source = MGLShapeSource(identifier: "route-source", features: [polyline], options: nil)
        let lineStyle = MGLLineStyleLayer(identifier: "route-style", source: source)
        lineStyle.lineJoin = NSExpression(forConstantValue: "round")
        lineStyle.lineCap = NSExpression(forConstantValue: "round")
        lineStyle.lineColor = NSExpression(forConstantValue: UIColor.gray)
        
        // The line width should gradually increase based on the zoom level.
        lineStyle.lineWidth = NSExpression(format: "mgl_interpolate:withCurveType:parameters:stops:($zoomLevel, 'linear', nil, %@)",
                                       [14: 5, 18: 20])
        
        mapView.style?.addSource(source)
        mapView.style?.addLayer(lineStyle)
    }
}

and added property

 var allCoordinates: [CLLocationCoordinate2D] = []