Changeset 36382 in osm for applications


Ignore:
Timestamp:
2025-02-04T20:37:26+01:00 (13 hours ago)
Author:
taylor.smock
Message:

Fix most sonarlint issues in buildings_tools

The remaining issues are as follows:

  • Package name (buildings_tools)
  • Some documentation for public methods where the purpose of the method was unclear
  • A loop which (according to sonarlint) should be combined with another loop
    • This isn't the case -- there are side effects from the loop.
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  
    1111import javax.swing.SpinnerNumberModel;
    1212
     13/**
     14 * Address dialog for buildings
     15 */
    1316public 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;
    1923
     24    /**
     25     * Create a new dialog object
     26     */
    2027    public AddressDialog() {
    2128        super(tr("Building address"));
     
    2633        streetname.setText(lstreetname);
    2734
    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);
    3037        incSpinner.setValue(inc);
    3138        addLabelled(tr("House number increment:"), incSpinner);
     
    3946            return "";
    4047        try {
    41             Integer num = NumberFormat.getInstance().parse(lhousenum).intValue() + inc;
    42             return num.toString();
     48            int num = NumberFormat.getInstance().parse(lhousenum).intValue() + inc;
     49            return Integer.toString(num);
    4350        } catch (ParseException e) {
    4451            return lhousenum;
     
    4653    }
    4754
     55    /**
     56     * Save values for future use in the current running JOSM instance
     57     */
    4858    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();
    5266    }
    5367
  • applications/editors/josm/plugins/buildings_tools/src/org/openstreetmap/josm/plugins/buildings_tools/AdvancedSettingsDialog.java

    r36081 r36382  
    44import static org.openstreetmap.josm.tools.I18n.tr;
    55
     6import java.awt.GridBagConstraints;
    67import java.util.Map;
    78
     
    3132        super(tr("Advanced settings"));
    3233
    33         panel.add(new JLabel(tr("Buildings tags:")), GBC.eol().fill(GBC.HORIZONTAL));
     34        panel.add(new JLabel(tr("Buildings tags:")), GBC.eol().fill(GridBagConstraints.HORIZONTAL));
    3435
    3536        for (Map.Entry<String, String> entry : ToolSettings.getTags().entrySet()) {
    3637            tagsModel.add(entry.getKey(), entry.getValue());
    3738        }
    38         panel.add(new TagEditorPanel(tagsModel, null, Changeset.MAX_CHANGESET_TAG_LENGTH), GBC.eop().fill(GBC.BOTH));
     39        panel.add(new TagEditorPanel(tagsModel, null, Changeset.MAX_CHANGESET_TAG_LENGTH), GBC.eop().fill(GridBagConstraints.BOTH));
    3940
    40         panel.add(cBigMode, GBC.eol().fill(GBC.HORIZONTAL));
    41         panel.add(cSoftCur, GBC.eol().fill(GBC.HORIZONTAL));
    42         panel.add(cNoClickDrag, GBC.eol().fill(GBC.HORIZONTAL));
    43         panel.add(cToggleMapMode, GBC.eol().fill(GBC.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));
    4445
    4546        cBigMode.setSelected(ToolSettings.isBBMode());
  • applications/editors/josm/plugins/buildings_tools/src/org/openstreetmap/josm/plugins/buildings_tools/AngleSnap.java

    r35978 r36382  
    1111import org.openstreetmap.josm.tools.Pair;
    1212
     13/**
     14 * A class for getting angles for snapping
     15 */
    1316public class AngleSnap {
    1417    private static final double PI_2 = Math.PI / 2;
    1518    final TreeSet<Double> snapSet = new TreeSet<>();
    1619
     20    /**
     21     * Clear the snap directions
     22     */
    1723    public final void clear() {
    1824        snapSet.clear();
    1925    }
    2026
     27    /**
     28     * Add a snap direction
     29     * @param snap The direction in radians
     30     */
    2131    public final void addSnap(double snap) {
    2232        snapSet.add(snap % PI_2);
    2333    }
    2434
     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     */
    2540    public final Double addSnap(Node[] nodes) {
    2641        if (nodes.length == 2) {
     
    3651    }
    3752
     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     */
    3857    public final void addSnap(Way way) {
    3958        for (Pair<Node, Node> pair : way.getNodePairs(false)) {
     
    4564    }
    4665
     66    /**
     67     * Get the angle between the first and last snaps added
     68     * @return The angle between the first and last snaps added
     69     */
    4770    public final Double getAngle() {
    4871        if (snapSet.isEmpty()) {
     
    6487    }
    6588
     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     */
    6694    public final double snapAngle(double angle) {
    6795        if (snapSet.isEmpty()) {
     
    78106
    79107        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);
    88109        } 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;
    97133        }
    98134    }
  • applications/editors/josm/plugins/buildings_tools/src/org/openstreetmap/josm/plugins/buildings_tools/Building.java

    r36134 r36382  
    3131import org.openstreetmap.josm.data.osm.BBox;
    3232import org.openstreetmap.josm.data.osm.DataSet;
     33import org.openstreetmap.josm.data.osm.IPrimitive;
    3334import org.openstreetmap.josm.data.osm.Node;
    3435import org.openstreetmap.josm.data.osm.OsmPrimitive;
     
    5354    private static final double EQUAL_NODE_DIST_TOLERANCE = 1e-6;
    5455
     56    /**
     57     * Clear the current angle information
     58     */
    5559    public void clearAngleSnap() {
    5660        angleSnap.clear();
     
    5862    }
    5963
     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     */
    6070    public void addAngleSnap(Node[] nodes) {
    6171        drawingAngle = angleSnap.addSnap(nodes);
    6272    }
    6373
     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     */
    6479    public void addAngleSnap(Way way) {
    6580        angleSnap.addSnap(way);
     
    7792    }
    7893
     94    /**
     95     * Check if we are currently drawing a rectangle
     96     * @return {@code true} if we are drawing a rectangle
     97     */
    7998    public boolean isRectDrawing() {
    8099        return drawingAngle != null && ToolSettings.getWidth() == 0 && ToolSettings.getLenStep() == 0
     
    82101    }
    83102
     103    /**
     104     * Get the current drawing angle
     105     * @return The current drawing angle. May be {@code null}.
     106     */
    84107    public Double getDrawingAngle() {
    85108        return drawingAngle;
    86109    }
    87110
     111    /**
     112     * Reset the current building drawing
     113     */
    88114    public void reset() {
    89115        len = 0;
     
    94120    }
    95121
     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     */
    96127    public EastNorth getPoint(int num) {
    97128        return en[num];
     
    209240    }
    210241
     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     */
    211247    public void paint(Graphics2D g, MapView mv) {
    212248        // Make a local copy to avoid other threads resetting what we are drawing.
     
    255291            if (n.isUsable() && findUsableTag(n)) {
    256292                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);
    269295                }
    270296            }
     
    273299            return null;
    274300        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;
    275311    }
    276312
     
    284320    }
    285321
     322    /**
     323     * Create a circle in the dataset
     324     * @return The created circle
     325     */
    286326    public Way createCircle() {
    287327        DataSet ds = MainApplication.getLayerManager().getEditDataSet();
     
    358398    }
    359399
     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     */
    360405    public Way createRectangle(boolean ctrl) {
    361406        if (len == 0)
     
    474519            Node addrNode = getAddressNode(w);
    475520            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));
    488536                }
    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);
    498547        }
    499548    }
  • applications/editors/josm/plugins/buildings_tools/src/org/openstreetmap/josm/plugins/buildings_tools/BuildingCircleAction.java

    r34572 r36382  
    1010import org.openstreetmap.josm.tools.Shortcut;
    1111
     12/**
     13 * The action for drawing building circles
     14 */
    1215public class BuildingCircleAction extends JosmAction {
    1316
     17    /**
     18     * Create a new building circle action
     19     */
    1420    public BuildingCircleAction() {
    1521        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  
    1010import org.openstreetmap.josm.tools.Shortcut;
    1111
     12/**
     13 * Draw rectangle buildings
     14 */
    1215public class BuildingRectangleAction extends JosmAction {
    1316
     17    /**
     18     * Create a new action for drawing rectangular buildings
     19     */
    1420    public BuildingRectangleAction() {
    1521        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  
    22package org.openstreetmap.josm.plugins.buildings_tools;
    33
     4import static org.openstreetmap.josm.tools.I18n.marktr;
    45import static org.openstreetmap.josm.tools.I18n.tr;
    56
     
    1011import org.openstreetmap.josm.tools.Shortcut;
    1112
     13/**
     14 * An action to open the {@link BuildingSizeDialog}
     15 */
    1216public 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     */
    1421    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)),
    1724                KeyEvent.VK_B, Shortcut.ALT_CTRL),
    1825                true, "edit:buildingsdialog", false);
  • applications/editors/josm/plugins/buildings_tools/src/org/openstreetmap/josm/plugins/buildings_tools/BuildingSizeDialog.java

    r35915 r36382  
    44import static org.openstreetmap.josm.tools.I18n.tr;
    55
    6 import java.awt.event.ActionEvent;
    7 import java.awt.event.ActionListener;
     6import java.awt.GridBagConstraints;
    87import java.text.NumberFormat;
    98import java.text.ParseException;
     
    1716import org.openstreetmap.josm.tools.GBC;
    1817
     18/**
     19 * A dialog for setting building sizes and other information
     20 */
    1921public class BuildingSizeDialog extends MyDialog {
    2022    private final JFormattedTextField twidth = new JFormattedTextField(NumberFormat.getInstance());
     
    2729    private final JRadioButton rectangleRadio = new JRadioButton(tr("Rectangle"));
    2830
     31    /**
     32     * Create a new dialog for building sizes
     33     */
    2934    public BuildingSizeDialog() {
    3035        super(tr("Set buildings size and shape"));
     
    3641        rectangleRadio.setSelected(ToolSettings.Shape.RECTANGLE == ToolSettings.getShape());
    3742
    38         panel.add(rectangleRadio, GBC.eol().fill(GBC.HORIZONTAL));
    39         panel.add(circleRadio, GBC.eol().fill(GBC.HORIZONTAL));
     43        panel.add(rectangleRadio, GBC.eol().fill(GridBagConstraints.HORIZONTAL));
     44        panel.add(circleRadio, GBC.eol().fill(GridBagConstraints.HORIZONTAL));
    4045
    4146        addLabelled(tr("Buildings width/diameter:"), twidth);
    4247        addLabelled(tr("Length step:"), tlenstep);
    43         panel.add(caddr, GBC.eol().fill(GBC.HORIZONTAL));
    44         panel.add(cAutoSelect, GBC.eol().fill(GBC.HORIZONTAL));
    45         panel.add(cAutoSelectReplaceSelection, GBC.eol().fill(GBC.HORIZONTAL));
    46         panel.add(cAddrNode, GBC.eol().fill(GBC.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));
    4752
    4853        twidth.setValue(ToolSettings.getWidth());
     
    5459
    5560        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();
    6365            }
    6466        });
    65         panel.add(bAdv, GBC.eol().insets(0, 5, 0, 0).anchor(GBC.EAST));
     67        panel.add(bAdv, GBC.eol().insets(0, 5, 0, 0).anchor(GridBagConstraints.EAST));
    6668
    6769        setupDialog();
     
    6971    }
    7072
     73    /**
     74     * Get the specified max width/diameter
     75     * @return The maximum width/diameter for rectangles/circles
     76     */
    7177    public final double width() {
    7278        try {
     
    7783    }
    7884
     85    /**
     86     * Get the step length for drawing rectangular buildings
     87     * @return The discrete steps to increase rectanglular building sizes
     88     */
    7989    public double lenstep() {
    8090        try {
     
    8595    }
    8696
     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     */
    87101    public final boolean useAddr() {
    88102        return caddr.isSelected();
    89103    }
    90104
     105    /**
     106     * Save the settings for this dialog
     107     */
    91108    public final void saveSettings() {
    92109        if (circleRadio.isSelected()) {
  • applications/editors/josm/plugins/buildings_tools/src/org/openstreetmap/josm/plugins/buildings_tools/DrawBuildingAction.java

    r36081 r36382  
    3939import java.util.LinkedList;
    4040import java.util.Map;
     41import java.util.Objects;
    4142
    4243import static org.openstreetmap.josm.plugins.buildings_tools.BuildingsToolsPlugin.latlon2eastNorth;
     
    5051        KeyPressReleaseListener, ModifierExListener {
    5152    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");
    5256    // We need to avoid opening many file descriptors on Linux under Wayland -- see JOSM #21929. This will probably also
    5357    // 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);
    5660
    5761    private enum Mode {
    58         None, Drawing, DrawingWidth, DrawingAngFix
     62        NONE, DRAWING, DRAWING_WIDTH, DRAWING_ANG_FIX
    5963    }
    6064
     
    6367    private Cursor customCursor;
    6468
    65     private Mode mode = Mode.None;
    66     private Mode nextMode = Mode.None;
     69    private Mode mode = Mode.NONE;
     70    private Mode nextMode = Mode.NONE;
    6771
    6872    private Color selectedColor = Color.red;
     
    7478    final transient Building building = new Building();
    7579
    76     private final PreferenceChangedListener shapeChangeListener = event -> updCursor();
     80    private final transient PreferenceChangedListener shapeChangeListener = event -> updCursor();
    7781
    7882    /**
     
    8084     */
    8185    public DrawBuildingAction() {
    82         super(tr("Draw buildings"), "building", tr("Draw buildings"),
     86        super(tr(DRAW_BUILDINGS), BUILDING_STRING, tr(DRAW_BUILDINGS),
    8387                Shortcut.registerShortcut("mapmode:buildings",
    84                         tr("Mode: {0}", tr("Draw buildings")),
     88                        tr("Mode: {0}", tr(DRAW_BUILDINGS)),
    8589                        KeyEvent.VK_B, Shortcut.DIRECT),
    8690                // Set super.cursor to crosshair without overlay because super.cursor is final,
    8791                // but we use two different cursors with overlays for rectangular and circular buildings
    8892                // 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");
    9397    }
    9498
     
    160164        Config.getPref().removeKeyPreferenceChangeListener("buildings_tool.shape", shapeChangeListener);
    161165
    162         if (mode != Mode.None)
     166        if (mode != Mode.NONE)
    163167            map.mapView.repaint();
    164         mode = Mode.None;
     168        mode = Mode.NONE;
    165169    }
    166170
     
    169173     */
    170174    public final void cancelDrawing() {
    171         mode = Mode.None;
     175        mode = Mode.NONE;
    172176        MapFrame map = MainApplication.getMap();
    173177        if (map == null || map.mapView == null)
     
    188192            processMouseEvent(null);
    189193            updCursor();
    190             if (mode != Mode.None)
     194            if (mode != Mode.NONE)
    191195                MainApplication.getMap().mapView.repaint();
    192196        }
     
    196200    public void doKeyPressed(KeyEvent e) {
    197201        if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
    198             if (mode != Mode.None)
     202            if (mode != Mode.NONE)
    199203                e.consume();
    200204
     
    206210        }
    207211        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);
    214219        }
    215220    }
     
    227232            IWaySegment<Node, Way> ws = MainApplication.getMap().mapView.getNearestWaySegment(mousePos,
    228233                    OsmPrimitive::isSelectable);
    229             if (ws != null && ws.getWay().get("building") != null) {
     234            if (ws != null && ws.getWay().get(BUILDING_STRING) != null) {
    230235                EastNorth p1 = latlon2eastNorth(ws.getFirstNode());
    231236                EastNorth p2 = latlon2eastNorth(ws.getSecondNode());
     
    250255            building.setPlaceRect(p);
    251256            if (Math.abs(building.getLength()) < MIN_LEN_WIDTH)
    252                 return Mode.Drawing;
    253             return shift ? Mode.DrawingAngFix : Mode.None;
     257                return Mode.DRAWING;
     258            return shift ? Mode.DRAWING_ANG_FIX : Mode.NONE;
    254259        } 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);
    264261        } else {
    265262            building.setPlace(p, ToolSettings.getWidth(), ToolSettings.getLenStep(), shift);
    266263            if (building.getLength() < MIN_LEN_WIDTH)
    267                 return Mode.Drawing;
     264                return Mode.DRAWING;
    268265            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;
    271280    }
    272281
     
    275284        double width = Math.abs(building.getWidth());
    276285        MainApplication.getMap().statusLine.setDist(width);
    277         return width < MIN_LEN_WIDTH ? Mode.DrawingWidth : Mode.None;
     286        return width < MIN_LEN_WIDTH ? Mode.DRAWING_WIDTH : Mode.NONE;
    278287    }
    279288
    280289    private Mode modeDrawingAngFix() {
    281290        building.angFix(getEastNorth());
    282         return Mode.None;
     291        return Mode.NONE;
    283292    }
    284293
     
    288297            updateKeyModifiers(e);
    289298        }
    290         if (mode == Mode.None) {
    291             nextMode = Mode.None;
    292             return;
    293         }
    294 
    295         if (mode == Mode.Drawing) {
     299        if (mode == Mode.NONE) {
     300            nextMode = Mode.NONE;
     301            return;
     302        }
     303
     304        if (mode == Mode.DRAWING) {
    296305            nextMode = modeDrawing();
    297         } else if (mode == Mode.DrawingWidth) {
     306        } else if (mode == Mode.DRAWING_WIDTH) {
    298307            nextMode = modeDrawingWidth();
    299         } else if (mode == Mode.DrawingAngFix) {
     308        } else if (mode == Mode.DRAWING_ANG_FIX) {
    300309            nextMode = modeDrawingAngFix();
    301310        } else {
     
    306315    @Override
    307316    public void paint(Graphics2D g, MapView mv, Bounds bbox) {
    308         if (mode == Mode.None || building.getLength() == 0) {
     317        if (mode == Mode.NONE || building.getLength() == 0) {
    309318            return;
    310319        }
     
    324333        EastNorth en = getEastNorth();
    325334        building.setBase(en);
    326         mode = Mode.Drawing;
     335        mode = Mode.DRAWING;
    327336        updateStatusLine();
    328337    }
     
    330339    private void drawingAdvance(MouseEvent e) {
    331340        processMouseEvent(e);
    332         if (this.mode != Mode.None && this.nextMode == Mode.None) {
     341        if (this.mode != Mode.NONE && this.nextMode == Mode.NONE) {
    333342            drawingFinish();
    334343        } else {
     
    346355                w = building.createRectangle(ctrl);
    347356            }
    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());
    359367                }
    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        }
    363376    }
    364377
     
    372385        requestFocusInMapView();
    373386
    374         if (mode == Mode.None)
     387        if (mode == Mode.NONE)
    375388            drawingStart(e);
    376389    }
     
    380393        processMouseEvent(e);
    381394        updCursor();
    382         if (mode != Mode.None)
     395        if (mode != Mode.NONE)
    383396            MainApplication.getMap().mapView.repaint();
    384397    }
     
    399412        }
    400413
    401         if (mode == Mode.Drawing && !dragged)
    402             return;
    403         if (mode == Mode.None)
     414        if (mode == Mode.DRAWING && !dragged)
     415            return;
     416        if (mode == Mode.NONE)
    404417            return;
    405418
     
    418431            } else {
    419432                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) {
    421434                    setCursor(cursorJoinWay);
    422435                    return;
     
    437450        processMouseEvent(e);
    438451        updCursor();
    439         if (mode != Mode.None)
     452        if (mode != Mode.NONE)
    440453            MainApplication.getMap().mapView.repaint();
    441454    }
     
    443456    @Override
    444457    public String getModeHelpText() {
    445         if (mode == Mode.None)
     458        if (mode == Mode.NONE)
    446459            return tr("Point on the corner of the building to start drawing");
    447         if (mode == Mode.Drawing)
     460        if (mode == Mode.DRAWING)
    448461            return tr("Point on opposite end of the building");
    449         if (mode == Mode.DrawingWidth)
     462        if (mode == Mode.DRAWING_WIDTH)
    450463            return tr("Set width of the building");
    451464        return "";
  • applications/editors/josm/plugins/buildings_tools/src/org/openstreetmap/josm/plugins/buildings_tools/MergeAddrPointsAction.java

    r36134 r36382  
    2727import org.openstreetmap.josm.command.SequenceCommand;
    2828import org.openstreetmap.josm.data.UndoRedoHandler;
     29import org.openstreetmap.josm.data.osm.IPrimitive;
    2930import org.openstreetmap.josm.data.osm.Node;
    3031import org.openstreetmap.josm.data.osm.OsmPrimitive;
     
    4344public class MergeAddrPointsAction extends JosmAction {
    4445
     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
    4555    /**
    4656     * Merge the address point with the building
     
    6676        List<Node> addrNodes = new LinkedList<>();
    6777        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) {
    68110        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)) {
    80114                for (String key : p.getKeys().keySet()) {
    81115                    if (key.startsWith("addr:")) {
     
    90124            new Notification(tr("No address nodes found in the selection"))
    91125                    .setIcon(JOptionPane.ERROR_MESSAGE).show();
    92             return;
     126            return false;
    93127        }
    94128        if (buildings.isEmpty()) {
    95129            new Notification(tr("No building ways found in the selection"))
    96130                    .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) {
    100143        // find nodes covered by more than one building, see #17625
    101144        Map<Node, Way> nodeToWayMap = new HashMap<>();
     
    113156        }
    114157        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) {
    117164        int multi = 0;
    118165        int conflicts = 0;
    119         List<Pair<Node, Way>> replaced = new ArrayList<>();
    120         Set<Relation> modifiedRelations = new HashSet<>();
    121166        for (Way w : buildings) {
    122167            Node mergeNode = null;
     
    137182                continue;
    138183            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) {
    164219        for (Relation r : modifiedRelations) {
    165220            List<RelationMember> members = new ArrayList<>(r.getMembers());
     
    178233            }
    179234        }
    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;
    187240        if (multi != 0)
    188241            new Notification(trn("There is {0} building with multiple address nodes inside",
     
    191244        if (conflicts != 0)
    192245            new Notification(trn("There is {0} building with address conflicts",
    193                             "There are {0} buildings with address conflicts", conflicts, conflicts))
     246                    "There are {0} buildings with address conflicts", conflicts, conflicts))
    194247                    .setIcon(JOptionPane.WARNING_MESSAGE).show();
    195248        if (!overlappingWays.isEmpty())
     
    199252            new Notification(tr("No address nodes inside buildings found"))
    200253                    .setIcon(JOptionPane.INFORMATION_MESSAGE).show();
    201         if (!cmds.isEmpty())
    202             UndoRedoHandler.getInstance().add(new SequenceCommand("Merge addresses", cmds));
    203254    }
    204255
  • applications/editors/josm/plugins/buildings_tools/src/org/openstreetmap/josm/plugins/buildings_tools/MyDialog.java

    r35500 r36382  
    55
    66import java.awt.Component;
     7import java.awt.GridBagConstraints;
    78import java.awt.GridBagLayout;
    89import java.awt.Insets;
     
    1516import org.openstreetmap.josm.tools.GBC;
    1617
     18/**
     19 * A customized dialog for buildings tools
     20 */
    1721public abstract class MyDialog extends ExtendedDialog {
    1822    private static final String[] BUTTON_TEXTS = new String[] {tr("OK"), tr("Cancel")};
     
    2529        panel.add(label, GBC.std());
    2630        label.setLabelFor(c);
    27         panel.add(c, GBC.eol().fill(GBC.HORIZONTAL));
     31        panel.add(c, GBC.eol().fill(GridBagConstraints.HORIZONTAL));
    2832    }
    2933
    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) {
    3139        super(MainApplication.getMainFrame(), title, BUTTON_TEXTS, true);
    3240        contentInsets = new Insets(15, 15, 5, 15);
Note: See TracChangeset for help on using the changeset viewer.