source: josm/trunk/src/org/openstreetmap/josm/corrector/TagCorrector.java@ 12984

Last change on this file since 12984 was 12663, checked in by Don-vip, 7 years ago

see #15182 - move NameFormatter* from gui to data.osm

  • Property svn:eol-style set to native
File size: 9.1 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.corrector;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.GridBagLayout;
7import java.util.ArrayList;
8import java.util.Collection;
9import java.util.Collections;
10import java.util.HashMap;
11import java.util.HashSet;
12import java.util.List;
13import java.util.Map;
14import java.util.Map.Entry;
15import java.util.Set;
16
17import javax.swing.JLabel;
18import javax.swing.JOptionPane;
19import javax.swing.JPanel;
20import javax.swing.JScrollPane;
21
22import org.openstreetmap.josm.Main;
23import org.openstreetmap.josm.command.ChangeCommand;
24import org.openstreetmap.josm.command.ChangeRelationMemberRoleCommand;
25import org.openstreetmap.josm.command.Command;
26import org.openstreetmap.josm.data.correction.RoleCorrection;
27import org.openstreetmap.josm.data.correction.TagCorrection;
28import org.openstreetmap.josm.data.osm.DataSet;
29import org.openstreetmap.josm.data.osm.DefaultNameFormatter;
30import org.openstreetmap.josm.data.osm.Node;
31import org.openstreetmap.josm.data.osm.OsmPrimitive;
32import org.openstreetmap.josm.data.osm.Relation;
33import org.openstreetmap.josm.data.osm.Way;
34import org.openstreetmap.josm.gui.correction.RoleCorrectionTable;
35import org.openstreetmap.josm.gui.correction.TagCorrectionTable;
36import org.openstreetmap.josm.gui.widgets.JMultilineLabel;
37import org.openstreetmap.josm.tools.GBC;
38import org.openstreetmap.josm.tools.ImageProvider;
39import org.openstreetmap.josm.tools.UserCancelException;
40
41/**
42 * Abstract base class for automatic tag corrections.
43 *
44 * Subclasses call applyCorrections() with maps of the requested
45 * corrections and a dialog is pesented to the user to
46 * confirm these changes.
47 * @param <P> The type of OSM primitive to correct
48 */
49public abstract class TagCorrector<P extends OsmPrimitive> {
50
51 public abstract Collection<Command> execute(P oldprimitive, P primitive) throws UserCancelException;
52
53 private static final String[] APPLICATION_OPTIONS = new String[] {
54 tr("Apply selected changes"),
55 tr("Do not apply changes"),
56 tr("Cancel")
57 };
58
59 /**
60 * Creates the commands to correct the tags. Asks the users about it.
61 * @param dataSet The data set the primitives will be in once the commands are executed
62 * @param tagCorrectionsMap The possible tag corrections
63 * @param roleCorrectionMap The possible role corrections
64 * @param description A description to add to the dialog.
65 * @return A list of commands
66 * @throws UserCancelException If the user canceled
67 */
68 protected Collection<Command> applyCorrections(
69 DataSet dataSet,
70 Map<OsmPrimitive, List<TagCorrection>> tagCorrectionsMap,
71 Map<OsmPrimitive, List<RoleCorrection>> roleCorrectionMap,
72 String description) throws UserCancelException {
73
74 if (!tagCorrectionsMap.isEmpty() || !roleCorrectionMap.isEmpty()) {
75 Collection<Command> commands = new ArrayList<>();
76 Map<OsmPrimitive, TagCorrectionTable> tagTableMap = new HashMap<>();
77 Map<OsmPrimitive, RoleCorrectionTable> roleTableMap = new HashMap<>();
78
79 final JPanel p = new JPanel(new GridBagLayout());
80
81 final JMultilineLabel label1 = new JMultilineLabel(description);
82 label1.setMaxWidth(600);
83 p.add(label1, GBC.eop().anchor(GBC.CENTER).fill(GBC.HORIZONTAL));
84
85 final JMultilineLabel label2 = new JMultilineLabel(
86 tr("Please select which changes you want to apply."));
87 label2.setMaxWidth(600);
88 p.add(label2, GBC.eop().anchor(GBC.CENTER).fill(GBC.HORIZONTAL));
89
90 for (Entry<OsmPrimitive, List<TagCorrection>> entry : tagCorrectionsMap.entrySet()) {
91 final OsmPrimitive primitive = entry.getKey();
92 final List<TagCorrection> tagCorrections = entry.getValue();
93
94 if (tagCorrections.isEmpty()) {
95 continue;
96 }
97
98 final JLabel propertiesLabel = new JLabel(tr("Tags of "));
99 p.add(propertiesLabel, GBC.std());
100
101 final JLabel primitiveLabel = new JLabel(
102 primitive.getDisplayName(DefaultNameFormatter.getInstance()) + ':',
103 ImageProvider.get(primitive.getDisplayType()),
104 JLabel.LEFT
105 );
106 p.add(primitiveLabel, GBC.eol());
107
108 final TagCorrectionTable table = new TagCorrectionTable(
109 tagCorrections);
110 final JScrollPane scrollPane = new JScrollPane(table);
111 p.add(scrollPane, GBC.eop().fill(GBC.HORIZONTAL));
112
113 tagTableMap.put(primitive, table);
114 }
115
116 for (Entry<OsmPrimitive, List<RoleCorrection>> entry : roleCorrectionMap.entrySet()) {
117 final OsmPrimitive primitive = entry.getKey();
118 final List<RoleCorrection> roleCorrections = entry.getValue();
119
120 if (roleCorrections.isEmpty()) {
121 continue;
122 }
123
124 final JLabel rolesLabel = new JLabel(tr("Roles in relations referring to"));
125 p.add(rolesLabel, GBC.std());
126
127 final JLabel primitiveLabel = new JLabel(
128 primitive.getDisplayName(DefaultNameFormatter.getInstance()),
129 ImageProvider.get(primitive.getDisplayType()),
130 JLabel.LEFT
131 );
132 p.add(primitiveLabel, GBC.eol());
133 rolesLabel.setLabelFor(primitiveLabel);
134
135 final RoleCorrectionTable table = new RoleCorrectionTable(roleCorrections);
136 final JScrollPane scrollPane = new JScrollPane(table);
137 p.add(scrollPane, GBC.eop().fill(GBC.HORIZONTAL));
138 primitiveLabel.setLabelFor(table);
139
140 roleTableMap.put(primitive, table);
141 }
142
143 int answer = JOptionPane.showOptionDialog(
144 Main.parent,
145 p,
146 tr("Automatic tag correction"),
147 JOptionPane.YES_NO_CANCEL_OPTION,
148 JOptionPane.PLAIN_MESSAGE,
149 null,
150 APPLICATION_OPTIONS,
151 APPLICATION_OPTIONS[0]
152 );
153
154 if (answer == JOptionPane.YES_OPTION) {
155 for (Entry<OsmPrimitive, List<TagCorrection>> entry : tagCorrectionsMap.entrySet()) {
156 OsmPrimitive primitive = entry.getKey();
157
158 // create the clone
159 OsmPrimitive clone;
160 if (primitive instanceof Way) {
161 clone = new Way((Way) primitive);
162 } else if (primitive instanceof Node) {
163 clone = new Node((Node) primitive);
164 } else if (primitive instanceof Relation) {
165 clone = new Relation((Relation) primitive);
166 } else
167 throw new AssertionError();
168
169 // use this structure to remember keys that have been set already so that
170 // they're not dropped by a later step
171 Set<String> keysChanged = new HashSet<>();
172
173 // apply all changes to this clone
174 List<TagCorrection> tagCorrections = entry.getValue();
175 for (int i = 0; i < tagCorrections.size(); i++) {
176 if (tagTableMap.get(primitive).getCorrectionTableModel().getApply(i)) {
177 TagCorrection tagCorrection = tagCorrections.get(i);
178 if (tagCorrection.isKeyChanged() && !keysChanged.contains(tagCorrection.oldKey)) {
179 clone.remove(tagCorrection.oldKey);
180 }
181 clone.put(tagCorrection.newKey, tagCorrection.newValue);
182 keysChanged.add(tagCorrection.newKey);
183 }
184 }
185
186 // save the clone
187 if (!keysChanged.isEmpty()) {
188 commands.add(new ChangeCommand(dataSet, primitive, clone));
189 }
190 }
191 for (Entry<OsmPrimitive, List<RoleCorrection>> entry : roleCorrectionMap.entrySet()) {
192 OsmPrimitive primitive = entry.getKey();
193 List<RoleCorrection> roleCorrections = entry.getValue();
194
195 for (int i = 0; i < roleCorrections.size(); i++) {
196 RoleCorrection roleCorrection = roleCorrections.get(i);
197 if (roleTableMap.get(primitive).getCorrectionTableModel().getApply(i)) {
198 commands.add(new ChangeRelationMemberRoleCommand(dataSet,
199 roleCorrection.relation, roleCorrection.position, roleCorrection.newRole));
200 }
201 }
202 }
203 } else if (answer != JOptionPane.NO_OPTION)
204 throw new UserCancelException();
205 return commands;
206 }
207
208 return Collections.emptyList();
209 }
210}
Note: See TracBrowser for help on using the repository browser.