I am using Osm2Po to find routes between two points.

I am trying to find routes based on the difficulty specified by the user.

Basically, I would like to calculate the cost based on some parameter in the way. For now this parameter could be the type of road e.g. if its a primary road the cost would increase. If it was a secondary road it the cost would decrease especially. Any road with a cyclelane would have the best cost.

I have been looking into overriding the DefaultRouter methods: traverse, findpath and calcEdgeCost.

I was thinking that I could get the clazz type from the edge being currently examined and set its cost using calcEdgeCost.

One problem is that for some reason calling getVertexClazzes returns nothing but zeroes. getEdgeFlags returns null.

Here is part of my osm2po.config which might be relevant

#wayTagResolver.class = com.to.another.package.YourWayTagResolver
#nodeTagResolver.class = com.to.another.package.YourNodeTagResolver
#relationTagResolver.class = com.to.another.package.YourRelationTagResolver

# Properties of the DefaultWayTagResolver use this prefix.
wayTagResolver.prefix = wtr

# Custom flags with ascending binary values 1, 2, 4, 8 ...
# You may define up to 32 Flags (Bits).
wtr.flagList = car, bike, foot, rail, ferry 

# final decision; only allow ways with these flags
wtr.finalMask = bike

# very special hint for level_crossing modification
wtr.shuttleTrainMask = rail|car

# Main-Tag definitions. Params 1-4:
# 1) concurrent order
# 2) class (1-127)
# 3) default speed in kmh
# 4) allowed transportation type (optional) - since v4.5.30

wtr.tag.highway.motorway =       1, 11, 120, car    
wtr.tag.highway.motorway_link =  1, 12, 30,  car    
wtr.tag.highway.trunk =          1, 13, 90,  car    
wtr.tag.highway.trunk_link =     1, 14, 30,  car    
wtr.tag.highway.primary =        1, 15, 15,  car|bike    
wtr.tag.highway.primary_link =   1, 16, 30,  car    
wtr.tag.highway.secondary =      1, 21, 15,  car|bike    
wtr.tag.highway.secondary_link = 1, 22, 15,  car|bike    
wtr.tag.highway.tertiary =       1, 31, 12,  car|bike    
wtr.tag.highway.residential =    1, 32, 12,  car|bike    
wtr.tag.highway.road =           1, 41, 14,  car|bike    
wtr.tag.highway.unclassified =   1, 42, 12,  car|bike    
wtr.tag.highway.service =       1, 51, 5,   car|bike  
wtr.tag.highway.living_street = 1, 63, 7,   car|bike|foot      
wtr.tag.highway.pedestrian =    1, 62, 5,   bike|foot    
wtr.tag.highway.track =         1, 71, 10,  bike|foot    
wtr.tag.highway.path =          1, 72, 10,  bike|foot    
wtr.tag.highway.cycleway =      1, 81, 15,  bike    
#wtr.tag.highway.footway =       1, 91, 5,   foot    
#wtr.tag.highway.steps =         1, 92, 5,   foot    
wtr.tag.route.ferry =            2, 01, 10,  ferry   
wtr.tag.route.shuttle_train =    2, 02, 50,  rail|car   
wtr.tag.railway.rail =           3, 03, 50,  rail

1 Answer 1


There are two aproaches. So, firstly decide whether you need static or dynamic data. For the latter it is necessary to overwrite the Java-API. I think this is a static problem, meaning, the costs can be precalculated.

What you need is a different configuration. In your scenario the speed is never used. So why not regarding it as "your" costs. And if I see it correcly, you have already tried to follow this idea. Let's suppose you're going to prefer cycleways to tertiaries:


wtr.tag.highway.tertiary = 1, 1, 10, bike
wtr.tag.highway.cycleway = 1, 2, 20, bike


if maxSpeedOverrides is not set to false osm2po overrides the configured speed values (10, 20) with OSM's maxSpeed-tag-value if given.

As for the technical questions:

The graph.getVertexClazzes() method returns an array of user defined special flags/ids for nodes. 0 means that there is nothing special. A good example of how to use this array can be found in the osm2po plugins' sources. Search for Traffic-Signals.

Nevertheless, you actually need graph.getEdgeFlags() in order to receive street type infos. It's another array which can be populated with user defined 32-bit-integers. You can intercept the generation of these values by overwriting/injecting/configuring your own GraphBuildInterceptor. The "DefaultGraphBuildInterceptor" just copies the kmh and street-type(clazz) into the graph file while running osm2po with cmd=g (GraphBuild-Phase).

A return value of null means, that it is not needed and hence not cached by the graph-constructor. But there is a second constructor which lets you fine tune which addition you want. There are several consts, each starting with SUPPORTS. In your case graph.isSupported(SUPPORT_EDGEFLAGS) will return false. And finally, here is the constructor which includes vertex-coordinates and street-types/flags:

new Graph(graphFile, new Log(), Graph.SUPPORT_LATLON | Graph.SUPPORT_EDGEFLAGS);

By the way: The supported-flags can also be found the config. e.g.:

graph.support.edgeflags = true

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.