Changeset 2014 in josm


Ignore:
Timestamp:
2009-08-30T18:55:03+02:00 (15 years ago)
Author:
stoecker
Message:

fixed #3205 - patch by dmuecke - arrange orthogonal not working

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/actions/OrthogonalizeAction.java

    r1898 r2014  
    3434 * 4. Compute new intersection points of two adjascent edges
    3535 * 5. Move nodes to these points
     36 * 6. if there are nodes between edges then align the nodes
    3637 */
    3738public final class OrthogonalizeAction extends JosmAction {
     
    5253
    5354        ArrayList<Node> dirnodes = new ArrayList<Node>();
    54 
    55         // Check the selection if it is suitible for the orthogonalization
     55        ArrayList<Node> alignNodes = new ArrayList<Node>();
     56
     57        // Check the selection if it is suitable for the orthogonalisation
    5658        for (OsmPrimitive osm : sel) {
    5759            // Check if not more than two nodes in the selection
     
    105107                }
    106108                if(delta < Math.PI/4) {
    107                     OptionPaneUtil.showMessageDialog(
    108                             Main.parent,
    109                             tr("Please select ways with almost right angles to orthogonalize."),
    110                             tr("Information"),
    111                             JOptionPane.INFORMATION_MESSAGE
    112                     );
    113                     return;
    114                 }
     109                    // not an edge
     110                    alignNodes.add(way.getNode(i2));
     111                }
     112            }
     113
     114            // first node has to be an edge so we move the node to the end of the way
     115            while (alignNodes.contains(way.firstNode())) {
     116                Node n = way.firstNode();
     117                way.removeNode(n);
     118                way.addNode(way.getNodesCount() - 2, n); // ! -2 because first node == last node in closed way
    115119            }
    116120        }
     
    160164            }
    161165
    162             Way way = (Way)osm;
     166            Way oldWay = (Way) osm;
     167            Way way = new Way();
     168            // copy only edges into way
     169            for (Node origNode : oldWay.getNodes()) {
     170                if (alignNodes.contains(origNode)) {
     171                    continue;
     172                }
     173                way.addNode(origNode);
     174            }
    163175            int nodes = way.getNodesCount();
    164176            int sides = nodes - 1;
    165177            // Copy necessary data into a more suitable data structure
    166178            EastNorth en[] = new EastNorth[sides];
    167             for (int i=0; i < sides; i++) {
     179            for (int i = 0; i < sides; i++) {
    168180                en[i] = new EastNorth(way.getNode(i).getEastNorth().east(), way.getNode(i).getEastNorth().north());
    169181            }
     
    222234            }
    223235
     236            EastNorth aligna = null;
     237            EastNorth alignb = null;
     238            EastNorth align0 = null;
     239            Node nodea = null;
     240            Node nodeb = null;
     241            Node node0 = null;
    224242
    225243            for (int i=0; i < sides; i++) {
     
    277295                    cmds.add(new MoveCommand(n, dx, dy));
    278296                }
     297
     298                // align all nodes between two edges
     299                aligna = alignb;
     300                alignb = intersection;
     301                nodea = nodeb;
     302                nodeb = n;
     303                if (aligna != null) {
     304
     305                    MoveCommand cmd = alignSide(findNodesToAlign(oldWay, nodea, nodeb), aligna, alignb);
     306                    if (cmd != null) {
     307                        cmds.add(cmd);
     308                    }
     309
     310                } else {
     311                    align0 = alignb;
     312                    node0 = nodeb;
     313                }
     314            }
     315            MoveCommand cmd = alignSide(findNodesToAlign(oldWay, nodeb, node0), alignb, align0);
     316            if (cmd != null) {
     317                cmds.add(cmd);
    279318            }
    280319        }
     
    284323            Main.map.repaint();
    285324        }
     325    }
     326
     327    private MoveCommand alignSide(ArrayList<Node> aNodes, EastNorth aligna, EastNorth alignb) {
     328
     329        // Find out co-ords of A and B
     330        double ax = aligna.east();
     331        double ay = aligna.north();
     332        double bx = alignb.east();
     333        double by = alignb.north();
     334
     335        // OK, for each node to move, work out where to move it!
     336        for (Node n1 : aNodes) {
     337            // Get existing co-ords of node to move
     338            double nx = n1.getEastNorth().east();
     339            double ny = n1.getEastNorth().north();
     340
     341            if (ax == bx) {
     342                // Special case if AB is vertical...
     343                nx = ax;
     344            } else if (ay == by) {
     345                // ...or horizontal
     346                ny = ay;
     347            } else {
     348                // Otherwise calculate position by solving y=mx+c
     349                double m1 = (by - ay) / (bx - ax);
     350                double c1 = ay - (ax * m1);
     351                double m2 = (-1) / m1;
     352                double c2 = n1.getEastNorth().north() - (n1.getEastNorth().east() * m2);
     353
     354                nx = (c2 - c1) / (m1 - m2);
     355                ny = (m1 * nx) + c1;
     356            }
     357
     358            // Return the command to move the node to its new position.
     359            return new MoveCommand(n1, nx - n1.getEastNorth().east(), ny - n1.getEastNorth().north());
     360        }
     361        return null;
     362    }
     363
     364    private ArrayList<Node> findNodesToAlign(Way w, Node from, Node to) {
     365        ArrayList<Node> l = new ArrayList<Node>();
     366        boolean start = false;
     367        for (int i = 0; i < w.getNodesCount(); i++) {
     368            Node n = w.getNode(i % w.getNodesCount());
     369            if (n.equals(to)) {
     370                break;
     371            }
     372            if (start) {
     373                l.add(n);
     374            }
     375            if (n.equals(from)) {
     376                start = true;
     377            }
     378
     379        }
     380        return l;
    286381    }
    287382
Note: See TracChangeset for help on using the changeset viewer.