- Timestamp:
- 2013-02-11T18:19:49+01:00 (12 years ago)
- Location:
- trunk/src/org/openstreetmap/josm
- Files:
-
- 2 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java
r5590 r5705 308 308 private Color highlightColorTransparent; 309 309 310 private static int FLAG_NORMAL = 0;311 private static int FLAG_DISABLED = 1;312 private static int FLAG_MEMBER_OF_SELECTED = 2;313 private static int FLAG_SELECTED = 4;310 private static final int FLAG_NORMAL = 0; 311 private static final int FLAG_DISABLED = 1; 312 private static final int FLAG_MEMBER_OF_SELECTED = 2; 313 private static final int FLAG_SELECTED = 4; 314 314 315 315 private static final double PHI = Math.toRadians(20); … … 366 366 } 367 367 368 private void collectRelationStyles(DataSet data, StyleCollector sc, BBox bbox) {369 for (Relation r: data.searchRelations(bbox)) {370 if (r.isDrawable()) {371 if (r.isDisabled()) {372 sc.add(r, FLAG_DISABLED);373 } else if (data.isSelected(r)) {374 sc.add(r, FLAG_SELECTED);375 } else {376 sc.add(r, FLAG_NORMAL);377 }378 }379 }380 }381 382 368 private void collectWayStyles(DataSet data, StyleCollector sc, BBox bbox) { 383 369 for (final Way w : data.searchWays(bbox)) { … … 391 377 } else { 392 378 sc.add(w, FLAG_NORMAL); 379 } 380 } 381 } 382 } 383 384 private void collectRelationStyles(DataSet data, StyleCollector sc, BBox bbox) { 385 for (Relation r: data.searchRelations(bbox)) { 386 if (r.isDrawable()) { 387 if (r.isDisabled()) { 388 sc.add(r, FLAG_DISABLED); 389 } else if (data.isSelected(r)) { 390 sc.add(r, FLAG_SELECTED); 391 } else { 392 sc.add(r, FLAG_NORMAL); 393 393 } 394 394 } -
trunk/src/org/openstreetmap/josm/gui/mappaint/Environment.java
r4069 r5705 8 8 import org.openstreetmap.josm.tools.CheckParameterUtil; 9 9 10 /** 11 * Environment is a data object to provide access to various "global" parameters. 12 * It is used during processing of MapCSS rules and for the generation of 13 * style elements. 14 */ 10 15 public class Environment { 11 16 -
trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Expression.java
r5701 r5705 2 2 package org.openstreetmap.josm.gui.mappaint.mapcss; 3 3 4 import static org.openstreetmap.josm.tools.Utils.equal;4 import org.openstreetmap.josm.gui.mappaint.Environment; 5 5 6 import java.awt.Color; 7 import java.lang.reflect.Array; 8 import java.lang.reflect.InvocationTargetException; 9 import java.lang.reflect.Method; 10 import java.util.ArrayList; 11 import java.util.Arrays; 12 import java.util.List; 13 import java.util.regex.Matcher; 14 import java.util.regex.Pattern; 15 16 import org.openstreetmap.josm.Main; 17 import org.openstreetmap.josm.actions.search.SearchCompiler; 18 import org.openstreetmap.josm.actions.search.SearchCompiler.Match; 19 import org.openstreetmap.josm.actions.search.SearchCompiler.ParseError; 20 import org.openstreetmap.josm.data.osm.OsmPrimitive; 21 import org.openstreetmap.josm.gui.mappaint.Cascade; 22 import org.openstreetmap.josm.gui.mappaint.Environment; 23 import org.openstreetmap.josm.tools.CheckParameterUtil; 24 import org.openstreetmap.josm.tools.ColorHelper; 25 import org.openstreetmap.josm.tools.Utils; 26 6 /** 7 * A MapCSS Expression. 8 * 9 * Can be evaluated in a certain {@link Environment}. Usually takes 10 * parameters, that are also Expressions and have to be evaluated first. 11 */ 27 12 public interface Expression { 28 public Object evaluate(Environment env); 29 30 public static class LiteralExpression implements Expression { 31 Object literal; 32 33 public LiteralExpression(Object literal) { 34 CheckParameterUtil.ensureParameterNotNull(literal); 35 this.literal = literal; 36 } 37 38 @Override 39 public Object evaluate(Environment env) { 40 return literal; 41 } 42 43 @Override 44 public String toString() { 45 if (literal instanceof float[]) 46 return Arrays.toString((float[]) literal); 47 return "<"+literal.toString()+">"; 48 } 49 } 50 51 public static class FunctionExpression implements Expression { 52 String name; 53 List<Expression> args; 54 55 public FunctionExpression(String name, List<Expression> args) { 56 this.name = name; 57 this.args = args; 58 } 59 60 public static class EvalFunctions { 61 Environment env; 62 63 public Object eval(Object o) { 64 return o; 65 } 66 67 public static float plus(float... args) { 68 float res = 0; 69 for (float f : args) { 70 res += f; 71 } 72 return res; 73 } 74 75 public Float minus(float... args) { 76 if (args.length == 0) 77 return 0f; 78 if (args.length == 1) 79 return -args[0]; 80 float res = args[0]; 81 for (int i=1; i<args.length; ++i) { 82 res -= args[i]; 83 } 84 return res; 85 } 86 87 public static float times(float... args) { 88 float res = 1; 89 for (float f : args) { 90 res *= f; 91 } 92 return res; 93 } 94 95 public Float divided_by(float... args) { 96 if (args.length == 0) 97 return 1f; 98 float res = args[0]; 99 for (int i=1; i<args.length; ++i) { 100 if (args[i] == 0f) 101 return null; 102 res /= args[i]; 103 } 104 return res; 105 } 106 107 public static List list(Object... args) { 108 return Arrays.asList(args); 109 } 110 111 public static Object get(List objects, float index) { 112 int idx = Math.round(index); 113 if (idx >=0 && idx < objects.size()) 114 return objects.get(idx); 115 return null; 116 } 117 118 public List split(String sep, String toSplit) { 119 return Arrays.asList(toSplit.split(Pattern.quote(sep))); 120 } 121 122 public Color rgb(float r, float g, float b) { 123 Color c = null; 124 try { 125 c = new Color(r, g, b); 126 } catch (IllegalArgumentException e) { 127 return null; 128 } 129 return c; 130 } 131 132 public Color html2color(String html) { 133 return ColorHelper.html2color(html); 134 } 135 136 public String color2html(Color c) { 137 return ColorHelper.color2html(c); 138 } 139 140 public float red(Color c) { 141 return Utils.color_int2float(c.getRed()); 142 } 143 144 public float green(Color c) { 145 return Utils.color_int2float(c.getGreen()); 146 } 147 148 public float blue(Color c) { 149 return Utils.color_int2float(c.getBlue()); 150 } 151 152 public String concat(Object... args) { 153 StringBuilder res = new StringBuilder(); 154 for (Object f : args) { 155 res.append(f.toString()); 156 } 157 return res.toString(); 158 } 159 160 public Object prop(String key) { 161 return prop(key, null); 162 } 163 164 public Object prop(String key, String layer) { 165 Cascade c; 166 if (layer == null) { 167 c = env.mc.getCascade(env.layer); 168 } else { 169 c = env.mc.getCascade(layer); 170 } 171 return c.get(key); 172 } 173 174 public Boolean is_prop_set(String key) { 175 return is_prop_set(key, null); 176 } 177 178 public Boolean is_prop_set(String key, String layer) { 179 Cascade c; 180 if (layer == null) { 181 // env.layer is null if expression is evaluated 182 // in ExpressionCondition, but MultiCascade.getCascade 183 // handles this 184 c = env.mc.getCascade(env.layer); 185 } else { 186 c = env.mc.getCascade(layer); 187 } 188 return c.containsKey(key); 189 } 190 191 public String tag(String key) { 192 return env.osm.get(key); 193 } 194 195 public String parent_tag(String key) { 196 if (env.parent == null) { 197 // we don't have a matched parent, so just search all referrers 198 for (OsmPrimitive parent : env.osm.getReferrers()) { 199 String value = parent.get(key); 200 if (value != null) 201 return value; 202 } 203 return null; 204 } 205 return env.parent.get(key); 206 } 207 208 public boolean has_tag_key(String key) { 209 return env.osm.hasKey(key); 210 } 211 212 public Float index() { 213 if (env.index == null) 214 return null; 215 return new Float(env.index + 1); 216 } 217 218 public String role() { 219 return env.getRole(); 220 } 221 222 public boolean not(boolean b) { 223 return !b; 224 } 225 226 public boolean greater_equal(float a, float b) { 227 return a >= b; 228 } 229 230 public boolean less_equal(float a, float b) { 231 return a <= b; 232 } 233 234 public boolean greater(float a, float b) { 235 return a > b; 236 } 237 238 public boolean less(float a, float b) { 239 return a < b; 240 } 241 242 public int length(String s) { 243 return s.length(); 244 } 245 246 public int length(List l) { 247 return l.size(); 248 } 249 250 @SuppressWarnings("unchecked") 251 public boolean equal(Object a, Object b) { 252 // make sure the casts are done in a meaningful way, so 253 // the 2 objects really can be considered equal 254 for (Class klass : new Class[] { 255 Float.class, Boolean.class, Color.class, float[].class, String.class }) { 256 Object a2 = Cascade.convertTo(a, klass); 257 Object b2 = Cascade.convertTo(b, klass); 258 if (a2 != null && b2 != null && a2.equals(b2)) 259 return true; 260 } 261 return false; 262 } 263 264 public Boolean JOSM_search(String s) { 265 Match m; 266 try { 267 m = SearchCompiler.compile(s, false, false); 268 } catch (ParseError ex) { 269 return null; 270 } 271 return m.match(env.osm); 272 } 273 274 public String JOSM_pref(String s, String def) { 275 String res = Main.pref.get(s, null); 276 return res != null ? res : def; 277 } 278 279 public Color JOSM_pref_color(String s, Color def) { 280 Color res = Main.pref.getColor(s, null); 281 return res != null ? res : def; 282 } 283 284 public static boolean regexp_test(String pattern, String target) { 285 return Pattern.matches(pattern, target); 286 } 287 288 public static boolean regexp_test(String pattern, String target, String flags) { 289 int f = 0; 290 if (flags.contains("i")) { 291 f |= Pattern.CASE_INSENSITIVE; 292 } 293 if (flags.contains("s")) { 294 f |= Pattern.DOTALL; 295 } 296 if (flags.contains("m")) { 297 f |= Pattern.MULTILINE; 298 } 299 return Pattern.compile(pattern, f).matcher(target).matches(); 300 } 301 302 public static List regexp_match(String pattern, String target, String flags) { 303 int f = 0; 304 if (flags.contains("i")) { 305 f |= Pattern.CASE_INSENSITIVE; 306 } 307 if (flags.contains("s")) { 308 f |= Pattern.DOTALL; 309 } 310 if (flags.contains("m")) { 311 f |= Pattern.MULTILINE; 312 } 313 Matcher m = Pattern.compile(pattern, f).matcher(target); 314 if (m.matches()) { 315 List result = new ArrayList(m.groupCount() + 1); 316 for (int i=0; i<=m.groupCount(); i++) { 317 result.add(m.group(i)); 318 } 319 return result; 320 } else 321 return null; 322 } 323 324 public static List regexp_match(String pattern, String target) { 325 Matcher m = Pattern.compile(pattern).matcher(target); 326 if (m.matches()) { 327 List result = new ArrayList(m.groupCount() + 1); 328 for (int i=0; i<=m.groupCount(); i++) { 329 result.add(m.group(i)); 330 } 331 return result; 332 } else 333 return null; 334 } 335 336 public long osm_id() { 337 return env.osm.getUniqueId(); 338 } 339 } 340 341 @Override 342 public Object evaluate(Environment env) { 343 if (equal(name, "cond")) { // this needs special handling since only one argument should be evaluated 344 if (args.size() != 3) 345 return null; 346 Boolean b = Cascade.convertTo(args.get(0).evaluate(env), boolean.class); 347 if (b == null) 348 return null; 349 return args.get(b ? 1 : 2).evaluate(env); 350 } 351 if (equal(name, "and")) { 352 for (Expression arg : args) { 353 Boolean b = Cascade.convertTo(arg.evaluate(env), boolean.class); 354 if (b == null || !b) 355 return false; 356 } 357 return true; 358 } 359 if (equal(name, "or")) { 360 for (Expression arg : args) { 361 Boolean b = Cascade.convertTo(arg.evaluate(env), boolean.class); 362 if (b != null && b) 363 return true; 364 } 365 return false; 366 } 367 EvalFunctions fn = new EvalFunctions(); 368 fn.env = env; 369 Method[] customMethods = EvalFunctions.class.getDeclaredMethods(); 370 List<Method> allMethods = new ArrayList<Method>(); 371 allMethods.addAll(Arrays.asList(customMethods)); 372 try { 373 allMethods.add(Math.class.getMethod("abs", float.class)); 374 allMethods.add(Math.class.getMethod("acos", double.class)); 375 allMethods.add(Math.class.getMethod("asin", double.class)); 376 allMethods.add(Math.class.getMethod("atan", double.class)); 377 allMethods.add(Math.class.getMethod("atan2", double.class, double.class)); 378 allMethods.add(Math.class.getMethod("ceil", double.class)); 379 allMethods.add(Math.class.getMethod("cos", double.class)); 380 allMethods.add(Math.class.getMethod("cosh", double.class)); 381 allMethods.add(Math.class.getMethod("exp", double.class)); 382 allMethods.add(Math.class.getMethod("floor", double.class)); 383 allMethods.add(Math.class.getMethod("log", double.class)); 384 allMethods.add(Math.class.getMethod("max", float.class, float.class)); 385 allMethods.add(Math.class.getMethod("min", float.class, float.class)); 386 allMethods.add(Math.class.getMethod("random")); 387 allMethods.add(Math.class.getMethod("round", float.class)); 388 allMethods.add(Math.class.getMethod("signum", double.class)); 389 allMethods.add(Math.class.getMethod("sin", double.class)); 390 allMethods.add(Math.class.getMethod("sinh", double.class)); 391 allMethods.add(Math.class.getMethod("sqrt", double.class)); 392 allMethods.add(Math.class.getMethod("tan", double.class)); 393 allMethods.add(Math.class.getMethod("tanh", double.class)); 394 } catch (NoSuchMethodException ex) { 395 throw new RuntimeException(ex); 396 } catch (SecurityException ex) { 397 throw new RuntimeException(ex); 398 } 399 for (Method m : allMethods) { 400 if (!m.getName().equals(name)) { 401 continue; 402 } 403 Class<?>[] expectedParameterTypes = m.getParameterTypes(); 404 Object[] convertedArgs = new Object[expectedParameterTypes.length]; 405 406 if (expectedParameterTypes.length == 1 && expectedParameterTypes[0].isArray()) 407 { 408 Class<?> arrayComponentType = expectedParameterTypes[0].getComponentType(); 409 Object arrayArg = Array.newInstance(arrayComponentType, args.size()); 410 for (int i=0; i<args.size(); ++i) 411 { 412 Object o = Cascade.convertTo(args.get(i).evaluate(env), arrayComponentType); 413 if (o == null) 414 return null; 415 Array.set(arrayArg, i, o); 416 } 417 convertedArgs[0] = arrayArg; 418 } else { 419 if (args.size() != expectedParameterTypes.length) { 420 continue; 421 } 422 for (int i=0; i<args.size(); ++i) { 423 convertedArgs[i] = Cascade.convertTo(args.get(i).evaluate(env), expectedParameterTypes[i]); 424 if (convertedArgs[i] == null) 425 return null; 426 } 427 } 428 Object result = null; 429 try { 430 result = m.invoke(fn, convertedArgs); 431 } catch (IllegalAccessException ex) { 432 throw new RuntimeException(ex); 433 } catch (IllegalArgumentException ex) { 434 throw new RuntimeException(ex); 435 } catch (InvocationTargetException ex) { 436 System.err.println(ex); 437 return null; 438 } 439 return result; 440 } 441 return null; 442 } 443 444 @Override 445 public String toString() { 446 return name + "(" + Utils.join(", ", args) + ")"; 447 } 448 449 } 13 /** 14 * Evaluate this expression. 15 * @param env The environment 16 * @return the result of the evaluation, can be a {@link java.util.List}, String or any 17 * primitive type or wrapper classes of a primitive type. 18 */ 19 Object evaluate(Environment env); 450 20 } -
trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Instruction.java
r5342 r5705 34 34 public AssignmentInstruction(String key, Object val) { 35 35 this.key = key; 36 if (val instanceof Expression.LiteralExpression) {37 Object litValue = (( Expression.LiteralExpression) val).evaluate(null);36 if (val instanceof LiteralExpression) { 37 Object litValue = ((LiteralExpression) val).evaluate(null); 38 38 if (key.equals(TEXT)) { 39 39 /* Special case for declaration 'text: ...' -
trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParser.jj
r5620 r5705 19 19 import org.openstreetmap.josm.gui.mappaint.mapcss.MapCSSStyleSource; 20 20 import org.openstreetmap.josm.gui.mappaint.mapcss.Selector; 21 import org.openstreetmap.josm.gui.mappaint.mapcss.Expression .FunctionExpression;22 import org.openstreetmap.josm.gui.mappaint.mapcss. Expression.LiteralExpression;21 import org.openstreetmap.josm.gui.mappaint.mapcss.ExpressionFactory; 22 import org.openstreetmap.josm.gui.mappaint.mapcss.LiteralExpression; 23 23 import org.openstreetmap.josm.gui.mappaint.mapcss.MapCSSException; 24 24 import org.openstreetmap.josm.gui.mappaint.mapcss.Selector.ChildOrParentSelector; … … 502 502 if (op == null) 503 503 return args.get(0); 504 return newFunctionExpression(op, args);504 return ExpressionFactory.createFunctionExpression(op, args); 505 505 } 506 506 } … … 509 509 { 510 510 Expression nested; 511 FunctionExpression fn;511 Expression fn; 512 512 Object lit; 513 513 } … … 521 521 } 522 522 523 FunctionExpression function() :523 Expression function() : 524 524 { 525 525 Token tmp; … … 536 536 )? 537 537 <RPAR> 538 { return newFunctionExpression(name, args); }538 { return ExpressionFactory.createFunctionExpression(name, args); } 539 539 } 540 540
Note:
See TracChangeset
for help on using the changeset viewer.