Encoded values do not match when loading cache with custom encoded values

Hey!
We are using the graphhopper-core (4.0) in a spring/boot application.
Our data has custom way tags that we would like to load into the cache.
For this purpose we have created a StringEncodedValue that is not shared.
This value is set in a our custom encoder:

public class CustomFlagEncoder extends Bike2WeightFlagEncoder {
    private StringEncodedValue encodedValue;

    @Override
    public void applyWayTags(ReaderWay way, EdgeIteratorState edge) {
        super.applyWayTags(way, edge);

        edge.set(encodedValue, way.getTag(CustomTag.DATA_KEY, ""));
    }

    @Override
    public void createEncodedValues(List<EncodedValue> registerNewEncodedValue, String prefix, int index) {
        super.createEncodedValues(registerNewEncodedValue, prefix, index);

        encodedValue = getStringEncodedValue(CustomTag.ENCODED_VALUE_KEY);
    }
}

This value is then used in our custom weighting, by getting it using the given FlagEncoder.
The graphhopper instance is initialized with a CustomEncodedValueFactory:

public class CustomEncodedValueFactory implements EncodedValueFactory {

    private final EncodedValueFactory baseEncodedValueFactory;

    public CustomEncodedValueFactory(EncodedValueFactory baseEncodedValueFactory) {
        this.baseEncodedValueFactory = baseEncodedValueFactory;
    }

    @Override
    public EncodedValue create(String encodedValueString) {
        if (encodedValueString.contains(CustomTag.ENCODED_VALUE_KEY)) {
            return CustomTag.create();
        }

        return baseEncodedValueFactory.create(encodedValueString);
    }
}

and a TagParser is added to the EncodingManagerBuilder prior to the load or process:

public class CustomTagParser implements TagParser {
    private StringEncodedValue encodedValue;

    CustomTagParser() {
        this.encodedValue = CustomTag.create();
    }

    @Override
    public void createEncodedValues(EncodedValueLookup lookup, List<EncodedValue> registerNewEncodedValue) {
        registerNewEncodedValue.add(encodedValue = CustomTag.create());
    }

    @Override
    public IntsRef handleWayTags(IntsRef edgeFlags, ReaderWay way, boolean ferry, IntsRef relationFlags) {
        if (way.hasTag(CustomTag.DATA_KEY)) {
            encodedValue.setString(false, edgeFlags, way.getTag(CustomTag.DATA_KEY));
        }
        return edgeFlags;
    }
}

The issue im getting after loading the cache again when I restart the application is: java.lang.IllegalStateException: Encoded values do not match

What isnt matching is that our CustomTag doesnt seem to be shifted correctly.

Im sitting at this problem since a long time now and unfortunately switching to the server version of graphhopper is no option anymore.

Hope you can help me!
Cheers!

Hi @Shino!

Did you specify your encoded value/s in DefaultTagParserFactory.java and DefaultEncodedValueFactory.java?

Hello I added it manually prior to load
super.getEncodingManagerBuilder().add(new CustomTagParser());

I will try to do it via the factory and report back.

Great! Also check if you need to specify your Custom Weighting in DefaultWeightingFactor.java. This is what I needed to do for my custom encoded values and custom weightings to work

Hello,
when I define a factory:

public class CustomTagParserFactory implements TagParserFactory {
    private final DefaultTagParserFactory defaultTagParserFactory;

    CustomTagParserFactory(DefaultTagParserFactory defaultTagParserFactory) {
        this.defaultTagParserFactory = defaultTagParserFactory;
    }

    @Override
    public TagParser create(String name, PMap configuration) {
        if (name.contains(CustomTag.ENCODED_VALUE_KEY)) {
            return new CustomTagParser();
        }

        return defaultTagParserFactory.create(name, configuration);
    }
}

and set it via the setter, the TagParser is not created and thus neither the encoded value.

Thus Im getting the error that the encoded value for my custom key is null when the FlagEncoders attempt to use them.

Do I have to set graph.encoded_values?

Regarding the CustomWeighting:
We are using an AdjustedWeighting based on the FastestWeighting, so I believe that is not required right?

For some of my encoded values I set the graph.encoded_values, but not for all. I don’t think it is required to set graph.encoded_values if you already registered your encoded value in your createEncodedValues method as you did. I set graph.encoded_values when I use the Local MVT tool and want to inspect the encoded_values visually.

Oh I see. I extended the FastestWeighting and I had some issues that was only resolved when I specified my Custom Weighting in DefaultWeightingFactory. This might not be the case for you.

If I can’t help you, some of the other guys on here will definitely be able to help you!

Thanks for your help so far, you pointed me in a direction to continue :slight_smile:

Glad to help! :grinning:

Hey!
Im not sure if that is a solution. But I added the encoded value and tagparser manually to the EncodingManagerBuilder.

Now graphhopper starts but when I attempt to do routing I get an IndexOutOfBoundsException for the encoded value I guess. Have you ever encountered that?

Hi, I don’t think that I have. Can you share snip/screenshot of the exact error you receive?

Hey,
sorry for not answering. I was going down deep into the depths of graphhopper.
I found out that I was simply using the wrong kind of EncodedValue. It seems that StringEncodedValue is not what I was needing and there seem to be problems with the reinitialization. So I simply modeled it with an EnumEncodedValue and see there it worked like a charm.

No worries. I am glad you solved your problem!

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.