Change speed for certain vehicle profile

Hi everyone,

I want to create a custom weighting for some specific nodes (near a lon,lat position).
I need to modify the speed of specific edges (retrieved by the locationIndex.findClosest),
something similar to the code of :

Using the graphhopper-core library version 2.1 the following code does not work anymore.

edge.setFlags(carEncoder.setSpeed(edge.getFlags(), value));

Is there any way in version 2.1 to achieve the same result?
Thank you in advance

Modifying the estimated speed for e.g. car can be done like this:

// init once:
DecimalEncodedValue avgSpeedEnc = encoder.getAverageSpeedEnc();

// use for edge:
double oldValue = edge.get(avgSpeedEnc);
edge.set(avgSpeedEnc, newValue);
// if the encoded value can store two directions you can also use the getReverse/setReverse methods
1 Like

Is it not recommended to use encoder.getAverageSpeedEnc()?

I’m unsure if we should recommend it as we have the plan to remove the FlagEncoders (?)

But as something similar will exist (CarEncodedValues?) it will be likely easy to migrate to it, so probably we should continue suggesting encoder.getXYEnc()

Have edited my original answer that used encodingManager.getDecimalEncodedValue(EncodingManager.getKey(encoder.toString(), "average_speed"))

1 Like

Thank you for the quick reply!
This does something but it doesn’t change the final route

My code sligthly changes the sample code of the github page

public static void routing(GraphHopper hopper) {
    // simple configuration of the request object
    GHRequest req = new GHRequest(41.901102,12.501942,41.907168, 12.475761) //Rome city
                    .putHint(Parameters.CH.DISABLE, true);
    GHResponse rsp = hopper.route(req);
    //Get edge near a point (used on the route) and its EdgeIteratorState
    Graph graph = hopper.getGraphHopperStorage();
    LocationIndex locationIndex = hopper.getLocationIndex();
    Snap qr = locationIndex.findClosest(41.9110453,12.4949017, EdgeFilter.ALL_EDGES);
    int edgeId = qr.getClosestEdge().getEdge();
    EdgeIteratorState edge = graph.getEdgeIteratorState(edgeId, Integer.MIN_VALUE);
    FlagEncoder carEncoder = hopper.getEncodingManager().getEncoder("car");
    //The code you suggested me
    DecimalEncodedValue avgSpeedEnc = hopper.getEncodingManager().getDecimalEncodedValue(EncodingManager.getKey(carEncoder.toString(), "average_speed"));
    double oldValue = edge.get(avgSpeedEnc);
    System.out.println(oldValue); //Prints 45.0
    edge.set(avgSpeedEnc, 00.0d); //Slow the speed 
    System.out.println(edge.get(avgSpeedEnc));//Prints 0.0

    // handle errors
    if (rsp.hasErrors())
        throw new RuntimeException(rsp.getErrors().toString());

    // use the best path, see the GHResponse class for more possibilities.
    ResponsePath path = rsp.getBest();
    // points, distance in meters and time in millis of the full path
    PointList pointList = path.getPoints();
    double distance = path.getDistance();
    long timeInMs = path.getTime();
    System.out.println(pointList.toLineString(false)); //Returns the same route 

    assert Helper.round(path.getDistance(), -2) == 900;

The route is always the same :frowning:

Do the routing (hopper.route(req)) after you changed the speed :).

Please note that this only works for disabled CH, so exactly how the route is currently queried. If you want to make the change for CH too you need to do these changes before importOrLoad.

Also if you want to make an edge inaccessible additionally to setting the speed to 0 you need to use

accessEnc = encoder.getAccessEnc();
edge.set(accessEnc, false);
edge.setReverse(accessEnc, false);

Or set the speed to a bigger value. Unfortunately this is a current limitation and can be hopefully avoided in a future version.

Another possibility would be to just store some information at this edge like

edge.set(trafficJamEnc, true)

and then use this encoded value in the CustomWeighting to influence the speed, max_speed or priority.

Thank you, now it changes the route.
I was really stuck on this, now I can understad more and more about the library.

Have a nice weekend

1 Like

The possibility you gave is interesting,
but how i create trafficJamEnc?
and how can I force the GH instance to use the CustomWeighting class I create?


but how i create trafficJamEnc?

You create e.g. a BooleanEncodedValue and add it to the EncodingManager. E.g. see CustomWeightingTest where we create an EncodedValue for lanes:

carFE = new CarFlagEncoder().setSpeedTwoDirections(true);
laneEnc = new UnsignedIntEncodedValue("lanes", 2, true);
encodingManager = new EncodingManager.Builder().add(carFE).add(laneEnc).build();

and how can I force the GH instance to use the CustomWeighting class I create?

You can use it in the custom weighting file or per request. See the profiles:

Powered by Discourse