- Timestamp:
- 2010-11-15T00:02:20+01:00 (14 years ago)
- Location:
- trunk/src/org/openstreetmap/josm
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/actions/AddNodeAction.java
r3363 r3656 20 20 */ 21 21 public final class AddNodeAction extends JosmAction { 22 // remember input from last time 23 private String text; 24 22 25 //static private final Logger logger = Logger.getLogger(AddNodeAction.class.getName()); 23 26 … … 34 37 35 38 LatLonDialog dialog = new LatLonDialog(Main.parent, tr("Add Node..."), ht("/Action/AddNode")); 39 40 if (text != null) { 41 dialog.setText(text); 42 } 43 36 44 dialog.setVisible(true); 37 45 if (dialog.isCanceled()) … … 41 49 if (coordinates == null) 42 50 return; 51 52 text = dialog.getText(); 53 43 54 Node nnew = new Node(coordinates); 44 55 -
trunk/src/org/openstreetmap/josm/data/coor/LatLon.java
r3438 r3656 99 99 } 100 100 101 p rivatefinal static String SOUTH = trc("compass", "S");102 p rivatefinal static String NORTH = trc("compass", "N");101 public final static String SOUTH = trc("compass", "S"); 102 public final static String NORTH = trc("compass", "N"); 103 103 public String latToString(CoordinateFormat d) { 104 104 switch(d) { … … 115 115 } 116 116 117 p rivatefinal static String WEST = trc("compass", "W");118 p rivatefinal static String EAST = trc("compass", "E");117 public final static String WEST = trc("compass", "W"); 118 public final static String EAST = trc("compass", "E"); 119 119 public String lonToString(CoordinateFormat d) { 120 120 switch(d) { -
trunk/src/org/openstreetmap/josm/gui/dialogs/LatLonDialog.java
r3501 r3656 17 17 import java.text.NumberFormat; 18 18 import java.text.ParsePosition; 19 import java.util.ArrayList; 20 import java.util.List; 19 21 import java.util.Locale; 22 import java.util.regex.Matcher; 23 import java.util.regex.Pattern; 20 24 21 25 import javax.swing.AbstractAction; … … 26 30 import javax.swing.JOptionPane; 27 31 import javax.swing.JPanel; 32 import javax.swing.JSeparator; 28 33 import javax.swing.JTextField; 29 34 import javax.swing.KeyStroke; … … 38 43 import org.openstreetmap.josm.gui.help.ContextSensitiveHelpAction; 39 44 import org.openstreetmap.josm.gui.help.HelpUtil; 45 import org.openstreetmap.josm.gui.widgets.HtmlPanel; 40 46 import org.openstreetmap.josm.tools.GBC; 41 47 import org.openstreetmap.josm.tools.ImageProvider; … … 45 51 private static final Color BG_COLOR_ERROR = new Color(255,224,224); 46 52 47 private JTextField tfLat; 48 private JTextField tfLon; 53 private JTextField tfLatLon; 49 54 private String help; 50 55 private boolean canceled = false; … … 53 58 private CancelAction actCancel; 54 59 60 private static final double ZERO = 0.0; 61 private static final String DEG = "\u00B0"; 62 private static final String MIN = "\u2032"; 63 private static final String SEC = "\u2033"; 64 65 private static final char N_TR = LatLon.NORTH.charAt(0); 66 private static final char S_TR = LatLon.SOUTH.charAt(0); 67 private static final char E_TR = LatLon.EAST.charAt(0); 68 private static final char W_TR = LatLon.WEST.charAt(0); 69 70 private static final Pattern p = Pattern.compile( 71 "([+|-]?\\d+[.,]\\d+)|" // (1) 72 + "([+|-]?\\d+)|" // (2) 73 + "("+DEG+"|o|deg)|" // (3) 74 + "('|"+MIN+"|min)|" // (4) 75 + "(\"|"+SEC+"|sec)|" // (5) 76 + "(,|;)|" // (6) 77 + "([NSEW"+N_TR+S_TR+E_TR+W_TR+"])|"// (7) 78 + "\\s+|" 79 + "(.+)"); 80 55 81 protected JPanel buildInputForm() { 56 82 JPanel pnl = new JPanel(new GridBagLayout()); 57 83 pnl.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); 58 pnl.add(new JLabel("<html>"+ 59 tr("Enter the coordinates for the new node.") + 60 "<br>" + tr("Use decimal degrees.") + 61 "<br>" + tr("Negative values denote Western/Southern hemisphere.")), 62 GBC.eol()); 63 64 pnl.add(new JLabel(tr("Latitude")), GBC.std().insets(0,10,5,0)); 65 tfLat = new JTextField(12); 66 pnl.add(tfLat, GBC.eol().insets(0,10,0,0)); 67 pnl.add(new JLabel(tr("Longitude")), GBC.std().insets(0,0,5,10)); 68 tfLon = new JTextField(12); 69 pnl.add(tfLon, GBC.eol().insets(0,0,0,10)); 84 85 pnl.add(new JLabel(tr("Coordinates:")), GBC.std().insets(0,10,5,0)); 86 tfLatLon = new JTextField(24); 87 pnl.add(tfLatLon, GBC.eol().insets(0,10,0,0).fill(GBC.HORIZONTAL).weight(1.0, 0.0)); 88 89 pnl.add(new JSeparator(), GBC.eol().fill(GBC.HORIZONTAL).insets(0,5,0,5)); 90 91 pnl.add(new HtmlPanel( 92 tr("Enter the coordinates for the new node.<br/>You can separate longitude and latitude with space, comma or semicolon.<br/>" + 93 "Use positive numbers or N, E characters to indicate North or East cardinal direction.<br/>" + 94 "For South and West cardinal directions you can use either negative numbers or S, W characters.<br/>" + 95 "Coordinate value can be in one of three formats:<ul>" + 96 "<li><i>degrees</i><tt>°</tt></li>" + 97 "<li><i>degrees</i><tt>°</tt> <i>minutes</i><tt>'</tt></li>" + 98 "<li><i>degrees</i><tt>°</tt> <i>minutes</i><tt>'</tt> <i>seconds</i><tt>"</tt></li>" + 99 "</ul>" + 100 "Symbols <tt>°</tt>, <tt>'</tt>, <tt>′</tt>, <tt>"</tt>, <tt>″</tt> are optional.<br/><br/>" + 101 "Some examples:<ul>" + 102 "<li>49.29918° 19.24788°</li>" + 103 "<li>N 49.29918 E 19.24788</li>" + 104 "<li>W 49°29.918' S 19°24.788'</li>" + 105 "<li>N 49°29'04" E 19°24'43"</li>" + 106 "<li>49.29918 N, 19.24788 E</li>" + 107 "<li>49°29'21" N 19°24'38" E</li>" + 108 "<li>49 29 51, 19 24 18</li>" + 109 "<li>49 29, 19 24</li>" + 110 "<li>E 49 29, N 19 24</li>" + 111 "<li>49° 29; 19° 24</li>" + 112 "<li>N 49° 29, W 19° 24</li>" + 113 "<li>49° 29.5 S, 19° 24.6 E</li>" + 114 "<li>N 49 29.918 E 19 15.88</li>" + 115 "<li>49 29.4 19 24.5</li>" + 116 "<li>-49 29.4 N -19 24.5 W</li></ul>" + 117 "<li>48 deg 42' 52.13\" N, 21 deg 11' 47.60\" E</li></ul>" 118 )), 119 GBC.eol().fill().weight(1.0, 1.0)); 70 120 71 121 // parse and verify input on the fly 72 122 // 73 123 LatLonInputVerifier inputVerifier = new LatLonInputVerifier(); 74 tfLat.getDocument().addDocumentListener(inputVerifier); 75 tfLon.getDocument().addDocumentListener(inputVerifier); 124 tfLatLon.getDocument().addDocumentListener(inputVerifier); 76 125 77 126 // select the text in the field on focus 78 127 // 79 128 TextFieldFocusHandler focusHandler = new TextFieldFocusHandler(); 80 tfLat.addFocusListener(focusHandler); 81 tfLon.addFocusListener(focusHandler); 129 tfLatLon.addFocusListener(focusHandler); 82 130 return pnl; 83 131 } … … 131 179 } 132 180 this.coordinates = coordinates; 133 tfLat.setText(coordinates.latToString(CoordinateFormat.DECIMAL_DEGREES)); 134 tfLon.setText(coordinates.lonToString(CoordinateFormat.DECIMAL_DEGREES)); 181 tfLatLon.setText(coordinates.latToString(CoordinateFormat.DEGREES_MINUTES_SECONDS) + " " + coordinates.lonToString(CoordinateFormat.DEGREES_MINUTES_SECONDS)); 135 182 actOK.setEnabled(true); 136 183 } … … 157 204 // 158 205 input = input.trim(); 159 input = input.replaceAll( "\u00B0", ""); // the degree symbol206 input = input.replaceAll(DEG, ""); 160 207 161 208 // try to parse using the current locale … … 177 224 } 178 225 179 protected Double parseLatFromUserInput() {180 Double d = parseDoubleFromUserInput(tfLat.getText());181 if (d == null || ! LatLon.isValidLat(d)) {182 setErrorFeedback(tfLat, tr("Please enter a valid latitude in the range -90..90"));183 return null;184 } else {185 clearErrorFeedback(tfLat,tr("Please enter a latitude in the range -90..90"));186 }187 return d;188 }189 190 protected Double parseLonFromUserInput() {191 Double d = parseDoubleFromUserInput(tfLon.getText());192 if (d == null || ! LatLon.isValidLon(d)) {193 setErrorFeedback(tfLon, tr("Please enter a valid longitude in the range -180..180"));194 return null;195 } else {196 clearErrorFeedback(tfLon,tr("Please enter a longitude in the range -180..180"));197 }198 return d;199 }200 201 226 protected void parseUserInput() { 202 Double lat = parseLatFromUserInput(); 203 Double lon = parseLonFromUserInput(); 204 if (lat == null || lon == null) { 227 LatLon latLon; 228 try { 229 latLon = parse(tfLatLon.getText()); 230 if (!LatLon.isValidLat(latLon.lat()) || !LatLon.isValidLon(latLon.lon())) { 231 latLon = null; 232 } 233 } catch (IllegalArgumentException e) { 234 latLon = null; 235 } 236 if (latLon == null) { 237 setErrorFeedback(tfLatLon, tr("Please enter a GPS coordinates")); 205 238 coordinates = null; 206 239 actOK.setEnabled(false); 207 240 } else { 208 coordinates = new LatLon(lat,lon); 241 clearErrorFeedback(tfLatLon,tr("Please enter a GPS coordinates")); 242 coordinates = latLon; 209 243 actOK.setEnabled(true); 210 244 } … … 288 322 @Override 289 323 public void windowOpened(WindowEvent e) { 290 tfLat.requestFocusInWindow(); 291 } 292 } 293 324 tfLatLon.requestFocusInWindow(); 325 } 326 } 327 328 private static LatLon parse(final String coord) { 329 final Matcher m = p.matcher(coord); 330 331 final StringBuilder sb = new StringBuilder(); 332 final List<Object> list = new ArrayList<Object>(); 333 334 while (m.find()) { 335 if (m.group(1) != null) { 336 sb.append('R'); // floating point number 337 list.add(Double.parseDouble(m.group(1).replace(',', '.'))); 338 } else if (m.group(2) != null) { 339 sb.append('Z'); // integer number 340 list.add(Double.parseDouble(m.group(2))); 341 } else if (m.group(3) != null) { 342 sb.append('o'); // degree sign 343 } else if (m.group(4) != null) { 344 sb.append('\''); // seconds sign 345 } else if (m.group(5) != null) { 346 sb.append('"'); // minutes sign 347 } else if (m.group(6) != null) { 348 sb.append(','); // separator 349 } else if (m.group(7) != null) { 350 sb.append("x"); // cardinal direction 351 String c = m.group(7).toUpperCase(); 352 if (c.equals("N") || c.equals("S") || c.equals("E") || c.equals("W")) { 353 list.add(c); 354 } else { 355 list.add(c.replace(N_TR, 'N').replace(S_TR, 'S') 356 .replace(E_TR, 'E').replace(W_TR, 'W')); 357 } 358 } else if (m.group(8) != null) { 359 throw new IllegalArgumentException("invalid token: " + m.group(8)); 360 } 361 } 362 363 final String pattern = sb.toString(); 364 365 final Object[] params = list.toArray(); 366 final LatLonHolder latLon = new LatLonHolder(); 367 368 if (pattern.matches("Ro?,?Ro?")) { 369 setLatLonObj(latLon, 370 params[0], ZERO, ZERO, "N", 371 params[1], ZERO, ZERO, "E"); 372 } else if (pattern.matches("xRo?,?xRo?")) { 373 setLatLonObj(latLon, 374 params[1], ZERO, ZERO, params[0], 375 params[3], ZERO, ZERO, params[2]); 376 } else if (pattern.matches("Ro?x,?Ro?x")) { 377 setLatLonObj(latLon, 378 params[0], ZERO, ZERO, params[1], 379 params[2], ZERO, ZERO, params[3]); 380 } else if (pattern.matches("Zo[RZ]'?,?Zo[RZ]'?|Z[RZ],?Z[RZ]")) { 381 setLatLonObj(latLon, 382 params[0], params[1], ZERO, "N", 383 params[2], params[3], ZERO, "E"); 384 } else if (pattern.matches("xZo[RZ]'?,?xZo[RZ]'?|xZo?[RZ],?xZo?[RZ]")) { 385 setLatLonObj(latLon, 386 params[1], params[2], ZERO, params[0], 387 params[4], params[5], ZERO, params[3]); 388 } else if (pattern.matches("Zo[RZ]'?x,?Zo[RZ]'?x|Zo?[RZ]x,?Zo?[RZ]x")) { 389 setLatLonObj(latLon, 390 params[0], params[1], ZERO, params[2], 391 params[3], params[4], ZERO, params[5]); 392 } else if (pattern.matches("ZoZ'[RZ]\"?x,?ZoZ'[RZ]\"?x|ZZ[RZ]x,?ZZ[RZ]x")) { 393 setLatLonObj(latLon, 394 params[0], params[1], params[2], params[3], 395 params[4], params[5], params[6], params[7]); 396 } else if (pattern.matches("xZoZ'[RZ]\"?,?xZoZ'[RZ]\"?|xZZ[RZ],?xZZ[RZ]")) { 397 setLatLonObj(latLon, 398 params[1], params[2], params[3], params[0], 399 params[5], params[6], params[7], params[4]); 400 } else if (pattern.matches("ZZ[RZ],?ZZ[RZ]")) { 401 setLatLonObj(latLon, 402 params[0], params[1], params[2], "N", 403 params[3], params[4], params[5], "E"); 404 } else { 405 throw new IllegalArgumentException("invalid format: " + pattern); 406 } 407 408 return new LatLon(latLon.lat, latLon.lon); 409 } 410 411 private static class LatLonHolder { 412 double lat, lon; 413 } 414 415 private static void setLatLonObj(final LatLonHolder latLon, 416 final Object coord1deg, final Object coord1min, final Object coord1sec, final Object card1, 417 final Object coord2deg, final Object coord2min, final Object coord2sec, final Object card2) { 418 419 setLatLon(latLon, 420 (Double) coord1deg, (Double) coord1min, (Double) coord1sec, (String) card1, 421 (Double) coord2deg, (Double) coord2min, (Double) coord2sec, (String) card2); 422 } 423 424 private static void setLatLon(final LatLonHolder latLon, 425 final double coord1deg, final double coord1min, final double coord1sec, final String card1, 426 final double coord2deg, final double coord2min, final double coord2sec, final String card2) { 427 428 setLatLon(latLon, coord1deg, coord1min, coord1sec, card1); 429 setLatLon(latLon, coord2deg, coord2min, coord2sec, card2); 430 } 431 432 private static void setLatLon(final LatLonHolder latLon, final double coordDeg, final double coordMin, final double coordSec, final String card) { 433 if (coordDeg < -180 || coordDeg > 180 || coordMin < 0 || coordMin >= 60 || coordSec < 0 || coordSec > 60) { 434 throw new IllegalArgumentException("out of range"); 435 } 436 437 double coord = (coordDeg < 0 ? -1 : 1) * (Math.abs(coordDeg) + coordMin / 60 + coordSec / 3600); 438 coord = card.equals("N") || card.equals("E") ? coord : -coord; 439 if (card.equals("N") || card.equals("S")) { 440 latLon.lat = coord; 441 } else { 442 latLon.lon = coord; 443 } 444 } 445 446 public String getText() { 447 return tfLatLon.getText(); 448 } 449 450 public void setText(String text) { 451 tfLatLon.setText(text); 452 } 294 453 }
Note:
See TracChangeset
for help on using the changeset viewer.