Ticket #3205: ortho.txt

File ortho.txt, 6.4 KB (added by dmuecke, 16 years ago)
Line 
1Index: src/org/openstreetmap/josm/actions/OrthogonalizeAction.java
2===================================================================
3--- src/org/openstreetmap/josm/actions/OrthogonalizeAction.java (revision 1986)
4+++ src/org/openstreetmap/josm/actions/OrthogonalizeAction.java (working copy)
5@@ -33,6 +33,7 @@
6 * 3. Rotate every edge around its center to align with main orientation or perpendicular to it
7 * 4. Compute new intersection points of two adjascent edges
8 * 5. Move nodes to these points
9+ * 6. if there are nodes between edges then align the nodes
10 */
11 public final class OrthogonalizeAction extends JosmAction {
12
13@@ -51,8 +52,9 @@
14 Collection<OsmPrimitive> sel = getCurrentDataSet().getSelected();
15
16 ArrayList<Node> dirnodes = new ArrayList<Node>();
17+ ArrayList<Node> alignNodes = new ArrayList<Node>();
18
19- // Check the selection if it is suitible for the orthogonalization
20+ // Check the selection if it is suitable for the orthogonalisation
21 for (OsmPrimitive osm : sel) {
22 // Check if not more than two nodes in the selection
23 if(osm instanceof Node) {
24@@ -104,15 +106,17 @@
25 delta -= Math.PI;
26 }
27 if(delta < Math.PI/4) {
28- OptionPaneUtil.showMessageDialog(
29- Main.parent,
30- tr("Please select ways with almost right angles to orthogonalize."),
31- tr("Information"),
32- JOptionPane.INFORMATION_MESSAGE
33- );
34- return;
35+ // not an edge
36+ alignNodes.add(way.getNode(i2));
37 }
38 }
39+
40+ // first node has to be an edge so we move the node to the end of the way
41+ while (alignNodes.contains(way.firstNode())) {
42+ Node n = way.firstNode();
43+ way.removeNode(n);
44+ way.addNode(way.getNodesCount() - 2, n); // ! -2 because first node == last node in closed way
45+ }
46 }
47
48 if ("EPSG:4326".equals(Main.proj.toString())) {
49@@ -159,12 +163,20 @@
50 continue;
51 }
52
53- Way way = (Way)osm;
54+ Way oldWay = (Way) osm;
55+ Way way = new Way();
56+ // copy only edges into way
57+ for (Node origNode : oldWay.getNodes()) {
58+ if (alignNodes.contains(origNode)) {
59+ continue;
60+ }
61+ way.addNode(origNode);
62+ }
63 int nodes = way.getNodesCount();
64 int sides = nodes - 1;
65 // Copy necessary data into a more suitable data structure
66 EastNorth en[] = new EastNorth[sides];
67- for (int i=0; i < sides; i++) {
68+ for (int i = 0; i < sides; i++) {
69 en[i] = new EastNorth(way.getNode(i).getEastNorth().east(), way.getNode(i).getEastNorth().north());
70 }
71
72@@ -221,6 +233,12 @@
73 align_to_heading = normalize_angle(sum_weighted_headings/sum_weights);
74 }
75
76+ EastNorth aligna = null;
77+ EastNorth alignb = null;
78+ EastNorth align0 = null;
79+ Node nodea = null;
80+ Node nodeb = null;
81+ Node node0 = null;
82
83 for (int i=0; i < sides; i++) {
84 // Compute handy indices of three nodes to be used in one loop iteration.
85@@ -276,6 +294,27 @@
86 double dy = intersection.north()-n.getEastNorth().north();
87 cmds.add(new MoveCommand(n, dx, dy));
88 }
89+
90+ // align all nodes between two edges
91+ aligna = alignb;
92+ alignb = intersection;
93+ nodea = nodeb;
94+ nodeb = n;
95+ if (aligna != null) {
96+
97+ MoveCommand cmd = alignSide(findNodesToAlign(oldWay, nodea, nodeb), aligna, alignb);
98+ if (cmd != null) {
99+ cmds.add(cmd);
100+ }
101+
102+ } else {
103+ align0 = alignb;
104+ node0 = nodeb;
105+ }
106+ }
107+ MoveCommand cmd = alignSide(findNodesToAlign(oldWay, nodeb, node0), alignb, align0);
108+ if (cmd != null) {
109+ cmds.add(cmd);
110 }
111 }
112
113@@ -285,6 +324,62 @@
114 }
115 }
116
117+ private MoveCommand alignSide(ArrayList<Node> aNodes, EastNorth aligna, EastNorth alignb) {
118+
119+ // Find out co-ords of A and B
120+ double ax = aligna.east();
121+ double ay = aligna.north();
122+ double bx = alignb.east();
123+ double by = alignb.north();
124+
125+ // OK, for each node to move, work out where to move it!
126+ for (Node n1 : aNodes) {
127+ // Get existing co-ords of node to move
128+ double nx = n1.getEastNorth().east();
129+ double ny = n1.getEastNorth().north();
130+
131+ if (ax == bx) {
132+ // Special case if AB is vertical...
133+ nx = ax;
134+ } else if (ay == by) {
135+ // ...or horizontal
136+ ny = ay;
137+ } else {
138+ // Otherwise calculate position by solving y=mx+c
139+ double m1 = (by - ay) / (bx - ax);
140+ double c1 = ay - (ax * m1);
141+ double m2 = (-1) / m1;
142+ double c2 = n1.getEastNorth().north() - (n1.getEastNorth().east() * m2);
143+
144+ nx = (c2 - c1) / (m1 - m2);
145+ ny = (m1 * nx) + c1;
146+ }
147+
148+ // Return the command to move the node to its new position.
149+ return new MoveCommand(n1, nx - n1.getEastNorth().east(), ny - n1.getEastNorth().north());
150+ }
151+ return null;
152+ }
153+
154+ private ArrayList<Node> findNodesToAlign(Way w, Node from, Node to) {
155+ ArrayList<Node> l = new ArrayList<Node>();
156+ boolean start = false;
157+ for (int i = 0; i < w.getNodesCount(); i++) {
158+ Node n = w.getNode(i % w.getNodesCount());
159+ if (n.equals(to)) {
160+ break;
161+ }
162+ if (start) {
163+ l.add(n);
164+ }
165+ if (n.equals(from)) {
166+ start = true;
167+ }
168+
169+ }
170+ return l;
171+ }
172+
173 static double det(double a, double b, double c, double d)
174 {
175 return a * d - b * c;