Ticket #9223: bug9223.patch

File bug9223.patch, 4.4 KB (added by Balaitous, 12 years ago)
  • src/org/openstreetmap/josm/actions/AlignInCircleAction.java

     
    112112
    113113        // special case if no single nodes are selected and exactly one way is:
    114114        // then use the way's nodes
    115         if ((nodes.size() <= 2) && (ways.size() == 1)) {
    116             Way way = ways.get(0);
    117 
     115        if ((nodes.size() <= 2) && checkWaysArePolygon(ways)) {
    118116            // some more special combinations:
    119117            // When is selected node that is part of the way, then make a regular polygon, selected
    120118            // node doesn't move.
     
    123121            // When one way and one node is selected, set center to position of that node.
    124122            // When one more node, part of the way, is selected, set the radius equal to the
    125123            // distance between two nodes.
    126             if (nodes.size() > 0) {
    127                 if (nodes.size() == 1 && way.containsNode(nodes.get(0)) && allowRegularPolygon(way.getNodes())) {
    128                     regular = true;
    129                 } else if (nodes.size() >= 2) {
    130                     center = nodes.get(way.containsNode(nodes.get(0)) ? 1 : 0).getEastNorth();
    131                     if (nodes.size() == 2) {
    132                         radius = distance(nodes.get(0).getEastNorth(), nodes.get(1).getEastNorth());
    133                     }
    134                 }
    135                 nodes.clear();
     124                if (nodes.size() == 1 && ways.size() == 1) {
     125                        // Regular polygons are allowed only if there is just one way
     126                Way way = ways.get(0);
     127                if (nodes.size() == 1 && way.containsNode(nodes.get(0)) && allowRegularPolygon(way.getNodes()))
     128                        regular = true;
    136129            }
     130                if (nodes.size() >= 1) {
     131                        // First node not contained in any way will be center
     132                        for (Node node: nodes) {
     133                                boolean isContained = false;
     134                                for (Way way: ways)
     135                                        if (way.containsNode(node)) {
     136                                                isContained = true;
     137                                                break;
     138                                        }
     139                                if (!isContained) {
     140                                        center = node.getEastNorth();
     141                                        break;
     142                                }
     143                        }
     144                }
     145                if (nodes.size() == 2) {
     146                        radius = distance(nodes.get(0).getEastNorth(), nodes.get(1).getEastNorth());
     147                }
     148                nodes.clear();
    137149
    138             for (Node n : way.getNodes()) {
    139                 if (!nodes.contains(n)) {
    140                     nodes.add(n);
    141                 }
    142             }
     150                for(Way way: ways)
     151                        for (Node n : way.getNodes()) {
     152                                if (!nodes.contains(n)) {
     153                                        nodes.add(n);
     154                                }
     155                        }
    143156        }
    144157
    145158        if (nodes.size() < 4) {
     
    261274        }
    262275        return true;
    263276    }
     277
     278    /**
     279     * Determines if ways can be joined into a polygon.
     280     * @param ways The ways collection to check
     281     * @return true if all ways can be joined into a regular polygon
     282     */
     283    protected static boolean checkWaysArePolygon(Collection<Way> ways) {
     284        // For each way, nodes strictly between first and last should't be reference by an other way
     285        for(Way way: ways) {
     286                for(Node node: way.getNodes()) {
     287                        if(node == way.firstNode() || node == way.lastNode()) continue;
     288                        for(Way wayOther: ways) {
     289                                if(way == wayOther) continue;
     290                                if(node.getReferrers().contains(wayOther)) return false;
     291                        }
     292                }
     293        }
     294        // Test if ways can be joined
     295        Way currentWay = null;
     296        Node startNode = null, endNode = null;
     297        int used = 0;
     298        while(true) {
     299                Way nextWay = null;
     300                for(Way w: ways) {
     301                        if(w.firstNode() == w.lastNode()) return ways.size() == 1;
     302                        if(w == currentWay) continue;
     303                        if(currentWay == null) {
     304                                nextWay = w;
     305                                startNode = w.firstNode();
     306                                endNode = w.lastNode();
     307                                break;
     308                        }
     309                        if(w.firstNode() == endNode) {
     310                                nextWay = w;
     311                                endNode = w.lastNode();
     312                                break;
     313                        }
     314                        if(w.lastNode() == endNode) {
     315                                nextWay = w;
     316                                endNode = w.firstNode();
     317                                break;
     318                        }
     319                }
     320                if(nextWay == null) return false;
     321                used += 1;
     322                currentWay = nextWay;
     323                if(endNode == startNode) return used == ways.size();
     324        }
     325    }
    264326}