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

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

fix #5976 - support relation names for place relations

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