How to read surface tags stored in graph (0.13.0-pre14)

Hi,
we use Graphhopper with the RacingBikeFlagEncoder and MountainBikeFlagEncoder for different routing profiles. Furthermore we added a DataFlagEncoder to retrieve the surface from the EdgeIteratorState.
Is it correct that with the newly released version 0.13.0-pre14 we can remove the DataFlagEncoder and read the surface directly from the graph? If so could you help me out where to start?

Yes, this was introduced and explained in the following pull request:

You only need to include the following in the configuration

graph.encoded_values: surface

Additionally I recommend to add: road_class,road_class_link,road_environment,max_speed,road_access

Thanks for the quick reply! I added the encoded_values to my configuration and regenerated the graph, but I always get “other” as surface. Is this code correct?

Graphhopper initialization:

ElevationProvider elevationProvider = new MultiSourceElevationProvider();
elevationProvider.setCalcMean(true);

EncodingManager encodingManager = EncodingManager.create(new RacingBikeFlagEncoder(), new MountainBikeFlagEncoder());

GraphHopper routingHopper = new GraphHopperOSM()
        .setDataReaderFile(filename)
        .init(new CmdArgs()
                .put("graph.elevation.smoothing", "true")
                .put("graph.encoded_values", "surface,road_class,road_class_link,road_environment,max_speed,road_access")
        )
        .setEncodingManager(encodingManager)
        .setMinNetworkSize(200, 200)
        .setGraphHopperLocation(routingPath)
        .setElevationProvider(elevationProvider);

CustomEdgeFilter:

public boolean accept(EdgeIteratorState edgeState) {
    Surface surface = edgeState.get(new EnumEncodedValue<Surface>(Surface.KEY, Surface.class));
    System.out.println(surface);

@karussell Is there any documentation or code examples for this new functionality? I can’t find any instructions in the pull request.

Currently there is no documentation for the Java usage, other than the tests.

You need to get the EnumEncodedValue from the EncodingManager:

surfaceEnc = encodingManager.getEnumEncodedValue(Surface.KEY, Surface.class)

Do this only once and use the surfaceEnc variable to access the edge properties multiple times via

surface = edge.get(surfaceEnc)

Does this help?

@karussell Thanks, I tried it out. However when I call hopper.getEncodingManager().getEnumEncodedValue(Surface.KEY, Surface.class); I get an IllegalArgumentException: Cannot find EncodedValue surface in collection: null.
While debugging I found out the encoded_values I specified in init are not available. Do I have to add another encoder or something else? I attached a screenshot of the encoded values in the method getEncodedValue in EncodingManager.

I did some more debugging and I think setEncodingManager(encodingManager) in my setup overwrites the encoding manager with the encoded values created by the init call.
How can I use my two encoding managers for racing bike and mountainbike without interfering with the encoded values?

EDIT: Found a solution, it’s working now. Code if anyone is interested:
GraphHopper routingHopper = new GraphHopperOSM()
.setDataReaderFile(filename)
.init(new CmdArgs()
.put(“graph.elevation.smoothing”, “true”)
.put(“graph.encoded_values”, “surface,road_class,road_class_link,road_environment,road_access”)
.put(“graph.flag_encoders”, “mtb,racingbike”)
)
.setMinNetworkSize(200, 200)
.setGraphHopperLocation(routingPath)
.setElevationProvider(elevationProvider);

Can you remove the init call and do:

new EncodingManager.Builder(4).add(someFlagEncoder).add(someTagParser).build();

1 Like

Thanks a lot for your help, it’s all working fine now!

1 Like