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

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

mapcss: improvements in text label selection, performance and typo (patch by anonymous, see #6107)

  • Property svn:eol-style set to native
File size: 8.1 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.mappaint;
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.osm.OsmPrimitive;
11import org.openstreetmap.josm.tools.LanguageInfo;
12
13/**
14 * <p>Provides an abstract parent class and three concrete sub classes for various
15 * strategies on how to compose the text label which can be rendered close to a node
16 * or within an area in an OSM map.</p>
17 *
18 * <p>The three strategies below support three rules for composing a label:
19 * <ul>
20 * <li>{@link StaticLabelCompositionStrategy} - the label is given by a static text
21 * specified in the MapCSS style file</li>
22 *
23 * <li>{@link TagLookupCompositionStrategy} - the label is given by the content of a
24 * tag whose name specified in the MapCSS style file</li>
25 *
26 * <li>{@link DeriveLabelFromNameTagsCompositionStrategy} - the label is given by the value
27 * of one
28 * of the configured "name tags". The list of relevant name tags can be configured
29 * in the JOSM preferences
30 * content of a tag whose name specified in the MapCSS style file, see the preference
31 * option <tt>mappaint.nameOrder</tt>.</li>
32 * </ul>
33 * </p>
34 *
35 */
36public abstract class LabelCompositionStrategy {
37
38 /**
39 * Replies the text value to be rendered as label for the primitive {@code primitive}.
40 *
41 * @param primitive the primitive
42 *
43 * @return the text value to be rendered or null, if primitive is null or
44 * if no suitable value could be composed
45 */
46 abstract public String compose(OsmPrimitive primitive);
47
48 static public class StaticLabelCompositionStrategy extends LabelCompositionStrategy {
49 private String defaultLabel;
50 public StaticLabelCompositionStrategy(String defaultLabel){
51 this.defaultLabel = defaultLabel;
52 }
53
54 @Override
55 public String compose(OsmPrimitive primitive) {
56 return defaultLabel;
57 }
58
59 public String getDefaultLabel() {
60 return defaultLabel;
61 }
62
63 @Override
64 public String toString() {
65 return "{" + getClass().getSimpleName() + " defaultLabel=" + defaultLabel + "}";
66 }
67
68 @Override
69 public int hashCode() {
70 final int prime = 31;
71 int result = 1;
72 result = prime * result + ((defaultLabel == null) ? 0 : defaultLabel.hashCode());
73 return result;
74 }
75
76 @Override
77 public boolean equals(Object obj) {
78 if (this == obj)
79 return true;
80 if (obj == null)
81 return false;
82 if (getClass() != obj.getClass())
83 return false;
84 StaticLabelCompositionStrategy other = (StaticLabelCompositionStrategy) obj;
85 if (defaultLabel == null) {
86 if (other.defaultLabel != null)
87 return false;
88 } else if (!defaultLabel.equals(other.defaultLabel))
89 return false;
90 return true;
91 }
92 }
93
94 static public class TagLookupCompositionStrategy extends LabelCompositionStrategy {
95
96 private String defaultLabelTag;
97 public TagLookupCompositionStrategy(String defaultLabelTag){
98 if (defaultLabelTag != null) {
99 defaultLabelTag = defaultLabelTag.trim();
100 if (defaultLabelTag.isEmpty()) {
101 defaultLabelTag = null;
102 }
103 }
104 this.defaultLabelTag = defaultLabelTag;
105 }
106
107 @Override
108 public String compose(OsmPrimitive primitive) {
109 if (defaultLabelTag == null) return null;
110 if (primitive == null) return null;
111 return primitive.get(defaultLabelTag);
112 }
113
114 public String getDefaultLabelTag() {
115 return defaultLabelTag;
116 }
117
118 @Override
119 public String toString() {
120 return "{" + getClass().getSimpleName() + " defaultLabelTag=" + defaultLabelTag + "}";
121 }
122
123 @Override
124 public int hashCode() {
125 final int prime = 31;
126 int result = 1;
127 result = prime * result + ((defaultLabelTag == null) ? 0 : defaultLabelTag.hashCode());
128 return result;
129 }
130
131 @Override
132 public boolean equals(Object obj) {
133 if (this == obj)
134 return true;
135 if (obj == null)
136 return false;
137 if (getClass() != obj.getClass())
138 return false;
139 TagLookupCompositionStrategy other = (TagLookupCompositionStrategy) obj;
140 if (defaultLabelTag == null) {
141 if (other.defaultLabelTag != null)
142 return false;
143 } else if (!defaultLabelTag.equals(other.defaultLabelTag))
144 return false;
145 return true;
146 }
147 }
148
149 static public class DeriveLabelFromNameTagsCompositionStrategy extends LabelCompositionStrategy {
150
151 /**
152 * The list of default name tags from which a label candidate is derived.
153 */
154 static public final String[] DEFAULT_NAME_TAGS = {
155 "name:" + LanguageInfo.getJOSMLocaleCode(),
156 "name",
157 "int_name",
158 "ref",
159 "operator",
160 "brand",
161 "addr:housenumber"
162 };
163
164 private List<String> nameTags = new ArrayList<String>();
165
166 /**
167 * <p>Creates the strategy and initializes its name tags from the preferences.</p>
168 *
169 * <p><strong>Note:</strong> If the list of name tags in the preferences changes, strategy instances
170 * are not notified. It's up to the client to listen to preference changes and
171 * invoke {@link #initNameTagsFromPreferences()} accordingly.</p>
172 *
173 */
174 public DeriveLabelFromNameTagsCompositionStrategy() {
175 initNameTagsFromPreferences();
176 }
177
178 /**
179 * Sets the name tags to be looked up in order to build up the label
180 *
181 * @param nameTags the name tags. null values are ignore.
182 */
183 public void setNameTags(List<String> nameTags){
184 if (nameTags == null) {
185 nameTags = Collections.emptyList();
186 }
187 this.nameTags = new ArrayList<String>();
188 for(String tag: nameTags) {
189 if (tag == null) {
190 continue;
191 }
192 tag = tag.trim();
193 if (tag.isEmpty()) {
194 continue;
195 }
196 this.nameTags.add(tag);
197 }
198 }
199
200 /**
201 * Replies an unmodifiable list of the name tags used to compose the label.
202 *
203 * @return the list of name tags
204 */
205 public List<String> getNameTags() {
206 return Collections.unmodifiableList(nameTags);
207 }
208
209 /**
210 * Initializes the name tags to use from a list of default name tags (see
211 * {@link #DEFAULT_NAME_TAGS}) and from name tags configured in the preferences
212 * using the preference key <tt>mappaint.nameOrder</tt>.
213 */
214 public void initNameTagsFromPreferences() {
215 if (Main.pref == null){
216 this.nameTags = new ArrayList<String>(Arrays.asList(DEFAULT_NAME_TAGS));
217 } else {
218 this.nameTags = new ArrayList<String>(
219 Main.pref.getCollection("mappaint.nameOrder", Arrays.asList(DEFAULT_NAME_TAGS))
220 );
221 }
222 }
223
224 private String getPrimitiveName(OsmPrimitive n) {
225 String name = null;
226 if (!n.hasKeys()) return null;
227 for (String rn : nameTags) {
228 name = n.get(rn);
229 if (name != null) return name;
230 }
231 return null;
232 }
233
234 @Override
235 public String compose(OsmPrimitive primitive) {
236 if (primitive == null) return null;
237 return getPrimitiveName(primitive);
238 }
239
240 @Override
241 public String toString() {
242 return "{" + getClass().getSimpleName() +"}";
243 }
244 }
245}
Note: See TracBrowser for help on using the repository browser.