Changeset 16162 in osm for applications/editors/josm/plugins/terracer/src
- Timestamp:
- 2009-06-26T22:11:40+02:00 (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/terracer/src/terracer/TerracerAction.java
r14048 r16162 1 1 /** 2 2 * Terracer: A JOSM Plugin for terraced houses. 3 * 3 * 4 4 * Copyright 2009 CloudMade Ltd. 5 * 5 * 6 6 * Released under the GPLv2, see LICENSE file for details. 7 7 */ … … 11 11 import static org.openstreetmap.josm.tools.I18n.trn; 12 12 13 import java.awt.BorderLayout;14 13 import java.awt.Choice; 15 14 import java.awt.Component; … … 20 19 import java.awt.event.KeyEvent; 21 20 import java.util.ArrayList; 22 import java.util.Arrays;23 21 import java.util.Collection; 24 22 import java.util.Collections; 25 import java.util.HashMap;26 23 import java.util.LinkedList; 27 import java.util.List;28 import java.util.Map;29 import java.util.TreeMap;30 24 import java.util.TreeSet; 31 25 32 import javax.swing.JComponent;33 26 import javax.swing.JFormattedTextField; 34 27 import javax.swing.JLabel; … … 36 29 import javax.swing.JPanel; 37 30 import javax.swing.JSpinner; 38 import javax.swing.JTextField;39 31 import javax.swing.SpinnerNumberModel; 40 import javax.swing.SpringLayout;41 32 import javax.swing.event.ChangeEvent; 42 33 import javax.swing.event.ChangeListener; … … 53 44 import org.openstreetmap.josm.data.osm.RelationMember; 54 45 import org.openstreetmap.josm.data.osm.Way; 55 import org.openstreetmap.josm.gui.tagging.TaggingPreset.Item;56 46 import org.openstreetmap.josm.tools.AutoCompleteComboBox; 57 47 import org.openstreetmap.josm.tools.GBC; … … 62 52 * Terraces a quadrilateral, closed way into a series of quadrilateral, 63 53 * closed ways. 64 * 54 * 65 55 * At present it only works on quadrilaterals, but there is no reason 66 * why it couldn't be extended to work with other shapes too. The 67 * algorithm employed is naive, but it works in the simple case. 68 * 56 * why it couldn't be extended to work with other shapes too. The 57 * algorithm employed is naive, but it works in the simple case. 58 * 69 59 * @author zere 70 60 */ … … 76 66 77 67 public TerracerAction() { 78 super(tr("Terrace a building"), 79 "terrace", 68 super(tr("Terrace a building"), 69 "terrace", 80 70 tr("Creates individual buildings from a long building."), 81 Shortcut.registerShortcut("tools:Terracer", 71 Shortcut.registerShortcut("tools:Terracer", 82 72 tr("Tool: {0}", tr("Terrace a building")), 83 KeyEvent.VK_T, Shortcut.GROUP_EDIT, 73 KeyEvent.VK_T, Shortcut.GROUP_EDIT, 84 74 Shortcut.SHIFT_DEFAULT), 85 75 true); … … 112 102 optionPane.createDialog(Main.parent, title).setVisible(true); 113 103 Object answerObj = optionPane.getValue(); 114 if (answerObj != null && 104 if (answerObj != null && 115 105 answerObj != JOptionPane.UNINITIALIZED_VALUE && 116 (answerObj instanceof Integer && 106 (answerObj instanceof Integer && 117 107 (Integer)answerObj == JOptionPane.OK_OPTION)) { 118 108 119 109 // call out to the method which does the actual 120 110 // terracing. 121 terraceBuilding(way, 122 dialog.numberFrom(), 111 terraceBuilding(way, 112 dialog.numberFrom(), 123 113 dialog.numberTo(), 124 114 dialog.stepSize(), … … 137 127 138 128 if (badSelect) { 139 JOptionPane.showMessageDialog(Main.parent, 129 JOptionPane.showMessageDialog(Main.parent, 140 130 tr("Select a single, closed way of at least four nodes.")); 141 131 } … … 144 134 /** 145 135 * Terraces a single, closed, quadrilateral way. 146 * 136 * 147 137 * Any node must be adjacent to both a short and long edge, we naively 148 138 * choose the longest edge and its opposite and interpolate along them 149 139 * linearly to produce new nodes. Those nodes are then assembled into 150 140 * closed, quadrilateral ways and left in the selection. 151 * 141 * 152 142 * @param w The closed, quadrilateral way to terrace. 153 143 */ … … 167 157 Collection<Way> ways = new LinkedList<Way>(); 168 158 169 // create intermediate nodes by interpolating. 159 // create intermediate nodes by interpolating. 170 160 for (int i = 0; i <= nb; ++i) { 171 new_nodes[0][i] = interpolateAlong(interp.a, frontLength * ( double)(i) / (double)(nb));172 new_nodes[1][i] = interpolateAlong(interp.b, backLength * ( double)(i) / (double)(nb));161 new_nodes[0][i] = interpolateAlong(interp.a, frontLength * (i) / (nb)); 162 new_nodes[1][i] = interpolateAlong(interp.b, backLength * (i) / (nb)); 173 163 commands.add(new AddCommand(new_nodes[0][i])); 174 164 commands.add(new AddCommand(new_nodes[1][i])); … … 214 204 * Creates a node at a certain distance along a way, as calculated by the 215 205 * great circle distance. 216 * 217 * Note that this really isn't an efficient way to do this and leads to 206 * 207 * Note that this really isn't an efficient way to do this and leads to 218 208 * O(N^2) running time for the main algorithm, but its simple and easy 219 209 * to understand, and probably won't matter for reasonable-sized ways. 220 * 210 * 221 211 * @param w The way to interpolate. 222 212 * @param l The length at which to place the node. … … 226 216 Node n = null; 227 217 for (Pair<Node,Node> p : w.getNodePairs(false)) { 228 final double seg_length = p.a. coor.greatCircleDistance(p.b.coor);218 final double seg_length = p.a.getCoor().greatCircleDistance(p.b.getCoor()); 229 219 if (l <= seg_length) { 230 220 n = interpolateNode(p.a, p.b, l / seg_length); … … 245 235 * Calculates the great circle length of a way by summing the great circle 246 236 * distance of each pair of nodes. 247 * 237 * 248 238 * @param w The way to calculate length of. 249 239 * @return The length of the way. … … 252 242 double length = 0.0; 253 243 for (Pair<Node,Node> p : w.getNodePairs(false)) { 254 length += p.a. coor.greatCircleDistance(p.b.coor);244 length += p.a.getCoor().greatCircleDistance(p.b.getCoor()); 255 245 } 256 246 return length; … … 258 248 259 249 /** 260 * Given a way, try and find a definite front and back by looking at the 250 * Given a way, try and find a definite front and back by looking at the 261 251 * segments to find the "sides". Sides are assumed to be single segments 262 252 * which cannot be contiguous. 263 * 253 * 264 254 * @param w The way to analyse. 265 255 * @return A pair of ways (front, back) pointing in the same directions. … … 327 317 Node a = w.nodes.get(i); 328 318 Node b = w.nodes.get((i+1) % (w.nodes.size() - 1)); 329 return a. coor.greatCircleDistance(b.coor);319 return a.getCoor().greatCircleDistance(b.getCoor()); 330 320 } 331 321 … … 334 324 * into order and return the array of indexes such that, for a returned array 335 325 * x, a[x[i]] is sorted for ascending index i. 336 * 326 * 337 327 * This isn't efficient at all, but should be fine for the small arrays we're 338 328 * expecting. If this gets slow - replace it with some more efficient algorithm. 339 * 329 * 340 330 * @param a The array to sort. 341 * @return An array of indexes, the same size as the input, such that a[x[i]] 331 * @return An array of indexes, the same size as the input, such that a[x[i]] 342 332 * is in sorted order. 343 333 */ … … 370 360 371 361 /** 372 * Calculate "sideness" metric for each segment in a way. 362 * Calculate "sideness" metric for each segment in a way. 373 363 */ 374 364 private double[] calculateSideness(Way w) { … … 385 375 } 386 376 sideness[length-1] = calculateSideness( 387 w.nodes.get(length - 2), w.nodes.get(length - 1), 377 w.nodes.get(length - 2), w.nodes.get(length - 1), 388 378 w.nodes.get(length), w.nodes.get(1)); 389 379 … … 397 387 */ 398 388 private double calculateSideness(Node a, Node b, Node c, Node d) { 399 final double ndx = b. coor.getX() - a.coor.getX();400 final double pdx = d. coor.getX() - c.coor.getX();401 final double ndy = b. coor.getY() - a.coor.getY();402 final double pdy = d. coor.getY() - c.coor.getY();403 404 return (ndx * pdx + ndy * pdy) / 389 final double ndx = b.getCoor().getX() - a.getCoor().getX(); 390 final double pdx = d.getCoor().getX() - c.getCoor().getX(); 391 final double ndy = b.getCoor().getY() - a.getCoor().getY(); 392 final double pdy = d.getCoor().getY() - c.getCoor().getY(); 393 394 return (ndx * pdx + ndy * pdy) / 405 395 Math.sqrt((ndx * ndx + ndy * ndy) * (pdx * pdx + pdy * pdy)); 406 396 } … … 426 416 chi = new JSpinner(hi); 427 417 428 lo.addChangeListener(new ChangeListener() { 418 lo.addChangeListener(new ChangeListener() { 429 419 public void stateChanged(ChangeEvent e) { 430 420 hi.setMinimum((Integer)lo.getNumber()); 431 421 } 432 422 }); 433 hi.addChangeListener(new ChangeListener() { 423 hi.addChangeListener(new ChangeListener() { 434 424 public void stateChanged(ChangeEvent e) { 435 425 lo.setMaximum((Integer)hi.getNumber()); … … 521 511 522 512 /** 523 * Generates a list of all visible names of highways in order to do 513 * Generates a list of all visible names of highways in order to do 524 514 * autocompletion on the road name. 525 515 */ … … 539 529 * Creates a new node at the interpolated position between the argument 540 530 * nodes. Interpolates linearly in Lat/Lon coordinates. 541 * 531 * 542 532 * @param a First node, at which f=0. 543 533 * @param b Last node, at which f=1. … … 551 541 552 542 /** 553 * Calculates the interpolated position between the argument nodes. Interpolates 543 * Calculates the interpolated position between the argument nodes. Interpolates 554 544 * linearly in Lat/Lon coordinates. 555 * 545 * 556 546 * @param a First node, at which f=0. 557 547 * @param b Last node, at which f=1. … … 563 553 // screen coordinates rather than lat/lon, but it doesn't seem to 564 554 // make a great deal of difference at the scale of most terraces. 565 return new LatLon(a. coor.lat() * (1.0 - f) + b.coor.lat() * f,566 a. coor.lon() * (1.0 - f) + b.coor.lon() * f);555 return new LatLon(a.getCoor().lat() * (1.0 - f) + b.getCoor().lat() * f, 556 a.getCoor().lon() * (1.0 - f) + b.getCoor().lon() * f); 567 557 } 568 558 }
Note:
See TracChangeset
for help on using the changeset viewer.