0

im trying to create a route that follows a gps trace i provide. The gps trace is cleaned up and it has no loops in it and is in correct order. I checked it with other services. It has 1920 points. You can find the trace here GPX Files Sadly if i create a route based on provided sdk example (github) i get loops in my path.

I was hoping you could help me to solve following problems:

  1. how do i avoid loops while creating route by using HERE ios Swift SDK

  2. how do i set route options is such way to follow provided point array and not create a fastest or balanced route.

Since i could not find those functions in Ios sdk i used additional REST API to filter the route a bit to remove all points that were not matched correctly according to here maps... before drawing the route.. ie everything with low probability, warnings, big distance to the road... yet the result is still not good. Here is a cleaned up file.. the file is being created after the original was maped / run once through HERE Maps. In this file all points that have low confidence or produce warnings or have big distance to original points .. are removed. This is the one i use to create a route and it still have the same issues like loops and weird turns.

Thank you very much in advance! BR.

So far i have this code:

private lazy var router = NMACoreRouter()



 @objc func do_routing_stuff( gps_trace :[NMAWaypoint]) {
    var stops = [Any]()
    stops = gps_trace
    

    let routingMode = NMARoutingMode(routingType: .fastest,
                                     transportMode: .car,
                                     routingOptions: .avoidHighway)
    
    // Trigger the route calculation
           router.calculateRoute(withStops: stops ,
                                      routingMode: routingMode)
           { [weak self] routeResult, error in
               guard error == .none else {
                   self?.showMessage("Error:route calculation returned error code \(error.rawValue)")
                   return
               }

               guard let result = routeResult, let routes = result.routes, routes.count > 0 else {
                   self?.showMessage("Error:route result returned is not valid")
                   return
               }

               // Let's add the 1st result onto the map
               self?.route = routes[0]
               self?.updateMapRoute(with: self?.route)

              // self?.startNavigation()
           }
    
}

private func updateMapRoute(with route: NMARoute?) {
    // remove previously created map route from map
    if let previousMapRoute = mapRoute {
        mapView.remove(mapObject:previousMapRoute)
    }
    
    guard let unwrappedRoute = route else {
        return
    }
    
    mapRoute = NMAMapRoute(unwrappedRoute)
    mapRoute?.traveledColor = .clear
    _ = mapRoute.map{ mapView?.add(mapObject: $0) }
    
    // In order to see the entire route, we orientate the
    // map view accordingly
    if let boundingBox = unwrappedRoute.boundingBox {
        geoBoundingBox = boundingBox
        mapView.set(boundingBox: boundingBox, animation: .linear)
    }
}

enter image description here enter image description here

in comparison same route presented with leaflet maps.

pic4

enter image description here

Andreas
  • 397
  • 4
  • 18
  • 37

2 Answers2

1

I believe the problem you have is that you are feeding the Routing API a large number of waypoints, all of which are in close proximity to each other.

You have almost 2000 waypoints in your GPX file (and ~1300 in your cleaned one). Each of these waypoints is less than 10 meters distance from their closest neighbors. This is not the type of data that the Routing API is really designed to work with.

I've experimented with your GPX Trace and I have come up with the following solution: simply skip a bunch of coordinates in your trace.

First, clean up your trace using the Route Matching API (which I believe you have been doing).

Second, pick the first trkpt in the GPX file as your first waypoint for the Routing call. Then skip the next 20 points. Pick the following trkpoint as the second waypoint. Repeat this until you are at the end of the file. Then add the last trkpt in the trace as the final waypoint.

Then call the Routing API and you should get a good match between your trace and your route, without any loops or other weird routing artefacts.

Some notes:

I have picked 20 as the number of traces to skip, because this would put about 200m in between each waypoint. That should be close enough to ensure that the Routing API does not deviate too much from the traced route. For larger traces you may wish to increase that number. For traces in urban environments with lots alternate routes, you may want to use a smaller number.

It's important to clean the data with the Route Matching API first, to avoid picking outliers as waypoints.

Also, you may not wish to use the "avoidHighways" option. Given your use case, there doesn't seem to be a benefit and I could see it causing additional problems.

leopectus
  • 842
  • 5
  • 12
1

By now you probably worked it out, but your waypoints are likely landing on bridges or tunnels that are along your route but not on the road you want. I.e. the waypoint is intended to be on the road under the bridge but the routing engine perceives that you want to drive on the bridge. The routing engine is looping around those roads to drive you on that waypoint on the bridge or in the tunnel. There is no simple solution to this that I have found.

Schwarz Software
  • 1,114
  • 8
  • 22
  • 1
    Thank you. Ill check for that and try to remove points which are on the bridge or tunnel. No i did not worked it out actually. I think i got lucky since i decreased the point density and had no points on a bridge or tunnel. – Andreas Jun 02 '22 at 05:29
  • One potential auto solution is to reverse geocode the points. If the point has 2 addresses then it *may* be a bridge or tunnel, delete that waypoint. Apart from that I haven't worked out how to tell HERE maps which road is the correct road given a gps co-ordinate. – Schwarz Software Jun 02 '22 at 06:24
  • since im getting my coordinates out of openstreetmap i can filter out bridges and tunnels in db. Let's see if it helps. I since abandoned HERE maps and go with mapbox but maybe ill come back. – Andreas Jun 02 '22 at 06:52