Ignore:
Timestamp:
2017-09-08T22:02:38+02:00 (2 years ago)
Author:
bastiK
Message:

closes #15273, see #15229, see #15182 - add command line interface module for projections

  • run josm project --help to see the options
  • extracts parser from LatLon and CustomProjection into LatLonParser
Location:
trunk/src/org/openstreetmap/josm/data
Files:
2 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/coor/LatLon.java

    r12745 r12792  
    1515import java.text.DecimalFormat;
    1616import java.text.NumberFormat;
    17 import java.util.ArrayList;
    1817import java.util.Arrays;
    19 import java.util.List;
    2018import java.util.Locale;
    2119import java.util.Objects;
    22 import java.util.regex.Matcher;
    23 import java.util.regex.Pattern;
    2420
    2521import org.openstreetmap.josm.Main;
     
    2723import org.openstreetmap.josm.data.coor.conversion.DMSCoordinateFormat;
    2824import org.openstreetmap.josm.data.coor.conversion.DecimalDegreesCoordinateFormat;
     25import org.openstreetmap.josm.data.coor.conversion.LatLonParser;
    2926import org.openstreetmap.josm.data.coor.conversion.NauticalCoordinateFormat;
    3027import org.openstreetmap.josm.tools.Logging;
     
    8986    }
    9087
    91     /** Character denoting South, as string */
     88    /**
     89     * Character denoting South, as string.
     90     * @deprecated use {@link LatLonParser#SOUTH}
     91     */
     92    @Deprecated
    9293    public static final String SOUTH = trc("compass", "S");
    93     /** Character denoting North, as string */
     94    /**
     95     * Character denoting North, as string.
     96     * @deprecated use {@link LatLonParser#NORTH}
     97     */
     98    @Deprecated
    9499    public static final String NORTH = trc("compass", "N");
    95     /** Character denoting West, as string */
     100    /**
     101     * Character denoting West, as string.
     102     * @deprecated use {@link LatLonParser#WEST}
     103     */
     104    @Deprecated
    96105    public static final String WEST = trc("compass", "W");
    97     /** Character denoting East, as string */
     106    /**
     107     * Character denoting East, as string.
     108     * @deprecated use {@link LatLonParser#EAST}
     109     */
     110    @Deprecated
    98111    public static final String EAST = trc("compass", "E");
    99 
    100     private static final char N_TR = NORTH.charAt(0);
    101     private static final char S_TR = SOUTH.charAt(0);
    102     private static final char E_TR = EAST.charAt(0);
    103     private static final char W_TR = WEST.charAt(0);
    104 
    105     private static final String DEG = "\u00B0";
    106     private static final String MIN = "\u2032";
    107     private static final String SEC = "\u2033";
    108 
    109     private static final Pattern P = Pattern.compile(
    110             "([+|-]?\\d+[.,]\\d+)|"             // (1)
    111             + "([+|-]?\\d+)|"                   // (2)
    112             + "("+DEG+"|o|deg)|"                // (3)
    113             + "('|"+MIN+"|min)|"                // (4)
    114             + "(\"|"+SEC+"|sec)|"               // (5)
    115             + "(,|;)|"                          // (6)
    116             + "([NSEW"+N_TR+S_TR+E_TR+W_TR+"])|"// (7)
    117             + "\\s+|"
    118             + "(.+)", Pattern.CASE_INSENSITIVE);
    119 
    120     private static final Pattern P_XML = Pattern.compile(
    121             "lat=[\"']([+|-]?\\d+[.,]\\d+)[\"']\\s+lon=[\"']([+|-]?\\d+[.,]\\d+)[\"']");
    122112
    123113    /**
     
    517507    }
    518508
    519     private static class LatLonHolder {
    520         private double lat = Double.NaN;
    521         private double lon = Double.NaN;
    522     }
    523 
    524     private static void setLatLonObj(final LatLonHolder latLon,
    525             final Object coord1deg, final Object coord1min, final Object coord1sec, final Object card1,
    526             final Object coord2deg, final Object coord2min, final Object coord2sec, final Object card2) {
    527 
    528         setLatLon(latLon,
    529                 (Double) coord1deg, (Double) coord1min, (Double) coord1sec, (String) card1,
    530                 (Double) coord2deg, (Double) coord2min, (Double) coord2sec, (String) card2);
    531     }
    532 
    533     private static void setLatLon(final LatLonHolder latLon,
    534             final double coord1deg, final double coord1min, final double coord1sec, final String card1,
    535             final double coord2deg, final double coord2min, final double coord2sec, final String card2) {
    536 
    537         setLatLon(latLon, coord1deg, coord1min, coord1sec, card1);
    538         setLatLon(latLon, coord2deg, coord2min, coord2sec, card2);
    539         if (Double.isNaN(latLon.lat) || Double.isNaN(latLon.lon)) {
    540             throw new IllegalArgumentException("invalid lat/lon parameters");
    541         }
    542     }
    543 
    544     private static void setLatLon(final LatLonHolder latLon, final double coordDeg, final double coordMin, final double coordSec,
    545             final String card) {
    546         if (coordDeg < -180 || coordDeg > 180 || coordMin < 0 || coordMin >= 60 || coordSec < 0 || coordSec > 60) {
    547             throw new IllegalArgumentException("out of range");
    548         }
    549 
    550         double coord = (coordDeg < 0 ? -1 : 1) * (Math.abs(coordDeg) + coordMin / 60 + coordSec / 3600);
    551         coord = "N".equals(card) || "E".equals(card) ? coord : -coord;
    552         if ("N".equals(card) || "S".equals(card)) {
    553             latLon.lat = coord;
    554         } else {
    555             latLon.lon = coord;
    556         }
    557     }
    558 
    559509    /**
    560510     * Parses the given string as lat/lon.
     
    562512     * @return parsed lat/lon
    563513     * @since 11045
    564      */
     514     * @deprecated use {@link LatLonParser#parse(java.lang.String)}
     515     */
     516    @Deprecated
    565517    public static LatLon parse(String coord) {
    566         final LatLonHolder latLon = new LatLonHolder();
    567         final Matcher mXml = P_XML.matcher(coord);
    568         if (mXml.matches()) {
    569             setLatLonObj(latLon,
    570                     Double.valueOf(mXml.group(1).replace(',', '.')), 0.0, 0.0, "N",
    571                     Double.valueOf(mXml.group(2).replace(',', '.')), 0.0, 0.0, "E");
    572         } else {
    573             final Matcher m = P.matcher(coord);
    574 
    575             final StringBuilder sb = new StringBuilder();
    576             final List<Object> list = new ArrayList<>();
    577 
    578             while (m.find()) {
    579                 if (m.group(1) != null) {
    580                     sb.append('R');     // floating point number
    581                     list.add(Double.valueOf(m.group(1).replace(',', '.')));
    582                 } else if (m.group(2) != null) {
    583                     sb.append('Z');     // integer number
    584                     list.add(Double.valueOf(m.group(2)));
    585                 } else if (m.group(3) != null) {
    586                     sb.append('o');     // degree sign
    587                 } else if (m.group(4) != null) {
    588                     sb.append('\'');    // seconds sign
    589                 } else if (m.group(5) != null) {
    590                     sb.append('"');     // minutes sign
    591                 } else if (m.group(6) != null) {
    592                     sb.append(',');     // separator
    593                 } else if (m.group(7) != null) {
    594                     sb.append('x');     // cardinal direction
    595                     String c = m.group(7).toUpperCase(Locale.ENGLISH);
    596                     if ("N".equalsIgnoreCase(c) || "S".equalsIgnoreCase(c) || "E".equalsIgnoreCase(c) || "W".equalsIgnoreCase(c)) {
    597                         list.add(c);
    598                     } else {
    599                         list.add(c.replace(N_TR, 'N').replace(S_TR, 'S')
    600                                   .replace(E_TR, 'E').replace(W_TR, 'W'));
    601                     }
    602                 } else if (m.group(8) != null) {
    603                     throw new IllegalArgumentException("invalid token: " + m.group(8));
    604                 }
    605             }
    606 
    607             final String pattern = sb.toString();
    608 
    609             final Object[] params = list.toArray();
    610 
    611             if (pattern.matches("Ro?,?Ro?")) {
    612                 setLatLonObj(latLon,
    613                         params[0], 0.0, 0.0, "N",
    614                         params[1], 0.0, 0.0, "E");
    615             } else if (pattern.matches("xRo?,?xRo?")) {
    616                 setLatLonObj(latLon,
    617                         params[1], 0.0, 0.0, params[0],
    618                         params[3], 0.0, 0.0, params[2]);
    619             } else if (pattern.matches("Ro?x,?Ro?x")) {
    620                 setLatLonObj(latLon,
    621                         params[0], 0.0, 0.0, params[1],
    622                         params[2], 0.0, 0.0, params[3]);
    623             } else if (pattern.matches("Zo[RZ]'?,?Zo[RZ]'?|Z[RZ],?Z[RZ]")) {
    624                 setLatLonObj(latLon,
    625                         params[0], params[1], 0.0, "N",
    626                         params[2], params[3], 0.0, "E");
    627             } else if (pattern.matches("xZo[RZ]'?,?xZo[RZ]'?|xZo?[RZ],?xZo?[RZ]")) {
    628                 setLatLonObj(latLon,
    629                         params[1], params[2], 0.0, params[0],
    630                         params[4], params[5], 0.0, params[3]);
    631             } else if (pattern.matches("Zo[RZ]'?x,?Zo[RZ]'?x|Zo?[RZ]x,?Zo?[RZ]x")) {
    632                 setLatLonObj(latLon,
    633                         params[0], params[1], 0.0, params[2],
    634                         params[3], params[4], 0.0, params[5]);
    635             } else if (pattern.matches("ZoZ'[RZ]\"?x,?ZoZ'[RZ]\"?x|ZZ[RZ]x,?ZZ[RZ]x")) {
    636                 setLatLonObj(latLon,
    637                         params[0], params[1], params[2], params[3],
    638                         params[4], params[5], params[6], params[7]);
    639             } else if (pattern.matches("xZoZ'[RZ]\"?,?xZoZ'[RZ]\"?|xZZ[RZ],?xZZ[RZ]")) {
    640                 setLatLonObj(latLon,
    641                         params[1], params[2], params[3], params[0],
    642                         params[5], params[6], params[7], params[4]);
    643             } else if (pattern.matches("ZZ[RZ],?ZZ[RZ]")) {
    644                 setLatLonObj(latLon,
    645                         params[0], params[1], params[2], "N",
    646                         params[3], params[4], params[5], "E");
    647             } else {
    648                 throw new IllegalArgumentException("invalid format: " + pattern);
    649             }
    650         }
    651 
    652         return new LatLon(latLon.lat, latLon.lon);
     518        return LatLonParser.parse(coord);
    653519    }
    654520}
  • trunk/src/org/openstreetmap/josm/data/projection/CustomProjection.java

    r12620 r12792  
    1919import org.openstreetmap.josm.data.coor.EastNorth;
    2020import org.openstreetmap.josm.data.coor.LatLon;
     21import org.openstreetmap.josm.data.coor.conversion.LatLonParser;
    2122import org.openstreetmap.josm.data.projection.datum.CentricDatum;
    2223import org.openstreetmap.josm.data.projection.datum.Datum;
     
    655656    /**
    656657     * Convert an angle string to a double value
    657      * @param angleStr The string. e.g. -1.1 or 50d 10' 3"
     658     * @param angleStr The string. e.g. -1.1 or 50d10'3"
    658659     * @param parameterName Only for error message.
    659660     * @return The angle value, in degrees.
     
    661662     */
    662663    public static double parseAngle(String angleStr, String parameterName) throws ProjectionConfigurationException {
    663         final String floatPattern = "(\\d+(\\.\\d*)?)";
    664         // pattern does all error handling.
    665         Matcher in = Pattern.compile("^(?<neg1>-)?"
    666                 + "(?=\\d)(?:(?<single>" + floatPattern + ")|"
    667                 + "((?<degree>" + floatPattern + ")d)?"
    668                 + "((?<minutes>" + floatPattern + ")\')?"
    669                 + "((?<seconds>" + floatPattern + ")\")?)"
    670                 + "(?:[NE]|(?<neg2>[SW]))?$").matcher(angleStr);
    671 
    672         if (!in.find()) {
     664        try {
     665            return LatLonParser.parseCoordinate(angleStr);
     666        } catch (IllegalArgumentException e) {
    673667            throw new ProjectionConfigurationException(
    674668                    tr("Unable to parse value ''{1}'' of parameter ''{0}'' as coordinate value.", parameterName, angleStr));
    675669        }
    676 
    677         double value = 0;
    678         if (in.group("single") != null) {
    679             value += Double.parseDouble(in.group("single"));
    680         }
    681         if (in.group("degree") != null) {
    682             value += Double.parseDouble(in.group("degree"));
    683         }
    684         if (in.group("minutes") != null) {
    685             value += Double.parseDouble(in.group("minutes")) / 60;
    686         }
    687         if (in.group("seconds") != null) {
    688             value += Double.parseDouble(in.group("seconds")) / 3600;
    689         }
    690 
    691         if (in.group("neg1") != null ^ in.group("neg2") != null) {
    692             value = -value;
    693         }
    694         return value;
    695670    }
    696671
     
    915890        return result;
    916891    }
     892
     893    /**
     894     * Return true, if a geographic coordinate reference system is represented.
     895     *
     896     * I.e. if it returns latitude/longitude values rather than Cartesian
     897     * east/north coordinates on a flat surface.
     898     * @return true, if it is geographic
     899     * @since 12792
     900     */
     901    public boolean isGeographic() {
     902        return proj.isGeographic();
     903    }
     904
    917905}
Note: See TracChangeset for help on using the changeset viewer.