#8170 closed enhancement (fixed)
mapcss parent_tag(key_name) only selects value from 1 parent
| Reported by: | Polyglot | Owned by: | team |
|---|---|---|---|
| Priority: | normal | Milestone: | 15.09 |
| Component: | Core mappaint | Version: | |
| Keywords: | mapcss parent_tag | Cc: | Klumbumbus |
Description
On the wiki I find the following:
parent_tag(key_name)
get the value of the key key_name from the object's parent(s)
It suggests that more than 1 value can be shown. (The use case is a bus stop which is a member of several routes)
I think it's coded here:
182 public String parent_tag(String key) {
183 if (env.parent == null) {
184 // we don't have a matched parent, so just search all referrers
185 for (OsmPrimitive parent : env.osm.getReferrers()) {
186 String value = parent.get(key);
187 if (value != null)
188 return value;
189 }
190 return null;
191 }
192 return env.parent.get(key);
193 }
I'm not a java coder so I don't dare to touch it myself, but couldn't it work with a loop and return a list of values in a string separated by ";"? What is a matched parent? One defined by the selector expression?
Attachments (0)
Change History (14)
comment:1 by , 13 years ago
comment:2 by , 13 years ago
Semicolon as separator is a little arbitrary, other user probably want space or space,dash,space.
Maybe a second function "parent_tags(String key, String sep)"?
comment:3 by , 13 years ago
I proposed semicolon because that's what I put in route_ref of our bus stops.
I was also thinking that a separate function would be even better. Extra brownie points for a user defined separator.
I didn't propose to have a separate function, as I don't know how that would fit in the general mapcss standard.
Jo
comment:4 by , 13 years ago
I've been reading up a bit on how mapcss is being implemented in other products. Am I correct if I deduce JOSM has more eval expressions than the other implementations at the moment i.e. parent_tag isn't available (yet) in the other implementations? And thus it wouldn't be a problem to create a separate parent_tags function?
If parent_count() is ever implemented, it probably needs a selector as well. I would only be interested in other PT relations when working with a style sheet dedicated to PT. Will it ever be possible to 'loop' over them? That would be terrific for creating 'spider' diagrams of PT maps. 1 route relation in its assigned color on the road, itself. Another next/above it and another beneath it.
For the time being I would already be happy with a list of colors that can be used to 'hash' the line. If 4 relations pass over a road, I'd like to be able to colour it in small 'segments' of each of the assigned colours. Of course, this doesn't make sense any more when there are more than say 5 or 6 relevant routes passing there.
comment:5 by , 11 years ago
parent_tags() should probably return a list, and than list functions can be used to alter the list in whatever way you like, i.e. join(parent_tags(ref), ";") would give a ; separated string of all refs, while maybe the same user would like to see join(parent_tags(name), " - "), having parent_tags() return a list gives you all the flexibility of list functions to work directly on it.
comment:6 by , 11 years ago
| Component: | Internal mappaint style → Core mappaint |
|---|
comment:7 by , 11 years ago
| Cc: | added |
|---|
comment:9 by , 10 years ago
| Milestone: | → 15.09 |
|---|
comment:10 by , 10 years ago
Hi Simon,
Thank you for implementing this. I see you have a test case for a node and tags from its parent ways. I'm trying to make it work for a node which is a child of a relation. Unfortunately I only get 1 result, instead of a longer list.
relation[route=bus] > node|z16-::parent_ref {text-color: pink; font-size: 19; text: join_list(";", parent_tags(ref)); text-halo-radius: 2; text-offset-y: -40; z-index:5.0;}
I'm testing on this node: https://www.openstreetmap.org/node/2956645204
comment:11 by , 10 years ago
This relates to the general behavior that only one child/parent is matched by the child/parent selector. Then, env.parent != null and simply Collections.singletonList(env.parent.get(key)) is returned. I do not see a simple solution for that at the moment …
comment:12 by , 10 years ago
It is not the same what you would like to achieve, but this maybe helps you:
relation[route=bus] > node::parent_ref { set busroutenode; } node|z16-.busroutenode::parent_ref { text-color: pink; font-size: 19; text: join_list(";", parent_tags(ref)); text-halo-radius: 2; text-offset-y: -40; z-index:5.0; }
comment:13 by , 10 years ago
Wouldn't it be possible to simply drop
if (env.parent == null) {
as a condition? The whole point of trying to fetch a tag of all the parents is that the matched parent is irrelevant.
I see another problem appearing. What if the same ref is present in several parents, like on this node:
https://www.openstreetmap.org/node/80724709
It's an extreme example... A very busy bus stop.
Jo
comment:14 by , 10 years ago
The problem with env.parent == null is that the role selectors (relation >[role=...] node[public_transport]) don't have any effect. Neither solution is satisfying, before having #7151 resolved.



What do you think about this? It's untested and probably contains syntax errors, but it should be 'almost there'.
public String parent_tag(String key) { if (env.parent == null) { // we don't have a matched parent, so just search all referrers String value = ""; for (OsmPrimitive parent : env.osm.getReferrers()) { value += parent.get(key) + ";"; } if (value != null) return left(value,len(value)-1); # remove trailing ';' else return null; } return env.parent.get(key); }