source: josm/trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleIndex.java@ 16184

Last change on this file since 16184 was 16172, checked in by simon04, 4 years ago

Fix JavaDoc warnings

File size: 6.2 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.text.MessageFormat;
7import java.util.Collections;
8import java.util.Iterator;
9import java.util.Map;
10import java.util.Set;
11import java.util.stream.Collectors;
12import java.util.stream.Stream;
13
14import org.openstreetmap.josm.data.osm.INode;
15import org.openstreetmap.josm.data.osm.IPrimitive;
16import org.openstreetmap.josm.data.osm.IRelation;
17import org.openstreetmap.josm.data.osm.IWay;
18import org.openstreetmap.josm.data.osm.OsmUtils;
19import org.openstreetmap.josm.gui.mappaint.mapcss.MapCSSStyleSource.MapCSSRuleIndex;
20import org.openstreetmap.josm.tools.JosmRuntimeException;
21import org.openstreetmap.josm.tools.Logging;
22
23/**
24 * Store indexes of {@link MapCSSRule}s using {@link MapCSSRuleIndex} differentiated by {@linkplain Selector#getBase() base}
25 */
26public final class MapCSSStyleIndex {
27
28 /**
29 * Rules for nodes
30 */
31 final MapCSSRuleIndex nodeRules = new MapCSSRuleIndex();
32 /**
33 * Rules for ways without tag area=no
34 */
35 final MapCSSRuleIndex wayRules = new MapCSSRuleIndex();
36 /**
37 * Rules for ways with tag area=no
38 */
39 final MapCSSRuleIndex wayNoAreaRules = new MapCSSRuleIndex();
40 /**
41 * Rules for relations that are not multipolygon relations
42 */
43 final MapCSSRuleIndex relationRules = new MapCSSRuleIndex();
44 /**
45 * Rules for multipolygon relations
46 */
47 final MapCSSRuleIndex multipolygonRules = new MapCSSRuleIndex();
48 /**
49 * rules to apply canvas properties
50 */
51 final MapCSSRuleIndex canvasRules = new MapCSSRuleIndex();
52
53 /**
54 * Clear the index.
55 * <p>
56 * You must own the write lock STYLE_SOURCE_LOCK when calling this method.
57 */
58 public void clear() {
59 nodeRules.clear();
60 wayRules.clear();
61 wayNoAreaRules.clear();
62 relationRules.clear();
63 multipolygonRules.clear();
64 canvasRules.clear();
65 }
66
67 /**
68 * Builds and initializes the index.
69 * <p>
70 * You must own the write lock of STYLE_SOURCE_LOCK when calling this method.
71 * @param ruleStream the rules to index
72 */
73 public void buildIndex(Stream<MapCSSRule> ruleStream) {
74 clear();
75 // optimization: filter rules for different primitive types
76 ruleStream.forEach(rule -> {
77 final Map<String, MapCSSRule> selectorsByBase;
78 final Set<String> bases = rule.selectors.stream().map(Selector::getBase).collect(Collectors.toSet());
79 if (bases.size() == 1) {
80 // reuse rule
81 selectorsByBase = Collections.singletonMap(bases.iterator().next(), rule);
82 } else {
83 selectorsByBase = rule.selectors.stream()
84 .collect(Collectors.groupingBy(Selector::getBase,
85 Collectors.collectingAndThen(Collectors.toList(), selectors -> new MapCSSRule(selectors, rule.declaration))));
86 }
87 selectorsByBase.forEach((base, optRule) -> {
88 switch (base) {
89 case Selector.BASE_NODE:
90 nodeRules.add(optRule);
91 break;
92 case Selector.BASE_WAY:
93 wayNoAreaRules.add(optRule);
94 wayRules.add(optRule);
95 break;
96 case Selector.BASE_AREA:
97 wayRules.add(optRule);
98 multipolygonRules.add(optRule);
99 break;
100 case Selector.BASE_RELATION:
101 relationRules.add(optRule);
102 multipolygonRules.add(optRule);
103 break;
104 case Selector.BASE_ANY:
105 nodeRules.add(optRule);
106 wayRules.add(optRule);
107 wayNoAreaRules.add(optRule);
108 relationRules.add(optRule);
109 multipolygonRules.add(optRule);
110 break;
111 case Selector.BASE_CANVAS:
112 canvasRules.add(optRule);
113 break;
114 case Selector.BASE_META:
115 case Selector.BASE_SETTING:
116 case Selector.BASE_SETTINGS:
117 break;
118 default:
119 final RuntimeException e = new JosmRuntimeException(MessageFormat.format("Unknown MapCSS base selector {0}", base));
120 Logging.warn(tr("Failed to index validator rules. Error was: {0}", e.getMessage()));
121 Logging.error(e);
122 }
123 });
124 });
125 initIndex();
126 }
127
128 private void initIndex() {
129 nodeRules.initIndex();
130 wayRules.initIndex();
131 wayNoAreaRules.initIndex();
132 relationRules.initIndex();
133 multipolygonRules.initIndex();
134 canvasRules.initIndex();
135 }
136
137 /**
138 * Get the index of rules for the given primitive.
139 * @param p the primitive
140 * @return index of rules for the given primitive
141 */
142 public MapCSSRuleIndex get(IPrimitive p) {
143 if (p instanceof INode) {
144 return nodeRules;
145 } else if (p instanceof IWay) {
146 if (OsmUtils.isFalse(p.get("area"))) {
147 return wayNoAreaRules;
148 } else {
149 return wayRules;
150 }
151 } else if (p instanceof IRelation) {
152 if (((IRelation<?>) p).isMultipolygon()) {
153 return multipolygonRules;
154 } else if (p.hasKey("#canvas")) {
155 return canvasRules;
156 } else {
157 return relationRules;
158 }
159 } else {
160 throw new IllegalArgumentException("Unsupported type: " + p);
161 }
162 }
163
164 /**
165 * Get a subset of all rules that might match the primitive. Rules not included in the result are guaranteed to
166 * not match this primitive.
167 * <p>
168 * You must have a read lock of STYLE_SOURCE_LOCK when calling this method.
169 *
170 * @param osm the primitive to match
171 * @return An iterator over possible rules in the right order.
172 */
173 public Iterator<MapCSSRule> getRuleCandidates(IPrimitive osm) {
174 return get(osm).getRuleCandidates(osm);
175 }
176}
Note: See TracBrowser for help on using the repository browser.