Ticket #23521: 23521-alpha.patch
File 23521-alpha.patch, 51.7 KB (added by , 11 months ago) |
---|
-
src/relcontext/RelContextDialog.java
17 17 import java.awt.event.MouseAdapter; 18 18 import java.awt.event.MouseEvent; 19 19 import java.awt.event.MouseListener; 20 import java.beans.PropertyChangeEvent;21 import java.beans.PropertyChangeListener;22 20 import java.io.BufferedReader; 23 21 import java.io.InputStream; 24 22 import java.io.InputStreamReader; … … 50 48 import javax.swing.JTable; 51 49 import javax.swing.ListSelectionModel; 52 50 import javax.swing.SwingUtilities; 53 import javax.swing.event.ListSelectionEvent;54 import javax.swing.event.ListSelectionListener;55 51 import javax.swing.table.DefaultTableCellRenderer; 56 52 import javax.swing.table.DefaultTableModel; 57 53 import javax.swing.table.TableColumnModel; … … 110 106 public static final String PREF_PREFIX = "reltoolbox"; 111 107 112 108 private final DefaultTableModel relationsData; 113 private final ChosenRelation chosenRelation;109 private final transient ChosenRelation chosenRelation; 114 110 private final JPanel chosenRelationPanel; 115 111 private final ChosenRelationPopupMenu popupMenu; 116 112 private final MultipolygonSettingsPopup multiPopupMenu; … … 412 408 413 409 @Override 414 410 public void destroy() { 411 chosenRelation.removeChosenRelationListener(this); 415 412 enterRoleAction.destroy(); 416 413 findRelationAction.destroy(); 417 414 createMultipolygonAction.destroy(); … … 486 483 dlg.setVisible(true); 487 484 488 485 Object answer = optionPane.getValue(); 486 dlg.dispose(); 489 487 if (answer == null || answer == JOptionPane.UNINITIALIZED_VALUE 490 488 || (answer instanceof Integer && (Integer) answer != JOptionPane.OK_OPTION)) 491 489 return null; … … 544 542 List<Command> commands = new ArrayList<>(); 545 543 for (int i = 0; i < r.getMembersCount(); i++) { 546 544 RelationMember m = r.getMember(i); 547 if (selected.contains(m.getMember())) { 548 if (!role.equals(m.getRole())) { 549 commands.add(new ChangeRelationMemberRoleCommand(r, i, role)); 550 } 545 if (selected.contains(m.getMember()) && !role.equals(m.getRole())) { 546 commands.add(new ChangeRelationMemberRoleCommand(r, i, role)); 551 547 } 552 548 } 553 549 if (!commands.isEmpty()) { 554 // UndoRedoHandler.getInstance().add(new ChangeCommand(chosenRelation.get(), r));555 550 UndoRedoHandler.getInstance().add(new SequenceCommand(tr("Change relation member roles to {0}", role), commands)); 556 551 } 557 552 } -
src/relcontext/actions/AddRemoveMemberAction.java
9 9 import java.util.Collection; 10 10 11 11 import org.openstreetmap.josm.actions.JosmAction; 12 import org.openstreetmap.josm.command.Change Command;12 import org.openstreetmap.josm.command.ChangeMembersCommand; 13 13 import org.openstreetmap.josm.command.Command; 14 14 import org.openstreetmap.josm.data.UndoRedoHandler; 15 15 import org.openstreetmap.josm.data.osm.DataSet; … … 81 81 } 82 82 83 83 if (!r.getMemberPrimitives().equals(rel.get().getMemberPrimitives())) { 84 UndoRedoHandler.getInstance().add(new Change Command(rel.get(), r));84 UndoRedoHandler.getInstance().add(new ChangeMembersCommand(rel.get(), r.getMembers())); 85 85 } 86 r.setMembers(null); // See #19885 86 87 } 87 88 88 89 /** … … 95 96 96 97 if (firstNode != null && !firstNode.equals(lastNode)) { 97 98 for (int i = 0; i < r.getMembersCount(); i++) { 98 if (r.getMember(i).getType() .equals(OsmPrimitiveType.WAY)) {99 if (r.getMember(i).getType() == OsmPrimitiveType.WAY) { 99 100 Way rw = (Way) r.getMember(i).getMember(); 100 101 Node firstNodeR = rw.firstNode(); 101 102 Node lastNodeR = rw.lastNode(); … … 132 133 } 133 134 134 135 protected void updateIcon() { 135 // todo: change icon based on selection136 136 final int state; // 0=unknown, 1=add, 2=remove, 3=both 137 137 DataSet ds = getLayerManager().getEditDataSet(); 138 if (ds == null || ds.getSelected() == null 139 || ds.getSelected().isEmpty() || rel == null || rel.get() == null) { 138 if (ds == null || ds.getSelected().isEmpty() || rel == null || rel.get() == null) { 140 139 state = 0; 141 140 } else { 142 141 Collection<OsmPrimitive> toAdd = new ArrayList<>(ds.getSelected()); … … 155 154 } 156 155 } 157 156 } 158 GuiHelper.runInEDT(new Runnable() { 159 @Override 160 public void run() { 161 if (state == 0) { 162 putValue(LARGE_ICON_KEY, ImageProvider.get("relcontext", "addremove")); 163 } else { 164 String iconName = state == 1 ? "add" : state == 2 ? "remove" : "addremove"; 165 putValue(NAME, null); 166 putValue(LARGE_ICON_KEY, ImageProvider.get("relcontext", iconName)); 167 } 157 GuiHelper.runInEDT(() -> { 158 if (state == 0) { 159 putValue(LARGE_ICON_KEY, ImageProvider.get("relcontext", "addremove")); 160 } else { 161 String iconName = state == 1 ? "add" : state == 2 ? "remove" : "addremove"; 162 putValue(NAME, null); 163 putValue(LARGE_ICON_KEY, ImageProvider.get("relcontext", iconName)); 168 164 } 169 165 }); 170 166 } -
src/relcontext/actions/ClearChosenRelationAction.java
15 15 import relcontext.ChosenRelationListener; 16 16 17 17 public class ClearChosenRelationAction extends AbstractAction implements ChosenRelationListener { 18 private final ChosenRelation rel;18 private final transient ChosenRelation rel; 19 19 20 20 public ClearChosenRelationAction(ChosenRelation rel) { 21 21 super(); -
src/relcontext/actions/CreateMultipolygonAction.java
6 6 import java.awt.Dialog.ModalityType; 7 7 import java.awt.GridBagLayout; 8 8 import java.awt.event.ActionEvent; 9 import java.awt.event.ActionListener;10 9 import java.awt.event.KeyEvent; 11 10 import java.util.ArrayList; 12 11 import java.util.Arrays; 13 12 import java.util.Collection; 13 import java.util.Collections; 14 14 import java.util.HashMap; 15 15 import java.util.HashSet; 16 16 import java.util.List; 17 17 import java.util.Map; 18 import java.util.Map.Entry; 18 19 import java.util.Set; 19 20 import java.util.TreeSet; 20 21 … … 27 28 28 29 import org.openstreetmap.josm.actions.JosmAction; 29 30 import org.openstreetmap.josm.command.AddCommand; 30 import org.openstreetmap.josm.command.ChangeCommand;31 31 import org.openstreetmap.josm.command.ChangePropertyCommand; 32 32 import org.openstreetmap.josm.command.Command; 33 33 import org.openstreetmap.josm.command.SequenceCommand; … … 39 39 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 40 40 import org.openstreetmap.josm.data.osm.Relation; 41 41 import org.openstreetmap.josm.data.osm.RelationMember; 42 import org.openstreetmap.josm.data.osm.TagMap; 42 43 import org.openstreetmap.josm.data.osm.Way; 43 44 import org.openstreetmap.josm.gui.MainApplication; 44 45 import org.openstreetmap.josm.spi.preferences.Config; … … 55 56 */ 56 57 public class CreateMultipolygonAction extends JosmAction { 57 58 private static final String PREF_MULTIPOLY = "reltoolbox.multipolygon."; 58 protected ChosenRelation chRel;59 protected transient ChosenRelation chRel; 59 60 60 61 public CreateMultipolygonAction(ChosenRelation chRel) { 61 62 super("Multi", "data/multipolygon", tr("Create a multipolygon from selected objects"), … … 71 72 72 73 public static boolean getDefaultPropertyValue(String property) { 73 74 switch (property) { 74 75 76 77 78 79 80 81 75 case "boundary": 76 case "alltags": 77 case "allowsplit": 78 return false; 79 case "boundaryways": 80 case "tags": 81 case "single": 82 return true; 82 83 } 83 84 throw new IllegalArgumentException(property); 84 85 } 85 86 86 private boolean getPref(String property) {87 private static boolean getPref(String property) { 87 88 return Config.getPref().getBoolean(PREF_MULTIPOLY + property, getDefaultPropertyValue(property)); 88 89 } 89 90 … … 96 97 List<Relation> rels = null; 97 98 if (getPref("allowsplit") || selectedWays.size() == 1) { 98 99 if (SplittingMultipolygons.canProcess(selectedWays)) { 99 rels = SplittingMultipolygons.process( ds.getSelectedWays());100 rels = SplittingMultipolygons.process(selectedWays); 100 101 } 101 102 } else { 102 103 if (TheRing.areAllOfThoseRings(selectedWays)) { … … 200 201 private void addBoundaryMembers(Relation rel) { 201 202 for (OsmPrimitive p : getLayerManager().getEditDataSet().getSelected()) { 202 203 String role = null; 203 if (p.getType() .equals(OsmPrimitiveType.RELATION)) {204 if (p.getType() == OsmPrimitiveType.RELATION) { 204 205 role = "subarea"; 205 } else if (p.getType() .equals(OsmPrimitiveType.NODE)) {206 } else if (p.getType() == OsmPrimitiveType.NODE) { 206 207 Node n = (Node) p; 207 208 if (!n.isIncomplete()) { 208 209 if (n.hasKey("place")) { … … 318 319 boolean isBoundary = getPref("boundary"); 319 320 if (isBoundary || !getPref("alltags")) { 320 321 for (RelationMember m : relation.getMembers()) { 321 if (m.hasRole() && m.getRole().equals("outer") && m.isWay()) {322 if (m.hasRole() && "outer".equals(m.getRole()) && m.isWay()) { 322 323 for (String key : values.keySet()) { 323 324 if (!m.getWay().hasKey(key) && !relation.hasKey(key)) { 324 325 conflictingKeys.add(key); … … 336 337 values.remove(linearTag); 337 338 } 338 339 339 if ( values.containsKey("natural") && values.get("natural").equals("coastline")) {340 if ("coastline".equals(values.get("natural"))) { 340 341 values.remove("natural"); 341 342 } 342 343 … … 355 356 List<Command> commands = new ArrayList<>(); 356 357 boolean moveTags = getPref("tags"); 357 358 358 for (String key : values.keySet()) { 359 for (Entry<String, String> entry : values.entrySet()) { 360 String key = entry.getKey(); 359 361 List<OsmPrimitive> affectedWays = new ArrayList<>(); 360 String value = values.get(key);362 String value = entry.getValue(); 361 363 362 364 for (Way way : innerWays) { 363 365 if (way.hasKey(key) && (isBoundary || value.equals(way.get(key)))) { … … 374 376 } 375 377 } 376 378 377 if ( affectedWays.size() > 0) {379 if (!affectedWays.isEmpty()) { 378 380 commands.add(new ChangePropertyCommand(affectedWays, key, null)); 379 381 } 380 382 } … … 385 387 values.put("name", name); 386 388 } 387 389 boolean fixed = false; 388 Relation r2 = new Relation(relation); 389 for (String key : values.keySet()) { 390 if (!r2.hasKey(key) && !key.equals("area") 391 && (!isBoundary || key.equals("admin_level") || key.equals("name"))) { 392 if (relation.isNew()) { 393 relation.put(key, values.get(key)); 390 TagMap tags = relation.getKeys(); 391 for (Entry<String, String> e: values.entrySet()) { 392 final String key = e.getKey(); 393 final String val = e.getValue(); 394 if (!tags.containsKey(key) && !"area".equals(key) 395 && (!isBoundary || "admin_level".equals(key) || "name".equals(key))) { 396 if (relation.getDataSet() == null) { 397 relation.put(key, val); 394 398 } else { 395 r2.put(key, values.get(key));399 tags.put(key, val); 396 400 } 397 401 fixed = true; 398 402 } 399 403 } 400 if (fixed && !relation.isNew()) {401 commands.add(new Change Command(relation, r2));404 if (fixed && relation.getDataSet() != null) { 405 commands.add(new ChangePropertyCommand(Collections.singleton(relation), tags)); 402 406 } 403 407 } 404 408 … … 443 447 final JDialog dlg = optionPane.createDialog(MainApplication.getMainFrame(), tr("Create a new relation")); 444 448 dlg.setModalityType(ModalityType.DOCUMENT_MODAL); 445 449 446 name.addActionListener(new ActionListener() { 447 @Override 448 public void actionPerformed(ActionEvent e) { 449 dlg.setVisible(false); 450 optionPane.setValue(JOptionPane.OK_OPTION); 451 } 450 name.addActionListener(e -> { 451 dlg.setVisible(false); 452 optionPane.setValue(JOptionPane.OK_OPTION); 452 453 }); 453 454 454 455 dlg.setVisible(true); 455 456 456 457 Object answer = optionPane.getValue(); 458 dlg.dispose(); 457 459 if (answer == null || answer == JOptionPane.UNINITIALIZED_VALUE 458 460 || (answer instanceof Integer && (Integer) answer != JOptionPane.OK_OPTION)) 459 461 return false; 460 462 461 String admin _level = admin.getText().trim();462 String new _name = name.getText().trim();463 if ( admin_level.equals("10") || (admin_level.length() == 1 && Character.isDigit(admin_level.charAt(0)))) {464 rel.put("admin_level", admin _level);465 Config.getPref().put(PREF_MULTIPOLY + "lastadmin", admin _level);463 String adminLevel = admin.getText().trim(); 464 String newName = name.getText().trim(); 465 if ("10".equals(adminLevel) || (adminLevel.length() == 1 && Character.isDigit(adminLevel.charAt(0)))) { 466 rel.put("admin_level", adminLevel); 467 Config.getPref().put(PREF_MULTIPOLY + "lastadmin", adminLevel); 466 468 } 467 if ( new_name.length() > 0) {468 rel.put("name", new _name);469 if (!newName.isEmpty()) { 470 rel.put("name", newName); 469 471 } 470 472 return true; 471 473 } -
src/relcontext/actions/CreateRelationAction.java
126 126 dlg.setVisible(true); 127 127 128 128 Object answer = optionPane.getValue(); 129 dlg.dispose(); 129 130 if (answer == null || answer == JOptionPane.UNINITIALIZED_VALUE 130 131 || (answer instanceof Integer && (Integer) answer != JOptionPane.OK_OPTION)) 131 132 return null; -
src/relcontext/actions/FindRelationAction.java
122 122 dlg.setVisible(true); 123 123 124 124 Object answer = optionPane.getValue(); 125 dlg.dispose(); 126 125 127 if (answer == null || answer == JOptionPane.UNINITIALIZED_VALUE 126 128 || (answer instanceof Integer && (Integer) answer != JOptionPane.OK_OPTION)) 127 129 return; -
src/relcontext/actions/ReconstructPolygonAction.java
7 7 import java.awt.event.KeyEvent; 8 8 import java.util.ArrayList; 9 9 import java.util.Arrays; 10 import java.util.Collection; 10 11 import java.util.Collections; 11 12 import java.util.HashSet; 12 13 import java.util.List; … … 18 19 import org.openstreetmap.josm.actions.JosmAction; 19 20 import org.openstreetmap.josm.command.AddCommand; 20 21 import org.openstreetmap.josm.command.ChangeCommand; 22 import org.openstreetmap.josm.command.ChangeMembersCommand; 21 23 import org.openstreetmap.josm.command.Command; 22 24 import org.openstreetmap.josm.command.DeleteCommand; 23 25 import org.openstreetmap.josm.command.SequenceCommand; … … 42 44 * @author Zverik 43 45 */ 44 46 public class ReconstructPolygonAction extends JosmAction implements ChosenRelationListener { 45 private final ChosenRelation rel;47 private final transient ChosenRelation rel; 46 48 47 49 private static final List<String> IRRELEVANT_KEYS = Arrays.asList("source", "created_by", "note"); 48 50 51 /** 52 * Reconstruct one or more polygons from multipolygon relation. 53 * @param rel the multipolygon relation 54 */ 49 55 public ReconstructPolygonAction(ChosenRelation rel) { 50 56 super(tr("Reconstruct polygon"), "dialogs/filter", tr("Reconstruct polygon from multipolygon relation"), 51 57 Shortcut.registerShortcut("reltoolbox:reconstructpoly", tr("Relation Toolbox: {0}", 52 58 tr("Reconstruct polygon from multipolygon relation")), 53 KeyEvent.CHAR_UNDEFINED, Shortcut.NONE), false );59 KeyEvent.CHAR_UNDEFINED, Shortcut.NONE), false, false); 54 60 this.rel = rel; 55 61 rel.addChosenRelationListener(this); 56 62 setEnabled(isSuitableRelation(rel.get())); … … 71 77 } 72 78 if (wont) { 73 79 JOptionPane.showMessageDialog(MainApplication.getMainFrame(), 74 tr("Multipolygon must consist only of ways with one referring relation"),80 tr("Multipolygon must consist only of ways"), 75 81 tr("Reconstruct polygon"), JOptionPane.ERROR_MESSAGE); 76 82 return; 77 83 } … … 84 90 } 85 91 86 92 rel.clear(); 87 List<OsmPrimitive> newSelection = new ArrayList<>();88 93 List<Command> commands = new ArrayList<>(); 89 94 Command relationDeleteCommand = DeleteCommand.delete(Collections.singleton(r), true, true); 90 95 if (relationDeleteCommand == null) … … 107 112 if (!myInnerWays.isEmpty()) { 108 113 // this ring has inner rings, so we leave a multipolygon in 109 114 // place and don't reconstruct the rings. 115 List<RelationMember> members = new ArrayList<>(); 110 116 Relation n; 111 if (relationReused) {112 n = new Relation();113 n.setKeys(r.getKeys());114 } else {115 n = new Relation(r);116 n.setMembers(null);117 }118 117 for (Way w : p.ways) { 119 n.addMember(new RelationMember("outer", w));118 members.add(new RelationMember("outer", w)); 120 119 } 121 120 for (JoinedPolygon i : myInnerWays) { 122 121 for (Way w : i.ways) { 123 n.addMember(new RelationMember("inner", w));122 members.add(new RelationMember("inner", w)); 124 123 } 125 124 } 126 125 if (relationReused) { 126 n = new Relation(); 127 n.setKeys(r.getKeys()); 128 n.setMembers(members); 127 129 commands.add(new AddCommand(ds, n)); 128 130 } else { 129 131 relationReused = true; 130 commands.add(new Change Command(r, n));132 commands.add(new ChangeMembersCommand(r, members)); 131 133 } 132 newSelection.add(n);133 134 continue; 134 135 } 135 136 … … 185 186 result.setNodes(p.nodes); 186 187 result.addNode(result.firstNode()); 187 188 result.setKeys(tags); 188 newSelection.add(candidateWay == null ? result : candidateWay);189 189 commands.add(candidateWay == null ? new AddCommand(ds, result) : new ChangeCommand(candidateWay, result)); 190 190 } 191 191 … … 194 194 // The relation needs to be deleted first, so that undo/redo continue to work properly 195 195 commands.add(0, relationDeleteCommand); 196 196 } 197 198 197 UndoRedoHandler.getInstance().add(new SequenceCommand(tr("Reconstruct polygons from relation {0}", 199 198 r.getDisplayName(DefaultNameFormatter.getInstance())), commands)); 199 Collection<? extends OsmPrimitive> newSelection = UndoRedoHandler.getInstance().getLastCommand().getParticipatingPrimitives(); 200 newSelection.removeIf(p -> p.isDeleted()); 200 201 ds.setSelected(newSelection); 201 202 } 202 203 -
src/relcontext/actions/ReconstructRouteAction.java
12 12 13 13 import javax.swing.AbstractAction; 14 14 15 import org.openstreetmap.josm.command.ChangeCommand; 16 import org.openstreetmap.josm.command.Command; 15 import org.openstreetmap.josm.command.ChangeMembersCommand; 17 16 import org.openstreetmap.josm.data.UndoRedoHandler; 18 17 import org.openstreetmap.josm.data.coor.EastNorth; 19 18 import org.openstreetmap.josm.data.osm.Node; … … 34 33 * @author freeExec 35 34 */ 36 35 public class ReconstructRouteAction extends AbstractAction implements ChosenRelationListener { 37 private final ChosenRelation rel;36 private final transient ChosenRelation rel; 38 37 38 /** 39 * Reconstruct route relation to scheme of public_transport. 40 * @param rel chosen relation 41 */ 39 42 public ReconstructRouteAction(ChosenRelation rel) { 40 43 super(tr("Reconstruct route")); 41 44 putValue(SMALL_ICON, ImageProvider.get("dialogs", "filter")); … … 48 51 @Override 49 52 public void actionPerformed(ActionEvent e) { 50 53 Relation r = rel.get(); 51 Relation recRel = new Relation(r); 52 recRel.removeMembersFor(recRel.getMemberPrimitives()); 54 List<RelationMember> recMembers = new ArrayList<>(); 53 55 54 56 Map<OsmPrimitive, RelationMember> stopMembers = new LinkedHashMap<>(); 55 57 Map<String, List<RelationMember>> platformMembers = new LinkedHashMap<>(); … … 117 119 nIndex != wayNodeEndIndex; 118 120 nIndex += increment) { 119 121 Node refNode = w.getNode(nIndex); 120 if (PublicTransportHelper.isNodeStop(refNode)) { 121 if (stopMembers.containsKey(refNode)) { 122 recRel.addMember(stopMembers.get(refNode)); 123 stopMembers.remove(refNode); 124 String stopName = PublicTransportHelper.getNameViaStoparea(refNode); 125 if (stopName == null) { 126 stopName = ""; 122 if (!(PublicTransportHelper.isNodeStop(refNode) && stopMembers.containsKey(refNode))) 123 continue; 124 recMembers.add(stopMembers.get(refNode)); 125 stopMembers.remove(refNode); 126 String stopName = PublicTransportHelper.getNameViaStoparea(refNode); 127 if (stopName == null) { 128 stopName = ""; 129 } 130 boolean existsPlatform = platformMembers.containsKey(stopName); 131 if (!existsPlatform) { 132 stopName = ""; // find of the nameless 133 } 134 if (existsPlatform || platformMembers.containsKey(stopName)) { 135 List<RelationMember> lMember = platformMembers.get(stopName); 136 if (lMember.size() == 1) { 137 recMembers.add(lMember.get(0)); 138 lMember.remove(0); 139 } else { 140 // choose closest 141 RelationMember candidat = getClosestPlatform(lMember, refNode); 142 if (candidat != null) { 143 recMembers.add(candidat); 144 lMember.remove(candidat); 127 145 } 128 boolean existsPlatform = platformMembers.containsKey(stopName);129 if (!existsPlatform) {130 stopName = ""; // find of the nameless131 }132 if (existsPlatform || platformMembers.containsKey(stopName)) {133 List<RelationMember> lMember = platformMembers.get(stopName);134 if (lMember.size() == 1) {135 recRel.addMember(lMember.get(0));136 lMember.remove(0);137 } else {138 // choose closest139 RelationMember candidat = getClosestPlatform(lMember, refNode);140 if (candidat != null) {141 recRel.addMember(candidat);142 lMember.remove(candidat);143 }144 }145 if (lMember.isEmpty()) {146 platformMembers.remove(stopName);147 }148 }149 146 } 147 if (lMember.isEmpty()) { 148 platformMembers.remove(stopName); 149 } 150 150 } 151 151 } 152 152 } 153 153 154 154 for (RelationMember stop : stopMembers.values()) { 155 rec Rel.addMember(stop);155 recMembers.add(stop); 156 156 String stopName = PublicTransportHelper.getNameViaStoparea(stop); 157 157 boolean existsPlatform = platformMembers.containsKey(stopName); 158 158 if (!existsPlatform) { … … 161 161 if (existsPlatform || platformMembers.containsKey(stopName)) { 162 162 List<RelationMember> lMember = platformMembers.get(stopName); 163 163 if (lMember.size() == 1) { 164 rec Rel.addMember(lMember.get(0));164 recMembers.add(lMember.get(0)); 165 165 lMember.remove(0); 166 166 } else { 167 167 // choose closest 168 168 RelationMember candidat = getClosestPlatform(lMember, stop.getNode()); 169 169 if (candidat != null) { 170 rec Rel.addMember(candidat);170 recMembers.add(candidat); 171 171 lMember.remove(candidat); 172 172 } 173 173 } … … 179 179 180 180 for (List<RelationMember> lPlatforms : platformMembers.values()) { 181 181 for (RelationMember platform : lPlatforms) { 182 rec Rel.addMember(platform);182 recMembers.add(platform); 183 183 } 184 184 } 185 185 186 186 for (RelationMember route : routeMembers) { 187 rec Rel.addMember(route);187 recMembers.add(route); 188 188 } 189 189 for (RelationMember wtf : wtfMembers) { 190 rec Rel.addMember(wtf);190 recMembers.add(wtf); 191 191 } 192 Command command = new ChangeCommand(r, recRel); 193 UndoRedoHandler.getInstance().add(command); 192 UndoRedoHandler.getInstance().add(new ChangeMembersCommand(r, recMembers)); 194 193 } 195 194 196 195 private static final double maxSqrDistBetweenStopAndPlatform = 2000; // ~ 26m 197 private RelationMember getClosestPlatform(List<RelationMember> members, Node stop) { 196 197 private static RelationMember getClosestPlatform(List<RelationMember> members, Node stop) { 198 198 if (stop == null || members.isEmpty()) return null; 199 199 double maxDist = maxSqrDistBetweenStopAndPlatform; 200 200 RelationMember result = null; … … 228 228 setEnabled(isSuitableRelation(newRelation)); 229 229 } 230 230 231 private boolean isSuitableRelation(Relation newRelation) {231 private static boolean isSuitableRelation(Relation newRelation) { 232 232 return !(newRelation == null || !"route".equals(newRelation.get("type")) || newRelation.getMembersCount() == 0); 233 233 } 234 234 } -
src/relcontext/actions/SplittingMultipolygons.java
11 11 import java.util.Iterator; 12 12 import java.util.List; 13 13 import java.util.Map; 14 import java.util.Map.Entry; 14 15 import java.util.Objects; 15 16 16 17 import org.openstreetmap.josm.command.AddCommand; … … 350 351 for (OsmPrimitive p : n.getReferrers()) { 351 352 if (p instanceof Way && !p.equals(ring)) { 352 353 for (OsmPrimitive r : p.getReferrers()) { 353 if (r instanceof Relation && r.hasKey("type") && r.get("type").equals("multipolygon")) {354 if (r instanceof Relation && "multipolygon".equals(r.get("type"))) { 354 355 if (touchingWays.containsKey(p)) { 355 356 touchingWays.put((Way) p, Boolean.TRUE); 356 357 } else { … … 364 365 } 365 366 366 367 List<TheRing> otherWays = new ArrayList<>(); 367 for ( Way w : touchingWays.keySet()) {368 if ( touchingWays.get(w)) {369 otherWays.add(new TheRing( w));368 for (Entry<Way, Boolean> e : touchingWays.entrySet()) { 369 if (Boolean.TRUE.equals(e.getValue())) { 370 otherWays.add(new TheRing(e.getKey())); 370 371 } 371 372 } 372 373 -
src/relcontext/relationfix/AssociatedStreetFixer.java
4 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 5 6 6 import java.util.ArrayList; 7 import java.util.Collections; 7 8 import java.util.HashMap; 8 9 import java.util.List; 9 10 import java.util.Map; 10 11 11 import org.openstreetmap.josm.command.ChangeCommand; 12 import org.openstreetmap.josm.command.ChangeMembersCommand; 13 import org.openstreetmap.josm.command.ChangePropertyCommand; 12 14 import org.openstreetmap.josm.command.Command; 13 15 import org.openstreetmap.josm.command.SequenceCommand; 14 16 import org.openstreetmap.josm.data.osm.DataSet; … … 22 24 23 25 public class AssociatedStreetFixer extends RelationFixer { 24 26 27 private static final String ADDR_HOUSENUMBER = "addr:housenumber"; 28 private static final String BUILDING = "building"; 29 private static final String HOUSE = "house"; 30 private static final String STREET = "street"; 31 25 32 public AssociatedStreetFixer() { 26 33 super("associatedStreet"); 27 34 } … … 29 36 @Override 30 37 public boolean isRelationGood(Relation rel) { 31 38 for (RelationMember m : rel.getMembers()) { 32 if (m.getType() .equals(OsmPrimitiveType.NODE) && !"house".equals(m.getRole())) {39 if (m.getType() == OsmPrimitiveType.NODE && !HOUSE.equals(m.getRole())) { 33 40 setWarningMessage(tr("Node without ''house'' role found")); 34 41 return false; 35 42 } 36 if (m.getType() .equals(OsmPrimitiveType.WAY) && !("house".equals(m.getRole()) || "street".equals(m.getRole()))) {43 if (m.getType() == OsmPrimitiveType.WAY && !(HOUSE.equals(m.getRole()) || STREET.equals(m.getRole()))) { 37 44 setWarningMessage(tr("Way without ''house'' or ''street'' role found")); 38 45 return false; 39 46 } 40 if (m.getType() .equals(OsmPrimitiveType.RELATION) && !"house".equals(m.getRole())) {47 if (m.getType() == OsmPrimitiveType.RELATION && !HOUSE.equals(m.getRole())) { 41 48 setWarningMessage(tr("Relation without ''house'' role found")); 42 49 return false; 43 50 } … … 53 60 streetName = ""; 54 61 } 55 62 for (RelationMember m : rel.getMembers()) { 56 if ( "street".equals(m.getRole()) && !streetName.equals(m.getWay().get("name"))) {63 if (STREET.equals(m.getRole()) && !streetName.equals(m.getWay().get("name"))) { 57 64 String anotherName = m.getWay().get("name"); 58 65 if (anotherName != null && !anotherName.isEmpty()) { 59 66 setWarningMessage(tr("Relation has streets with different names")); … … 71 78 // any way/point/relation with addr:housenumber=* or building=* or type=multipolygon -> house 72 79 // name - check which name is most used in street members and add to relation 73 80 // copy this name to the other street members (???) 74 Relation rel = new Relation(source);81 List<RelationMember> members = source.getMembers(); 75 82 boolean fixed = false; 76 83 77 for (int i = 0; i < rel.getMembersCount(); i++) { 78 RelationMember m = rel.getMember(i); 79 84 for (int i = 0; i < members.size(); i++) { 85 RelationMember m = members.get(i); 80 86 if (m.isNode()) { 81 87 Node node = m.getNode(); 82 if (! "house".equals(m.getRole()) &&83 (node.hasKey( "building") || node.hasKey("addr:housenumber"))) {88 if (!HOUSE.equals(m.getRole()) && 89 (node.hasKey(BUILDING) || node.hasKey(ADDR_HOUSENUMBER))) { 84 90 fixed = true; 85 rel.setMember(i, new RelationMember("house", node));91 members.set(i, new RelationMember(HOUSE, node)); 86 92 } 87 93 } else if (m.isWay()) { 88 94 Way way = m.getWay(); 89 if (! "street".equals(m.getRole()) && way.hasKey("highway")) {95 if (!STREET.equals(m.getRole()) && way.hasKey("highway")) { 90 96 fixed = true; 91 rel.setMember(i, new RelationMember("street", way));92 } else if (! "house".equals(m.getRole()) &&93 (way.hasKey( "building") || way.hasKey("addr:housenumber"))) {97 members.set(i, new RelationMember(STREET, way)); 98 } else if (!HOUSE.equals(m.getRole()) && 99 (way.hasKey(BUILDING) || way.hasKey(ADDR_HOUSENUMBER))) { 94 100 fixed = true; 95 rel.setMember(i, new RelationMember("house", way));101 members.set(i, new RelationMember(HOUSE, way)); 96 102 } 97 103 } else if (m.isRelation()) { 98 104 Relation relation = m.getRelation(); 99 if (! "house".equals(m.getRole()) &&100 (relation.hasKey( "building") || relation.hasKey("addr:housenumber") || "multipolygon".equals(relation.get("type")))) {105 if (!HOUSE.equals(m.getRole()) && 106 (relation.hasKey(BUILDING) || relation.hasKey(ADDR_HOUSENUMBER) || "multipolygon".equals(relation.get("type")))) { 101 107 fixed = true; 102 rel.setMember(i, new RelationMember("house", relation));108 members.set(i, new RelationMember(HOUSE, relation)); 103 109 } 104 110 } 105 111 } … … 106 112 107 113 // fill relation name 108 114 Map<String, Integer> streetNames = new HashMap<>(); 109 for (RelationMember m : rel.getMembers()) {110 if ( "street".equals(m.getRole()) && m.isWay()) {115 for (RelationMember m : members) { 116 if (STREET.equals(m.getRole()) && m.isWay()) { 111 117 String name = m.getWay().get("name"); 112 118 if (name == null || name.isEmpty()) { 113 119 continue; 114 120 } 115 116 121 Integer count = streetNames.get(name); 117 118 122 streetNames.put(name, count != null ? count + 1 : 1); 119 123 } 120 124 } … … 127 131 } 128 132 } 129 133 130 if (!rel.hasKey("name") && !commonName.isEmpty()) { 131 fixed = true; 132 rel.put("name", commonName); 133 } else { 134 commonName = ""; // set empty common name - if we already have name on relation, do not overwrite it 134 Map<String, String> nameTag = new HashMap<>(); 135 if (!source.hasKey("name") && !commonName.isEmpty()) { 136 nameTag.put("name", commonName); 135 137 } 136 138 137 139 List<Command> commandList = new ArrayList<>(); 140 final DataSet ds = Utils.firstNonNull(source.getDataSet(), MainApplication.getLayerManager().getEditDataSet()); 138 141 if (fixed) { 139 final DataSet ds = Utils.firstNonNull(source.getDataSet(), MainApplication.getLayerManager().getEditDataSet()); 140 commandList.add(new ChangeCommand(ds, source, rel)); 142 commandList.add(new ChangeMembersCommand(ds, source, members)); 141 143 } 144 if (!nameTag.isEmpty()) { 145 commandList.add(new ChangePropertyCommand(ds, Collections.singleton(source), nameTag)); 146 } 142 147 143 /*if (!commonName.isEmpty())144 // fill common name to streets145 for (RelationMember m : rel.getMembers())146 if ("street".equals(m.getRole()) && m.isWay()) {147 String name = m.getWay().get("name");148 if (commonName.equals(name)) continue;149 150 // TODO: ask user if he really wants to overwrite street name??151 152 Way oldWay = m.getWay();153 Way newWay = new Way(oldWay);154 newWay.put("name", commonName);155 156 commandList.add(new ChangeCommand(MainApplication.getLayerManager().getEditDataSet(), oldWay, newWay));157 }158 */159 148 // return results 160 if (commandList.isEmpty()) {149 if (commandList.isEmpty()) 161 150 return null; 162 }163 151 return SequenceCommand.wrapIfNeeded(tr("fix associatedStreet relation"), commandList); 164 152 } 165 153 } -
src/relcontext/relationfix/BoundaryFixer.java
3 3 4 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 5 6 import org.openstreetmap.josm.command.ChangeCommand; 6 import java.util.ArrayList; 7 import java.util.List; 8 9 import org.openstreetmap.josm.command.ChangeMembersCommand; 7 10 import org.openstreetmap.josm.command.Command; 8 11 import org.openstreetmap.josm.data.osm.DataSet; 9 12 import org.openstreetmap.josm.data.osm.Node; … … 36 39 @Override 37 40 public boolean isRelationGood(Relation rel) { 38 41 for (RelationMember m : rel.getMembers()) { 39 if (m.getType() .equals(OsmPrimitiveType.RELATION)&& !"subarea".equals(m.getRole())) {42 if (m.getType() == OsmPrimitiveType.RELATION && !"subarea".equals(m.getRole())) { 40 43 setWarningMessage(tr("Relation without ''subarea'' role found")); 41 44 return false; 42 45 } 43 if (m.getType() .equals(OsmPrimitiveType.NODE)&& !("label".equals(m.getRole()) || "admin_centre".equals(m.getRole()))) {46 if (m.getType() == OsmPrimitiveType.NODE && !("label".equals(m.getRole()) || "admin_centre".equals(m.getRole()))) { 44 47 setWarningMessage(tr("Node without ''label'' or ''admin_centre'' role found")); 45 48 return false; 46 49 } 47 if (m.getType() .equals(OsmPrimitiveType.WAY)&& !("outer".equals(m.getRole()) || "inner".equals(m.getRole()))) {50 if (m.getType() == OsmPrimitiveType.WAY && !("outer".equals(m.getRole()) || "inner".equals(m.getRole()))) { 48 51 setWarningMessage(tr("Way without ''inner'' or ''outer'' role found")); 49 52 return false; 50 53 } … … 55 58 56 59 @Override 57 60 public Command fixRelation(Relation rel) { 58 Relation r = rel; 59 Relation rr = fixMultipolygonRoles(r); 60 boolean fixed = false; 61 if (rr != null) { 62 fixed = true; 63 r = rr; 61 List<RelationMember> members = fixMultipolygonRoles(rel.getMembers()); 62 if (members.isEmpty()) { 63 members = rel.getMembers(); 64 64 } 65 rr = fixBoundaryRoles(r); 66 if (rr != null) { 67 fixed = true; 68 r = rr; 69 } 70 if (fixed) { 65 members = fixBoundaryRoles(members); 66 if (!members.equals(rel.getMembers())) { 71 67 final DataSet ds = Utils.firstNonNull(rel.getDataSet(), MainApplication.getLayerManager().getEditDataSet()); 72 return new Change Command(ds, rel, r);68 return new ChangeMembersCommand(ds, rel, members); 73 69 } 74 70 return null; 75 71 } 76 72 77 private Relation fixBoundaryRoles(Relation source) { 78 Relation r = new Relation(source); 79 boolean fixed = false; 80 for (int i = 0; i < r.getMembersCount(); i++) { 81 RelationMember m = r.getMember(i); 73 /** 74 * Possibly change roles of non-way members. 75 * @param origMembers original list of relation members 76 * @return either the original and unmodified list or a new one with at least one new item 77 */ 78 private static List<RelationMember> fixBoundaryRoles(List<RelationMember> origMembers) { 79 List<RelationMember> members = origMembers; 80 for (int i = 0; i < members.size(); i++) { 81 RelationMember m = members.get(i); 82 82 String role = null; 83 83 if (m.isRelation()) { 84 84 role = "subarea"; 85 } else if (m.isNode() ) {85 } else if (m.isNode() && !m.getMember().isIncomplete()) { 86 86 Node n = (Node) m.getMember(); 87 if (!n.isIncomplete()) { 88 if (n.hasKey("place")) { 89 String place = n.get("place"); 90 if (place.equals("state") || place.equals("country") || 91 place.equals("county") || place.equals("region")) { 92 role = "label"; 93 } else { 94 role = "admin_centre"; 95 } 87 if (n.hasKey("place")) { 88 String place = n.get("place"); 89 if ("state".equals(place) || "country".equals(place) || 90 "county".equals(place) || "region".equals(place)) { 91 role = "label"; 96 92 } else { 97 role = " label";93 role = "admin_centre"; 98 94 } 95 } else { 96 role = "label"; 99 97 } 100 98 } 101 99 if (role != null && !role.equals(m.getRole())) { 102 r.setMember(i, new RelationMember(role, m.getMember())); 103 fixed = true; 100 if (members == origMembers) { 101 members = new ArrayList<>(origMembers); // don't modify original list 102 } 103 members.set(i, new RelationMember(role, m.getMember())); 104 104 } 105 105 } 106 return fixed ? r : null;106 return members; 107 107 } 108 108 } -
src/relcontext/relationfix/MultipolygonFixer.java
4 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 5 6 6 import java.util.ArrayList; 7 import java.util.Collection ;7 import java.util.Collections; 8 8 import java.util.HashSet; 9 import java.util.List; 9 10 import java.util.Set; 11 import java.util.stream.Collectors; 10 12 11 import org.openstreetmap.josm.command.Change Command;13 import org.openstreetmap.josm.command.ChangeMembersCommand; 12 14 import org.openstreetmap.josm.command.Command; 13 15 import org.openstreetmap.josm.data.osm.DataSet; 14 16 import org.openstreetmap.josm.data.osm.MultipolygonBuilder; … … 28 30 super("multipolygon"); 29 31 } 30 32 31 protected MultipolygonFixer(String... types) {33 protected MultipolygonFixer(String... types) { 32 34 super(types); 33 35 } 34 36 … … 35 37 @Override 36 38 public boolean isRelationGood(Relation rel) { 37 39 for (RelationMember m : rel.getMembers()) { 38 if (m.getType() .equals(OsmPrimitiveType.WAY)&& !("outer".equals(m.getRole()) || "inner".equals(m.getRole()))) {40 if (m.getType() == OsmPrimitiveType.WAY && !("outer".equals(m.getRole()) || "inner".equals(m.getRole()))) { 39 41 setWarningMessage(tr("Way without ''inner'' or ''outer'' role found")); 40 42 return false; 41 43 } … … 46 48 47 49 @Override 48 50 public Command fixRelation(Relation rel) { 49 Relation rr = fixMultipolygonRoles(rel);50 if ( rr != null) {51 List<RelationMember> members = fixMultipolygonRoles(rel.getMembers()); 52 if (!members.equals(rel.getMembers())) { 51 53 final DataSet ds = Utils.firstNonNull(rel.getDataSet(), MainApplication.getLayerManager().getEditDataSet()); 52 return new Change Command(ds, rel, rr);54 return new ChangeMembersCommand(ds, rel, members); 53 55 } 54 56 return null; 55 57 } 56 58 57 59 /** 58 * Basically, created multipolygon from scratch, and if successful, replace roles with new ones. 60 * Basically, create member list of a multipolygon from scratch, and if 61 * successful, replace roles with new ones. 62 * 63 * @param origMembers original list of relation members 64 * @return either the original and unmodified list or a new one with at least 65 * one new item or the empty list if the way members don't build a 66 * correct multipolygon 59 67 */ 60 protected Relation fixMultipolygonRoles(Relation source) { 61 Collection<Way> ways = new ArrayList<>(source.getMemberPrimitives(Way.class)); 68 protected List<RelationMember> fixMultipolygonRoles(final List<RelationMember> origMembers) { 69 List<Way> ways = origMembers.stream().filter(m -> m.isWay()).map(m -> m.getWay()).collect(Collectors.toList()); 70 62 71 MultipolygonBuilder mpc = new MultipolygonBuilder(); 63 72 String error = mpc.makeFromWays(ways); 64 73 if (error != null) 65 return null;74 return Collections.emptyList(); 66 75 67 Relation r = new Relation(source);68 boolean fixed = false;69 76 Set<Way> outerWays = new HashSet<>(); 70 77 for (MultipolygonBuilder.JoinedPolygon poly : mpc.outerWays) { 71 78 outerWays.addAll(poly.ways); … … 74 81 for (MultipolygonBuilder.JoinedPolygon poly : mpc.innerWays) { 75 82 innerWays.addAll(poly.ways); 76 83 } 77 for (int i = 0; i < r.getMembersCount(); i++) { 78 RelationMember m = r.getMember(i); 84 List<RelationMember> members = origMembers; 85 for (int i = 0; i < members.size(); i++) { 86 RelationMember m = members.get(i); 79 87 if (m.isWay()) { 80 88 final Way way = m.getWay(); 81 89 String role = null; … … 85 93 role = "inner"; 86 94 } 87 95 if (role != null && !role.equals(m.getRole())) { 88 r.setMember(i, new RelationMember(role, way)); 89 fixed = true; 96 if (members == origMembers) { 97 members = new ArrayList<>(origMembers); // don't modify original list 98 } 99 members.set(i, new RelationMember(role, way)); 90 100 } 91 101 } 92 102 } 93 return fixed ? r : null;103 return members; 94 104 } 95 105 } -
src/relcontext/relationfix/PublicTransportFixer.java
3 3 4 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 5 6 import org.openstreetmap.josm.command.ChangeCommand; 6 import java.util.ArrayList; 7 import java.util.List; 8 9 import org.openstreetmap.josm.command.ChangeMembersCommand; 7 10 import org.openstreetmap.josm.command.Command; 8 11 import org.openstreetmap.josm.data.osm.DataSet; 9 12 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; … … 10 13 import org.openstreetmap.josm.data.osm.Relation; 11 14 import org.openstreetmap.josm.data.osm.RelationMember; 12 15 import org.openstreetmap.josm.gui.MainApplication; 16 import org.openstreetmap.josm.tools.Utils; 13 17 14 import org.openstreetmap.josm.tools.Utils;15 18 import relcontext.actions.PublicTransportHelper; 16 19 17 20 /** … … 25 28 super("route", "public_transport"); 26 29 } 27 30 28 /*protected PublicTransportFixer(String...types) {29 super(types);30 }*/31 32 31 @Override 33 32 public boolean isRelationGood(Relation rel) { 34 33 for (RelationMember m : rel.getMembers()) { 35 if (m.getType() .equals(OsmPrimitiveType.NODE)34 if (m.getType() == OsmPrimitiveType.NODE 36 35 && !(m.getRole().startsWith(PublicTransportHelper.STOP) || m.getRole().startsWith(PublicTransportHelper.PLATFORM))) { 37 36 setWarningMessage(tr("Node without ''stop'' or ''platform'' role found")); 38 37 return false; 39 38 } 40 if (m.getType() .equals(OsmPrimitiveType.WAY)39 if (m.getType() == OsmPrimitiveType.WAY 41 40 && PublicTransportHelper.isWayPlatform(m) 42 41 && !m.getRole().startsWith(PublicTransportHelper.PLATFORM)) { 43 42 setWarningMessage(tr("Way platform without ''platform'' role found") + " r" + m.getUniqueId()); … … 48 47 return true; 49 48 } 50 49 51 /*@Override52 public boolean isFixerApplicable(Relation rel) {53 return true;54 }*/55 56 50 @Override 57 51 public Command fixRelation(Relation rel) { 58 Relation r = rel; 59 Relation rr = fixStopPlatformRole(r); 60 boolean fixed = false; 61 if (rr != null) { 62 fixed = true; 63 r = rr; 64 } 65 if (fixed) { 52 List<RelationMember> members = fixStopPlatformRole(rel.getMembers()); 53 if (!members.equals(rel.getMembers())) { 66 54 final DataSet ds = Utils.firstNonNull(rel.getDataSet(), MainApplication.getLayerManager().getEditDataSet()); 67 return new Change Command(ds, rel, r);55 return new ChangeMembersCommand(ds, rel, rel.getMembers()); 68 56 } 69 57 return null; 70 58 } 71 59 72 private Relation fixStopPlatformRole(Relation source) { 73 Relation r = new Relation(source); 74 boolean fixed = false; 75 for (int i = 0; i < r.getMembersCount(); i++) { 76 RelationMember m = r.getMember(i); 60 /** 61 * Fix roles of members. 62 * @param origMembers original list of relation members 63 * @return either the original and unmodified list or a new one with at least one new item 64 */ 65 private static List<RelationMember> fixStopPlatformRole(List<RelationMember> origMembers) { 66 List<RelationMember> members = origMembers; 67 for (int i = 0; i < members.size(); i++) { 68 RelationMember m = members.get(i); 77 69 String role = PublicTransportHelper.getRoleByMember(m); 78 70 79 71 if (role != null && !m.getRole().startsWith(role)) { 80 r.setMember(i, new RelationMember(role, m.getMember())); 81 fixed = true; 72 if (members == origMembers) { 73 members = new ArrayList<>(origMembers); 74 } 75 members.set(i, new RelationMember(role, m.getMember())); 82 76 } 83 77 } 84 return fixed ? r : null;78 return members; 85 79 } 86 80 }