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

Last change on this file since 3747 was 3389, checked in by bastiK, 14 years ago

fixed #5228 - type=line (bus-)relation is translated to "Freileitung (Starkstrom)" (power line)

  • Property svn:eol-style set to native
File size: 15.5 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 name = node.isNew() ? tr("node") : ""+ node.getId();
112 }
113 name += " (" + node.getCoor().latToString(CoordinateFormat.getDefaultFormat()) + ", " + node.getCoor().lonToString(CoordinateFormat.getDefaultFormat()) + ")";
114 }
115 name = decorateNameWithId(name, node);
116 return name;
117 }
118
119 /**
120 * Formats a name for a way
121 *
122 * @param way the way
123 * @return the name
124 */
125 public String format(Way way) {
126 String name = "";
127 if (way.isIncomplete()) {
128 name = tr("incomplete");
129 } else {
130 if (Main.pref.getBoolean("osm-primitives.localize-name", true)) {
131 name = way.getLocalName();
132 } else {
133 name = way.getName();
134 }
135 if (name == null) {
136 name = way.get("ref");
137 }
138 if (name == null) {
139 name =
140 (way.get("highway") != null) ? tr("highway") :
141 (way.get("railway") != null) ? tr("railway") :
142 (way.get("waterway") != null) ? tr("waterway") :
143 (way.get("landuse") != null) ? tr("landuse") : "";
144 }
145
146 int nodesNo = way.getNodesCount();
147 if (nodesNo > 1 && way.isClosed()) {
148 nodesNo--;
149 }
150 if(name.length() == 0 )
151 name = String.valueOf(way.getId());
152 /* note: length == 0 should no longer happen, but leave the bracket code
153 nevertheless, who knows what future brings */
154 String nodes = trn("{0} node", "{0} nodes", nodesNo, nodesNo);
155 name += (name.length() > 0) ? " ("+nodes+")" : nodes;
156 }
157 name = decorateNameWithId(name, way);
158 return name;
159 }
160
161 /**
162 * Formats a name for a relation
163 *
164 * @param relation the relation
165 * @return the name
166 */
167 public String format(Relation relation) {
168 String name;
169 if (relation.isIncomplete()) {
170 name = tr("incomplete");
171 } else {
172 name = trc("Relation type", relation.get("type"));
173 if (name == null) {
174 name = (relation.get("public_transport") != null) ? tr("public transport") : "";
175 }
176 if (name == null) {
177 String building = relation.get("building");
178 if(OsmUtils.isTrue(building))
179 name = tr("building");
180 else if(building != null)
181 name = tr(building); // translate tag!
182 }
183 if (name == null) {
184 name = tr("relation");
185 }
186 String admin_level = relation.get("admin_level");
187 if (admin_level != null) {
188 name += "["+admin_level+"]";
189 }
190
191 name += " (";
192 String nameTag = null;
193 for (String n : getNamingtagsForRelations()) {
194 if (n.equals("name")) {
195 if (Main.pref.getBoolean("osm-primitives.localize-name", true)) {
196 nameTag = relation.getLocalName();
197 } else {
198 nameTag = relation.getName();
199 }
200 } else if (n.equals(":LocationCode")) {
201 for (String m : relation.keySet()) {
202 if (m.endsWith(n)) {
203 nameTag = relation.get(m);
204 break;
205 }
206 }
207 } else {
208 String str = relation.get(n);
209 if(str != null)
210 nameTag = tr(str);
211 }
212 if (nameTag != null) {
213 break;
214 }
215 }
216 if (nameTag == null) {
217 name += Long.toString(relation.getId()) + ", ";
218 } else {
219 name += "\"" + nameTag + "\", ";
220 }
221
222 int mbno = relation.getMembersCount();
223 name += trn("{0} member", "{0} members", mbno, mbno);
224
225 boolean incomplete = false;
226 for (RelationMember m : relation.getMembers()) {
227 if (m.getMember().isIncomplete()) {
228 incomplete = true;
229 break;
230 }
231 }
232 if (incomplete) {
233 name += ", "+tr("incomplete");
234 }
235
236 name += ")";
237 }
238 name = decorateNameWithId(name, relation);
239 return name;
240 }
241
242 /**
243 * Formats a name for a changeset
244 *
245 * @param changeset the changeset
246 * @return the name
247 */
248 public String format(Changeset changeset) {
249 return tr("Changeset {0}",changeset.getId());
250 }
251
252 /**
253 * Builds a default tooltip text for the primitive <code>primitive</code>.
254 *
255 * @param primitive the primitmive
256 * @return the tooltip text
257 */
258 public String buildDefaultToolTip(OsmPrimitive primitive) {
259 StringBuilder sb = new StringBuilder();
260 sb.append("<html>");
261 sb.append("<strong>id</strong>=")
262 .append(primitive.getId())
263 .append("<br>");
264 ArrayList<String> keyList = new ArrayList<String>(primitive.keySet());
265 Collections.sort(keyList);
266 for (int i = 0; i < keyList.size(); i++) {
267 if (i > 0) {
268 sb.append("<br>");
269 }
270 String key = keyList.get(i);
271 sb.append("<strong>")
272 .append(key)
273 .append("</strong>")
274 .append("=");
275 String value = primitive.get(key);
276 while(value.length() != 0) {
277 sb.append(value.substring(0,Math.min(50, value.length())));
278 if (value.length() > 50) {
279 sb.append("<br>");
280 value = value.substring(50);
281 } else {
282 value = "";
283 }
284 }
285 }
286 sb.append("</html>");
287 return sb.toString();
288 }
289
290 /**
291 * Decorates the name of primitive with its id, if the preference
292 * <tt>osm-primitives.showid</tt> is set.
293 *
294 * The id is append to the {@see StringBuilder} passed in in <code>name</code>.
295 *
296 * @param name the name without the id
297 * @param primitive the primitive
298 */
299 protected void decorateNameWithId(StringBuilder name, HistoryOsmPrimitive primitive) {
300 if (Main.pref.getBoolean("osm-primitives.showid")) {
301 name.append(tr(" [id: {0}]", primitive.getId()));
302 }
303 }
304
305 /**
306 * Formats a name for a history node
307 *
308 * @param node the node
309 * @return the name
310 */
311 public String format(HistoryNode node) {
312 StringBuilder sb = new StringBuilder();
313 String name;
314 if (Main.pref.getBoolean("osm-primitives.localize-name", true)) {
315 name = node.getLocalName();
316 } else {
317 name = node.getName();
318 }
319 if (name == null) {
320 sb.append(node.getId());
321 } else {
322 sb.append(name);
323 }
324 sb.append(" (")
325 .append(node.getCoords().latToString(CoordinateFormat.getDefaultFormat()))
326 .append(", ")
327 .append(node.getCoords().lonToString(CoordinateFormat.getDefaultFormat()))
328 .append(")");
329 decorateNameWithId(sb, node);
330 return sb.toString();
331 }
332
333 /**
334 * Formats a name for a way
335 *
336 * @param way the way
337 * @return the name
338 */
339 public String format(HistoryWay way) {
340 StringBuilder sb = new StringBuilder();
341 String name;
342 if (Main.pref.getBoolean("osm-primitives.localize-name", true)) {
343 name = way.getLocalName();
344 } else {
345 name = way.getName();
346 }
347 if (name != null) {
348 sb.append(name);
349 }
350 if (sb.length() == 0 && way.get("ref") != null) {
351 sb.append(way.get("ref"));
352 }
353 if (sb.length() == 0) {
354 sb.append(
355 (way.get("highway") != null) ? tr("highway") :
356 (way.get("railway") != null) ? tr("railway") :
357 (way.get("waterway") != null) ? tr("waterway") :
358 (way.get("landuse") != null) ? tr("landuse") : ""
359 );
360 }
361
362 int nodesNo = way.isClosed() ? way.getNumNodes() -1 : way.getNumNodes();
363 String nodes = trn("{0} node", "{0} nodes", nodesNo, nodesNo);
364 if(sb.length() == 0 )
365 sb.append(way.getId());
366 /* note: length == 0 should no longer happen, but leave the bracket code
367 nevertheless, who knows what future brings */
368 sb.append((sb.length() > 0) ? " ("+nodes+")" : nodes);
369 decorateNameWithId(sb, way);
370 return sb.toString();
371 }
372
373 /**
374 * Formats a name for a {@see HistoryRelation})
375 *
376 * @param relation the relation
377 * @return the name
378 */
379 public String format(HistoryRelation relation) {
380 StringBuilder sb = new StringBuilder();
381 if (relation.get("type") != null) {
382 sb.append(relation.get("type"));
383 } else {
384 sb.append(tr("relation"));
385 }
386 sb.append(" (");
387 String nameTag = null;
388 Set<String> namingTags = new HashSet<String>(getNamingtagsForRelations());
389 for (String n : relation.getTags().keySet()) {
390 // #3328: "note " and " note" are name tags too
391 if (namingTags.contains(n.trim())) {
392 if (Main.pref.getBoolean("osm-primitives.localize-name", true)) {
393 nameTag = relation.getLocalName();
394 } else {
395 nameTag = relation.getName();
396 }
397 if (nameTag == null) {
398 nameTag = relation.get(n);
399 }
400 }
401 if (nameTag != null) {
402 break;
403 }
404 }
405 if (nameTag == null) {
406 sb.append(Long.toString(relation.getId())).append(", ");
407 } else {
408 sb.append("\"").append(nameTag).append("\", ");
409 }
410
411 int mbno = relation.getNumMembers();
412 sb.append(trn("{0} member", "{0} members", mbno, mbno)).append(")");
413
414 decorateNameWithId(sb, relation);
415 return sb.toString();
416 }
417
418 /**
419 * Builds a default tooltip text for an HistoryOsmPrimitive <code>primitive</code>.
420 *
421 * @param primitive the primitmive
422 * @return the tooltip text
423 */
424 public String buildDefaultToolTip(HistoryOsmPrimitive primitive) {
425 StringBuilder sb = new StringBuilder();
426 sb.append("<html>");
427 sb.append("<strong>id</strong>=")
428 .append(primitive.getId())
429 .append("<br>");
430 ArrayList<String> keyList = new ArrayList<String>(primitive.getTags().keySet());
431 Collections.sort(keyList);
432 for (int i = 0; i < keyList.size(); i++) {
433 if (i > 0) {
434 sb.append("<br>");
435 }
436 String key = keyList.get(i);
437 sb.append("<strong>")
438 .append(key)
439 .append("</strong>")
440 .append("=");
441 String value = primitive.get(key);
442 while(value.length() != 0) {
443 sb.append(value.substring(0,Math.min(50, value.length())));
444 if (value.length() > 50) {
445 sb.append("<br>");
446 value = value.substring(50);
447 } else {
448 value = "";
449 }
450 }
451 }
452 sb.append("</html>");
453 return sb.toString();
454 }
455}
Note: See TracBrowser for help on using the repository browser.