Ticket #7237: LatLonPlugin2.diff

File LatLonPlugin2.diff, 23.3 KB (added by lysgaard, 9 years ago)

Newest diff for the latlonplugin

  • src/utilsplugin2/UtilsPlugin2.java

    Cannot display: file marked as a binary type.
    svn:mime-type = application/octet-stream
    
    Property changes on: images/latlon.png
    ___________________________________________________________________
    Added: svn:mime-type
       + application/octet-stream
    
     
    3232    JMenuItem undoSelection;
    3333    JMenuItem extractPoint;
    3434    JMenuItem wiki;
     35    JMenuItem latlon;
    3536   
    3637    JMenuItem replaceGeometry;
    3738    JMenuItem tagBuffer;
     
    6465        extractPoint = MainMenu.add(toolsMenu, new ExtractPointAction());
    6566        symmetry = MainMenu.add(toolsMenu, new SymmetryAction());
    6667        wiki = MainMenu.add(toolsMenu, new OpenPageAction());
     68        latlon = MainMenu.add(toolsMenu, new LatLonAction());
    6769
    6870        JMenu selectionMenu = Main.main.menu.addMenu(marktr("Selection"), KeyEvent.VK_N, Main.main.menu.defaultMenuPos, "help");
    6971        selectWayNodes = MainMenu.add(selectionMenu, new SelectWayNodesAction());
  • src/utilsplugin2/LatLonAction.java

     
     1// License: GPL. Copyright 2007 by Immanuel Scholz and others
     2package utilsplugin2;
     3
     4import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
     5import static org.openstreetmap.josm.tools.I18n.tr;
     6
     7import java.awt.event.ActionEvent;
     8import java.awt.event.KeyEvent;
     9
     10import java.util.Collection;
     11import java.util.LinkedList;
     12
     13import org.openstreetmap.josm.Main;
     14import org.openstreetmap.josm.command.AddCommand;
     15import org.openstreetmap.josm.command.SequenceCommand;
     16import org.openstreetmap.josm.command.Command;
     17import org.openstreetmap.josm.data.coor.LatLon;
     18import org.openstreetmap.josm.data.osm.Node;
     19import org.openstreetmap.josm.data.osm.Way;
     20import org.openstreetmap.josm.tools.Shortcut;
     21import org.openstreetmap.josm.actions.JosmAction;
     22
     23/**
     24 * This action displays a dialog where the user can enter a latitude and longitude,
     25 * and when ok is pressed, a new node is created at the specified position.
     26 */
     27public final class LatLonAction extends JosmAction {
     28    // remember input from last time
     29    private String textLatLon;
     30
     31    public LatLonAction() {
     32        super(tr("Lat Lon tool"), "latlon", tr("Create geometry by entering lat lon coordinates for it."),
     33                Shortcut.registerShortcut("addnode", tr("Edit: {0}", tr("Add Node...")), KeyEvent.VK_D, Shortcut.GROUP_EDIT,
     34                        Shortcut.SHIFT_DEFAULT), true);
     35        putValue("help", ht("/Action/AddNode"));
     36    }
     37
     38    public void actionPerformed(ActionEvent e) {
     39        if (!isEnabled())
     40            return;
     41
     42        LatLonDialog dialog = new LatLonDialog(Main.parent, tr("Add Node..."), ht("/Action/AddNode"));
     43
     44        if (textLatLon != null) {
     45            dialog.setLatLonText(textLatLon);
     46        }
     47
     48        dialog.showDialog();
     49       
     50        if (dialog.getValue() != 1)
     51            return;
     52
     53        LatLon[] coordinates = dialog.getCoordinates();
     54        String type = dialog.getGeomType();
     55        if (coordinates == null)
     56            return;
     57
     58        textLatLon = dialog.getLatLonText();
     59
     60        // we create a list of commands that will modify the map in the way we want.
     61        Collection<Command> cmds = new LinkedList<Command>();
     62        // first we create all the nodes, then we do extra stuff based on what geometry type we need.
     63        LinkedList<Node> nodes = new LinkedList<Node>();
     64
     65        for (LatLon ll : coordinates) {
     66            Node nnew = new Node(ll);
     67            nodes.add(nnew);
     68            cmds.add(new AddCommand(nnew));
     69        }
     70
     71        if (type == "nodes") {
     72            //we dont need to do anything, we already have all the nodes
     73        }
     74        if (type == "way") {
     75            Way wnew = new Way();
     76            wnew.setNodes(nodes);
     77            cmds.add(new AddCommand(wnew));
     78        }
     79        if (type == "area") {
     80            nodes.add(nodes.get(0)); // this is needed to close the way.
     81            Way wnew = new Way();
     82            wnew.setNodes(nodes);
     83            cmds.add(new AddCommand(wnew));
     84        }
     85        Main.main.undoRedo.add(new SequenceCommand(tr("Lat Lon tool"), cmds));
     86        Main.map.mapView.repaint();
     87    }
     88
     89    @Override
     90    protected void updateEnabledState() {
     91        setEnabled(getEditLayer() != null);
     92    }
     93}
  • src/utilsplugin2/LatLonDialog.java

     
     1// License: GPL. For details, see LICENSE file.
     2package utilsplugin2;
     3
     4import static org.openstreetmap.josm.tools.I18n.tr;
     5
     6import java.awt.Color;
     7import java.awt.Component;
     8import java.awt.GridBagLayout;
     9import java.awt.event.ActionEvent;
     10import java.awt.event.FocusEvent;
     11import java.awt.event.FocusListener;
     12import java.awt.event.WindowAdapter;
     13import java.awt.event.WindowEvent;
     14import java.text.NumberFormat;
     15import java.text.ParsePosition;
     16import java.util.ArrayList;
     17import java.util.List;
     18import java.util.Locale;
     19import java.util.regex.Matcher;
     20import java.util.regex.Pattern;
     21
     22import javax.swing.AbstractAction;
     23import javax.swing.BorderFactory;
     24import javax.swing.JLabel;
     25import javax.swing.JPanel;
     26import javax.swing.JSeparator;
     27import javax.swing.JTabbedPane;
     28
     29import javax.swing.text.Document;
     30import javax.swing.JTextArea;
     31import javax.swing.JScrollPane;
     32import javax.swing.ButtonGroup;
     33import javax.swing.JRadioButton;
     34
     35import javax.swing.UIManager;
     36import javax.swing.event.ChangeEvent;
     37import javax.swing.event.ChangeListener;
     38import javax.swing.event.DocumentEvent;
     39import javax.swing.event.DocumentListener;
     40
     41import org.openstreetmap.josm.Main;
     42import org.openstreetmap.josm.data.coor.CoordinateFormat;
     43import org.openstreetmap.josm.data.coor.LatLon;
     44import org.openstreetmap.josm.gui.ExtendedDialog;
     45import org.openstreetmap.josm.gui.widgets.HtmlPanel;
     46import org.openstreetmap.josm.tools.GBC;
     47import org.openstreetmap.josm.tools.ImageProvider;
     48import org.openstreetmap.josm.tools.WindowGeometry;
     49
     50public class LatLonDialog extends ExtendedDialog {
     51    private static final Color BG_COLOR_ERROR = new Color(255,224,224);
     52
     53    public JTabbedPane tabs;
     54    private JTextArea taLatLon;
     55    private JScrollPane spScroll;
     56    private JRadioButton rbNodes;
     57    private JRadioButton rbWay;
     58    private JRadioButton rbClosedWay;
     59    private ButtonGroup bgType;
     60    private String geomType;
     61
     62    private LatLon[] latLonCoordinates;
     63
     64    private static final double ZERO = 0.0;
     65    private static final String DEG = "\u00B0";
     66    private static final String MIN = "\u2032";
     67    private static final String SEC = "\u2033";
     68
     69    private static final char N_TR = LatLon.NORTH.charAt(0);
     70    private static final char S_TR = LatLon.SOUTH.charAt(0);
     71    private static final char E_TR = LatLon.EAST.charAt(0);
     72    private static final char W_TR = LatLon.WEST.charAt(0);
     73
     74    private static final Pattern p = Pattern.compile(
     75            "([+|-]?\\d+[.,]\\d+)|"             // (1)
     76            + "([+|-]?\\d+)|"                   // (2)
     77            + "("+DEG+"|o|deg)|"                // (3)
     78            + "('|"+MIN+"|min)|"                // (4)
     79            + "(\"|"+SEC+"|sec)|"               // (5)
     80            + "(,|;)|"                          // (6)
     81            + "([NSEW"+N_TR+S_TR+E_TR+W_TR+"])|"// (7)
     82            + "\\s+|"
     83            + "(.+)");
     84
     85    protected JPanel buildLatLon() {
     86        JPanel pnl = new JPanel(new GridBagLayout());
     87        pnl.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
     88
     89        pnl.add(new JLabel(tr("Coordinates:")), GBC.std().insets(0,10,5,0));
     90
     91        taLatLon = new JTextArea(5,24);
     92        taLatLon.getDocument().addDocumentListener(new CoordinateListener());
     93        spScroll = new JScrollPane(taLatLon);
     94        pnl.add(spScroll, GBC.eol().insets(0,10,0,0).fill().weight(2.0, 2.0));
     95
     96        //Radio button setup
     97        bgType = new ButtonGroup();
     98
     99        rbNodes = new JRadioButton("Nodes", true);
     100        rbNodes.setActionCommand("nodes");
     101        bgType.add(rbNodes);
     102        pnl.add(rbNodes, GBC.eol());
     103
     104        rbWay = new JRadioButton("Way");
     105        rbWay.setActionCommand("way");
     106        bgType.add(rbWay);
     107        pnl.add(rbWay, GBC.eol());
     108
     109        rbClosedWay = new JRadioButton("Closed Way (Area)");
     110        rbClosedWay.setActionCommand("area");
     111        bgType.add(rbClosedWay);
     112        pnl.add(rbClosedWay, GBC.eol());
     113
     114        //pnl.add(bgType, GBC.eol().insets(0,10,0,0).fill(GBC.HORIZONTAL).weight(2.0, 0.0));
     115        //pnl.add(new JRadioButton("test"));
     116        //pnl.add(bgType);
     117
     118        pnl.add(new JSeparator(), GBC.eol().fill(GBC.HORIZONTAL).insets(0,5,0,5));
     119
     120        pnl.add(new HtmlPanel(
     121                tr("Enter the coordinates for the new nodes, one for each line.<br/>If you enter two lines with the same coordinates there will be generated duplicate nodes.<br/>You can separate longitude and latitude with space, comma or semicolon.<br/>" +
     122                    "Use positive numbers or N, E characters to indicate North or East cardinal direction.<br/>" +
     123                    "For South and West cardinal directions you can use either negative numbers or S, W characters.<br/>" +
     124                    "Coordinate value can be in one of three formats:<ul>" +
     125                    "<li><i>degrees</i><tt>&deg;</tt></li>" +
     126                    "<li><i>degrees</i><tt>&deg;</tt> <i>minutes</i><tt>&#39;</tt></li>" +
     127                    "<li><i>degrees</i><tt>&deg;</tt> <i>minutes</i><tt>&#39;</tt> <i>seconds</i><tt>&quot</tt></li>" +
     128                    "</ul>" +
     129                    "Symbols <tt>&deg;</tt>, <tt>&#39;</tt>, <tt>&prime;</tt>, <tt>&quot;</tt>, <tt>&Prime;</tt> are optional.<br/><br/>" +
     130                    "Some examples:<ul>" +
     131                    "<li>49.29918&deg; 19.24788&deg;</li>" +
     132                    "<li>N 49.29918 E 19.24788</li>" +
     133                    "<li>W 49&deg;29.918&#39; S 19&deg;24.788&#39;</li>" +
     134                    "<li>N 49&deg;29&#39;04&quot; E 19&deg;24&#39;43&quot;</li>" +
     135                    "<li>49.29918 N, 19.24788 E</li>" +
     136                    "<li>49&deg;29&#39;21&quot; N 19&deg;24&#39;38&quot; E</li>" +
     137                    "<li>49 29 51, 19 24 18</li>" +
     138                    "<li>49 29, 19 24</li>" +
     139                    "<li>E 49 29, N 19 24</li>" +
     140                    "<li>49&deg; 29; 19&deg; 24</li>" +
     141                    "<li>N 49&deg; 29, W 19&deg; 24</li>" +
     142                    "<li>49&deg; 29.5 S, 19&deg; 24.6 E</li>" +
     143                    "<li>N 49 29.918 E 19 15.88</li>" +
     144                    "<li>49 29.4 19 24.5</li>" +
     145                    "<li>-49 29.4 N -19 24.5 W</li></ul>" +
     146                    "<li>48 deg 42&#39; 52.13\" N, 21 deg 11&#39; 47.60\" E</li></ul>"
     147                )),
     148                GBC.eol().fill().weight(1.0, 1.0));
     149
     150        // parse and verify input on the fly
     151        //
     152        LatLonInputVerifier inputVerifier = new LatLonInputVerifier();
     153        taLatLon.getDocument().addDocumentListener(inputVerifier);
     154
     155        // select the text in the field on focus
     156        //
     157        TextFieldFocusHandler focusHandler = new TextFieldFocusHandler();
     158        taLatLon.addFocusListener(focusHandler);
     159        return pnl;
     160    }
     161
     162    protected void build() {
     163        tabs = new JTabbedPane();
     164        tabs.addTab(tr("Lat/Lon"), buildLatLon());
     165        tabs.getModel().addChangeListener(new ChangeListener() {
     166            @Override
     167            public void stateChanged(ChangeEvent e) {
     168                switch (tabs.getModel().getSelectedIndex()) {
     169                    case 0: parseLatLonUserInput(); break;
     170                    default: throw new AssertionError();
     171                }
     172            }
     173        });
     174        setContent(tabs, false);
     175    }
     176
     177    public LatLonDialog(Component parent, String title, String help) {
     178        super(Main.parent, tr("Add Node..."), new String[] { tr("Ok"), tr("Cancel") });
     179        setButtonIcons(new String[] { "ok", "cancel" });
     180        configureContextsensitiveHelp("/Action/AddNode", true);
     181
     182        build();
     183        setCoordinates(null);
     184    }
     185
     186    public void setCoordinates(LatLon[] ll) {
     187        if (ll == null) {
     188            ll = new LatLon[] {};
     189        }
     190        this.latLonCoordinates = ll;
     191    String text = "";
     192    for (LatLon latlon : ll) {
     193            text = text + latlon.latToString(CoordinateFormat.getDefaultFormat()) + " " + latlon.lonToString(CoordinateFormat.getDefaultFormat()) + "\n";
     194        }
     195        taLatLon.setText(text);
     196        setOkEnabled(true);
     197    }
     198
     199    public LatLon[] getCoordinates() {
     200        return latLonCoordinates;
     201    }
     202
     203    public LatLon[] getLatLonCoordinates() {
     204        return latLonCoordinates;
     205    }
     206
     207    public String getGeomType() {
     208        return bgType.getSelection().getActionCommand();
     209    }
     210
     211    protected void setErrorFeedback(JTextArea tf, String message) {
     212        tf.setBorder(BorderFactory.createLineBorder(Color.RED, 1));
     213        tf.setToolTipText(message);
     214        tf.setBackground(BG_COLOR_ERROR);
     215    }
     216
     217    protected void clearErrorFeedback(JTextArea tf, String message) {
     218        tf.setBorder(UIManager.getBorder("TextField.border"));
     219        tf.setToolTipText(message);
     220        tf.setBackground(UIManager.getColor("TextField.background"));
     221    }
     222
     223    protected Double parseDoubleFromUserInput(String input) {
     224        if (input == null) return null;
     225        // remove white space and an optional degree symbol
     226        //
     227        input = input.trim();
     228        input = input.replaceAll(DEG, "");
     229
     230        // try to parse using the current locale
     231        //
     232        NumberFormat f = NumberFormat.getNumberInstance();
     233        Number n=null;
     234        ParsePosition pp = new ParsePosition(0);
     235        n = f.parse(input,pp);
     236        if (pp.getErrorIndex() >= 0 || pp.getIndex()<input.length()) {
     237            // fall back - try to parse with the english locale
     238            //
     239            pp = new ParsePosition(0);
     240            f = NumberFormat.getNumberInstance(Locale.ENGLISH);
     241            n = f.parse(input, pp);
     242            if (pp.getErrorIndex() >= 0 || pp.getIndex()<input.length())
     243                return null;
     244        }
     245        return n== null ? null : n.doubleValue();
     246    }
     247
     248    protected void parseLatLonUserInput() {
     249        LatLon[] latLons;
     250        try {
     251            latLons = parseLatLons(taLatLon.getText());
     252        Boolean working = true;
     253        int i=0;
     254        while (working && i < latLons.length) {
     255        if (!LatLon.isValidLat(latLons[i].lat()) || !LatLon.isValidLon(latLons[i].lon())) {
     256                    latLons = null;
     257            working = false;
     258                }
     259        i++;
     260        }
     261        } catch (IllegalArgumentException e) {
     262            latLons = null;
     263        }
     264        if (latLons == null) {
     265            setErrorFeedback(taLatLon, tr("Please enter a GPS coordinates"));
     266            latLonCoordinates = null;
     267            setOkEnabled(false);
     268        } else {
     269            clearErrorFeedback(taLatLon,tr("Please enter a GPS coordinates"));
     270            latLonCoordinates = latLons;
     271            setOkEnabled(true);
     272        }
     273    }
     274
     275    private void setOkEnabled(boolean b) {
     276        if (buttons != null && buttons.size() > 0) {
     277            buttons.get(0).setEnabled(b);
     278        }
     279    }
     280
     281    @Override
     282    public void setVisible(boolean visible) {
     283        if (visible) {
     284            WindowGeometry.centerInWindow(Main.parent, getSize()).applySafe(this);
     285        }
     286        super.setVisible(visible);
     287    }
     288
     289    class LatLonInputVerifier implements DocumentListener {
     290        public void changedUpdate(DocumentEvent e) {
     291            parseLatLonUserInput();
     292        }
     293
     294        public void insertUpdate(DocumentEvent e) {
     295            parseLatLonUserInput();
     296        }
     297
     298        public void removeUpdate(DocumentEvent e) {
     299            parseLatLonUserInput();
     300        }
     301    }
     302
     303    static class TextFieldFocusHandler implements FocusListener {
     304        public void focusGained(FocusEvent e) {
     305            Component c = e.getComponent();
     306            if (c instanceof JTextArea) {
     307                JTextArea tf = (JTextArea)c;
     308                tf.selectAll();
     309            }
     310        }
     311        public void focusLost(FocusEvent e) {}
     312    }
     313
     314    private static LatLon[] parseLatLons(final String text) {
     315        String lines[] = text.split("\\r?\\n");
     316        List<LatLon> latLons = new ArrayList<LatLon>();
     317        for (String line : lines) {
     318            latLons.add(parseLatLon(line));
     319        }
     320        return latLons.toArray(new LatLon[]{});
     321    }
     322
     323    private static LatLon parseLatLon(final String coord) {
     324        final Matcher m = p.matcher(coord);
     325
     326        final StringBuilder sb = new StringBuilder();
     327        final List<Object> list = new ArrayList<Object>();
     328
     329        while (m.find()) {
     330            if (m.group(1) != null) {
     331                sb.append('R');     // floating point number
     332                list.add(Double.parseDouble(m.group(1).replace(',', '.')));
     333            } else if (m.group(2) != null) {
     334                sb.append('Z');     // integer number
     335                list.add(Double.parseDouble(m.group(2)));
     336            } else if (m.group(3) != null) {
     337                sb.append('o');     // degree sign
     338            } else if (m.group(4) != null) {
     339                sb.append('\'');    // seconds sign
     340            } else if (m.group(5) != null) {
     341                sb.append('"');     // minutes sign
     342            } else if (m.group(6) != null) {
     343                sb.append(',');     // separator
     344            } else if (m.group(7) != null) {
     345                sb.append("x");     // cardinal direction
     346                String c = m.group(7).toUpperCase();
     347                if (c.equals("N") || c.equals("S") || c.equals("E") || c.equals("W")) {
     348                    list.add(c);
     349                } else {
     350                    list.add(c.replace(N_TR, 'N').replace(S_TR, 'S')
     351                            .replace(E_TR, 'E').replace(W_TR, 'W'));
     352                }
     353            } else if (m.group(8) != null) {
     354                throw new IllegalArgumentException("invalid token: " + m.group(8));
     355            }
     356        }
     357
     358        final String pattern = sb.toString();
     359
     360        final Object[] params = list.toArray();
     361        final LatLonHolder latLon = new LatLonHolder();
     362
     363        if (pattern.matches("Ro?,?Ro?")) {
     364            setLatLonObj(latLon,
     365                    params[0], ZERO, ZERO, "N",
     366                    params[1], ZERO, ZERO, "E");
     367        } else if (pattern.matches("xRo?,?xRo?")) {
     368            setLatLonObj(latLon,
     369                    params[1], ZERO, ZERO, params[0],
     370                    params[3], ZERO, ZERO, params[2]);
     371        } else if (pattern.matches("Ro?x,?Ro?x")) {
     372            setLatLonObj(latLon,
     373                    params[0], ZERO, ZERO, params[1],
     374                    params[2], ZERO, ZERO, params[3]);
     375        } else if (pattern.matches("Zo[RZ]'?,?Zo[RZ]'?|Z[RZ],?Z[RZ]")) {
     376            setLatLonObj(latLon,
     377                    params[0], params[1], ZERO, "N",
     378                    params[2], params[3], ZERO, "E");
     379        } else if (pattern.matches("xZo[RZ]'?,?xZo[RZ]'?|xZo?[RZ],?xZo?[RZ]")) {
     380            setLatLonObj(latLon,
     381                    params[1], params[2], ZERO, params[0],
     382                    params[4], params[5], ZERO, params[3]);
     383        } else if (pattern.matches("Zo[RZ]'?x,?Zo[RZ]'?x|Zo?[RZ]x,?Zo?[RZ]x")) {
     384            setLatLonObj(latLon,
     385                    params[0], params[1], ZERO, params[2],
     386                    params[3], params[4], ZERO, params[5]);
     387        } else if (pattern.matches("ZoZ'[RZ]\"?x,?ZoZ'[RZ]\"?x|ZZ[RZ]x,?ZZ[RZ]x")) {
     388            setLatLonObj(latLon,
     389                    params[0], params[1], params[2], params[3],
     390                    params[4], params[5], params[6], params[7]);
     391        } else if (pattern.matches("xZoZ'[RZ]\"?,?xZoZ'[RZ]\"?|xZZ[RZ],?xZZ[RZ]")) {
     392            setLatLonObj(latLon,
     393                    params[1], params[2], params[3], params[0],
     394                    params[5], params[6], params[7], params[4]);
     395        } else if (pattern.matches("ZZ[RZ],?ZZ[RZ]")) {
     396            setLatLonObj(latLon,
     397                    params[0], params[1], params[2], "N",
     398                    params[3], params[4], params[5], "E");
     399        } else {
     400            throw new IllegalArgumentException("invalid format: " + pattern);
     401        }
     402
     403        return new LatLon(latLon.lat, latLon.lon);
     404    }
     405
     406    private static class LatLonHolder {
     407        double lat, lon;
     408    }
     409
     410    private static void setLatLonObj(final LatLonHolder latLon,
     411            final Object coord1deg, final Object coord1min, final Object coord1sec, final Object card1,
     412            final Object coord2deg, final Object coord2min, final Object coord2sec, final Object card2) {
     413
     414        setLatLon(latLon,
     415                (Double) coord1deg, (Double) coord1min, (Double) coord1sec, (String) card1,
     416                (Double) coord2deg, (Double) coord2min, (Double) coord2sec, (String) card2);
     417    }
     418
     419    private static void setLatLon(final LatLonHolder latLon,
     420            final double coord1deg, final double coord1min, final double coord1sec, final String card1,
     421            final double coord2deg, final double coord2min, final double coord2sec, final String card2) {
     422
     423        setLatLon(latLon, coord1deg, coord1min, coord1sec, card1);
     424        setLatLon(latLon, coord2deg, coord2min, coord2sec, card2);
     425    }
     426
     427    private static void setLatLon(final LatLonHolder latLon, final double coordDeg, final double coordMin, final double coordSec, final String card) {
     428        if (coordDeg < -180 || coordDeg > 180 || coordMin < 0 || coordMin >= 60 || coordSec < 0 || coordSec > 60) {
     429            throw new IllegalArgumentException("out of range");
     430        }
     431
     432        double coord = (coordDeg < 0 ? -1 : 1) * (Math.abs(coordDeg) + coordMin / 60 + coordSec / 3600);
     433        coord = card.equals("N") || card.equals("E") ? coord : -coord;
     434        if (card.equals("N") || card.equals("S")) {
     435            latLon.lat = coord;
     436        } else {
     437            latLon.lon = coord;
     438        }
     439    }
     440
     441    public String getLatLonText() {
     442        return taLatLon.getText();
     443    }
     444
     445    public void setLatLonText(String text) {
     446        taLatLon.setText(text);
     447    }
     448
     449    private class CoordinateListener implements DocumentListener {
     450        public void changedUpdate(DocumentEvent e) {
     451            //not fired
     452        }
     453        public void insertUpdate(DocumentEvent e) {
     454            updateButtons();
     455        }
     456        public void removeUpdate(DocumentEvent e) {
     457            updateButtons();
     458        }
     459        private void updateButtons() {
     460            String text = taLatLon.getText();
     461            String[] lines = text.split("\r\n|\r|\n");
     462            rbNodes.setEnabled(true);
     463            rbWay.setEnabled(true);
     464            rbClosedWay.setEnabled(true);
     465            if (lines.length < 3) {
     466                rbClosedWay.setEnabled(false);
     467                bgType.setSelected(rbNodes.getModel(), true);
     468            }
     469            if (lines.length < 2) {
     470                rbWay.setEnabled(false);
     471                bgType.setSelected(rbNodes.getModel(), true);
     472            }
     473        }
     474    }
     475}