source: josm/trunk/src/org/openstreetmap/josm/gui/mappaint/StyleSource.java@ 3817

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

make turn restriction rendering work again

  • Property svn:eol-style set to native
File size: 9.7 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.mappaint;
3
4import java.util.Collection;
5import java.util.Collections;
6import java.util.HashMap;
7import java.util.Iterator;
8import java.util.LinkedList;
9import java.util.List;
10import java.util.regex.Matcher;
11import java.util.regex.Pattern;
12
13import org.openstreetmap.josm.data.osm.Node;
14import org.openstreetmap.josm.data.osm.OsmPrimitive;
15import org.openstreetmap.josm.data.osm.OsmUtils;
16import org.openstreetmap.josm.data.osm.Way;
17import org.openstreetmap.josm.gui.mappaint.xml.XmlCondition;
18import org.openstreetmap.josm.gui.preferences.SourceEntry;
19
20public class StyleSource extends SourceEntry {
21
22 public final HashMap<String, IconElemStyle> icons = new HashMap<String, IconElemStyle>();
23 public final HashMap<String, LineElemStyle> lines = new HashMap<String, LineElemStyle>();
24 public final HashMap<String, LineElemStyle> modifiers = new HashMap<String, LineElemStyle>();
25 public final HashMap<String, AreaElemStyle> areas = new HashMap<String, AreaElemStyle>();
26 public final LinkedList<IconElemStyle> iconsList = new LinkedList<IconElemStyle>();
27 public final LinkedList<LineElemStyle> linesList = new LinkedList<LineElemStyle>();
28 public final LinkedList<LineElemStyle> modifiersList = new LinkedList<LineElemStyle>();
29 public final LinkedList<AreaElemStyle> areasList = new LinkedList<AreaElemStyle>();
30
31 public boolean hasError = false;
32
33 public StyleSource(String url, String name, String shortdescription) {
34 super(url, name, shortdescription, true);
35 }
36
37 public StyleSource(SourceEntry entry) {
38 super(entry.url, entry.name, entry.shortdescription, entry.active);
39 }
40
41 public IconElemStyle getNode(OsmPrimitive primitive, IconElemStyle icon) {
42 for (String key : primitive.keySet()) {
43 String val = primitive.get(key);
44 IconElemStyle style;
45 if ((style = icons.get("n" + key + "=" + val)) != null) {
46 if (icon == null || style.priority >= icon.priority) {
47 icon = style;
48 }
49 }
50 if ((style = icons.get("b" + key + "=" + OsmUtils.getNamedOsmBoolean(val))) != null) {
51 if (icon == null || style.priority >= icon.priority) {
52 icon = style;
53 }
54 }
55 if ((style = icons.get("x" + key)) != null) {
56 if (icon == null || style.priority >= icon.priority) {
57 icon = style;
58 }
59 }
60 }
61 for (IconElemStyle s : iconsList) {
62 if ((icon == null || s.priority >= icon.priority) && s.check(primitive)) {
63 icon = s;
64 }
65 }
66 return icon;
67 }
68
69 /**
70 * @param closed The primitive is a closed way or we pretend it is closed.
71 * This is useful for multipolygon relations and outer ways of untagged
72 * multipolygon relations.
73 */
74 public ElemStyle get(OsmPrimitive primitive, boolean closed, AreaElemStyle area, LineElemStyle line) {
75 String lineIdx = null;
76 HashMap<String, LineElemStyle> overlayMap = new HashMap<String, LineElemStyle>();
77 for (String key : primitive.keySet()) {
78 String val = primitive.get(key);
79 AreaElemStyle styleArea;
80 LineElemStyle styleLine;
81 String idx = "n" + key + "=" + val;
82 if ((styleArea = areas.get(idx)) != null && (area == null || styleArea.priority >= area.priority) && (closed || !styleArea.closed)) {
83 area = styleArea;
84 }
85 if ((styleLine = lines.get(idx)) != null && (line == null || styleLine.priority >= line.priority)) {
86 line = styleLine;
87 lineIdx = idx;
88 }
89 if ((styleLine = modifiers.get(idx)) != null) {
90 overlayMap.put(idx, styleLine);
91 }
92 idx = "b" + key + "=" + OsmUtils.getNamedOsmBoolean(val);
93 if ((styleArea = areas.get(idx)) != null && (area == null || styleArea.priority >= area.priority) && (closed || !styleArea.closed)) {
94 area = styleArea;
95 }
96 if ((styleLine = lines.get(idx)) != null && (line == null || styleLine.priority >= line.priority)) {
97 line = styleLine;
98 lineIdx = idx;
99 }
100 if ((styleLine = modifiers.get(idx)) != null) {
101 overlayMap.put(idx, styleLine);
102 }
103 idx = "x" + key;
104 if ((styleArea = areas.get(idx)) != null && (area == null || styleArea.priority >= area.priority) && (closed || !styleArea.closed)) {
105 area = styleArea;
106 }
107 if ((styleLine = lines.get(idx)) != null && (line == null || styleLine.priority >= line.priority)) {
108 line = styleLine;
109 lineIdx = idx;
110 }
111 if ((styleLine = modifiers.get(idx)) != null) {
112 overlayMap.put(idx, styleLine);
113 }
114 }
115 for (AreaElemStyle s : areasList) {
116 if ((area == null || s.priority >= area.priority) && (closed || !s.closed) && s.check(primitive)) {
117 area = s;
118 }
119 }
120 for (LineElemStyle s : linesList) {
121 if ((line == null || s.priority >= line.priority) && s.check(primitive)) {
122 line = s;
123 }
124 }
125 for (LineElemStyle s : modifiersList) {
126 if (s.check(primitive)) {
127 overlayMap.put(s.getCode(), s);
128 }
129 }
130 overlayMap.remove(lineIdx); // do not use overlay if linestyle is from the same rule (example: railway=tram)
131 if (!overlayMap.isEmpty() && line != null) {
132 List<LineElemStyle> tmp = new LinkedList<LineElemStyle>();
133 if (line.overlays != null) {
134 tmp.addAll(line.overlays);
135 }
136 tmp.addAll(overlayMap.values());
137 Collections.sort(tmp);
138 line = new LineElemStyle(line, tmp);
139 }
140 if (area != null) {
141 if (line != null) {
142 return new AreaElemStyle(area, line);
143 } else {
144 return area;
145 }
146 }
147 return line;
148 }
149
150 public boolean isArea(OsmPrimitive o) {
151 if (o.hasKeys() && !(o instanceof Node)) {
152 boolean noclosed = o instanceof Way && !((Way) o).isClosed();
153 Iterator<String> iterator = o.keySet().iterator();
154 while (iterator.hasNext()) {
155 String key = iterator.next();
156 String val = o.get(key);
157 AreaElemStyle s = areas.get("n" + key + "=" + val);
158 if (s == null || (s.closed && noclosed)) {
159 s = areas.get("b" + key + "=" + OsmUtils.getNamedOsmBoolean(val));
160 }
161 if (s == null || (s.closed && noclosed)) {
162 s = areas.get("x" + key);
163 }
164 if (s != null && !(s.closed && noclosed)) {
165 return true;
166 }
167 }
168 for (AreaElemStyle s : areasList) {
169 if (!(s.closed && noclosed) && s.check(o)) {
170 return true;
171 }
172 }
173 }
174 return false;
175 }
176
177 public boolean hasAreas() {
178 return areas.size() > 0;
179 }
180
181 public void add(XmlCondition c, Collection<XmlCondition> conditions, LineElemStyle style) {
182 if(conditions != null)
183 {
184 style.conditions = conditions;
185 linesList.add(style);
186 }
187 else {
188 String key = c.getKey();
189 style.code = key;
190 lines.put(key, style);
191 }
192 }
193
194 public void addModifier(XmlCondition c, Collection<XmlCondition> conditions, LineElemStyle style) {
195 if(conditions != null)
196 {
197 style.conditions = conditions;
198 modifiersList.add(style);
199 }
200 else
201 {
202 String key = c.getKey();
203 style.code = key;
204 modifiers.put(key, style);
205 }
206 }
207
208 public void add(XmlCondition c, Collection<XmlCondition> conditions, AreaElemStyle style) {
209 if(conditions != null)
210 {
211 style.conditions = conditions;
212 areasList.add(style);
213 }
214 else
215 {
216 String key = c.getKey();
217 style.code = key;
218 areas.put(key, style);
219 }
220 }
221
222 public void add(XmlCondition c, Collection<XmlCondition> conditions, IconElemStyle style) {
223 if(conditions != null)
224 {
225 style.conditions = conditions;
226 iconsList.add(style);
227 }
228 else
229 {
230 String key = c.getKey();
231 style.code = key;
232 icons.put(key, style);
233 }
234 }
235
236 /**
237 * the name / identifier that should be used to save custom color values
238 * and similar stuff to the preference file
239 * @return the identifier; never null. Usually the result is "standard"
240 */
241 public String getPrefName() {
242 return name == null ? "standard" : name;
243 }
244
245 /**
246 * String to show in menus and error messages.
247 * @return Usually the shortdescription, but can be the file name
248 * if no shortdescription is available.
249 */
250 public String getDisplayString() {
251 if (shortdescription != null)
252 return shortdescription;
253 /**
254 * extract file part from url, e.g.:
255 * http://www.test.com/file.xml?format=text --> file.xml
256 */
257 Pattern p = Pattern.compile("([^/\\\\]*?)([?].*)?$");
258 Matcher m = p.matcher(url);
259 if (m.find()) {
260 return m.group(1);
261 } else {
262 System.err.println("Warning: Unexpected URL format: "+url);
263 return url;
264 }
265 }
266}
Note: See TracBrowser for help on using the repository browser.