Changeset 11045 in josm for trunk/src/org/openstreetmap/josm/data
- Timestamp:
- 2016-09-23T21:13:02+02:00 (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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 }
Note:
See TracChangeset
for help on using the changeset viewer.