Ignore:
Timestamp:
2019-04-07T09:48:42+02:00 (5 years ago)
Author:
gerdp
Message:

fix #17569: building_tools crashes when drawing circular building near 180 longitude

  • use method Node.isOutSideWorld() instead of LatLon.isOutSideWorld() (requires JOSM r14960)
  • improve code which tries to find an address node below the building to work also with circular buildings
  • fix some SonarLint inssues Use "==" to perform this enum comparison instead of using "equals"
Location:
applications/editors/josm/plugins/buildings_tools
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/buildings_tools/build.xml

    r34572 r34968  
    44    <property name="commit.message" value="BuildingTools: Alt key to disable tags"/>
    55    <!-- enter the *lowest* JOSM version this plugin is currently compatible with -->
    6     <property name="plugin.main.version" value="14153"/>
     6    <property name="plugin.main.version" value="14960"/>
    77   
    88    <!-- Configure these properties (replace "..." accordingly).
  • applications/editors/josm/plugins/buildings_tools/src/org/openstreetmap/josm/plugins/buildings_tools/Building.java

    r34850 r34968  
    33
    44import static org.openstreetmap.josm.plugins.buildings_tools.BuildingsToolsPlugin.eastNorth2latlon;
    5 import static org.openstreetmap.josm.plugins.buildings_tools.BuildingsToolsPlugin.latlon2eastNorth;
    65import static org.openstreetmap.josm.tools.I18n.tr;
    76
    87import java.awt.Graphics2D;
    98import java.awt.Point;
     9import java.awt.geom.Area;
    1010import java.awt.geom.GeneralPath;
    1111import java.util.ArrayList;
     
    7979    public boolean isRectDrawing() {
    8080        return drawingAngle != null && ToolSettings.getWidth() == 0 && ToolSettings.getLenStep() == 0
    81                 && ToolSettings.Shape.RECTANGLE.equals(ToolSettings.getShape());
     81                && ToolSettings.Shape.RECTANGLE == ToolSettings.getShape();
    8282    }
    8383
     
    134134        final EastNorth p1 = en[0];
    135135        en[1] = new EastNorth(p1.east() + Math.sin(heading) * len * meter, p1.north() + Math.cos(heading) * len * meter);
    136         if (ToolSettings.Shape.RECTANGLE.equals(ToolSettings.getShape())) {
     136        if (ToolSettings.Shape.RECTANGLE == ToolSettings.getShape()) {
    137137            en[2] = new EastNorth(p1.east() + Math.sin(heading) * len * meter + Math.cos(heading) * width * meter,
    138138                    p1.north() + Math.cos(heading) * len * meter - Math.sin(heading) * width * meter);
     
    217217        b.moveTo(pp1.x, pp1.y);
    218218        b.lineTo(pp2.x, pp2.y);
    219         if (ToolSettings.Shape.RECTANGLE.equals(ToolSettings.getShape())) {
     219        if (ToolSettings.Shape.RECTANGLE == ToolSettings.getShape()) {
    220220            Point pp3 = mv.getPoint(eastNorth2latlon(en[2]));
    221221            Point pp4 = mv.getPoint(eastNorth2latlon(en[3]));
     
    238238     * Returns a node with address tags under the building.
    239239     *
     240     * @param w
     241     *            the building way
    240242     * @return A node with address tags under the building.
    241243     */
    242     private Node getAddressNode() {
    243         BBox bbox = new BBox(eastNorth2latlon(en[0]), eastNorth2latlon(en[1]));
    244         if (ToolSettings.Shape.RECTANGLE.equals(ToolSettings.getShape())) {
    245             bbox.add(eastNorth2latlon(en[2]));
    246             bbox.add(eastNorth2latlon(en[3]));
    247         }
     244    private static Node getAddressNode(Way w) {
     245        BBox bbox = w.getBBox();
    248246        List<Node> nodes = new LinkedList<>();
    249         nodesloop:
     247        Area area = Geometry.getArea(w.getNodes());
    250248        for (Node n : MainApplication.getLayerManager().getEditDataSet().searchNodes(bbox)) {
    251249            if (n.isUsable() && findUsableTag(n)) {
    252                 double x = projection1(latlon2eastNorth(n.getCoor()));
    253                 double y = projection2(latlon2eastNorth(n.getCoor()));
    254                 if (Math.signum(x) != Math.signum(len) || Math.signum(y) != Math.signum(width))
    255                     continue;
    256                 if (Math.abs(x) > Math.abs(len) || Math.abs(y) > Math.abs(width))
    257                     continue;
    258                 for (OsmPrimitive p : n.getReferrers()) {
    259                     // Don't use nodes if they're referenced by ways
    260                     if (p.getType() == OsmPrimitiveType.WAY)
    261                         continue nodesloop;
     250                EastNorth enTest = n.getEastNorth();
     251                if (area.contains(enTest.getX(), enTest.getY())) {
     252                    boolean useNode = true;
     253                    for (OsmPrimitive p : n.getReferrers()) {
     254                        // Don't use nodes if they're referenced by ways
     255                        if (p.getType() == OsmPrimitiveType.WAY) {
     256                            useNode = false;
     257                            break;
     258                        }
     259                    }
     260                    if (useNode) {
     261                        nodes.add(n);
     262                    }
    262263                }
    263                 nodes.add(n);
    264264            }
    265265        }
     
    297297                created[i] = false;
    298298            }
    299             if (nodes[i].getCoor().isOutSideWorld()) {
     299            if (nodes[i].isOutSideWorld()) {
    300300                JOptionPane.showMessageDialog(MainApplication.getMainFrame(),
    301301                        tr("Cannot place building outside of the world."));
     
    325325        ds.addSelected(w.getNodes());
    326326
     327        int oldNumWays = ds.getWays().size();
    327328        CreateCircleAction action = new CreateCircleAction();
    328329        action.setEnabled(true);
     
    332333        ds.clearSelection();
    333334        ds.addSelected(selectedPrimitives);
    334 
    335         // get the way with the smallest id with the assumption that it is
    336         // newest way created by CreateCirclAction
    337         List<Way> ways = new ArrayList<>(ds.getWays());
    338         Collections.sort(ways);
    339         w = ways.get(0);
    340 
    341         addAddress(w, null);
    342 
    343         return w;
     335        if (oldNumWays < ds.getWays().size()) {
     336            // get the way with the smallest id with the assumption that it is
     337            // newest way created by CreateCirclAction
     338            List<Way> ways = new ArrayList<>(ds.getWays());
     339            Collections.sort(ways);
     340            w = ways.get(0);
     341
     342            addAddress(w, null);
     343
     344            return w;
     345        } else {
     346            // CreateCircleAction failed
     347            if (!addNodesCmd.isEmpty()) {
     348                UndoRedoHandler.getInstance().undo(1);
     349            }
     350            return null;
     351        }
    344352    }
    345353
     
    362370                created[i] = false;
    363371            }
    364             if (nodes[i].getCoor().isOutSideWorld()) {
     372            if (nodes[i].isOutSideWorld()) {
    365373                JOptionPane.showMessageDialog(MainApplication.getMainFrame(),
    366374                        tr("Cannot place building outside of the world."));
     
    458466    }
    459467
    460     private void addAddress(Way w, Collection<Command> cmdList) {
     468    private static void addAddress(Way w, Collection<Command> cmdList) {
    461469        if (ToolSettings.PROP_USE_ADDR_NODE.get()) {
    462             Node addrNode = getAddressNode();
     470            Node addrNode = getAddressNode(w);
    463471            if (addrNode != null) {
    464472                Collection<Command> addressCmds = cmdList != null ? cmdList : new LinkedList<>();
  • applications/editors/josm/plugins/buildings_tools/src/org/openstreetmap/josm/plugins/buildings_tools/BuildingSizeDialog.java

    r34572 r34968  
    3232        shapeGroup.add(circleRadio);
    3333        shapeGroup.add(rectangleRadio);
    34         circleRadio.setSelected(ToolSettings.Shape.CIRCLE.equals(ToolSettings.getShape()));
    35         rectangleRadio.setSelected(ToolSettings.Shape.RECTANGLE.equals(ToolSettings.getShape()));
     34        circleRadio.setSelected(ToolSettings.Shape.CIRCLE == ToolSettings.getShape());
     35        rectangleRadio.setSelected(ToolSettings.Shape.RECTANGLE == ToolSettings.getShape());
    3636
    3737        panel.add(rectangleRadio, GBC.eol().fill(GBC.HORIZONTAL));
  • applications/editors/josm/plugins/buildings_tools/src/org/openstreetmap/josm/plugins/buildings_tools/DrawBuildingAction.java

    r34904 r34968  
    8181    private static Cursor getCursor() {
    8282        try {
    83             if (ToolSettings.Shape.CIRCLE.equals(ToolSettings.getShape())) {
     83            if (ToolSettings.Shape.CIRCLE == ToolSettings.getShape()) {
    8484                return ImageProvider.getCursor("crosshair", "silo");
    8585            } else {
     
    226226    private boolean isRectDrawing() {
    227227        return building.isRectDrawing() && (!shift || ToolSettings.isBBMode())
    228                 && ToolSettings.Shape.RECTANGLE.equals(ToolSettings.getShape());
     228                && ToolSettings.Shape.RECTANGLE == ToolSettings.getShape();
    229229    }
    230230
     
    234234            building.setPlaceRect(p);
    235235            return shift ? Mode.DrawingAngFix : Mode.None;
    236         } else if (ToolSettings.Shape.CIRCLE.equals(ToolSettings.getShape())) {
     236        } else if (ToolSettings.Shape.CIRCLE == ToolSettings.getShape()) {
    237237            if (ToolSettings.getWidth() != 0) {
    238238                building.setPlaceCircle(p, ToolSettings.getWidth(), shift);
     
    320320        if (building.getLength() != 0) {
    321321            Way w;
    322             if (ToolSettings.Shape.CIRCLE.equals(ToolSettings.getShape())) {
     322            if (ToolSettings.Shape.CIRCLE == ToolSettings.getShape()) {
    323323                w = building.createCircle();
    324324            } else {
Note: See TracChangeset for help on using the changeset viewer.