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

Last change on this file since 10763 was 10763, checked in by Don-vip, 3 years ago

sonar - squid:S2156 - "final" classes should not have "protected" members

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