source: josm/trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSource.java@ 3848

Last change on this file since 3848 was 3848, checked in by bastiK, 13 years ago

Experimental mapcss support. All *.java files in the gui/mappaint/mapcss/parser folder are generated from the javacc source file MapCSSParser.jj in the same folder. The generated code sums up to 2700 lines, there is no further build dependency.

  • Property svn:eol-style set to native
File size: 5.4 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.mappaint.mapcss;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.io.IOException;
7import java.io.InputStream;
8import java.util.ArrayList;
9import java.util.List;
10import java.util.Map.Entry;
11
12import org.openstreetmap.josm.data.osm.Node;
13import org.openstreetmap.josm.data.osm.OsmPrimitive;
14import org.openstreetmap.josm.gui.mappaint.Cascade;
15import org.openstreetmap.josm.gui.mappaint.MultiCascade;
16import org.openstreetmap.josm.gui.mappaint.Range;
17import org.openstreetmap.josm.gui.mappaint.StyleSource;
18import org.openstreetmap.josm.gui.mappaint.mapcss.parser.MapCSSParser;
19import org.openstreetmap.josm.gui.mappaint.mapcss.parser.ParseException;
20import org.openstreetmap.josm.gui.mappaint.mapcss.parser.TokenMgrError;
21import org.openstreetmap.josm.gui.preferences.SourceEntry;
22import org.openstreetmap.josm.io.MirroredInputStream;
23import org.openstreetmap.josm.tools.LanguageInfo;
24import org.openstreetmap.josm.tools.Utils;
25
26public class MapCSSStyleSource extends StyleSource {
27
28 final public List<MapCSSRule> rules;
29
30 public MapCSSStyleSource(String url, String name, String shortdescription) {
31 super(url, name, shortdescription);
32 rules = new ArrayList<MapCSSRule>();
33 }
34
35 public MapCSSStyleSource(SourceEntry entry) {
36 super(entry);
37 rules = new ArrayList<MapCSSRule>();
38 }
39
40 @Override
41 public void loadStyleSource() {
42 rules.clear();
43 try {
44 MirroredInputStream in = new MirroredInputStream(url);
45 InputStream zip = in.getZipEntry("mapcss", "style");
46 InputStream input;
47 if (zip != null) {
48 input = zip;
49 zipIcons = in.getFile();
50 } else {
51 input = in;
52 zipIcons = null;
53 }
54 MapCSSParser parser = new MapCSSParser(input, "UTF-8");
55 parser.sheet(this);
56 loadMeta();
57 } catch(IOException e) {
58 System.err.println(tr("Warning: failed to load Mappaint styles from ''{0}''. Exception was: {1}", url, e.toString()));
59 e.printStackTrace();
60 hasError = true;
61 } catch (TokenMgrError e) {
62 System.err.println(tr("Warning: failed to parse Mappaint styles from ''{0}''. Error was: {1}", url, e.getMessage()));
63 e.printStackTrace();
64 hasError = true;
65 } catch (ParseException e) {
66 System.err.println(tr("Warning: failed to parse Mappaint styles from ''{0}''. Error was: {1}", url, e.getMessage()));
67 e.printStackTrace();
68 hasError = true;
69 }
70 }
71
72 /**
73 * load meta info from a selector "meta"
74 */
75 private void loadMeta() {
76 MultiCascade mc = new MultiCascade();
77 Node n = new Node();
78 String code = LanguageInfo.getJOSMLocaleCode();
79 n.put("lang", code);
80 // create a fake environment to read the meta data block
81 Environment env = new Environment(n, mc, "default");
82
83 NEXT_RULE:
84 for (MapCSSRule r : rules) {
85 for (Selector s : r.selectors) {
86 if (s.base.equals("meta")) {
87 for (Condition cnd : s.conds) {
88 if (!cnd.applies(n))
89 continue NEXT_RULE;
90 }
91 for (Instruction i : r.declaration) {
92 i.execute(env);
93 }
94 }
95 }
96 }
97 Cascade c = mc.getCascade("default");
98 String sd = c.get("title", null, String.class);
99 if (sd != null) {
100 this.shortdescription = sd;
101 }
102 }
103
104 @Override
105 public void apply(MultiCascade mc, OsmPrimitive osm, double scale, OsmPrimitive multipolyOuterWay, boolean pretendWayIsClosed) {
106 for (MapCSSRule r : rules) {
107 for (Selector s : r.selectors) {
108 if (s.applies(osm)) {
109 if (s.range.contains(scale)) {
110 mc.range = Range.cut(mc.range, s.range);
111 } else {
112 mc.range = mc.range.reduceAround(scale, s.range);
113 continue;
114 }
115
116 String sub = s.subpart;
117 if (sub == null) {
118 sub = "default";
119 }
120
121 Cascade c = mc.get(sub);
122 if (c == null) {
123 if (mc.containsKey("*")) {
124 c = mc.get("*").clone();
125 } else {
126 c = new Cascade();
127 }
128 mc.put(sub, c);
129 }
130
131 if (sub.equals("*")) {
132 for (Entry<String, Cascade> entry : mc.entrySet()) {
133 Environment env = new Environment(osm, mc, entry.getKey());
134 for (Instruction i : r.declaration) {
135 i.execute(env);
136 }
137 }
138 } else {
139 Environment env = new Environment(osm, mc, sub);
140 for (Instruction i : r.declaration) {
141 i.execute(env);
142 }
143 }
144 }
145 }
146 }
147 }
148
149 @Override
150 public String toString() {
151 return Utils.join("\n", rules);
152 }
153}
Note: See TracBrowser for help on using the repository browser.