Changeset 11045 in josm
- Timestamp:
- 2016-09-23T21:13:02+02:00 (8 years ago)
- Location:
- trunk
- Files:
-
- 1 deleted
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/actions/JumpToAction.java
r10601 r11045 20 20 import org.openstreetmap.josm.data.coor.LatLon; 21 21 import org.openstreetmap.josm.gui.MapView; 22 import org.openstreetmap.josm.gui.dialogs.LatLonDialog;23 22 import org.openstreetmap.josm.gui.widgets.JosmTextField; 24 23 import org.openstreetmap.josm.tools.GBC; … … 148 147 } catch (NumberFormatException ex) { 149 148 try { 150 ll = LatLon Dialog.parseLatLon(lat.getText() + "; " + lon.getText());149 ll = LatLon.parse(lat.getText() + "; " + lon.getText()); 151 150 } catch (IllegalArgumentException ex2) { 152 151 JOptionPane.showMessageDialog(Main.parent, -
trunk/src/org/openstreetmap/josm/data/coor/LatLon.java
r10915 r11045 15 15 import java.text.DecimalFormat; 16 16 import java.text.NumberFormat; 17 import java.util.ArrayList; 17 18 import java.util.Arrays; 19 import java.util.List; 18 20 import java.util.Locale; 19 21 import java.util.Objects; 22 import java.util.regex.Matcher; 23 import java.util.regex.Pattern; 20 24 21 25 import org.openstreetmap.gui.jmapviewer.interfaces.ICoordinate; … … 82 86 private static final String cDm00 = cDmMinuteFormatter.format(0.0); 83 87 88 /** Character denoting South, as string */ 89 public static final String SOUTH = trc("compass", "S"); 90 /** Character denoting North, as string */ 91 public static final String NORTH = trc("compass", "N"); 92 /** Character denoting West, as string */ 93 public static final String WEST = trc("compass", "W"); 94 /** Character denoting East, as string */ 95 public static final String EAST = trc("compass", "E"); 96 97 private static final char N_TR = NORTH.charAt(0); 98 private static final char S_TR = SOUTH.charAt(0); 99 private static final char E_TR = EAST.charAt(0); 100 private static final char W_TR = WEST.charAt(0); 101 102 private static final String DEG = "\u00B0"; 103 private static final String MIN = "\u2032"; 104 private static final String SEC = "\u2033"; 105 106 private static final Pattern P = Pattern.compile( 107 "([+|-]?\\d+[.,]\\d+)|" // (1) 108 + "([+|-]?\\d+)|" // (2) 109 + "("+DEG+"|o|deg)|" // (3) 110 + "('|"+MIN+"|min)|" // (4) 111 + "(\"|"+SEC+"|sec)|" // (5) 112 + "(,|;)|" // (6) 113 + "([NSEW"+N_TR+S_TR+E_TR+W_TR+"])|"// (7) 114 + "\\s+|" 115 + "(.+)", Pattern.CASE_INSENSITIVE); 116 117 private static final Pattern P_XML = Pattern.compile( 118 "lat=[\"']([+|-]?\\d+[.,]\\d+)[\"']\\s+lon=[\"']([+|-]?\\d+[.,]\\d+)[\"']"); 119 84 120 /** 85 121 * Replies true if lat is in the range [-90,90] … … 235 271 } 236 272 237 public static final String SOUTH = trc("compass", "S");238 public static final String NORTH = trc("compass", "N");239 240 273 /** 241 274 * Formats the latitude part according to the given format … … 260 293 return x; 261 294 } 262 263 public static final String WEST = trc("compass", "W");264 public static final String EAST = trc("compass", "E");265 295 266 296 /** … … 512 542 return new org.openstreetmap.gui.jmapviewer.Coordinate(lat(), lon()); 513 543 } 544 545 private static class LatLonHolder { 546 private double lat = Double.NaN; 547 private double lon = Double.NaN; 548 } 549 550 private static void setLatLonObj(final LatLonHolder latLon, 551 final Object coord1deg, final Object coord1min, final Object coord1sec, final Object card1, 552 final Object coord2deg, final Object coord2min, final Object coord2sec, final Object card2) { 553 554 setLatLon(latLon, 555 (Double) coord1deg, (Double) coord1min, (Double) coord1sec, (String) card1, 556 (Double) coord2deg, (Double) coord2min, (Double) coord2sec, (String) card2); 557 } 558 559 private static void setLatLon(final LatLonHolder latLon, 560 final double coord1deg, final double coord1min, final double coord1sec, final String card1, 561 final double coord2deg, final double coord2min, final double coord2sec, final String card2) { 562 563 setLatLon(latLon, coord1deg, coord1min, coord1sec, card1); 564 setLatLon(latLon, coord2deg, coord2min, coord2sec, card2); 565 if (Double.isNaN(latLon.lat) || Double.isNaN(latLon.lon)) { 566 throw new IllegalArgumentException("invalid lat/lon parameters"); 567 } 568 } 569 570 private static void setLatLon(final LatLonHolder latLon, final double coordDeg, final double coordMin, final double coordSec, 571 final String card) { 572 if (coordDeg < -180 || coordDeg > 180 || coordMin < 0 || coordMin >= 60 || coordSec < 0 || coordSec > 60) { 573 throw new IllegalArgumentException("out of range"); 574 } 575 576 double coord = (coordDeg < 0 ? -1 : 1) * (Math.abs(coordDeg) + coordMin / 60 + coordSec / 3600); 577 coord = "N".equals(card) || "E".equals(card) ? coord : -coord; 578 if ("N".equals(card) || "S".equals(card)) { 579 latLon.lat = coord; 580 } else { 581 latLon.lon = coord; 582 } 583 } 584 585 /** 586 * Parses the given string as lat/lon. 587 * @param coord String to parse 588 * @return parsed lat/lon 589 * @since 11045 590 */ 591 public static LatLon parse(String coord) { 592 final LatLonHolder latLon = new LatLonHolder(); 593 final Matcher mXml = P_XML.matcher(coord); 594 if (mXml.matches()) { 595 setLatLonObj(latLon, 596 Double.valueOf(mXml.group(1).replace(',', '.')), 0.0, 0.0, "N", 597 Double.valueOf(mXml.group(2).replace(',', '.')), 0.0, 0.0, "E"); 598 } else { 599 final Matcher m = P.matcher(coord); 600 601 final StringBuilder sb = new StringBuilder(); 602 final List<Object> list = new ArrayList<>(); 603 604 while (m.find()) { 605 if (m.group(1) != null) { 606 sb.append('R'); // floating point number 607 list.add(Double.valueOf(m.group(1).replace(',', '.'))); 608 } else if (m.group(2) != null) { 609 sb.append('Z'); // integer number 610 list.add(Double.valueOf(m.group(2))); 611 } else if (m.group(3) != null) { 612 sb.append('o'); // degree sign 613 } else if (m.group(4) != null) { 614 sb.append('\''); // seconds sign 615 } else if (m.group(5) != null) { 616 sb.append('"'); // minutes sign 617 } else if (m.group(6) != null) { 618 sb.append(','); // separator 619 } else if (m.group(7) != null) { 620 sb.append('x'); // cardinal direction 621 String c = m.group(7).toUpperCase(Locale.ENGLISH); 622 if ("N".equalsIgnoreCase(c) || "S".equalsIgnoreCase(c) || "E".equalsIgnoreCase(c) || "W".equalsIgnoreCase(c)) { 623 list.add(c); 624 } else { 625 list.add(c.replace(N_TR, 'N').replace(S_TR, 'S') 626 .replace(E_TR, 'E').replace(W_TR, 'W')); 627 } 628 } else if (m.group(8) != null) { 629 throw new IllegalArgumentException("invalid token: " + m.group(8)); 630 } 631 } 632 633 final String pattern = sb.toString(); 634 635 final Object[] params = list.toArray(); 636 637 if (pattern.matches("Ro?,?Ro?")) { 638 setLatLonObj(latLon, 639 params[0], 0.0, 0.0, "N", 640 params[1], 0.0, 0.0, "E"); 641 } else if (pattern.matches("xRo?,?xRo?")) { 642 setLatLonObj(latLon, 643 params[1], 0.0, 0.0, params[0], 644 params[3], 0.0, 0.0, params[2]); 645 } else if (pattern.matches("Ro?x,?Ro?x")) { 646 setLatLonObj(latLon, 647 params[0], 0.0, 0.0, params[1], 648 params[2], 0.0, 0.0, params[3]); 649 } else if (pattern.matches("Zo[RZ]'?,?Zo[RZ]'?|Z[RZ],?Z[RZ]")) { 650 setLatLonObj(latLon, 651 params[0], params[1], 0.0, "N", 652 params[2], params[3], 0.0, "E"); 653 } else if (pattern.matches("xZo[RZ]'?,?xZo[RZ]'?|xZo?[RZ],?xZo?[RZ]")) { 654 setLatLonObj(latLon, 655 params[1], params[2], 0.0, params[0], 656 params[4], params[5], 0.0, params[3]); 657 } else if (pattern.matches("Zo[RZ]'?x,?Zo[RZ]'?x|Zo?[RZ]x,?Zo?[RZ]x")) { 658 setLatLonObj(latLon, 659 params[0], params[1], 0.0, params[2], 660 params[3], params[4], 0.0, params[5]); 661 } else if (pattern.matches("ZoZ'[RZ]\"?x,?ZoZ'[RZ]\"?x|ZZ[RZ]x,?ZZ[RZ]x")) { 662 setLatLonObj(latLon, 663 params[0], params[1], params[2], params[3], 664 params[4], params[5], params[6], params[7]); 665 } else if (pattern.matches("xZoZ'[RZ]\"?,?xZoZ'[RZ]\"?|xZZ[RZ],?xZZ[RZ]")) { 666 setLatLonObj(latLon, 667 params[1], params[2], params[3], params[0], 668 params[5], params[6], params[7], params[4]); 669 } else if (pattern.matches("ZZ[RZ],?ZZ[RZ]")) { 670 setLatLonObj(latLon, 671 params[0], params[1], params[2], "N", 672 params[3], params[4], params[5], "E"); 673 } else { 674 throw new IllegalArgumentException("invalid format: " + pattern); 675 } 676 } 677 678 return new LatLon(latLon.lat, latLon.lon); 679 } 514 680 } -
trunk/src/org/openstreetmap/josm/gui/dialogs/LatLonDialog.java
r10627 r11045 9 9 import java.awt.event.FocusEvent; 10 10 import java.awt.event.FocusListener; 11 import java.util.ArrayList;12 11 import java.util.Arrays; 13 import java.util.List;14 import java.util.Locale;15 import java.util.regex.Matcher;16 import java.util.regex.Pattern;17 12 18 13 import javax.swing.BorderFactory; … … 43 38 private LatLon latLonCoordinates; 44 39 private EastNorth eastNorthCoordinates; 45 46 private static final Double ZERO = 0.0;47 private static final String DEG = "\u00B0";48 private static final String MIN = "\u2032";49 private static final String SEC = "\u2033";50 51 private static final char N_TR = LatLon.NORTH.charAt(0);52 private static final char S_TR = LatLon.SOUTH.charAt(0);53 private static final char E_TR = LatLon.EAST.charAt(0);54 private static final char W_TR = LatLon.WEST.charAt(0);55 56 private static final Pattern P = Pattern.compile(57 "([+|-]?\\d+[.,]\\d+)|" // (1)58 + "([+|-]?\\d+)|" // (2)59 + "("+DEG+"|o|deg)|" // (3)60 + "('|"+MIN+"|min)|" // (4)61 + "(\"|"+SEC+"|sec)|" // (5)62 + "(,|;)|" // (6)63 + "([NSEW"+N_TR+S_TR+E_TR+W_TR+"])|"// (7)64 + "\\s+|"65 + "(.+)");66 67 private static final Pattern P_XML = Pattern.compile(68 "lat=[\"']([+|-]?\\d+[.,]\\d+)[\"']\\s+lon=[\"']([+|-]?\\d+[.,]\\d+)[\"']");69 40 70 41 protected JPanel buildLatLon() { … … 231 202 LatLon latLon; 232 203 try { 233 latLon = parseLatLon(tfLatLon.getText());204 latLon = LatLon.parse(tfLatLon.getText()); 234 205 if (!LatLon.isValidLat(latLon.lat()) || !LatLon.isValidLon(latLon.lon())) { 235 206 latLon = null; … … 339 310 } 340 311 312 /** 313 * Parses the given string as lat/lon. 314 * @param coord String to parse 315 * @return parsed lat/lon 316 * @deprecated use {@link LatLon#parse(String)} instead 317 */ 318 @Deprecated 341 319 public static LatLon parseLatLon(final String coord) { 342 final LatLonHolder latLon = new LatLonHolder(); 343 final Matcher mXml = P_XML.matcher(coord); 344 if (mXml.matches()) { 345 setLatLonObj(latLon, 346 Double.valueOf(mXml.group(1).replace(',', '.')), ZERO, ZERO, "N", 347 Double.valueOf(mXml.group(2).replace(',', '.')), ZERO, ZERO, "E"); 348 } else { 349 final Matcher m = P.matcher(coord); 350 351 final StringBuilder sb = new StringBuilder(); 352 final List<Object> list = new ArrayList<>(); 353 354 while (m.find()) { 355 if (m.group(1) != null) { 356 sb.append('R'); // floating point number 357 list.add(Double.valueOf(m.group(1).replace(',', '.'))); 358 } else if (m.group(2) != null) { 359 sb.append('Z'); // integer number 360 list.add(Double.valueOf(m.group(2))); 361 } else if (m.group(3) != null) { 362 sb.append('o'); // degree sign 363 } else if (m.group(4) != null) { 364 sb.append('\''); // seconds sign 365 } else if (m.group(5) != null) { 366 sb.append('"'); // minutes sign 367 } else if (m.group(6) != null) { 368 sb.append(','); // separator 369 } else if (m.group(7) != null) { 370 sb.append('x'); // cardinal direction 371 String c = m.group(7).toUpperCase(Locale.ENGLISH); 372 if ("N".equals(c) || "S".equals(c) || "E".equals(c) || "W".equals(c)) { 373 list.add(c); 374 } else { 375 list.add(c.replace(N_TR, 'N').replace(S_TR, 'S') 376 .replace(E_TR, 'E').replace(W_TR, 'W')); 377 } 378 } else if (m.group(8) != null) { 379 throw new IllegalArgumentException("invalid token: " + m.group(8)); 380 } 381 } 382 383 final String pattern = sb.toString(); 384 385 final Object[] params = list.toArray(); 386 387 if (pattern.matches("Ro?,?Ro?")) { 388 setLatLonObj(latLon, 389 params[0], ZERO, ZERO, "N", 390 params[1], ZERO, ZERO, "E"); 391 } else if (pattern.matches("xRo?,?xRo?")) { 392 setLatLonObj(latLon, 393 params[1], ZERO, ZERO, params[0], 394 params[3], ZERO, ZERO, params[2]); 395 } else if (pattern.matches("Ro?x,?Ro?x")) { 396 setLatLonObj(latLon, 397 params[0], ZERO, ZERO, params[1], 398 params[2], ZERO, ZERO, params[3]); 399 } else if (pattern.matches("Zo[RZ]'?,?Zo[RZ]'?|Z[RZ],?Z[RZ]")) { 400 setLatLonObj(latLon, 401 params[0], params[1], ZERO, "N", 402 params[2], params[3], ZERO, "E"); 403 } else if (pattern.matches("xZo[RZ]'?,?xZo[RZ]'?|xZo?[RZ],?xZo?[RZ]")) { 404 setLatLonObj(latLon, 405 params[1], params[2], ZERO, params[0], 406 params[4], params[5], ZERO, params[3]); 407 } else if (pattern.matches("Zo[RZ]'?x,?Zo[RZ]'?x|Zo?[RZ]x,?Zo?[RZ]x")) { 408 setLatLonObj(latLon, 409 params[0], params[1], ZERO, params[2], 410 params[3], params[4], ZERO, params[5]); 411 } else if (pattern.matches("ZoZ'[RZ]\"?x,?ZoZ'[RZ]\"?x|ZZ[RZ]x,?ZZ[RZ]x")) { 412 setLatLonObj(latLon, 413 params[0], params[1], params[2], params[3], 414 params[4], params[5], params[6], params[7]); 415 } else if (pattern.matches("xZoZ'[RZ]\"?,?xZoZ'[RZ]\"?|xZZ[RZ],?xZZ[RZ]")) { 416 setLatLonObj(latLon, 417 params[1], params[2], params[3], params[0], 418 params[5], params[6], params[7], params[4]); 419 } else if (pattern.matches("ZZ[RZ],?ZZ[RZ]")) { 420 setLatLonObj(latLon, 421 params[0], params[1], params[2], "N", 422 params[3], params[4], params[5], "E"); 423 } else { 424 throw new IllegalArgumentException("invalid format: " + pattern); 425 } 426 } 427 428 return new LatLon(latLon.lat, latLon.lon); 320 return LatLon.parse(coord); 429 321 } 430 322 … … 441 333 } 442 334 443 private static class LatLonHolder {444 private double lat;445 private double lon;446 }447 448 private static void setLatLonObj(final LatLonHolder latLon,449 final Object coord1deg, final Object coord1min, final Object coord1sec, final Object card1,450 final Object coord2deg, final Object coord2min, final Object coord2sec, final Object card2) {451 452 setLatLon(latLon,453 (Double) coord1deg, (Double) coord1min, (Double) coord1sec, (String) card1,454 (Double) coord2deg, (Double) coord2min, (Double) coord2sec, (String) card2);455 }456 457 private static void setLatLon(final LatLonHolder latLon,458 final double coord1deg, final double coord1min, final double coord1sec, final String card1,459 final double coord2deg, final double coord2min, final double coord2sec, final String card2) {460 461 setLatLon(latLon, coord1deg, coord1min, coord1sec, card1);462 setLatLon(latLon, coord2deg, coord2min, coord2sec, card2);463 }464 465 private static void setLatLon(final LatLonHolder latLon, final double coordDeg, final double coordMin, final double coordSec,466 final String card) {467 if (coordDeg < -180 || coordDeg > 180 || coordMin < 0 || coordMin >= 60 || coordSec < 0 || coordSec > 60) {468 throw new IllegalArgumentException("out of range");469 }470 471 double coord = (coordDeg < 0 ? -1 : 1) * (Math.abs(coordDeg) + coordMin / 60 + coordSec / 3600);472 coord = "N".equals(card) || "E".equals(card) ? coord : -coord;473 if ("N".equals(card) || "S".equals(card)) {474 latLon.lat = coord;475 } else {476 latLon.lon = coord;477 }478 }479 480 335 public String getLatLonText() { 481 336 return tfLatLon.getText(); -
trunk/test/unit/org/openstreetmap/josm/data/coor/LatLonTest.java
r10945 r11045 204 204 assertEquals(10, ll3.getCenter(ll2).lon(), 1e-10); 205 205 } 206 207 /** 208 * Unit test of {@link LatLon#parse} method. 209 */ 210 @Test 211 public void testParse() { 212 assertEquals(new LatLon(49.29918, 19.24788), LatLon.parse("49.29918° 19.24788°")); 213 assertEquals(new LatLon(49.29918, 19.24788), LatLon.parse("N 49.29918 E 19.24788°")); 214 assertEquals(new LatLon(49.29918, 19.24788), LatLon.parse("49.29918° 19.24788°")); 215 assertEquals(new LatLon(49.29918, 19.24788), LatLon.parse("N 49.29918 E 19.24788")); 216 assertEquals(new LatLon(49.29918, 19.24788), LatLon.parse("n 49.29918 e 19.24788")); 217 assertEquals(new LatLon(-19 - 24.788 / 60, -49 - 29.918 / 60), LatLon.parse("W 49°29.918' S 19°24.788'")); 218 assertEquals(new LatLon(-19 - 24.788 / 60, -49 - 29.918 / 60), LatLon.parse("w 49°29.918' s 19°24.788'")); 219 assertEquals(new LatLon(49 + 29. / 60 + 04. / 3600, 19 + 24. / 60 + 43. / 3600), LatLon.parse("N 49°29'04\" E 19°24'43\"")); 220 assertEquals(new LatLon(49.29918, 19.24788), LatLon.parse("49.29918 N, 19.24788 E")); 221 assertEquals(new LatLon(49.29918, 19.24788), LatLon.parse("49.29918 n, 19.24788 e")); 222 assertEquals(new LatLon(49 + 29. / 60 + 21. / 3600, 19 + 24. / 60 + 38. / 3600), LatLon.parse("49°29'21\" N 19°24'38\" E")); 223 assertEquals(new LatLon(49 + 29. / 60 + 51. / 3600, 19 + 24. / 60 + 18. / 3600), LatLon.parse("49 29 51, 19 24 18")); 224 assertEquals(new LatLon(49 + 29. / 60, 19 + 24. / 60), LatLon.parse("49 29, 19 24")); 225 assertEquals(new LatLon(19 + 24. / 60, 49 + 29. / 60), LatLon.parse("E 49 29, N 19 24")); 226 assertEquals(new LatLon(49 + 29. / 60, 19 + 24. / 60), LatLon.parse("49° 29; 19° 24")); 227 assertEquals(new LatLon(49 + 29. / 60, 19 + 24. / 60), LatLon.parse("49° 29; 19° 24")); 228 assertEquals(new LatLon(49 + 29. / 60, -19 - 24. / 60), LatLon.parse("N 49° 29, W 19° 24")); 229 assertEquals(new LatLon(-49 - 29.5 / 60, 19 + 24.6 / 60), LatLon.parse("49° 29.5 S, 19° 24.6 E")); 230 assertEquals(new LatLon(49 + 29.918 / 60, 19 + 15.88 / 60), LatLon.parse("N 49 29.918 E 19 15.88")); 231 assertEquals(new LatLon(49 + 29.4 / 60, 19 + 24.5 / 60), LatLon.parse("49 29.4 19 24.5")); 232 assertEquals(new LatLon(-49 - 29.4 / 60, 19 + 24.5 / 60), LatLon.parse("-49 29.4 N -19 24.5 W")); 233 } 234 235 /** 236 * Unit test of {@link LatLon#parse} method - invalid case 1. 237 */ 238 @Test(expected = IllegalArgumentException.class) 239 public void testParseInvalid1() { 240 LatLon.parse("48°45'S 23°30'S"); 241 } 242 243 /** 244 * Unit test of {@link LatLon#parse} method - invalid case 2. 245 */ 246 @Test(expected = IllegalArgumentException.class) 247 public void testParseInvalid2() { 248 LatLon.parse("47°45'N 24°00'S"); 249 } 206 250 }
Note:
See TracChangeset
for help on using the changeset viewer.