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

Last change on this file since 13750 was 13158, checked in by Don-vip, 6 years ago

javadoc

  • Property svn:eol-style set to native
File size: 9.3 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 presented 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 /**
52 * Executes the tag correction.
53 * @param oldprimitive old primitive
54 * @param primitive new primitive
55 * @return A list of commands
56 * @throws UserCancelException If the user canceled
57 * @see #applyCorrections(DataSet, Map, Map, String)
58 */
59 public abstract Collection<Command> execute(P oldprimitive, P primitive) throws UserCancelException;
60
61 private static final String[] APPLICATION_OPTIONS = new String[] {
62 tr("Apply selected changes"),
63 tr("Do not apply changes"),
64 tr("Cancel")
65 };
66
67 /**
68 * Creates the commands to correct the tags. Asks the users about it.
69 * @param dataSet The data set the primitives will be in once the commands are executed
70 * @param tagCorrectionsMap The possible tag corrections
71 * @param roleCorrectionMap The possible role corrections
72 * @param description A description to add to the dialog.
73 * @return A list of commands
74 * @throws UserCancelException If the user canceled
75 */
76 protected Collection<Command> applyCorrections(
77 DataSet dataSet,
78 Map<OsmPrimitive, List<TagCorrection>> tagCorrectionsMap,
79 Map<OsmPrimitive, List<RoleCorrection>> roleCorrectionMap,
80 String description) throws UserCancelException {
81
82 if (!tagCorrectionsMap.isEmpty() || !roleCorrectionMap.isEmpty()) {
83 Collection<Command> commands = new ArrayList<>();
84 Map<OsmPrimitive, TagCorrectionTable> tagTableMap = new HashMap<>();
85 Map<OsmPrimitive, RoleCorrectionTable> roleTableMap = new HashMap<>();
86
87 final JPanel p = new JPanel(new GridBagLayout());
88
89 final JMultilineLabel label1 = new JMultilineLabel(description);
90 label1.setMaxWidth(600);
91 p.add(label1, GBC.eop().anchor(GBC.CENTER).fill(GBC.HORIZONTAL));
92
93 final JMultilineLabel label2 = new JMultilineLabel(
94 tr("Please select which changes you want to apply."));
95 label2.setMaxWidth(600);
96 p.add(label2, GBC.eop().anchor(GBC.CENTER).fill(GBC.HORIZONTAL));
97
98 for (Entry<OsmPrimitive, List<TagCorrection>> entry : tagCorrectionsMap.entrySet()) {
99 final OsmPrimitive primitive = entry.getKey();
100 final List<TagCorrection> tagCorrections = entry.getValue();
101
102 if (tagCorrections.isEmpty()) {
103 continue;
104 }
105
106 final JLabel propertiesLabel = new JLabel(tr("Tags of "));
107 p.add(propertiesLabel, GBC.std());
108
109 final JLabel primitiveLabel = new JLabel(
110 primitive.getDisplayName(DefaultNameFormatter.getInstance()) + ':',
111 ImageProvider.get(primitive.getDisplayType()),
112 JLabel.LEFT
113 );
114 p.add(primitiveLabel, GBC.eol());
115
116 final TagCorrectionTable table = new TagCorrectionTable(
117 tagCorrections);
118 final JScrollPane scrollPane = new JScrollPane(table);
119 p.add(scrollPane, GBC.eop().fill(GBC.HORIZONTAL));
120
121 tagTableMap.put(primitive, table);
122 }
123
124 for (Entry<OsmPrimitive, List<RoleCorrection>> entry : roleCorrectionMap.entrySet()) {
125 final OsmPrimitive primitive = entry.getKey();
126 final List<RoleCorrection> roleCorrections = entry.getValue();
127
128 if (roleCorrections.isEmpty()) {
129 continue;
130 }
131
132 final JLabel rolesLabel = new JLabel(tr("Roles in relations referring to"));
133 p.add(rolesLabel, GBC.std());
134
135 final JLabel primitiveLabel = new JLabel(
136 primitive.getDisplayName(DefaultNameFormatter.getInstance()),
137 ImageProvider.get(primitive.getDisplayType()),
138 JLabel.LEFT
139 );
140 p.add(primitiveLabel, GBC.eol());
141 rolesLabel.setLabelFor(primitiveLabel);
142
143 final RoleCorrectionTable table = new RoleCorrectionTable(roleCorrections);
144 final JScrollPane scrollPane = new JScrollPane(table);
145 p.add(scrollPane, GBC.eop().fill(GBC.HORIZONTAL));
146 primitiveLabel.setLabelFor(table);
147
148 roleTableMap.put(primitive, table);
149 }
150
151 int answer = JOptionPane.showOptionDialog(
152 Main.parent,
153 p,
154 tr("Automatic tag correction"),
155 JOptionPane.YES_NO_CANCEL_OPTION,
156 JOptionPane.PLAIN_MESSAGE,
157 null,
158 APPLICATION_OPTIONS,
159 APPLICATION_OPTIONS[0]
160 );
161
162 if (answer == JOptionPane.YES_OPTION) {
163 for (Entry<OsmPrimitive, List<TagCorrection>> entry : tagCorrectionsMap.entrySet()) {
164 OsmPrimitive primitive = entry.getKey();
165
166 // create the clone
167 OsmPrimitive clone;
168 if (primitive instanceof Way) {
169 clone = new Way((Way) primitive);
170 } else if (primitive instanceof Node) {
171 clone = new Node((Node) primitive);
172 } else if (primitive instanceof Relation) {
173 clone = new Relation((Relation) primitive);
174 } else
175 throw new AssertionError();
176
177 // use this structure to remember keys that have been set already so that
178 // they're not dropped by a later step
179 Set<String> keysChanged = new HashSet<>();
180
181 // apply all changes to this clone
182 List<TagCorrection> tagCorrections = entry.getValue();
183 for (int i = 0; i < tagCorrections.size(); i++) {
184 if (tagTableMap.get(primitive).getCorrectionTableModel().getApply(i)) {
185 TagCorrection tagCorrection = tagCorrections.get(i);
186 if (tagCorrection.isKeyChanged() && !keysChanged.contains(tagCorrection.oldKey)) {
187 clone.remove(tagCorrection.oldKey);
188 }
189 clone.put(tagCorrection.newKey, tagCorrection.newValue);
190 keysChanged.add(tagCorrection.newKey);
191 }
192 }
193
194 // save the clone
195 if (!keysChanged.isEmpty()) {
196 commands.add(new ChangeCommand(dataSet, primitive, clone));
197 }
198 }
199 for (Entry<OsmPrimitive, List<RoleCorrection>> entry : roleCorrectionMap.entrySet()) {
200 OsmPrimitive primitive = entry.getKey();
201 List<RoleCorrection> roleCorrections = entry.getValue();
202
203 for (int i = 0; i < roleCorrections.size(); i++) {
204 RoleCorrection roleCorrection = roleCorrections.get(i);
205 if (roleTableMap.get(primitive).getCorrectionTableModel().getApply(i)) {
206 commands.add(new ChangeRelationMemberRoleCommand(dataSet,
207 roleCorrection.relation, roleCorrection.position, roleCorrection.newRole));
208 }
209 }
210 }
211 } else if (answer != JOptionPane.NO_OPTION)
212 throw new UserCancelException();
213 return commands;
214 }
215
216 return Collections.emptyList();
217 }
218}
Note: See TracBrowser for help on using the repository browser.