Custom string PathDetail

Hello! I’m trying to add my own PathDetail to Graph. I tried to use “street name” as example, but it is quite hard to follow. I’m trying to add hike name and colour to result. It is tricky, because one way can be in multiple relations which means multiple colors and names (example).

I do know how to create relation tag parser and retrieve those information from OSM tags, but I have no idea how to:

  1. Store those data in StringEncodedValue
    I cannot find any StringEncodedValue constructor that would match my needs. There is always “expectedValueCount” or list of “values”, but I cannot know how many values it has to hold. I need some configuration that would match “street name”, which means that encoded value has to store any given String. For example in this way String would be something like:
    "Schronisko PTTK w Dolinie Pięciu Stawów Polskich - Schronisko PTTK przy Morskim Oku #0000FF;Wodogrzmoty Mickiewicza - Schronisko PTTK przy Morskim Oku #FF0000"
    This string is built from relation one and relation two

  2. How to add data to PathDetail
    After I already insert hike trail data into Graph, how should I put in in PathDetail? I see that I can override PathDetailBuilderFactory and then should I use the same code that is used for STREET_NAME? (of course with my own parameter name)

 if (requestedPathDetails.contains(STREET_NAME))
            builders.add(new KVStringDetails(STREET_NAME));

If param name provided to KVStringDetails matches encoded value name, then Graphhopper will automatically use it as next PathDetail?

Fetching the data is easy via the KV storage but feeding this might be the challenge.

Let’s say you have the tag xy in an OSM way, then it is pretty easy and you just put xy in the KV storage like it is done for e.g. the name tag (STREET_NAME).

But having a tag in a relation is more complicated, but should be still possible with some customization in OSMReader. But what if a single way is part of multiple relations? Just comma separated like you suggested?

Maybe comma separated, maybe some combination of “:|:” to make sure that it will be possible to split by it in post processing. I’ll take take of multiple relations, it should not be that hard, but I cannot find code which creates StringEncodedValue and puts STREET_NAME into it. Could you direct me where I can find it?

It is not StringEncodedValue (which goes into the edges DataAccess). It is the KVStorage:

Oh, I see, I didn’t have to use key values before, so I’ll need to dig in little more. I see that “key_values” is set as tag on way? To can I use RelationParser, retrieve key_values and put it there? Or is RelationParser executed before “preprocessWay” method which you showed me?

key_values is a “virtual” tag and only used to propagate the data to the reading place:

Map<String, KValue> map = way.getTag("key_values", Collections.emptyMap());
if (!map.isEmpty())
    edge.setKeyValues(map);

can I use RelationParser, retrieve key_values and put it there?

This is a bit tricky. You can have a look into the place where we read other data from relations like “putRelFlagsMap” and add a hashmap to store the name tag per ID for the relation. And then you can read this hashmap in addEdge and add it to the keyValues map.