source: josm/trunk/src/org/openstreetmap/josm/corrector/ReverseWayNoTagCorrector.java@ 9621

Last change on this file since 9621 was 9539, checked in by simon04, 8 years ago

fix #10290 - Improve ReverseWayNoTagCorrector

It evaluates its own directional tags together with those defined at
OsmPrimitive#directionKeys minus the ones that can be corrected using
ReverseWayTagCorrector.

  • Property svn:eol-style set to native
File size: 5.0 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.corrector;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5import static org.openstreetmap.josm.tools.I18n.trn;
6
7import java.util.Arrays;
8import java.util.Map;
9
10import javax.swing.JOptionPane;
11
12import org.openstreetmap.josm.Main;
13import org.openstreetmap.josm.data.osm.OsmPrimitive;
14import org.openstreetmap.josm.data.osm.Tag;
15import org.openstreetmap.josm.data.osm.TagCollection;
16import org.openstreetmap.josm.data.osm.Tagged;
17import org.openstreetmap.josm.data.osm.Way;
18import org.openstreetmap.josm.gui.ConditionalOptionPaneUtil;
19import org.openstreetmap.josm.gui.DefaultNameFormatter;
20import org.openstreetmap.josm.tools.UserCancelException;
21import org.openstreetmap.josm.tools.Utils;
22
23/**
24 * A ReverseWayNoTagCorrector warns about ways that should not be reversed
25 * because their semantic meaning cannot be preserved in that case.
26 * E.g. natural=coastline, natural=cliff, barrier=retaining_wall cannot be changed.
27 * @see ReverseWayTagCorrector for handling of tags that can be modified (oneway=yes, etc.)
28 * @since 5724
29 */
30public final class ReverseWayNoTagCorrector {
31
32 private ReverseWayNoTagCorrector() {
33 // Hide default constructor for utils classes
34 }
35
36 /**
37 * Tags that imply a semantic meaning from the way direction and cannot be changed.
38 */
39 private static final TagCollection directionalTags = new TagCollection(Arrays.asList(new Tag[]{
40 new Tag("natural", "coastline"),
41 new Tag("natural", "cliff"),
42 new Tag("barrier", "guard_rail"),
43 new Tag("barrier", "kerb"),
44 new Tag("barrier", "retaining_wall"),
45 new Tag("man_made", "embankment"),
46 }));
47
48 /**
49 * Replies the tags that imply a semantic meaning from <code>way</code> direction and cannot be changed.
50 * @param way The way to look for
51 * @return tags that imply a semantic meaning from <code>way</code> direction and cannot be changed
52 */
53 public static TagCollection getDirectionalTags(Tagged way) {
54 final TagCollection collection = new TagCollection();
55 for (Map.Entry<String, String> entry : way.getKeys().entrySet()) {
56 final Tag tag = new Tag(entry.getKey(), entry.getValue());
57 final boolean isDirectional = directionalTags.contains(tag) || OsmPrimitive.directionalKeyPredicate.evaluate(tag);
58 if (isDirectional) {
59 final boolean cannotBeCorrected = ReverseWayTagCorrector.getTagCorrections(tag).isEmpty();
60 if (cannotBeCorrected) {
61 collection.add(tag);
62 }
63 }
64 }
65 return collection;
66 }
67
68 /**
69 * Tests whether way can be reversed without semantic change.
70 * Looks for tags like natural=cliff, barrier=retaining_wall.
71 * @param way The way to check
72 * @return false if the semantic meaning change if the way is reversed, true otherwise.
73 */
74 public static boolean isReversible(Tagged way) {
75 return getDirectionalTags(way).isEmpty();
76 }
77
78 protected static boolean confirmReverseWay(Way way, TagCollection tags) {
79 String msg = trn(
80 // Singular, if a single tag is impacted
81 "<html>You are going to reverse the way ''{0}'',"
82 + "<br/> whose semantic meaning of its tag ''{1}'' is defined by its direction.<br/>"
83 + "Do you really want to change the way direction, thus its semantic meaning?</html>",
84 // Plural, if several tags are impacted
85 "<html>You are going to reverse the way ''{0}'',"
86 + "<br/> whose semantic meaning of these tags are defined by its direction:<br/>{1}"
87 + "Do you really want to change the way direction, thus its semantic meaning?</html>",
88 tags.size(),
89 way.getDisplayName(DefaultNameFormatter.getInstance()),
90 Utils.joinAsHtmlUnorderedList(tags)
91 );
92 int ret = ConditionalOptionPaneUtil.showOptionDialog(
93 "reverse_directional_way",
94 Main.parent,
95 msg,
96 tr("Reverse directional way."),
97 JOptionPane.YES_NO_CANCEL_OPTION,
98 JOptionPane.WARNING_MESSAGE,
99 null,
100 null
101 );
102 switch(ret) {
103 case ConditionalOptionPaneUtil.DIALOG_DISABLED_OPTION:
104 case JOptionPane.YES_OPTION:
105 return true;
106 default:
107 return false;
108 }
109 }
110
111 /**
112 * Checks the given way can be safely reversed and asks user to confirm the operation if it not the case.
113 * @param way The way to check
114 * @throws UserCancelException If the user cancels the operation
115 */
116 public static void checkAndConfirmReverseWay(Way way) throws UserCancelException {
117 TagCollection tags = getDirectionalTags(way);
118 if (!tags.isEmpty() && !confirmReverseWay(way, tags)) {
119 throw new UserCancelException();
120 }
121 }
122}
Note: See TracBrowser for help on using the repository browser.