Restrictions are not considered with flex profile

I checked out the flex_vehicleprofile branch, built it and created the following Truck Profile (truck_profile.yml):

name: truck_profile
base: car
max_speed: 80
no_access:
 max_height: 4
 max_width: 2.6
 max_weight: 40000
consider_oneway: false

When routing from 48.888025,9.158108 to 48.888618,9.162297 it should avoid the Robert-Bosch-Straße (weight restriction 7.5t, see link), but it doesn’t.

The important lines in my config.yml:

 prepare.ch.weightings: no
 graph.encoding_manager: /PATH/TO/truck_profile.yml
 prepare.lm.weightings: truck_profile

What am I doing wrong?

Ha. This is simply not implemented but it shouldn’t be hard to add it :slight_smile: … maybe you can have a look how it is done for e.g. the toll value: https://github.com/graphhopper/graphhopper/commit/21d08e833520d5253ba78ea54abdd69902066a75

That explains a lot :smiley:
The only other way to implement truck profiles is to create a FlagEncoder, right?

For productive use of truck profiles what would you recommend to use?

FlagEncoder is a concept that we’ll hopefully be able to “faid out” and replace it with other things as it simply does too many things. So for cases like this a new FlagEncoder is not necessary anymore and you need to add e.g. the width as new edge property (EncodedValue) and then limit the access in the FlexWeighting

Okay, cool.
The existing properties (Toll, RoadClass etc.) are all enums. I don’t understand how this would be done for decimal values like MaxWeight.
How would the profile and the parser look like?

EDIT:
Also, in FlexModel there is already maxWidth, maxHeight and maxWeight in the NoAccess class?

Instead of EnumEncodedValue you can use DecimalEncodedValue. The usage via edge.set/get is identical to the EnumEncodedValue

I used DescimalEncodedValue now but found that the official OSM Key is called “maxweight”.
Now in my created “MaxWeightParser.java” it should look something like this, right?

public class MaxWeightParser extends AbstractTagParser {
    private final DecimalEncodedValue maxWeightEnc;

    public MaxWeightParser() {
        super(EncodingManager.MAX_WEIGHT);
        this.maxWeightEnc = new DecimalEncodedValueImpl("max_weight", 8, 0, 1, false);
    }

    public DecimalEncodedValue getEnc() {
        return maxWeightEnc;
    }

    @Override
    public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way, long allowed, long relationFlags) {
        if (way.hasTag("maxweight", "yes"))
            maxWeightEnc.setDecimal(false, edgeFlags, way.getTag("maxweight", 999d));
        return edgeFlags;
    }
}

In “FlexWeighting.java” I added the following:

        if (model.getNoAccess().getMaxWeight() != 0)
            noAccessCalcs.add(new NoAccessCalc() {
                @Override
                public boolean blocked(EdgeIteratorState edgeState, boolean reverse, int prevOrNextEdgeId) {
                    return model.getNoAccess().getMaxWeight() > edgeState.get(maxWeightEnc);
                }
            });

Still doesn’t work…

There are two problems. This

hasTag("maxweight", "yes")

should be just

hasTag("maxweight")

and way.getTag("maxweight", 999d)) should return the maximum value that fits in the EncodedValue or should return 0 meaning that there is no value and it would use some default.

Also this should be the otherway around?

model.getNoAccess().getMaxWeight() > edgeState.get(maxWeightEnc);

Made the changes, but it still doesn’t work. Am I missing something? Do I need a special OSM-File or what could be the problem?

Or could it be the request itself?
localhost:8989/maps/?point=48.888148%2C9.15807&point=48.888339%2C9.162093&locale=de&vehicle=truck_profile&weighting=fastest&elevation=false&use_miles=false&layer=OpenStreetMap

Hard to judge without code. Probably best is to create a unit test like there are already some in this branch regarding the FlexWeighting and then debug which values are stored for the edge and see if they are applied in the FlexWeighting

Okay, I changed the code of FlexWeightingTest to my needs. How can I run the test? mvn clean test verify doesn’t execute the test.

Usually you do this in your IDE like IntelliJ. Running single tests with maven is cumbersome.

How can I run the test? mvn clean test verify doesn’t execute the test.

It should. Did you put it under the test folder?

I used this file initially added by you:

    graphhopper/core/src/test/java/com/graphhopper/routing/weighting/FlexWeightingTest.java

But it has no annotated test-methods. That’s why I was wondering.

Yes, that’s not a proper test class :wink:
I wrote this branch in the mindset that I have to rewrite several parts.

Please use any other class as example, e.g. one that has some @Test annotation

Alright, I got the test working and everything looks good, except of one thing. When I go to localhost:8989 and calculate a route, it always says weighting=fastest and doesn’t use the flex weighting. How can I change that?
In the config.yml I have prepare.ch.weightings: no.

You have to tweak the UI on your own. (you can change it in the URL and it will preserved until a page reload)

So there is no way to always use the FlexModel?
In GraphHopper.java there is this method:

public Weighting createWeighting(HintsMap hintsMap, FlagEncoder encoder, Graph graph) {
        String weightingStr = toLowerCase(hintsMap.getWeighting());
        Weighting weighting = null;

        FlexModel flexModel = importVehicleModels.get(weightingStr);
        if (flexModel != null) {
            weighting = new FlexWeighting(flexModel).init(encodingManager);
        } else if ...
}

Now on the web frontend when I use the buttons to select one of the flex profiles:
grafik
the route is calculated without FlexWeighting. But when I use the textarea for flex:
grafik
FlexWeighting is being used!

How can I enable FlexWeighting for the buttons as well?

This is not yet implemented on the JS side. As I said: you have to tweak the UI on your own