Ticket #6129: mapcss-parent-props-in-descendant-selectors.patch
File mapcss-parent-props-in-descendant-selectors.patch, 14.3 KB (added by , 13 years ago) |
---|
-
src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java
5 5 import java.util.ArrayList; 6 6 import java.util.Collection; 7 7 import java.util.Collections; 8 import java.util.HashMap; 8 9 import java.util.Iterator; 9 10 import java.util.List; 10 11 import java.util.Map.Entry; … … 21 22 22 23 public class ElemStyles { 23 24 private List<StyleSource> styleSources; 25 private HashMap<String, HashMap<OsmPrimitive, Environment>> envs; 24 26 private boolean drawMultipolygon; 25 27 26 28 private int cacheIdx; … … 28 30 public ElemStyles() 29 31 { 30 32 styleSources = new ArrayList<StyleSource>(); 33 envs = new HashMap<String, HashMap<OsmPrimitive, Environment>>(); 31 34 } 32 35 33 36 public void clearCached() { … … 83 86 84 87 private Pair<StyleList, Range> getImpl(OsmPrimitive osm, double scale, NavigatableComponent nc) { 85 88 if (osm instanceof Node) 86 {87 89 return generateStyles(osm, scale, null, false); 88 }89 90 else if (osm instanceof Way) 90 91 { 91 92 Pair<StyleList, Range> p = generateStyles(osm, scale, null, false); … … 121 122 Pair<StyleList, Range> mpElemStyles = getStyleCacheWithRange(r, scale, nc); 122 123 LineElemStyle mpLine = Utils.find(mpElemStyles.a, LineElemStyle.class); 123 124 if (mpLine != null) { 124 125 126 125 p.a = new StyleList(p.a, mpLine); 126 p.b = Range.cut(p.b, mpElemStyles.b); 127 break; 127 128 } else if (wayColor == null) { 128 129 AreaElemStyle mpArea = Utils.find(mpElemStyles.a, AreaElemStyle.class); 129 130 if (mpArea != null) { … … 198 199 return null; 199 200 } 200 201 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 201 209 /** 202 210 * @param multipolyOuterWay support for a very old multipolygon tagging style 203 211 * where you add the tags both to the outer and the inner way. … … 219 227 } 220 228 221 229 for (Entry<String, Cascade> e : mc.getLayers()) { 222 if ("*".equals(e.getKey())) 230 if ("*".equals(e.getKey())) { 223 231 continue; 232 } 224 233 env.layer = e.getKey(); 225 234 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 226 242 if (osm instanceof Way) { 227 243 addIfNotNull(sl, AreaElemStyle.create(c)); 228 244 addIfNotNull(sl, LineElemStyle.createLine(env)); -
src/org/openstreetmap/josm/gui/mappaint/LabelCompositionStrategy.java
108 108 public String compose(OsmPrimitive primitive) { 109 109 if (defaultLabelTag == null) return null; 110 110 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; 112 123 } 113 124 114 125 public String getDefaultLabelTag() { -
src/org/openstreetmap/josm/gui/mappaint/mapcss/Expression.java
57 57 public static class EvalFunctions { 58 58 Environment env; 59 59 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 60 78 public Object eval(Object o) { 61 79 return o; 62 80 } … … 72 90 public Float minus(float... args) { 73 91 if (args.length == 0) 74 92 return 0f; 75 if (args.length == 1) { // unary minus93 if (args.length == 1) 76 94 return -args[0]; 77 }78 95 float res = args[0]; 79 96 for (int i=1; i<args.length; ++i) { 80 97 res -= args[i]; … … 134 151 135 152 public Object prop(String key, String layer) { 136 153 Cascade c; 154 Environment e = getEnvironment(key, layer); 137 155 if (layer == null) { 138 c = e nv.mc.getCascade(env.layer);156 c = e.mc.getCascade(e.layer); 139 157 } else { 140 c = e nv.mc.getCascade(layer);158 c = e.mc.getCascade(layer); 141 159 } 142 return c.get(key );160 return c.get(key.replaceAll("parent[.]", "")); 143 161 } 144 162 145 163 public Boolean is_prop_set(String key) { … … 148 166 149 167 public Boolean is_prop_set(String key, String layer) { 150 168 Cascade c; 169 Environment e = getEnvironment(key, layer); 151 170 if (layer == null) { 152 171 // env.layer is null if expression is evaluated 153 172 // in ExpressionCondition, but MultiCascade.getCascade 154 173 // handles this 155 c = e nv.mc.getCascade(env.layer);174 c = e.mc.getCascade(e.layer); 156 175 } else { 157 c = e nv.mc.getCascade(layer);176 c = e.mc.getCascade(layer); 158 177 } 159 return c.containsKey(key );178 return c.containsKey(key.replaceAll("parent[.]", "")); 160 179 } 161 180 162 181 public String get_tag_value(String key) { 163 return env.osm.get(key);182 return getEnvironment(key, null).osm.get(key.replaceAll("parent[.]", "")); 164 183 } 165 184 166 185 public boolean has_tag_key(String key) { 167 return env.osm.hasKey(key);186 return getEnvironment(key, null).osm.hasKey(key.replaceAll("parent[.]", "")); 168 187 } 169 188 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 170 197 public boolean not(boolean b) { 171 198 return !b; 172 199 } … … 212 239 } catch (ParseError ex) { 213 240 return null; 214 241 } 215 return m.match( env.osm);242 return m.match(getEnvironment(s, null).osm); 216 243 } 217 244 218 245 public String JOSM_pref(String s, String def) { … … 285 312 throw new RuntimeException(ex); 286 313 } 287 314 for (Method m : allMethods) { 288 if (!m.getName().equals(name)) 315 if (!m.getName().equals(name)) { 289 316 continue; 317 } 290 318 Class<?>[] expectedParameterTypes = m.getParameterTypes(); 291 319 Object[] convertedArgs = new Object[expectedParameterTypes.length]; 292 320 … … 303 331 } 304 332 convertedArgs[0] = arrayArg; 305 333 } else { 306 if (args.size() != expectedParameterTypes.length) 334 if (args.size() != expectedParameterTypes.length) { 307 335 continue; 336 } 308 337 for (int i=0; i<args.size(); ++i) { 309 338 convertedArgs[i] = Cascade.convertTo(args.get(i).evaluate(env), expectedParameterTypes[i]); 310 339 if (convertedArgs[i] == null) -
src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSource.java
109 109 Environment env = new Environment(n, mc, "default", this); 110 110 111 111 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 } 121 126 } 122 for (Instruction i : r.declaration) {123 i.execute(env);124 }125 127 } 126 128 } 127 129 } 128 }129 130 return mc.getCascade("default"); 130 131 } 131 132 … … 139 140 Environment env = new Environment(osm, mc, null, this); 140 141 for (MapCSSRule r : rules) { 141 142 for (Selector s : r.selectors) { 143 String sub = s.getSubpart(); 144 if (sub == null) { 145 sub = "default"; 146 } 147 env.layer = sub; 148 142 149 if (s.applies(env)) { 143 150 if (s.getRange().contains(scale)) { 144 151 mc.range = Range.cut(mc.range, s.getRange()); … … 147 154 continue; 148 155 } 149 156 150 String sub = s.getSubpart();151 if (sub == null) {152 sub = "default";153 }154 155 157 if (sub.equals("*")) { 156 158 for (Entry<String, Cascade> entry : mc.getLayers()) { 157 159 env.layer = entry.getKey(); … … 163 165 } 164 166 } 165 167 } 166 env.layer = sub; 168 167 169 for (Instruction i : r.declaration) { 168 170 i.execute(env); 169 171 } -
src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java
9 9 import org.openstreetmap.josm.data.osm.Relation; 10 10 import org.openstreetmap.josm.data.osm.Way; 11 11 import org.openstreetmap.josm.gui.mappaint.Environment; 12 import org.openstreetmap.josm.gui.mappaint.MapPaintStyles; 12 13 import org.openstreetmap.josm.gui.mappaint.Range; 13 14 import org.openstreetmap.josm.tools.Pair; 14 15 import org.openstreetmap.josm.tools.Utils; 15 16 16 17 public interface Selector { 17 18 18 19 public boolean applies(Environment e); 19 20 20 21 public String getSubpart(); … … 35 36 if (!b.applies(e)) 36 37 return false; 37 38 38 Environment e2 = n ew Environment(null, e.mc, e.layer, e.source);39 Environment e2 = null; 39 40 if (child) { 40 41 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); 43 45 return true; 46 } 44 47 } 45 48 } else { 46 49 if (e.osm instanceof Relation) { 47 50 for (OsmPrimitive chld : ((Relation) e.osm).getMemberPrimitives()) { 48 e2 .osm = chld;51 e2 = MapPaintStyles.getStyles().getEnvironment(chld, e.mc, e.layer, e.source); 49 52 if (a.applies(e2)) 50 53 return true; 51 54 } 52 55 } else if (e.osm instanceof Way) { 53 56 for (Node n : ((Way) e.osm).getNodes()) { 54 e2 .osm = n;57 e2 = MapPaintStyles.getStyles().getEnvironment(n, e.mc, e.layer, e.source); 55 58 if (a.applies(e2)) 56 59 return true; 57 60 }