ios – Calculate distance and time between two waypoints of a route with here maps

0
132


I have a function that create a route between two points. Everything is fine. But now I need to create a function that given two waypoints of some pre-calculated route, return the distance and time between these waypoints. The function’s I have created to calculate and show the route in map are:

// Create map marker for some coordinate
func addCircleMapMarker(geoCoordinates: GeoCoordinates, imageName: String) {
    guard let image = UIImage(named: imageName)?.resizedTo(size: CGSize(width: 30, height: 30)), let imageData = image.pngData() else {
        return
    }
    
    let mapMarker = MapMarker(at: geoCoordinates, image: MapImage(pixelData: imageData, imageFormat: ImageFormat.png))
    mapView.mapScene.addMapMarker(mapMarker)
    self.allMarkers.append(mapMarker)
}
    
// Calculate route with given waypoints (can return a list of routes !)
func calculateRoute(origin: GeoCoordinates, stops stopPlaces: [GeoCoordinates]? = nil, destination: GeoCoordinates) async -> [heresdk.Route]? {
    
    return await withCheckedContinuation { continuation in
        let routingEng = self.getRoutingEngine()
        let carOptions = CarOptions()
        
        // Waypoints for origin, stop's (if exists at least one) and destination
        var routeWaypoints = [Waypoint]()
        let originWaypoint = Waypoint(coordinates: origin)
        let destinationWaypoint = Waypoint(coordinates: destination)
        
        // Origin waypoint
        routeWaypoints.append(originWaypoint)
        
        // All stops waypoints (if exist)
        if let stops = stopPlaces {
            for stp in stops {
                routeWaypoints.append(Waypoint(coordinates: stp))
            }
        }
        
        // Destination waypoint
        routeWaypoints.append(destinationWaypoint)
        
        routingEng.calculateRoute(with: routeWaypoints, carOptions: carOptions) { (routingError, routes) in
            continuation.resume(returning: routes)
        }
    }
}

// Add route to map and save route data to be re-used or cleared when needed
func addRoute(origin: GeoCoordinates, stops stopPlaces: [GeoCoordinates]? = nil, destination: GeoCoordinates) {
    
    Task {
        let routes = await self.calculateRoute(origin: origin, stops: stopPlaces, destination: destination)
        guard let routeList = routes, let firstRoute = routeList.first else { return }
        
        let lengthInMeters = firstRoute.lengthInMeters
        let estimatedTravelTimeInSeconds = firstRoute.duration
        
        self.distanceTrip = lengthInMeters
        self.durationTrip = estimatedTravelTimeInSeconds
        
        self.showRouteInMap(route: firstRoute)
    }
}

// Show route in map
func showRouteInMap(route: heresdk.Route) {
    
    self.clearMap()
    
    self.currentRoute.accept(route)
    
    // Show route as polyline.
    let routeGeoPolyline = route.geometry
    let routeMapPolyline = MapPolyline(geometry: routeGeoPolyline,
                                        widthInPixels: 20,
                                        color: UIColor(red: 0,
                                                        green: 0.56,
                                                        blue: 0.54,
                                                        alpha: 0.63))
    mapView.mapScene.addMapPolyline(routeMapPolyline)
    self.routePolyline = routeMapPolyline
    
    let startPoint = route.sections.first!.departurePlace.mapMatchedCoordinates
    let destination = route.sections.last!.arrivalPlace.mapMatchedCoordinates
    
    // Draw a circle to indicate starting point and destination.
    self.addCircleMapMarker(geoCoordinates: startPoint, imageName: "map-marker.png")
    self.addCircleMapMarker(geoCoordinates: destination, imageName: "map-marker.png")
}

// Clear map elements (route polyline, map markers etc.)
func clearMap() {
    self.clearWaypointMapMarker()
    self.clearRoute()
}

// Clear all waypoint map markers
private func clearWaypointMapMarker() {
    for mapMarker in allMarkers {
        mapView.mapScene.removeMapMarker(mapMarker)
    }
    
    allMarkers.removeAll()
}

// Clear current route
private func clearRoute() {
    guard let mapRoute = self.routePolyline else { return }
    mapView.mapScene.removeMapPolyline(mapRoute)
}

So with that route I have calculated, I need for example know from the polyline how to get distance and time in the route waypoints.