Avoid coordinates when generating a route using Mapbox Direction API
Asked Answered
I

2

6

I have been using Mapbox for my app to generate route and turn-by-turn navigation and it's working well. However I would like to avoid to go through some coordinates of the route but I can't figure it out.

The code to get the route :

Directions.shared.calculate(options) { [unowned self] (waypoints, routes, error) in
        // Take first route and customize it in a way to get around some coordinates
    }

Here is a scenario :

1- User location is latitude = 37.332331410000002, longitude = -122.0312186

2- The user is going to Santa Clara Unified School located on latitude = 37.354100000000003,longitude = -121.9552

3- The Api generates the following route :

 [0] = {
latitude = 37.332329999999999
longitude = -122.03118000000001
}
  [1] = {
    latitude = 37.332619999999999
    longitude = -122.03118000000001
  }
  [2] = {
    latitude = 37.332609999999995
    longitude = -122.03097000000001
  }
  [3] = {
    latitude = 37.332609999999995
    longitude = -122.03076000000001
  }
  [4] = {
    latitude = 37.332199999999993
    longitude = -122.03076000000001
  }
  [5] = {
    latitude = 37.331689999999995
    longitude = -122.03076000000001
  }
  [6] = {
    latitude = 37.331689999999995
    longitude = -122.03190000000002
  }
  [7] = {
    latitude = 37.331719999999997
    longitude = -122.03199000000002
  }
  [8] = {
    latitude = 37.331759999999996
    longitude = -122.03205000000003
  } ...

4- Suppose the generated route goes through East Homestead Rd, I would like to be able to avoid this road and generate a new route even if it's a longer one.In the screen below avoid the route in red because going through East Homestead Rd and take the next fastest route not going through East Homestead Rd enter image description here

Any help would be appreciated !

EDIT : Here is the query for finding if a route has points to avoid in it

// $linestring is the array of coordinates from the route in the string format of (lng lat,lng2 lat2,lng3 lat3,lng4 lat4....)
$query = $this->em->createQuery('
            SELECT   count(i) as counter
            FROM     HitsBundle:Hit i
            WHERE i.datetime BETWEEN :lastMonth AND :now 
                  AND 
                  MBRCovers(
                    ST_Buffer( 
                        ST_GeomFromText(\'LineString('.$linestring.')\') ,
                        0.00001
                    ),
                    i.coordinates
                  ) = 1
            GROUP BY i.coordinates
            HAVING  counter > 1
        ')
            ->setParameter('lastMonth', $lastMonth)
            ->setParameter('now', new \DateTime())
            ->setMaxResults(1);

EDIT: Related issue on Github

Ijssel answered 2/6, 2018 at 18:27 Comment(2)
Can you elaborate a bit? A concrete example would helpAware
@MihaiFratu updated with an exampleIjssel
N
3

I may be rough-guessing here, but looking through Mapbox API it does not have any options to avoid while generating routes, therefore you need to implement some route-selection logic on client-side.

Basically you need to have an algorithm which gets a set of points to avoid and checks if your Route geometry GeoJSON or Polyline are within some threshold range from given points. If it is - discard the route (or lower route priority).

Of course it may fail to find a route if all routes provided by Mapbox are discarded - Mapbox does not know about your restrictions, therefore using weight for routes could be one option of solving this.

These posts might give you some hints:

Narcoanalysis answered 11/6, 2018 at 10:4 Comment(3)
The issue with the proposed solution is that it is very likely to not find any route because of the multitude of different coordinates to avoid. In my case the shortest route is not always the best. I will give it a try and see if it works. The best however would be to be able to give the API the coordinates to avoid and based on that get a set of routes. Maybe worth a feature request ?Ijssel
Of course you could try this, but normally it is not easy for non-opensource projects (unless you are a heavy-paying customer). You should really assess your exact use-case, why you need this functionality. If you want your clients take a certain route for example, you may try to hint the mapping API with waypoints.Narcoanalysis
Finally I adopted the way described earlier and looped through the route until finding the one free of points. The query is on the first post.Ijssel
I
0

After few months dealing with the MapBox Direction API we've come to the conclusion that it's not reliable for this specific use case. When calculating routes from Point A to Point B using the Direction API, MapBox offers an option includesAlternativeRoutes if set to true it provides alternative routes. However this is not consistent and in most cases it returns only the preferred route.

According to MapBox :

If the value of this property is true, the server attempts to find additional reasonable routes that visit the waypoints. Regardless, multiple routes are only returned if it is possible to visit the waypoints by a different route without significantly increasing the distance or travel time.

So we will switch to Google Maps as this feature is crucial to our business logic.

Ijssel answered 19/10, 2018 at 16:26 Comment(2)
It doesn't appear to me that Google Maps provides this feature either. Can you elaborate on why Google Maps was better in this case?Myology
@Myology At the end we used an hybrid solution as mentioned on the first answer, We get all the routes from MapBox (including alternatives) then we send routes to backend to check them for point to avoid and send back the one with the least number of points. This doesn't answer the issue but less time consumingIjssel

© 2022 - 2024 — McMap. All rights reserved.