Changeset 36382 in osm for applications
- Timestamp:
- 2025-02-04T20:37:26+01:00 (13 hours ago)
- Location:
- applications/editors/josm/plugins/buildings_tools/src/org/openstreetmap/josm/plugins/buildings_tools
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/buildings_tools/src/org/openstreetmap/josm/plugins/buildings_tools/AddressDialog.java
r34572 r36382 11 11 import javax.swing.SpinnerNumberModel; 12 12 13 /** 14 * Address dialog for buildings 15 */ 13 16 public class AddressDialog extends MyDialog { 14 private static String lhousenum, lstreetname; 15 private static int inc = 0; 16 private JTextField housenum = new JTextField(); 17 private JTextField streetname = new JTextField(); 18 private JSpinner incSpinner; 17 private static String lhousenum; 18 private static String lstreetname; 19 private static int inc; 20 private final JTextField housenum = new JTextField(); 21 private final JTextField streetname = new JTextField(); 22 private final JSpinner incSpinner; 19 23 24 /** 25 * Create a new dialog object 26 */ 20 27 public AddressDialog() { 21 28 super(tr("Building address")); … … 26 33 streetname.setText(lstreetname); 27 34 28 SpinnerNumberModel inc _model = new SpinnerNumberModel(0, Integer.MIN_VALUE, Integer.MAX_VALUE, 1);29 incSpinner = new JSpinner(inc _model);35 SpinnerNumberModel incModel = new SpinnerNumberModel(0, Integer.MIN_VALUE, Integer.MAX_VALUE, 1); 36 incSpinner = new JSpinner(incModel); 30 37 incSpinner.setValue(inc); 31 38 addLabelled(tr("House number increment:"), incSpinner); … … 39 46 return ""; 40 47 try { 41 Integernum = NumberFormat.getInstance().parse(lhousenum).intValue() + inc;42 return num.toString();48 int num = NumberFormat.getInstance().parse(lhousenum).intValue() + inc; 49 return Integer.toString(num); 43 50 } catch (ParseException e) { 44 51 return lhousenum; … … 46 53 } 47 54 55 /** 56 * Save values for future use in the current running JOSM instance 57 */ 48 58 public final void saveValues() { 49 lhousenum = housenum.getText(); 50 lstreetname = streetname.getText(); 51 inc = (Integer) incSpinner.getValue(); 59 saveValues(this); 60 } 61 62 private static void saveValues(AddressDialog dialog) { 63 lhousenum = dialog.getHouseNum(); 64 lstreetname = dialog.getStreetName(); 65 inc = (Integer) dialog.incSpinner.getValue(); 52 66 } 53 67 -
applications/editors/josm/plugins/buildings_tools/src/org/openstreetmap/josm/plugins/buildings_tools/AdvancedSettingsDialog.java
r36081 r36382 4 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 5 6 import java.awt.GridBagConstraints; 6 7 import java.util.Map; 7 8 … … 31 32 super(tr("Advanced settings")); 32 33 33 panel.add(new JLabel(tr("Buildings tags:")), GBC.eol().fill(G BC.HORIZONTAL));34 panel.add(new JLabel(tr("Buildings tags:")), GBC.eol().fill(GridBagConstraints.HORIZONTAL)); 34 35 35 36 for (Map.Entry<String, String> entry : ToolSettings.getTags().entrySet()) { 36 37 tagsModel.add(entry.getKey(), entry.getValue()); 37 38 } 38 panel.add(new TagEditorPanel(tagsModel, null, Changeset.MAX_CHANGESET_TAG_LENGTH), GBC.eop().fill(G BC.BOTH));39 panel.add(new TagEditorPanel(tagsModel, null, Changeset.MAX_CHANGESET_TAG_LENGTH), GBC.eop().fill(GridBagConstraints.BOTH)); 39 40 40 panel.add(cBigMode, GBC.eol().fill(G BC.HORIZONTAL));41 panel.add(cSoftCur, GBC.eol().fill(G BC.HORIZONTAL));42 panel.add(cNoClickDrag, GBC.eol().fill(G BC.HORIZONTAL));43 panel.add(cToggleMapMode, GBC.eol().fill(G BC.HORIZONTAL));41 panel.add(cBigMode, GBC.eol().fill(GridBagConstraints.HORIZONTAL)); 42 panel.add(cSoftCur, GBC.eol().fill(GridBagConstraints.HORIZONTAL)); 43 panel.add(cNoClickDrag, GBC.eol().fill(GridBagConstraints.HORIZONTAL)); 44 panel.add(cToggleMapMode, GBC.eol().fill(GridBagConstraints.HORIZONTAL)); 44 45 45 46 cBigMode.setSelected(ToolSettings.isBBMode()); -
applications/editors/josm/plugins/buildings_tools/src/org/openstreetmap/josm/plugins/buildings_tools/AngleSnap.java
r35978 r36382 11 11 import org.openstreetmap.josm.tools.Pair; 12 12 13 /** 14 * A class for getting angles for snapping 15 */ 13 16 public class AngleSnap { 14 17 private static final double PI_2 = Math.PI / 2; 15 18 final TreeSet<Double> snapSet = new TreeSet<>(); 16 19 20 /** 21 * Clear the snap directions 22 */ 17 23 public final void clear() { 18 24 snapSet.clear(); 19 25 } 20 26 27 /** 28 * Add a snap direction 29 * @param snap The direction in radians 30 */ 21 31 public final void addSnap(double snap) { 22 32 snapSet.add(snap % PI_2); 23 33 } 24 34 35 /** 36 * Add node pairs to the possible snap directions (the heading and 45 degrees from heading) 37 * @param nodes The nodes to iterate through 38 * @return The heading between the nodes in radians 39 */ 25 40 public final Double addSnap(Node[] nodes) { 26 41 if (nodes.length == 2) { … … 36 51 } 37 52 53 /** 54 * Add way segments to the possible snap directions 55 * @param way The way to add node pairs from to the snap directions 56 */ 38 57 public final void addSnap(Way way) { 39 58 for (Pair<Node, Node> pair : way.getNodePairs(false)) { … … 45 64 } 46 65 66 /** 67 * Get the angle between the first and last snaps added 68 * @return The angle between the first and last snaps added 69 */ 47 70 public final Double getAngle() { 48 71 if (snapSet.isEmpty()) { … … 64 87 } 65 88 89 /** 90 * Get the snap angle given a starting angle 91 * @param angle The angle to get the snap for 92 * @return The best angle for snapping, or the originating angle 93 */ 66 94 public final double snapAngle(double angle) { 67 95 if (snapSet.isEmpty()) { … … 78 106 79 107 if (Math.abs(ang - next) > Math.abs(ang - prev)) { 80 if (Math.abs(ang - prev) > Math.PI / 8) { 81 return angle; 82 } else { 83 double ret = prev + PI_2 * quadrant; 84 if (ret < 0) 85 ret += 2 * Math.PI; 86 return ret; 87 } 108 return prevSnapAngle(quadrant, prev, ang, angle); 88 109 } else { 89 if (Math.abs(ang - next) > Math.PI / 8) { 90 return angle; 91 } else { 92 double ret = next + PI_2 * quadrant; 93 if (ret > 2 * Math.PI) 94 ret -= 2 * Math.PI; 95 return ret; 96 } 110 return nextSnapAngle(quadrant, next, ang, angle); 111 } 112 } 113 114 private static double nextSnapAngle(double quadrant, double next, double ang, double angle) { 115 if (Math.abs(ang - next) > Math.PI / 8) { 116 return angle; 117 } else { 118 double ret = next + PI_2 * quadrant; 119 if (ret > 2 * Math.PI) 120 ret -= 2 * Math.PI; 121 return ret; 122 } 123 } 124 125 private static double prevSnapAngle(double quadrant, double prev, double ang, double angle) { 126 if (Math.abs(ang - prev) > Math.PI / 8) { 127 return angle; 128 } else { 129 double ret = prev + PI_2 * quadrant; 130 if (ret < 0) 131 ret += 2 * Math.PI; 132 return ret; 97 133 } 98 134 } -
applications/editors/josm/plugins/buildings_tools/src/org/openstreetmap/josm/plugins/buildings_tools/Building.java
r36134 r36382 31 31 import org.openstreetmap.josm.data.osm.BBox; 32 32 import org.openstreetmap.josm.data.osm.DataSet; 33 import org.openstreetmap.josm.data.osm.IPrimitive; 33 34 import org.openstreetmap.josm.data.osm.Node; 34 35 import org.openstreetmap.josm.data.osm.OsmPrimitive; … … 53 54 private static final double EQUAL_NODE_DIST_TOLERANCE = 1e-6; 54 55 56 /** 57 * Clear the current angle information 58 */ 55 59 public void clearAngleSnap() { 56 60 angleSnap.clear(); … … 58 62 } 59 63 64 /** 65 * Add nodes to the angle snap collection and set the current drawing angle to the heading between 66 * the nodes. 67 * @param nodes The node array to use 68 * @see AngleSnap#addSnap(Node[]) 69 */ 60 70 public void addAngleSnap(Node[] nodes) { 61 71 drawingAngle = angleSnap.addSnap(nodes); 62 72 } 63 73 74 /** 75 * Add a way to the angle snap collection and set the drawing angle if it is not already set 76 * @param way The way to add to the angle snap 77 * @see AngleSnap#addSnap(Way) 78 */ 64 79 public void addAngleSnap(Way way) { 65 80 angleSnap.addSnap(way); … … 77 92 } 78 93 94 /** 95 * Check if we are currently drawing a rectangle 96 * @return {@code true} if we are drawing a rectangle 97 */ 79 98 public boolean isRectDrawing() { 80 99 return drawingAngle != null && ToolSettings.getWidth() == 0 && ToolSettings.getLenStep() == 0 … … 82 101 } 83 102 103 /** 104 * Get the current drawing angle 105 * @return The current drawing angle. May be {@code null}. 106 */ 84 107 public Double getDrawingAngle() { 85 108 return drawingAngle; 86 109 } 87 110 111 /** 112 * Reset the current building drawing 113 */ 88 114 public void reset() { 89 115 len = 0; … … 94 120 } 95 121 122 /** 123 * Get the east north point specified 124 * @param num The point to get from the {@link #en} array 125 * @return The EastNorth point 126 */ 96 127 public EastNorth getPoint(int num) { 97 128 return en[num]; … … 209 240 } 210 241 242 /** 243 * Paint the way to be generated on mouse release 244 * @param g The graphics to paint on 245 * @param mv The current map view 246 */ 211 247 public void paint(Graphics2D g, MapView mv) { 212 248 // Make a local copy to avoid other threads resetting what we are drawing. … … 255 291 if (n.isUsable() && findUsableTag(n)) { 256 292 EastNorth enTest = n.getEastNorth(); 257 if (area.contains(enTest.getX(), enTest.getY())) { 258 boolean useNode = true; 259 for (OsmPrimitive p : n.getReferrers()) { 260 // Don't use nodes if they're referenced by ways 261 if (p.getType() == OsmPrimitiveType.WAY) { 262 useNode = false; 263 break; 264 } 265 } 266 if (useNode) { 267 nodes.add(n); 268 } 293 if (area.contains(enTest.getX(), enTest.getY()) && usableAddressNode(n)) { 294 nodes.add(n); 269 295 } 270 296 } … … 273 299 return null; 274 300 return nodes.get(0); 301 } 302 303 private static boolean usableAddressNode(IPrimitive node) { 304 for (IPrimitive p : node.getReferrers()) { 305 // Don't use nodes if they're referenced by ways 306 if (p.getType() == OsmPrimitiveType.WAY) { 307 return false; 308 } 309 } 310 return true; 275 311 } 276 312 … … 284 320 } 285 321 322 /** 323 * Create a circle in the dataset 324 * @return The created circle 325 */ 286 326 public Way createCircle() { 287 327 DataSet ds = MainApplication.getLayerManager().getEditDataSet(); … … 358 398 } 359 399 400 /** 401 * Create a rectangle on the current edit dataset 402 * @param ctrl {@code true} if the ctrl button is held 403 * @return The created rectangle or {@code null} 404 */ 360 405 public Way createRectangle(boolean ctrl) { 361 406 if (len == 0) … … 474 519 Node addrNode = getAddressNode(w); 475 520 if (addrNode != null) { 476 Collection<Command> addressCmds = cmdList != null ? cmdList : new LinkedList<>(); 477 addrNode.getKeys().forEach(w::put); 478 for (OsmPrimitive p : addrNode.getReferrers()) { 479 Relation r = (Relation) p; 480 List<RelationMember> members = new ArrayList<>(r.getMembers()); 481 for (int i = 0; i < members.size(); i++) { 482 RelationMember member = members.get(i); 483 if (addrNode.equals(member.getMember())) { 484 members.set(i, new RelationMember(member.getRole(), w)); 485 } 486 } 487 addressCmds.add(new ChangeMembersCommand(r, members)); 521 addAddressCommand(w, cmdList, addrNode); 522 } 523 } 524 } 525 526 private static void addAddressCommand(Way w, Collection<Command> cmdList, Node addrNode) { 527 Collection<Command> addressCmds = cmdList != null ? cmdList : new LinkedList<>(); 528 addrNode.getKeys().forEach(w::put); 529 for (OsmPrimitive p : addrNode.getReferrers()) { 530 Relation r = (Relation) p; 531 List<RelationMember> members = new ArrayList<>(r.getMembers()); 532 for (int i = 0; i < members.size(); i++) { 533 RelationMember member = members.get(i); 534 if (addrNode.equals(member.getMember())) { 535 members.set(i, new RelationMember(member.getRole(), w)); 488 536 } 489 final Command deleteCommand = DeleteCommand.delete(Collections.singleton(addrNode)); 490 if (deleteCommand != null) { 491 addressCmds.add(deleteCommand); 492 } 493 if (cmdList == null) { 494 Command c = new SequenceCommand(tr("Add address for building"), addressCmds); 495 UndoRedoHandler.getInstance().add(c); 496 } 497 } 537 } 538 addressCmds.add(new ChangeMembersCommand(r, members)); 539 } 540 final Command deleteCommand = DeleteCommand.delete(Collections.singleton(addrNode)); 541 if (deleteCommand != null) { 542 addressCmds.add(deleteCommand); 543 } 544 if (cmdList == null) { 545 Command c = new SequenceCommand(tr("Add address for building"), addressCmds); 546 UndoRedoHandler.getInstance().add(c); 498 547 } 499 548 } -
applications/editors/josm/plugins/buildings_tools/src/org/openstreetmap/josm/plugins/buildings_tools/BuildingCircleAction.java
r34572 r36382 10 10 import org.openstreetmap.josm.tools.Shortcut; 11 11 12 /** 13 * The action for drawing building circles 14 */ 12 15 public class BuildingCircleAction extends JosmAction { 13 16 17 /** 18 * Create a new building circle action 19 */ 14 20 public BuildingCircleAction() { 15 21 super(tr("Set building shape to circle"), "mapmode/silo", tr("Set building shape to circle"), -
applications/editors/josm/plugins/buildings_tools/src/org/openstreetmap/josm/plugins/buildings_tools/BuildingRectangleAction.java
r35474 r36382 10 10 import org.openstreetmap.josm.tools.Shortcut; 11 11 12 /** 13 * Draw rectangle buildings 14 */ 12 15 public class BuildingRectangleAction extends JosmAction { 13 16 17 /** 18 * Create a new action for drawing rectangular buildings 19 */ 14 20 public BuildingRectangleAction() { 15 21 super(tr("Set building shape to rectangle"), "mapmode/rectangular", tr("Set building shape to rectangle"), -
applications/editors/josm/plugins/buildings_tools/src/org/openstreetmap/josm/plugins/buildings_tools/BuildingSizeAction.java
r35579 r36382 2 2 package org.openstreetmap.josm.plugins.buildings_tools; 3 3 4 import static org.openstreetmap.josm.tools.I18n.marktr; 4 5 import static org.openstreetmap.josm.tools.I18n.tr; 5 6 … … 10 11 import org.openstreetmap.josm.tools.Shortcut; 11 12 13 /** 14 * An action to open the {@link BuildingSizeDialog} 15 */ 12 16 public class BuildingSizeAction extends JosmAction { 13 17 private static final String SET_BUILDINGS_SIZE = marktr("Set buildings size"); 18 /** 19 * Create a new action for setting building sizes 20 */ 14 21 public BuildingSizeAction() { 15 super(tr( "Set buildings size"), "mapmode/building", tr("Set buildings size"),16 Shortcut.registerShortcut("edit:buildingsdialog", tr("Data: {0}", tr( "Set buildings size")),22 super(tr(SET_BUILDINGS_SIZE), "mapmode/building", tr(SET_BUILDINGS_SIZE), 23 Shortcut.registerShortcut("edit:buildingsdialog", tr("Data: {0}", tr(SET_BUILDINGS_SIZE)), 17 24 KeyEvent.VK_B, Shortcut.ALT_CTRL), 18 25 true, "edit:buildingsdialog", false); -
applications/editors/josm/plugins/buildings_tools/src/org/openstreetmap/josm/plugins/buildings_tools/BuildingSizeDialog.java
r35915 r36382 4 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 5 6 import java.awt.event.ActionEvent; 7 import java.awt.event.ActionListener; 6 import java.awt.GridBagConstraints; 8 7 import java.text.NumberFormat; 9 8 import java.text.ParseException; … … 17 16 import org.openstreetmap.josm.tools.GBC; 18 17 18 /** 19 * A dialog for setting building sizes and other information 20 */ 19 21 public class BuildingSizeDialog extends MyDialog { 20 22 private final JFormattedTextField twidth = new JFormattedTextField(NumberFormat.getInstance()); … … 27 29 private final JRadioButton rectangleRadio = new JRadioButton(tr("Rectangle")); 28 30 31 /** 32 * Create a new dialog for building sizes 33 */ 29 34 public BuildingSizeDialog() { 30 35 super(tr("Set buildings size and shape")); … … 36 41 rectangleRadio.setSelected(ToolSettings.Shape.RECTANGLE == ToolSettings.getShape()); 37 42 38 panel.add(rectangleRadio, GBC.eol().fill(G BC.HORIZONTAL));39 panel.add(circleRadio, GBC.eol().fill(G BC.HORIZONTAL));43 panel.add(rectangleRadio, GBC.eol().fill(GridBagConstraints.HORIZONTAL)); 44 panel.add(circleRadio, GBC.eol().fill(GridBagConstraints.HORIZONTAL)); 40 45 41 46 addLabelled(tr("Buildings width/diameter:"), twidth); 42 47 addLabelled(tr("Length step:"), tlenstep); 43 panel.add(caddr, GBC.eol().fill(G BC.HORIZONTAL));44 panel.add(cAutoSelect, GBC.eol().fill(G BC.HORIZONTAL));45 panel.add(cAutoSelectReplaceSelection, GBC.eol().fill(G BC.HORIZONTAL));46 panel.add(cAddrNode, GBC.eol().fill(G BC.HORIZONTAL));48 panel.add(caddr, GBC.eol().fill(GridBagConstraints.HORIZONTAL)); 49 panel.add(cAutoSelect, GBC.eol().fill(GridBagConstraints.HORIZONTAL)); 50 panel.add(cAutoSelectReplaceSelection, GBC.eol().fill(GridBagConstraints.HORIZONTAL)); 51 panel.add(cAddrNode, GBC.eol().fill(GridBagConstraints.HORIZONTAL)); 47 52 48 53 twidth.setValue(ToolSettings.getWidth()); … … 54 59 55 60 JButton bAdv = new JButton(tr("Advanced...")); 56 bAdv.addActionListener(new ActionListener() { 57 @Override 58 public void actionPerformed(ActionEvent arg0) { 59 AdvancedSettingsDialog dlg = new AdvancedSettingsDialog(); 60 if (dlg.getValue() == 1) { 61 dlg.saveSettings(); 62 } 61 bAdv.addActionListener(ignored -> { 62 AdvancedSettingsDialog dlg = new AdvancedSettingsDialog(); 63 if (dlg.getValue() == 1) { 64 dlg.saveSettings(); 63 65 } 64 66 }); 65 panel.add(bAdv, GBC.eol().insets(0, 5, 0, 0).anchor(G BC.EAST));67 panel.add(bAdv, GBC.eol().insets(0, 5, 0, 0).anchor(GridBagConstraints.EAST)); 66 68 67 69 setupDialog(); … … 69 71 } 70 72 73 /** 74 * Get the specified max width/diameter 75 * @return The maximum width/diameter for rectangles/circles 76 */ 71 77 public final double width() { 72 78 try { … … 77 83 } 78 84 85 /** 86 * Get the step length for drawing rectangular buildings 87 * @return The discrete steps to increase rectanglular building sizes 88 */ 79 89 public double lenstep() { 80 90 try { … … 85 95 } 86 96 97 /** 98 * Check if the user wants to use addresses from underlying nodes 99 * @return {@code true} if the user wants to use addresses 100 */ 87 101 public final boolean useAddr() { 88 102 return caddr.isSelected(); 89 103 } 90 104 105 /** 106 * Save the settings for this dialog 107 */ 91 108 public final void saveSettings() { 92 109 if (circleRadio.isSelected()) { -
applications/editors/josm/plugins/buildings_tools/src/org/openstreetmap/josm/plugins/buildings_tools/DrawBuildingAction.java
r36081 r36382 39 39 import java.util.LinkedList; 40 40 import java.util.Map; 41 import java.util.Objects; 41 42 42 43 import static org.openstreetmap.josm.plugins.buildings_tools.BuildingsToolsPlugin.latlon2eastNorth; … … 50 51 KeyPressReleaseListener, ModifierExListener { 51 52 private static final long serialVersionUID = -3515263157730927711L; 53 private static final String CROSSHAIR = "crosshair"; 54 private static final String BUILDING_STRING = "building"; 55 private static final String DRAW_BUILDINGS = marktr("Draw buildings"); 52 56 // We need to avoid opening many file descriptors on Linux under Wayland -- see JOSM #21929. This will probably also 53 57 // improve performance, since we aren't creating cursors all the time. 54 private static final Cursor CURSOR_SILO = ImageProvider.getCursor( "crosshair", "silo");55 private static final Cursor CURSOR_BUILDING = ImageProvider.getCursor( "crosshair", "building");58 private static final Cursor CURSOR_SILO = ImageProvider.getCursor(CROSSHAIR, "silo"); 59 private static final Cursor CURSOR_BUILDING = ImageProvider.getCursor(CROSSHAIR, BUILDING_STRING); 56 60 57 61 private enum Mode { 58 N one, Drawing, DrawingWidth, DrawingAngFix62 NONE, DRAWING, DRAWING_WIDTH, DRAWING_ANG_FIX 59 63 } 60 64 … … 63 67 private Cursor customCursor; 64 68 65 private Mode mode = Mode.N one;66 private Mode nextMode = Mode.N one;69 private Mode mode = Mode.NONE; 70 private Mode nextMode = Mode.NONE; 67 71 68 72 private Color selectedColor = Color.red; … … 74 78 final transient Building building = new Building(); 75 79 76 private final PreferenceChangedListener shapeChangeListener = event -> updCursor(); 80 private final transient PreferenceChangedListener shapeChangeListener = event -> updCursor(); 77 81 78 82 /** … … 80 84 */ 81 85 public DrawBuildingAction() { 82 super(tr( "Draw buildings"), "building", tr("Draw buildings"),86 super(tr(DRAW_BUILDINGS), BUILDING_STRING, tr(DRAW_BUILDINGS), 83 87 Shortcut.registerShortcut("mapmode:buildings", 84 tr("Mode: {0}", tr( "Draw buildings")),88 tr("Mode: {0}", tr(DRAW_BUILDINGS)), 85 89 KeyEvent.VK_B, Shortcut.DIRECT), 86 90 // Set super.cursor to crosshair without overlay because super.cursor is final, 87 91 // but we use two different cursors with overlays for rectangular and circular buildings 88 92 // the actual cursor is drawn in enterMode() 89 ImageProvider.getCursor( "crosshair", null));90 91 cursorJoinNode = ImageProvider.getCursor( "crosshair", "joinnode");92 cursorJoinWay = ImageProvider.getCursor( "crosshair", "joinway");93 ImageProvider.getCursor(CROSSHAIR, null)); 94 95 cursorJoinNode = ImageProvider.getCursor(CROSSHAIR, "joinnode"); 96 cursorJoinWay = ImageProvider.getCursor(CROSSHAIR, "joinway"); 93 97 } 94 98 … … 160 164 Config.getPref().removeKeyPreferenceChangeListener("buildings_tool.shape", shapeChangeListener); 161 165 162 if (mode != Mode.N one)166 if (mode != Mode.NONE) 163 167 map.mapView.repaint(); 164 mode = Mode.N one;168 mode = Mode.NONE; 165 169 } 166 170 … … 169 173 */ 170 174 public final void cancelDrawing() { 171 mode = Mode.N one;175 mode = Mode.NONE; 172 176 MapFrame map = MainApplication.getMap(); 173 177 if (map == null || map.mapView == null) … … 188 192 processMouseEvent(null); 189 193 updCursor(); 190 if (mode != Mode.N one)194 if (mode != Mode.NONE) 191 195 MainApplication.getMap().mapView.repaint(); 192 196 } … … 196 200 public void doKeyPressed(KeyEvent e) { 197 201 if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { 198 if (mode != Mode.N one)202 if (mode != Mode.NONE) 199 203 e.consume(); 200 204 … … 206 210 } 207 211 e.consume(); 208 switch (ToolSettings.getShape()) { 209 case CIRCLE: 210 ToolSettings.saveShape(ToolSettings.Shape.RECTANGLE); 211 break; 212 case RECTANGLE: 213 ToolSettings.saveShape(ToolSettings.Shape.CIRCLE); 212 ToolSettings.Shape shape = ToolSettings.getShape(); 213 if (Objects.requireNonNull(shape) == ToolSettings.Shape.CIRCLE) { 214 ToolSettings.saveShape(ToolSettings.Shape.RECTANGLE); 215 } else if (shape == ToolSettings.Shape.RECTANGLE) { 216 ToolSettings.saveShape(ToolSettings.Shape.CIRCLE); 217 } else { 218 throw new IllegalStateException("Unknown shape " + shape); 214 219 } 215 220 } … … 227 232 IWaySegment<Node, Way> ws = MainApplication.getMap().mapView.getNearestWaySegment(mousePos, 228 233 OsmPrimitive::isSelectable); 229 if (ws != null && ws.getWay().get( "building") != null) {234 if (ws != null && ws.getWay().get(BUILDING_STRING) != null) { 230 235 EastNorth p1 = latlon2eastNorth(ws.getFirstNode()); 231 236 EastNorth p2 = latlon2eastNorth(ws.getSecondNode()); … … 250 255 building.setPlaceRect(p); 251 256 if (Math.abs(building.getLength()) < MIN_LEN_WIDTH) 252 return Mode.D rawing;253 return shift ? Mode.D rawingAngFix: Mode.None;257 return Mode.DRAWING; 258 return shift ? Mode.DRAWING_ANG_FIX : Mode.NONE; 254 259 } else if (ToolSettings.Shape.CIRCLE == ToolSettings.getShape()) { 255 if (ToolSettings.getWidth() != 0) { 256 building.setPlaceCircle(p, ToolSettings.getWidth(), shift); 257 } else { 258 building.setPlace(p, ToolSettings.getWidth(), ToolSettings.getLenStep(), shift); 259 } 260 if (building.getLength() < MIN_LEN_WIDTH) 261 return Mode.Drawing; 262 MainApplication.getMap().statusLine.setDist(building.getLength()); 263 return Mode.None; 260 return modeDrawingCircle(p); 264 261 } else { 265 262 building.setPlace(p, ToolSettings.getWidth(), ToolSettings.getLenStep(), shift); 266 263 if (building.getLength() < MIN_LEN_WIDTH) 267 return Mode.D rawing;264 return Mode.DRAWING; 268 265 MainApplication.getMap().statusLine.setDist(building.getLength()); 269 return ToolSettings.getWidth() == 0 ? Mode.DrawingWidth : Mode.None; 270 } 266 return ToolSettings.getWidth() == 0 ? Mode.DRAWING_WIDTH : Mode.NONE; 267 } 268 } 269 270 private Mode modeDrawingCircle(EastNorth p) { 271 if (ToolSettings.getWidth() != 0) { 272 building.setPlaceCircle(p, ToolSettings.getWidth(), shift); 273 } else { 274 building.setPlace(p, ToolSettings.getWidth(), ToolSettings.getLenStep(), shift); 275 } 276 if (building.getLength() < MIN_LEN_WIDTH) 277 return Mode.DRAWING; 278 MainApplication.getMap().statusLine.setDist(building.getLength()); 279 return Mode.NONE; 271 280 } 272 281 … … 275 284 double width = Math.abs(building.getWidth()); 276 285 MainApplication.getMap().statusLine.setDist(width); 277 return width < MIN_LEN_WIDTH ? Mode.D rawingWidth: Mode.None;286 return width < MIN_LEN_WIDTH ? Mode.DRAWING_WIDTH : Mode.NONE; 278 287 } 279 288 280 289 private Mode modeDrawingAngFix() { 281 290 building.angFix(getEastNorth()); 282 return Mode.N one;291 return Mode.NONE; 283 292 } 284 293 … … 288 297 updateKeyModifiers(e); 289 298 } 290 if (mode == Mode.N one) {291 nextMode = Mode.N one;292 return; 293 } 294 295 if (mode == Mode.D rawing) {299 if (mode == Mode.NONE) { 300 nextMode = Mode.NONE; 301 return; 302 } 303 304 if (mode == Mode.DRAWING) { 296 305 nextMode = modeDrawing(); 297 } else if (mode == Mode.D rawingWidth) {306 } else if (mode == Mode.DRAWING_WIDTH) { 298 307 nextMode = modeDrawingWidth(); 299 } else if (mode == Mode.D rawingAngFix) {308 } else if (mode == Mode.DRAWING_ANG_FIX) { 300 309 nextMode = modeDrawingAngFix(); 301 310 } else { … … 306 315 @Override 307 316 public void paint(Graphics2D g, MapView mv, Bounds bbox) { 308 if (mode == Mode.N one|| building.getLength() == 0) {317 if (mode == Mode.NONE || building.getLength() == 0) { 309 318 return; 310 319 } … … 324 333 EastNorth en = getEastNorth(); 325 334 building.setBase(en); 326 mode = Mode.D rawing;335 mode = Mode.DRAWING; 327 336 updateStatusLine(); 328 337 } … … 330 339 private void drawingAdvance(MouseEvent e) { 331 340 processMouseEvent(e); 332 if (this.mode != Mode.N one&& this.nextMode == Mode.None) {341 if (this.mode != Mode.NONE && this.nextMode == Mode.NONE) { 333 342 drawingFinish(); 334 343 } else { … … 346 355 w = building.createRectangle(ctrl); 347 356 } 348 if (w != null) { 349 if (!alt || ToolSettings.isUsingAddr()) 350 for (Map.Entry<String, String> kv : ToolSettings.getTags().entrySet()) { 351 w.put(kv.getKey(), kv.getValue()); 352 } 353 if (ToolSettings.isUsingAddr()) 354 showAddrDialog(w); 355 if (ToolSettings.isAutoSelect() 356 && (getLayerManager().getEditDataSet().getSelected().isEmpty() || shift || 357 ToolSettings.isAutoSelectReplaceSelection())) { 358 getLayerManager().getEditDataSet().setSelected(w); 357 drawingFinish(w); 358 } 359 cancelDrawing(); 360 } 361 362 private void drawingFinish(Way w) { 363 if (w != null) { 364 if (!alt || ToolSettings.isUsingAddr()) 365 for (Map.Entry<String, String> kv : ToolSettings.getTags().entrySet()) { 366 w.put(kv.getKey(), kv.getValue()); 359 367 } 360 } 361 } 362 cancelDrawing(); 368 if (ToolSettings.isUsingAddr()) 369 showAddrDialog(w); 370 if (ToolSettings.isAutoSelect() 371 && (getLayerManager().getEditDataSet().getSelected().isEmpty() || shift || 372 ToolSettings.isAutoSelectReplaceSelection())) { 373 getLayerManager().getEditDataSet().setSelected(w); 374 } 375 } 363 376 } 364 377 … … 372 385 requestFocusInMapView(); 373 386 374 if (mode == Mode.N one)387 if (mode == Mode.NONE) 375 388 drawingStart(e); 376 389 } … … 380 393 processMouseEvent(e); 381 394 updCursor(); 382 if (mode != Mode.N one)395 if (mode != Mode.NONE) 383 396 MainApplication.getMap().mapView.repaint(); 384 397 } … … 399 412 } 400 413 401 if (mode == Mode.D rawing&& !dragged)402 return; 403 if (mode == Mode.N one)414 if (mode == Mode.DRAWING && !dragged) 415 return; 416 if (mode == Mode.NONE) 404 417 return; 405 418 … … 418 431 } else { 419 432 Way w = MainApplication.getMap().mapView.getNearestWay(mousePos, OsmPrimitive::isSelectable); 420 if (w != null && w.get( "building") != null) {433 if (w != null && w.get(BUILDING_STRING) != null) { 421 434 setCursor(cursorJoinWay); 422 435 return; … … 437 450 processMouseEvent(e); 438 451 updCursor(); 439 if (mode != Mode.N one)452 if (mode != Mode.NONE) 440 453 MainApplication.getMap().mapView.repaint(); 441 454 } … … 443 456 @Override 444 457 public String getModeHelpText() { 445 if (mode == Mode.N one)458 if (mode == Mode.NONE) 446 459 return tr("Point on the corner of the building to start drawing"); 447 if (mode == Mode.D rawing)460 if (mode == Mode.DRAWING) 448 461 return tr("Point on opposite end of the building"); 449 if (mode == Mode.D rawingWidth)462 if (mode == Mode.DRAWING_WIDTH) 450 463 return tr("Set width of the building"); 451 464 return ""; -
applications/editors/josm/plugins/buildings_tools/src/org/openstreetmap/josm/plugins/buildings_tools/MergeAddrPointsAction.java
r36134 r36382 27 27 import org.openstreetmap.josm.command.SequenceCommand; 28 28 import org.openstreetmap.josm.data.UndoRedoHandler; 29 import org.openstreetmap.josm.data.osm.IPrimitive; 29 30 import org.openstreetmap.josm.data.osm.Node; 30 31 import org.openstreetmap.josm.data.osm.OsmPrimitive; … … 43 44 public class MergeAddrPointsAction extends JosmAction { 44 45 46 private static class MultiConflict { 47 private final int multi; 48 private final int conflicts; 49 public MultiConflict(int multi, int conflict) { 50 this.multi = multi; 51 this.conflicts = conflict; 52 } 53 } 54 45 55 /** 46 56 * Merge the address point with the building … … 66 76 List<Node> addrNodes = new LinkedList<>(); 67 77 List<Way> buildings = new LinkedList<>(); 78 if (!generateAddressesAndBuildings(selection, addrNodes, buildings)) { 79 return; 80 } 81 82 Set<Way> overlappingWays = removeNodesInMoreThanOneBuilding(addrNodes, buildings); 83 84 List<Command> cmds = new LinkedList<>(); 85 List<Pair<Node, Way>> replaced = new ArrayList<>(); 86 Set<Relation> modifiedRelations = new HashSet<>(); 87 88 MultiConflict multiConflict = parseBuildingWays(cmds, replaced, modifiedRelations, buildings, addrNodes); 89 parseRelations(cmds, replaced, modifiedRelations); 90 if (!replaced.isEmpty()) { 91 final Command deleteCommand = DeleteCommand.delete(replaced.stream().map(p -> p.a).collect(Collectors.toList())); 92 if (deleteCommand != null) { 93 cmds.add(deleteCommand); 94 } 95 } 96 97 generateFinalMessages(cmds, overlappingWays, multiConflict); 98 if (!cmds.isEmpty()) 99 UndoRedoHandler.getInstance().add(new SequenceCommand("Merge addresses", cmds)); 100 } 101 102 /** 103 * Find the addresses and buildings from the selection 104 * @param selection The selection to look through 105 * @param addrNodes The collection to add address nodes to 106 * @param buildings The collection to add buildings to 107 * @return {@code true} if we can continue on 108 */ 109 private static boolean generateAddressesAndBuildings(Collection<OsmPrimitive> selection, List<Node> addrNodes, List<Way> buildings) { 68 110 for (OsmPrimitive p : selection) { 69 if (p.getType() == OsmPrimitiveType.NODE) { 70 boolean refsOK = true; 71 for (OsmPrimitive r : p.getReferrers()) { 72 if (r.getType() == OsmPrimitiveType.WAY) { 73 // Don't use nodes if they're referenced by ways 74 refsOK = false; 75 break; 76 } 77 } 78 if (!refsOK) 79 continue; 111 // Don't use nodes if they're referenced by ways 112 if (p.getType() == OsmPrimitiveType.NODE 113 && p.getReferrers().stream().map(IPrimitive::getType).noneMatch(OsmPrimitiveType.WAY::equals)) { 80 114 for (String key : p.getKeys().keySet()) { 81 115 if (key.startsWith("addr:")) { … … 90 124 new Notification(tr("No address nodes found in the selection")) 91 125 .setIcon(JOptionPane.ERROR_MESSAGE).show(); 92 return; 126 return false; 93 127 } 94 128 if (buildings.isEmpty()) { 95 129 new Notification(tr("No building ways found in the selection")) 96 130 .setIcon(JOptionPane.ERROR_MESSAGE).show(); 97 return; 98 } 99 131 return false; 132 } 133 return true; 134 } 135 136 /** 137 * Remove nodes that are in more than one building 138 * @param addrNodes The address nodes to look through 139 * @param buildings The buildings to look through 140 * @return The overlapping ways 141 */ 142 private static Set<Way> removeNodesInMoreThanOneBuilding(List<Node> addrNodes, List<Way> buildings) { 100 143 // find nodes covered by more than one building, see #17625 101 144 Map<Node, Way> nodeToWayMap = new HashMap<>(); … … 113 156 } 114 157 buildings.removeAll(overlappingWays); 115 116 List<Command> cmds = new LinkedList<>(); 158 return overlappingWays; 159 } 160 161 private static MultiConflict parseBuildingWays(List<Command> cmds, List<Pair<Node, Way>> replaced, 162 Set<Relation> modifiedRelations, List<Way> buildings, 163 List<Node> addrNodes) { 117 164 int multi = 0; 118 165 int conflicts = 0; 119 List<Pair<Node, Way>> replaced = new ArrayList<>();120 Set<Relation> modifiedRelations = new HashSet<>();121 166 for (Way w : buildings) { 122 167 Node mergeNode = null; … … 137 182 continue; 138 183 if (mergeNode != null) { 139 boolean hasConflicts = false; 140 Map<String, String> tags = new HashMap<>(); 141 for (Map.Entry<String, String> entry : mergeNode.getKeys().entrySet()) { 142 String newValue = entry.getValue(); 143 if (newValue == null) 144 continue; 145 String oldValue = w.getKeys().get(entry.getKey()); 146 if (!newValue.equals(oldValue)) { 147 if (oldValue == null) { 148 tags.put(entry.getKey(), newValue); 149 } else 150 hasConflicts = true; 151 } 152 } 153 if (hasConflicts) 154 conflicts++; 155 if (!tags.isEmpty()) 156 cmds.add(new ChangePropertyCommand(Collections.singleton(w), tags)); 157 if (!hasConflicts) { 158 replaced.add(Pair.create(mergeNode, w)); 159 modifiedRelations.addAll(mergeNode.referrers(Relation.class).collect(Collectors.toList())); 160 } 161 } 162 } 163 184 conflicts += checkForConflicts(cmds, replaced, modifiedRelations, w, mergeNode); 185 } 186 } 187 return new MultiConflict(multi, conflicts); 188 } 189 190 private static int checkForConflicts(List<Command> cmds, List<Pair<Node, Way>> replaced, 191 Set<Relation> modifiedRelations, Way w, Node mergeNode) { 192 boolean hasConflicts = false; 193 int conflicts = 0; 194 Map<String, String> tags = new HashMap<>(); 195 for (Map.Entry<String, String> entry : mergeNode.getKeys().entrySet()) { 196 String newValue = entry.getValue(); 197 if (newValue == null) 198 continue; 199 String oldValue = w.getKeys().get(entry.getKey()); 200 if (!newValue.equals(oldValue)) { 201 if (oldValue == null) { 202 tags.put(entry.getKey(), newValue); 203 } else 204 hasConflicts = true; 205 } 206 } 207 if (hasConflicts) 208 conflicts++; 209 if (!tags.isEmpty()) 210 cmds.add(new ChangePropertyCommand(Collections.singleton(w), tags)); 211 if (!hasConflicts) { 212 replaced.add(Pair.create(mergeNode, w)); 213 modifiedRelations.addAll(mergeNode.referrers(Relation.class).collect(Collectors.toList())); 214 } 215 return conflicts; 216 } 217 218 private static void parseRelations(List<Command> cmds, List<Pair<Node, Way>> replaced, Set<Relation> modifiedRelations) { 164 219 for (Relation r : modifiedRelations) { 165 220 List<RelationMember> members = new ArrayList<>(r.getMembers()); … … 178 233 } 179 234 } 180 if (!replaced.isEmpty()) { 181 final Command deleteCommand = DeleteCommand.delete(replaced.stream().map(p -> p.a).collect(Collectors.toList())); 182 if (deleteCommand != null) { 183 cmds.add(deleteCommand); 184 } 185 } 186 235 } 236 237 private static void generateFinalMessages(List<Command> cmds, Set<Way> overlappingWays, MultiConflict multiConflict) { 238 final int multi = multiConflict.multi; 239 final int conflicts = multiConflict.conflicts; 187 240 if (multi != 0) 188 241 new Notification(trn("There is {0} building with multiple address nodes inside", … … 191 244 if (conflicts != 0) 192 245 new Notification(trn("There is {0} building with address conflicts", 193 246 "There are {0} buildings with address conflicts", conflicts, conflicts)) 194 247 .setIcon(JOptionPane.WARNING_MESSAGE).show(); 195 248 if (!overlappingWays.isEmpty()) … … 199 252 new Notification(tr("No address nodes inside buildings found")) 200 253 .setIcon(JOptionPane.INFORMATION_MESSAGE).show(); 201 if (!cmds.isEmpty())202 UndoRedoHandler.getInstance().add(new SequenceCommand("Merge addresses", cmds));203 254 } 204 255 -
applications/editors/josm/plugins/buildings_tools/src/org/openstreetmap/josm/plugins/buildings_tools/MyDialog.java
r35500 r36382 5 5 6 6 import java.awt.Component; 7 import java.awt.GridBagConstraints; 7 8 import java.awt.GridBagLayout; 8 9 import java.awt.Insets; … … 15 16 import org.openstreetmap.josm.tools.GBC; 16 17 18 /** 19 * A customized dialog for buildings tools 20 */ 17 21 public abstract class MyDialog extends ExtendedDialog { 18 22 private static final String[] BUTTON_TEXTS = new String[] {tr("OK"), tr("Cancel")}; … … 25 29 panel.add(label, GBC.std()); 26 30 label.setLabelFor(c); 27 panel.add(c, GBC.eol().fill(G BC.HORIZONTAL));31 panel.add(c, GBC.eol().fill(GridBagConstraints.HORIZONTAL)); 28 32 } 29 33 30 public MyDialog(String title) { 34 /** 35 * Create a new dialog 36 * @param title The title for the dialog 37 */ 38 protected MyDialog(String title) { 31 39 super(MainApplication.getMainFrame(), title, BUTTON_TEXTS, true); 32 40 contentInsets = new Insets(15, 15, 5, 15);
Note:
See TracChangeset
for help on using the changeset viewer.