Ticket #6129: mapcss-parent-props-in-descendant-selectors.patch

File mapcss-parent-props-in-descendant-selectors.patch, 14.3 KB (added by cmuelle8, 13 years ago)

have more mapcss features..

  • src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java

     
    55import java.util.ArrayList;
    66import java.util.Collection;
    77import java.util.Collections;
     8import java.util.HashMap;
    89import java.util.Iterator;
    910import java.util.List;
    1011import java.util.Map.Entry;
     
    2122
    2223public class ElemStyles {
    2324    private List<StyleSource> styleSources;
     25    private HashMap<String, HashMap<OsmPrimitive, Environment>> envs;
    2426    private boolean drawMultipolygon;
    2527
    2628    private int cacheIdx;
     
    2830    public ElemStyles()
    2931    {
    3032        styleSources = new ArrayList<StyleSource>();
     33        envs = new HashMap<String, HashMap<OsmPrimitive, Environment>>();
    3134    }
    3235
    3336    public void clearCached() {
     
    8386
    8487    private Pair<StyleList, Range> getImpl(OsmPrimitive osm, double scale, NavigatableComponent nc) {
    8588        if (osm instanceof Node)
    86         {
    8789            return generateStyles(osm, scale, null, false);
    88         }
    8990        else if (osm instanceof Way)
    9091        {
    9192            Pair<StyleList, Range> p = generateStyles(osm, scale, null, false);
     
    121122                        Pair<StyleList, Range> mpElemStyles = getStyleCacheWithRange(r, scale, nc);
    122123                        LineElemStyle mpLine = Utils.find(mpElemStyles.a, LineElemStyle.class);
    123124                        if (mpLine != null) {
    124                                 p.a = new StyleList(p.a, mpLine);
    125                                 p.b = Range.cut(p.b, mpElemStyles.b);
    126                                 break;
     125                            p.a = new StyleList(p.a, mpLine);
     126                            p.b = Range.cut(p.b, mpElemStyles.b);
     127                            break;
    127128                        } else if (wayColor == null) {
    128129                            AreaElemStyle mpArea = Utils.find(mpElemStyles.a, AreaElemStyle.class);
    129130                            if (mpArea != null) {
     
    198199        return null;
    199200    }
    200201
     202    public Environment getEnvironment(OsmPrimitive osm, MultiCascade mc, String layer, StyleSource source) {
     203        return (envs.containsKey(layer) && envs.get(layer).containsKey(osm)
     204                ? envs.get(layer).get(osm)
     205                        : new Environment(osm, mc, layer, source)
     206        );
     207    }
     208
    201209    /**
    202210     * @param multipolyOuterWay support for a very old multipolygon tagging style
    203211     * where you add the tags both to the outer and the inner way.
     
    219227        }
    220228
    221229        for (Entry<String, Cascade> e : mc.getLayers()) {
    222             if ("*".equals(e.getKey()))
     230            if ("*".equals(e.getKey())) {
    223231                continue;
     232            }
    224233            env.layer = e.getKey();
    225234            Cascade c = e.getValue();
     235
     236            if (envs.containsKey(env.layer)) {
     237                envs.get(env.layer).put(env.osm, env);
     238            } else {
     239                envs.put(env.layer, new HashMap<OsmPrimitive, Environment>());
     240            }
     241
    226242            if (osm instanceof Way) {
    227243                addIfNotNull(sl, AreaElemStyle.create(c));
    228244                addIfNotNull(sl, LineElemStyle.createLine(env));
  • src/org/openstreetmap/josm/gui/mappaint/LabelCompositionStrategy.java

     
    108108        public String compose(OsmPrimitive primitive) {
    109109            if (defaultLabelTag == null) return null;
    110110            if (primitive == null) return null;
    111             return primitive.get(defaultLabelTag);
     111
     112            String res = new String("");
     113            if (defaultLabelTag.indexOf(' ') >= 0) {
     114                String tags[] = defaultLabelTag.split(" ");
     115                for (String tag : tags) {
     116                    res += (primitive.get(tag)==null) ? tag : primitive.get(tag);
     117                    res += ' ';
     118                }
     119            } else {
     120                res = primitive.get(defaultLabelTag);
     121            }
     122            return res;
    112123        }
    113124
    114125        public String getDefaultLabelTag() {
  • src/org/openstreetmap/josm/gui/mappaint/mapcss/Expression.java

     
    5757        public static class EvalFunctions {
    5858            Environment env;
    5959
     60            private Environment getEnvironment(String key, String layer) {
     61                Environment res = env;
     62
     63                if (layer == null) {
     64                    layer = env.layer;
     65                }
     66
     67                while (key.startsWith("parent.")) {
     68                    if (res != null) {
     69                        res = (Environment) res.mc.getCascade(layer).get("env-parent");
     70
     71                    }
     72                    key = key.replaceFirst("parent[.]", "");
     73                }
     74
     75                return (res==null)?env:res;
     76            }
     77
    6078            public Object eval(Object o) {
    6179                return o;
    6280            }
     
    7290            public Float minus(float... args) {
    7391                if (args.length == 0)
    7492                    return 0f;
    75                 if (args.length == 1) { // unary minus
     93                if (args.length == 1)
    7694                    return -args[0];
    77                 }
    7895                float res = args[0];
    7996                for (int i=1; i<args.length; ++i) {
    8097                    res -= args[i];
     
    134151
    135152            public Object prop(String key, String layer) {
    136153                Cascade c;
     154                Environment e = getEnvironment(key, layer);
    137155                if (layer == null) {
    138                     c = env.mc.getCascade(env.layer);
     156                    c = e.mc.getCascade(e.layer);
    139157                } else {
    140                     c = env.mc.getCascade(layer);
     158                    c = e.mc.getCascade(layer);
    141159                }
    142                 return c.get(key);
     160                return c.get(key.replaceAll("parent[.]", ""));
    143161            }
    144162
    145163            public Boolean is_prop_set(String key) {
     
    148166
    149167            public Boolean is_prop_set(String key, String layer) {
    150168                Cascade c;
     169                Environment e = getEnvironment(key, layer);
    151170                if (layer == null) {
    152171                    // env.layer is null if expression is evaluated
    153172                    // in ExpressionCondition, but MultiCascade.getCascade
    154173                    // handles this
    155                     c = env.mc.getCascade(env.layer);
     174                    c = e.mc.getCascade(e.layer);
    156175                } else {
    157                     c = env.mc.getCascade(layer);
     176                    c = e.mc.getCascade(layer);
    158177                }
    159                 return c.containsKey(key);
     178                return c.containsKey(key.replaceAll("parent[.]", ""));
    160179            }
    161180
    162181            public String get_tag_value(String key) {
    163                 return env.osm.get(key);
     182                return getEnvironment(key, null).osm.get(key.replaceAll("parent[.]", ""));
    164183            }
    165184
    166185            public boolean has_tag_key(String key) {
    167                 return env.osm.hasKey(key);
     186                return getEnvironment(key, null).osm.hasKey(key.replaceAll("parent[.]", ""));
    168187            }
    169188
     189            public String concat(Object... args) {
     190                String res = new String("");
     191                for (Object f : args) {
     192                    res += f.toString();
     193                }
     194                return res;
     195            }
     196
    170197            public boolean not(boolean b) {
    171198                return !b;
    172199            }
     
    212239                } catch (ParseError ex) {
    213240                    return null;
    214241                }
    215                 return m.match(env.osm);
     242                return m.match(getEnvironment(s, null).osm);
    216243            }
    217244
    218245            public String JOSM_pref(String s, String def) {
     
    285312                throw  new RuntimeException(ex);
    286313            }
    287314            for (Method m : allMethods) {
    288                 if (!m.getName().equals(name))
     315                if (!m.getName().equals(name)) {
    289316                    continue;
     317                }
    290318                Class<?>[] expectedParameterTypes = m.getParameterTypes();
    291319                Object[] convertedArgs = new Object[expectedParameterTypes.length];
    292320
     
    303331                    }
    304332                    convertedArgs[0] = arrayArg;
    305333                } else {
    306                     if (args.size() != expectedParameterTypes.length)
     334                    if (args.size() != expectedParameterTypes.length) {
    307335                        continue;
     336                    }
    308337                    for (int i=0; i<args.size(); ++i) {
    309338                        convertedArgs[i] = Cascade.convertTo(args.get(i).evaluate(env), expectedParameterTypes[i]);
    310339                        if (convertedArgs[i] == null)
  • src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSource.java

     
    109109        Environment env = new Environment(n, mc, "default", this);
    110110
    111111        NEXT_RULE:
    112         for (MapCSSRule r : rules) {
    113             for (Selector s : r.selectors) {
    114                 if ((s instanceof GeneralSelector)) {
    115                     GeneralSelector gs = (GeneralSelector) s;
    116                     if (gs.base.equals(type))
    117                      {
    118                         for (Condition cnd : gs.conds) {
    119                             if (!cnd.applies(env))
    120                                 continue NEXT_RULE;
     112            for (MapCSSRule r : rules) {
     113                for (Selector s : r.selectors) {
     114                    if ((s instanceof GeneralSelector)) {
     115                        GeneralSelector gs = (GeneralSelector) s;
     116                        if (gs.base.equals(type))
     117                        {
     118                            for (Condition cnd : gs.conds) {
     119                                if (!cnd.applies(env)) {
     120                                    continue NEXT_RULE;
     121                                }
     122                            }
     123                            for (Instruction i : r.declaration) {
     124                                i.execute(env);
     125                            }
    121126                        }
    122                         for (Instruction i : r.declaration) {
    123                             i.execute(env);
    124                         }
    125127                    }
    126128                }
    127129            }
    128         }
    129130        return mc.getCascade("default");
    130131    }
    131132
     
    139140        Environment env = new Environment(osm, mc, null, this);
    140141        for (MapCSSRule r : rules) {
    141142            for (Selector s : r.selectors) {
     143                String sub = s.getSubpart();
     144                if (sub == null) {
     145                    sub = "default";
     146                }
     147                env.layer = sub;
     148
    142149                if (s.applies(env)) {
    143150                    if (s.getRange().contains(scale)) {
    144151                        mc.range = Range.cut(mc.range, s.getRange());
     
    147154                        continue;
    148155                    }
    149156
    150                     String sub = s.getSubpart();
    151                     if (sub == null) {
    152                         sub = "default";
    153                     }
    154 
    155157                    if (sub.equals("*")) {
    156158                        for (Entry<String, Cascade> entry : mc.getLayers()) {
    157159                            env.layer = entry.getKey();
     
    163165                            }
    164166                        }
    165167                    }
    166                     env.layer = sub;
     168
    167169                    for (Instruction i : r.declaration) {
    168170                        i.execute(env);
    169171                    }
  • src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java

     
    99import org.openstreetmap.josm.data.osm.Relation;
    1010import org.openstreetmap.josm.data.osm.Way;
    1111import org.openstreetmap.josm.gui.mappaint.Environment;
     12import org.openstreetmap.josm.gui.mappaint.MapPaintStyles;
    1213import org.openstreetmap.josm.gui.mappaint.Range;
    1314import org.openstreetmap.josm.tools.Pair;
    1415import org.openstreetmap.josm.tools.Utils;
    1516
    1617public interface Selector {
    17    
     18
    1819    public boolean applies(Environment e);
    1920
    2021    public String getSubpart();
     
    3536            if (!b.applies(e))
    3637                return false;
    3738
    38             Environment e2 = new Environment(null, e.mc, e.layer, e.source);
     39            Environment e2 = null;
    3940            if (child) {
    4041                for (OsmPrimitive osm : e.osm.getReferrers()) {
    41                     e2.osm = osm;
    42                     if (a.applies(e2))
     42                    e2 = MapPaintStyles.getStyles().getEnvironment(osm, e.mc, e.layer, e.source);
     43                    if (a.applies(e2)) {
     44                        e.mc.getOrCreateCascade(e2.layer).putOrClear("env-parent", e2);
    4345                        return true;
     46                    }
    4447                }
    4548            } else {
    4649                if (e.osm instanceof Relation) {
    4750                    for (OsmPrimitive chld : ((Relation) e.osm).getMemberPrimitives()) {
    48                         e2.osm = chld;
     51                        e2 = MapPaintStyles.getStyles().getEnvironment(chld, e.mc, e.layer, e.source);
    4952                        if (a.applies(e2))
    5053                            return true;
    5154                    }
    5255                } else if (e.osm instanceof Way) {
    5356                    for (Node n : ((Way) e.osm).getNodes()) {
    54                         e2.osm = n;
     57                        e2 = MapPaintStyles.getStyles().getEnvironment(n, e.mc, e.layer, e.source);
    5558                        if (a.applies(e2))
    5659                            return true;
    5760                    }