source: josm/trunk/src/org/openstreetmap/josm/gui/DefaultNameFormatter.java@ 3291

Last change on this file since 3291 was 3291, checked in by stoecker, 14 years ago

fix #4414 - draw selected relation and selected elements a bit different

  • Property svn:eol-style set to native
File size: 15.4 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5import static org.openstreetmap.josm.tools.I18n.trn;
6
7import java.util.ArrayList;
8import java.util.Arrays;
9import java.util.Collections;
10import java.util.HashSet;
11import java.util.List;
12import java.util.Set;
13
14import org.openstreetmap.josm.Main;
15import org.openstreetmap.josm.data.coor.CoordinateFormat;
16import org.openstreetmap.josm.data.osm.Changeset;
17import org.openstreetmap.josm.data.osm.NameFormatter;
18import org.openstreetmap.josm.data.osm.Node;
19import org.openstreetmap.josm.data.osm.OsmPrimitive;
20import org.openstreetmap.josm.data.osm.OsmUtils;
21import org.openstreetmap.josm.data.osm.Relation;
22import org.openstreetmap.josm.data.osm.RelationMember;
23import org.openstreetmap.josm.data.osm.Way;
24import org.openstreetmap.josm.data.osm.history.HistoryNameFormatter;
25import org.openstreetmap.josm.data.osm.history.HistoryNode;
26import org.openstreetmap.josm.data.osm.history.HistoryOsmPrimitive;
27import org.openstreetmap.josm.data.osm.history.HistoryRelation;
28import org.openstreetmap.josm.data.osm.history.HistoryWay;
29
30/**
31 * This is the default implementation of a {@see NameFormatter} for names of {@see OsmPrimitive}s.
32 *
33 */
34public class DefaultNameFormatter implements NameFormatter, HistoryNameFormatter {
35
36 static private DefaultNameFormatter instance;
37
38 /**
39 * Replies the unique instance of this formatter
40 *
41 * @return the unique instance of this formatter
42 */
43 static public DefaultNameFormatter getInstance() {
44 if (instance == null) {
45 instance = new DefaultNameFormatter();
46 }
47 return instance;
48 }
49
50 /** the default list of tags which are used as naming tags in relations */
51 static public final String[] DEFAULT_NAMING_TAGS_FOR_RELATIONS = {"name", "ref", "restriction", "landuse", "natural",
52 "public_transport", ":LocationCode", "note"};
53
54 /** the current list of tags used as naming tags in relations */
55 static private List<String> namingTagsForRelations = null;
56
57 /**
58 * Replies the list of naming tags used in relations. The list is given (in this order) by:
59 * <ul>
60 * <li>by the tag names in the preference <tt>relation.nameOrder</tt></li>
61 * <li>by the default tags in {@see #DEFAULT_NAMING_TAGS_FOR_RELATIONS}
62 * </ul>
63 *
64 * @return the list of naming tags used in relations
65 */
66 static public List<String> getNamingtagsForRelations() {
67 if (namingTagsForRelations == null) {
68 namingTagsForRelations = new ArrayList<String>(
69 Main.pref.getCollection("relation.nameOrder", Arrays.asList(DEFAULT_NAMING_TAGS_FOR_RELATIONS))
70 );
71 }
72 return namingTagsForRelations;
73 }
74
75 /**
76 * Decorates the name of primitive with its id, if the preference
77 * <tt>osm-primitives.showid</tt> is set. Shows unique id if osm-primitives.showid.new-primitives is set
78 *
79 * @param name the name without the id
80 * @param primitive the primitive
81 * @return the decorated name
82 */
83 protected String decorateNameWithId(String name, OsmPrimitive primitive) {
84 if (Main.pref.getBoolean("osm-primitives.showid"))
85 if (Main.pref.getBoolean("osm-primitives.showid.new-primitives"))
86 return name + tr(" [id: {0}]", primitive.getUniqueId());
87 else
88 return name + tr(" [id: {0}]", primitive.getId());
89 else
90 return name;
91 }
92
93 /**
94 * Formats a name for a node
95 *
96 * @param node the node
97 * @return the name
98 */
99 public String format(Node node) {
100 String name = "";
101 if (node.isIncomplete()) {
102 name = tr("incomplete");
103 } else {
104 if (Main.pref.getBoolean("osm-primitives.localize-name", true)) {
105 name = node.getLocalName();
106 } else {
107 name = node.getName();
108 }
109 if (name == null) {
110 name = node.isNew() ? tr("node") : ""+ node.getId();
111 }
112 name += " (" + node.getCoor().latToString(CoordinateFormat.getDefaultFormat()) + ", " + node.getCoor().lonToString(CoordinateFormat.getDefaultFormat()) + ")";
113 }
114 name = decorateNameWithId(name, node);
115 return name;
116 }
117
118 /**
119 * Formats a name for a way
120 *
121 * @param way the way
122 * @return the name
123 */
124 public String format(Way way) {
125 String name = "";
126 if (way.isIncomplete()) {
127 name = tr("incomplete");
128 } else {
129 if (Main.pref.getBoolean("osm-primitives.localize-name", true)) {
130 name = way.getLocalName();
131 } else {
132 name = way.getName();
133 }
134 if (name == null) {
135 name = way.get("ref");
136 }
137 if (name == null) {
138 name =
139 (way.get("highway") != null) ? tr("highway") :
140 (way.get("railway") != null) ? tr("railway") :
141 (way.get("waterway") != null) ? tr("waterway") :
142 (way.get("landuse") != null) ? tr("landuse") : "";
143 }
144
145 int nodesNo = way.getNodesCount();
146 if (nodesNo > 1 && way.isClosed()) {
147 nodesNo--;
148 }
149 if(name.length() == 0 )
150 name = String.valueOf(way.getId());
151 /* note: length == 0 should no longer happen, but leave the bracket code
152 nevertheless, who knows what future brings */
153 String nodes = trn("{0} node", "{0} nodes", nodesNo, nodesNo);
154 name += (name.length() > 0) ? " ("+nodes+")" : nodes;
155 }
156 name = decorateNameWithId(name, way);
157 return name;
158 }
159
160 /**
161 * Formats a name for a relation
162 *
163 * @param relation the relation
164 * @return the name
165 */
166 public String format(Relation relation) {
167 String name;
168 if (relation.isIncomplete()) {
169 name = tr("incomplete");
170 } else {
171 name = tr(relation.get("type"));
172 if (name == null) {
173 name = (relation.get("public_transport") != null) ? tr("public transport") : "";
174 }
175 if (name == null) {
176 String building = relation.get("building");
177 if(OsmUtils.isTrue(building))
178 name = tr("building");
179 else if(building != null)
180 name = tr(building); // translate tag!
181 }
182 if (name == null) {
183 name = tr("relation");
184 }
185 String admin_level = relation.get("admin_level");
186 if (admin_level != null) {
187 name += "["+admin_level+"]";
188 }
189
190 name += " (";
191 String nameTag = null;
192 for (String n : getNamingtagsForRelations()) {
193 if (n.equals("name")) {
194 if (Main.pref.getBoolean("osm-primitives.localize-name", true)) {
195 nameTag = relation.getLocalName();
196 } else {
197 nameTag = relation.getName();
198 }
199 } else if (n.equals(":LocationCode")) {
200 for (String m : relation.keySet()) {
201 if (m.endsWith(n)) {
202 nameTag = relation.get(m);
203 break;
204 }
205 }
206 } else {
207 String str = relation.get(n);
208 if(str != null)
209 nameTag = tr(str);
210 }
211 if (nameTag != null) {
212 break;
213 }
214 }
215 if (nameTag == null) {
216 name += Long.toString(relation.getId()) + ", ";
217 } else {
218 name += "\"" + nameTag + "\", ";
219 }
220
221 int mbno = relation.getMembersCount();
222 name += trn("{0} member", "{0} members", mbno, mbno);
223
224 boolean incomplete = false;
225 for (RelationMember m : relation.getMembers()) {
226 if (m.getMember().isIncomplete()) {
227 incomplete = true;
228 break;
229 }
230 }
231 if (incomplete) {
232 name += ", "+tr("incomplete");
233 }
234
235 name += ")";
236 }
237 name = decorateNameWithId(name, relation);
238 return name;
239 }
240
241 /**
242 * Formats a name for a changeset
243 *
244 * @param changeset the changeset
245 * @return the name
246 */
247 public String format(Changeset changeset) {
248 return tr("Changeset {0}",changeset.getId());
249 }
250
251 /**
252 * Builds a default tooltip text for the primitive <code>primitive</code>.
253 *
254 * @param primitive the primitmive
255 * @return the tooltip text
256 */
257 public String buildDefaultToolTip(OsmPrimitive primitive) {
258 StringBuilder sb = new StringBuilder();
259 sb.append("<html>");
260 sb.append("<strong>id</strong>=")
261 .append(primitive.getId())
262 .append("<br>");
263 ArrayList<String> keyList = new ArrayList<String>(primitive.keySet());
264 Collections.sort(keyList);
265 for (int i = 0; i < keyList.size(); i++) {
266 if (i > 0) {
267 sb.append("<br>");
268 }
269 String key = keyList.get(i);
270 sb.append("<strong>")
271 .append(key)
272 .append("</strong>")
273 .append("=");
274 String value = primitive.get(key);
275 while(value.length() != 0) {
276 sb.append(value.substring(0,Math.min(50, value.length())));
277 if (value.length() > 50) {
278 sb.append("<br>");
279 value = value.substring(50);
280 } else {
281 value = "";
282 }
283 }
284 }
285 sb.append("</html>");
286 return sb.toString();
287 }
288
289 /**
290 * Decorates the name of primitive with its id, if the preference
291 * <tt>osm-primitives.showid</tt> is set.
292 *
293 * The id is append to the {@see StringBuilder} passed in in <code>name</code>.
294 *
295 * @param name the name without the id
296 * @param primitive the primitive
297 */
298 protected void decorateNameWithId(StringBuilder name, HistoryOsmPrimitive primitive) {
299 if (Main.pref.getBoolean("osm-primitives.showid")) {
300 name.append(tr(" [id: {0}]", primitive.getId()));
301 }
302 }
303
304 /**
305 * Formats a name for a history node
306 *
307 * @param node the node
308 * @return the name
309 */
310 public String format(HistoryNode node) {
311 StringBuilder sb = new StringBuilder();
312 String name;
313 if (Main.pref.getBoolean("osm-primitives.localize-name", true)) {
314 name = node.getLocalName();
315 } else {
316 name = node.getName();
317 }
318 if (name == null) {
319 sb.append(node.getId());
320 } else {
321 sb.append(name);
322 }
323 sb.append(" (")
324 .append(node.getCoords().latToString(CoordinateFormat.getDefaultFormat()))
325 .append(", ")
326 .append(node.getCoords().lonToString(CoordinateFormat.getDefaultFormat()))
327 .append(")");
328 decorateNameWithId(sb, node);
329 return sb.toString();
330 }
331
332 /**
333 * Formats a name for a way
334 *
335 * @param way the way
336 * @return the name
337 */
338 public String format(HistoryWay way) {
339 StringBuilder sb = new StringBuilder();
340 String name;
341 if (Main.pref.getBoolean("osm-primitives.localize-name", true)) {
342 name = way.getLocalName();
343 } else {
344 name = way.getName();
345 }
346 if (name != null) {
347 sb.append(name);
348 }
349 if (sb.length() == 0 && way.get("ref") != null) {
350 sb.append(way.get("ref"));
351 }
352 if (sb.length() == 0) {
353 sb.append(
354 (way.get("highway") != null) ? tr("highway") :
355 (way.get("railway") != null) ? tr("railway") :
356 (way.get("waterway") != null) ? tr("waterway") :
357 (way.get("landuse") != null) ? tr("landuse") : ""
358 );
359 }
360
361 int nodesNo = way.isClosed() ? way.getNumNodes() -1 : way.getNumNodes();
362 String nodes = trn("{0} node", "{0} nodes", nodesNo, nodesNo);
363 if(sb.length() == 0 )
364 sb.append(way.getId());
365 /* note: length == 0 should no longer happen, but leave the bracket code
366 nevertheless, who knows what future brings */
367 sb.append((sb.length() > 0) ? " ("+nodes+")" : nodes);
368 decorateNameWithId(sb, way);
369 return sb.toString();
370 }
371
372 /**
373 * Formats a name for a {@see HistoryRelation})
374 *
375 * @param relation the relation
376 * @return the name
377 */
378 public String format(HistoryRelation relation) {
379 StringBuilder sb = new StringBuilder();
380 if (relation.get("type") != null) {
381 sb.append(relation.get("type"));
382 } else {
383 sb.append(tr("relation"));
384 }
385 sb.append(" (");
386 String nameTag = null;
387 Set<String> namingTags = new HashSet<String>(getNamingtagsForRelations());
388 for (String n : relation.getTags().keySet()) {
389 // #3328: "note " and " note" are name tags too
390 if (namingTags.contains(n.trim())) {
391 if (Main.pref.getBoolean("osm-primitives.localize-name", true)) {
392 nameTag = relation.getLocalName();
393 } else {
394 nameTag = relation.getName();
395 }
396 if (nameTag == null) {
397 nameTag = relation.get(n);
398 }
399 }
400 if (nameTag != null) {
401 break;
402 }
403 }
404 if (nameTag == null) {
405 sb.append(Long.toString(relation.getId())).append(", ");
406 } else {
407 sb.append("\"").append(nameTag).append("\", ");
408 }
409
410 int mbno = relation.getNumMembers();
411 sb.append(trn("{0} member", "{0} members", mbno, mbno)).append(")");
412
413 decorateNameWithId(sb, relation);
414 return sb.toString();
415 }
416
417 /**
418 * Builds a default tooltip text for an HistoryOsmPrimitive <code>primitive</code>.
419 *
420 * @param primitive the primitmive
421 * @return the tooltip text
422 */
423 public String buildDefaultToolTip(HistoryOsmPrimitive primitive) {
424 StringBuilder sb = new StringBuilder();
425 sb.append("<html>");
426 sb.append("<strong>id</strong>=")
427 .append(primitive.getId())
428 .append("<br>");
429 ArrayList<String> keyList = new ArrayList<String>(primitive.getTags().keySet());
430 Collections.sort(keyList);
431 for (int i = 0; i < keyList.size(); i++) {
432 if (i > 0) {
433 sb.append("<br>");
434 }
435 String key = keyList.get(i);
436 sb.append("<strong>")
437 .append(key)
438 .append("</strong>")
439 .append("=");
440 String value = primitive.get(key);
441 while(value.length() != 0) {
442 sb.append(value.substring(0,Math.min(50, value.length())));
443 if (value.length() > 50) {
444 sb.append("<br>");
445 value = value.substring(50);
446 } else {
447 value = "";
448 }
449 }
450 }
451 sb.append("</html>");
452 return sb.toString();
453 }
454}
Note: See TracBrowser for help on using the repository browser.