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

Last change on this file since 11615 was 11615, checked in by Don-vip, 7 years ago

add javadoc

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