Modify

Opened 11 years ago

Closed 8 years ago

Last modified 8 years ago

#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:

http://josm.openstreetmap.de/browser/josm/trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Expression.java

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 Polyglot, 11 years ago

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);
	            }

comment:2 by bastiK, 11 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 Polyglot, 11 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 Polyglot, 11 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 Aun Johnsen <lists@…>, 10 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 Don-vip, 10 years ago

Component: Internal mappaint styleCore mappaint

comment:7 by Klumbumbus, 9 years ago

Cc: Klumbumbus added

comment:8 by simon04, 8 years ago

Resolution: fixed
Status: newclosed

In 8775/josm:

fix #8170 - MapCSS: add functions parent_tags(key) and join_list(sep, list)

The method parent_tags(key) returns all parent's values for key as a list ordered by a natural ordering.
The method join_list(sep, list) joins the elements of list to one string separated by sep.

comment:9 by simon04, 8 years ago

Milestone: 15.09

comment:10 by Polyglot, 8 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

Last edited 8 years ago by Klumbumbus (previous) (diff)

comment:11 by simon04, 8 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 Klumbumbus, 8 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 Polyglot, 8 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 simon04, 8 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.

Modify Ticket

Change Properties
Set your email in Preferences
Action
as closed The owner will remain team.
as The resolution will be set.
The resolution will be deleted. Next status will be 'reopened'.

Add Comment


E-mail address and name can be saved in the Preferences .
 
Note: See TracTickets for help on using tickets.