source: josm/trunk/src/org/openstreetmap/josm/gui/mappaint/styleelement/LabelCompositionStrategy.java@ 9278

Last change on this file since 9278 was 9278, checked in by bastiK, 8 years ago

move ElemStyle classes to new package, rename to (Style)Element

  • Property svn:eol-style set to native
File size: 10.4 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.mappaint.styleelement;
3
4import java.util.ArrayList;
5import java.util.Arrays;
6import java.util.Collections;
7import java.util.List;
8
9import org.openstreetmap.josm.Main;
10import org.openstreetmap.josm.data.Preferences.PreferenceChangeEvent;
11import org.openstreetmap.josm.data.Preferences.PreferenceChangedListener;
12import org.openstreetmap.josm.data.osm.OsmPrimitive;
13import org.openstreetmap.josm.tools.LanguageInfo;
14
15/**
16 * <p>Provides an abstract parent class and three concrete sub classes for various
17 * strategies on how to compose the text label which can be rendered close to a node
18 * or within an area in an OSM map.</p>
19 *
20 * <p>The three strategies below support three rules for composing a label:
21 * <ul>
22 * <li>{@link StaticLabelCompositionStrategy} - the label is given by a static text
23 * specified in the MapCSS style file</li>
24 *
25 * <li>{@link TagLookupCompositionStrategy} - the label is given by the content of a
26 * tag whose name specified in the MapCSS style file</li>
27 *
28 * <li>{@link DeriveLabelFromNameTagsCompositionStrategy} - the label is given by the value
29 * of one
30 * of the configured "name tags". The list of relevant name tags can be configured
31 * in the JOSM preferences
32 * content of a tag whose name specified in the MapCSS style file, see the preference
33 * options <tt>mappaint.nameOrder</tt> and <tt>mappaint.nameComplementOrder</tt>.</li>
34 * </ul>
35 *
36 */
37public abstract class LabelCompositionStrategy {
38
39 /**
40 * Replies the text value to be rendered as label for the primitive {@code primitive}.
41 *
42 * @param primitive the primitive
43 *
44 * @return the text value to be rendered or null, if primitive is null or
45 * if no suitable value could be composed
46 */
47 public abstract String compose(OsmPrimitive primitive);
48
49 public static class StaticLabelCompositionStrategy extends LabelCompositionStrategy {
50 private final String defaultLabel;
51
52 public StaticLabelCompositionStrategy(String defaultLabel) {
53 this.defaultLabel = defaultLabel;
54 }
55
56 @Override
57 public String compose(OsmPrimitive primitive) {
58 return defaultLabel;
59 }
60
61 public String getDefaultLabel() {
62 return defaultLabel;
63 }
64
65 @Override
66 public String toString() {
67 return '{' + getClass().getSimpleName() + " defaultLabel=" + defaultLabel + '}';
68 }
69
70 @Override
71 public int hashCode() {
72 final int prime = 31;
73 int result = 1;
74 result = prime * result + ((defaultLabel == null) ? 0 : defaultLabel.hashCode());
75 return result;
76 }
77
78 @Override
79 public boolean equals(Object obj) {
80 if (this == obj)
81 return true;
82 if (obj == null)
83 return false;
84 if (getClass() != obj.getClass())
85 return false;
86 StaticLabelCompositionStrategy other = (StaticLabelCompositionStrategy) obj;
87 if (defaultLabel == null) {
88 if (other.defaultLabel != null)
89 return false;
90 } else if (!defaultLabel.equals(other.defaultLabel))
91 return false;
92 return true;
93 }
94 }
95
96 public static class TagLookupCompositionStrategy extends LabelCompositionStrategy {
97
98 private final String defaultLabelTag;
99
100 public TagLookupCompositionStrategy(String defaultLabelTag) {
101 if (defaultLabelTag != null) {
102 defaultLabelTag = defaultLabelTag.trim();
103 if (defaultLabelTag.isEmpty()) {
104 defaultLabelTag = null;
105 }
106 }
107 this.defaultLabelTag = defaultLabelTag;
108 }
109
110 @Override
111 public String compose(OsmPrimitive primitive) {
112 if (defaultLabelTag == null) return null;
113 if (primitive == null) return null;
114 return primitive.get(defaultLabelTag);
115 }
116
117 public String getDefaultLabelTag() {
118 return defaultLabelTag;
119 }
120
121 @Override
122 public String toString() {
123 return '{' + getClass().getSimpleName() + " defaultLabelTag=" + defaultLabelTag + '}';
124 }
125
126 @Override
127 public int hashCode() {
128 final int prime = 31;
129 int result = 1;
130 result = prime * result + ((defaultLabelTag == null) ? 0 : defaultLabelTag.hashCode());
131 return result;
132 }
133
134 @Override
135 public boolean equals(Object obj) {
136 if (this == obj)
137 return true;
138 if (obj == null)
139 return false;
140 if (getClass() != obj.getClass())
141 return false;
142 TagLookupCompositionStrategy other = (TagLookupCompositionStrategy) obj;
143 if (defaultLabelTag == null) {
144 if (other.defaultLabelTag != null)
145 return false;
146 } else if (!defaultLabelTag.equals(other.defaultLabelTag))
147 return false;
148 return true;
149 }
150 }
151
152 public static class DeriveLabelFromNameTagsCompositionStrategy
153 extends LabelCompositionStrategy implements PreferenceChangedListener {
154
155 /**
156 * The list of default name tags from which a label candidate is derived.
157 */
158 private static final String[] DEFAULT_NAME_TAGS = {
159 "name:" + LanguageInfo.getJOSMLocaleCode(),
160 "name",
161 "int_name",
162 "distance",
163 "ref",
164 "operator",
165 "brand",
166 "addr:housenumber"
167 };
168
169 /**
170 * The list of default name complement tags from which a label candidate is derived.
171 */
172 private static final String[] DEFAULT_NAME_COMPLEMENT_TAGS = {
173 "capacity"
174 };
175
176 private List<String> nameTags = new ArrayList<>();
177 private List<String> nameComplementTags = new ArrayList<>();
178
179 /**
180 * <p>Creates the strategy and initializes its name tags from the preferences.</p>
181 */
182 public DeriveLabelFromNameTagsCompositionStrategy() {
183 initNameTagsFromPreferences();
184 }
185
186 private static List<String> buildNameTags(List<String> nameTags) {
187 if (nameTags == null) {
188 nameTags = Collections.emptyList();
189 }
190 List<String> result = new ArrayList<>();
191 for (String tag: nameTags) {
192 if (tag == null) {
193 continue;
194 }
195 tag = tag.trim();
196 if (tag.isEmpty()) {
197 continue;
198 }
199 result.add(tag);
200 }
201 return result;
202 }
203
204 /**
205 * Sets the name tags to be looked up in order to build up the label.
206 *
207 * @param nameTags the name tags. null values are ignored.
208 */
209 public void setNameTags(List<String> nameTags) {
210 this.nameTags = buildNameTags(nameTags);
211 }
212
213 /**
214 * Sets the name complement tags to be looked up in order to build up the label.
215 *
216 * @param nameComplementTags the name complement tags. null values are ignored.
217 * @since 6541
218 */
219 public void setNameComplementTags(List<String> nameComplementTags) {
220 this.nameComplementTags = buildNameTags(nameComplementTags);
221 }
222
223 /**
224 * Replies an unmodifiable list of the name tags used to compose the label.
225 *
226 * @return the list of name tags
227 */
228 public List<String> getNameTags() {
229 return Collections.unmodifiableList(nameTags);
230 }
231
232 /**
233 * Replies an unmodifiable list of the name complement tags used to compose the label.
234 *
235 * @return the list of name complement tags
236 * @since 6541
237 */
238 public List<String> getNameComplementTags() {
239 return Collections.unmodifiableList(nameComplementTags);
240 }
241
242 /**
243 * Initializes the name tags to use from a list of default name tags (see
244 * {@link #DEFAULT_NAME_TAGS} and {@link #DEFAULT_NAME_COMPLEMENT_TAGS})
245 * and from name tags configured in the preferences using the keys
246 * <tt>mappaint.nameOrder</tt> and <tt>mappaint.nameComplementOrder</tt>.
247 */
248 public final void initNameTagsFromPreferences() {
249 if (Main.pref == null) {
250 this.nameTags = new ArrayList<>(Arrays.asList(DEFAULT_NAME_TAGS));
251 this.nameComplementTags = new ArrayList<>(Arrays.asList(DEFAULT_NAME_COMPLEMENT_TAGS));
252 } else {
253 this.nameTags = new ArrayList<>(
254 Main.pref.getCollection("mappaint.nameOrder", Arrays.asList(DEFAULT_NAME_TAGS))
255 );
256 this.nameComplementTags = new ArrayList<>(
257 Main.pref.getCollection("mappaint.nameComplementOrder", Arrays.asList(DEFAULT_NAME_COMPLEMENT_TAGS))
258 );
259 }
260 }
261
262 private String getPrimitiveName(OsmPrimitive n) {
263 StringBuilder name = new StringBuilder();
264 if (!n.hasKeys()) return null;
265 for (String rn : nameTags) {
266 String val = n.get(rn);
267 if (val != null) {
268 name.append(val);
269 break;
270 }
271 }
272 for (String rn : nameComplementTags) {
273 String comp = n.get(rn);
274 if (comp != null) {
275 if (name.length() == 0) {
276 name.append(comp);
277 } else {
278 name.append(" (").append(comp).append(')');
279 }
280 break;
281 }
282 }
283 return name.toString();
284 }
285
286 @Override
287 public String compose(OsmPrimitive primitive) {
288 if (primitive == null) return null;
289 return getPrimitiveName(primitive);
290 }
291
292 @Override
293 public String toString() {
294 return "{" + getClass().getSimpleName() +'}';
295 }
296
297 @Override
298 public void preferenceChanged(PreferenceChangeEvent e) {
299 if (e.getKey() != null && e.getKey().startsWith("mappaint.name")) {
300 initNameTagsFromPreferences();
301 }
302 }
303 }
304}
Note: See TracBrowser for help on using the repository browser.