Changeset 12792 in josm for trunk


Ignore:
Timestamp:
2017-09-08T22:02:38+02:00 (7 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
Files:
2 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/actions/JumpToAction.java

    r12639 r12792  
    2020import org.openstreetmap.josm.data.Bounds;
    2121import org.openstreetmap.josm.data.coor.LatLon;
     22import org.openstreetmap.josm.data.coor.conversion.LatLonParser;
    2223import org.openstreetmap.josm.gui.ExtendedDialog;
    2324import org.openstreetmap.josm.gui.MainApplication;
     
    161162            } catch (NumberFormatException ex) {
    162163                try {
    163                     ll = LatLon.parse(lat.getText() + "; " + lon.getText());
     164                    ll = LatLonParser.parse(lat.getText() + "; " + lon.getText());
    164165                } catch (IllegalArgumentException ex2) {
    165166                    JOptionPane.showMessageDialog(Main.parent,
  • 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}
  • trunk/src/org/openstreetmap/josm/gui/MainApplication.java

    r12790 r12792  
    3434import java.util.Locale;
    3535import java.util.Map;
     36import java.util.Objects;
    3637import java.util.Optional;
    3738import java.util.Set;
     
    6162import org.jdesktop.swinghelper.debug.CheckThreadViolationRepaintManager;
    6263import org.openstreetmap.gui.jmapviewer.FeatureAdapter;
     64import org.openstreetmap.josm.CLIModule;
    6365import org.openstreetmap.josm.Main;
    6466import org.openstreetmap.josm.actions.DeleteAction;
     
    8587import org.openstreetmap.josm.data.osm.UserInfo;
    8688import org.openstreetmap.josm.data.osm.search.SearchMode;
     89import org.openstreetmap.josm.data.projection.ProjectionCLI;
    8790import org.openstreetmap.josm.data.projection.datum.NTV2GridShiftFileSource;
    8891import org.openstreetmap.josm.data.projection.datum.NTV2GridShiftFileWrapper;
     
    163166     * Command-line arguments used to run the application.
    164167     */
    165     private static final List<String> COMMAND_LINE_ARGS = new ArrayList<>();
     168    private static List<String> commandLineArgs;
    166169
    167170    /**
     
    230233        public void layerAdded(LayerAddEvent e) {
    231234            // Do nothing
     235        }
     236    };
     237
     238    private static final List<CLIModule> cliModules = new ArrayList<>();
     239
     240    /**
     241     * Default JOSM command line interface.
     242     * <p>
     243     * Runs JOSM and performs some action, depending on the options and positional
     244     * arguments.
     245     */
     246    public static final CLIModule JOSM_CLI_MODULE = new CLIModule() {
     247        @Override
     248        public String getActionKeyword() {
     249            return "runjosm";
     250        }
     251
     252        @Override
     253        public void processArguments(String[] argArray) {
     254            ProgramArguments args = null;
     255            // construct argument table
     256            try {
     257                args = new ProgramArguments(argArray);
     258            } catch (IllegalArgumentException e) {
     259                System.err.println(e.getMessage());
     260                System.exit(1);
     261            }
     262            mainJOSM(args);
    232263        }
    233264    };
     
    256287        }
    257288    };
     289
     290    static {
     291        registerCLIModue(JOSM_CLI_MODULE);
     292        registerCLIModue(ProjectionCLI.INSTANCE);
     293    }
     294
     295    /**
     296     * Register a command line interface module.
     297     * @param module the module
     298     * @since 12792
     299     */
     300    public static void registerCLIModue(CLIModule module) {
     301        cliModules.add(module);
     302    }
    258303
    259304    /**
     
    488533     */
    489534    public static List<String> getCommandLineArgs() {
    490         return Collections.unmodifiableList(COMMAND_LINE_ARGS);
     535        return Collections.unmodifiableList(commandLineArgs);
    491536    }
    492537
     
    766811    public static void main(final String[] argArray) {
    767812        I18n.init();
    768 
    769         ProgramArguments args = null;
    770         // construct argument table
    771         try {
    772             args = new ProgramArguments(argArray);
    773         } catch (IllegalArgumentException e) {
    774             System.err.println(e.getMessage());
    775             System.exit(1);
    776             return;
    777         }
     813        commandLineArgs = Arrays.asList(Arrays.copyOf(argArray, argArray.length));
     814
     815        if (argArray.length > 0) {
     816            String moduleStr = argArray[0];
     817            for (CLIModule module : cliModules) {
     818                if (Objects.equals(moduleStr, module.getActionKeyword())) {
     819                   String[] argArrayCdr = Arrays.copyOfRange(argArray, 1, argArray.length);
     820                   module.processArguments(argArrayCdr);
     821                   return;
     822                }
     823            }
     824        }
     825        // no module specified, use default (josm)
     826        JOSM_CLI_MODULE.processArguments(argArray);
     827    }
     828
     829    /**
     830     * Main method to run the JOSM GUI.
     831     * @param args program arguments
     832     */
     833    public static void mainJOSM(ProgramArguments args) {
    778834
    779835        if (!GraphicsEnvironment.isHeadless()) {
     
    821877            return;
    822878        }
    823 
    824         COMMAND_LINE_ARGS.addAll(Arrays.asList(argArray));
    825879
    826880        boolean skipLoadingPlugins = args.hasOption(Option.SKIP_PLUGINS);
  • trunk/src/org/openstreetmap/josm/gui/ProgramArguments.java

    r12633 r12792  
    113113     */
    114114    private void buildCommandLineArgumentMap(String... args) {
    115         LongOpt[] los = Stream.of(Option.values()).map(Option::toLongOpt).toArray(i -> new LongOpt[i]);
     115        LongOpt[] los = Stream.of(Option.values()).map(Option::toLongOpt).toArray(LongOpt[]::new);
    116116
    117117        Getopt g = new Getopt("JOSM", args, "hv", los);
  • trunk/src/org/openstreetmap/josm/gui/dialogs/LatLonDialog.java

    r12735 r12792  
    2727import org.openstreetmap.josm.data.coor.LatLon;
    2828import org.openstreetmap.josm.data.coor.conversion.CoordinateFormatManager;
     29import org.openstreetmap.josm.data.coor.conversion.LatLonParser;
    2930import org.openstreetmap.josm.gui.ExtendedDialog;
    3031import org.openstreetmap.josm.gui.util.WindowGeometry;
     
    245246        LatLon latLon;
    246247        try {
    247             latLon = LatLon.parse(tfLatLon.getText());
     248            latLon = LatLonParser.parse(tfLatLon.getText());
    248249            if (!LatLon.isValidLat(latLon.lat()) || !LatLon.isValidLon(latLon.lon())) {
    249250                latLon = null;
Note: See TracChangeset for help on using the changeset viewer.