Changeset 32357 in osm


Ignore:
Timestamp:
2016-06-22T01:38:10+02:00 (8 years ago)
Author:
donvip
Message:

update to new JOSM + code cleanup (Eclipse formatting)

Location:
applications/editors/josm/plugins/public_transport
Files:
33 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/public_transport/.settings/org.eclipse.jdt.core.prefs

    r30736 r32357  
    6363org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
    6464org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
    65 org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
    66 org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
     65org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning
     66org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning
    6767org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
    6868org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
     
    8686org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
    8787org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
     88org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore
    8889org.eclipse.jdt.core.compiler.problem.unusedImport=warning
    8990org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
  • applications/editors/josm/plugins/public_transport/build.xml

    r31923 r32357  
    55    <property name="commit.message" value="Commit message"/>
    66    <!-- enter the *lowest* JOSM version this plugin is currently compatible with -->
    7     <property name="plugin.main.version" value="7817"/>
     7    <property name="plugin.main.version" value="10279"/>
    88
    99    <property name="plugin.author" value="Roland M. Olbricht"/>
  • applications/editors/josm/plugins/public_transport/src/public_transport/AStarAlgorithm.java

    r30358 r32357  
    77import java.util.Vector;
    88
    9 public abstract class AStarAlgorithm
    10 {
     9public abstract class AStarAlgorithm {
    1110    // The following abstract functions and subclasses must be overridden by a class using
    1211    // AStarAlgorithm.
    1312
    14     public static abstract class Vertex implements Comparable< Vertex >
    15     {
     13    public static abstract class Vertex implements Comparable<Vertex> {
     14        @Override
    1615        public abstract int compareTo(Vertex v);
    1716    };
    1817
    19     public static abstract class Edge
    20     {
     18    public static abstract class Edge {
    2119        public abstract Vertex getBegin();
     20
    2221        public abstract Vertex getEnd();
    2322
     
    2524    };
    2625
    27     public abstract Vector< Edge > getNeighbors(Vertex vertex);
     26    public abstract Vector<Edge> getNeighbors(Vertex vertex);
    2827
    2928    public abstract double estimateDistance(Vertex vertex);
     
    3130    // end of interface to override -------------------------------------------
    3231
    33     public AStarAlgorithm(Vertex begin, Vertex end)
    34     {
     32    public AStarAlgorithm(Vertex begin, Vertex end) {
    3533        this.begin = begin;
    3634        this.end = end;
    37         openList = new TreeMap< Vertex, Double >();
    38         closedList = new TreeSet< Vertex >();
    39         pathTail = new TreeMap< Vertex, Edge >();
     35        openList = new TreeMap<>();
     36        closedList = new TreeSet<>();
     37        pathTail = new TreeMap<>();
    4038    }
    4139
    42     public Vertex determineCurrentStart()
    43     {
     40    public Vertex determineCurrentStart() {
    4441        Vertex minVertex = null;
    4542        double minDist = 0;
    46         Iterator< Map.Entry< Vertex, Double > > iter = openList.entrySet().iterator();
    47         while (iter.hasNext())
    48         {
    49             Map.Entry< Vertex, Double > entry = iter.next();
     43        Iterator<Map.Entry<Vertex, Double>> iter = openList.entrySet().iterator();
     44        while (iter.hasNext()) {
     45            Map.Entry<Vertex, Double> entry = iter.next();
    5046            double distance = entry.getValue().doubleValue() + estimateDistance(entry.getKey());
    51             if (minVertex == null || distance < minDist)
    52             {
     47            if (minVertex == null || distance < minDist) {
    5348                minDist = distance;
    5449                minVertex = entry.getKey();
    5550            }
    5651        }
    57         if (minVertex != null)
    58         {
     52        if (minVertex != null) {
    5953            System.out.print(openList.get(minVertex).doubleValue());
    6054            System.out.print("\t");
     
    6559    }
    6660
    67     Vector< Edge > shortestPath()
    68     {
     61    Vector<Edge> shortestPath() {
    6962        // Travel through the network
    7063        Vertex currentStart = begin;
    7164        openList.put(currentStart, 0.0);
    72         while (currentStart != null && !currentStart.equals(end))
    73         {
     65        while (currentStart != null && !currentStart.equals(end)) {
    7466            double startDistance = openList.get(currentStart).doubleValue();
    7567
     
    7870            closedList.add(currentStart);
    7971
    80             Iterator< Edge > neighbors = getNeighbors(currentStart).iterator();
    81             while (neighbors.hasNext())
    82             {
     72            Iterator<Edge> neighbors = getNeighbors(currentStart).iterator();
     73            while (neighbors.hasNext()) {
    8374                Edge edge = neighbors.next();
    8475
     
    9182                double distance = startDistance + edge.getLength();
    9283
    93                 if (knownDistance == null || distance < knownDistance.doubleValue())
    94                 {
    95             openList.put(edge.getEnd(), distance);
     84                if (knownDistance == null || distance < knownDistance.doubleValue()) {
     85                    openList.put(edge.getEnd(), distance);
    9686                    pathTail.put(edge.getEnd(), edge);
    9787                }
     
    10595
    10696        // Reconstruct the found path
    107         Vector< Edge > backwards = new Vector< Edge >();
     97        Vector<Edge> backwards = new Vector<>();
    10898        Vertex currentEnd = end;
    109         while (!currentEnd.equals(begin))
    110         {
     99        while (!currentEnd.equals(begin)) {
    111100            backwards.add(pathTail.get(currentEnd));
    112101            currentEnd = pathTail.get(currentEnd).getBegin();
    113102        }
    114103
    115         Vector< Edge > result = new Vector< Edge >();
    116         for (int i = backwards.size()-1; i >= 0; --i)
     104        Vector<Edge> result = new Vector<>();
     105        for (int i = backwards.size() - 1; i >= 0; --i)
    117106            result.add(backwards.elementAt(i));
    118107        return result;
     
    120109
    121110    protected Vertex begin;
     111
    122112    protected Vertex end;
    123113
    124     private TreeSet< Vertex > closedList;
    125     private TreeMap< Vertex, Double > openList;
    126     private TreeMap< Vertex, Edge > pathTail;
    127 };
     114    private TreeSet<Vertex> closedList;
     115
     116    private TreeMap<Vertex, Double> openList;
     117
     118    private TreeMap<Vertex, Edge> pathTail;
     119}
  • applications/editors/josm/plugins/public_transport/src/public_transport/AbstractImporterDialog.java

    r31995 r32357  
    2020public abstract class AbstractImporterDialog<T extends JosmAction> {
    2121
    22     private static final String[] stoptypes = new String[]{marktr("bus"), marktr("tram"), marktr("light_rail"), marktr("subway"), marktr("rail")};
     22    private static final String[] stoptypes = new String[] { marktr("bus"), marktr("tram"),
     23            marktr("light_rail"), marktr("subway"), marktr("rail") };
    2324
    2425    private final JDialog jDialog;
     26
    2527    protected final JTabbedPane tabbedPane;
     28
    2629    protected final JComboBox<TransText> cbStoptype;
    2730
    2831    protected final JTextField tfGPSTimeStart;
     32
    2933    protected final JTextField tfStopwatchStart;
     34
    3035    protected final JTextField tfTimeWindow;
     36
    3137    protected final JTextField tfThreshold;
    3238
     
    3642        tabbedPane = new JTabbedPane();
    3743        jDialog.add(tabbedPane);
    38        
     44
    3945        cbStoptype = new JComboBox<>();
    4046        cbStoptype.setEditable(false);
    41         for(String type : stoptypes)
     47        for (String type : stoptypes)
    4248            cbStoptype.addItem(new TransText(type));
    4349        cbStoptype.setActionCommand(actionPrefix + ".settingsStoptype");
    4450        cbStoptype.addActionListener(controller);
    45        
     51
    4652        tfGPSTimeStart = new JTextField("00:00:00", 15);
    4753        tfGPSTimeStart.setActionCommand(actionPrefix + ".settingsGPSTimeStart");
     
    6167
    6268        initDialog(controller);
    63        
     69
    6470        jDialog.pack();
    6571        jDialog.setLocationRelativeTo(frame);
    6672    }
    67    
     73
    6874    protected abstract void initDialog(T controller);
    69    
    70     public void setTrackValid(boolean valid)
    71     {
    72       tabbedPane.setEnabledAt(2, valid);
     75
     76    public void setTrackValid(boolean valid) {
     77        tabbedPane.setEnabledAt(2, valid);
    7378    }
    7479
    75     public void setVisible(boolean visible)
    76     {
    77       jDialog.setVisible(visible);
     80    public void setVisible(boolean visible) {
     81        jDialog.setVisible(visible);
    7882    }
    7983
    80     public void setSettings
    81         (String gpsSyncTime, String stopwatchStart,
    82          double timeWindow, double threshold)
    83     {
    84       tfGPSTimeStart.setText(gpsSyncTime);
    85       tfStopwatchStart.setText(stopwatchStart);
    86       tfTimeWindow.setText(Double.toString(timeWindow));
    87       tfThreshold.setText(Double.toString(threshold));
     84    public void setSettings(String gpsSyncTime, String stopwatchStart, double timeWindow,
     85            double threshold) {
     86        tfGPSTimeStart.setText(gpsSyncTime);
     87        tfStopwatchStart.setText(stopwatchStart);
     88        tfTimeWindow.setText(Double.toString(timeWindow));
     89        tfThreshold.setText(Double.toString(threshold));
    8890    }
    8991
    90     public String getStoptype()
    91     {
    92       return ((TransText)cbStoptype.getSelectedItem()).text;
     92    public String getStoptype() {
     93        return ((TransText) cbStoptype.getSelectedItem()).text;
    9394    }
    9495
    95     public boolean gpsTimeStartValid()
    96     {
    97       if (parseTime(tfGPSTimeStart.getText()) >= 0)
    98       {
    99         return true;
    100       }
    101       else
    102       {
    103         JOptionPane.showMessageDialog
    104         (null, tr("Can''t parse a time from this string."), tr("Invalid value"),
    105          JOptionPane.ERROR_MESSAGE);
    106         return false;
    107       }
    108     }
    109    
    110     public String getGpsTimeStart()
    111     {
    112       return tfGPSTimeStart.getText();
     96    public boolean gpsTimeStartValid() {
     97        if (parseTime(tfGPSTimeStart.getText()) >= 0) {
     98            return true;
     99        } else {
     100            JOptionPane.showMessageDialog(null, tr("Can''t parse a time from this string."),
     101                    tr("Invalid value"), JOptionPane.ERROR_MESSAGE);
     102            return false;
     103        }
    113104    }
    114105
    115     public void setGpsTimeStart(String s)
    116     {
    117       tfGPSTimeStart.setText(s);
     106    public String getGpsTimeStart() {
     107        return tfGPSTimeStart.getText();
    118108    }
    119109
    120     public boolean stopwatchStartValid()
    121     {
    122       if (parseTime(tfStopwatchStart.getText()) >= 0)
    123       {
    124         return true;
    125       }
    126       else
    127       {
    128         JOptionPane.showMessageDialog
    129         (null, tr("Can''t parse a time from this string."), tr("Invalid value"),
    130          JOptionPane.ERROR_MESSAGE);
    131         return false;
    132       }
     110    public void setGpsTimeStart(String s) {
     111        tfGPSTimeStart.setText(s);
    133112    }
    134113
    135     public String getStopwatchStart()
    136     {
    137       return tfStopwatchStart.getText();
     114    public boolean stopwatchStartValid() {
     115        if (parseTime(tfStopwatchStart.getText()) >= 0) {
     116            return true;
     117        } else {
     118            JOptionPane.showMessageDialog(null, tr("Can''t parse a time from this string."),
     119                    tr("Invalid value"), JOptionPane.ERROR_MESSAGE);
     120            return false;
     121        }
    138122    }
    139123
    140     public void setStopwatchStart(String s)
    141     {
    142       tfStopwatchStart.setText(s);
     124    public String getStopwatchStart() {
     125        return tfStopwatchStart.getText();
    143126    }
    144127
    145     public double getTimeWindow()
    146     {
    147       return Double.parseDouble(tfTimeWindow.getText());
    148     }
    149    
    150     public double getThreshold()
    151     {
    152       return Double.parseDouble(tfThreshold.getText());
     128    public void setStopwatchStart(String s) {
     129        tfStopwatchStart.setText(s);
    153130    }
    154131
    155     public static double parseTime(String s)
    156     {
    157       if ((s.charAt(2) != ':') || (s.charAt(2) != ':')
    158        || (s.length() < 8))
    159         return -1;
    160       int hour = Integer.parseInt(s.substring(0, 2));
    161       int minute = Integer.parseInt(s.substring(3, 5));
    162       double second = Double.parseDouble(s.substring(6, s.length()));
    163       if ((hour < 0) || (hour > 23) || (minute < 0) || (minute > 59)
    164        || (second < 0) || (second >= 60.0))
    165         return -1;
    166       return (second + minute*60 + hour*60*60);
     132    public double getTimeWindow() {
     133        return Double.parseDouble(tfTimeWindow.getText());
     134    }
     135
     136    public double getThreshold() {
     137        return Double.parseDouble(tfThreshold.getText());
     138    }
     139
     140    public static double parseTime(String s) {
     141        if ((s.charAt(2) != ':') || (s.charAt(2) != ':') || (s.length() < 8))
     142            return -1;
     143        int hour = Integer.parseInt(s.substring(0, 2));
     144        int minute = Integer.parseInt(s.substring(3, 5));
     145        double second = Double.parseDouble(s.substring(6, s.length()));
     146        if ((hour < 0) || (hour > 23) || (minute < 0) || (minute > 59) || (second < 0)
     147                || (second >= 60.0))
     148            return -1;
     149        return (second + minute * 60 + hour * 60 * 60);
    167150    }
    168151}
  • applications/editors/josm/plugins/public_transport/src/public_transport/GTFSAddCommand.java

    r29854 r32357  
    1111import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1212
    13 public class GTFSAddCommand extends Command
    14 {
    15   private Vector< Integer > workingLines = null;
    16   private Vector< String > typesForUndo = null;
    17   private GTFSStopTableModel gtfsStopTM = null;
    18   private String type = null;
     13public class GTFSAddCommand extends Command {
     14    private Vector<Integer> workingLines = null;
    1915
    20   public GTFSAddCommand(GTFSImporterAction controller)
    21   {
    22     gtfsStopTM = controller.getGTFSStopTableModel();
    23     type = controller.getDialog().getStoptype();
    24     workingLines = new Vector< Integer >();
    25     typesForUndo = new Vector< String >();
     16    private Vector<String> typesForUndo = null;
    2617
    27     // use either selected lines or all lines if no line is selected
    28     int[] selectedLines = controller.getDialog().getGTFSStopTable().getSelectedRows();
    29     Vector< Integer > consideredLines = new Vector< Integer >();
    30     if (selectedLines.length > 0)
    31     {
    32       for (int i = 0; i < selectedLines.length; ++i)
    33     consideredLines.add(selectedLines[i]);
    34     }
    35     else
    36     {
    37       for (int i = 0; i < gtfsStopTM.getRowCount(); ++i)
    38     consideredLines.add(new Integer(i));
     18    private GTFSStopTableModel gtfsStopTM = null;
     19
     20    private String type = null;
     21
     22    public GTFSAddCommand(GTFSImporterAction controller) {
     23        gtfsStopTM = controller.getGTFSStopTableModel();
     24        type = controller.getDialog().getStoptype();
     25        workingLines = new Vector<>();
     26        typesForUndo = new Vector<>();
     27
     28        // use either selected lines or all lines if no line is selected
     29        int[] selectedLines = controller.getDialog().getGTFSStopTable().getSelectedRows();
     30        Vector<Integer> consideredLines = new Vector<>();
     31        if (selectedLines.length > 0) {
     32            for (int i = 0; i < selectedLines.length; ++i)
     33                consideredLines.add(selectedLines[i]);
     34        } else {
     35            for (int i = 0; i < gtfsStopTM.getRowCount(); ++i)
     36                consideredLines.add(new Integer(i));
     37        }
     38
     39        // keep only lines where a node can be added
     40        for (int i = 0; i < consideredLines.size(); ++i) {
     41            if (gtfsStopTM.nodes.elementAt(consideredLines.elementAt(i)) == null)
     42                workingLines.add(consideredLines.elementAt(i));
     43        }
    3944    }
    4045
    41     // keep only lines where a node can be added
    42     for (int i = 0; i < consideredLines.size(); ++i)
    43     {
    44       if (gtfsStopTM.nodes.elementAt(consideredLines.elementAt(i)) == null)
    45     workingLines.add(consideredLines.elementAt(i));
     46    @Override
     47    public boolean executeCommand() {
     48        typesForUndo.clear();
     49        for (int i = 0; i < workingLines.size(); ++i) {
     50            int j = workingLines.elementAt(i).intValue();
     51            typesForUndo.add((String) gtfsStopTM.getValueAt(j, 2));
     52            Node node = GTFSImporterAction.createNode(gtfsStopTM.coors.elementAt(j),
     53                    (String) gtfsStopTM.getValueAt(j, 0), (String) gtfsStopTM.getValueAt(j, 1));
     54            gtfsStopTM.nodes.set(j, node);
     55            gtfsStopTM.setValueAt(tr("added"), j, 2);
     56        }
     57        return true;
    4658    }
    47   }
    4859
    49   public boolean executeCommand()
    50   {
    51     typesForUndo.clear();
    52     for (int i = 0; i < workingLines.size(); ++i)
    53     {
    54       int j = workingLines.elementAt(i).intValue();
    55       typesForUndo.add((String)gtfsStopTM.getValueAt(j, 2));
    56       Node node = GTFSImporterAction.createNode
    57         (gtfsStopTM.coors.elementAt(j), (String)gtfsStopTM.getValueAt(j, 0),
    58          (String)gtfsStopTM.getValueAt(j, 1));
    59       gtfsStopTM.nodes.set(j, node);
    60       gtfsStopTM.setValueAt(tr("added"), j, 2);
     60    @Override
     61    public void undoCommand() {
     62        for (int i = 0; i < workingLines.size(); ++i) {
     63            int j = workingLines.elementAt(i).intValue();
     64            Node node = gtfsStopTM.nodes.elementAt(j);
     65            gtfsStopTM.nodes.set(j, null);
     66            gtfsStopTM.setValueAt(typesForUndo.elementAt(i), j, 2);
     67            if (node == null)
     68                continue;
     69            Main.getLayerManager().getEditDataSet().removePrimitive(node);
     70            node.setDeleted(true);
     71        }
    6172    }
    62     return true;
    63   }
    6473
    65   public void undoCommand()
    66   {
    67     for (int i = 0; i < workingLines.size(); ++i)
    68     {
    69       int j = workingLines.elementAt(i).intValue();
    70       Node node = gtfsStopTM.nodes.elementAt(j);
    71       gtfsStopTM.nodes.set(j, null);
    72       gtfsStopTM.setValueAt(typesForUndo.elementAt(i), j, 2);
    73       if (node == null)
    74     continue;
    75       Main.main.getCurrentDataSet().removePrimitive(node);
    76       node.setDeleted(true);
     74    @Override
     75    public void fillModifiedData(Collection<OsmPrimitive> modified,
     76            Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
    7777    }
    78   }
    7978
    80   public void fillModifiedData
    81     (Collection< OsmPrimitive > modified, Collection< OsmPrimitive > deleted,
    82      Collection< OsmPrimitive > added)
    83   {
    84   }
    85 
    86   @Override public String getDescriptionText()
    87   {
    88     return tr("Public Transport: Enable GTFSStops");
    89   }
    90 };
     79    @Override
     80    public String getDescriptionText() {
     81        return tr("Public Transport: Enable GTFSStops");
     82    }
     83}
  • applications/editors/josm/plugins/public_transport/src/public_transport/GTFSCatchCommand.java

    r29854 r32357  
    99import org.openstreetmap.josm.Main;
    1010import org.openstreetmap.josm.command.Command;
     11import org.openstreetmap.josm.data.osm.DataSet;
    1112import org.openstreetmap.josm.data.osm.Node;
    1213import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1314
    14 public class GTFSCatchCommand extends Command
    15 {
    16   private Vector< Integer > workingLines = null;
    17   private Node undoMapNode = null;
    18   private Node undoTableNode = null;
    19   private GTFSStopTableModel gtfsStopTM = null;
    20   private String type = null;
     15public class GTFSCatchCommand extends Command {
     16    private Vector<Integer> workingLines = null;
    2117
    22   public GTFSCatchCommand(GTFSImporterAction controller)
    23   {
    24     gtfsStopTM = controller.getGTFSStopTableModel();
    25     workingLines = new Vector< Integer >();
     18    private Node undoMapNode = null;
    2619
    27     // use either selected lines or all lines if no line is selected
    28     int[] selectedLines = controller.getDialog().getGTFSStopTable().getSelectedRows();
    29     if (selectedLines.length != 1)
    30       return;
    31     workingLines.add(selectedLines[0]);
    32   }
     20    private Node undoTableNode = null;
    3321
    34   public boolean executeCommand()
    35   {
    36     if (workingLines.size() != 1)
    37       return false;
    38     Node dest = null;
    39     Iterator< Node > iter =
    40         Main.main.getCurrentDataSet().getSelectedNodes().iterator();
    41     int j = workingLines.elementAt(0);
    42     while (iter.hasNext())
    43     {
    44       Node n = iter.next();
    45       if ((n != null) && (n.equals(gtfsStopTM.nodes.elementAt(j))))
    46     continue;
    47       if (dest != null)
    48     return false;
    49       dest = n;
    50     }
    51     if (dest == null)
    52       return false;
    53     undoMapNode = new Node(dest);
     22    private GTFSStopTableModel gtfsStopTM = null;
    5423
    55     Node node = gtfsStopTM.nodes.elementAt(j);
    56     undoTableNode = node;
    57     if (node != null)
    58     {
    59       Main.main.getCurrentDataSet().removePrimitive(node);
    60       node.setDeleted(true);
     24    private String type = null;
     25
     26    public GTFSCatchCommand(GTFSImporterAction controller) {
     27        gtfsStopTM = controller.getGTFSStopTableModel();
     28        workingLines = new Vector<>();
     29
     30        // use either selected lines or all lines if no line is selected
     31        int[] selectedLines = controller.getDialog().getGTFSStopTable().getSelectedRows();
     32        if (selectedLines.length != 1)
     33            return;
     34        workingLines.add(selectedLines[0]);
    6135    }
    6236
    63     dest.setCoor(gtfsStopTM.coors.elementAt(j));
    64     dest.put("highway", "bus_stop");
    65     dest.put("stop_id", (String)gtfsStopTM.getValueAt(j, 0));
    66     if (dest.get("name") == null)
    67       dest.put("name", (String)gtfsStopTM.getValueAt(j, 1));
    68     dest.put("note", "moved by gtfs import");
    69     gtfsStopTM.nodes.set(j, dest);
    70     type = (String)gtfsStopTM.getValueAt(j, 2);
    71     gtfsStopTM.setValueAt("fed", j, 2);
     37    @Override
     38    public boolean executeCommand() {
     39        if (workingLines.size() != 1)
     40            return false;
     41        Node dest = null;
     42        DataSet ds = Main.getLayerManager().getEditDataSet();
     43        Iterator<Node> iter = ds.getSelectedNodes().iterator();
     44        int j = workingLines.elementAt(0);
     45        while (iter.hasNext()) {
     46            Node n = iter.next();
     47            if ((n != null) && (n.equals(gtfsStopTM.nodes.elementAt(j))))
     48                continue;
     49            if (dest != null)
     50                return false;
     51            dest = n;
     52        }
     53        if (dest == null)
     54            return false;
     55        undoMapNode = new Node(dest);
    7256
    73     return true;
    74   }
     57        Node node = gtfsStopTM.nodes.elementAt(j);
     58        undoTableNode = node;
     59        if (node != null) {
     60            ds.removePrimitive(node);
     61            node.setDeleted(true);
     62        }
    7563
    76   public void undoCommand()
    77   {
    78     if (workingLines.size() != 1)
    79       return;
    80     int j = workingLines.elementAt(0);
     64        dest.setCoor(gtfsStopTM.coors.elementAt(j));
     65        dest.put("highway", "bus_stop");
     66        dest.put("stop_id", (String) gtfsStopTM.getValueAt(j, 0));
     67        if (dest.get("name") == null)
     68            dest.put("name", (String) gtfsStopTM.getValueAt(j, 1));
     69        dest.put("note", "moved by gtfs import");
     70        gtfsStopTM.nodes.set(j, dest);
     71        type = (String) gtfsStopTM.getValueAt(j, 2);
     72        gtfsStopTM.setValueAt("fed", j, 2);
    8173
    82     Node node = gtfsStopTM.nodes.elementAt(j);
    83     if (node != null)
    84     {
    85       Main.main.getCurrentDataSet().removePrimitive(node);
    86       node.setDeleted(true);
     74        return true;
    8775    }
    8876
    89     if (undoMapNode != null)
    90     {
    91       undoMapNode.setDeleted(false);
    92       Main.main.getCurrentDataSet().addPrimitive(undoMapNode);
     77    @Override
     78    public void undoCommand() {
     79        if (workingLines.size() != 1)
     80            return;
     81        int j = workingLines.elementAt(0);
     82
     83        DataSet ds = Main.getLayerManager().getEditDataSet();
     84        Node node = gtfsStopTM.nodes.elementAt(j);
     85        if (node != null) {
     86            ds.removePrimitive(node);
     87            node.setDeleted(true);
     88        }
     89
     90        if (undoMapNode != null) {
     91            undoMapNode.setDeleted(false);
     92            ds.addPrimitive(undoMapNode);
     93        }
     94        if (undoTableNode != null) {
     95            undoTableNode.setDeleted(false);
     96            ds.addPrimitive(undoTableNode);
     97        }
     98        gtfsStopTM.nodes.set(j, undoTableNode);
     99        gtfsStopTM.setValueAt(type, j, 2);
    93100    }
    94     if (undoTableNode != null)
    95     {
    96       undoTableNode.setDeleted(false);
    97       Main.main.getCurrentDataSet().addPrimitive(undoTableNode);
     101
     102    @Override
     103    public void fillModifiedData(Collection<OsmPrimitive> modified,
     104            Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
    98105    }
    99     gtfsStopTM.nodes.set(j, undoTableNode);
    100     gtfsStopTM.setValueAt(type, j, 2);
    101   }
    102106
    103   public void fillModifiedData
    104     (Collection< OsmPrimitive > modified, Collection< OsmPrimitive > deleted,
    105      Collection< OsmPrimitive > added)
    106   {
    107   }
    108 
    109   @Override public String getDescriptionText()
    110   {
    111     return tr("Public Transport: Catch GTFS stops");
    112   }
    113 };
     107    @Override
     108    public String getDescriptionText() {
     109        return tr("Public Transport: Catch GTFS stops");
     110    }
     111}
  • applications/editors/josm/plugins/public_transport/src/public_transport/GTFSDeleteCommand.java

    r29854 r32357  
    1111import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1212
    13 public class GTFSDeleteCommand extends Command
    14 {
    15   private Vector< Integer > workingLines = null;
    16   private Vector< Node > nodesForUndo = null;
    17   private Vector< String > typesForUndo = null;
    18   private GTFSStopTableModel gtfsStopTM = null;
     13public class GTFSDeleteCommand extends Command {
     14    private Vector<Integer> workingLines = null;
    1915
    20   public GTFSDeleteCommand(GTFSImporterAction controller)
    21   {
    22     gtfsStopTM = controller.getGTFSStopTableModel();
    23     workingLines = new Vector< Integer >();
    24     nodesForUndo = new Vector< Node >();
    25     typesForUndo = new Vector< String >();
     16    private Vector<Node> nodesForUndo = null;
    2617
    27     // use either selected lines or all lines if no line is selected
    28     int[] selectedLines = controller.getDialog().getGTFSStopTable().getSelectedRows();
    29     Vector< Integer > consideredLines = new Vector< Integer >();
    30     if (selectedLines.length > 0)
    31     {
    32       for (int i = 0; i < selectedLines.length; ++i)
    33     consideredLines.add(selectedLines[i]);
    34     }
    35     else
    36     {
    37       for (int i = 0; i < gtfsStopTM.getRowCount(); ++i)
    38     consideredLines.add(new Integer(i));
     18    private Vector<String> typesForUndo = null;
     19
     20    private GTFSStopTableModel gtfsStopTM = null;
     21
     22    public GTFSDeleteCommand(GTFSImporterAction controller) {
     23        gtfsStopTM = controller.getGTFSStopTableModel();
     24        workingLines = new Vector<>();
     25        nodesForUndo = new Vector<>();
     26        typesForUndo = new Vector<>();
     27
     28        // use either selected lines or all lines if no line is selected
     29        int[] selectedLines = controller.getDialog().getGTFSStopTable().getSelectedRows();
     30        Vector<Integer> consideredLines = new Vector<>();
     31        if (selectedLines.length > 0) {
     32            for (int i = 0; i < selectedLines.length; ++i)
     33                consideredLines.add(selectedLines[i]);
     34        } else {
     35            for (int i = 0; i < gtfsStopTM.getRowCount(); ++i)
     36                consideredLines.add(new Integer(i));
     37        }
     38
     39        // keep only lines where a node can be added
     40        for (int i = 0; i < consideredLines.size(); ++i) {
     41            if (gtfsStopTM.nodes.elementAt(consideredLines.elementAt(i)) != null)
     42                workingLines.add(consideredLines.elementAt(i));
     43        }
    3944    }
    4045
    41     // keep only lines where a node can be added
    42     for (int i = 0; i < consideredLines.size(); ++i)
    43     {
    44       if (gtfsStopTM.nodes.elementAt(consideredLines.elementAt(i)) != null)
    45     workingLines.add(consideredLines.elementAt(i));
     46    @Override
     47    public boolean executeCommand() {
     48        nodesForUndo.clear();
     49        typesForUndo.clear();
     50        for (int i = 0; i < workingLines.size(); ++i) {
     51            int j = workingLines.elementAt(i).intValue();
     52            Node node = gtfsStopTM.nodes.elementAt(j);
     53            nodesForUndo.add(node);
     54            typesForUndo.add((String) gtfsStopTM.getValueAt(j, 2));
     55            if (node == null)
     56                continue;
     57            gtfsStopTM.nodes.set(j, null);
     58            gtfsStopTM.setValueAt(tr("skipped"), j, 2);
     59            Main.getLayerManager().getEditDataSet().removePrimitive(node);
     60            node.setDeleted(true);
     61        }
     62        return true;
    4663    }
    47   }
    4864
    49   public boolean executeCommand()
    50   {
    51     nodesForUndo.clear();
    52     typesForUndo.clear();
    53     for (int i = 0; i < workingLines.size(); ++i)
    54     {
    55       int j = workingLines.elementAt(i).intValue();
    56       Node node = gtfsStopTM.nodes.elementAt(j);
    57       nodesForUndo.add(node);
    58       typesForUndo.add((String)gtfsStopTM.getValueAt(j, 2));
    59       if (node == null)
    60     continue;
    61       gtfsStopTM.nodes.set(j, null);
    62       gtfsStopTM.setValueAt(tr("skipped"), j, 2);
    63       Main.main.getCurrentDataSet().removePrimitive(node);
    64       node.setDeleted(true);
     65    @Override
     66    public void undoCommand() {
     67        for (int i = 0; i < workingLines.size(); ++i) {
     68            int j = workingLines.elementAt(i).intValue();
     69            Node node = nodesForUndo.elementAt(i);
     70            gtfsStopTM.nodes.set(j, node);
     71            gtfsStopTM.setValueAt(typesForUndo.elementAt(i), j, 2);
     72            if (node == null)
     73                continue;
     74            node.setDeleted(false);
     75            Main.getLayerManager().getEditDataSet().addPrimitive(node);
     76        }
    6577    }
    66     return true;
    67   }
    6878
    69   public void undoCommand()
    70   {
    71     for (int i = 0; i < workingLines.size(); ++i)
    72     {
    73       int j = workingLines.elementAt(i).intValue();
    74       Node node = nodesForUndo.elementAt(i);
    75       gtfsStopTM.nodes.set(j, node);
    76       gtfsStopTM.setValueAt(typesForUndo.elementAt(i), j, 2);
    77       if (node == null)
    78     continue;
    79       node.setDeleted(false);
    80       Main.main.getCurrentDataSet().addPrimitive(node);
     79    @Override
     80    public void fillModifiedData(Collection<OsmPrimitive> modified,
     81            Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
    8182    }
    82   }
    8383
    84   public void fillModifiedData
    85     (Collection< OsmPrimitive > modified, Collection< OsmPrimitive > deleted,
    86      Collection< OsmPrimitive > added)
    87   {
    88   }
    89 
    90   @Override public String getDescriptionText()
    91   {
    92     return tr("Public Transport: Disable GTFS");
    93   }
    94 };
     84    @Override
     85    public String getDescriptionText() {
     86        return tr("Public Transport: Disable GTFS");
     87    }
     88}
  • applications/editors/josm/plugins/public_transport/src/public_transport/GTFSImporterAction.java

    r31114 r32357  
    2424import org.openstreetmap.josm.actions.JosmAction;
    2525import org.openstreetmap.josm.data.coor.LatLon;
     26import org.openstreetmap.josm.data.osm.DataSet;
    2627import org.openstreetmap.josm.data.osm.Node;
    2728import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2829import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
    2930
    30 public class GTFSImporterAction extends JosmAction
    31 {
    32   private static GTFSImporterDialog dialog = null;
    33   private static DefaultListModel tracksListModel = null;
    34   private static Vector< String > data = null;
    35   private static TrackReference currentTrack = null;
    36   private static GTFSStopTableModel gtfsStopTM = null;
    37   public boolean inEvent = false;
    38 
    39   public GTFSImporterAction()
    40   {
    41     super(tr("Create Stops from GTFS ..."), null,
    42       tr("Create Stops from a GTFS file"), null, false);
    43       putValue("toolbar", "publictransport/gtfsimporter");
    44       Main.toolbar.register(this);
    45   }
    46 
    47   public GTFSStopTableModel getGTFSStopTableModel()
    48   {
    49     return gtfsStopTM;
    50   }
    51 
    52   public GTFSImporterDialog getDialog()
    53   {
    54     return dialog;
    55   }
    56 
    57   public DefaultListModel getTracksListModel()
    58   {
    59     if (tracksListModel == null)
    60       tracksListModel = new DefaultListModel();
    61     return tracksListModel;
    62   }
    63 
    64   public TrackReference getCurrentTrack()
    65   {
    66     return currentTrack;
    67   }
    68 
    69   @Override
    70 public void actionPerformed(ActionEvent event) {
    71 
    72     if (dialog == null)
    73       dialog = new GTFSImporterDialog(this);
    74 
    75     dialog.setVisible(true);
    76 
    77     if (tr("Create Stops from GTFS ...").equals(event.getActionCommand()))
    78     {
    79       String curDir = Main.pref.get("lastDirectory");
    80       if (curDir.equals(""))
    81       {
    82         curDir = ".";
    83       }
    84       JFileChooser fc = new JFileChooser(new File(curDir));
    85       fc.setDialogTitle(tr("Select GTFS file (stops.txt)"));
    86       fc.setMultiSelectionEnabled(false);
    87 
    88       int answer = fc.showOpenDialog(Main.parent);
    89       if (answer != JFileChooser.APPROVE_OPTION)
    90         return;
    91 
    92       if (!fc.getCurrentDirectory().getAbsolutePath().equals(curDir))
    93         Main.pref.put("lastDirectory", fc.getCurrentDirectory().getAbsolutePath());
    94 
    95       importData(fc.getSelectedFile());
    96 
    97       refreshData();
    98     }
     31public class GTFSImporterAction extends JosmAction {
     32    private static GTFSImporterDialog dialog = null;
     33
     34    private static DefaultListModel<?> tracksListModel = null;
     35
     36    private static Vector<String> data = null;
     37
     38    private static TrackReference currentTrack = null;
     39
     40    private static GTFSStopTableModel gtfsStopTM = null;
     41
     42    public boolean inEvent = false;
     43
     44    /**
     45     * Constructs a new {@code GTFSImporterAction}.
     46     */
     47    public GTFSImporterAction() {
     48        super(tr("Create Stops from GTFS ..."), null, tr("Create Stops from a GTFS file"), null,
     49                false);
     50        putValue("toolbar", "publictransport/gtfsimporter");
     51        Main.toolbar.register(this);
     52    }
     53
     54    public GTFSStopTableModel getGTFSStopTableModel() {
     55        return gtfsStopTM;
     56    }
     57
     58    public GTFSImporterDialog getDialog() {
     59        return dialog;
     60    }
     61
     62    public DefaultListModel<?> getTracksListModel() {
     63        if (tracksListModel == null)
     64            tracksListModel = new DefaultListModel<>();
     65        return tracksListModel;
     66    }
     67
     68    public TrackReference getCurrentTrack() {
     69        return currentTrack;
     70    }
     71
     72    @Override
     73    public void actionPerformed(ActionEvent event) {
     74
     75        if (dialog == null)
     76            dialog = new GTFSImporterDialog(this);
     77
     78        dialog.setVisible(true);
     79
     80        if (tr("Create Stops from GTFS ...").equals(event.getActionCommand())) {
     81            String curDir = Main.pref.get("lastDirectory");
     82            if (curDir.isEmpty()) {
     83                curDir = ".";
     84            }
     85            JFileChooser fc = new JFileChooser(new File(curDir));
     86            fc.setDialogTitle(tr("Select GTFS file (stops.txt)"));
     87            fc.setMultiSelectionEnabled(false);
     88
     89            int answer = fc.showOpenDialog(Main.parent);
     90            if (answer != JFileChooser.APPROVE_OPTION)
     91                return;
     92
     93            if (!fc.getCurrentDirectory().getAbsolutePath().equals(curDir))
     94                Main.pref.put("lastDirectory", fc.getCurrentDirectory().getAbsolutePath());
     95
     96            importData(fc.getSelectedFile());
     97
     98            refreshData();
     99        }
    99100/*    else if ("stopImporter.settingsGPSTimeStart".equals(event.getActionCommand()))
    100101    {
     
    130131      dialog.getStoplistTable().clearSelection();
    131132    }*/
    132     else if ("gtfsImporter.gtfsStopsAdd".equals(event.getActionCommand()))
    133       Main.main.undoRedo.add(new GTFSAddCommand(this));
    134     else if ("gtfsImporter.gtfsStopsDelete".equals(event.getActionCommand()))
    135       Main.main.undoRedo.add(new GTFSDeleteCommand(this));
    136     else if ("gtfsImporter.gtfsStopsCatch".equals(event.getActionCommand()))
    137       Main.main.undoRedo.add(new GTFSCatchCommand(this));
    138     else if ("gtfsImporter.gtfsStopsJoin".equals(event.getActionCommand()))
    139       Main.main.undoRedo.add(new GTFSJoinCommand(this));
    140     else if ("gtfsImporter.gtfsStopsFind".equals(event.getActionCommand()))
    141       findNodesInTable(dialog.getGTFSStopTable(), gtfsStopTM.nodes);
    142     else if ("gtfsImporter.gtfsStopsShow".equals(event.getActionCommand()))
    143       showNodesFromTable(dialog.getGTFSStopTable(), gtfsStopTM.nodes);
    144     else if ("gtfsImporter.gtfsStopsMark".equals(event.getActionCommand()))
    145       markNodesFromTable(dialog.getGTFSStopTable(), gtfsStopTM.nodes);
    146   }
    147 
    148   private void importData(final File file)
    149   {
    150     try
    151     {
    152       FileReader is = new FileReader(file);
    153       final BufferedReader r = new BufferedReader(is);
    154 
    155       if (data == null)
    156     data = new Vector< String >();
    157       else
    158     data.clear();
    159 
    160       while (r.ready())
    161     data.add(r.readLine());
    162     }
    163     catch (FileNotFoundException e)
    164     {
    165       e.printStackTrace();
    166       JOptionPane.showMessageDialog(null, tr("File \"{0}\" does not exist", file.getName()));
    167     }
    168     catch (IOException e)
    169     {
    170       e.printStackTrace();
    171       JOptionPane.showMessageDialog(null, tr("IOException \"{0}\" occurred", e.toString()));
    172     }
    173   }
    174 
    175   private void refreshData()
    176   {
    177     if (data != null)
    178     {
    179       Vector< Node > existingStops = new Vector< Node >();
    180 
    181       if (Main.main.getCurrentDataSet() == null)
    182       {
    183         JOptionPane.showMessageDialog(null, tr("There exists no dataset."
    184         + " Try to download data from the server or open an OSM file."),
    185         tr("No data found"), JOptionPane.ERROR_MESSAGE);
    186 
    187         return;
    188       }
    189       else
    190       {
    191         Iterator< Node > iter =
    192         Main.main.getCurrentDataSet().getNodes().iterator();
    193         while (iter.hasNext())
    194         {
    195           Node node = iter.next();
    196           if ("bus_stop".equals(node.get("highway")))
    197             existingStops.add(node);
    198         }
    199       }
    200 
    201       Iterator< String > iter = data.iterator();
    202       if (iter.hasNext())
    203         gtfsStopTM = new GTFSStopTableModel(this, iter.next());
    204       else
    205       {
    206         JOptionPane.showMessageDialog
    207         (null, tr("The GTFS file was empty."), tr("No data found"),
    208         JOptionPane.ERROR_MESSAGE);
    209 
    210         return;
    211       }
    212 
    213       while (iter.hasNext())
    214       {
    215         String s = iter.next();
    216         gtfsStopTM.addRow(s, existingStops);
    217       }
    218       dialog.setGTFSStopTableModel(gtfsStopTM);
    219     }
    220     else
    221     {
    222       JOptionPane.showMessageDialog
    223       (null, tr("The GTFS file was empty."), tr("No data found"),
    224        JOptionPane.ERROR_MESSAGE);
    225     }
    226   }
     133        else if ("gtfsImporter.gtfsStopsAdd".equals(event.getActionCommand()))
     134            Main.main.undoRedo.add(new GTFSAddCommand(this));
     135        else if ("gtfsImporter.gtfsStopsDelete".equals(event.getActionCommand()))
     136            Main.main.undoRedo.add(new GTFSDeleteCommand(this));
     137        else if ("gtfsImporter.gtfsStopsCatch".equals(event.getActionCommand()))
     138            Main.main.undoRedo.add(new GTFSCatchCommand(this));
     139        else if ("gtfsImporter.gtfsStopsJoin".equals(event.getActionCommand()))
     140            Main.main.undoRedo.add(new GTFSJoinCommand(this));
     141        else if ("gtfsImporter.gtfsStopsFind".equals(event.getActionCommand()))
     142            findNodesInTable(dialog.getGTFSStopTable(), gtfsStopTM.nodes);
     143        else if ("gtfsImporter.gtfsStopsShow".equals(event.getActionCommand()))
     144            showNodesFromTable(dialog.getGTFSStopTable(), gtfsStopTM.nodes);
     145        else if ("gtfsImporter.gtfsStopsMark".equals(event.getActionCommand()))
     146            markNodesFromTable(dialog.getGTFSStopTable(), gtfsStopTM.nodes);
     147    }
     148
     149    private void importData(final File file) {
     150        try {
     151            FileReader is = new FileReader(file);
     152            final BufferedReader r = new BufferedReader(is);
     153
     154            if (data == null)
     155                data = new Vector<>();
     156            else
     157                data.clear();
     158
     159            while (r.ready())
     160                data.add(r.readLine());
     161        } catch (FileNotFoundException e) {
     162            Main.error(e);
     163            JOptionPane.showMessageDialog(null, tr("File \"{0}\" does not exist", file.getName()));
     164        } catch (IOException e) {
     165            Main.error(e);
     166            JOptionPane.showMessageDialog(null, tr("IOException \"{0}\" occurred", e.toString()));
     167        }
     168    }
     169
     170    private void refreshData() {
     171        if (data != null) {
     172            Vector<Node> existingStops = new Vector<>();
     173
     174            DataSet ds = Main.getLayerManager().getEditDataSet();
     175            if (ds == null) {
     176                JOptionPane.showMessageDialog(null,
     177                        tr("There exists no dataset. Try to download data from the server or open an OSM file."),
     178                        tr("No data found"), JOptionPane.ERROR_MESSAGE);
     179
     180                return;
     181            } else {
     182                Iterator<Node> iter = ds.getNodes().iterator();
     183                while (iter.hasNext()) {
     184                    Node node = iter.next();
     185                    if ("bus_stop".equals(node.get("highway")))
     186                        existingStops.add(node);
     187                }
     188            }
     189
     190            Iterator<String> iter = data.iterator();
     191            if (iter.hasNext())
     192                gtfsStopTM = new GTFSStopTableModel(this, iter.next());
     193            else {
     194                JOptionPane.showMessageDialog(null, tr("The GTFS file was empty."),
     195                        tr("No data found"), JOptionPane.ERROR_MESSAGE);
     196                return;
     197            }
     198
     199            while (iter.hasNext()) {
     200                String s = iter.next();
     201                gtfsStopTM.addRow(s, existingStops);
     202            }
     203            dialog.setGTFSStopTableModel(gtfsStopTM);
     204        } else {
     205            JOptionPane.showMessageDialog(null, tr("The GTFS file was empty."), tr("No data found"),
     206                    JOptionPane.ERROR_MESSAGE);
     207        }
     208    }
    227209
    228210//   public void tracksSelectionChanged(int selectedPos)
     
    249231//   }
    250232
    251   public static Node createNode(LatLon latLon, String id, String name)
    252   {
    253     Node node = new Node(latLon);
    254     node.put("highway", "bus_stop");
    255     node.put("stop_id", id);
    256     node.put("name", name);
    257     if (Main.main.getCurrentDataSet() == null)
    258     {
    259       JOptionPane.showMessageDialog(null, tr("There exists no dataset."
    260       + " Try to download data from the server or open an OSM file."),
    261       tr("No data found"), JOptionPane.ERROR_MESSAGE);
    262 
    263       return null;
    264     }
    265     Main.main.getCurrentDataSet().addPrimitive(node);
    266     return node;
    267   }
    268 
    269   /* returns a collection of all selected lines or
    270      a collection of all lines otherwise */
    271   public static Vector< Integer > getConsideredLines(JTable table)
    272   {
    273     int[] selectedLines = table.getSelectedRows();
    274     Vector< Integer > consideredLines = new Vector< Integer >();
    275     if (selectedLines.length > 0)
    276     {
    277       for (int i = 0; i < selectedLines.length; ++i)
    278         consideredLines.add(selectedLines[i]);
    279     }
    280     else
    281     {
    282       for (int i = 0; i < table.getRowCount(); ++i)
    283         consideredLines.add(new Integer(i));
    284     }
    285     return consideredLines;
    286   }
    287 
    288   /* marks the table items whose nodes are marked on the map */
    289   public static void findNodesInTable(JTable table, Vector< Node > nodes)
    290   {
    291     if (Main.main.getCurrentDataSet() == null)
    292       return;
    293 
    294     table.clearSelection();
    295 
    296     for (int i = 0; i < table.getRowCount(); ++i)
    297     {
    298       if ((nodes.elementAt(i) != null) &&
    299       (Main.main.getCurrentDataSet().isSelected(nodes.elementAt(i))))
    300         table.addRowSelectionInterval(i, i);
    301     }
    302   }
    303 
    304   /* shows the nodes that correspond to the marked lines in the table.
    305      If no lines are marked in the table, show all nodes from the vector */
    306   public static void showNodesFromTable(JTable table, Vector< Node > nodes)
    307   {
    308     BoundingXYVisitor box = new BoundingXYVisitor();
    309     Vector< Integer > consideredLines = getConsideredLines(table);
    310     for (int i = 0; i < consideredLines.size(); ++i)
    311     {
    312       int j = consideredLines.elementAt(i);
    313       if (nodes.elementAt(j) != null)
    314         nodes.elementAt(j).accept(box);
    315     }
    316     if (box.getBounds() == null)
    317       return;
    318     box.enlargeBoundingBox();
    319     Main.map.mapView.zoomTo(box);
    320   }
    321 
    322   /* marks the nodes that correspond to the marked lines in the table.
    323   If no lines are marked in the table, mark all nodes from the vector */
    324   public static void markNodesFromTable(JTable table, Vector< Node > nodes)
    325   {
    326     OsmPrimitive[] osmp = { null };
    327     Main.main.getCurrentDataSet().setSelected(osmp);
    328     Vector< Integer > consideredLines = getConsideredLines(table);
    329     for (int i = 0; i < consideredLines.size(); ++i)
    330     {
    331       int j = consideredLines.elementAt(i);
    332       if (nodes.elementAt(j) != null)
    333         Main.main.getCurrentDataSet().addSelected(nodes.elementAt(j));
    334     }
    335   }
    336 
    337   public static String timeOf(double t)
    338   {
    339     t -= Math.floor(t/24/60/60)*24*60*60;
    340 
    341     int hour = (int)Math.floor(t/60/60);
    342     t -=  Math.floor(t/60/60)*60*60;
    343     int minute = (int)Math.floor(t/60);
    344     t -=  Math.floor(t/60)*60;
    345     double second = t;
    346 
    347     Format format = new DecimalFormat("00");
    348     Format formatS = new DecimalFormat("00.###");
    349     return (format.format(hour) + ":" + format.format(minute) + ":"
    350     + formatS.format(second));
    351   }
    352 
    353   public Action getFocusAddAction()
    354   {
    355     return new FocusAddAction();
    356   }
    357 
    358   private class FocusAddAction extends AbstractAction
    359   {
    360     @Override
    361     public void actionPerformed(ActionEvent e)
    362     {
    363       Main.main.undoRedo.add(new GTFSAddCommand(GTFSImporterAction.this));
    364       showNodesFromTable(dialog.getGTFSStopTable(), gtfsStopTM.nodes);
    365     }
    366   };
     233    public static Node createNode(LatLon latLon, String id, String name) {
     234        Node node = new Node(latLon);
     235        node.put("highway", "bus_stop");
     236        node.put("stop_id", id);
     237        node.put("name", name);
     238        DataSet ds = Main.getLayerManager().getEditDataSet();
     239        if (ds == null) {
     240            JOptionPane.showMessageDialog(null,
     241                    tr("There exists no dataset."
     242                            + " Try to download data from the server or open an OSM file."),
     243                    tr("No data found"), JOptionPane.ERROR_MESSAGE);
     244
     245            return null;
     246        }
     247        ds.addPrimitive(node);
     248        return node;
     249    }
     250
     251    /**
     252     * returns a collection of all selected lines or a collection of all lines otherwise
     253     */
     254    public static Vector<Integer> getConsideredLines(JTable table) {
     255        int[] selectedLines = table.getSelectedRows();
     256        Vector<Integer> consideredLines = new Vector<>();
     257        if (selectedLines.length > 0) {
     258            for (int i = 0; i < selectedLines.length; ++i)
     259                consideredLines.add(selectedLines[i]);
     260        } else {
     261            for (int i = 0; i < table.getRowCount(); ++i)
     262                consideredLines.add(new Integer(i));
     263        }
     264        return consideredLines;
     265    }
     266
     267    /** marks the table items whose nodes are marked on the map */
     268    public static void findNodesInTable(JTable table, Vector<Node> nodes) {
     269        DataSet ds = Main.getLayerManager().getEditDataSet();
     270        if (ds == null)
     271            return;
     272
     273        table.clearSelection();
     274
     275        for (int i = 0; i < table.getRowCount(); ++i) {
     276            if ((nodes.elementAt(i) != null) && (ds.isSelected(nodes.elementAt(i))))
     277                table.addRowSelectionInterval(i, i);
     278        }
     279    }
     280
     281    /**
     282     * shows the nodes that correspond to the marked lines in the table.
     283     * If no lines are marked in the table, show all nodes from the vector
     284     */
     285    public static void showNodesFromTable(JTable table, Vector<Node> nodes) {
     286        BoundingXYVisitor box = new BoundingXYVisitor();
     287        Vector<Integer> consideredLines = getConsideredLines(table);
     288        for (int i = 0; i < consideredLines.size(); ++i) {
     289            int j = consideredLines.elementAt(i);
     290            if (nodes.elementAt(j) != null)
     291                nodes.elementAt(j).accept(box);
     292        }
     293        if (box.getBounds() == null)
     294            return;
     295        box.enlargeBoundingBox();
     296        Main.map.mapView.zoomTo(box);
     297    }
     298
     299    /**
     300     * marks the nodes that correspond to the marked lines in the table.
     301     * If no lines are marked in the table, mark all nodes from the vector
     302     */
     303    public static void markNodesFromTable(JTable table, Vector<Node> nodes) {
     304        OsmPrimitive[] osmp = { null };
     305        DataSet ds = Main.getLayerManager().getEditDataSet();
     306        ds.setSelected(osmp);
     307        Vector<Integer> consideredLines = getConsideredLines(table);
     308        for (int i = 0; i < consideredLines.size(); ++i) {
     309            int j = consideredLines.elementAt(i);
     310            if (nodes.elementAt(j) != null)
     311                ds.addSelected(nodes.elementAt(j));
     312        }
     313    }
     314
     315    public static String timeOf(double t) {
     316        t -= Math.floor(t / 24 / 60 / 60) * 24 * 60 * 60;
     317
     318        int hour = (int) Math.floor(t / 60 / 60);
     319        t -= Math.floor(t / 60 / 60) * 60 * 60;
     320        int minute = (int) Math.floor(t / 60);
     321        t -= Math.floor(t / 60) * 60;
     322        double second = t;
     323
     324        Format format = new DecimalFormat("00");
     325        Format formatS = new DecimalFormat("00.###");
     326        return format.format(hour) + ":" + format.format(minute) + ":" + formatS.format(second);
     327    }
     328
     329    public Action getFocusAddAction() {
     330        return new FocusAddAction();
     331    }
     332
     333    private class FocusAddAction extends AbstractAction {
     334        @Override
     335        public void actionPerformed(ActionEvent e) {
     336            Main.main.undoRedo.add(new GTFSAddCommand(GTFSImporterAction.this));
     337            showNodesFromTable(dialog.getGTFSStopTable(), gtfsStopTM.nodes);
     338        }
     339    }
    367340
    368341/*  public Action getFocusWaypointShelterAction(String shelter)
  • applications/editors/josm/plugins/public_transport/src/public_transport/GTFSImporterDialog.java

    r31995 r32357  
    1414import javax.swing.KeyStroke;
    1515
    16 public class GTFSImporterDialog extends AbstractImporterDialog<GTFSImporterAction>
    17 {
    18   private JTable gtfsStopTable = null;
    19 
    20   public GTFSImporterDialog(GTFSImporterAction controller)
    21   {
    22       super(controller, tr("Create Stops from GTFS"), "gtfsImporter");
    23   }
    24  
    25   @Override
    26   protected void initDialog(GTFSImporterAction controller) {
    27     JPanel tabSettings = new JPanel();
    28     tabbedPane.addTab(tr("Settings"), tabSettings);
    29     JPanel tabWaypoints = new JPanel();
    30     tabbedPane.addTab(tr("GTFS-Stops"), tabWaypoints);
    31     tabbedPane.setEnabledAt(0, false);
    32     tabbedPane.setEnabledAt(1, true);
    33 
    34     //Settings Tab
    35     JPanel contentPane = tabSettings;
    36     GridBagLayout gridbag = new GridBagLayout();
    37     GridBagConstraints layoutCons = new GridBagConstraints();
    38     contentPane.setLayout(gridbag);
    39 
    40     JLabel label = new JLabel(tr("Type of stops to add"));
    41 
    42     layoutCons.gridx = 0;
    43     layoutCons.gridy = 0;
    44     layoutCons.gridwidth = 2;
    45     layoutCons.weightx = 0.0;
    46     layoutCons.weighty = 0.0;
    47     layoutCons.fill = GridBagConstraints.BOTH;
    48     gridbag.setConstraints(label, layoutCons);
    49     contentPane.add(label);
    50 
    51     layoutCons.gridx = 0;
    52     layoutCons.gridy = 1;
    53     layoutCons.gridwidth = 1;
    54     layoutCons.weightx = 0.0;
    55     layoutCons.weighty = 0.0;
    56     layoutCons.fill = GridBagConstraints.BOTH;
    57     gridbag.setConstraints(cbStoptype, layoutCons);
    58     contentPane.add(cbStoptype);
    59 
    60     label = new JLabel(tr("Time on your GPS device"));
    61 
    62     layoutCons.gridx = 0;
    63     layoutCons.gridy = 2;
    64     layoutCons.gridwidth = 2;
    65     layoutCons.weightx = 0.0;
    66     layoutCons.weighty = 0.0;
    67     layoutCons.fill = GridBagConstraints.BOTH;
    68     gridbag.setConstraints(label, layoutCons);
    69     contentPane.add(label);
    70 
    71     layoutCons.gridx = 0;
    72     layoutCons.gridy = 3;
    73     layoutCons.gridwidth = 1;
    74     layoutCons.weightx = 0.0;
    75     layoutCons.weighty = 0.0;
    76     layoutCons.fill = GridBagConstraints.BOTH;
    77     gridbag.setConstraints(tfGPSTimeStart, layoutCons);
    78     contentPane.add(tfGPSTimeStart);
    79 
    80     /* I18n: Don't change the time format, you only may translate the letters */
    81     label = new JLabel(tr("HH:MM:SS.sss"));
    82 
    83     layoutCons.gridx = 1;
    84     layoutCons.gridy = 3;
    85     layoutCons.gridwidth = 1;
    86     layoutCons.weightx = 0.0;
    87     layoutCons.weighty = 0.0;
    88     layoutCons.fill = GridBagConstraints.BOTH;
    89     gridbag.setConstraints(label, layoutCons);
    90     contentPane.add(label);
    91 
    92     label = new JLabel(tr("Time on your stopwatch"));
    93 
    94     layoutCons.gridx = 0;
    95     layoutCons.gridy = 4;
    96     layoutCons.gridwidth = 2;
    97     layoutCons.weightx = 0.0;
    98     layoutCons.weighty = 0.0;
    99     layoutCons.fill = GridBagConstraints.BOTH;
    100     gridbag.setConstraints(label, layoutCons);
    101     contentPane.add(label);
    102 
    103     layoutCons.gridx = 0;
    104     layoutCons.gridy = 5;
    105     layoutCons.gridwidth = 1;
    106     layoutCons.weightx = 0.0;
    107     layoutCons.weighty = 0.0;
    108     layoutCons.fill = GridBagConstraints.BOTH;
    109     gridbag.setConstraints(tfStopwatchStart, layoutCons);
    110     contentPane.add(tfStopwatchStart);
    111 
    112     /* I18n: Don't change the time format, you only may translate the letters */
    113     label = new JLabel(tr("HH:MM:SS.sss"));
    114 
    115     layoutCons.gridx = 1;
    116     layoutCons.gridy = 5;
    117     layoutCons.gridwidth = 1;
    118     layoutCons.weightx = 0.0;
    119     layoutCons.weighty = 0.0;
    120     layoutCons.fill = GridBagConstraints.BOTH;
    121     gridbag.setConstraints(label, layoutCons);
    122     contentPane.add(label);
    123 
    124     label = new JLabel(tr("Time window"));
    125 
    126     layoutCons.gridx = 0;
    127     layoutCons.gridy = 6;
    128     layoutCons.gridwidth = 2;
    129     layoutCons.weightx = 0.0;
    130     layoutCons.weighty = 0.0;
    131     layoutCons.fill = GridBagConstraints.BOTH;
    132     gridbag.setConstraints(label, layoutCons);
    133     contentPane.add(label);
    134 
    135     layoutCons.gridx = 0;
    136     layoutCons.gridy = 7;
    137     layoutCons.gridwidth = 1;
    138     layoutCons.weightx = 0.0;
    139     layoutCons.weighty = 0.0;
    140     layoutCons.fill = GridBagConstraints.BOTH;
    141     gridbag.setConstraints(tfTimeWindow, layoutCons);
    142     contentPane.add(tfTimeWindow);
    143 
    144     label = new JLabel(tr("seconds"));
    145 
    146     layoutCons.gridx = 1;
    147     layoutCons.gridy = 7;
    148     layoutCons.gridwidth = 1;
    149     layoutCons.weightx = 0.0;
    150     layoutCons.weighty = 0.0;
    151     layoutCons.fill = GridBagConstraints.BOTH;
    152     gridbag.setConstraints(label, layoutCons);
    153     contentPane.add(label);
    154 
    155     label = new JLabel(tr("Move Threshold"));
    156 
    157     layoutCons.gridx = 0;
    158     layoutCons.gridy = 8;
    159     layoutCons.gridwidth = 2;
    160     layoutCons.weightx = 0.0;
    161     layoutCons.weighty = 0.0;
    162     layoutCons.fill = GridBagConstraints.BOTH;
    163     gridbag.setConstraints(label, layoutCons);
    164     contentPane.add(label);
    165 
    166     layoutCons.gridx = 0;
    167     layoutCons.gridy = 9;
    168     layoutCons.gridwidth = 1;
    169     layoutCons.weightx = 0.0;
    170     layoutCons.weighty = 0.0;
    171     layoutCons.fill = GridBagConstraints.BOTH;
    172     gridbag.setConstraints(tfThreshold, layoutCons);
    173     contentPane.add(tfThreshold);
    174 
    175     label = new JLabel(tr("meters"));
    176 
    177     layoutCons.gridx = 1;
    178     layoutCons.gridy = 9;
    179     layoutCons.gridwidth = 1;
    180     layoutCons.weightx = 0.0;
    181     layoutCons.weighty = 0.0;
    182     layoutCons.fill = GridBagConstraints.BOTH;
    183     gridbag.setConstraints(label, layoutCons);
    184     contentPane.add(label);
    185 
    186     JButton bSuggestStops = new JButton(tr("Suggest Stops"));
    187     bSuggestStops.setActionCommand("gtfsImporter.settingsSuggestStops");
    188     bSuggestStops.addActionListener(controller);
    189 
    190     layoutCons.gridx = 0;
    191     layoutCons.gridy = 10;
    192     layoutCons.gridwidth = 3;
    193     layoutCons.weightx = 1.0;
    194     layoutCons.weighty = 0.0;
    195     layoutCons.fill = GridBagConstraints.BOTH;
    196     gridbag.setConstraints(bSuggestStops, layoutCons);
    197     contentPane.add(bSuggestStops);
    198 
    199     //Waypoints Tab
    200     contentPane = tabWaypoints;
    201     gridbag = new GridBagLayout();
    202     layoutCons = new GridBagConstraints();
    203     contentPane.setLayout(gridbag);
    204     contentPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put
    205         (KeyStroke.getKeyStroke("alt N"), "gtfsImporter.gtfsStopsFocusAdd");
    206     contentPane.getActionMap().put
    207     ("gtfsImporter.gtfsStopsFocusAdd", controller.getFocusAddAction());
     16public class GTFSImporterDialog extends AbstractImporterDialog<GTFSImporterAction> {
     17    private JTable gtfsStopTable = null;
     18
     19    public GTFSImporterDialog(GTFSImporterAction controller) {
     20        super(controller, tr("Create Stops from GTFS"), "gtfsImporter");
     21    }
     22
     23    @Override
     24    protected void initDialog(GTFSImporterAction controller) {
     25        JPanel tabSettings = new JPanel();
     26        tabbedPane.addTab(tr("Settings"), tabSettings);
     27        JPanel tabWaypoints = new JPanel();
     28        tabbedPane.addTab(tr("GTFS-Stops"), tabWaypoints);
     29        tabbedPane.setEnabledAt(0, false);
     30        tabbedPane.setEnabledAt(1, true);
     31
     32        // Settings Tab
     33        JPanel contentPane = tabSettings;
     34        GridBagLayout gridbag = new GridBagLayout();
     35        GridBagConstraints layoutCons = new GridBagConstraints();
     36        contentPane.setLayout(gridbag);
     37
     38        JLabel label = new JLabel(tr("Type of stops to add"));
     39
     40        layoutCons.gridx = 0;
     41        layoutCons.gridy = 0;
     42        layoutCons.gridwidth = 2;
     43        layoutCons.weightx = 0.0;
     44        layoutCons.weighty = 0.0;
     45        layoutCons.fill = GridBagConstraints.BOTH;
     46        gridbag.setConstraints(label, layoutCons);
     47        contentPane.add(label);
     48
     49        layoutCons.gridx = 0;
     50        layoutCons.gridy = 1;
     51        layoutCons.gridwidth = 1;
     52        layoutCons.weightx = 0.0;
     53        layoutCons.weighty = 0.0;
     54        layoutCons.fill = GridBagConstraints.BOTH;
     55        gridbag.setConstraints(cbStoptype, layoutCons);
     56        contentPane.add(cbStoptype);
     57
     58        label = new JLabel(tr("Time on your GPS device"));
     59
     60        layoutCons.gridx = 0;
     61        layoutCons.gridy = 2;
     62        layoutCons.gridwidth = 2;
     63        layoutCons.weightx = 0.0;
     64        layoutCons.weighty = 0.0;
     65        layoutCons.fill = GridBagConstraints.BOTH;
     66        gridbag.setConstraints(label, layoutCons);
     67        contentPane.add(label);
     68
     69        layoutCons.gridx = 0;
     70        layoutCons.gridy = 3;
     71        layoutCons.gridwidth = 1;
     72        layoutCons.weightx = 0.0;
     73        layoutCons.weighty = 0.0;
     74        layoutCons.fill = GridBagConstraints.BOTH;
     75        gridbag.setConstraints(tfGPSTimeStart, layoutCons);
     76        contentPane.add(tfGPSTimeStart);
     77
     78        /* I18n: Don't change the time format, you only may translate the letters */
     79        label = new JLabel(tr("HH:MM:SS.sss"));
     80
     81        layoutCons.gridx = 1;
     82        layoutCons.gridy = 3;
     83        layoutCons.gridwidth = 1;
     84        layoutCons.weightx = 0.0;
     85        layoutCons.weighty = 0.0;
     86        layoutCons.fill = GridBagConstraints.BOTH;
     87        gridbag.setConstraints(label, layoutCons);
     88        contentPane.add(label);
     89
     90        label = new JLabel(tr("Time on your stopwatch"));
     91
     92        layoutCons.gridx = 0;
     93        layoutCons.gridy = 4;
     94        layoutCons.gridwidth = 2;
     95        layoutCons.weightx = 0.0;
     96        layoutCons.weighty = 0.0;
     97        layoutCons.fill = GridBagConstraints.BOTH;
     98        gridbag.setConstraints(label, layoutCons);
     99        contentPane.add(label);
     100
     101        layoutCons.gridx = 0;
     102        layoutCons.gridy = 5;
     103        layoutCons.gridwidth = 1;
     104        layoutCons.weightx = 0.0;
     105        layoutCons.weighty = 0.0;
     106        layoutCons.fill = GridBagConstraints.BOTH;
     107        gridbag.setConstraints(tfStopwatchStart, layoutCons);
     108        contentPane.add(tfStopwatchStart);
     109
     110        /* I18n: Don't change the time format, you only may translate the letters */
     111        label = new JLabel(tr("HH:MM:SS.sss"));
     112
     113        layoutCons.gridx = 1;
     114        layoutCons.gridy = 5;
     115        layoutCons.gridwidth = 1;
     116        layoutCons.weightx = 0.0;
     117        layoutCons.weighty = 0.0;
     118        layoutCons.fill = GridBagConstraints.BOTH;
     119        gridbag.setConstraints(label, layoutCons);
     120        contentPane.add(label);
     121
     122        label = new JLabel(tr("Time window"));
     123
     124        layoutCons.gridx = 0;
     125        layoutCons.gridy = 6;
     126        layoutCons.gridwidth = 2;
     127        layoutCons.weightx = 0.0;
     128        layoutCons.weighty = 0.0;
     129        layoutCons.fill = GridBagConstraints.BOTH;
     130        gridbag.setConstraints(label, layoutCons);
     131        contentPane.add(label);
     132
     133        layoutCons.gridx = 0;
     134        layoutCons.gridy = 7;
     135        layoutCons.gridwidth = 1;
     136        layoutCons.weightx = 0.0;
     137        layoutCons.weighty = 0.0;
     138        layoutCons.fill = GridBagConstraints.BOTH;
     139        gridbag.setConstraints(tfTimeWindow, layoutCons);
     140        contentPane.add(tfTimeWindow);
     141
     142        label = new JLabel(tr("seconds"));
     143
     144        layoutCons.gridx = 1;
     145        layoutCons.gridy = 7;
     146        layoutCons.gridwidth = 1;
     147        layoutCons.weightx = 0.0;
     148        layoutCons.weighty = 0.0;
     149        layoutCons.fill = GridBagConstraints.BOTH;
     150        gridbag.setConstraints(label, layoutCons);
     151        contentPane.add(label);
     152
     153        label = new JLabel(tr("Move Threshold"));
     154
     155        layoutCons.gridx = 0;
     156        layoutCons.gridy = 8;
     157        layoutCons.gridwidth = 2;
     158        layoutCons.weightx = 0.0;
     159        layoutCons.weighty = 0.0;
     160        layoutCons.fill = GridBagConstraints.BOTH;
     161        gridbag.setConstraints(label, layoutCons);
     162        contentPane.add(label);
     163
     164        layoutCons.gridx = 0;
     165        layoutCons.gridy = 9;
     166        layoutCons.gridwidth = 1;
     167        layoutCons.weightx = 0.0;
     168        layoutCons.weighty = 0.0;
     169        layoutCons.fill = GridBagConstraints.BOTH;
     170        gridbag.setConstraints(tfThreshold, layoutCons);
     171        contentPane.add(tfThreshold);
     172
     173        label = new JLabel(tr("meters"));
     174
     175        layoutCons.gridx = 1;
     176        layoutCons.gridy = 9;
     177        layoutCons.gridwidth = 1;
     178        layoutCons.weightx = 0.0;
     179        layoutCons.weighty = 0.0;
     180        layoutCons.fill = GridBagConstraints.BOTH;
     181        gridbag.setConstraints(label, layoutCons);
     182        contentPane.add(label);
     183
     184        JButton bSuggestStops = new JButton(tr("Suggest Stops"));
     185        bSuggestStops.setActionCommand("gtfsImporter.settingsSuggestStops");
     186        bSuggestStops.addActionListener(controller);
     187
     188        layoutCons.gridx = 0;
     189        layoutCons.gridy = 10;
     190        layoutCons.gridwidth = 3;
     191        layoutCons.weightx = 1.0;
     192        layoutCons.weighty = 0.0;
     193        layoutCons.fill = GridBagConstraints.BOTH;
     194        gridbag.setConstraints(bSuggestStops, layoutCons);
     195        contentPane.add(bSuggestStops);
     196
     197        // Waypoints Tab
     198        contentPane = tabWaypoints;
     199        gridbag = new GridBagLayout();
     200        layoutCons = new GridBagConstraints();
     201        contentPane.setLayout(gridbag);
     202        contentPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
     203                .put(KeyStroke.getKeyStroke("alt N"), "gtfsImporter.gtfsStopsFocusAdd");
     204        contentPane.getActionMap().put("gtfsImporter.gtfsStopsFocusAdd",
     205                controller.getFocusAddAction());
    208206/*    contentPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put
    209207        (KeyStroke.getKeyStroke("alt S"), "gtfsImporter.focusShelterYes");
     
    227225     controller.getFocusWaypointDeleteAction());*/
    228226
    229     gtfsStopTable = new JTable();
    230     JScrollPane tableSP = new JScrollPane(gtfsStopTable);
    231 
    232     layoutCons.gridx = 0;
    233     layoutCons.gridy = 0;
    234     layoutCons.gridwidth = 4;
    235     layoutCons.weightx = 1.0;
    236     layoutCons.weighty = 1.0;
    237     layoutCons.fill = GridBagConstraints.BOTH;
    238     gridbag.setConstraints(tableSP, layoutCons);
    239     contentPane.add(tableSP);
    240 
    241     JButton bFind = new JButton(tr("Find"));
    242     bFind.setActionCommand("gtfsImporter.gtfsStopsFind");
    243     bFind.addActionListener(controller);
    244 
    245     layoutCons.gridx = 0;
    246     layoutCons.gridy = 1;
    247     layoutCons.gridwidth = 1;
    248     layoutCons.weightx = 1.0;
    249     layoutCons.weighty = 0.0;
    250     layoutCons.fill = GridBagConstraints.BOTH;
    251     gridbag.setConstraints(bFind, layoutCons);
    252     contentPane.add(bFind);
    253 
    254     JButton bShow = new JButton(tr("Show"));
    255     bShow.setActionCommand("gtfsImporter.gtfsStopsShow");
    256     bShow.addActionListener(controller);
    257 
    258     layoutCons.gridx = 0;
    259     layoutCons.gridy = 2;
    260     layoutCons.gridwidth = 1;
    261     layoutCons.weightx = 1.0;
    262     layoutCons.weighty = 0.0;
    263     layoutCons.fill = GridBagConstraints.BOTH;
    264     gridbag.setConstraints(bShow, layoutCons);
    265     contentPane.add(bShow);
    266 
    267     JButton bMark = new JButton(tr("Mark"));
    268     bMark.setActionCommand("gtfsImporter.gtfsStopsMark");
    269     bMark.addActionListener(controller);
    270 
    271     layoutCons.gridx = 1;
    272     layoutCons.gridy = 1;
    273     layoutCons.gridheight = 2;
    274     layoutCons.gridwidth = 1;
    275     layoutCons.weightx = 1.0;
    276     layoutCons.weighty = 0.0;
    277     layoutCons.fill = GridBagConstraints.BOTH;
    278     gridbag.setConstraints(bMark, layoutCons);
    279     contentPane.add(bMark);
    280 
    281     JButton bCatch = new JButton(tr("Catch"));
    282     bCatch.setActionCommand("gtfsImporter.gtfsStopsCatch");
    283     bCatch.addActionListener(controller);
    284 
    285     layoutCons.gridx = 2;
    286     layoutCons.gridy = 1;
    287     layoutCons.gridheight = 1;
    288     layoutCons.gridwidth = 1;
    289     layoutCons.weightx = 1.0;
    290     layoutCons.weighty = 0.0;
    291     layoutCons.fill = GridBagConstraints.BOTH;
    292     gridbag.setConstraints(bCatch, layoutCons);
    293     contentPane.add(bCatch);
    294 
    295     JButton bJoin = new JButton(tr("Join"));
    296     bJoin.setActionCommand("gtfsImporter.gtfsStopsJoin");
    297     bJoin.addActionListener(controller);
    298 
    299     layoutCons.gridx = 2;
    300     layoutCons.gridy = 2;
    301     layoutCons.gridheight = 1;
    302     layoutCons.gridwidth = 1;
    303     layoutCons.weightx = 1.0;
    304     layoutCons.weighty = 0.0;
    305     layoutCons.fill = GridBagConstraints.BOTH;
    306     gridbag.setConstraints(bJoin, layoutCons);
    307     contentPane.add(bJoin);
    308 
    309     JButton bAdd = new JButton(tr("Enable"));
    310     bAdd.setActionCommand("gtfsImporter.gtfsStopsAdd");
    311     bAdd.addActionListener(controller);
    312 
    313     layoutCons.gridx = 3;
    314     layoutCons.gridy = 1;
    315     layoutCons.gridheight = 1;
    316     layoutCons.gridwidth = 1;
    317     layoutCons.weightx = 1.0;
    318     layoutCons.weighty = 0.0;
    319     layoutCons.fill = GridBagConstraints.BOTH;
    320     gridbag.setConstraints(bAdd, layoutCons);
    321     contentPane.add(bAdd);
    322 
    323     JButton bDelete = new JButton(tr("Disable"));
    324     bDelete.setActionCommand("gtfsImporter.gtfsStopsDelete");
    325     bDelete.addActionListener(controller);
    326 
    327     layoutCons.gridx = 3;
    328     layoutCons.gridy = 2;
    329     layoutCons.gridwidth = 1;
    330     layoutCons.weightx = 1.0;
    331     layoutCons.weighty = 0.0;
    332     layoutCons.fill = GridBagConstraints.BOTH;
    333     gridbag.setConstraints(bDelete, layoutCons);
    334     contentPane.add(bDelete);
    335   }
    336 
    337   public JTable getGTFSStopTable()
    338   {
    339     return gtfsStopTable;
    340   }
    341 
    342   public void setGTFSStopTableModel(GTFSStopTableModel model)
    343   {
    344     gtfsStopTable.setModel(model);
    345     int width = gtfsStopTable.getPreferredSize().width;
    346     gtfsStopTable.getColumnModel().getColumn(0).setPreferredWidth((int)(width * 0.3));
    347     gtfsStopTable.getColumnModel().getColumn(1).setPreferredWidth((int)(width * 0.6));
    348     gtfsStopTable.getColumnModel().getColumn(2).setPreferredWidth((int)(width * 0.1));
    349   }
     227        gtfsStopTable = new JTable();
     228        JScrollPane tableSP = new JScrollPane(gtfsStopTable);
     229
     230        layoutCons.gridx = 0;
     231        layoutCons.gridy = 0;
     232        layoutCons.gridwidth = 4;
     233        layoutCons.weightx = 1.0;
     234        layoutCons.weighty = 1.0;
     235        layoutCons.fill = GridBagConstraints.BOTH;
     236        gridbag.setConstraints(tableSP, layoutCons);
     237        contentPane.add(tableSP);
     238
     239        JButton bFind = new JButton(tr("Find"));
     240        bFind.setActionCommand("gtfsImporter.gtfsStopsFind");
     241        bFind.addActionListener(controller);
     242
     243        layoutCons.gridx = 0;
     244        layoutCons.gridy = 1;
     245        layoutCons.gridwidth = 1;
     246        layoutCons.weightx = 1.0;
     247        layoutCons.weighty = 0.0;
     248        layoutCons.fill = GridBagConstraints.BOTH;
     249        gridbag.setConstraints(bFind, layoutCons);
     250        contentPane.add(bFind);
     251
     252        JButton bShow = new JButton(tr("Show"));
     253        bShow.setActionCommand("gtfsImporter.gtfsStopsShow");
     254        bShow.addActionListener(controller);
     255
     256        layoutCons.gridx = 0;
     257        layoutCons.gridy = 2;
     258        layoutCons.gridwidth = 1;
     259        layoutCons.weightx = 1.0;
     260        layoutCons.weighty = 0.0;
     261        layoutCons.fill = GridBagConstraints.BOTH;
     262        gridbag.setConstraints(bShow, layoutCons);
     263        contentPane.add(bShow);
     264
     265        JButton bMark = new JButton(tr("Mark"));
     266        bMark.setActionCommand("gtfsImporter.gtfsStopsMark");
     267        bMark.addActionListener(controller);
     268
     269        layoutCons.gridx = 1;
     270        layoutCons.gridy = 1;
     271        layoutCons.gridheight = 2;
     272        layoutCons.gridwidth = 1;
     273        layoutCons.weightx = 1.0;
     274        layoutCons.weighty = 0.0;
     275        layoutCons.fill = GridBagConstraints.BOTH;
     276        gridbag.setConstraints(bMark, layoutCons);
     277        contentPane.add(bMark);
     278
     279        JButton bCatch = new JButton(tr("Catch"));
     280        bCatch.setActionCommand("gtfsImporter.gtfsStopsCatch");
     281        bCatch.addActionListener(controller);
     282
     283        layoutCons.gridx = 2;
     284        layoutCons.gridy = 1;
     285        layoutCons.gridheight = 1;
     286        layoutCons.gridwidth = 1;
     287        layoutCons.weightx = 1.0;
     288        layoutCons.weighty = 0.0;
     289        layoutCons.fill = GridBagConstraints.BOTH;
     290        gridbag.setConstraints(bCatch, layoutCons);
     291        contentPane.add(bCatch);
     292
     293        JButton bJoin = new JButton(tr("Join"));
     294        bJoin.setActionCommand("gtfsImporter.gtfsStopsJoin");
     295        bJoin.addActionListener(controller);
     296
     297        layoutCons.gridx = 2;
     298        layoutCons.gridy = 2;
     299        layoutCons.gridheight = 1;
     300        layoutCons.gridwidth = 1;
     301        layoutCons.weightx = 1.0;
     302        layoutCons.weighty = 0.0;
     303        layoutCons.fill = GridBagConstraints.BOTH;
     304        gridbag.setConstraints(bJoin, layoutCons);
     305        contentPane.add(bJoin);
     306
     307        JButton bAdd = new JButton(tr("Enable"));
     308        bAdd.setActionCommand("gtfsImporter.gtfsStopsAdd");
     309        bAdd.addActionListener(controller);
     310
     311        layoutCons.gridx = 3;
     312        layoutCons.gridy = 1;
     313        layoutCons.gridheight = 1;
     314        layoutCons.gridwidth = 1;
     315        layoutCons.weightx = 1.0;
     316        layoutCons.weighty = 0.0;
     317        layoutCons.fill = GridBagConstraints.BOTH;
     318        gridbag.setConstraints(bAdd, layoutCons);
     319        contentPane.add(bAdd);
     320
     321        JButton bDelete = new JButton(tr("Disable"));
     322        bDelete.setActionCommand("gtfsImporter.gtfsStopsDelete");
     323        bDelete.addActionListener(controller);
     324
     325        layoutCons.gridx = 3;
     326        layoutCons.gridy = 2;
     327        layoutCons.gridwidth = 1;
     328        layoutCons.weightx = 1.0;
     329        layoutCons.weighty = 0.0;
     330        layoutCons.fill = GridBagConstraints.BOTH;
     331        gridbag.setConstraints(bDelete, layoutCons);
     332        contentPane.add(bDelete);
     333    }
     334
     335    public JTable getGTFSStopTable() {
     336        return gtfsStopTable;
     337    }
     338
     339    public void setGTFSStopTableModel(GTFSStopTableModel model) {
     340        gtfsStopTable.setModel(model);
     341        int width = gtfsStopTable.getPreferredSize().width;
     342        gtfsStopTable.getColumnModel().getColumn(0).setPreferredWidth((int) (width * 0.3));
     343        gtfsStopTable.getColumnModel().getColumn(1).setPreferredWidth((int) (width * 0.6));
     344        gtfsStopTable.getColumnModel().getColumn(2).setPreferredWidth((int) (width * 0.1));
     345    }
    350346
    351347/*  private class TracksLSL implements ListSelectionListener
  • applications/editors/josm/plugins/public_transport/src/public_transport/GTFSJoinCommand.java

    r29854 r32357  
    99import org.openstreetmap.josm.Main;
    1010import org.openstreetmap.josm.command.Command;
     11import org.openstreetmap.josm.data.osm.DataSet;
    1112import org.openstreetmap.josm.data.osm.Node;
    1213import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1314
    14 public class GTFSJoinCommand extends Command
    15 {
    16   private Vector< Integer > workingLines = null;
    17   private Node undoMapNode = null;
    18   private Node undoTableNode = null;
    19   private GTFSStopTableModel gtfsStopTM = null;
    20   private String type = null;
     15public class GTFSJoinCommand extends Command {
     16    private Vector<Integer> workingLines = null;
    2117
    22   public GTFSJoinCommand(GTFSImporterAction controller)
    23   {
    24     gtfsStopTM = controller.getGTFSStopTableModel();
    25     workingLines = new Vector< Integer >();
     18    private Node undoMapNode = null;
    2619
    27     // use either selected lines or all lines if no line is selected
    28     int[] selectedLines = controller.getDialog().getGTFSStopTable().getSelectedRows();
    29     if (selectedLines.length != 1)
    30       return;
    31     workingLines.add(selectedLines[0]);
    32   }
     20    private Node undoTableNode = null;
    3321
    34   public boolean executeCommand()
    35   {
    36     if (workingLines.size() != 1)
    37       return false;
    38     Node dest = null;
    39     Iterator< Node > iter =
    40         Main.main.getCurrentDataSet().getSelectedNodes().iterator();
    41     int j = workingLines.elementAt(0);
    42     while (iter.hasNext())
    43     {
    44       Node n = iter.next();
    45       if ((n != null) && (n.equals(gtfsStopTM.nodes.elementAt(j))))
    46     continue;
    47       if (dest != null)
    48     return false;
    49       dest = n;
    50     }
    51     if (dest == null)
    52       return false;
    53     undoMapNode = new Node(dest);
     22    private GTFSStopTableModel gtfsStopTM = null;
    5423
    55     Node node = gtfsStopTM.nodes.elementAt(j);
    56     undoTableNode = node;
    57     if (node != null)
    58     {
    59       Main.main.getCurrentDataSet().removePrimitive(node);
    60       node.setDeleted(true);
     24    private String type = null;
     25
     26    public GTFSJoinCommand(GTFSImporterAction controller) {
     27        gtfsStopTM = controller.getGTFSStopTableModel();
     28        workingLines = new Vector<>();
     29
     30        // use either selected lines or all lines if no line is selected
     31        int[] selectedLines = controller.getDialog().getGTFSStopTable().getSelectedRows();
     32        if (selectedLines.length != 1)
     33            return;
     34        workingLines.add(selectedLines[0]);
    6135    }
    6236
    63     dest.put("highway", "bus_stop");
    64     dest.put("stop_id", (String)gtfsStopTM.getValueAt(j, 0));
    65     if (dest.get("name") == null)
    66       dest.put("name", (String)gtfsStopTM.getValueAt(j, 1));
    67     gtfsStopTM.nodes.set(j, dest);
    68     type = (String)gtfsStopTM.getValueAt(j, 2);
    69     gtfsStopTM.setValueAt(tr("moved"), j, 2);
     37    @Override
     38    public boolean executeCommand() {
     39        if (workingLines.size() != 1)
     40            return false;
     41        Node dest = null;
     42        DataSet ds = Main.getLayerManager().getEditDataSet();
     43        Iterator<Node> iter = ds.getSelectedNodes().iterator();
     44        int j = workingLines.elementAt(0);
     45        while (iter.hasNext()) {
     46            Node n = iter.next();
     47            if ((n != null) && (n.equals(gtfsStopTM.nodes.elementAt(j))))
     48                continue;
     49            if (dest != null)
     50                return false;
     51            dest = n;
     52        }
     53        if (dest == null)
     54            return false;
     55        undoMapNode = new Node(dest);
    7056
    71     return true;
    72   }
     57        Node node = gtfsStopTM.nodes.elementAt(j);
     58        undoTableNode = node;
     59        if (node != null) {
     60            ds.removePrimitive(node);
     61            node.setDeleted(true);
     62        }
    7363
    74   public void undoCommand()
    75   {
    76     if (workingLines.size() != 1)
    77       return;
    78     int j = workingLines.elementAt(0);
     64        dest.put("highway", "bus_stop");
     65        dest.put("stop_id", (String) gtfsStopTM.getValueAt(j, 0));
     66        if (dest.get("name") == null)
     67            dest.put("name", (String) gtfsStopTM.getValueAt(j, 1));
     68        gtfsStopTM.nodes.set(j, dest);
     69        type = (String) gtfsStopTM.getValueAt(j, 2);
     70        gtfsStopTM.setValueAt(tr("moved"), j, 2);
    7971
    80     Node node = gtfsStopTM.nodes.elementAt(j);
    81     if (node != null)
    82     {
    83       Main.main.getCurrentDataSet().removePrimitive(node);
    84       node.setDeleted(true);
     72        return true;
    8573    }
    8674
    87     if (undoMapNode != null)
    88     {
    89       undoMapNode.setDeleted(false);
    90       Main.main.getCurrentDataSet().addPrimitive(undoMapNode);
     75    @Override
     76    public void undoCommand() {
     77        if (workingLines.size() != 1)
     78            return;
     79        int j = workingLines.elementAt(0);
     80
     81        DataSet ds = Main.getLayerManager().getEditDataSet();
     82        Node node = gtfsStopTM.nodes.elementAt(j);
     83        if (node != null) {
     84            ds.removePrimitive(node);
     85            node.setDeleted(true);
     86        }
     87
     88        if (undoMapNode != null) {
     89            undoMapNode.setDeleted(false);
     90            ds.addPrimitive(undoMapNode);
     91        }
     92        if (undoTableNode != null) {
     93            undoTableNode.setDeleted(false);
     94            ds.addPrimitive(undoTableNode);
     95        }
     96        gtfsStopTM.nodes.set(j, undoTableNode);
     97        gtfsStopTM.setValueAt(type, j, 2);
    9198    }
    92     if (undoTableNode != null)
    93     {
    94       undoTableNode.setDeleted(false);
    95       Main.main.getCurrentDataSet().addPrimitive(undoTableNode);
     99
     100    @Override
     101    public void fillModifiedData(Collection<OsmPrimitive> modified,
     102            Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
    96103    }
    97     gtfsStopTM.nodes.set(j, undoTableNode);
    98     gtfsStopTM.setValueAt(type, j, 2);
    99   }
    100104
    101   public void fillModifiedData
    102     (Collection< OsmPrimitive > modified, Collection< OsmPrimitive > deleted,
    103      Collection< OsmPrimitive > added)
    104   {
    105   }
    106 
    107   @Override public String getDescriptionText()
    108   {
    109     return tr("Public Transport: Join GTFS stops");
    110   }
     105    @Override
     106    public String getDescriptionText() {
     107        return tr("Public Transport: Join GTFS stops");
     108    }
    111109};
  • applications/editors/josm/plugins/public_transport/src/public_transport/GTFSStopTableModel.java

    r30664 r32357  
    1313import org.openstreetmap.josm.data.DataSource;
    1414import org.openstreetmap.josm.data.coor.LatLon;
     15import org.openstreetmap.josm.data.osm.DataSet;
    1516import org.openstreetmap.josm.data.osm.Node;
    1617
    17 public class GTFSStopTableModel extends DefaultTableModel
    18       implements TableModelListener
    19 {
    20   private GTFSImporterAction controller = null;
    21   public Vector< Node > nodes = new Vector< Node >();
    22   public Vector< LatLon > coors = new Vector< LatLon >();
    23   private int idCol = -1;
    24   private int nameCol = -1;
    25   private int latCol = -1;
    26   private int lonCol = -1;
    27   private char separator = ',';
    28 
    29   public GTFSStopTableModel(GTFSImporterAction controller,
    30                 String columnConfig)
    31   {
    32     int pos = columnConfig.indexOf(separator);
    33     if (pos == -1)
    34     {
    35       separator = ';';
    36       pos = columnConfig.indexOf(separator);
    37     }
    38     if (pos == -1)
    39     {
    40       separator = '\t';
    41       pos = columnConfig.indexOf(separator);
    42     }
    43     int oldPos = 0;
    44     int i = 0;
    45     while (pos > -1)
    46     {
    47       String title = stripQuot(columnConfig.substring(oldPos, pos));
    48       if ("stop_id".equals(title))
    49     idCol = i;
    50       else if ("stop_name".equals(title))
    51     nameCol = i;
    52       else if ("stop_lat".equals(title))
    53     latCol = i;
    54       else if ("stop_lon".equals(title))
    55     lonCol = i;
    56       ++i;
    57       oldPos = pos + 1;
    58       pos = columnConfig.indexOf(separator, oldPos);
    59     }
    60     String title = columnConfig.substring(oldPos);
    61     if ("stop_id".equals(title))
    62       idCol = i;
    63     else if ("stop_name".equals(title))
    64       nameCol = i;
    65     else if ("stop_lat".equals(title))
    66       latCol = i;
    67     else if ("stop_lon".equals(title))
    68       lonCol = i;
    69 
    70     this.controller = controller;
    71     addColumn(tr("Id"));
    72     addColumn(tr("Name"));
    73     addColumn(tr("State"));
    74     addTableModelListener(this);
    75   }
    76 
    77   public boolean isCellEditable(int row, int column)
    78   {
    79     return false;
    80   }
    81 
    82   public void addRow(Object[] obj)
    83   {
    84     throw new UnsupportedOperationException();
    85   }
    86 
    87   public void insertRow(int insPos, Object[] obj)
    88   {
    89     throw new UnsupportedOperationException();
    90   }
    91 
    92   public void addRow(String s)
    93   {
    94     insertRow(-1, s, new Vector< Node >());
    95   }
    96 
    97   public void addRow(String s, Vector< Node > existingStops)
    98   {
    99     insertRow(-1, s, existingStops);
    100   }
    101 
    102   /* tokenizes a line as follows:
    103      any comma outside a pair of double quotation marks is taken as field separator.
    104      In particular, neither \" nor \, have a special meaning.
    105      Returns the position of the next field separator, if any. Otherwise it returns -1.
    106      s - the string to tokenize.
    107      startPos - the position of the last field separator plus 1 or the value 0. */
    108   private int tokenize(String s, int startPos)
    109   {
    110     int pos = startPos;
    111     boolean insideDoubleQuoted = false;
    112     while (pos < s.length())
    113     {
    114       if ('"' == s.charAt(pos))
    115         insideDoubleQuoted = !insideDoubleQuoted;
    116       else if ((separator == s.charAt(pos)) && (!insideDoubleQuoted))
    117         break;
    118       ++pos;
    119     }
    120     if (pos < s.length())
    121       return pos;
    122     else
    123       return -1;
    124   }
    125 
    126   private String stripQuot(String s)
    127   {
    128     int pos = s.indexOf('"');
    129     while (pos > -1)
    130     {
    131       s = s.substring(0, pos) + s.substring(pos + 1);
    132       pos = s.indexOf('"');
    133     }
    134     return s;
    135   }
    136 
    137   public void insertRow(int insPos, String s, Vector< Node > existingStops)
    138   {
    139     String[] buf = { "", "", tr("pending") };
    140     int pos = tokenize(s, 0);
    141     int oldPos = 0;
    142     int i = 0;
    143     double lat = 0;
    144     double lon = 0;
    145     while (pos > -1)
    146     {
    147       if (i == idCol)
    148     buf[0] = stripQuot(s.substring(oldPos, pos));
    149       else if (i == nameCol)
    150     buf[1] = stripQuot(s.substring(oldPos, pos));
    151       else if (i == latCol)
    152     lat = Double.parseDouble(stripQuot(s.substring(oldPos, pos)));
    153       else if (i == lonCol)
    154     lon = Double.parseDouble(stripQuot(s.substring(oldPos, pos)));
    155       ++i;
    156       oldPos = pos + 1;
    157       pos = tokenize(s, oldPos);
    158     }
    159     if (i == idCol)
    160       buf[0] = stripQuot(s.substring(oldPos));
    161     else if (i == nameCol)
    162       buf[1] = stripQuot(s.substring(oldPos));
    163     else if (i == latCol)
    164       lat = Double.parseDouble(stripQuot(s.substring(oldPos)));
    165     else if (i == lonCol)
    166       lon = Double.parseDouble(stripQuot(s.substring(oldPos)));
    167 
    168     LatLon coor = new LatLon(lat, lon);
    169 
    170     if (Main.main.getCurrentDataSet() != null)
    171     {
    172       boolean inside = false;
    173       Iterator< DataSource > iter =
    174           Main.main.getCurrentDataSet().dataSources.iterator();
    175       while (iter.hasNext())
    176       {
    177         if (iter.next().bounds.contains(coor))
    178         {
    179           inside = true;
    180           break;
    181         }
    182       }
    183       if (!inside)
    184         buf[2] = tr("outside");
    185     }
    186 
    187     boolean nearBusStop = false;
    188     Iterator< Node > iter = existingStops.iterator();
    189     while (iter.hasNext())
    190     {
    191       Node node = iter.next();
    192       if (coor.greatCircleDistance(node.getCoor()) < 1000)
    193       {
    194         nearBusStop = true;
    195         break;
    196       }
    197     }
    198 
    199     if (insPos == -1)
    200     {
    201       if ((nearBusStop) || !(tr("pending").equals(buf[2])))
    202         nodes.addElement(null);
    203       else
    204       {
    205         Node node = GTFSImporterAction.createNode(coor, buf[0], buf[1]);
    206         nodes.addElement(node);
    207         buf[2] = tr("added");
    208       }
    209       coors.addElement(coor);
    210       super.addRow(buf);
    211     }
    212     else
    213     {
    214       if ((nearBusStop) || !(tr("pending").equals(buf[2])))
    215         nodes.insertElementAt(null, insPos);
    216       else
    217       {
    218         Node node = GTFSImporterAction.createNode(coor, buf[0], buf[1]);
    219         nodes.insertElementAt(node, insPos);
    220         buf[2] = tr("added");
    221       }
    222       coors.insertElementAt(coor, insPos);
    223       super.insertRow(insPos, buf);
    224     }
    225   }
    226 
    227   public void clear()
    228   {
    229     nodes.clear();
    230     super.setRowCount(0);
    231   }
    232 
    233   public void tableChanged(TableModelEvent e)
    234   {
    235   }
    236 };
     18public class GTFSStopTableModel extends DefaultTableModel implements TableModelListener {
     19    private GTFSImporterAction controller = null;
     20
     21    public Vector<Node> nodes = new Vector<Node>();
     22
     23    public Vector<LatLon> coors = new Vector<LatLon>();
     24
     25    private int idCol = -1;
     26
     27    private int nameCol = -1;
     28
     29    private int latCol = -1;
     30
     31    private int lonCol = -1;
     32
     33    private char separator = ',';
     34
     35    public GTFSStopTableModel(GTFSImporterAction controller, String columnConfig) {
     36        int pos = columnConfig.indexOf(separator);
     37        if (pos == -1) {
     38            separator = ';';
     39            pos = columnConfig.indexOf(separator);
     40        }
     41        if (pos == -1) {
     42            separator = '\t';
     43            pos = columnConfig.indexOf(separator);
     44        }
     45        int oldPos = 0;
     46        int i = 0;
     47        while (pos > -1) {
     48            String title = stripQuot(columnConfig.substring(oldPos, pos));
     49            if ("stop_id".equals(title))
     50                idCol = i;
     51            else if ("stop_name".equals(title))
     52                nameCol = i;
     53            else if ("stop_lat".equals(title))
     54                latCol = i;
     55            else if ("stop_lon".equals(title))
     56                lonCol = i;
     57            ++i;
     58            oldPos = pos + 1;
     59            pos = columnConfig.indexOf(separator, oldPos);
     60        }
     61        String title = columnConfig.substring(oldPos);
     62        if ("stop_id".equals(title))
     63            idCol = i;
     64        else if ("stop_name".equals(title))
     65            nameCol = i;
     66        else if ("stop_lat".equals(title))
     67            latCol = i;
     68        else if ("stop_lon".equals(title))
     69            lonCol = i;
     70
     71        this.controller = controller;
     72        addColumn(tr("Id"));
     73        addColumn(tr("Name"));
     74        addColumn(tr("State"));
     75        addTableModelListener(this);
     76    }
     77
     78    @Override
     79    public boolean isCellEditable(int row, int column) {
     80        return false;
     81    }
     82
     83    @Override
     84    public void addRow(Object[] obj) {
     85        throw new UnsupportedOperationException();
     86    }
     87
     88    @Override
     89    public void insertRow(int insPos, Object[] obj) {
     90        throw new UnsupportedOperationException();
     91    }
     92
     93    public void addRow(String s) {
     94        insertRow(-1, s, new Vector<Node>());
     95    }
     96
     97    public void addRow(String s, Vector<Node> existingStops) {
     98        insertRow(-1, s, existingStops);
     99    }
     100
     101    /*
     102     * tokenizes a line as follows: any comma outside a pair of double quotation marks is taken as field separator. In particular, neither \" nor \,
     103     * have a special meaning. Returns the position of the next field separator, if any. Otherwise it returns -1. s - the string to tokenize. startPos
     104     * - the position of the last field separator plus 1 or the value 0.
     105     */
     106    private int tokenize(String s, int startPos) {
     107        int pos = startPos;
     108        boolean insideDoubleQuoted = false;
     109        while (pos < s.length()) {
     110            if ('"' == s.charAt(pos))
     111                insideDoubleQuoted = !insideDoubleQuoted;
     112            else if ((separator == s.charAt(pos)) && (!insideDoubleQuoted))
     113                break;
     114            ++pos;
     115        }
     116        if (pos < s.length())
     117            return pos;
     118        else
     119            return -1;
     120    }
     121
     122    private String stripQuot(String s) {
     123        int pos = s.indexOf('"');
     124        while (pos > -1) {
     125            s = s.substring(0, pos) + s.substring(pos + 1);
     126            pos = s.indexOf('"');
     127        }
     128        return s;
     129    }
     130
     131    public void insertRow(int insPos, String s, Vector<Node> existingStops) {
     132        String[] buf = { "", "", tr("pending") };
     133        int pos = tokenize(s, 0);
     134        int oldPos = 0;
     135        int i = 0;
     136        double lat = 0;
     137        double lon = 0;
     138        while (pos > -1) {
     139            if (i == idCol)
     140                buf[0] = stripQuot(s.substring(oldPos, pos));
     141            else if (i == nameCol)
     142                buf[1] = stripQuot(s.substring(oldPos, pos));
     143            else if (i == latCol)
     144                lat = Double.parseDouble(stripQuot(s.substring(oldPos, pos)));
     145            else if (i == lonCol)
     146                lon = Double.parseDouble(stripQuot(s.substring(oldPos, pos)));
     147            ++i;
     148            oldPos = pos + 1;
     149            pos = tokenize(s, oldPos);
     150        }
     151        if (i == idCol)
     152            buf[0] = stripQuot(s.substring(oldPos));
     153        else if (i == nameCol)
     154            buf[1] = stripQuot(s.substring(oldPos));
     155        else if (i == latCol)
     156            lat = Double.parseDouble(stripQuot(s.substring(oldPos)));
     157        else if (i == lonCol)
     158            lon = Double.parseDouble(stripQuot(s.substring(oldPos)));
     159
     160        LatLon coor = new LatLon(lat, lon);
     161
     162        DataSet ds = Main.getLayerManager().getEditDataSet();
     163        if (ds != null) {
     164            boolean inside = false;
     165            Iterator<DataSource> iter = ds.dataSources.iterator();
     166            while (iter.hasNext()) {
     167                if (iter.next().bounds.contains(coor)) {
     168                    inside = true;
     169                    break;
     170                }
     171            }
     172            if (!inside)
     173                buf[2] = tr("outside");
     174        }
     175
     176        boolean nearBusStop = false;
     177        Iterator<Node> iter = existingStops.iterator();
     178        while (iter.hasNext()) {
     179            Node node = iter.next();
     180            if (coor.greatCircleDistance(node.getCoor()) < 1000) {
     181                nearBusStop = true;
     182                break;
     183            }
     184        }
     185
     186        if (insPos == -1) {
     187            if ((nearBusStop) || !(tr("pending").equals(buf[2])))
     188                nodes.addElement(null);
     189            else {
     190                Node node = GTFSImporterAction.createNode(coor, buf[0], buf[1]);
     191                nodes.addElement(node);
     192                buf[2] = tr("added");
     193            }
     194            coors.addElement(coor);
     195            super.addRow(buf);
     196        } else {
     197            if ((nearBusStop) || !(tr("pending").equals(buf[2])))
     198                nodes.insertElementAt(null, insPos);
     199            else {
     200                Node node = GTFSImporterAction.createNode(coor, buf[0], buf[1]);
     201                nodes.insertElementAt(node, insPos);
     202                buf[2] = tr("added");
     203            }
     204            coors.insertElementAt(coor, insPos);
     205            super.insertRow(insPos, buf);
     206        }
     207    }
     208
     209    public void clear() {
     210        nodes.clear();
     211        super.setRowCount(0);
     212    }
     213
     214    @Override
     215    public void tableChanged(TableModelEvent e) {
     216    }
     217}
  • applications/editors/josm/plugins/public_transport/src/public_transport/ItineraryTableModel.java

    r26168 r32357  
    1212import org.openstreetmap.josm.data.osm.Way;
    1313
    14 public class ItineraryTableModel extends DefaultTableModel
    15     implements TableModelListener
    16 {
    17   public Vector<Way> ways = new Vector<Way>();
    18   public boolean inEvent = false;
     14public class ItineraryTableModel extends DefaultTableModel implements TableModelListener {
     15    public Vector<Way> ways = new Vector<>();
    1916
    20   public boolean isCellEditable(int row, int column)
    21   {
    22     if (column != 1)
    23       return false;
    24     if (ways.elementAt(row) == null)
    25       return false;
    26     return true;
    27   }
     17    public boolean inEvent = false;
    2818
    29   public void addRow(Object[] obj)
    30   {
    31     ways.addElement(null);
    32     super.addRow(obj);
    33   }
    34 
    35   public void insertRow(int insPos, Object[] obj)
    36   {
    37     if (insPos == -1)
    38     {
    39       ways.addElement(null);
    40       super.addRow(obj);
    41     }
    42     else
    43     {
    44       ways.insertElementAt(null, insPos);
    45       super.insertRow(insPos, obj);
    46     }
    47   }
    48 
    49   public void addRow(Way way, String role)
    50   {
    51     insertRow(-1, way, role);
    52   }
    53 
    54   public void insertRow(int insPos, Way way, String role)
    55   {
    56     String[] buf = { "", "" };
    57     String curName = way.get("name");
    58     if (way.isIncomplete())
    59       buf[0] = tr("[incomplete]");
    60     else if (way.getNodesCount() < 1)
    61       buf[0] = tr("[empty way]");
    62     else if (curName != null)
    63       buf[0] = curName;
    64     else
    65       buf[0] = tr("[ID] {0}", (new Long(way.getId())).toString());
    66     buf[1] = role;
    67     if (insPos == -1)
    68     {
    69       ways.addElement(way);
    70       super.addRow(buf);
    71     }
    72     else
    73     {
    74       ways.insertElementAt(way, insPos);
    75       super.insertRow(insPos, buf);
    76     }
    77   }
    78 
    79   public void clear()
    80   {
    81     ways.clear();
    82     super.setRowCount(0);
    83   }
    84 
    85   public void cleanupGaps()
    86   {
    87     inEvent = true;
    88     Node lastNode = null;
    89 
    90     for (int i = 0; i < getRowCount(); ++i)
    91     {
    92       if (ways.elementAt(i) == null)
    93       {
    94         ++i;
    95         if (i >= getRowCount())
    96           break;
    97       }
    98       while ((ways.elementAt(i) == null) &&
    99       ((i == 0) || (ways.elementAt(i-1) == null)))
    100       {
    101         ways.removeElementAt(i);
    102         removeRow(i);
    103         if (i >= getRowCount())
    104           break;
    105       }
    106       if (i >= getRowCount())
    107         break;
    108 
    109       boolean gapRequired = gapNecessary
    110       (ways.elementAt(i), (String)(getValueAt(i, 1)), lastNode);
    111       if ((i > 0) && (!gapRequired) && (ways.elementAt(i-1) == null))
    112       {
    113         ways.removeElementAt(i-1);
    114         removeRow(i-1);
    115         --i;
    116       }
    117       else if ((i > 0) && gapRequired && (ways.elementAt(i-1) != null))
    118       {
    119         String[] buf = { "", "" };
    120         buf[0] = tr("[gap]");
    121         insertRow(i, buf);
    122         ++i;
    123       }
    124       lastNode = getLastNode(ways.elementAt(i), (String)(getValueAt(i, 1)));
    125     }
    126     while ((getRowCount() > 0) &&
    127       (ways.elementAt(getRowCount()-1) == null))
    128     {
    129       ways.removeElementAt(getRowCount()-1);
    130       removeRow(getRowCount()-1);
    131     }
    132     inEvent = false;
    133   }
    134 
    135   public void tableChanged(TableModelEvent e)
    136   {
    137     if (e.getType() == TableModelEvent.UPDATE)
    138     {
    139       if (inEvent)
    140         return;
    141       cleanupGaps();
    142       RoutePatternAction.rebuildWays();
    143     }
    144   }
    145 
    146   private Node getLastNode(Way way, String role)
    147   {
    148     if ((way == null) || (way.isIncomplete()) || (way.getNodesCount() < 1))
    149       return null;
    150     else
    151     {
    152       if ("backward".equals(role))
    153         return way.getNode(0);
    154       else
    155         return way.getNode(way.getNodesCount() - 1);
    156     }
    157   }
    158 
    159   private boolean gapNecessary(Way way, String role, Node lastNode)
    160   {
    161     if ((way != null) && (!(way.isIncomplete())) && (way.getNodesCount() >= 1))
    162     {
    163       Node firstNode = null;
    164       if ("backward".equals(role))
    165         firstNode = way.getNode(way.getNodesCount() - 1);
    166       else
    167         firstNode = way.getNode(0);
    168       if ((lastNode != null) && (!lastNode.equals(firstNode)))
     19    @Override
     20    public boolean isCellEditable(int row, int column) {
     21        if (column != 1)
     22            return false;
     23        if (ways.elementAt(row) == null)
     24            return false;
    16925        return true;
    17026    }
    171     return false;
    172   }
    173 };
     27
     28    @Override
     29    public void addRow(Object[] obj) {
     30        ways.addElement(null);
     31        super.addRow(obj);
     32    }
     33
     34    @Override
     35    public void insertRow(int insPos, Object[] obj) {
     36        if (insPos == -1) {
     37            ways.addElement(null);
     38            super.addRow(obj);
     39        } else {
     40            ways.insertElementAt(null, insPos);
     41            super.insertRow(insPos, obj);
     42        }
     43    }
     44
     45    public void addRow(Way way, String role) {
     46        insertRow(-1, way, role);
     47    }
     48
     49    public void insertRow(int insPos, Way way, String role) {
     50        String[] buf = { "", "" };
     51        String curName = way.get("name");
     52        if (way.isIncomplete())
     53            buf[0] = tr("[incomplete]");
     54        else if (way.getNodesCount() < 1)
     55            buf[0] = tr("[empty way]");
     56        else if (curName != null)
     57            buf[0] = curName;
     58        else
     59            buf[0] = tr("[ID] {0}", (new Long(way.getId())).toString());
     60        buf[1] = role;
     61        if (insPos == -1) {
     62            ways.addElement(way);
     63            super.addRow(buf);
     64        } else {
     65            ways.insertElementAt(way, insPos);
     66            super.insertRow(insPos, buf);
     67        }
     68    }
     69
     70    public void clear() {
     71        ways.clear();
     72        super.setRowCount(0);
     73    }
     74
     75    public void cleanupGaps() {
     76        inEvent = true;
     77        Node lastNode = null;
     78
     79        for (int i = 0; i < getRowCount(); ++i) {
     80            if (ways.elementAt(i) == null) {
     81                ++i;
     82                if (i >= getRowCount())
     83                    break;
     84            }
     85            while ((ways.elementAt(i) == null) && ((i == 0) || (ways.elementAt(i - 1) == null))) {
     86                ways.removeElementAt(i);
     87                removeRow(i);
     88                if (i >= getRowCount())
     89                    break;
     90            }
     91            if (i >= getRowCount())
     92                break;
     93
     94            boolean gapRequired = gapNecessary(ways.elementAt(i), (String) (getValueAt(i, 1)),
     95                    lastNode);
     96            if ((i > 0) && (!gapRequired) && (ways.elementAt(i - 1) == null)) {
     97                ways.removeElementAt(i - 1);
     98                removeRow(i - 1);
     99                --i;
     100            } else if ((i > 0) && gapRequired && (ways.elementAt(i - 1) != null)) {
     101                String[] buf = { "", "" };
     102                buf[0] = tr("[gap]");
     103                insertRow(i, buf);
     104                ++i;
     105            }
     106            lastNode = getLastNode(ways.elementAt(i), (String) (getValueAt(i, 1)));
     107        }
     108        while ((getRowCount() > 0) && (ways.elementAt(getRowCount() - 1) == null)) {
     109            ways.removeElementAt(getRowCount() - 1);
     110            removeRow(getRowCount() - 1);
     111        }
     112        inEvent = false;
     113    }
     114
     115    @Override
     116    public void tableChanged(TableModelEvent e) {
     117        if (e.getType() == TableModelEvent.UPDATE) {
     118            if (inEvent)
     119                return;
     120            cleanupGaps();
     121            RoutePatternAction.rebuildWays();
     122        }
     123    }
     124
     125    private Node getLastNode(Way way, String role) {
     126        if ((way == null) || (way.isIncomplete()) || (way.getNodesCount() < 1))
     127            return null;
     128        else {
     129            if ("backward".equals(role))
     130                return way.getNode(0);
     131            else
     132                return way.getNode(way.getNodesCount() - 1);
     133        }
     134    }
     135
     136    private boolean gapNecessary(Way way, String role, Node lastNode) {
     137        if ((way != null) && (!(way.isIncomplete())) && (way.getNodesCount() >= 1)) {
     138            Node firstNode = null;
     139            if ("backward".equals(role))
     140                firstNode = way.getNode(way.getNodesCount() - 1);
     141            else
     142                firstNode = way.getNode(0);
     143            if ((lastNode != null) && (!lastNode.equals(firstNode)))
     144                return true;
     145        }
     146        return false;
     147    }
     148}
  • applications/editors/josm/plugins/public_transport/src/public_transport/PublicTransportAStar.java

    r29854 r32357  
    1010import org.openstreetmap.josm.data.osm.Way;
    1111
    12 public class PublicTransportAStar extends AStarAlgorithm
    13 {
    14     public PublicTransportAStar(Node start, Node end)
    15     {
     12public class PublicTransportAStar extends AStarAlgorithm {
     13    public PublicTransportAStar(Node start, Node end) {
    1614        super(new NodeVertex(start), new NodeVertex(end));
    17     };
     15    }
    1816
    19     public static class NodeVertex extends AStarAlgorithm.Vertex
    20     {
    21         public NodeVertex(Node node)
    22         {
     17    public static class NodeVertex extends AStarAlgorithm.Vertex {
     18        public NodeVertex(Node node) {
    2319            this.node = node;
    2420        }
    2521
    26         public int compareTo(AStarAlgorithm.Vertex v)
    27         {
    28             return this.node.compareTo(((NodeVertex)v).node);
     22        @Override
     23        public int compareTo(AStarAlgorithm.Vertex v) {
     24            return this.node.compareTo(((NodeVertex) v).node);
    2925        }
    3026
    31         public boolean equals(Object o)
    32         {
    33             if ((NodeVertex)o == null)
     27        @Override
     28        public boolean equals(Object o) {
     29            if ((NodeVertex) o == null)
    3430                return false;
    35             return node.equals(((NodeVertex)o).node);
     31            return node.equals(((NodeVertex) o).node);
    3632        }
    3733
    3834        public Node node;
    39     };
     35    }
    4036
    41     public static class PartialWayEdge extends AStarAlgorithm.Edge
    42     {
    43         public PartialWayEdge(Way way, int beginIndex, int endIndex)
    44         {
     37    public static class PartialWayEdge extends AStarAlgorithm.Edge {
     38        public PartialWayEdge(Way way, int beginIndex, int endIndex) {
    4539            this.way = way;
    4640            this.beginIndex = beginIndex;
     
    4842        }
    4943
    50         public AStarAlgorithm.Vertex getBegin()
    51         {
     44        @Override
     45        public AStarAlgorithm.Vertex getBegin() {
    5246            return new NodeVertex(way.getNode(beginIndex));
    5347        }
    5448
    55         public AStarAlgorithm.Vertex getEnd()
    56         {
     49        @Override
     50        public AStarAlgorithm.Vertex getEnd() {
    5751            return new NodeVertex(way.getNode(endIndex));
    5852        }
    5953
    60         public double getLength()
    61         {
     54        @Override
     55        public double getLength() {
    6256            int min = beginIndex;
    6357            int max = endIndex;
    64             if (endIndex < beginIndex)
    65             {
     58            if (endIndex < beginIndex) {
    6659                min = endIndex;
    6760                max = beginIndex;
     
    7063            double totalDistance = 0;
    7164            for (int i = min; i < max; ++i)
    72                 totalDistance += way.getNode(i).getCoor().greatCircleDistance(way.getNode(i+1).getCoor());
     65                totalDistance += way.getNode(i).getCoor()
     66                        .greatCircleDistance(way.getNode(i + 1).getCoor());
    7367            return totalDistance;
    7468        }
    7569
    7670        public Way way;
     71
    7772        public int beginIndex;
     73
    7874        public int endIndex;
    79     };
     75    }
    8076
    81     public Vector< AStarAlgorithm.Edge > getNeighbors(AStarAlgorithm.Vertex vertex)
    82     {
    83         if (waysPerNode == null)
    84         {
    85             waysPerNode = new TreeMap< Node, TreeSet< Way > >();
     77    @Override
     78    public Vector<AStarAlgorithm.Edge> getNeighbors(AStarAlgorithm.Vertex vertex) {
     79        if (waysPerNode == null) {
     80            waysPerNode = new TreeMap<>();
    8681
    87             Iterator< Way > iter = Main.main.getCurrentDataSet().getWays().iterator();
    88             while (iter.hasNext())
    89             {
     82            Iterator<Way> iter = Main.getLayerManager().getEditDataSet().getWays().iterator();
     83            while (iter.hasNext()) {
    9084                Way way = iter.next();
    9185
     
    9690                // Further tests whether the way is eligible.
    9791
    98                 for (int i = 0; i < way.getNodesCount(); ++i)
    99                 {
     92                for (int i = 0; i < way.getNodesCount(); ++i) {
    10093                    if (waysPerNode.get(way.getNode(i)) == null)
    101                         waysPerNode.put(way.getNode(i), new TreeSet< Way >());
     94                        waysPerNode.put(way.getNode(i), new TreeSet<Way>());
    10295                    waysPerNode.get(way.getNode(i)).add(way);
    10396                }
     
    10598        }
    10699
    107         NodeVertex nodeVertex = (NodeVertex)vertex;
     100        NodeVertex nodeVertex = (NodeVertex) vertex;
    108101        System.out.println(nodeVertex.node.getUniqueId());
    109102
    110         Vector< AStarAlgorithm.Edge > result = new Vector< AStarAlgorithm.Edge >();
     103        Vector<AStarAlgorithm.Edge> result = new Vector<>();
    111104        // Determine all ways in which nodeVertex.node is contained.
    112         Iterator< Way > iter = waysPerNode.get(nodeVertex.node).iterator();
    113         while (iter.hasNext())
    114         {
     105        Iterator<Way> iter = waysPerNode.get(nodeVertex.node).iterator();
     106        while (iter.hasNext()) {
    115107            Way way = iter.next();
    116108
     
    121113            // Further tests whether the way is eligible.
    122114
    123             for (int i = 0; i < way.getNodesCount(); ++i)
    124             {
    125                 if (way.getNode(i).equals(nodeVertex.node))
    126                 {
     115            for (int i = 0; i < way.getNodesCount(); ++i) {
     116                if (way.getNode(i).equals(nodeVertex.node)) {
    127117                    if (i > 0)
    128                         result.add(new PartialWayEdge(way, i, i-1));
    129                     if (i < way.getNodesCount()-1)
    130                         result.add(new PartialWayEdge(way, i, i+1));
     118                        result.add(new PartialWayEdge(way, i, i - 1));
     119                    if (i < way.getNodesCount() - 1)
     120                        result.add(new PartialWayEdge(way, i, i + 1));
    131121                }
    132122            }
     
    136126    }
    137127
    138     TreeMap< Node, TreeSet< Way > > waysPerNode = null;
     128    TreeMap<Node, TreeSet<Way>> waysPerNode = null;
    139129
    140     public double estimateDistance(AStarAlgorithm.Vertex vertex)
    141     {
    142         NodeVertex nodeVertex = (NodeVertex)vertex;
    143         return ((NodeVertex)super.end).node.getCoor().greatCircleDistance(nodeVertex.node.getCoor());
     130    @Override
     131    public double estimateDistance(AStarAlgorithm.Vertex vertex) {
     132        NodeVertex nodeVertex = (NodeVertex) vertex;
     133        return ((NodeVertex) super.end).node.getCoor()
     134                .greatCircleDistance(nodeVertex.node.getCoor());
    144135    }
    145136};
  • applications/editors/josm/plugins/public_transport/src/public_transport/PublicTransportPlugin.java

    r31646 r32357  
    1515public class PublicTransportPlugin extends Plugin {
    1616
    17   static JMenu jMenu;
     17    static JMenu jMenu;
    1818
    19   public PublicTransportPlugin(PluginInformation info)
    20   {
    21     super(info);
    22     refreshMenu();
    23   }
     19    public PublicTransportPlugin(PluginInformation info) {
     20        super(info);
     21        refreshMenu();
     22    }
    2423
    25   public static void refreshMenu()
    26   {
    27     MainMenu menu = Main.main.menu;
     24    public static void refreshMenu() {
     25        MainMenu menu = Main.main.menu;
    2826
    29     if (jMenu == null)
    30       jMenu = menu.addMenu("Public Transport", tr("Public Transport"), KeyEvent.VK_COMMA, menu.getDefaultMenuPos(), "help");
    31     else
    32       jMenu.removeAll();
     27        if (jMenu == null)
     28            jMenu = menu.addMenu("Public Transport", tr("Public Transport"), KeyEvent.VK_COMMA,
     29                    menu.getDefaultMenuPos(), "help");
     30        else
     31            jMenu.removeAll();
    3332
    34     jMenu.addSeparator();
    35     jMenu.add(new JMenuItem(new StopImporterAction()));
    36     jMenu.add(new JMenuItem(new RoutePatternAction()));
    37     jMenu.add(new JMenuItem(new GTFSImporterAction()));
    38     setEnabledAll(true);
    39   }
     33        jMenu.addSeparator();
     34        jMenu.add(new JMenuItem(new StopImporterAction()));
     35        jMenu.add(new JMenuItem(new RoutePatternAction()));
     36        jMenu.add(new JMenuItem(new GTFSImporterAction()));
     37        setEnabledAll(true);
     38    }
    4039
    41   private static void setEnabledAll(boolean isEnabled)
    42   {
    43     for(int i=0; i < jMenu.getItemCount(); i++) {
    44       JMenuItem item = jMenu.getItem(i);
     40    private static void setEnabledAll(boolean isEnabled) {
     41        for (int i = 0; i < jMenu.getItemCount(); i++) {
     42            JMenuItem item = jMenu.getItem(i);
    4543
    46       if(item != null) item.setEnabled(isEnabled);
     44            if (item != null)
     45                item.setEnabled(isEnabled);
     46        }
    4747    }
    48   }
    4948}
  • applications/editors/josm/plugins/public_transport/src/public_transport/RoutePatternAction.java

    r31114 r32357  
    5555public class RoutePatternAction extends JosmAction {
    5656
    57   public static int STOPLIST_ROLE_COLUMN = 2;
    58 
    59   private class RoutesLSL implements ListSelectionListener {
    60     RoutePatternAction root = null;
    61 
    62     public RoutesLSL(RoutePatternAction rpa) {
    63       root = rpa;
     57    public static int STOPLIST_ROLE_COLUMN = 2;
     58
     59    private class RoutesLSL implements ListSelectionListener {
     60        RoutePatternAction root = null;
     61
     62        public RoutesLSL(RoutePatternAction rpa) {
     63            root = rpa;
     64        }
     65
     66        @Override
     67        public void valueChanged(ListSelectionEvent e) {
     68            root.routesSelectionChanged();
     69        }
    6470    }
    6571
     72    private class RouteReference implements Comparable<RouteReference> {
     73        Relation route;
     74
     75        public RouteReference(Relation route) {
     76            this.route = route;
     77        }
     78
     79        @Override
     80        public int compareTo(RouteReference rr) {
     81            if (route.get("route") != null) {
     82                if (rr.route.get("route") == null)
     83                    return -1;
     84                int result = route.get("route").compareTo(rr.route.get("route"));
     85                if (result != 0)
     86                    return result;
     87            } else if (rr.route.get("route") != null)
     88                return 1;
     89            if (route.get("ref") != null) {
     90                if (rr.route.get("ref") == null)
     91                    return -1;
     92                int result = route.get("ref").compareTo(rr.route.get("ref"));
     93                if (result != 0)
     94                    return result;
     95            } else if (rr.route.get("ref") != null)
     96                return 1;
     97            if (route.get("to") != null) {
     98                if (rr.route.get("to") == null)
     99                    return -1;
     100                int result = route.get("to").compareTo(rr.route.get("to"));
     101                if (result != 0)
     102                    return result;
     103            } else if (rr.route.get("to") != null)
     104                return 1;
     105            if (route.get("direction") != null) {
     106                if (rr.route.get("direction") == null)
     107                    return -1;
     108                int result = route.get("direction").compareTo(rr.route.get("direction"));
     109                if (result != 0)
     110                    return result;
     111            } else if (rr.route.get("direction") != null)
     112                return 1;
     113            if (route.getId() < rr.route.getId())
     114                return -1;
     115            else if (route.getId() > rr.route.getId())
     116                return 1;
     117            return 0;
     118        }
     119
     120        @Override
     121        public String toString() {
     122            String buf = route.get("route");
     123            if ((route.get("ref") != null) && (route.get("ref") != "")) {
     124                buf += " " + route.get("ref");
     125            }
     126            if ((route.get("loc_ref") != null) && (route.get("loc_ref") != "")) {
     127                buf += " [" + route.get("loc_ref") + "]";
     128            }
     129
     130            if ((route.get("to") != null) && (route.get("to") != "")) {
     131                buf += ": " + route.get("to");
     132            } else if ((route.get("direction") != null) && (route.get("direction") != "")) {
     133                buf += " " + route.get("ref") + ": " + route.get("direction");
     134            } else {
     135                buf += " " + route.get("ref");
     136            }
     137            buf += tr(" [ID] {0}", Long.toString(route.getId()));
     138
     139            return buf;
     140        }
     141    }
     142
     143    private class TagTableModel extends DefaultTableModel implements TableModelListener {
     144        Relation relation = null;
     145
     146        TreeSet<String> blacklist = null;
     147
     148        boolean hasFixedKeys = true;
     149
     150        public TagTableModel(boolean hasFixedKeys) {
     151            this.hasFixedKeys = hasFixedKeys;
     152        }
     153
     154        @Override
     155        public boolean isCellEditable(int row, int column) {
     156            if ((column == 0) && (hasFixedKeys))
     157                return false;
     158            return true;
     159        }
     160
     161        public void readRelation(Relation rel) {
     162            relation = rel;
     163
     164            for (int i = 0; i < getRowCount(); ++i) {
     165                String value = rel.get((String) getValueAt(i, 0));
     166                if (value == null)
     167                    value = "";
     168                setValueAt(value, i, 1);
     169            }
     170        }
     171
     172        public void readRelation(Relation rel, TreeSet<String> blacklist) {
     173            relation = rel;
     174            this.blacklist = blacklist;
     175
     176            setRowCount(0);
     177            Iterator<Map.Entry<String, String>> iter = rel.getKeys().entrySet().iterator();
     178            while (iter.hasNext()) {
     179                Map.Entry<String, String> entry = iter.next();
     180                if (!blacklist.contains(entry.getKey())) {
     181                    Vector<String> newRow = new Vector<>();
     182                    newRow.add(entry.getKey());
     183                    newRow.add(entry.getValue());
     184                    addRow(newRow);
     185                }
     186            }
     187
     188            for (int i = 0; i < getRowCount(); ++i) {
     189                String value = rel.get((String) getValueAt(i, 0));
     190                if (value == null)
     191                    value = "";
     192                setValueAt(value, i, 1);
     193            }
     194        }
     195
     196        @Override
     197        public void tableChanged(TableModelEvent e) {
     198            if (e.getType() == TableModelEvent.UPDATE) {
     199                relation.setModified(true);
     200
     201                String key = (String) getValueAt(e.getFirstRow(), 0);
     202                if (key == null)
     203                    return;
     204                if ((blacklist == null) || (!blacklist.contains(key))) {
     205                    relation.setModified(true);
     206                    if ("".equals(getValueAt(e.getFirstRow(), 1)))
     207                        relation.remove(key);
     208                    else
     209                        relation.put(key, (String) getValueAt(e.getFirstRow(), 1));
     210                } else {
     211                    if (e.getColumn() == 0)
     212                        setValueAt("", e.getFirstRow(), 0);
     213                }
     214            }
     215        }
     216    }
     217
     218    private class CustomCellEditorTable extends JTable {
     219        TreeMap<Integer, TableCellEditor> col1 = null;
     220
     221        TreeMap<Integer, TableCellEditor> col2 = null;
     222
     223        public CustomCellEditorTable() {
     224            col1 = new TreeMap<>();
     225            col2 = new TreeMap<>();
     226        }
     227
     228        @Override
     229        public TableCellEditor getCellEditor(int row, int column) {
     230            TableCellEditor editor = null;
     231            if (column == 0)
     232                editor = col1.get(new Integer(row));
     233            else
     234                editor = col2.get(new Integer(row));
     235            if (editor == null)
     236                return new DefaultCellEditor(new JTextField());
     237            else
     238                return editor;
     239        }
     240
     241        public void setCellEditor(int row, int column, TableCellEditor editor) {
     242            if (column == 0)
     243                col1.put(new Integer(row), editor);
     244            else
     245                col2.put(new Integer(row), editor);
     246        }
     247    }
     248
     249    private class StoplistTableModel extends DefaultTableModel {
     250
     251        public Vector<Node> nodes = new Vector<>();
     252
     253        @Override
     254        public boolean isCellEditable(int row, int column) {
     255            if (column != STOPLIST_ROLE_COLUMN)
     256                return false;
     257            return true;
     258        }
     259
     260        @Override
     261        public void addRow(Object[] obj) {
     262            throw new UnsupportedOperationException();
     263        }
     264
     265        @Override
     266        public void insertRow(int insPos, Object[] obj) {
     267            throw new UnsupportedOperationException();
     268        }
     269
     270        public void addRow(Node node, String role, double distance) {
     271            insertRow(-1, node, role, distance);
     272        }
     273
     274        public void insertRow(int insPos, Node node, String role, double distance) {
     275            String[] buf = { "", "", "", "" };
     276            String curName = node.get("name");
     277            if (curName != null) {
     278                buf[0] = curName;
     279            } else {
     280                buf[0] = tr("[ID] {0}", (new Long(node.getId())).toString());
     281            }
     282            String curRef = node.get("ref");
     283            if (curRef != null) {
     284                buf[1] = curRef;
     285            }
     286            buf[STOPLIST_ROLE_COLUMN] = role;
     287            buf[3] = Double.toString(((double) (int) (distance * 40000 / 360.0 * 100)) / 100);
     288
     289            if (insPos == -1) {
     290                nodes.addElement(node);
     291                super.addRow(buf);
     292            } else {
     293                nodes.insertElementAt(node, insPos);
     294                super.insertRow(insPos, buf);
     295            }
     296        }
     297
     298        public void clear() {
     299            nodes.clear();
     300            super.setRowCount(0);
     301        }
     302    }
     303
     304    private class StoplistTableModelListener implements TableModelListener {
     305        @Override
     306        public void tableChanged(TableModelEvent e) {
     307            if (e.getType() == TableModelEvent.UPDATE) {
     308                rebuildNodes();
     309            }
     310        }
     311    }
     312
     313    private class SegmentMetric {
     314        public double aLat, aLon;
     315
     316        public double length;
     317
     318        public double d1, d2, o1, o2;
     319
     320        public double distance;
     321
     322        public SegmentMetric(double fromLat, double fromLon, double toLat, double toLon,
     323                double distance) {
     324            this.distance = distance;
     325
     326            aLat = fromLat;
     327            aLon = fromLon;
     328
     329            // Compute length and direction
     330            // length is in units of latitude degrees
     331            d1 = toLat - fromLat;
     332            d2 = (toLon - fromLon) * Math.cos(fromLat * Math.PI / 180.0);
     333            length = Math.sqrt(d1 * d1 + d2 * d2);
     334
     335            // Normalise direction
     336            d1 = d1 / length;
     337            d2 = d2 / length;
     338
     339            // Compute orthogonal direction (right hand size is positive)
     340            o1 = -d2;
     341            o2 = d1;
     342
     343            // Prepare lon direction to reduce the number of necessary multiplications
     344            d2 = d2 * Math.cos(fromLat * Math.PI / 180.0);
     345            o2 = o2 * Math.cos(fromLat * Math.PI / 180.0);
     346        }
     347    }
     348
     349    private class StopReference implements Comparable<StopReference> {
     350        public int index = 0;
     351
     352        public double pos = 0;
     353
     354        public double distance = 0;
     355
     356        public String name = "";
     357
     358        public String role = "";
     359
     360        public Node node;
     361
     362        public StopReference(int inIndex, double inPos, double inDistance, String inName,
     363                String inRole, Node inNode) {
     364            index = inIndex;
     365            pos = inPos;
     366            distance = inDistance;
     367            name = inName;
     368            role = inRole;
     369            node = inNode;
     370        }
     371
     372        @Override
     373        public int compareTo(StopReference sr) {
     374            if (this.index < sr.index)
     375                return -1;
     376            if (this.index > sr.index)
     377                return 1;
     378            if (this.pos < sr.pos)
     379                return -1;
     380            if (this.pos > sr.pos)
     381                return 1;
     382            return 0;
     383        }
     384    }
     385
     386    private static JDialog jDialog = null;
     387
     388    private static JTabbedPane tabbedPane = null;
     389
     390    private static DefaultListModel<RouteReference> relsListModel = null;
     391
     392    private static TagTableModel requiredTagsData = null;
     393
     394    private static CustomCellEditorTable requiredTagsTable = null;
     395
     396    private static TagTableModel commonTagsData = null;
     397
     398    private static CustomCellEditorTable commonTagsTable = null;
     399
     400    private static TagTableModel otherTagsData = null;
     401
     402    private static TreeSet<String> tagBlacklist = null;
     403
     404    private static CustomCellEditorTable otherTagsTable = null;
     405
     406    private static ItineraryTableModel itineraryData = null;
     407
     408    private static JTable itineraryTable = null;
     409
     410    private static StoplistTableModel stoplistData = null;
     411
     412    private static JTable stoplistTable = null;
     413
     414    private static JList<RouteReference> relsList = null;
     415
     416    private static JCheckBox cbRight = null;
     417
     418    private static JCheckBox cbLeft = null;
     419
     420    private static JTextField tfSuggestStopsLimit = null;
     421
     422    private static Relation currentRoute = null;
     423
     424    private static Vector<SegmentMetric> segmentMetrics = null;
     425
     426    private static Vector<RelationMember> markedWays = new Vector<>();
     427
     428    private static Vector<RelationMember> markedNodes = new Vector<>();
     429
     430    public RoutePatternAction() {
     431        super(tr("Route patterns ..."), null, tr("Edit Route patterns for public transport"), null,
     432                false);
     433        putValue("toolbar", "publictransport/routepattern");
     434        Main.toolbar.register(this);
     435    }
     436
    66437    @Override
    67     public void valueChanged(ListSelectionEvent e) {
    68       root.routesSelectionChanged();
     438    public void actionPerformed(ActionEvent event) {
     439        Frame frame = JOptionPane.getFrameForComponent(Main.parent);
     440        DataSet mainDataSet = Main.getLayerManager().getEditDataSet();
     441
     442        if (jDialog == null) {
     443            jDialog = new JDialog(frame, tr("Route Patterns"), false);
     444            tabbedPane = new JTabbedPane();
     445            JPanel tabOverview = new JPanel();
     446            tabbedPane.addTab(tr("Overview"), tabOverview);
     447            JPanel tabTags = new JPanel();
     448            tabbedPane.addTab(tr("Tags"), tabTags);
     449            JPanel tabItinerary = new JPanel();
     450            tabbedPane.addTab(tr("Itinerary"), tabItinerary);
     451            JPanel tabStoplist = new JPanel();
     452            tabbedPane.addTab(tr("Stops"), tabStoplist);
     453            JPanel tabMeta = new JPanel();
     454            tabbedPane.addTab(tr("Meta"), tabMeta);
     455            tabbedPane.setEnabledAt(0, true);
     456            tabbedPane.setEnabledAt(1, false);
     457            tabbedPane.setEnabledAt(2, false);
     458            tabbedPane.setEnabledAt(3, false);
     459            tabbedPane.setEnabledAt(4, false);
     460            jDialog.add(tabbedPane);
     461
     462            // Overview Tab
     463            Container contentPane = tabOverview;
     464            GridBagLayout gridbag = new GridBagLayout();
     465            GridBagConstraints layoutCons = new GridBagConstraints();
     466            contentPane.setLayout(gridbag);
     467
     468            JLabel headline = new JLabel(tr("Existing route patterns:"));
     469
     470            layoutCons.gridx = 0;
     471            layoutCons.gridy = 0;
     472            layoutCons.gridwidth = 3;
     473            layoutCons.weightx = 0.0;
     474            layoutCons.weighty = 0.0;
     475            layoutCons.fill = GridBagConstraints.BOTH;
     476            gridbag.setConstraints(headline, layoutCons);
     477            contentPane.add(headline);
     478
     479            relsListModel = new DefaultListModel<>();
     480            relsList = new JList<>(relsListModel);
     481            JScrollPane rpListSP = new JScrollPane(relsList);
     482            String[] data = { "1", "2", "3", "4", "5", "6" };
     483            relsListModel.copyInto(data);
     484            relsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
     485            relsList.addListSelectionListener(new RoutesLSL(this));
     486
     487            layoutCons.gridx = 0;
     488            layoutCons.gridy = 1;
     489            layoutCons.gridwidth = 3;
     490            layoutCons.weightx = 1.0;
     491            layoutCons.weighty = 1.0;
     492            layoutCons.fill = GridBagConstraints.BOTH;
     493            gridbag.setConstraints(rpListSP, layoutCons);
     494            contentPane.add(rpListSP);
     495
     496            JButton bRefresh = new JButton(tr("Refresh"));
     497            bRefresh.setActionCommand("routePattern.refresh");
     498            bRefresh.addActionListener(this);
     499
     500            layoutCons.gridx = 0;
     501            layoutCons.gridy = 2;
     502            layoutCons.gridwidth = 1;
     503            layoutCons.gridheight = 2;
     504            layoutCons.weightx = 1.0;
     505            layoutCons.weighty = 0.0;
     506            layoutCons.fill = GridBagConstraints.BOTH;
     507            gridbag.setConstraints(bRefresh, layoutCons);
     508            contentPane.add(bRefresh);
     509
     510            JButton bNew = new JButton(tr("New"));
     511            bNew.setActionCommand("routePattern.overviewNew");
     512            bNew.addActionListener(this);
     513
     514            layoutCons.gridx = 1;
     515            layoutCons.gridy = 2;
     516            layoutCons.gridwidth = 1;
     517            layoutCons.gridheight = 1;
     518            layoutCons.weightx = 1.0;
     519            layoutCons.weighty = 0.0;
     520            layoutCons.fill = GridBagConstraints.BOTH;
     521            gridbag.setConstraints(bNew, layoutCons);
     522            contentPane.add(bNew);
     523
     524            JButton bDelete = new JButton(tr("Delete"));
     525            bDelete.setActionCommand("routePattern.overviewDelete");
     526            bDelete.addActionListener(this);
     527
     528            layoutCons.gridx = 1;
     529            layoutCons.gridy = 3;
     530            layoutCons.gridwidth = 1;
     531            layoutCons.gridheight = 1;
     532            layoutCons.weightx = 1.0;
     533            layoutCons.weighty = 0.0;
     534            layoutCons.fill = GridBagConstraints.BOTH;
     535            gridbag.setConstraints(bDelete, layoutCons);
     536            contentPane.add(bDelete);
     537
     538            JButton bDuplicate = new JButton(tr("Duplicate"));
     539            bDuplicate.setActionCommand("routePattern.overviewDuplicate");
     540            bDuplicate.addActionListener(this);
     541
     542            layoutCons.gridx = 2;
     543            layoutCons.gridy = 2;
     544            layoutCons.gridwidth = 1;
     545            layoutCons.gridheight = 1;
     546            layoutCons.weightx = 1.0;
     547            layoutCons.weighty = 0.0;
     548            layoutCons.fill = GridBagConstraints.BOTH;
     549            gridbag.setConstraints(bDuplicate, layoutCons);
     550            contentPane.add(bDuplicate);
     551
     552            JButton bReflect = new JButton(tr("Reflect"));
     553            bReflect.setActionCommand("routePattern.overviewReflect");
     554            bReflect.addActionListener(this);
     555
     556            layoutCons.gridx = 2;
     557            layoutCons.gridy = 3;
     558            layoutCons.gridwidth = 1;
     559            layoutCons.gridheight = 1;
     560            layoutCons.weightx = 1.0;
     561            layoutCons.weighty = 0.0;
     562            layoutCons.fill = GridBagConstraints.BOTH;
     563            gridbag.setConstraints(bReflect, layoutCons);
     564            contentPane.add(bReflect);
     565
     566            // Tags Tab
     567            /* Container */ contentPane = tabTags;
     568            /* GridBagLayout */ gridbag = new GridBagLayout();
     569            /* GridBagConstraints */ layoutCons = new GridBagConstraints();
     570            contentPane.setLayout(gridbag);
     571
     572            /* JLabel */ headline = new JLabel(tr("Required tags:"));
     573
     574            layoutCons.gridx = 0;
     575            layoutCons.gridy = 0;
     576            layoutCons.weightx = 0.0;
     577            layoutCons.weighty = 0.0;
     578            layoutCons.fill = GridBagConstraints.BOTH;
     579            gridbag.setConstraints(headline, layoutCons);
     580            contentPane.add(headline);
     581
     582            requiredTagsTable = new CustomCellEditorTable();
     583            requiredTagsData = new TagTableModel(true);
     584            requiredTagsData.addColumn(tr("Key"));
     585            requiredTagsData.addColumn(tr("Value"));
     586            tagBlacklist = new TreeSet<>();
     587            Vector<String> rowContent = new Vector<>();
     588            /* TODO: keys and values should also be translated using TransText class */
     589            rowContent.add("type");
     590            tagBlacklist.add("type");
     591            rowContent.add("route");
     592            requiredTagsData.addRow(rowContent);
     593            JComboBox<String> comboBox = new JComboBox<>();
     594            comboBox.addItem("route");
     595            requiredTagsTable.setCellEditor(0, 1, new DefaultCellEditor(comboBox));
     596            rowContent = new Vector<>();
     597            rowContent.add(0, "route");
     598            tagBlacklist.add("route");
     599            rowContent.add(1, "bus");
     600            requiredTagsData.addRow(rowContent);
     601            /* JComboBox */ comboBox = new JComboBox<>();
     602            comboBox.addItem("bus");
     603            comboBox.addItem("trolleybus");
     604            comboBox.addItem("tram");
     605            comboBox.addItem("light_rail");
     606            comboBox.addItem("subway");
     607            comboBox.addItem("rail");
     608            requiredTagsTable.setCellEditor(1, 1, new DefaultCellEditor(comboBox));
     609            rowContent = new Vector<>();
     610            rowContent.add(0, "ref");
     611            tagBlacklist.add("ref");
     612            rowContent.add(1, "");
     613            requiredTagsData.addRow(rowContent);
     614            rowContent = new Vector<>();
     615            rowContent.add(0, "to");
     616            tagBlacklist.add("to");
     617            rowContent.add(1, "");
     618            requiredTagsData.addRow(rowContent);
     619            rowContent = new Vector<>();
     620            rowContent.add(0, "network");
     621            tagBlacklist.add("network");
     622            rowContent.add(1, "");
     623            requiredTagsData.addRow(rowContent);
     624            requiredTagsTable.setModel(requiredTagsData);
     625            JScrollPane tableSP = new JScrollPane(requiredTagsTable);
     626            requiredTagsData.addTableModelListener(requiredTagsData);
     627
     628            layoutCons.gridx = 0;
     629            layoutCons.gridy = 1;
     630            layoutCons.weightx = 1.0;
     631            layoutCons.weighty = 0.25;
     632            layoutCons.fill = GridBagConstraints.BOTH;
     633            gridbag.setConstraints(tableSP, layoutCons);
     634            Dimension preferredSize = tableSP.getPreferredSize();
     635            preferredSize.setSize(tableSP.getPreferredSize().getWidth(),
     636                    tableSP.getPreferredSize().getHeight() / 4.0);
     637            tableSP.setPreferredSize(preferredSize);
     638            contentPane.add(tableSP);
     639
     640            headline = new JLabel(tr("Common tags:"));
     641
     642            layoutCons.gridx = 0;
     643            layoutCons.gridy = 2;
     644            layoutCons.weightx = 0.0;
     645            layoutCons.weighty = 0.0;
     646            layoutCons.fill = GridBagConstraints.BOTH;
     647            gridbag.setConstraints(headline, layoutCons);
     648            contentPane.add(headline);
     649
     650            commonTagsTable = new CustomCellEditorTable();
     651            commonTagsData = new TagTableModel(true);
     652            commonTagsData.addColumn(tr("Key"));
     653            commonTagsData.addColumn(tr("Value"));
     654            rowContent = new Vector<>();
     655            rowContent.add(0, "loc_ref");
     656            tagBlacklist.add("loc_ref");
     657            rowContent.add(1, "");
     658            commonTagsData.addRow(rowContent);
     659            rowContent = new Vector<>();
     660            rowContent.add(0, "direction");
     661            tagBlacklist.add("direction");
     662            rowContent.add(1, "");
     663            commonTagsData.addRow(rowContent);
     664            rowContent = new Vector<>();
     665            rowContent.add(0, "from");
     666            tagBlacklist.add("from");
     667            rowContent.add(1, "");
     668            commonTagsData.addRow(rowContent);
     669            rowContent = new Vector<>();
     670            rowContent.add(0, "operator");
     671            tagBlacklist.add("operator");
     672            rowContent.add(1, "");
     673            commonTagsData.addRow(rowContent);
     674            rowContent = new Vector<>();
     675            rowContent.add(0, "color");
     676            tagBlacklist.add("color");
     677            rowContent.add(1, "");
     678            commonTagsData.addRow(rowContent);
     679            rowContent = new Vector<>();
     680            rowContent.add(0, "name");
     681            tagBlacklist.add("name");
     682            rowContent.add(1, "");
     683            commonTagsData.addRow(rowContent);
     684            commonTagsTable.setModel(commonTagsData);
     685            /* JScrollPane */ tableSP = new JScrollPane(commonTagsTable);
     686            commonTagsData.addTableModelListener(commonTagsData);
     687
     688            layoutCons.gridx = 0;
     689            layoutCons.gridy = 3;
     690            layoutCons.weightx = 1.0;
     691            layoutCons.weighty = 0.25;
     692            layoutCons.fill = GridBagConstraints.BOTH;
     693            gridbag.setConstraints(tableSP, layoutCons);
     694            /* Dimension */ preferredSize = tableSP.getPreferredSize();
     695            preferredSize.setSize(tableSP.getPreferredSize().getWidth(),
     696                    tableSP.getPreferredSize().getHeight() / 4.0);
     697            tableSP.setPreferredSize(preferredSize);
     698            contentPane.add(tableSP);
     699
     700            headline = new JLabel(tr("Additional tags:"));
     701
     702            layoutCons.gridx = 0;
     703            layoutCons.gridy = 4;
     704            layoutCons.weightx = 0.0;
     705            layoutCons.weighty = 0.0;
     706            layoutCons.fill = GridBagConstraints.BOTH;
     707            gridbag.setConstraints(headline, layoutCons);
     708            contentPane.add(headline);
     709
     710            otherTagsTable = new CustomCellEditorTable();
     711            otherTagsData = new TagTableModel(false);
     712            otherTagsData.addColumn(tr("Key"));
     713            otherTagsData.addColumn(tr("Value"));
     714            otherTagsTable.setModel(otherTagsData);
     715            /* JScrollPane */ tableSP = new JScrollPane(otherTagsTable);
     716            otherTagsData.addTableModelListener(otherTagsData);
     717
     718            layoutCons.gridx = 0;
     719            layoutCons.gridy = 5;
     720            layoutCons.weightx = 1.0;
     721            layoutCons.weighty = 1.0;
     722            layoutCons.fill = GridBagConstraints.BOTH;
     723            gridbag.setConstraints(tableSP, layoutCons);
     724            /* Dimension */ preferredSize = tableSP.getPreferredSize();
     725            preferredSize.setSize(tableSP.getPreferredSize().getWidth(),
     726                    tableSP.getPreferredSize().getHeight() / 2.0);
     727            tableSP.setPreferredSize(preferredSize);
     728            contentPane.add(tableSP);
     729
     730            JButton bAddTag = new JButton(tr("Add a new Tag"));
     731            bAddTag.setActionCommand("routePattern.tagAddTag");
     732            bAddTag.addActionListener(this);
     733
     734            layoutCons.gridx = 0;
     735            layoutCons.gridy = 6;
     736            layoutCons.gridwidth = 1;
     737            layoutCons.weightx = 1.0;
     738            layoutCons.weighty = 0.0;
     739            layoutCons.fill = GridBagConstraints.BOTH;
     740            gridbag.setConstraints(bAddTag, layoutCons);
     741            contentPane.add(bAddTag);
     742
     743            // Itinerary Tab
     744            contentPane = tabItinerary;
     745            gridbag = new GridBagLayout();
     746            layoutCons = new GridBagConstraints();
     747            contentPane.setLayout(gridbag);
     748
     749            itineraryTable = new JTable();
     750            itineraryData = new ItineraryTableModel();
     751            itineraryData.addColumn(tr("Name/Id"));
     752            itineraryData.addColumn(tr("Role"));
     753            itineraryTable.setModel(itineraryData);
     754            /* JScrollPane */ tableSP = new JScrollPane(itineraryTable);
     755            /* JComboBox */ comboBox = new JComboBox<>();
     756            comboBox.addItem("");
     757            comboBox.addItem("forward");
     758            comboBox.addItem("backward");
     759            itineraryTable.getColumnModel().getColumn(1)
     760                    .setCellEditor(new DefaultCellEditor(comboBox));
     761            itineraryData.addTableModelListener(itineraryData);
     762
     763            layoutCons.gridx = 0;
     764            layoutCons.gridy = 0;
     765            layoutCons.gridwidth = 4;
     766            layoutCons.weightx = 1.0;
     767            layoutCons.weighty = 1.0;
     768            layoutCons.fill = GridBagConstraints.BOTH;
     769            gridbag.setConstraints(tableSP, layoutCons);
     770            contentPane.add(tableSP);
     771
     772            JButton bFind = new JButton(tr("Find"));
     773            bFind.setActionCommand("routePattern.itineraryFind");
     774            bFind.addActionListener(this);
     775
     776            layoutCons.gridx = 0;
     777            layoutCons.gridy = 1;
     778            layoutCons.gridwidth = 1;
     779            layoutCons.weightx = 1.0;
     780            layoutCons.weighty = 0.0;
     781            layoutCons.fill = GridBagConstraints.BOTH;
     782            gridbag.setConstraints(bFind, layoutCons);
     783            contentPane.add(bFind);
     784
     785            JButton bShow = new JButton(tr("Show"));
     786            bShow.setActionCommand("routePattern.itineraryShow");
     787            bShow.addActionListener(this);
     788
     789            layoutCons.gridx = 0;
     790            layoutCons.gridy = 2;
     791            layoutCons.gridwidth = 1;
     792            layoutCons.weightx = 1.0;
     793            layoutCons.weighty = 0.0;
     794            layoutCons.fill = GridBagConstraints.BOTH;
     795            gridbag.setConstraints(bShow, layoutCons);
     796            contentPane.add(bShow);
     797
     798            JButton bMark = new JButton(tr("Mark"));
     799            bMark.setActionCommand("routePattern.itineraryMark");
     800            bMark.addActionListener(this);
     801
     802            layoutCons.gridx = 1;
     803            layoutCons.gridy = 1;
     804            layoutCons.gridheight = 2;
     805            layoutCons.gridwidth = 1;
     806            layoutCons.weightx = 1.0;
     807            layoutCons.weighty = 0.0;
     808            layoutCons.fill = GridBagConstraints.BOTH;
     809            gridbag.setConstraints(bMark, layoutCons);
     810            contentPane.add(bMark);
     811
     812            JButton bAdd = new JButton(tr("Add"));
     813            bAdd.setActionCommand("routePattern.itineraryAdd");
     814            bAdd.addActionListener(this);
     815
     816            layoutCons.gridx = 2;
     817            layoutCons.gridy = 1;
     818            layoutCons.gridheight = 1;
     819            layoutCons.gridwidth = 1;
     820            layoutCons.weightx = 1.0;
     821            layoutCons.weighty = 0.0;
     822            layoutCons.fill = GridBagConstraints.BOTH;
     823            gridbag.setConstraints(bAdd, layoutCons);
     824            contentPane.add(bAdd);
     825
     826            /* JButton */ bDelete = new JButton(tr("Delete"));
     827            bDelete.setActionCommand("routePattern.itineraryDelete");
     828            bDelete.addActionListener(this);
     829
     830            layoutCons.gridx = 2;
     831            layoutCons.gridy = 2;
     832            layoutCons.gridwidth = 1;
     833            layoutCons.weightx = 1.0;
     834            layoutCons.weighty = 0.0;
     835            layoutCons.fill = GridBagConstraints.BOTH;
     836            gridbag.setConstraints(bDelete, layoutCons);
     837            contentPane.add(bDelete);
     838
     839            JButton bSort = new JButton(tr("Sort"));
     840            bSort.setActionCommand("routePattern.itinerarySort");
     841            bSort.addActionListener(this);
     842
     843            layoutCons.gridx = 3;
     844            layoutCons.gridy = 1;
     845            layoutCons.gridwidth = 1;
     846            layoutCons.weightx = 1.0;
     847            layoutCons.weighty = 0.0;
     848            layoutCons.fill = GridBagConstraints.BOTH;
     849            gridbag.setConstraints(bSort, layoutCons);
     850            contentPane.add(bSort);
     851
     852            /* JButton */ bReflect = new JButton(tr("Reflect"));
     853            bReflect.setActionCommand("routePattern.itineraryReflect");
     854            bReflect.addActionListener(this);
     855
     856            layoutCons.gridx = 3;
     857            layoutCons.gridy = 2;
     858            layoutCons.gridwidth = 1;
     859            layoutCons.weightx = 1.0;
     860            layoutCons.weighty = 0.0;
     861            layoutCons.fill = GridBagConstraints.BOTH;
     862            gridbag.setConstraints(bReflect, layoutCons);
     863            contentPane.add(bReflect);
     864
     865            // Stoplist Tab
     866            contentPane = tabStoplist;
     867            gridbag = new GridBagLayout();
     868            layoutCons = new GridBagConstraints();
     869            contentPane.setLayout(gridbag);
     870
     871            stoplistTable = new JTable();
     872            stoplistData = new StoplistTableModel();
     873            stoplistData.addColumn(tr("Name/Id"));
     874            stoplistData.addColumn(tr("Ref"));
     875            stoplistData.addColumn(tr("Role"));
     876            stoplistData.addColumn(tr("km"));
     877            stoplistTable.setModel(stoplistData);
     878            /* JScrollPane */ tableSP = new JScrollPane(stoplistTable);
     879            /* JComboBox */ comboBox = new JComboBox<>();
     880            comboBox.addItem("");
     881            comboBox.addItem("forward_stop");
     882            comboBox.addItem("backward_stop");
     883            stoplistTable.getColumnModel().getColumn(STOPLIST_ROLE_COLUMN)
     884                    .setCellEditor(new DefaultCellEditor(comboBox));
     885            stoplistData.addTableModelListener(new StoplistTableModelListener());
     886
     887            layoutCons.gridx = 0;
     888            layoutCons.gridy = 0;
     889            layoutCons.gridwidth = 4;
     890            layoutCons.weightx = 1.0;
     891            layoutCons.weighty = 1.0;
     892            layoutCons.fill = GridBagConstraints.BOTH;
     893            gridbag.setConstraints(tableSP, layoutCons);
     894            contentPane.add(tableSP);
     895
     896            /* JButton */ bFind = new JButton(tr("Find"));
     897            bFind.setActionCommand("routePattern.stoplistFind");
     898            bFind.addActionListener(this);
     899
     900            layoutCons.gridx = 0;
     901            layoutCons.gridy = 1;
     902            layoutCons.gridwidth = 1;
     903            layoutCons.weightx = 1.0;
     904            layoutCons.weighty = 0.0;
     905            layoutCons.fill = GridBagConstraints.BOTH;
     906            gridbag.setConstraints(bFind, layoutCons);
     907            contentPane.add(bFind);
     908
     909            /* JButton */ bShow = new JButton(tr("Show"));
     910            bShow.setActionCommand("routePattern.stoplistShow");
     911            bShow.addActionListener(this);
     912
     913            layoutCons.gridx = 0;
     914            layoutCons.gridy = 2;
     915            layoutCons.gridwidth = 1;
     916            layoutCons.weightx = 1.0;
     917            layoutCons.weighty = 0.0;
     918            layoutCons.fill = GridBagConstraints.BOTH;
     919            gridbag.setConstraints(bShow, layoutCons);
     920            contentPane.add(bShow);
     921
     922            /* JButton */ bMark = new JButton(tr("Mark"));
     923            bMark.setActionCommand("routePattern.stoplistMark");
     924            bMark.addActionListener(this);
     925
     926            layoutCons.gridx = 1;
     927            layoutCons.gridy = 1;
     928            layoutCons.gridheight = 2;
     929            layoutCons.gridwidth = 1;
     930            layoutCons.weightx = 1.0;
     931            layoutCons.weighty = 0.0;
     932            layoutCons.fill = GridBagConstraints.BOTH;
     933            gridbag.setConstraints(bMark, layoutCons);
     934            contentPane.add(bMark);
     935
     936            /* JButton */ bAdd = new JButton(tr("Add"));
     937            bAdd.setActionCommand("routePattern.stoplistAdd");
     938            bAdd.addActionListener(this);
     939
     940            layoutCons.gridx = 2;
     941            layoutCons.gridy = 1;
     942            layoutCons.gridheight = 1;
     943            layoutCons.gridwidth = 1;
     944            layoutCons.weightx = 1.0;
     945            layoutCons.weighty = 0.0;
     946            layoutCons.fill = GridBagConstraints.BOTH;
     947            gridbag.setConstraints(bAdd, layoutCons);
     948            contentPane.add(bAdd);
     949
     950            /* JButton */ bDelete = new JButton(tr("Delete"));
     951            bDelete.setActionCommand("routePattern.stoplistDelete");
     952            bDelete.addActionListener(this);
     953
     954            layoutCons.gridx = 2;
     955            layoutCons.gridy = 2;
     956            layoutCons.gridwidth = 1;
     957            layoutCons.weightx = 1.0;
     958            layoutCons.weighty = 0.0;
     959            layoutCons.fill = GridBagConstraints.BOTH;
     960            gridbag.setConstraints(bDelete, layoutCons);
     961            contentPane.add(bDelete);
     962
     963            /* JButton */ bSort = new JButton(tr("Sort"));
     964            bSort.setActionCommand("routePattern.stoplistSort");
     965            bSort.addActionListener(this);
     966
     967            layoutCons.gridx = 3;
     968            layoutCons.gridy = 1;
     969            layoutCons.gridwidth = 1;
     970            layoutCons.weightx = 1.0;
     971            layoutCons.weighty = 0.0;
     972            layoutCons.fill = GridBagConstraints.BOTH;
     973            gridbag.setConstraints(bSort, layoutCons);
     974            contentPane.add(bSort);
     975
     976            /* JButton */ bReflect = new JButton(tr("Reflect"));
     977            bReflect.setActionCommand("routePattern.stoplistReflect");
     978            bReflect.addActionListener(this);
     979
     980            layoutCons.gridx = 3;
     981            layoutCons.gridy = 2;
     982            layoutCons.gridwidth = 1;
     983            layoutCons.weightx = 1.0;
     984            layoutCons.weighty = 0.0;
     985            layoutCons.fill = GridBagConstraints.BOTH;
     986            gridbag.setConstraints(bReflect, layoutCons);
     987            contentPane.add(bReflect);
     988
     989            // Meta Tab
     990            contentPane = tabMeta;
     991            gridbag = new GridBagLayout();
     992            layoutCons = new GridBagConstraints();
     993            contentPane.setLayout(gridbag);
     994
     995            JLabel rightleft = new JLabel(tr("Stops are possible on the"));
     996
     997            layoutCons.gridx = 0;
     998            layoutCons.gridy = 1;
     999            layoutCons.gridwidth = 2;
     1000            layoutCons.weightx = 0.0;
     1001            layoutCons.weighty = 0.0;
     1002            layoutCons.fill = GridBagConstraints.BOTH;
     1003            gridbag.setConstraints(rightleft, layoutCons);
     1004            contentPane.add(rightleft);
     1005
     1006            cbRight = new JCheckBox(tr("right hand side"), true);
     1007
     1008            layoutCons.gridx = 0;
     1009            layoutCons.gridy = 2;
     1010            layoutCons.gridwidth = 2;
     1011            layoutCons.weightx = 0.0;
     1012            layoutCons.weighty = 0.0;
     1013            layoutCons.fill = GridBagConstraints.BOTH;
     1014            gridbag.setConstraints(cbRight, layoutCons);
     1015            contentPane.add(cbRight);
     1016
     1017            cbLeft = new JCheckBox(tr("left hand side"), false);
     1018
     1019            layoutCons.gridx = 0;
     1020            layoutCons.gridy = 3;
     1021            layoutCons.gridwidth = 2;
     1022            layoutCons.weightx = 0.0;
     1023            layoutCons.weighty = 0.0;
     1024            layoutCons.fill = GridBagConstraints.BOTH;
     1025            gridbag.setConstraints(cbLeft, layoutCons);
     1026            contentPane.add(cbLeft);
     1027
     1028            JLabel maxdist = new JLabel(tr("Maximum distance from route"));
     1029
     1030            layoutCons.gridx = 0;
     1031            layoutCons.gridy = 4;
     1032            layoutCons.gridwidth = 2;
     1033            layoutCons.weightx = 0.0;
     1034            layoutCons.weighty = 0.0;
     1035            layoutCons.fill = GridBagConstraints.BOTH;
     1036            gridbag.setConstraints(maxdist, layoutCons);
     1037            contentPane.add(maxdist);
     1038
     1039            tfSuggestStopsLimit = new JTextField("20", 4);
     1040
     1041            layoutCons.gridx = 0;
     1042            layoutCons.gridy = 5;
     1043            layoutCons.gridwidth = 1;
     1044            layoutCons.weightx = 0.0;
     1045            layoutCons.weighty = 0.0;
     1046            layoutCons.fill = GridBagConstraints.BOTH;
     1047            gridbag.setConstraints(tfSuggestStopsLimit, layoutCons);
     1048            contentPane.add(tfSuggestStopsLimit);
     1049
     1050            JLabel meters = new JLabel(tr("meters"));
     1051
     1052            layoutCons.gridx = 1;
     1053            layoutCons.gridy = 5;
     1054            layoutCons.gridwidth = 1;
     1055            layoutCons.weightx = 0.0;
     1056            layoutCons.weighty = 0.0;
     1057            layoutCons.fill = GridBagConstraints.BOTH;
     1058            gridbag.setConstraints(meters, layoutCons);
     1059            contentPane.add(meters);
     1060
     1061            JButton bSuggestStops = new JButton(tr("Suggest Stops"));
     1062            bSuggestStops.setActionCommand("routePattern.metaSuggestStops");
     1063            bSuggestStops.addActionListener(this);
     1064
     1065            layoutCons.gridx = 0;
     1066            layoutCons.gridy = 6;
     1067            layoutCons.gridwidth = 3;
     1068            layoutCons.weightx = 1.0;
     1069            layoutCons.weighty = 0.0;
     1070            layoutCons.fill = GridBagConstraints.BOTH;
     1071            gridbag.setConstraints(bSuggestStops, layoutCons);
     1072            contentPane.add(bSuggestStops);
     1073
     1074            jDialog.pack();
     1075        }
     1076
     1077        if ("routePattern.refresh".equals(event.getActionCommand())) {
     1078            refreshData();
     1079        } else if ("routePattern.overviewNew".equals(event.getActionCommand())) {
     1080            currentRoute = new Relation();
     1081            currentRoute.put("type", "route");
     1082            currentRoute.put("route", "bus");
     1083            mainDataSet.addPrimitive(currentRoute);
     1084
     1085            refreshData();
     1086
     1087            for (int i = 0; i < relsListModel.size(); ++i) {
     1088                if (currentRoute == relsListModel.elementAt(i).route)
     1089                    relsList.setSelectedIndex(i);
     1090            }
     1091        } else if ("routePattern.overviewDuplicate".equals(event.getActionCommand())) {
     1092            currentRoute = new Relation(currentRoute, true);
     1093            currentRoute.put("type", "route");
     1094            currentRoute.put("route", "bus");
     1095            mainDataSet.addPrimitive(currentRoute);
     1096
     1097            refreshData();
     1098
     1099            for (int i = 0; i < relsListModel.size(); ++i) {
     1100                if (currentRoute == relsListModel.elementAt(i).route)
     1101                    relsList.setSelectedIndex(i);
     1102            }
     1103        } else if ("routePattern.overviewReflect".equals(event.getActionCommand())) {
     1104            currentRoute.setModified(true);
     1105            String tag_from = currentRoute.get("from");
     1106            String tag_to = currentRoute.get("to");
     1107            currentRoute.put("from", tag_to);
     1108            currentRoute.put("to", tag_from);
     1109
     1110            Vector<RelationMember> itemsToReflect = new Vector<>();
     1111            Vector<RelationMember> otherItems = new Vector<>();
     1112
     1113            // Temp
     1114            Node firstNode = null;
     1115            // Node lastNode = null;
     1116
     1117            for (int i = 0; i < currentRoute.getMembersCount(); ++i) {
     1118                RelationMember item = currentRoute.getMember(i);
     1119
     1120                if (item.isWay()) {
     1121                    String role = item.getRole();
     1122                    if ("backward".equals(role))
     1123                        role = "forward";
     1124                    else if ("forward".equals(role))
     1125                        role = "backward";
     1126                    else
     1127                        role = "backward";
     1128
     1129                    itemsToReflect.add(new RelationMember(role, item.getWay()));
     1130
     1131                    // Temp
     1132                    if (firstNode == null) {
     1133                        firstNode = item.getWay().getNode(0);
     1134                    }
     1135                    // lastNode = item.getWay().getNode(item.getWay().getNodesCount() - 1);
     1136                } else if (item.isNode())
     1137                    itemsToReflect.add(item);
     1138                else
     1139                    otherItems.add(item);
     1140            }
     1141
     1142            currentRoute.setMembers(null);
     1143            for (int i = itemsToReflect.size() - 1; i >= 0; --i)
     1144                currentRoute.addMember(itemsToReflect.elementAt(i));
     1145            for (int i = 0; i < otherItems.size(); ++i)
     1146                currentRoute.addMember(otherItems.elementAt(i));
     1147
     1148            refreshData();
     1149
     1150            for (int i = 0; i < relsListModel.size(); ++i) {
     1151                if (currentRoute == relsListModel.elementAt(i).route)
     1152                    relsList.setSelectedIndex(i);
     1153            }
     1154
     1155            // Temp
     1156            /*
     1157             * if (firstNode != null) { Vector< AStarAlgorithm.Edge > path = new PublicTransportAStar(firstNode, lastNode).shortestPath(); Iterator<
     1158             * AStarAlgorithm.Edge > iter = path.iterator(); while (iter.hasNext()) { PublicTransportAStar.PartialWayEdge edge =
     1159             * (PublicTransportAStar.PartialWayEdge)iter.next(); System.out.print(edge.way.getUniqueId()); System.out.print("\t");
     1160             * System.out.print(edge.beginIndex); System.out.print("\t"); System.out.print(edge.endIndex); System.out.print("\n"); } }
     1161             */
     1162        } else if ("routePattern.overviewDelete".equals(event.getActionCommand())) {
     1163            DeleteAction.deleteRelation(Main.getLayerManager().getEditLayer(), currentRoute);
     1164
     1165            currentRoute = null;
     1166            tabbedPane.setEnabledAt(1, false);
     1167            tabbedPane.setEnabledAt(2, false);
     1168            tabbedPane.setEnabledAt(3, false);
     1169            tabbedPane.setEnabledAt(4, false);
     1170
     1171            refreshData();
     1172        } else if ("routePattern.tagAddTag".equals(event.getActionCommand())) {
     1173            Vector<String> rowContent = new Vector<>();
     1174            rowContent.add("");
     1175            rowContent.add("");
     1176            otherTagsData.addRow(rowContent);
     1177        } else if ("routePattern.itineraryFind".equals(event.getActionCommand())) {
     1178            if (mainDataSet == null)
     1179                return;
     1180
     1181            itineraryTable.clearSelection();
     1182
     1183            for (int i = 0; i < itineraryData.getRowCount(); ++i) {
     1184                if ((itineraryData.ways.elementAt(i) != null)
     1185                        && (mainDataSet.isSelected(itineraryData.ways.elementAt(i))))
     1186                    itineraryTable.addRowSelectionInterval(i, i);
     1187            }
     1188        } else if ("routePattern.itineraryShow".equals(event.getActionCommand())) {
     1189            BoundingXYVisitor box = new BoundingXYVisitor();
     1190            if (itineraryTable.getSelectedRowCount() > 0) {
     1191                for (int i = 0; i < itineraryData.getRowCount(); ++i) {
     1192                    if ((itineraryTable.isRowSelected(i))
     1193                            && (itineraryData.ways.elementAt(i) != null)) {
     1194                        itineraryData.ways.elementAt(i).accept(box);
     1195                    }
     1196                }
     1197            } else {
     1198                for (int i = 0; i < itineraryData.getRowCount(); ++i) {
     1199                    if (itineraryData.ways.elementAt(i) != null) {
     1200                        itineraryData.ways.elementAt(i).accept(box);
     1201                    }
     1202                }
     1203            }
     1204            if (box.getBounds() == null)
     1205                return;
     1206            box.enlargeBoundingBox();
     1207            Main.map.mapView.zoomTo(box);
     1208        } else if ("routePattern.itineraryMark".equals(event.getActionCommand())) {
     1209            OsmPrimitive[] osmp = { null };
     1210            Main.getLayerManager().getEditDataSet().setSelected(osmp);
     1211            markedWays.clear();
     1212            if (itineraryTable.getSelectedRowCount() > 0) {
     1213                for (int i = 0; i < itineraryData.getRowCount(); ++i) {
     1214                    if ((itineraryTable.isRowSelected(i))
     1215                            && (itineraryData.ways.elementAt(i) != null)) {
     1216                        mainDataSet.addSelected(itineraryData.ways.elementAt(i));
     1217
     1218                        RelationMember markedWay = new RelationMember(
     1219                                (String) (itineraryData.getValueAt(i, 1)),
     1220                                itineraryData.ways.elementAt(i));
     1221                        markedWays.addElement(markedWay);
     1222                    }
     1223                }
     1224            } else {
     1225                for (int i = 0; i < itineraryData.getRowCount(); ++i) {
     1226                    if (itineraryData.ways.elementAt(i) != null) {
     1227                        mainDataSet.addSelected(itineraryData.ways.elementAt(i));
     1228
     1229                        RelationMember markedWay = new RelationMember(
     1230                                (String) (itineraryData.getValueAt(i, 1)),
     1231                                itineraryData.ways.elementAt(i));
     1232                        markedWays.addElement(markedWay);
     1233                    }
     1234                }
     1235            }
     1236        } else if ("routePattern.itineraryAdd".equals(event.getActionCommand())) {
     1237            int insPos = itineraryTable.getSelectedRow();
     1238            Iterator<RelationMember> relIter = markedWays.iterator();
     1239            TreeSet<Way> addedWays = new TreeSet<>();
     1240            if (mainDataSet == null)
     1241                return;
     1242
     1243            while (relIter.hasNext()) {
     1244                RelationMember curMember = relIter.next();
     1245                if ((curMember.isWay()) && (mainDataSet.isSelected(curMember.getWay()))) {
     1246                    itineraryData.insertRow(insPos, curMember.getWay(), curMember.getRole());
     1247                    if (insPos >= 0)
     1248                        ++insPos;
     1249
     1250                    addedWays.add(curMember.getWay());
     1251                }
     1252            }
     1253
     1254            Collection<Way> selectedWays = mainDataSet.getSelectedWays();
     1255            Iterator<Way> wayIter = selectedWays.iterator();
     1256
     1257            while (wayIter.hasNext()) {
     1258                Way curMember = wayIter.next();
     1259                if (!(addedWays.contains(curMember))) {
     1260                    itineraryData.insertRow(insPos, curMember, "");
     1261                    if (insPos >= 0)
     1262                        ++insPos;
     1263                }
     1264            }
     1265
     1266            if ((insPos > 0) && (insPos < itineraryData.getRowCount())) {
     1267                while ((insPos < itineraryData.getRowCount())
     1268                        && (itineraryData.ways.elementAt(insPos) == null))
     1269                    ++insPos;
     1270                itineraryTable.removeRowSelectionInterval(0, itineraryData.getRowCount() - 1);
     1271                if (insPos < itineraryData.getRowCount())
     1272                    itineraryTable.addRowSelectionInterval(insPos, insPos);
     1273            }
     1274
     1275            itineraryData.cleanupGaps();
     1276            segmentMetrics = fillSegmentMetrics();
     1277            rebuildWays();
     1278        } else if ("routePattern.itineraryDelete".equals(event.getActionCommand())) {
     1279            for (int i = itineraryData.getRowCount() - 1; i >= 0; --i) {
     1280                if ((itineraryTable.isRowSelected(i))
     1281                        && (itineraryData.ways.elementAt(i) != null)) {
     1282                    itineraryData.ways.removeElementAt(i);
     1283                    itineraryData.removeRow(i);
     1284                }
     1285            }
     1286
     1287            itineraryData.cleanupGaps();
     1288            segmentMetrics = fillSegmentMetrics();
     1289            rebuildWays();
     1290        } else if ("routePattern.itinerarySort".equals(event.getActionCommand())) {
     1291            TreeSet<Way> usedWays = new TreeSet<>();
     1292            TreeMap<Node, LinkedList<RelationMember>> frontNodes = new TreeMap<>();
     1293            TreeMap<Node, LinkedList<RelationMember>> backNodes = new TreeMap<>();
     1294            Vector<LinkedList<RelationMember>> loops = new Vector<>();
     1295            int insPos = itineraryTable.getSelectedRow();
     1296
     1297            if (itineraryTable.getSelectedRowCount() > 0) {
     1298                for (int i = itineraryData.getRowCount() - 1; i >= 0; --i) {
     1299                    if ((itineraryTable.isRowSelected(i))
     1300                            && (itineraryData.ways.elementAt(i) != null)) {
     1301                        if (!(usedWays.contains(itineraryData.ways.elementAt(i)))) {
     1302                            addWayToSortingData(itineraryData.ways.elementAt(i), frontNodes,
     1303                                    backNodes, loops);
     1304                            usedWays.add(itineraryData.ways.elementAt(i));
     1305                        }
     1306
     1307                        itineraryData.ways.removeElementAt(i);
     1308                        itineraryData.removeRow(i);
     1309                    }
     1310                }
     1311            } else {
     1312                for (int i = itineraryData.getRowCount() - 1; i >= 0; --i) {
     1313                    if (itineraryData.ways.elementAt(i) != null) {
     1314                        if (!(usedWays.contains(itineraryData.ways.elementAt(i)))) {
     1315                            addWayToSortingData(itineraryData.ways.elementAt(i), frontNodes,
     1316                                    backNodes, loops);
     1317                            usedWays.add(itineraryData.ways.elementAt(i));
     1318                        }
     1319                    }
     1320                }
     1321
     1322                itineraryData.clear();
     1323            }
     1324
     1325            Iterator<Map.Entry<Node, LinkedList<RelationMember>>> entryIter = frontNodes.entrySet()
     1326                    .iterator();
     1327            while (entryIter.hasNext()) {
     1328                Iterator<RelationMember> relIter = entryIter.next().getValue().iterator();
     1329                while (relIter.hasNext()) {
     1330                    RelationMember curMember = relIter.next();
     1331                    itineraryData.insertRow(insPos, curMember.getWay(), curMember.getRole());
     1332                    if (insPos >= 0)
     1333                        ++insPos;
     1334                }
     1335            }
     1336
     1337            Iterator<LinkedList<RelationMember>> listIter = loops.iterator();
     1338            while (listIter.hasNext()) {
     1339                Iterator<RelationMember> relIter = listIter.next().iterator();
     1340                while (relIter.hasNext()) {
     1341                    RelationMember curMember = relIter.next();
     1342                    itineraryData.insertRow(insPos, curMember.getWay(), curMember.getRole());
     1343                    if (insPos >= 0)
     1344                        ++insPos;
     1345                }
     1346            }
     1347
     1348            itineraryData.cleanupGaps();
     1349            segmentMetrics = fillSegmentMetrics();
     1350            rebuildWays();
     1351        } else if ("routePattern.itineraryReflect".equals(event.getActionCommand())) {
     1352            Vector<RelationMember> itemsToReflect = new Vector<>();
     1353            int insPos = itineraryTable.getSelectedRow();
     1354
     1355            if (itineraryTable.getSelectedRowCount() > 0) {
     1356                for (int i = itineraryData.getRowCount() - 1; i >= 0; --i) {
     1357                    if ((itineraryTable.isRowSelected(i))
     1358                            && (itineraryData.ways.elementAt(i) != null)) {
     1359                        String role = (String) (itineraryData.getValueAt(i, 1));
     1360                        if ("backward".equals(role))
     1361                            role = "forward";
     1362                        else if ("forward".equals(role))
     1363                            role = "backward";
     1364                        else
     1365                            role = "backward";
     1366                        RelationMember markedWay = new RelationMember(role,
     1367                                itineraryData.ways.elementAt(i));
     1368                        itemsToReflect.addElement(markedWay);
     1369
     1370                        itineraryData.ways.removeElementAt(i);
     1371                        itineraryData.removeRow(i);
     1372                    }
     1373                }
     1374            } else {
     1375                for (int i = itineraryData.getRowCount() - 1; i >= 0; --i) {
     1376                    if (itineraryData.ways.elementAt(i) != null) {
     1377                        String role = (String) (itineraryData.getValueAt(i, 1));
     1378                        if ("backward".equals(role))
     1379                            role = "forward";
     1380                        else if ("forward".equals(role))
     1381                            role = "backward";
     1382                        else
     1383                            role = "backward";
     1384                        RelationMember markedWay = new RelationMember(role,
     1385                                itineraryData.ways.elementAt(i));
     1386                        itemsToReflect.addElement(markedWay);
     1387                    }
     1388                }
     1389
     1390                itineraryData.clear();
     1391            }
     1392
     1393            int startPos = insPos;
     1394            Iterator<RelationMember> relIter = itemsToReflect.iterator();
     1395            while (relIter.hasNext()) {
     1396                RelationMember curMember = relIter.next();
     1397                if (curMember.isWay()) {
     1398                    itineraryData.insertRow(insPos, curMember.getWay(), curMember.getRole());
     1399                    if (insPos >= 0)
     1400                        ++insPos;
     1401                }
     1402            }
     1403            if (insPos >= 0)
     1404                itineraryTable.addRowSelectionInterval(startPos, insPos - 1);
     1405
     1406            itineraryData.cleanupGaps();
     1407            segmentMetrics = fillSegmentMetrics();
     1408            rebuildWays();
     1409        } else if ("routePattern.stoplistFind".equals(event.getActionCommand())) {
     1410            if (mainDataSet == null)
     1411                return;
     1412
     1413            stoplistTable.clearSelection();
     1414
     1415            for (int i = 0; i < stoplistData.getRowCount(); ++i) {
     1416                if ((stoplistData.nodes.elementAt(i) != null)
     1417                        && (mainDataSet.isSelected(stoplistData.nodes.elementAt(i))))
     1418                    stoplistTable.addRowSelectionInterval(i, i);
     1419            }
     1420        } else if ("routePattern.stoplistShow".equals(event.getActionCommand())) {
     1421            BoundingXYVisitor box = new BoundingXYVisitor();
     1422            if (stoplistTable.getSelectedRowCount() > 0) {
     1423                for (int i = 0; i < stoplistData.getRowCount(); ++i) {
     1424                    if (stoplistTable.isRowSelected(i)) {
     1425                        stoplistData.nodes.elementAt(i).accept(box);
     1426                    }
     1427                }
     1428            } else {
     1429                for (int i = 0; i < stoplistData.getRowCount(); ++i) {
     1430                    stoplistData.nodes.elementAt(i).accept(box);
     1431                }
     1432            }
     1433            if (box.getBounds() == null)
     1434                return;
     1435            box.enlargeBoundingBox();
     1436            Main.map.mapView.zoomTo(box);
     1437        } else if ("routePattern.stoplistMark".equals(event.getActionCommand())) {
     1438            OsmPrimitive[] osmp = { null };
     1439            Main.getLayerManager().getEditDataSet().setSelected(osmp);
     1440            markedNodes.clear();
     1441            if (stoplistTable.getSelectedRowCount() > 0) {
     1442                for (int i = 0; i < stoplistData.getRowCount(); ++i) {
     1443                    if (stoplistTable.isRowSelected(i)) {
     1444                        mainDataSet.addSelected(stoplistData.nodes.elementAt(i));
     1445
     1446                        RelationMember markedNode = new RelationMember(
     1447                                (String) (stoplistData.getValueAt(i, 1)),
     1448                                stoplistData.nodes.elementAt(i));
     1449                        markedNodes.addElement(markedNode);
     1450                    }
     1451                }
     1452            } else {
     1453                for (int i = 0; i < stoplistData.getRowCount(); ++i) {
     1454                    mainDataSet.addSelected(stoplistData.nodes.elementAt(i));
     1455
     1456                    RelationMember markedNode = new RelationMember(
     1457                            (String) (stoplistData.getValueAt(i, 1)),
     1458                            stoplistData.nodes.elementAt(i));
     1459                    markedNodes.addElement(markedNode);
     1460                }
     1461            }
     1462        } else if ("routePattern.stoplistAdd".equals(event.getActionCommand())) {
     1463            int insPos = stoplistTable.getSelectedRow();
     1464            Iterator<RelationMember> relIter = markedNodes.iterator();
     1465            TreeSet<Node> addedNodes = new TreeSet<>();
     1466            if (mainDataSet == null)
     1467                return;
     1468
     1469            while (relIter.hasNext()) {
     1470                RelationMember curMember = relIter.next();
     1471                if ((curMember.isNode()) && (mainDataSet.isSelected(curMember.getNode()))) {
     1472                    StopReference sr = detectMinDistance(curMember.getNode(), segmentMetrics,
     1473                            cbRight.isSelected(), cbLeft.isSelected());
     1474                    stoplistData.insertRow(insPos, curMember.getNode(), curMember.getRole(),
     1475                            calcOffset(sr, segmentMetrics));
     1476                    if (insPos >= 0)
     1477                        ++insPos;
     1478
     1479                    addedNodes.add(curMember.getNode());
     1480                }
     1481            }
     1482
     1483            Collection<Node> selectedNodes = mainDataSet.getSelectedNodes();
     1484            Iterator<Node> nodeIter = selectedNodes.iterator();
     1485
     1486            while (nodeIter.hasNext()) {
     1487                Node curMember = nodeIter.next();
     1488                if (!(addedNodes.contains(curMember))) {
     1489                    StopReference sr = detectMinDistance(curMember, segmentMetrics,
     1490                            cbRight.isSelected(), cbLeft.isSelected());
     1491                    stoplistData.insertRow(insPos, curMember, "", calcOffset(sr, segmentMetrics));
     1492                    if (insPos >= 0)
     1493                        ++insPos;
     1494                }
     1495            }
     1496
     1497            if ((insPos > 0) && (insPos < stoplistData.getRowCount())) {
     1498                while ((insPos < stoplistData.getRowCount())
     1499                        && (stoplistData.nodes.elementAt(insPos) == null))
     1500                    ++insPos;
     1501                stoplistTable.removeRowSelectionInterval(0, stoplistData.getRowCount() - 1);
     1502                if (insPos < stoplistData.getRowCount())
     1503                    stoplistTable.addRowSelectionInterval(insPos, insPos);
     1504            }
     1505
     1506            rebuildNodes();
     1507        } else if ("routePattern.stoplistDelete".equals(event.getActionCommand())) {
     1508            for (int i = stoplistData.getRowCount() - 1; i >= 0; --i) {
     1509                if (stoplistTable.isRowSelected(i)) {
     1510                    stoplistData.nodes.removeElementAt(i);
     1511                    stoplistData.removeRow(i);
     1512                }
     1513            }
     1514
     1515            rebuildNodes();
     1516        } else if ("routePattern.stoplistSort".equals(event.getActionCommand())) {
     1517            // Prepare Segments: The segments of all usable ways are arranged in a linear
     1518            // list such that a coor can directly be checked concerning position and offset
     1519            Vector<StopReference> srm = new Vector<>();
     1520            int insPos = stoplistTable.getSelectedRow();
     1521            if (stoplistTable.getSelectedRowCount() > 0) {
     1522                // Determine for each member its position on the itinerary: position means here the
     1523                // point on the itinerary that has minimal distance to the coor
     1524                for (int i = stoplistData.getRowCount() - 1; i >= 0; --i) {
     1525                    if (stoplistTable.isRowSelected(i)) {
     1526                        StopReference sr = detectMinDistance(stoplistData.nodes.elementAt(i),
     1527                                segmentMetrics, cbRight.isSelected(), cbLeft.isSelected());
     1528                        if (sr != null) {
     1529                            if (sr.distance < Double.parseDouble(tfSuggestStopsLimit.getText())
     1530                                    * 9.0 / 1000000.0) {
     1531                                sr.role = (String) stoplistData.getValueAt(i, STOPLIST_ROLE_COLUMN);
     1532                                srm.addElement(sr);
     1533                            } else {
     1534                                sr.role = (String) stoplistData.getValueAt(i, STOPLIST_ROLE_COLUMN);
     1535                                sr.index = segmentMetrics.size() * 2;
     1536                                sr.pos = 0;
     1537                                srm.addElement(sr);
     1538                            }
     1539
     1540                            stoplistData.nodes.removeElementAt(i);
     1541                            stoplistData.removeRow(i);
     1542                        }
     1543                    }
     1544                }
     1545            } else {
     1546                // Determine for each member its position on the itinerary: position means here the
     1547                // point on the itinerary that has minimal distance to the coor
     1548                for (int i = stoplistData.getRowCount() - 1; i >= 0; --i) {
     1549                    StopReference sr = detectMinDistance(stoplistData.nodes.elementAt(i),
     1550                            segmentMetrics, cbRight.isSelected(), cbLeft.isSelected());
     1551                    if (sr != null) {
     1552                        if (sr.distance < Double.parseDouble(tfSuggestStopsLimit.getText()) * 9.0
     1553                                / 1000000.0) {
     1554                            sr.role = (String) stoplistData.getValueAt(i, STOPLIST_ROLE_COLUMN);
     1555                            srm.addElement(sr);
     1556                        } else {
     1557                            sr.role = (String) stoplistData.getValueAt(i, STOPLIST_ROLE_COLUMN);
     1558                            sr.index = segmentMetrics.size() * 2;
     1559                            sr.pos = 0;
     1560                            srm.addElement(sr);
     1561                        }
     1562                    }
     1563                }
     1564
     1565                stoplistData.clear();
     1566            }
     1567
     1568            Collections.sort(srm);
     1569
     1570            for (int i = 0; i < srm.size(); ++i) {
     1571                StopReference sr = detectMinDistance(srm.elementAt(i).node, segmentMetrics,
     1572                        cbRight.isSelected(), cbLeft.isSelected());
     1573                stoplistData.insertRow(insPos, srm.elementAt(i).node, srm.elementAt(i).role,
     1574                        calcOffset(sr, segmentMetrics));
     1575                if (insPos >= 0)
     1576                    ++insPos;
     1577            }
     1578
     1579            rebuildNodes();
     1580        } else if ("routePattern.stoplistReflect".equals(event.getActionCommand())) {
     1581            Vector<RelationMember> itemsToReflect = new Vector<>();
     1582            int insPos = stoplistTable.getSelectedRow();
     1583
     1584            if (stoplistTable.getSelectedRowCount() > 0) {
     1585                for (int i = stoplistData.getRowCount() - 1; i >= 0; --i) {
     1586                    if (stoplistTable.isRowSelected(i)) {
     1587                        String role = (String) (stoplistData.getValueAt(i, STOPLIST_ROLE_COLUMN));
     1588                        RelationMember markedNode = new RelationMember(role,
     1589                                stoplistData.nodes.elementAt(i));
     1590                        itemsToReflect.addElement(markedNode);
     1591
     1592                        stoplistData.nodes.removeElementAt(i);
     1593                        stoplistData.removeRow(i);
     1594                    }
     1595                }
     1596            } else {
     1597                for (int i = stoplistData.getRowCount() - 1; i >= 0; --i) {
     1598                    String role = (String) (stoplistData.getValueAt(i, STOPLIST_ROLE_COLUMN));
     1599                    RelationMember markedNode = new RelationMember(role,
     1600                            stoplistData.nodes.elementAt(i));
     1601                    itemsToReflect.addElement(markedNode);
     1602                }
     1603
     1604                stoplistData.clear();
     1605            }
     1606
     1607            int startPos = insPos;
     1608            Iterator<RelationMember> relIter = itemsToReflect.iterator();
     1609            while (relIter.hasNext()) {
     1610                RelationMember curMember = relIter.next();
     1611                if (curMember.isNode()) {
     1612                    StopReference sr = detectMinDistance(curMember.getNode(), segmentMetrics,
     1613                            cbRight.isSelected(), cbLeft.isSelected());
     1614                    stoplistData.insertRow(insPos, curMember.getNode(), curMember.getRole(),
     1615                            calcOffset(sr, segmentMetrics));
     1616                    if (insPos >= 0)
     1617                        ++insPos;
     1618                }
     1619            }
     1620            if (insPos >= 0)
     1621                stoplistTable.addRowSelectionInterval(startPos, insPos - 1);
     1622
     1623            rebuildNodes();
     1624        } else if ("routePattern.metaSuggestStops".equals(event.getActionCommand())) {
     1625            // Prepare Segments: The segments of all usable ways are arranged in a linear
     1626            // list such that a coor can directly be checked concerning position and offset
     1627            Vector<StopReference> srm = new Vector<>();
     1628            // Determine for each member its position on the itinerary: position means here the
     1629            // point on the itinerary that has minimal distance to the coor
     1630            mainDataSet = Main.getLayerManager().getEditDataSet();
     1631            if (mainDataSet != null) {
     1632                String stopKey = "";
     1633                String stopValue = "";
     1634                if ("bus".equals(currentRoute.get("route"))) {
     1635                    stopKey = "highway";
     1636                    stopValue = "bus_stop";
     1637                } else if ("trolleybus".equals(currentRoute.get("route"))) {
     1638                    stopKey = "highway";
     1639                    stopValue = "bus_stop";
     1640                } else if ("tram".equals(currentRoute.get("route"))) {
     1641                    stopKey = "railway";
     1642                    stopValue = "tram_stop";
     1643                } else if ("light_rail".equals(currentRoute.get("route"))) {
     1644                    stopKey = "railway";
     1645                    stopValue = "station";
     1646                } else if ("subway".equals(currentRoute.get("route"))) {
     1647                    stopKey = "railway";
     1648                    stopValue = "station";
     1649                } else if ("rail".equals(currentRoute.get("route"))) {
     1650                    stopKey = "railway";
     1651                    stopValue = "station";
     1652                }
     1653
     1654                Collection<Node> nodeCollection = mainDataSet.getNodes();
     1655                Iterator<Node> nodeIter = nodeCollection.iterator();
     1656                while (nodeIter.hasNext()) {
     1657                    Node currentNode = nodeIter.next();
     1658                    if (!currentNode.isUsable())
     1659                        continue;
     1660                    if (stopValue.equals(currentNode.get(stopKey))) {
     1661                        StopReference sr = detectMinDistance(currentNode, segmentMetrics,
     1662                                cbRight.isSelected(), cbLeft.isSelected());
     1663                        if ((sr != null)
     1664                                && (sr.distance < Double.parseDouble(tfSuggestStopsLimit.getText())
     1665                                        * 9.0 / 1000000.0))
     1666                            srm.addElement(sr);
     1667                    }
     1668                }
     1669            } else {
     1670                JOptionPane.showMessageDialog(null,
     1671                        tr("There exists no dataset."
     1672                                + " Try to download data from the server or open an OSM file."),
     1673                        tr("No data found"), JOptionPane.ERROR_MESSAGE);
     1674            }
     1675
     1676            Collections.sort(srm);
     1677
     1678            stoplistData.clear();
     1679            for (int i = 0; i < srm.size(); ++i) {
     1680                StopReference sr = detectMinDistance(srm.elementAt(i).node, segmentMetrics,
     1681                        cbRight.isSelected(), cbLeft.isSelected());
     1682                stoplistData.addRow(srm.elementAt(i).node, srm.elementAt(i).role,
     1683                        calcOffset(sr, segmentMetrics));
     1684            }
     1685
     1686            rebuildNodes();
     1687        } else {
     1688            refreshData();
     1689
     1690            jDialog.setLocationRelativeTo(frame);
     1691            jDialog.setVisible(true);
     1692        }
    691693    }
    70   };
    71 
    72   private class RouteReference implements Comparable< RouteReference > {
    73     Relation route;
    74 
    75     public RouteReference(Relation route) {
    76       this.route = route;
     1694
     1695    private void refreshData() {
     1696        Relation copy = currentRoute;
     1697        relsListModel.clear();
     1698        currentRoute = copy;
     1699
     1700        DataSet mainDataSet = Main.getLayerManager().getEditDataSet();
     1701        if (mainDataSet != null) {
     1702            Vector<RouteReference> relRefs = new Vector<>();
     1703            Collection<Relation> relCollection = mainDataSet.getRelations();
     1704            Iterator<Relation> relIter = relCollection.iterator();
     1705
     1706            while (relIter.hasNext()) {
     1707                Relation currentRel = relIter.next();
     1708                if (!currentRel.isDeleted()) {
     1709                    String routeVal = currentRel.get("route");
     1710                    if ("bus".equals(routeVal))
     1711                        relRefs.add(new RouteReference(currentRel));
     1712                    else if ("trolleybus".equals(routeVal))
     1713                        relRefs.add(new RouteReference(currentRel));
     1714                    else if ("tram".equals(routeVal))
     1715                        relRefs.add(new RouteReference(currentRel));
     1716                    else if ("light_rail".equals(routeVal))
     1717                        relRefs.add(new RouteReference(currentRel));
     1718                    else if ("subway".equals(routeVal))
     1719                        relRefs.add(new RouteReference(currentRel));
     1720                    else if ("rail".equals(routeVal))
     1721                        relRefs.add(new RouteReference(currentRel));
     1722                }
     1723            }
     1724
     1725            Collections.sort(relRefs);
     1726
     1727            Iterator<RouteReference> iter = relRefs.iterator();
     1728            while (iter.hasNext())
     1729                relsListModel.addElement(iter.next());
     1730        } else {
     1731            JOptionPane.showMessageDialog(null,
     1732                    tr("There exists no dataset."
     1733                            + " Try to download data from the server or open an OSM file."),
     1734                    tr("No data found"), JOptionPane.ERROR_MESSAGE);
     1735        }
    771736    }
    781737
    79     @Override
    80     public int compareTo(RouteReference rr) {
    81       if (route.get("route") != null)
    82       {
    83         if (rr.route.get("route") == null)
    84           return -1;
    85         int result = route.get("route").compareTo(rr.route.get("route"));
    86         if (result != 0)
    87           return result;
    88       }
    89       else if (rr.route.get("route") != null)
    90         return 1;
    91       if (route.get("ref") != null)
    92       {
    93         if (rr.route.get("ref") == null)
    94           return -1;
    95         int result = route.get("ref").compareTo(rr.route.get("ref"));
    96         if (result != 0)
    97       return result;
    98       }
    99       else if (rr.route.get("ref") != null)
    100         return 1;
    101       if (route.get("to") != null)
    102       {
    103         if (rr.route.get("to") == null)
    104           return -1;
    105         int result = route.get("to").compareTo(rr.route.get("to"));
    106         if (result != 0)
    107           return result;
    108       }
    109       else if (rr.route.get("to") != null)
    110         return 1;
    111       if (route.get("direction") != null)
    112       {
    113         if (rr.route.get("direction") == null)
    114           return -1;
    115         int result = route.get("direction").compareTo(rr.route.get("direction"));
    116         if (result != 0)
    117           return result;
    118       }
    119       else if (rr.route.get("direction") != null)
    120         return 1;
    121       if (route.getId() < rr.route.getId())
    122         return -1;
    123       else if (route.getId() > rr.route.getId())
    124         return 1;
    125       return 0;
     1738    // Rebuild ways in the relation currentRoute
     1739    public static void rebuildWays() {
     1740        currentRoute.setModified(true);
     1741        List<RelationMember> members = currentRoute.getMembers();
     1742        ListIterator<RelationMember> iter = members.listIterator();
     1743        while (iter.hasNext()) {
     1744            if (iter.next().isWay())
     1745                iter.remove();
     1746        }
     1747        for (int i = 0; i < itineraryData.getRowCount(); ++i) {
     1748            if (itineraryData.ways.elementAt(i) != null) {
     1749                RelationMember member = new RelationMember(
     1750                        (String) (itineraryData.getValueAt(i, 1)), itineraryData.ways.elementAt(i));
     1751                members.add(member);
     1752            }
     1753        }
     1754        currentRoute.setMembers(members);
    1261755    }
    1271756
    128     @Override
    129     public String toString() {
    130       String buf = route.get("route");
    131       if ((route.get("ref") != null) && (route.get("ref") != ""))
    132       {
    133         buf += " " + route.get("ref");
    134       }
    135       if ((route.get("loc_ref") != null) && (route.get("loc_ref") != ""))
    136       {
    137         buf += " [" + route.get("loc_ref") + "]";
    138       }
    139 
    140       if ((route.get("to") != null) && (route.get("to") != ""))
    141       {
    142         buf += ": " + route.get("to");
    143       }
    144       else if ((route.get("direction") != null) && (route.get("direction") != ""))
    145       {
    146         buf += " " + route.get("ref") + ": " + route.get("direction");
    147       }
    148       else
    149       {
    150         buf += " " + route.get("ref");
    151       }
    152       buf += tr(" [ID] {0}", Long.toString(route.getId()));
    153 
    154       return buf;
     1757    // Rebuild nodes in the relation currentRoute
     1758    private void rebuildNodes() {
     1759        currentRoute.setModified(true);
     1760        for (int i = currentRoute.getMembersCount() - 1; i >= 0; --i) {
     1761            if (currentRoute.getMember(i).isNode()) {
     1762                currentRoute.removeMember(i);
     1763            }
     1764        }
     1765        for (int i = 0; i < stoplistData.getRowCount(); ++i) {
     1766            RelationMember member = new RelationMember(
     1767                    (String) (stoplistData.getValueAt(i, STOPLIST_ROLE_COLUMN)),
     1768                    stoplistData.nodes.elementAt(i));
     1769            currentRoute.addMember(member);
     1770        }
    1551771    }
    156   };
    157 
    158   private class TagTableModel extends DefaultTableModel implements TableModelListener {
    159     Relation relation = null;
    160     TreeSet< String > blacklist = null;
    161     boolean hasFixedKeys = true;
    162 
    163     public TagTableModel(boolean hasFixedKeys) {
    164       this.hasFixedKeys = hasFixedKeys;
     1772
     1773    private void addWayToSortingData(Way way, TreeMap<Node, LinkedList<RelationMember>> frontNodes,
     1774            TreeMap<Node, LinkedList<RelationMember>> backNodes,
     1775            Vector<LinkedList<RelationMember>> loops) {
     1776        if (way.getNodesCount() < 1)
     1777            return;
     1778
     1779        Node firstNode = way.getNode(0);
     1780        Node lastNode = way.getNode(way.getNodesCount() - 1);
     1781
     1782        if (frontNodes.get(firstNode) != null) {
     1783            LinkedList<RelationMember> list = frontNodes.get(firstNode);
     1784            list.addFirst(new RelationMember("backward", way));
     1785            frontNodes.remove(firstNode);
     1786
     1787            Node lastListNode;
     1788            if ("backward".equals(list.getLast().getRole()))
     1789                lastListNode = list.getLast().getWay().getNode(0);
     1790            else
     1791                lastListNode = list.getLast().getWay()
     1792                        .getNode(list.getLast().getWay().getNodesCount() - 1);
     1793            if (lastNode.equals(lastListNode)) {
     1794                backNodes.remove(lastListNode);
     1795                loops.add(list);
     1796            } else if (frontNodes.get(lastNode) != null) {
     1797                backNodes.remove(lastListNode);
     1798                LinkedList<RelationMember> listToAppend = frontNodes.get(lastNode);
     1799                Iterator<RelationMember> memberIter = list.iterator();
     1800                while (memberIter.hasNext()) {
     1801                    RelationMember member = memberIter.next();
     1802                    if ("backward".equals(member.getRole()))
     1803                        listToAppend.addFirst(new RelationMember("forward", member.getWay()));
     1804                    else
     1805                        listToAppend.addFirst(new RelationMember("backward", member.getWay()));
     1806                }
     1807                frontNodes.remove(lastNode);
     1808                frontNodes.put(lastListNode, listToAppend);
     1809            } else if (backNodes.get(lastNode) != null) {
     1810                backNodes.remove(lastListNode);
     1811                LinkedList<RelationMember> listToAppend = backNodes.get(lastNode);
     1812                Iterator<RelationMember> memberIter = list.iterator();
     1813                while (memberIter.hasNext()) {
     1814                    RelationMember member = memberIter.next();
     1815                    listToAppend.addLast(member);
     1816                }
     1817                backNodes.remove(lastNode);
     1818                backNodes.put(lastListNode, listToAppend);
     1819            } else
     1820                frontNodes.put(lastNode, list);
     1821        } else if (backNodes.get(firstNode) != null) {
     1822            LinkedList<RelationMember> list = backNodes.get(firstNode);
     1823            list.addLast(new RelationMember("forward", way));
     1824            backNodes.remove(firstNode);
     1825
     1826            Node firstListNode;
     1827            if ("backward".equals(list.getFirst().getRole()))
     1828                firstListNode = list.getFirst().getWay()
     1829                        .getNode(list.getFirst().getWay().getNodesCount() - 1);
     1830            else
     1831                firstListNode = list.getFirst().getWay().getNode(0);
     1832            if (lastNode.equals(firstListNode)) {
     1833                frontNodes.remove(firstListNode);
     1834                loops.add(list);
     1835            } else if (frontNodes.get(lastNode) != null) {
     1836                frontNodes.remove(firstListNode);
     1837                LinkedList<RelationMember> listToAppend = frontNodes.get(lastNode);
     1838                ListIterator<RelationMember> memberIter = list.listIterator(list.size());
     1839                while (memberIter.hasPrevious()) {
     1840                    RelationMember member = memberIter.previous();
     1841                    listToAppend.addFirst(member);
     1842                }
     1843                frontNodes.remove(lastNode);
     1844                frontNodes.put(firstListNode, listToAppend);
     1845            } else if (backNodes.get(lastNode) != null) {
     1846                frontNodes.remove(firstListNode);
     1847                LinkedList<RelationMember> listToAppend = backNodes.get(lastNode);
     1848                ListIterator<RelationMember> memberIter = list.listIterator(list.size());
     1849                while (memberIter.hasPrevious()) {
     1850                    RelationMember member = memberIter.previous();
     1851                    if ("backward".equals(member.getRole()))
     1852                        listToAppend.addLast(new RelationMember("forward", member.getWay()));
     1853                    else
     1854                        listToAppend.addLast(new RelationMember("backward", member.getWay()));
     1855                }
     1856                backNodes.remove(lastNode);
     1857                backNodes.put(firstListNode, listToAppend);
     1858            } else
     1859                backNodes.put(lastNode, list);
     1860        } else if (frontNodes.get(lastNode) != null) {
     1861            LinkedList<RelationMember> list = frontNodes.get(lastNode);
     1862            list.addFirst(new RelationMember("forward", way));
     1863            frontNodes.remove(lastNode);
     1864            frontNodes.put(firstNode, list);
     1865        } else if (backNodes.get(lastNode) != null) {
     1866            LinkedList<RelationMember> list = backNodes.get(lastNode);
     1867            list.addLast(new RelationMember("backward", way));
     1868            backNodes.remove(lastNode);
     1869            backNodes.put(firstNode, list);
     1870        } else {
     1871            LinkedList<RelationMember> newList = new LinkedList<>();
     1872            newList.add(new RelationMember("forward", way));
     1873            frontNodes.put(firstNode, newList);
     1874            backNodes.put(lastNode, newList);
     1875        }
    1651876    }
    1661877
    167     @Override
    168     public boolean isCellEditable(int row, int column) {
    169       if ((column == 0) && (hasFixedKeys))
    170         return false;
    171       return true;
     1878    private void routesSelectionChanged() {
     1879        int selectedPos = relsList.getAnchorSelectionIndex();
     1880        if (relsList.isSelectedIndex(selectedPos)) {
     1881            currentRoute = relsListModel.elementAt(selectedPos).route;
     1882            tabbedPane.setEnabledAt(1, true);
     1883            tabbedPane.setEnabledAt(2, true);
     1884            tabbedPane.setEnabledAt(3, true);
     1885            tabbedPane.setEnabledAt(4, true);
     1886
     1887            // Prepare Tags
     1888            requiredTagsData.readRelation(currentRoute);
     1889            commonTagsData.readRelation(currentRoute);
     1890            otherTagsData.readRelation(currentRoute, tagBlacklist);
     1891
     1892            // Prepare Itinerary
     1893            itineraryData.clear();
     1894            List<RelationMember> relMembers = currentRoute.getMembers();
     1895            Iterator<RelationMember> relIter = relMembers.iterator();
     1896            fillItineraryTable(relIter, 0, -1);
     1897
     1898            // Prepare Stoplist
     1899            stoplistData.clear();
     1900            /* List<RelationMember> */ relMembers = currentRoute.getMembers();
     1901            /* Iterator<RelationMember> */ relIter = relMembers.iterator();
     1902            fillStoplistTable(relIter, -1);
     1903        } else {
     1904            currentRoute = null;
     1905            tabbedPane.setEnabledAt(1, false);
     1906            tabbedPane.setEnabledAt(2, false);
     1907            tabbedPane.setEnabledAt(3, false);
     1908            tabbedPane.setEnabledAt(4, false);
     1909        }
    1721910    }
    1731911
    174     public void readRelation(Relation rel) {
    175       relation = rel;
    176 
    177       for (int i = 0; i < getRowCount(); ++i)
    178       {
    179         String value = rel.get((String)getValueAt(i, 0));
    180         if (value == null)
    181           value = "";
    182         setValueAt(value, i, 1);
    183       }
     1912    private void fillItineraryTable(Iterator<RelationMember> relIter, long lastNodeId, int insPos) {
     1913        while (relIter.hasNext()) {
     1914            RelationMember curMember = relIter.next();
     1915            if (curMember.isWay()) {
     1916                itineraryData.insertRow(insPos, curMember.getWay(), curMember.getRole());
     1917                if (insPos >= 0)
     1918                    ++insPos;
     1919            }
     1920        }
     1921        itineraryData.cleanupGaps();
     1922        segmentMetrics = fillSegmentMetrics();
    1841923    }
    1851924
    186     public void readRelation(Relation rel, TreeSet< String > blacklist) {
    187       relation = rel;
    188       this.blacklist = blacklist;
    189 
    190       setRowCount(0);
    191       Iterator< Map.Entry< String, String > > iter = rel.getKeys().entrySet().iterator();
    192       while (iter.hasNext())
    193       {
    194         Map.Entry< String, String > entry = iter.next();
    195         if (!blacklist.contains(entry.getKey()))
    196         {
    197           Vector< String > newRow = new Vector< String >();
    198           newRow.add(entry.getKey());
    199           newRow.add(entry.getValue());
    200           addRow(newRow);
    201         }
    202       }
    203 
    204       for (int i = 0; i < getRowCount(); ++i)
    205       {
    206         String value = rel.get((String)getValueAt(i, 0));
    207         if (value == null)
    208           value = "";
    209         setValueAt(value, i, 1);
    210       }
     1925    private double calcOffset(StopReference sr, Vector<SegmentMetric> segmentMetrics) {
     1926        double offset = 0;
     1927        if ((sr.index + 1) / 2 < segmentMetrics.size()) {
     1928            offset = segmentMetrics.elementAt((sr.index + 1) / 2).distance;
     1929            if (sr.index % 2 == 0)
     1930                offset += sr.pos;
     1931        } else
     1932            offset = segmentMetrics.elementAt(segmentMetrics.size() - 1).distance
     1933                    + segmentMetrics.elementAt(segmentMetrics.size() - 1).length;
     1934
     1935        return offset;
    2111936    }
    2121937
    213     @Override
    214     public void tableChanged(TableModelEvent e)
    215     {
    216       if (e.getType() == TableModelEvent.UPDATE)
    217       {
    218         relation.setModified(true);
    219 
    220         String key = (String)getValueAt(e.getFirstRow(), 0);
    221         if (key == null)
    222           return;
    223         if ((blacklist == null) || (!blacklist.contains(key)))
    224         {
    225           relation.setModified(true);
    226           if ("".equals(getValueAt(e.getFirstRow(), 1)))
    227             relation.remove(key);
    228           else
    229             relation.put(key, (String)getValueAt(e.getFirstRow(), 1));
    230         }
    231         else
    232         {
    233           if (e.getColumn() == 0)
    234             setValueAt("", e.getFirstRow(), 0);
    235         }
    236       }
     1938    private void fillStoplistTable(Iterator<RelationMember> relIter, int insPos) {
     1939
     1940        while (relIter.hasNext()) {
     1941            RelationMember curMember = relIter.next();
     1942            if (curMember.isNode()) {
     1943                StopReference sr = detectMinDistance(curMember.getNode(), segmentMetrics,
     1944                        cbRight.isSelected(), cbLeft.isSelected());
     1945                if (sr == null)
     1946                    stoplistData.insertRow(insPos, curMember.getNode(), curMember.getRole(), 360.0);
     1947                else {
     1948                    stoplistData.insertRow(insPos, curMember.getNode(), curMember.getRole(),
     1949                            calcOffset(sr, segmentMetrics));
     1950                    if (insPos >= 0)
     1951                        ++insPos;
     1952                }
     1953            }
     1954        }
    2371955    }
    238   };
    239 
    240   private class CustomCellEditorTable extends JTable {
    241     TreeMap< Integer, TableCellEditor > col1 = null;
    242     TreeMap< Integer, TableCellEditor > col2 = null;
    243 
    244     public CustomCellEditorTable() {
    245       col1 = new TreeMap< Integer, TableCellEditor >();
    246       col2 = new TreeMap< Integer, TableCellEditor >();
     1956
     1957    private Vector<SegmentMetric> fillSegmentMetrics() {
     1958        Vector<SegmentMetric> segmentMetrics = new Vector<>();
     1959        double distance = 0;
     1960        for (int i = 0; i < itineraryData.getRowCount(); ++i) {
     1961            if (itineraryData.ways.elementAt(i) != null) {
     1962                Way way = itineraryData.ways.elementAt(i);
     1963                if (!(way.isIncomplete())) {
     1964                    if ("backward".equals((itineraryData.getValueAt(i, 1)))) {
     1965                        for (int j = way.getNodesCount() - 2; j >= 0; --j) {
     1966                            SegmentMetric sm = new SegmentMetric(way.getNode(j + 1).getCoor().lat(),
     1967                                    way.getNode(j + 1).getCoor().lon(),
     1968                                    way.getNode(j).getCoor().lat(), way.getNode(j).getCoor().lon(),
     1969                                    distance);
     1970                            segmentMetrics.add(sm);
     1971                            distance += sm.length;
     1972                        }
     1973                    } else {
     1974                        for (int j = 0; j < way.getNodesCount() - 1; ++j) {
     1975                            SegmentMetric sm = new SegmentMetric(way.getNode(j).getCoor().lat(),
     1976                                    way.getNode(j).getCoor().lon(),
     1977                                    way.getNode(j + 1).getCoor().lat(),
     1978                                    way.getNode(j + 1).getCoor().lon(), distance);
     1979                            segmentMetrics.add(sm);
     1980                            distance += sm.length;
     1981                        }
     1982                    }
     1983                }
     1984            } else
     1985                segmentMetrics.add(null);
     1986        }
     1987        return segmentMetrics;
    2471988    }
    2481989
    249     @Override
    250     public TableCellEditor getCellEditor(int row, int column) {
    251       TableCellEditor editor = null;
    252       if (column == 0)
    253         editor = col1.get(new Integer(row));
    254       else
    255         editor = col2.get(new Integer(row));
    256       if (editor == null)
    257         return new DefaultCellEditor(new JTextField());
    258       else
    259         return editor;
     1990    private StopReference detectMinDistance(Node node, Vector<SegmentMetric> segmentMetrics,
     1991            boolean rhsPossible, boolean lhsPossible) {
     1992        if (node == null || node.getCoor() == null)
     1993            return null;
     1994
     1995        int minIndex = -1;
     1996        double position = -1.0;
     1997        double distance = 180.0;
     1998        double lat = node.getCoor().lat();
     1999        double lon = node.getCoor().lon();
     2000
     2001        int curIndex = -2;
     2002        double angleLat = 100.0;
     2003        double angleLon = 200.0;
     2004        Iterator<SegmentMetric> iter = segmentMetrics.iterator();
     2005        while (iter.hasNext()) {
     2006            curIndex += 2;
     2007            SegmentMetric sm = iter.next();
     2008
     2009            if (sm == null) {
     2010                angleLat = 100.0;
     2011                angleLon = 200.0;
     2012
     2013                continue;
     2014            }
     2015
     2016            double curPosition = (lat - sm.aLat) * sm.d1 + (lon - sm.aLon) * sm.d2;
     2017
     2018            if (curPosition < 0) {
     2019                if (angleLat <= 90.0) {
     2020                    double lastSegAngle = Math.atan2(angleLat - sm.aLat, angleLon - sm.aLon);
     2021                    double segAngle = Math.atan2(sm.d1, -sm.o1);
     2022                    double vertexAngle = Math.atan2(lat - sm.aLat, lon - sm.aLon);
     2023
     2024                    boolean vertexOnSeg = (vertexAngle == segAngle)
     2025                            || (vertexAngle == lastSegAngle);
     2026                    boolean vertexOnTheLeft = (!vertexOnSeg)
     2027                            && (((lastSegAngle > vertexAngle) && (vertexAngle > segAngle))
     2028                                    || ((vertexAngle > segAngle) && (segAngle > lastSegAngle))
     2029                                    || ((segAngle > lastSegAngle) && (lastSegAngle > vertexAngle)));
     2030
     2031                    double currentDistance = Math
     2032                            .sqrt((lat - sm.aLat) * (lat - sm.aLat) + (lon - sm.aLon)
     2033                                    * (lon - sm.aLon) * Math.cos(sm.aLat * Math.PI / 180.0)
     2034                                    * Math.cos(sm.aLat * Math.PI / 180.0));
     2035                    curPosition = vertexAngle - segAngle;
     2036                    if (vertexOnTheLeft)
     2037                        curPosition = -curPosition;
     2038                    if (curPosition < 0)
     2039                        curPosition += 2 * Math.PI;
     2040                    if ((Math.abs(currentDistance) < distance)
     2041                            && (((!vertexOnTheLeft) && (rhsPossible))
     2042                                    || ((vertexOnTheLeft) && (lhsPossible)) || (vertexOnSeg))) {
     2043                        distance = Math.abs(currentDistance);
     2044                        minIndex = curIndex - 1;
     2045                        position = curPosition;
     2046                    }
     2047                }
     2048                angleLat = 100.0;
     2049                angleLon = 200.0;
     2050            } else if (curPosition > sm.length) {
     2051                angleLat = sm.aLat;
     2052                angleLon = sm.aLon;
     2053            } else {
     2054                double currentDistance = (lat - sm.aLat) * sm.o1 + (lon - sm.aLon) * sm.o2;
     2055                if ((Math.abs(currentDistance) < distance)
     2056                        && (((currentDistance >= 0) && (rhsPossible))
     2057                                || ((currentDistance <= 0) && (lhsPossible)))) {
     2058                    distance = Math.abs(currentDistance);
     2059                    minIndex = curIndex;
     2060                    position = curPosition;
     2061                }
     2062
     2063                angleLat = 100.0;
     2064                angleLon = 200.0;
     2065            }
     2066        }
     2067
     2068        if (minIndex == -1)
     2069            return new StopReference(segmentMetrics.size() * 2, 0, 180.0, node.get("name"), "",
     2070                    node);
     2071
     2072        return new StopReference(minIndex, position, distance, node.get("name"), "", node);
    2602073    }
    261 
    262     public void setCellEditor(int row, int column, TableCellEditor editor) {
    263       if (column == 0)
    264         col1.put(new Integer(row), editor);
    265       else
    266         col2.put(new Integer(row), editor);
    267     }
    268   };
    269 
    270   private class StoplistTableModel extends DefaultTableModel {
    271 
    272     public Vector<Node> nodes = new Vector<Node>();
    273 
    274     @Override
    275     public boolean isCellEditable(int row, int column) {
    276       if (column != STOPLIST_ROLE_COLUMN)
    277         return false;
    278       return true;
    279     }
    280 
    281     @Override
    282     public void addRow(Object[] obj) {
    283       throw new UnsupportedOperationException();
    284     }
    285 
    286     @Override
    287     public void insertRow(int insPos, Object[] obj) {
    288       throw new UnsupportedOperationException();
    289     }
    290 
    291     public void addRow(Node node, String role, double distance) {
    292       insertRow(-1, node, role, distance);
    293     }
    294 
    295     public void insertRow(int insPos, Node node, String role, double distance) {
    296       String[] buf = { "", "", "", "" };
    297       String curName = node.get("name");
    298       if (curName != null)
    299       {
    300         buf[0] = curName;
    301       }
    302       else
    303       {
    304         buf[0] = tr("[ID] {0}", (new Long(node.getId())).toString());
    305       }
    306       String curRef = node.get("ref");
    307       if (curRef != null)
    308       {
    309         buf[1] = curRef;
    310       }
    311       buf[STOPLIST_ROLE_COLUMN] = role;
    312       buf[3] = Double.toString(((double)(int)(distance*40000/360.0*100))/100);
    313 
    314       if (insPos == -1)
    315       {
    316         nodes.addElement(node);
    317         super.addRow(buf);
    318       }
    319       else
    320       {
    321         nodes.insertElementAt(node, insPos);
    322         super.insertRow(insPos, buf);
    323       }
    324     }
    325 
    326     public void clear()
    327     {
    328       nodes.clear();
    329       super.setRowCount(0);
    330     }
    331   };
    332 
    333   private class StoplistTableModelListener implements TableModelListener {
    334     @Override
    335     public void tableChanged(TableModelEvent e)
    336     {
    337       if (e.getType() == TableModelEvent.UPDATE)
    338       {
    339         rebuildNodes();
    340       }
    341     }
    342   };
    343 
    344   private class SegmentMetric {
    345     public double aLat, aLon;
    346     public double length;
    347     public double d1, d2, o1, o2;
    348     public double distance;
    349 
    350     public SegmentMetric(double fromLat, double fromLon, double toLat, double toLon,
    351                          double distance) {
    352       this.distance = distance;
    353 
    354       aLat = fromLat;
    355       aLon = fromLon;
    356 
    357       //Compute length and direction
    358       //length is in units of latitude degrees
    359       d1 = toLat - fromLat;
    360       d2 = (toLon - fromLon) * Math.cos(fromLat * Math.PI/180.0);
    361       length = Math.sqrt(d1*d1 + d2*d2);
    362 
    363       //Normalise direction
    364       d1 = d1 / length;
    365       d2 = d2 / length;
    366 
    367       //Compute orthogonal direction (right hand size is positive)
    368       o1 = - d2;
    369       o2 = d1;
    370 
    371       //Prepare lon direction to reduce the number of necessary multiplications
    372       d2 = d2 * Math.cos(fromLat * Math.PI/180.0);
    373       o2 = o2 * Math.cos(fromLat * Math.PI/180.0);
    374     }
    375   };
    376 
    377   private class StopReference implements Comparable< StopReference > {
    378     public int index = 0;
    379     public double pos = 0;
    380     public double distance = 0;
    381     public String name = "";
    382     public String role = "";
    383     public Node node;
    384 
    385     public StopReference(int inIndex, double inPos, double inDistance,
    386              String inName, String inRole, Node inNode) {
    387       index = inIndex;
    388       pos = inPos;
    389       distance = inDistance;
    390       name = inName;
    391       role = inRole;
    392       node = inNode;
    393     }
    394 
    395     @Override
    396     public int compareTo(StopReference sr) {
    397       if (this.index < sr.index)
    398     return -1;
    399       if (this.index > sr.index)
    400     return 1;
    401       if (this.pos < sr.pos)
    402     return -1;
    403       if (this.pos > sr.pos)
    404     return 1;
    405       return 0;
    406     }
    407   };
    408 
    409   private static JDialog jDialog = null;
    410   private static JTabbedPane tabbedPane = null;
    411   private static DefaultListModel<RouteReference> relsListModel = null;
    412   private static TagTableModel requiredTagsData = null;
    413   private static CustomCellEditorTable requiredTagsTable = null;
    414   private static TagTableModel commonTagsData = null;
    415   private static CustomCellEditorTable commonTagsTable = null;
    416   private static TagTableModel otherTagsData = null;
    417   private static TreeSet< String > tagBlacklist = null;
    418   private static CustomCellEditorTable otherTagsTable = null;
    419   private static ItineraryTableModel itineraryData = null;
    420   private static JTable itineraryTable = null;
    421   private static StoplistTableModel stoplistData = null;
    422   private static JTable stoplistTable = null;
    423   private static JList<RouteReference> relsList = null;
    424   private static JCheckBox cbRight = null;
    425   private static JCheckBox cbLeft = null;
    426   private static JTextField tfSuggestStopsLimit = null;
    427   private static Relation currentRoute = null;
    428   private static Vector< SegmentMetric > segmentMetrics = null;
    429   private static Vector< RelationMember > markedWays = new Vector< RelationMember >();
    430   private static Vector< RelationMember > markedNodes = new Vector< RelationMember >();
    431 
    432   public RoutePatternAction() {
    433     super(tr("Route patterns ..."), null,
    434       tr("Edit Route patterns for public transport"), null, false);
    435     putValue("toolbar", "publictransport/routepattern");
    436     Main.toolbar.register(this);
    437   }
    438 
    439   @Override
    440 public void actionPerformed(ActionEvent event) {
    441     Frame frame = JOptionPane.getFrameForComponent(Main.parent);
    442     DataSet mainDataSet = Main.main.getCurrentDataSet();
    443 
    444     if (jDialog == null)
    445     {
    446       jDialog = new JDialog(frame, tr("Route Patterns"), false);
    447       tabbedPane = new JTabbedPane();
    448       JPanel tabOverview = new JPanel();
    449       tabbedPane.addTab(tr("Overview"), tabOverview);
    450       JPanel tabTags = new JPanel();
    451       tabbedPane.addTab(tr("Tags"), tabTags);
    452       JPanel tabItinerary = new JPanel();
    453       tabbedPane.addTab(tr("Itinerary"), tabItinerary);
    454       JPanel tabStoplist = new JPanel();
    455       tabbedPane.addTab(tr("Stops"), tabStoplist);
    456       JPanel tabMeta = new JPanel();
    457       tabbedPane.addTab(tr("Meta"), tabMeta);
    458       tabbedPane.setEnabledAt(0, true);
    459       tabbedPane.setEnabledAt(1, false);
    460       tabbedPane.setEnabledAt(2, false);
    461       tabbedPane.setEnabledAt(3, false);
    462       tabbedPane.setEnabledAt(4, false);
    463       jDialog.add(tabbedPane);
    464 
    465       //Overview Tab
    466       Container contentPane = tabOverview;
    467       GridBagLayout gridbag = new GridBagLayout();
    468       GridBagConstraints layoutCons = new GridBagConstraints();
    469       contentPane.setLayout(gridbag);
    470 
    471       JLabel headline = new JLabel(tr("Existing route patterns:"));
    472 
    473       layoutCons.gridx = 0;
    474       layoutCons.gridy = 0;
    475       layoutCons.gridwidth = 3;
    476       layoutCons.weightx = 0.0;
    477       layoutCons.weighty = 0.0;
    478       layoutCons.fill = GridBagConstraints.BOTH;
    479       gridbag.setConstraints(headline, layoutCons);
    480       contentPane.add(headline);
    481 
    482       relsListModel = new DefaultListModel<>();
    483       relsList = new JList<>(relsListModel);
    484       JScrollPane rpListSP = new JScrollPane(relsList);
    485       String[] data = {"1", "2", "3", "4", "5", "6"};
    486       relsListModel.copyInto(data);
    487       relsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    488       relsList.addListSelectionListener(new RoutesLSL(this));
    489 
    490       layoutCons.gridx = 0;
    491       layoutCons.gridy = 1;
    492       layoutCons.gridwidth = 3;
    493       layoutCons.weightx = 1.0;
    494       layoutCons.weighty = 1.0;
    495       layoutCons.fill = GridBagConstraints.BOTH;
    496       gridbag.setConstraints(rpListSP, layoutCons);
    497       contentPane.add(rpListSP);
    498 
    499       JButton bRefresh = new JButton(tr("Refresh"));
    500       bRefresh.setActionCommand("routePattern.refresh");
    501       bRefresh.addActionListener(this);
    502 
    503       layoutCons.gridx = 0;
    504       layoutCons.gridy = 2;
    505       layoutCons.gridwidth = 1;
    506       layoutCons.gridheight = 2;
    507       layoutCons.weightx = 1.0;
    508       layoutCons.weighty = 0.0;
    509       layoutCons.fill = GridBagConstraints.BOTH;
    510       gridbag.setConstraints(bRefresh, layoutCons);
    511       contentPane.add(bRefresh);
    512 
    513       JButton bNew = new JButton(tr("New"));
    514       bNew.setActionCommand("routePattern.overviewNew");
    515       bNew.addActionListener(this);
    516 
    517       layoutCons.gridx = 1;
    518       layoutCons.gridy = 2;
    519       layoutCons.gridwidth = 1;
    520       layoutCons.gridheight = 1;
    521       layoutCons.weightx = 1.0;
    522       layoutCons.weighty = 0.0;
    523       layoutCons.fill = GridBagConstraints.BOTH;
    524       gridbag.setConstraints(bNew, layoutCons);
    525       contentPane.add(bNew);
    526 
    527       JButton bDelete = new JButton(tr("Delete"));
    528       bDelete.setActionCommand("routePattern.overviewDelete");
    529       bDelete.addActionListener(this);
    530 
    531       layoutCons.gridx = 1;
    532       layoutCons.gridy = 3;
    533       layoutCons.gridwidth = 1;
    534       layoutCons.gridheight = 1;
    535       layoutCons.weightx = 1.0;
    536       layoutCons.weighty = 0.0;
    537       layoutCons.fill = GridBagConstraints.BOTH;
    538       gridbag.setConstraints(bDelete, layoutCons);
    539       contentPane.add(bDelete);
    540 
    541       JButton bDuplicate = new JButton(tr("Duplicate"));
    542       bDuplicate.setActionCommand("routePattern.overviewDuplicate");
    543       bDuplicate.addActionListener(this);
    544 
    545       layoutCons.gridx = 2;
    546       layoutCons.gridy = 2;
    547       layoutCons.gridwidth = 1;
    548       layoutCons.gridheight = 1;
    549       layoutCons.weightx = 1.0;
    550       layoutCons.weighty = 0.0;
    551       layoutCons.fill = GridBagConstraints.BOTH;
    552       gridbag.setConstraints(bDuplicate, layoutCons);
    553       contentPane.add(bDuplicate);
    554 
    555       JButton bReflect = new JButton(tr("Reflect"));
    556       bReflect.setActionCommand("routePattern.overviewReflect");
    557       bReflect.addActionListener(this);
    558 
    559       layoutCons.gridx = 2;
    560       layoutCons.gridy = 3;
    561       layoutCons.gridwidth = 1;
    562       layoutCons.gridheight = 1;
    563       layoutCons.weightx = 1.0;
    564       layoutCons.weighty = 0.0;
    565       layoutCons.fill = GridBagConstraints.BOTH;
    566       gridbag.setConstraints(bReflect, layoutCons);
    567       contentPane.add(bReflect);
    568 
    569       //Tags Tab
    570       /*Container*/ contentPane = tabTags;
    571       /*GridBagLayout*/ gridbag = new GridBagLayout();
    572       /*GridBagConstraints*/ layoutCons = new GridBagConstraints();
    573       contentPane.setLayout(gridbag);
    574 
    575       /*JLabel*/ headline = new JLabel(tr("Required tags:"));
    576 
    577       layoutCons.gridx = 0;
    578       layoutCons.gridy = 0;
    579       layoutCons.weightx = 0.0;
    580       layoutCons.weighty = 0.0;
    581       layoutCons.fill = GridBagConstraints.BOTH;
    582       gridbag.setConstraints(headline, layoutCons);
    583       contentPane.add(headline);
    584 
    585       requiredTagsTable = new CustomCellEditorTable();
    586       requiredTagsData = new TagTableModel(true);
    587       requiredTagsData.addColumn(tr("Key"));
    588       requiredTagsData.addColumn(tr("Value"));
    589       tagBlacklist = new TreeSet< String >();
    590       Vector< String > rowContent = new Vector< String >();
    591       /* TODO: keys and values should also be translated using TransText class */
    592       rowContent.add("type");
    593       tagBlacklist.add("type");
    594       rowContent.add("route");
    595       requiredTagsData.addRow(rowContent);
    596       JComboBox<String> comboBox = new JComboBox<>();
    597       comboBox.addItem("route");
    598       requiredTagsTable.setCellEditor(0, 1, new DefaultCellEditor(comboBox));
    599       rowContent = new Vector< String >();
    600       rowContent.add(0, "route");
    601       tagBlacklist.add("route");
    602       rowContent.add(1, "bus");
    603       requiredTagsData.addRow(rowContent);
    604       /*JComboBox*/ comboBox = new JComboBox<>();
    605       comboBox.addItem("bus");
    606       comboBox.addItem("trolleybus");
    607       comboBox.addItem("tram");
    608       comboBox.addItem("light_rail");
    609       comboBox.addItem("subway");
    610       comboBox.addItem("rail");
    611       requiredTagsTable.setCellEditor(1, 1, new DefaultCellEditor(comboBox));
    612       rowContent = new Vector< String >();
    613       rowContent.add(0, "ref");
    614       tagBlacklist.add("ref");
    615       rowContent.add(1, "");
    616       requiredTagsData.addRow(rowContent);
    617       rowContent = new Vector< String >();
    618       rowContent.add(0, "to");
    619       tagBlacklist.add("to");
    620       rowContent.add(1, "");
    621       requiredTagsData.addRow(rowContent);
    622       rowContent = new Vector< String >();
    623       rowContent.add(0, "network");
    624       tagBlacklist.add("network");
    625       rowContent.add(1, "");
    626       requiredTagsData.addRow(rowContent);
    627       requiredTagsTable.setModel(requiredTagsData);
    628       JScrollPane tableSP = new JScrollPane(requiredTagsTable);
    629       requiredTagsData.addTableModelListener(requiredTagsData);
    630 
    631       layoutCons.gridx = 0;
    632       layoutCons.gridy = 1;
    633       layoutCons.weightx = 1.0;
    634       layoutCons.weighty = 0.25;
    635       layoutCons.fill = GridBagConstraints.BOTH;
    636       gridbag.setConstraints(tableSP, layoutCons);
    637       Dimension preferredSize = tableSP.getPreferredSize();
    638       preferredSize.setSize(tableSP.getPreferredSize().getWidth(), tableSP.getPreferredSize().getHeight()/4.0);
    639       tableSP.setPreferredSize(preferredSize);
    640       contentPane.add(tableSP);
    641 
    642       headline = new JLabel(tr("Common tags:"));
    643 
    644       layoutCons.gridx = 0;
    645       layoutCons.gridy = 2;
    646       layoutCons.weightx = 0.0;
    647       layoutCons.weighty = 0.0;
    648       layoutCons.fill = GridBagConstraints.BOTH;
    649       gridbag.setConstraints(headline, layoutCons);
    650       contentPane.add(headline);
    651 
    652       commonTagsTable = new CustomCellEditorTable();
    653       commonTagsData = new TagTableModel(true);
    654       commonTagsData.addColumn(tr("Key"));
    655       commonTagsData.addColumn(tr("Value"));
    656       rowContent = new Vector< String >();
    657       rowContent.add(0, "loc_ref");
    658       tagBlacklist.add("loc_ref");
    659       rowContent.add(1, "");
    660       commonTagsData.addRow(rowContent);
    661       rowContent = new Vector< String >();
    662       rowContent.add(0, "direction");
    663       tagBlacklist.add("direction");
    664       rowContent.add(1, "");
    665       commonTagsData.addRow(rowContent);
    666       rowContent = new Vector< String >();
    667       rowContent.add(0, "from");
    668       tagBlacklist.add("from");
    669       rowContent.add(1, "");
    670       commonTagsData.addRow(rowContent);
    671       rowContent = new Vector< String >();
    672       rowContent.add(0, "operator");
    673       tagBlacklist.add("operator");
    674       rowContent.add(1, "");
    675       commonTagsData.addRow(rowContent);
    676       rowContent = new Vector< String >();
    677       rowContent.add(0, "color");
    678       tagBlacklist.add("color");
    679       rowContent.add(1, "");
    680       commonTagsData.addRow(rowContent);
    681       rowContent = new Vector< String >();
    682       rowContent.add(0, "name");
    683       tagBlacklist.add("name");
    684       rowContent.add(1, "");
    685       commonTagsData.addRow(rowContent);
    686       commonTagsTable.setModel(commonTagsData);
    687       /*JScrollPane*/ tableSP = new JScrollPane(commonTagsTable);
    688       commonTagsData.addTableModelListener(commonTagsData);
    689 
    690       layoutCons.gridx = 0;
    691       layoutCons.gridy = 3;
    692       layoutCons.weightx = 1.0;
    693       layoutCons.weighty = 0.25;
    694       layoutCons.fill = GridBagConstraints.BOTH;
    695       gridbag.setConstraints(tableSP, layoutCons);
    696       /*Dimension*/ preferredSize = tableSP.getPreferredSize();
    697       preferredSize.setSize(tableSP.getPreferredSize().getWidth(), tableSP.getPreferredSize().getHeight()/4.0);
    698       tableSP.setPreferredSize(preferredSize);
    699       contentPane.add(tableSP);
    700 
    701       headline = new JLabel(tr("Additional tags:"));
    702 
    703       layoutCons.gridx = 0;
    704       layoutCons.gridy = 4;
    705       layoutCons.weightx = 0.0;
    706       layoutCons.weighty = 0.0;
    707       layoutCons.fill = GridBagConstraints.BOTH;
    708       gridbag.setConstraints(headline, layoutCons);
    709       contentPane.add(headline);
    710 
    711       otherTagsTable = new CustomCellEditorTable();
    712       otherTagsData = new TagTableModel(false);
    713       otherTagsData.addColumn(tr("Key"));
    714       otherTagsData.addColumn(tr("Value"));
    715       otherTagsTable.setModel(otherTagsData);
    716       /*JScrollPane*/ tableSP = new JScrollPane(otherTagsTable);
    717       otherTagsData.addTableModelListener(otherTagsData);
    718 
    719       layoutCons.gridx = 0;
    720       layoutCons.gridy = 5;
    721       layoutCons.weightx = 1.0;
    722       layoutCons.weighty = 1.0;
    723       layoutCons.fill = GridBagConstraints.BOTH;
    724       gridbag.setConstraints(tableSP, layoutCons);
    725       /*Dimension*/ preferredSize = tableSP.getPreferredSize();
    726       preferredSize.setSize(tableSP.getPreferredSize().getWidth(), tableSP.getPreferredSize().getHeight()/2.0);
    727       tableSP.setPreferredSize(preferredSize);
    728       contentPane.add(tableSP);
    729 
    730       JButton bAddTag = new JButton(tr("Add a new Tag"));
    731       bAddTag.setActionCommand("routePattern.tagAddTag");
    732       bAddTag.addActionListener(this);
    733 
    734       layoutCons.gridx = 0;
    735       layoutCons.gridy = 6;
    736       layoutCons.gridwidth = 1;
    737       layoutCons.weightx = 1.0;
    738       layoutCons.weighty = 0.0;
    739       layoutCons.fill = GridBagConstraints.BOTH;
    740       gridbag.setConstraints(bAddTag, layoutCons);
    741       contentPane.add(bAddTag);
    742 
    743       //Itinerary Tab
    744       contentPane = tabItinerary;
    745       gridbag = new GridBagLayout();
    746       layoutCons = new GridBagConstraints();
    747       contentPane.setLayout(gridbag);
    748 
    749       itineraryTable = new JTable();
    750       itineraryData = new ItineraryTableModel();
    751       itineraryData.addColumn(tr("Name/Id"));
    752       itineraryData.addColumn(tr("Role"));
    753       itineraryTable.setModel(itineraryData);
    754       /*JScrollPane*/ tableSP = new JScrollPane(itineraryTable);
    755       /*JComboBox*/ comboBox = new JComboBox<>();
    756       comboBox.addItem("");
    757       comboBox.addItem("forward");
    758       comboBox.addItem("backward");
    759       itineraryTable.getColumnModel().getColumn(1)
    760       .setCellEditor(new DefaultCellEditor(comboBox));
    761       itineraryData.addTableModelListener(itineraryData);
    762 
    763       layoutCons.gridx = 0;
    764       layoutCons.gridy = 0;
    765       layoutCons.gridwidth = 4;
    766       layoutCons.weightx = 1.0;
    767       layoutCons.weighty = 1.0;
    768       layoutCons.fill = GridBagConstraints.BOTH;
    769       gridbag.setConstraints(tableSP, layoutCons);
    770       contentPane.add(tableSP);
    771 
    772       JButton bFind = new JButton(tr("Find"));
    773       bFind.setActionCommand("routePattern.itineraryFind");
    774       bFind.addActionListener(this);
    775 
    776       layoutCons.gridx = 0;
    777       layoutCons.gridy = 1;
    778       layoutCons.gridwidth = 1;
    779       layoutCons.weightx = 1.0;
    780       layoutCons.weighty = 0.0;
    781       layoutCons.fill = GridBagConstraints.BOTH;
    782       gridbag.setConstraints(bFind, layoutCons);
    783       contentPane.add(bFind);
    784 
    785       JButton bShow = new JButton(tr("Show"));
    786       bShow.setActionCommand("routePattern.itineraryShow");
    787       bShow.addActionListener(this);
    788 
    789       layoutCons.gridx = 0;
    790       layoutCons.gridy = 2;
    791       layoutCons.gridwidth = 1;
    792       layoutCons.weightx = 1.0;
    793       layoutCons.weighty = 0.0;
    794       layoutCons.fill = GridBagConstraints.BOTH;
    795       gridbag.setConstraints(bShow, layoutCons);
    796       contentPane.add(bShow);
    797 
    798       JButton bMark = new JButton(tr("Mark"));
    799       bMark.setActionCommand("routePattern.itineraryMark");
    800       bMark.addActionListener(this);
    801 
    802       layoutCons.gridx = 1;
    803       layoutCons.gridy = 1;
    804       layoutCons.gridheight = 2;
    805       layoutCons.gridwidth = 1;
    806       layoutCons.weightx = 1.0;
    807       layoutCons.weighty = 0.0;
    808       layoutCons.fill = GridBagConstraints.BOTH;
    809       gridbag.setConstraints(bMark, layoutCons);
    810       contentPane.add(bMark);
    811 
    812       JButton bAdd = new JButton(tr("Add"));
    813       bAdd.setActionCommand("routePattern.itineraryAdd");
    814       bAdd.addActionListener(this);
    815 
    816       layoutCons.gridx = 2;
    817       layoutCons.gridy = 1;
    818       layoutCons.gridheight = 1;
    819       layoutCons.gridwidth = 1;
    820       layoutCons.weightx = 1.0;
    821       layoutCons.weighty = 0.0;
    822       layoutCons.fill = GridBagConstraints.BOTH;
    823       gridbag.setConstraints(bAdd, layoutCons);
    824       contentPane.add(bAdd);
    825 
    826       /*JButton*/ bDelete = new JButton(tr("Delete"));
    827       bDelete.setActionCommand("routePattern.itineraryDelete");
    828       bDelete.addActionListener(this);
    829 
    830       layoutCons.gridx = 2;
    831       layoutCons.gridy = 2;
    832       layoutCons.gridwidth = 1;
    833       layoutCons.weightx = 1.0;
    834       layoutCons.weighty = 0.0;
    835       layoutCons.fill = GridBagConstraints.BOTH;
    836       gridbag.setConstraints(bDelete, layoutCons);
    837       contentPane.add(bDelete);
    838 
    839       JButton bSort = new JButton(tr("Sort"));
    840       bSort.setActionCommand("routePattern.itinerarySort");
    841       bSort.addActionListener(this);
    842 
    843       layoutCons.gridx = 3;
    844       layoutCons.gridy = 1;
    845       layoutCons.gridwidth = 1;
    846       layoutCons.weightx = 1.0;
    847       layoutCons.weighty = 0.0;
    848       layoutCons.fill = GridBagConstraints.BOTH;
    849       gridbag.setConstraints(bSort, layoutCons);
    850       contentPane.add(bSort);
    851 
    852       /*JButton*/ bReflect = new JButton(tr("Reflect"));
    853       bReflect.setActionCommand("routePattern.itineraryReflect");
    854       bReflect.addActionListener(this);
    855 
    856       layoutCons.gridx = 3;
    857       layoutCons.gridy = 2;
    858       layoutCons.gridwidth = 1;
    859       layoutCons.weightx = 1.0;
    860       layoutCons.weighty = 0.0;
    861       layoutCons.fill = GridBagConstraints.BOTH;
    862       gridbag.setConstraints(bReflect, layoutCons);
    863       contentPane.add(bReflect);
    864 
    865       //Stoplist Tab
    866       contentPane = tabStoplist;
    867       gridbag = new GridBagLayout();
    868       layoutCons = new GridBagConstraints();
    869       contentPane.setLayout(gridbag);
    870 
    871       stoplistTable = new JTable();
    872       stoplistData = new StoplistTableModel();
    873       stoplistData.addColumn(tr("Name/Id"));
    874       stoplistData.addColumn(tr("Ref"));
    875       stoplistData.addColumn(tr("Role"));
    876       stoplistData.addColumn(tr("km"));
    877       stoplistTable.setModel(stoplistData);
    878       /*JScrollPane*/ tableSP = new JScrollPane(stoplistTable);
    879       /*JComboBox*/ comboBox = new JComboBox<>();
    880       comboBox.addItem("");
    881       comboBox.addItem("forward_stop");
    882       comboBox.addItem("backward_stop");
    883       stoplistTable.getColumnModel().getColumn(STOPLIST_ROLE_COLUMN)
    884                    .setCellEditor(new DefaultCellEditor(comboBox));
    885       stoplistData.addTableModelListener(new StoplistTableModelListener());
    886 
    887       layoutCons.gridx = 0;
    888       layoutCons.gridy = 0;
    889       layoutCons.gridwidth = 4;
    890       layoutCons.weightx = 1.0;
    891       layoutCons.weighty = 1.0;
    892       layoutCons.fill = GridBagConstraints.BOTH;
    893       gridbag.setConstraints(tableSP, layoutCons);
    894       contentPane.add(tableSP);
    895 
    896       /*JButton*/ bFind = new JButton(tr("Find"));
    897       bFind.setActionCommand("routePattern.stoplistFind");
    898       bFind.addActionListener(this);
    899 
    900       layoutCons.gridx = 0;
    901       layoutCons.gridy = 1;
    902       layoutCons.gridwidth = 1;
    903       layoutCons.weightx = 1.0;
    904       layoutCons.weighty = 0.0;
    905       layoutCons.fill = GridBagConstraints.BOTH;
    906       gridbag.setConstraints(bFind, layoutCons);
    907       contentPane.add(bFind);
    908 
    909       /*JButton*/ bShow = new JButton(tr("Show"));
    910       bShow.setActionCommand("routePattern.stoplistShow");
    911       bShow.addActionListener(this);
    912 
    913       layoutCons.gridx = 0;
    914       layoutCons.gridy = 2;
    915       layoutCons.gridwidth = 1;
    916       layoutCons.weightx = 1.0;
    917       layoutCons.weighty = 0.0;
    918       layoutCons.fill = GridBagConstraints.BOTH;
    919       gridbag.setConstraints(bShow, layoutCons);
    920       contentPane.add(bShow);
    921 
    922       /*JButton*/ bMark = new JButton(tr("Mark"));
    923       bMark.setActionCommand("routePattern.stoplistMark");
    924       bMark.addActionListener(this);
    925 
    926       layoutCons.gridx = 1;
    927       layoutCons.gridy = 1;
    928       layoutCons.gridheight = 2;
    929       layoutCons.gridwidth = 1;
    930       layoutCons.weightx = 1.0;
    931       layoutCons.weighty = 0.0;
    932       layoutCons.fill = GridBagConstraints.BOTH;
    933       gridbag.setConstraints(bMark, layoutCons);
    934       contentPane.add(bMark);
    935 
    936       /*JButton*/ bAdd = new JButton(tr("Add"));
    937       bAdd.setActionCommand("routePattern.stoplistAdd");
    938       bAdd.addActionListener(this);
    939 
    940       layoutCons.gridx = 2;
    941       layoutCons.gridy = 1;
    942       layoutCons.gridheight = 1;
    943       layoutCons.gridwidth = 1;
    944       layoutCons.weightx = 1.0;
    945       layoutCons.weighty = 0.0;
    946       layoutCons.fill = GridBagConstraints.BOTH;
    947       gridbag.setConstraints(bAdd, layoutCons);
    948       contentPane.add(bAdd);
    949 
    950       /*JButton*/ bDelete = new JButton(tr("Delete"));
    951       bDelete.setActionCommand("routePattern.stoplistDelete");
    952       bDelete.addActionListener(this);
    953 
    954       layoutCons.gridx = 2;
    955       layoutCons.gridy = 2;
    956       layoutCons.gridwidth = 1;
    957       layoutCons.weightx = 1.0;
    958       layoutCons.weighty = 0.0;
    959       layoutCons.fill = GridBagConstraints.BOTH;
    960       gridbag.setConstraints(bDelete, layoutCons);
    961       contentPane.add(bDelete);
    962 
    963       /*JButton*/ bSort = new JButton(tr("Sort"));
    964       bSort.setActionCommand("routePattern.stoplistSort");
    965       bSort.addActionListener(this);
    966 
    967       layoutCons.gridx = 3;
    968       layoutCons.gridy = 1;
    969       layoutCons.gridwidth = 1;
    970       layoutCons.weightx = 1.0;
    971       layoutCons.weighty = 0.0;
    972       layoutCons.fill = GridBagConstraints.BOTH;
    973       gridbag.setConstraints(bSort, layoutCons);
    974       contentPane.add(bSort);
    975 
    976       /*JButton*/ bReflect = new JButton(tr("Reflect"));
    977       bReflect.setActionCommand("routePattern.stoplistReflect");
    978       bReflect.addActionListener(this);
    979 
    980       layoutCons.gridx = 3;
    981       layoutCons.gridy = 2;
    982       layoutCons.gridwidth = 1;
    983       layoutCons.weightx = 1.0;
    984       layoutCons.weighty = 0.0;
    985       layoutCons.fill = GridBagConstraints.BOTH;
    986       gridbag.setConstraints(bReflect, layoutCons);
    987       contentPane.add(bReflect);
    988 
    989       //Meta Tab
    990       contentPane = tabMeta;
    991       gridbag = new GridBagLayout();
    992       layoutCons = new GridBagConstraints();
    993       contentPane.setLayout(gridbag);
    994 
    995       JLabel rightleft = new JLabel(tr("Stops are possible on the"));
    996 
    997       layoutCons.gridx = 0;
    998       layoutCons.gridy = 1;
    999       layoutCons.gridwidth = 2;
    1000       layoutCons.weightx = 0.0;
    1001       layoutCons.weighty = 0.0;
    1002       layoutCons.fill = GridBagConstraints.BOTH;
    1003       gridbag.setConstraints(rightleft, layoutCons);
    1004       contentPane.add(rightleft);
    1005 
    1006       cbRight = new JCheckBox(tr("right hand side"), true);
    1007 
    1008       layoutCons.gridx = 0;
    1009       layoutCons.gridy = 2;
    1010       layoutCons.gridwidth = 2;
    1011       layoutCons.weightx = 0.0;
    1012       layoutCons.weighty = 0.0;
    1013       layoutCons.fill = GridBagConstraints.BOTH;
    1014       gridbag.setConstraints(cbRight, layoutCons);
    1015       contentPane.add(cbRight);
    1016 
    1017       cbLeft = new JCheckBox(tr("left hand side"), false);
    1018 
    1019       layoutCons.gridx = 0;
    1020       layoutCons.gridy = 3;
    1021       layoutCons.gridwidth = 2;
    1022       layoutCons.weightx = 0.0;
    1023       layoutCons.weighty = 0.0;
    1024       layoutCons.fill = GridBagConstraints.BOTH;
    1025       gridbag.setConstraints(cbLeft, layoutCons);
    1026       contentPane.add(cbLeft);
    1027 
    1028       JLabel maxdist = new JLabel(tr("Maximum distance from route"));
    1029 
    1030       layoutCons.gridx = 0;
    1031       layoutCons.gridy = 4;
    1032       layoutCons.gridwidth = 2;
    1033       layoutCons.weightx = 0.0;
    1034       layoutCons.weighty = 0.0;
    1035       layoutCons.fill = GridBagConstraints.BOTH;
    1036       gridbag.setConstraints(maxdist, layoutCons);
    1037       contentPane.add(maxdist);
    1038 
    1039       tfSuggestStopsLimit = new JTextField("20", 4);
    1040 
    1041       layoutCons.gridx = 0;
    1042       layoutCons.gridy = 5;
    1043       layoutCons.gridwidth = 1;
    1044       layoutCons.weightx = 0.0;
    1045       layoutCons.weighty = 0.0;
    1046       layoutCons.fill = GridBagConstraints.BOTH;
    1047       gridbag.setConstraints(tfSuggestStopsLimit, layoutCons);
    1048       contentPane.add(tfSuggestStopsLimit);
    1049 
    1050       JLabel meters = new JLabel(tr("meters"));
    1051 
    1052       layoutCons.gridx = 1;
    1053       layoutCons.gridy = 5;
    1054       layoutCons.gridwidth = 1;
    1055       layoutCons.weightx = 0.0;
    1056       layoutCons.weighty = 0.0;
    1057       layoutCons.fill = GridBagConstraints.BOTH;
    1058       gridbag.setConstraints(meters, layoutCons);
    1059       contentPane.add(meters);
    1060 
    1061       JButton bSuggestStops = new JButton(tr("Suggest Stops"));
    1062       bSuggestStops.setActionCommand("routePattern.metaSuggestStops");
    1063       bSuggestStops.addActionListener(this);
    1064 
    1065       layoutCons.gridx = 0;
    1066       layoutCons.gridy = 6;
    1067       layoutCons.gridwidth = 3;
    1068       layoutCons.weightx = 1.0;
    1069       layoutCons.weighty = 0.0;
    1070       layoutCons.fill = GridBagConstraints.BOTH;
    1071       gridbag.setConstraints(bSuggestStops, layoutCons);
    1072       contentPane.add(bSuggestStops);
    1073 
    1074       jDialog.pack();
    1075     }
    1076 
    1077     if ("routePattern.refresh".equals(event.getActionCommand()))
    1078     {
    1079       refreshData();
    1080     }
    1081     else if ("routePattern.overviewNew".equals(event.getActionCommand()))
    1082     {
    1083       currentRoute = new Relation();
    1084       currentRoute.put("type", "route");
    1085       currentRoute.put("route", "bus");
    1086       mainDataSet.addPrimitive(currentRoute);
    1087 
    1088       refreshData();
    1089 
    1090       for (int i = 0; i < relsListModel.size(); ++i)
    1091       {
    1092     if (currentRoute == relsListModel.elementAt(i).route)
    1093       relsList.setSelectedIndex(i);
    1094       }
    1095     }
    1096     else if ("routePattern.overviewDuplicate".equals(event.getActionCommand()))
    1097     {
    1098       currentRoute = new Relation(currentRoute, true);
    1099       currentRoute.put("type", "route");
    1100       currentRoute.put("route", "bus");
    1101       mainDataSet.addPrimitive(currentRoute);
    1102 
    1103       refreshData();
    1104 
    1105       for (int i = 0; i < relsListModel.size(); ++i)
    1106       {
    1107     if (currentRoute == relsListModel.elementAt(i).route)
    1108       relsList.setSelectedIndex(i);
    1109       }
    1110     }
    1111     else if ("routePattern.overviewReflect".equals(event.getActionCommand()))
    1112     {
    1113       currentRoute.setModified(true);
    1114       String tag_from = currentRoute.get("from");
    1115       String tag_to = currentRoute.get("to");
    1116       currentRoute.put("from", tag_to);
    1117       currentRoute.put("to", tag_from);
    1118 
    1119       Vector< RelationMember > itemsToReflect = new Vector< RelationMember >();
    1120       Vector< RelationMember > otherItems = new Vector< RelationMember >();
    1121 
    1122       // Temp
    1123       Node firstNode = null;
    1124       //Node lastNode = null;
    1125 
    1126       for (int i = 0; i < currentRoute.getMembersCount(); ++i)
    1127       {
    1128         RelationMember item = currentRoute.getMember(i);
    1129 
    1130         if (item.isWay())
    1131         {
    1132           String role = item.getRole();
    1133           if ("backward".equals(role))
    1134             role = "forward";
    1135           else if ("forward".equals(role))
    1136             role = "backward";
    1137           else
    1138             role = "backward";
    1139 
    1140           itemsToReflect.add(new RelationMember(role, item.getWay()));
    1141 
    1142           // Temp
    1143           if (firstNode == null)
    1144           {
    1145               firstNode = item.getWay().getNode(0);
    1146           }
    1147           //lastNode = item.getWay().getNode(item.getWay().getNodesCount() - 1);
    1148         }
    1149         else if (item.isNode())
    1150           itemsToReflect.add(item);
    1151         else
    1152           otherItems.add(item);
    1153       }
    1154 
    1155       currentRoute.setMembers(null);
    1156       for (int i = itemsToReflect.size()-1; i >= 0; --i)
    1157         currentRoute.addMember(itemsToReflect.elementAt(i));
    1158       for (int i = 0; i < otherItems.size(); ++i)
    1159         currentRoute.addMember(otherItems.elementAt(i));
    1160 
    1161       refreshData();
    1162 
    1163       for (int i = 0; i < relsListModel.size(); ++i)
    1164       {
    1165         if (currentRoute == relsListModel.elementAt(i).route)
    1166           relsList.setSelectedIndex(i);
    1167       }
    1168 
    1169       // Temp
    1170 /*      if (firstNode != null)
    1171       {
    1172         Vector< AStarAlgorithm.Edge > path = new PublicTransportAStar(firstNode, lastNode).shortestPath();
    1173         Iterator< AStarAlgorithm.Edge > iter = path.iterator();
    1174         while (iter.hasNext())
    1175         {
    1176           PublicTransportAStar.PartialWayEdge edge = (PublicTransportAStar.PartialWayEdge)iter.next();
    1177           System.out.print(edge.way.getUniqueId());
    1178           System.out.print("\t");
    1179           System.out.print(edge.beginIndex);
    1180           System.out.print("\t");
    1181           System.out.print(edge.endIndex);
    1182           System.out.print("\n");
    1183         }
    1184       }*/
    1185     }
    1186     else if ("routePattern.overviewDelete".equals(event.getActionCommand()))
    1187     {
    1188       DeleteAction.deleteRelation(Main.main.getEditLayer(), currentRoute);
    1189 
    1190       currentRoute = null;
    1191       tabbedPane.setEnabledAt(1, false);
    1192       tabbedPane.setEnabledAt(2, false);
    1193       tabbedPane.setEnabledAt(3, false);
    1194       tabbedPane.setEnabledAt(4, false);
    1195 
    1196       refreshData();
    1197     }
    1198     else if ("routePattern.tagAddTag".equals(event.getActionCommand()))
    1199     {
    1200       Vector< String > rowContent = new Vector< String >();
    1201       rowContent.add("");
    1202       rowContent.add("");
    1203       otherTagsData.addRow(rowContent);
    1204     }
    1205     else if ("routePattern.itineraryFind".equals(event.getActionCommand()))
    1206     {
    1207       if (mainDataSet == null)
    1208         return;
    1209 
    1210       itineraryTable.clearSelection();
    1211 
    1212       for (int i = 0; i < itineraryData.getRowCount(); ++i)
    1213       {
    1214         if ((itineraryData.ways.elementAt(i) != null) &&
    1215             (mainDataSet.isSelected(itineraryData.ways.elementAt(i))))
    1216             itineraryTable.addRowSelectionInterval(i, i);
    1217       }
    1218     }
    1219     else if ("routePattern.itineraryShow".equals(event.getActionCommand()))
    1220     {
    1221       BoundingXYVisitor box = new BoundingXYVisitor();
    1222       if (itineraryTable.getSelectedRowCount() > 0)
    1223       {
    1224         for (int i = 0; i < itineraryData.getRowCount(); ++i)
    1225         {
    1226           if ((itineraryTable.isRowSelected(i)) && (itineraryData.ways.elementAt(i) != null))
    1227           {
    1228             itineraryData.ways.elementAt(i).accept(box);
    1229           }
    1230         }
    1231       }
    1232       else
    1233       {
    1234         for (int i = 0; i < itineraryData.getRowCount(); ++i)
    1235         {
    1236           if (itineraryData.ways.elementAt(i) != null)
    1237           {
    1238             itineraryData.ways.elementAt(i).accept(box);
    1239           }
    1240         }
    1241       }
    1242       if (box.getBounds() == null)
    1243         return;
    1244       box.enlargeBoundingBox();
    1245       Main.map.mapView.zoomTo(box);
    1246     }
    1247     else if ("routePattern.itineraryMark".equals(event.getActionCommand()))
    1248     {
    1249       OsmPrimitive[] osmp = { null };
    1250       Main.main.getCurrentDataSet().setSelected(osmp);
    1251       markedWays.clear();
    1252       if (itineraryTable.getSelectedRowCount() > 0)
    1253       {
    1254         for (int i = 0; i < itineraryData.getRowCount(); ++i)
    1255         {
    1256           if ((itineraryTable.isRowSelected(i)) && (itineraryData.ways.elementAt(i) != null))
    1257           {
    1258             mainDataSet.addSelected(itineraryData.ways.elementAt(i));
    1259 
    1260             RelationMember markedWay = new RelationMember
    1261             ((String)(itineraryData.getValueAt(i, 1)), itineraryData.ways.elementAt(i));
    1262             markedWays.addElement(markedWay);
    1263           }
    1264         }
    1265       }
    1266       else
    1267       {
    1268         for (int i = 0; i < itineraryData.getRowCount(); ++i)
    1269         {
    1270           if (itineraryData.ways.elementAt(i) != null)
    1271           {
    1272             mainDataSet.addSelected(itineraryData.ways.elementAt(i));
    1273 
    1274             RelationMember markedWay = new RelationMember
    1275             ((String)(itineraryData.getValueAt(i, 1)), itineraryData.ways.elementAt(i));
    1276             markedWays.addElement(markedWay);
    1277           }
    1278         }
    1279       }
    1280     }
    1281     else if ("routePattern.itineraryAdd".equals(event.getActionCommand()))
    1282     {
    1283       int insPos = itineraryTable.getSelectedRow();
    1284       Iterator<RelationMember> relIter = markedWays.iterator();
    1285       TreeSet<Way> addedWays = new TreeSet<Way>();
    1286       if (mainDataSet == null)
    1287         return;
    1288 
    1289       while (relIter.hasNext())
    1290       {
    1291         RelationMember curMember = relIter.next();
    1292         if ((curMember.isWay()) && (mainDataSet.isSelected(curMember.getWay())))
    1293         {
    1294           itineraryData.insertRow(insPos, curMember.getWay(), curMember.getRole());
    1295           if (insPos >= 0)
    1296             ++insPos;
    1297 
    1298           addedWays.add(curMember.getWay());
    1299         }
    1300       }
    1301 
    1302       Collection<Way> selectedWays = mainDataSet.getSelectedWays();
    1303       Iterator<Way> wayIter = selectedWays.iterator();
    1304 
    1305       while (wayIter.hasNext())
    1306       {
    1307         Way curMember = wayIter.next();
    1308         if (!(addedWays.contains(curMember)))
    1309         {
    1310           itineraryData.insertRow(insPos, curMember, "");
    1311           if (insPos >= 0)
    1312             ++insPos;
    1313         }
    1314       }
    1315 
    1316       if ((insPos > 0) && (insPos < itineraryData.getRowCount()))
    1317       {
    1318         while ((insPos < itineraryData.getRowCount())
    1319                   && (itineraryData.ways.elementAt(insPos) == null))
    1320           ++insPos;
    1321         itineraryTable.removeRowSelectionInterval(0, itineraryData.getRowCount()-1);
    1322         if (insPos < itineraryData.getRowCount())
    1323           itineraryTable.addRowSelectionInterval(insPos, insPos);
    1324       }
    1325 
    1326       itineraryData.cleanupGaps();
    1327       segmentMetrics = fillSegmentMetrics();
    1328       rebuildWays();
    1329     }
    1330     else if ("routePattern.itineraryDelete".equals(event.getActionCommand()))
    1331     {
    1332       for (int i = itineraryData.getRowCount()-1; i >=0; --i)
    1333       {
    1334         if ((itineraryTable.isRowSelected(i)) && (itineraryData.ways.elementAt(i) != null))
    1335         {
    1336           itineraryData.ways.removeElementAt(i);
    1337           itineraryData.removeRow(i);
    1338         }
    1339       }
    1340 
    1341       itineraryData.cleanupGaps();
    1342       segmentMetrics = fillSegmentMetrics();
    1343       rebuildWays();
    1344     }
    1345     else if ("routePattern.itinerarySort".equals(event.getActionCommand()))
    1346     {
    1347       TreeSet<Way> usedWays = new TreeSet<Way>();
    1348       TreeMap<Node, LinkedList<RelationMember> > frontNodes =
    1349       new TreeMap<Node, LinkedList<RelationMember> >();
    1350       TreeMap<Node, LinkedList<RelationMember> > backNodes =
    1351       new TreeMap<Node, LinkedList<RelationMember> >();
    1352       Vector< LinkedList<RelationMember> > loops =
    1353       new Vector< LinkedList<RelationMember> >();
    1354       int insPos = itineraryTable.getSelectedRow();
    1355 
    1356       if (itineraryTable.getSelectedRowCount() > 0)
    1357       {
    1358         for (int i = itineraryData.getRowCount()-1; i >=0; --i)
    1359         {
    1360           if ((itineraryTable.isRowSelected(i)) && (itineraryData.ways.elementAt(i) != null))
    1361           {
    1362             if (!(usedWays.contains(itineraryData.ways.elementAt(i))))
    1363             {
    1364               addWayToSortingData
    1365               (itineraryData.ways.elementAt(i), frontNodes, backNodes, loops);
    1366               usedWays.add(itineraryData.ways.elementAt(i));
    1367             }
    1368 
    1369             itineraryData.ways.removeElementAt(i);
    1370             itineraryData.removeRow(i);
    1371           }
    1372         }
    1373       }
    1374       else
    1375       {
    1376         for (int i = itineraryData.getRowCount()-1; i >=0; --i)
    1377         {
    1378           if (itineraryData.ways.elementAt(i) != null)
    1379           {
    1380             if (!(usedWays.contains(itineraryData.ways.elementAt(i))))
    1381             {
    1382               addWayToSortingData
    1383               (itineraryData.ways.elementAt(i), frontNodes, backNodes, loops);
    1384               usedWays.add(itineraryData.ways.elementAt(i));
    1385             }
    1386           }
    1387         }
    1388 
    1389         itineraryData.clear();
    1390       }
    1391 
    1392       Iterator< Map.Entry< Node, LinkedList<RelationMember> > > entryIter
    1393       = frontNodes.entrySet().iterator();
    1394       while (entryIter.hasNext())
    1395       {
    1396         Iterator<RelationMember> relIter = entryIter.next().getValue().iterator();
    1397         while (relIter.hasNext())
    1398         {
    1399           RelationMember curMember = relIter.next();
    1400           itineraryData.insertRow(insPos, curMember.getWay(), curMember.getRole());
    1401           if (insPos >= 0)
    1402             ++insPos;
    1403         }
    1404       }
    1405 
    1406       Iterator< LinkedList<RelationMember> > listIter = loops.iterator();
    1407       while (listIter.hasNext())
    1408       {
    1409         Iterator<RelationMember> relIter = listIter.next().iterator();
    1410         while (relIter.hasNext())
    1411         {
    1412           RelationMember curMember = relIter.next();
    1413           itineraryData.insertRow(insPos, curMember.getWay(), curMember.getRole());
    1414           if (insPos >= 0)
    1415             ++insPos;
    1416         }
    1417       }
    1418 
    1419       itineraryData.cleanupGaps();
    1420       segmentMetrics = fillSegmentMetrics();
    1421       rebuildWays();
    1422     }
    1423     else if ("routePattern.itineraryReflect".equals(event.getActionCommand()))
    1424     {
    1425       Vector<RelationMember> itemsToReflect = new Vector<RelationMember>();
    1426       int insPos = itineraryTable.getSelectedRow();
    1427 
    1428       if (itineraryTable.getSelectedRowCount() > 0)
    1429       {
    1430         for (int i = itineraryData.getRowCount()-1; i >=0; --i)
    1431         {
    1432           if ((itineraryTable.isRowSelected(i)) && (itineraryData.ways.elementAt(i) != null))
    1433           {
    1434             String role = (String)(itineraryData.getValueAt(i, 1));
    1435             if ("backward".equals(role))
    1436               role = "forward";
    1437             else if ("forward".equals(role))
    1438               role = "backward";
    1439             else
    1440               role = "backward";
    1441             RelationMember markedWay = new RelationMember
    1442             (role, itineraryData.ways.elementAt(i));
    1443             itemsToReflect.addElement(markedWay);
    1444 
    1445             itineraryData.ways.removeElementAt(i);
    1446             itineraryData.removeRow(i);
    1447           }
    1448         }
    1449       }
    1450       else
    1451       {
    1452         for (int i = itineraryData.getRowCount()-1; i >=0; --i)
    1453         {
    1454           if (itineraryData.ways.elementAt(i) != null)
    1455           {
    1456             String role = (String)(itineraryData.getValueAt(i, 1));
    1457             if ("backward".equals(role))
    1458               role = "forward";
    1459             else if ("forward".equals(role))
    1460               role = "backward";
    1461             else
    1462               role = "backward";
    1463             RelationMember markedWay = new RelationMember
    1464             (role, itineraryData.ways.elementAt(i));
    1465             itemsToReflect.addElement(markedWay);
    1466           }
    1467         }
    1468 
    1469         itineraryData.clear();
    1470       }
    1471 
    1472       int startPos = insPos;
    1473       Iterator<RelationMember> relIter = itemsToReflect.iterator();
    1474       while (relIter.hasNext())
    1475       {
    1476         RelationMember curMember = relIter.next();
    1477         if (curMember.isWay())
    1478         {
    1479           itineraryData.insertRow(insPos, curMember.getWay(), curMember.getRole());
    1480           if (insPos >= 0)
    1481             ++insPos;
    1482         }
    1483       }
    1484       if (insPos >= 0)
    1485         itineraryTable.addRowSelectionInterval(startPos, insPos-1);
    1486 
    1487       itineraryData.cleanupGaps();
    1488       segmentMetrics = fillSegmentMetrics();
    1489       rebuildWays();
    1490     }
    1491     else if ("routePattern.stoplistFind".equals(event.getActionCommand()))
    1492     {
    1493       if (mainDataSet == null)
    1494         return;
    1495 
    1496       stoplistTable.clearSelection();
    1497 
    1498       for (int i = 0; i < stoplistData.getRowCount(); ++i)
    1499       {
    1500         if ((stoplistData.nodes.elementAt(i) != null) &&
    1501               (mainDataSet.isSelected(stoplistData.nodes.elementAt(i))))
    1502           stoplistTable.addRowSelectionInterval(i, i);
    1503       }
    1504     }
    1505     else if ("routePattern.stoplistShow".equals(event.getActionCommand()))
    1506     {
    1507       BoundingXYVisitor box = new BoundingXYVisitor();
    1508       if (stoplistTable.getSelectedRowCount() > 0)
    1509       {
    1510         for (int i = 0; i < stoplistData.getRowCount(); ++i)
    1511         {
    1512           if (stoplistTable.isRowSelected(i))
    1513           {
    1514             stoplistData.nodes.elementAt(i).accept(box);
    1515           }
    1516         }
    1517       }
    1518       else
    1519       {
    1520         for (int i = 0; i < stoplistData.getRowCount(); ++i)
    1521         {
    1522           stoplistData.nodes.elementAt(i).accept(box);
    1523         }
    1524       }
    1525       if (box.getBounds() == null)
    1526         return;
    1527       box.enlargeBoundingBox();
    1528       Main.map.mapView.zoomTo(box);
    1529     }
    1530     else if ("routePattern.stoplistMark".equals(event.getActionCommand()))
    1531     {
    1532       OsmPrimitive[] osmp = { null };
    1533       Main.main.getCurrentDataSet().setSelected(osmp);
    1534       markedNodes.clear();
    1535       if (stoplistTable.getSelectedRowCount() > 0)
    1536       {
    1537         for (int i = 0; i < stoplistData.getRowCount(); ++i)
    1538         {
    1539           if (stoplistTable.isRowSelected(i))
    1540           {
    1541             mainDataSet.addSelected(stoplistData.nodes.elementAt(i));
    1542 
    1543             RelationMember markedNode = new RelationMember
    1544             ((String)(stoplistData.getValueAt(i, 1)), stoplistData.nodes.elementAt(i));
    1545             markedNodes.addElement(markedNode);
    1546           }
    1547         }
    1548       }
    1549       else
    1550       {
    1551         for (int i = 0; i < stoplistData.getRowCount(); ++i)
    1552         {
    1553           mainDataSet.addSelected(stoplistData.nodes.elementAt(i));
    1554 
    1555           RelationMember markedNode = new RelationMember
    1556               ((String)(stoplistData.getValueAt(i, 1)), stoplistData.nodes.elementAt(i));
    1557           markedNodes.addElement(markedNode);
    1558         }
    1559       }
    1560     }
    1561     else if ("routePattern.stoplistAdd".equals(event.getActionCommand()))
    1562     {
    1563       int insPos = stoplistTable.getSelectedRow();
    1564       Iterator<RelationMember> relIter = markedNodes.iterator();
    1565       TreeSet<Node> addedNodes = new TreeSet<Node>();
    1566       if (mainDataSet == null)
    1567         return;
    1568 
    1569       while (relIter.hasNext())
    1570       {
    1571         RelationMember curMember = relIter.next();
    1572         if ((curMember.isNode()) && (mainDataSet.isSelected(curMember.getNode())))
    1573         {
    1574           StopReference sr = detectMinDistance
    1575               (curMember.getNode(), segmentMetrics, cbRight.isSelected(), cbLeft.isSelected());
    1576           stoplistData.insertRow(insPos, curMember.getNode(), curMember.getRole(),
    1577               calcOffset(sr, segmentMetrics));
    1578           if (insPos >= 0)
    1579             ++insPos;
    1580 
    1581           addedNodes.add(curMember.getNode());
    1582         }
    1583       }
    1584 
    1585       Collection<Node> selectedNodes = mainDataSet.getSelectedNodes();
    1586       Iterator<Node> nodeIter = selectedNodes.iterator();
    1587 
    1588       while (nodeIter.hasNext())
    1589       {
    1590         Node curMember = nodeIter.next();
    1591         if (!(addedNodes.contains(curMember)))
    1592         {
    1593           StopReference sr = detectMinDistance
    1594               (curMember, segmentMetrics, cbRight.isSelected(), cbLeft.isSelected());
    1595           stoplistData.insertRow(insPos, curMember, "", calcOffset(sr, segmentMetrics));
    1596           if (insPos >= 0)
    1597             ++insPos;
    1598         }
    1599       }
    1600 
    1601       if ((insPos > 0) && (insPos < stoplistData.getRowCount()))
    1602       {
    1603         while ((insPos < stoplistData.getRowCount())
    1604                   && (stoplistData.nodes.elementAt(insPos) == null))
    1605           ++insPos;
    1606         stoplistTable.removeRowSelectionInterval(0, stoplistData.getRowCount()-1);
    1607         if (insPos < stoplistData.getRowCount())
    1608           stoplistTable.addRowSelectionInterval(insPos, insPos);
    1609       }
    1610 
    1611       rebuildNodes();
    1612     }
    1613     else if ("routePattern.stoplistDelete".equals(event.getActionCommand()))
    1614     {
    1615       for (int i = stoplistData.getRowCount()-1; i >=0; --i)
    1616       {
    1617         if (stoplistTable.isRowSelected(i))
    1618         {
    1619           stoplistData.nodes.removeElementAt(i);
    1620           stoplistData.removeRow(i);
    1621         }
    1622       }
    1623 
    1624       rebuildNodes();
    1625     }
    1626     else if ("routePattern.stoplistSort".equals(event.getActionCommand()))
    1627     {
    1628       // Prepare Segments: The segments of all usable ways are arranged in a linear
    1629       // list such that a coor can directly be checked concerning position and offset
    1630       Vector< StopReference > srm = new Vector< StopReference >();
    1631       int insPos = stoplistTable.getSelectedRow();
    1632       if (stoplistTable.getSelectedRowCount() > 0)
    1633       {
    1634         // Determine for each member its position on the itinerary: position means here the
    1635         // point on the itinerary that has minimal distance to the coor
    1636         for (int i = stoplistData.getRowCount()-1; i >= 0; --i)
    1637         {
    1638           if (stoplistTable.isRowSelected(i))
    1639           {
    1640             StopReference sr = detectMinDistance
    1641                 (stoplistData.nodes.elementAt(i), segmentMetrics,
    1642                 cbRight.isSelected(), cbLeft.isSelected());
    1643             if (sr != null)
    1644             {
    1645               if (sr.distance <
    1646                   Double.parseDouble(tfSuggestStopsLimit.getText()) * 9.0 / 1000000.0 )
    1647               {
    1648                 sr.role = (String)stoplistData.getValueAt(i, STOPLIST_ROLE_COLUMN);
    1649                 srm.addElement(sr);
    1650               }
    1651               else
    1652               {
    1653                 sr.role = (String)stoplistData.getValueAt(i, STOPLIST_ROLE_COLUMN);
    1654                 sr.index = segmentMetrics.size()*2;
    1655                 sr.pos = 0;
    1656                 srm.addElement(sr);
    1657               }
    1658 
    1659               stoplistData.nodes.removeElementAt(i);
    1660               stoplistData.removeRow(i);
    1661             }
    1662 
    1663           }
    1664         }
    1665       }
    1666       else
    1667       {
    1668         // Determine for each member its position on the itinerary: position means here the
    1669             // point on the itinerary that has minimal distance to the coor
    1670         for (int i = stoplistData.getRowCount()-1; i >= 0; --i)
    1671         {
    1672           StopReference sr = detectMinDistance
    1673               (stoplistData.nodes.elementAt(i), segmentMetrics,
    1674               cbRight.isSelected(), cbLeft.isSelected());
    1675           if (sr != null)
    1676           {
    1677             if (sr.distance <
    1678                   Double.parseDouble(tfSuggestStopsLimit.getText()) * 9.0 / 1000000.0 )
    1679             {
    1680               sr.role = (String)stoplistData.getValueAt(i, STOPLIST_ROLE_COLUMN);
    1681               srm.addElement(sr);
    1682             }
    1683             else
    1684             {
    1685               sr.role = (String)stoplistData.getValueAt(i, STOPLIST_ROLE_COLUMN);
    1686               sr.index = segmentMetrics.size()*2;
    1687               sr.pos = 0;
    1688               srm.addElement(sr);
    1689             }
    1690           }
    1691         }
    1692 
    1693         stoplistData.clear();
    1694       }
    1695 
    1696       Collections.sort(srm);
    1697 
    1698       for (int i = 0; i < srm.size(); ++i)
    1699       {
    1700         StopReference sr = detectMinDistance
    1701             (srm.elementAt(i).node, segmentMetrics, cbRight.isSelected(), cbLeft.isSelected());
    1702         stoplistData.insertRow(insPos, srm.elementAt(i).node, srm.elementAt(i).role,
    1703             calcOffset(sr, segmentMetrics));
    1704         if (insPos >= 0)
    1705           ++insPos;
    1706       }
    1707 
    1708       rebuildNodes();
    1709     }
    1710     else if ("routePattern.stoplistReflect".equals(event.getActionCommand()))
    1711     {
    1712       Vector< RelationMember > itemsToReflect = new Vector< RelationMember >();
    1713       int insPos = stoplistTable.getSelectedRow();
    1714 
    1715       if (stoplistTable.getSelectedRowCount() > 0)
    1716       {
    1717         for (int i = stoplistData.getRowCount()-1; i >=0; --i)
    1718         {
    1719           if (stoplistTable.isRowSelected(i))
    1720           {
    1721             String role = (String)(stoplistData.getValueAt(i, STOPLIST_ROLE_COLUMN));
    1722             RelationMember markedNode = new RelationMember
    1723                 (role, stoplistData.nodes.elementAt(i));
    1724             itemsToReflect.addElement(markedNode);
    1725 
    1726             stoplistData.nodes.removeElementAt(i);
    1727             stoplistData.removeRow(i);
    1728           }
    1729         }
    1730       }
    1731       else
    1732       {
    1733         for (int i = stoplistData.getRowCount()-1; i >=0; --i)
    1734         {
    1735           String role = (String)(stoplistData.getValueAt(i, STOPLIST_ROLE_COLUMN));
    1736           RelationMember markedNode = new RelationMember
    1737               (role, stoplistData.nodes.elementAt(i));
    1738           itemsToReflect.addElement(markedNode);
    1739         }
    1740 
    1741         stoplistData.clear();
    1742       }
    1743 
    1744       int startPos = insPos;
    1745       Iterator<RelationMember> relIter = itemsToReflect.iterator();
    1746       while (relIter.hasNext())
    1747       {
    1748         RelationMember curMember = relIter.next();
    1749         if (curMember.isNode())
    1750         {
    1751           StopReference sr = detectMinDistance
    1752               (curMember.getNode(), segmentMetrics, cbRight.isSelected(), cbLeft.isSelected());
    1753           stoplistData.insertRow(insPos, curMember.getNode(), curMember.getRole(),
    1754               calcOffset(sr, segmentMetrics));
    1755           if (insPos >= 0)
    1756             ++insPos;
    1757         }
    1758       }
    1759       if (insPos >= 0)
    1760         stoplistTable.addRowSelectionInterval(startPos, insPos-1);
    1761 
    1762       rebuildNodes();
    1763     }
    1764     else if ("routePattern.metaSuggestStops".equals(event.getActionCommand()))
    1765     {
    1766       // Prepare Segments: The segments of all usable ways are arranged in a linear
    1767       // list such that a coor can directly be checked concerning position and offset
    1768       Vector< StopReference > srm = new Vector< StopReference >();
    1769       // Determine for each member its position on the itinerary: position means here the
    1770       // point on the itinerary that has minimal distance to the coor
    1771       mainDataSet = Main.main.getCurrentDataSet();
    1772       if (mainDataSet != null)
    1773       {
    1774         String stopKey = "";
    1775         String stopValue = "";
    1776         if ("bus".equals(currentRoute.get("route")))
    1777         {
    1778           stopKey = "highway";
    1779           stopValue = "bus_stop";
    1780         }
    1781         else if ("trolleybus".equals(currentRoute.get("route")))
    1782         {
    1783           stopKey = "highway";
    1784           stopValue = "bus_stop";
    1785         }
    1786         else if ("tram".equals(currentRoute.get("route")))
    1787         {
    1788           stopKey = "railway";
    1789           stopValue = "tram_stop";
    1790         }
    1791         else if ("light_rail".equals(currentRoute.get("route")))
    1792         {
    1793           stopKey = "railway";
    1794           stopValue = "station";
    1795         }
    1796         else if ("subway".equals(currentRoute.get("route")))
    1797         {
    1798           stopKey = "railway";
    1799           stopValue = "station";
    1800         }
    1801         else if ("rail".equals(currentRoute.get("route")))
    1802         {
    1803           stopKey = "railway";
    1804           stopValue = "station";
    1805         }
    1806 
    1807         Collection< Node > nodeCollection = mainDataSet.getNodes();
    1808         Iterator< Node > nodeIter = nodeCollection.iterator();
    1809         while (nodeIter.hasNext())
    1810         {
    1811           Node currentNode = nodeIter.next();
    1812           if (!currentNode.isUsable())
    1813             continue;
    1814           if (stopValue.equals(currentNode.get(stopKey)))
    1815           {
    1816             StopReference sr = detectMinDistance
    1817                 (currentNode, segmentMetrics, cbRight.isSelected(), cbLeft.isSelected());
    1818             if ((sr != null) && (sr.distance <
    1819                 Double.parseDouble(tfSuggestStopsLimit.getText()) * 9.0 / 1000000.0 ))
    1820               srm.addElement(sr);
    1821           }
    1822         }
    1823       }
    1824       else
    1825       {
    1826         JOptionPane.showMessageDialog(null, tr("There exists no dataset."
    1827             + " Try to download data from the server or open an OSM file."),
    1828         tr("No data found"), JOptionPane.ERROR_MESSAGE);
    1829       }
    1830 
    1831       Collections.sort(srm);
    1832 
    1833       stoplistData.clear();
    1834       for (int i = 0; i < srm.size(); ++i)
    1835       {
    1836         StopReference sr = detectMinDistance
    1837             (srm.elementAt(i).node, segmentMetrics, cbRight.isSelected(), cbLeft.isSelected());
    1838         stoplistData.addRow(srm.elementAt(i).node, srm.elementAt(i).role,
    1839             calcOffset(sr, segmentMetrics));
    1840       }
    1841 
    1842       rebuildNodes();
    1843     }
    1844     else
    1845     {
    1846       refreshData();
    1847 
    1848       jDialog.setLocationRelativeTo(frame);
    1849       jDialog.setVisible(true);
    1850     }
    1851   }
    1852 
    1853   private void refreshData() {
    1854     Relation copy = currentRoute;
    1855     relsListModel.clear();
    1856     currentRoute = copy;
    1857 
    1858     DataSet mainDataSet = Main.main.getCurrentDataSet();
    1859     if (mainDataSet != null)
    1860     {
    1861       Vector< RouteReference > relRefs = new Vector< RouteReference >();
    1862       Collection< Relation > relCollection = mainDataSet.getRelations();
    1863       Iterator< Relation > relIter = relCollection.iterator();
    1864 
    1865       while (relIter.hasNext())
    1866       {
    1867         Relation currentRel = relIter.next();
    1868         if (!currentRel.isDeleted())
    1869         {
    1870           String routeVal = currentRel.get("route");
    1871           if ("bus".equals(routeVal))
    1872             relRefs.add(new RouteReference(currentRel));
    1873           else if ("trolleybus".equals(routeVal))
    1874             relRefs.add(new RouteReference(currentRel));
    1875           else if ("tram".equals(routeVal))
    1876             relRefs.add(new RouteReference(currentRel));
    1877           else if ("light_rail".equals(routeVal))
    1878             relRefs.add(new RouteReference(currentRel));
    1879           else if ("subway".equals(routeVal))
    1880             relRefs.add(new RouteReference(currentRel));
    1881           else if ("rail".equals(routeVal))
    1882             relRefs.add(new RouteReference(currentRel));
    1883         }
    1884       }
    1885 
    1886       Collections.sort(relRefs);
    1887 
    1888       Iterator< RouteReference > iter = relRefs.iterator();
    1889       while (iter.hasNext())
    1890         relsListModel.addElement(iter.next());
    1891     }
    1892     else
    1893     {
    1894       JOptionPane.showMessageDialog(null, tr("There exists no dataset."
    1895       + " Try to download data from the server or open an OSM file."),
    1896       tr("No data found"), JOptionPane.ERROR_MESSAGE);
    1897     }
    1898   }
    1899 
    1900   //Rebuild ways in the relation currentRoute
    1901   public static void rebuildWays() {
    1902     currentRoute.setModified(true);
    1903     List< RelationMember > members = currentRoute.getMembers();
    1904     ListIterator< RelationMember > iter = members.listIterator();
    1905     while (iter.hasNext())
    1906     {
    1907       if (iter.next().isWay())
    1908     iter.remove();
    1909     }
    1910     for (int i = 0; i < itineraryData.getRowCount(); ++i)
    1911     {
    1912       if (itineraryData.ways.elementAt(i) != null)
    1913       {
    1914         RelationMember member = new RelationMember
    1915         ((String)(itineraryData.getValueAt(i, 1)),
    1916          itineraryData.ways.elementAt(i));
    1917         members.add(member);
    1918       }
    1919     }
    1920     currentRoute.setMembers(members);
    1921   }
    1922 
    1923   //Rebuild nodes in the relation currentRoute
    1924   private void rebuildNodes() {
    1925     currentRoute.setModified(true);
    1926     for (int i = currentRoute.getMembersCount()-1; i >=0; --i)
    1927     {
    1928       if (currentRoute.getMember(i).isNode())
    1929       {
    1930         currentRoute.removeMember(i);
    1931       }
    1932     }
    1933     for (int i = 0; i < stoplistData.getRowCount(); ++i)
    1934     {
    1935       RelationMember member = new RelationMember
    1936           ((String)(stoplistData.getValueAt(i, STOPLIST_ROLE_COLUMN)),
    1937            stoplistData.nodes.elementAt(i));
    1938       currentRoute.addMember(member);
    1939     }
    1940   }
    1941 
    1942   private void addWayToSortingData
    1943       (Way way, TreeMap<Node, LinkedList<RelationMember> > frontNodes,
    1944        TreeMap<Node, LinkedList<RelationMember> > backNodes,
    1945        Vector< LinkedList<RelationMember> > loops)
    1946   {
    1947     if (way.getNodesCount() < 1)
    1948       return;
    1949 
    1950     Node firstNode = way.getNode(0);
    1951     Node lastNode = way.getNode(way.getNodesCount() - 1);
    1952 
    1953     if (frontNodes.get(firstNode) != null)
    1954     {
    1955       LinkedList<RelationMember> list = frontNodes.get(firstNode);
    1956       list.addFirst(new RelationMember("backward", way));
    1957       frontNodes.remove(firstNode);
    1958 
    1959       Node lastListNode = null;
    1960       if ("backward".equals(list.getLast().getRole()))
    1961         lastListNode = list.getLast().getWay().getNode(0);
    1962       else
    1963         lastListNode = list.getLast().getWay().getNode
    1964         (list.getLast().getWay().getNodesCount() - 1);
    1965       if (lastNode.equals(lastListNode))
    1966       {
    1967         backNodes.remove(lastListNode);
    1968         loops.add(list);
    1969       }
    1970       else if (frontNodes.get(lastNode) != null)
    1971       {
    1972         backNodes.remove(lastListNode);
    1973         LinkedList<RelationMember> listToAppend = frontNodes.get(lastNode);
    1974         Iterator<RelationMember> memberIter = list.iterator();
    1975         while (memberIter.hasNext())
    1976         {
    1977           RelationMember member = memberIter.next();
    1978           if ("backward".equals(member.getRole()))
    1979             listToAppend.addFirst(new RelationMember("forward", member.getWay()));
    1980           else
    1981             listToAppend.addFirst(new RelationMember("backward", member.getWay()));
    1982         }
    1983         frontNodes.remove(lastNode);
    1984         frontNodes.put(lastListNode, listToAppend);
    1985       }
    1986       else if (backNodes.get(lastNode) != null)
    1987       {
    1988         backNodes.remove(lastListNode);
    1989         LinkedList<RelationMember> listToAppend = backNodes.get(lastNode);
    1990         Iterator<RelationMember> memberIter = list.iterator();
    1991         while (memberIter.hasNext())
    1992         {
    1993           RelationMember member = memberIter.next();
    1994           listToAppend.addLast(member);
    1995         }
    1996         backNodes.remove(lastNode);
    1997         backNodes.put(lastListNode, listToAppend);
    1998       }
    1999       else
    2000         frontNodes.put(lastNode, list);
    2001     }
    2002     else if (backNodes.get(firstNode) != null)
    2003     {
    2004       LinkedList<RelationMember> list = backNodes.get(firstNode);
    2005       list.addLast(new RelationMember("forward", way));
    2006       backNodes.remove(firstNode);
    2007 
    2008       Node firstListNode = null;
    2009       if ("backward".equals(list.getFirst().getRole()))
    2010         firstListNode = list.getFirst().getWay().getNode
    2011         (list.getFirst().getWay().getNodesCount() - 1);
    2012       else
    2013         firstListNode = list.getFirst().getWay().getNode(0);
    2014       if (lastNode.equals(firstListNode))
    2015       {
    2016         frontNodes.remove(firstListNode);
    2017         loops.add(list);
    2018       }
    2019       else if (frontNodes.get(lastNode) != null)
    2020       {
    2021         frontNodes.remove(firstListNode);
    2022         LinkedList<RelationMember> listToAppend = frontNodes.get(lastNode);
    2023         ListIterator<RelationMember> memberIter = list.listIterator(list.size());
    2024         while (memberIter.hasPrevious())
    2025         {
    2026           RelationMember member = memberIter.previous();
    2027           listToAppend.addFirst(member);
    2028         }
    2029         frontNodes.remove(lastNode);
    2030         frontNodes.put(firstListNode, listToAppend);
    2031       }
    2032       else if (backNodes.get(lastNode) != null)
    2033       {
    2034         frontNodes.remove(firstListNode);
    2035         LinkedList<RelationMember> listToAppend = backNodes.get(lastNode);
    2036         ListIterator<RelationMember> memberIter = list.listIterator(list.size());
    2037         while (memberIter.hasPrevious())
    2038         {
    2039           RelationMember member = memberIter.previous();
    2040           if ("backward".equals(member.getRole()))
    2041             listToAppend.addLast(new RelationMember("forward", member.getWay()));
    2042           else
    2043             listToAppend.addLast(new RelationMember("backward", member.getWay()));
    2044         }
    2045         backNodes.remove(lastNode);
    2046         backNodes.put(firstListNode, listToAppend);
    2047       }
    2048       else
    2049         backNodes.put(lastNode, list);
    2050     }
    2051     else if (frontNodes.get(lastNode) != null)
    2052     {
    2053       LinkedList<RelationMember> list = frontNodes.get(lastNode);
    2054       list.addFirst(new RelationMember("forward", way));
    2055       frontNodes.remove(lastNode);
    2056       frontNodes.put(firstNode, list);
    2057     }
    2058     else if (backNodes.get(lastNode) != null)
    2059     {
    2060       LinkedList<RelationMember> list = backNodes.get(lastNode);
    2061       list.addLast(new RelationMember("backward", way));
    2062       backNodes.remove(lastNode);
    2063       backNodes.put(firstNode, list);
    2064     }
    2065     else
    2066     {
    2067       LinkedList<RelationMember> newList = new LinkedList<RelationMember>();
    2068       newList.add(new RelationMember("forward", way));
    2069       frontNodes.put(firstNode, newList);
    2070       backNodes.put(lastNode, newList);
    2071     }
    2072   }
    2073 
    2074   private void routesSelectionChanged() {
    2075     int selectedPos = relsList.getAnchorSelectionIndex();
    2076     if (relsList.isSelectedIndex(selectedPos))
    2077     {
    2078       currentRoute = relsListModel.elementAt(selectedPos).route;
    2079       tabbedPane.setEnabledAt(1, true);
    2080       tabbedPane.setEnabledAt(2, true);
    2081       tabbedPane.setEnabledAt(3, true);
    2082       tabbedPane.setEnabledAt(4, true);
    2083 
    2084       //Prepare Tags
    2085       requiredTagsData.readRelation(currentRoute);
    2086       commonTagsData.readRelation(currentRoute);
    2087       otherTagsData.readRelation(currentRoute, tagBlacklist);
    2088 
    2089       //Prepare Itinerary
    2090       itineraryData.clear();
    2091       List<RelationMember> relMembers = currentRoute.getMembers();
    2092       Iterator<RelationMember> relIter = relMembers.iterator();
    2093       fillItineraryTable(relIter, 0, -1);
    2094 
    2095       //Prepare Stoplist
    2096       stoplistData.clear();
    2097       /*List<RelationMember>*/ relMembers = currentRoute.getMembers();
    2098       /*Iterator<RelationMember>*/ relIter = relMembers.iterator();
    2099       fillStoplistTable(relIter, -1);
    2100     }
    2101     else
    2102     {
    2103       currentRoute = null;
    2104       tabbedPane.setEnabledAt(1, false);
    2105       tabbedPane.setEnabledAt(2, false);
    2106       tabbedPane.setEnabledAt(3, false);
    2107       tabbedPane.setEnabledAt(4, false);
    2108     }
    2109   }
    2110 
    2111   private void fillItineraryTable
    2112       (Iterator<RelationMember> relIter, long lastNodeId, int insPos) {
    2113     while (relIter.hasNext())
    2114     {
    2115       RelationMember curMember = relIter.next();
    2116       if (curMember.isWay())
    2117       {
    2118         itineraryData.insertRow(insPos, curMember.getWay(), curMember.getRole());
    2119         if (insPos >= 0)
    2120           ++insPos;
    2121       }
    2122     }
    2123     itineraryData.cleanupGaps();
    2124     segmentMetrics = fillSegmentMetrics();
    2125   }
    2126 
    2127   private double calcOffset(StopReference sr, Vector< SegmentMetric > segmentMetrics)
    2128   {
    2129     double offset = 0;
    2130     if ((sr.index+1) / 2 < segmentMetrics.size())
    2131     {
    2132       offset = segmentMetrics.elementAt((sr.index+1) / 2).distance;
    2133       if (sr.index % 2 == 0)
    2134         offset += sr.pos;
    2135     }
    2136     else
    2137       offset = segmentMetrics.elementAt(segmentMetrics.size() - 1).distance
    2138           + segmentMetrics.elementAt(segmentMetrics.size() - 1).length;
    2139 
    2140     return offset;
    2141   }
    2142 
    2143   private void fillStoplistTable
    2144       (Iterator<RelationMember> relIter, int insPos) {
    2145 
    2146     while (relIter.hasNext())
    2147     {
    2148       RelationMember curMember = relIter.next();
    2149       if (curMember.isNode())
    2150       {
    2151         StopReference sr = detectMinDistance
    2152             (curMember.getNode(), segmentMetrics, cbRight.isSelected(), cbLeft.isSelected());
    2153         if (sr == null)
    2154           stoplistData.insertRow(insPos, curMember.getNode(), curMember.getRole(), 360.0);
    2155         else
    2156         {
    2157           stoplistData.insertRow(insPos, curMember.getNode(), curMember.getRole(),
    2158               calcOffset(sr, segmentMetrics));
    2159           if (insPos >= 0)
    2160             ++insPos;
    2161         }
    2162       }
    2163     }
    2164   }
    2165 
    2166   private Vector< SegmentMetric > fillSegmentMetrics()
    2167   {
    2168     Vector< SegmentMetric > segmentMetrics = new Vector< SegmentMetric >();
    2169     double distance = 0;
    2170     for (int i = 0; i < itineraryData.getRowCount(); ++i)
    2171     {
    2172       if (itineraryData.ways.elementAt(i) != null)
    2173       {
    2174         Way way = itineraryData.ways.elementAt(i);
    2175         if (!(way.isIncomplete()))
    2176         {
    2177           if ("backward".equals((itineraryData.getValueAt(i, 1))))
    2178           {
    2179             for (int j = way.getNodesCount()-2; j >= 0; --j)
    2180             {
    2181               SegmentMetric sm = new SegmentMetric
    2182                   (way.getNode(j+1).getCoor().lat(), way.getNode(j+1).getCoor().lon(),
    2183                   way.getNode(j).getCoor().lat(), way.getNode(j).getCoor().lon(), distance);
    2184               segmentMetrics.add(sm);
    2185               distance += sm.length;
    2186             }
    2187           }
    2188           else
    2189           {
    2190             for (int j = 0; j < way.getNodesCount()-1; ++j)
    2191             {
    2192               SegmentMetric sm = new SegmentMetric
    2193                   (way.getNode(j).getCoor().lat(), way.getNode(j).getCoor().lon(),
    2194                   way.getNode(j+1).getCoor().lat(), way.getNode(j+1).getCoor().lon(), distance);
    2195               segmentMetrics.add(sm);
    2196               distance += sm.length;
    2197             }
    2198           }
    2199         }
    2200       }
    2201       else
    2202         segmentMetrics.add(null);
    2203     }
    2204     return segmentMetrics;
    2205   }
    2206 
    2207   private StopReference detectMinDistance
    2208       (Node node, Vector< SegmentMetric > segmentMetrics,
    2209        boolean rhsPossible, boolean lhsPossible) {
    2210     if (node == null || node.getCoor() == null)
    2211       return null;
    2212 
    2213     int minIndex = -1;
    2214     double position = -1.0;
    2215     double distance = 180.0;
    2216     double lat = node.getCoor().lat();
    2217     double lon = node.getCoor().lon();
    2218 
    2219     int curIndex = -2;
    2220     double angleLat = 100.0;
    2221     double angleLon = 200.0;
    2222     Iterator<SegmentMetric> iter = segmentMetrics.iterator();
    2223     while (iter.hasNext())
    2224     {
    2225       curIndex += 2;
    2226       SegmentMetric sm = iter.next();
    2227 
    2228       if (sm == null)
    2229       {
    2230         angleLat = 100.0;
    2231         angleLon = 200.0;
    2232 
    2233         continue;
    2234       }
    2235 
    2236       double curPosition = (lat - sm.aLat)*sm.d1 + (lon - sm.aLon)*sm.d2;
    2237 
    2238       if (curPosition < 0)
    2239       {
    2240         if (angleLat <= 90.0)
    2241         {
    2242           double lastSegAngle = Math.atan2(angleLat - sm.aLat, angleLon - sm.aLon);
    2243           double segAngle = Math.atan2(sm.d1, -sm.o1);
    2244           double vertexAngle = Math.atan2(lat - sm.aLat, lon - sm.aLon);
    2245 
    2246           boolean vertexOnSeg = (vertexAngle == segAngle) ||
    2247               (vertexAngle == lastSegAngle);
    2248           boolean vertexOnTheLeft = (!vertexOnSeg) &&
    2249               (((lastSegAngle > vertexAngle) && (vertexAngle > segAngle))
    2250               || ((vertexAngle > segAngle) && (segAngle > lastSegAngle))
    2251               || ((segAngle > lastSegAngle) && (lastSegAngle > vertexAngle)));
    2252 
    2253           double currentDistance = Math.sqrt((lat - sm.aLat)*(lat - sm.aLat)
    2254             + (lon - sm.aLon)*(lon - sm.aLon)
    2255             *Math.cos(sm.aLat * Math.PI/180.0)*Math.cos(sm.aLat * Math.PI/180.0));
    2256           curPosition = vertexAngle - segAngle;
    2257           if (vertexOnTheLeft)
    2258             curPosition = -curPosition;
    2259           if (curPosition < 0)
    2260             curPosition += 2*Math.PI;
    2261           if ((Math.abs(currentDistance) < distance)
    2262             && (((!vertexOnTheLeft) && (rhsPossible))
    2263             || ((vertexOnTheLeft) && (lhsPossible))
    2264               || (vertexOnSeg)))
    2265           {
    2266             distance = Math.abs(currentDistance);
    2267             minIndex = curIndex-1;
    2268             position = curPosition;
    2269           }
    2270         }
    2271         angleLat = 100.0;
    2272         angleLon = 200.0;
    2273       }
    2274       else if (curPosition > sm.length)
    2275       {
    2276         angleLat = sm.aLat;
    2277         angleLon = sm.aLon;
    2278       }
    2279       else
    2280       {
    2281         double currentDistance = (lat - sm.aLat)*sm.o1 + (lon - sm.aLon)*sm.o2;
    2282         if ((Math.abs(currentDistance) < distance)
    2283                 && (((currentDistance >= 0) && (rhsPossible))
    2284                 || ((currentDistance <= 0) && (lhsPossible))))
    2285         {
    2286           distance = Math.abs(currentDistance);
    2287           minIndex = curIndex;
    2288           position = curPosition;
    2289         }
    2290 
    2291         angleLat = 100.0;
    2292         angleLon = 200.0;
    2293       }
    2294     }
    2295 
    2296     if (minIndex == -1)
    2297       return new StopReference(segmentMetrics.size()*2, 0, 180.0, node.get("name"),
    2298                    "", node);
    2299 
    2300     return new StopReference(minIndex, position, distance, node.get("name"),
    2301                  "", node);
    2302   }
    23032074}
  • applications/editors/josm/plugins/public_transport/src/public_transport/SettingsStoptypeCommand.java

    r29854 r32357  
    1212import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1313
    14 public class SettingsStoptypeCommand extends Command
    15 {
    16   private class HighwayRailway
    17   {
    18     public HighwayRailway(Node node)
    19     {
    20       this.node = node;
    21       highway = node.get("highway");
    22       railway = node.get("railway");
     14public class SettingsStoptypeCommand extends Command {
     15    private class HighwayRailway {
     16        public HighwayRailway(Node node) {
     17            this.node = node;
     18            highway = node.get("highway");
     19            railway = node.get("railway");
     20        }
     21
     22        public Node node;
     23
     24        public String highway;
     25
     26        public String railway;
    2327    }
    2428
    25     public Node node;
    26     public String highway;
    27     public String railway;
    28   };
     29    private Vector<HighwayRailway> oldStrings = null;
    2930
    30   private Vector< HighwayRailway > oldStrings = null;
    31   private WaypointTableModel waypointTM = null;
    32   private DefaultListModel tracksListModel = null;
    33   private String type = null;
     31    private WaypointTableModel waypointTM = null;
    3432
    35   public SettingsStoptypeCommand(StopImporterAction controller)
    36   {
    37     waypointTM = controller.getWaypointTableModel();
    38     tracksListModel = controller.getTracksListModel();
    39     type = controller.getDialog().getStoptype();
    40     oldStrings = new Vector< HighwayRailway >();
    41   }
     33    private DefaultListModel<?> tracksListModel = null;
    4234
    43   public boolean executeCommand()
    44   {
    45     oldStrings.clear();
    46     for (int i = 0; i < waypointTM.getRowCount(); ++i)
    47     {
    48       if ((Node)waypointTM.nodes.elementAt(i) != null)
    49       {
    50         Node node = (Node)waypointTM.nodes.elementAt(i);
    51         oldStrings.add(new HighwayRailway(node));
    52         StopImporterAction.setTagsWrtType(node, type);
    53       }
     35    private String type = null;
     36
     37    public SettingsStoptypeCommand(StopImporterAction controller) {
     38        waypointTM = controller.getWaypointTableModel();
     39        tracksListModel = controller.getTracksListModel();
     40        type = controller.getDialog().getStoptype();
     41        oldStrings = new Vector<>();
    5442    }
    55     for (int j = 0; j < tracksListModel.size(); ++j)
    56     {
    57       TrackReference track = (TrackReference)tracksListModel.elementAt(j);
    58       for (int i = 0; i < track.stoplistTM.getRowCount(); ++i)
    59       {
    60         if (track.stoplistTM.nodeAt(i) != null)
    61         {
    62           Node node = track.stoplistTM.nodeAt(i);
    63           oldStrings.add(new HighwayRailway(node));
    64           StopImporterAction.setTagsWrtType(node, type);
     43
     44    @Override
     45    public boolean executeCommand() {
     46        oldStrings.clear();
     47        for (int i = 0; i < waypointTM.getRowCount(); ++i) {
     48            if (waypointTM.nodes.elementAt(i) != null) {
     49                Node node = waypointTM.nodes.elementAt(i);
     50                oldStrings.add(new HighwayRailway(node));
     51                StopImporterAction.setTagsWrtType(node, type);
     52            }
    6553        }
    66       }
     54        for (int j = 0; j < tracksListModel.size(); ++j) {
     55            TrackReference track = (TrackReference) tracksListModel.elementAt(j);
     56            for (int i = 0; i < track.stoplistTM.getRowCount(); ++i) {
     57                if (track.stoplistTM.nodeAt(i) != null) {
     58                    Node node = track.stoplistTM.nodeAt(i);
     59                    oldStrings.add(new HighwayRailway(node));
     60                    StopImporterAction.setTagsWrtType(node, type);
     61                }
     62            }
     63        }
     64        return true;
    6765    }
    68     return true;
    69   }
    7066
    71   public void undoCommand()
    72   {
    73     for (int i = 0; i < oldStrings.size(); ++i)
    74     {
    75       HighwayRailway hr = oldStrings.elementAt(i);
    76       hr.node.put("highway", hr.highway);
    77       hr.node.put("railway", hr.railway);
     67    @Override
     68    public void undoCommand() {
     69        for (int i = 0; i < oldStrings.size(); ++i) {
     70            HighwayRailway hr = oldStrings.elementAt(i);
     71            hr.node.put("highway", hr.highway);
     72            hr.node.put("railway", hr.railway);
     73        }
    7874    }
    79   }
    8075
    81   public void fillModifiedData
    82     (Collection< OsmPrimitive > modified, Collection< OsmPrimitive > deleted,
    83      Collection< OsmPrimitive > added)
    84   {
    85   }
     76    @Override
     77    public void fillModifiedData(Collection<OsmPrimitive> modified,
     78            Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
     79    }
    8680
    87   @Override public String getDescriptionText()
    88   {
    89     return tr("Public Transport: Change stop type");
    90   }
    91 
    92 };
     81    @Override
     82    public String getDescriptionText() {
     83        return tr("Public Transport: Change stop type");
     84    }
     85}
  • applications/editors/josm/plugins/public_transport/src/public_transport/StopImporterAction.java

    r31114 r32357  
    2929import org.openstreetmap.josm.data.gpx.GpxTrack;
    3030import org.openstreetmap.josm.data.gpx.WayPoint;
     31import org.openstreetmap.josm.data.osm.DataSet;
    3132import org.openstreetmap.josm.data.osm.Node;
    3233import org.openstreetmap.josm.data.osm.OsmPrimitive;
     
    3536import org.xml.sax.SAXException;
    3637
    37 public class StopImporterAction extends JosmAction
    38 {
    39   private static StopImporterDialog dialog = null;
    40   private static DefaultListModel<TrackReference> tracksListModel = null;
    41   private static GpxData data = null;
    42   private static TrackReference currentTrack = null;
    43   private static WaypointTableModel waypointTM = null;
    44   public boolean inEvent = false;
    45 
    46   public StopImporterAction()
    47   {
    48     super(tr("Create Stops from GPX ..."), null,
    49       tr("Create Stops from a GPX file"), null, false);
    50     putValue("toolbar", "publictransport/stopimporter");
    51     Main.toolbar.register(this);
    52   }
    53 
    54   public WaypointTableModel getWaypointTableModel()
    55   {
    56     return waypointTM;
    57   }
    58 
    59   public StopImporterDialog getDialog()
    60   {
    61     return dialog;
    62   }
    63 
    64   public DefaultListModel<TrackReference> getTracksListModel()
    65   {
    66     if (tracksListModel == null)
    67       tracksListModel = new DefaultListModel<>();
    68     return tracksListModel;
    69   }
    70 
    71   public TrackReference getCurrentTrack()
    72   {
    73     return currentTrack;
    74   }
    75 
    76   @Override
    77 public void actionPerformed(ActionEvent event)
    78   {
    79     if (dialog == null)
    80       dialog = new StopImporterDialog(this);
    81 
    82     dialog.setVisible(true);
    83 
    84     if (tr("Create Stops from GPX ...").equals(event.getActionCommand()))
    85     {
    86       String curDir = Main.pref.get("lastDirectory");
    87       if (curDir.equals(""))
    88       {
    89         curDir = ".";
    90       }
    91       JFileChooser fc = new JFileChooser(new File(curDir));
    92       fc.setDialogTitle(tr("Select GPX file"));
    93       fc.setMultiSelectionEnabled(false);
    94 
    95       int answer = fc.showOpenDialog(Main.parent);
    96       if (answer != JFileChooser.APPROVE_OPTION)
    97         return;
    98 
    99       if (!fc.getCurrentDirectory().getAbsolutePath().equals(curDir))
    100         Main.pref.put("lastDirectory", fc.getCurrentDirectory().getAbsolutePath());
    101 
    102       importData(fc.getSelectedFile());
    103 
    104       refreshData();
    105     }
    106     else if ("stopImporter.settingsGPSTimeStart".equals(event.getActionCommand()))
    107     {
    108       if ((!inEvent) && (dialog.gpsTimeStartValid()) && (currentTrack != null))
    109       Main.main.undoRedo.add(new TrackStoplistRelocateCommand(this));
    110     }
    111     else if ("stopImporter.settingsStopwatchStart".equals(event.getActionCommand()))
    112     {
    113       if ((!inEvent) && (dialog.stopwatchStartValid()) && (currentTrack != null))
    114       Main.main.undoRedo.add(new TrackStoplistRelocateCommand(this));
    115     }
    116     else if ("stopImporter.settingsTimeWindow".equals(event.getActionCommand()))
    117     {
    118       if (currentTrack != null)
    119       currentTrack.timeWindow = dialog.getTimeWindow();
    120     }
    121     else if ("stopImporter.settingsThreshold".equals(event.getActionCommand()))
    122     {
    123       if (currentTrack != null)
    124         currentTrack.threshold = dialog.getThreshold();
    125     }
    126     else if ("stopImporter.settingsSuggestStops".equals(event.getActionCommand()))
    127       Main.main.undoRedo.add(new TrackSuggestStopsCommand(this));
    128     else if ("stopImporter.stoplistFind".equals(event.getActionCommand()))
    129       findNodesInTable(dialog.getStoplistTable(), currentTrack.stoplistTM.getNodes());
    130     else if ("stopImporter.stoplistShow".equals(event.getActionCommand()))
    131       showNodesFromTable(dialog.getStoplistTable(), currentTrack.stoplistTM.getNodes());
    132     else if ("stopImporter.stoplistMark".equals(event.getActionCommand()))
    133       markNodesFromTable(dialog.getStoplistTable(), currentTrack.stoplistTM.getNodes());
    134     else if ("stopImporter.stoplistDetach".equals(event.getActionCommand()))
    135     {
    136       Main.main.undoRedo.add(new TrackStoplistDetachCommand(this));
    137       dialog.getStoplistTable().clearSelection();
    138     }
    139     else if ("stopImporter.stoplistAdd".equals(event.getActionCommand()))
    140       Main.main.undoRedo.add(new TrackStoplistAddCommand(this));
    141     else if ("stopImporter.stoplistDelete".equals(event.getActionCommand()))
    142       Main.main.undoRedo.add(new TrackStoplistDeleteCommand(this));
    143     else if ("stopImporter.stoplistSort".equals(event.getActionCommand()))
    144       Main.main.undoRedo.add(new TrackStoplistSortCommand(this));
    145     else if ("stopImporter.waypointsFind".equals(event.getActionCommand()))
    146       findNodesInTable(dialog.getWaypointsTable(), waypointTM.nodes);
    147     else if ("stopImporter.waypointsShow".equals(event.getActionCommand()))
    148       showNodesFromTable(dialog.getWaypointsTable(), waypointTM.nodes);
    149     else if ("stopImporter.waypointsMark".equals(event.getActionCommand()))
    150       markNodesFromTable(dialog.getWaypointsTable(), waypointTM.nodes);
    151     else if ("stopImporter.waypointsDetach".equals(event.getActionCommand()))
    152     {
    153       Main.main.undoRedo.add(new WaypointsDetachCommand(this));
    154       dialog.getWaypointsTable().clearSelection();
    155     }
    156     else if ("stopImporter.waypointsAdd".equals(event.getActionCommand()))
    157       Main.main.undoRedo.add(new WaypointsEnableCommand(this));
    158     else if ("stopImporter.waypointsDelete".equals(event.getActionCommand()))
    159       Main.main.undoRedo.add(new WaypointsDisableCommand(this));
    160     else if ("stopImporter.settingsStoptype".equals(event.getActionCommand()))
    161       Main.main.undoRedo.add(new SettingsStoptypeCommand(this));
    162   }
    163 
    164   private void importData(final File file)
    165   {
    166     try
    167     {
    168       InputStream is;
    169       if (file.getName().endsWith(".gpx.gz"))
    170         is = new GZIPInputStream(new FileInputStream(file));
    171       else
    172         is = new FileInputStream(file);
    173       // Workaround for SAX BOM bug
    174       // https://bugs.openjdk.java.net/browse/JDK-6206835
    175       if (!((is.read() == 0xef) && (is.read() == 0xbb) && (is.read() == 0xbf)))
    176       {
    177         is.close();
    178         if (file.getName().endsWith(".gpx.gz"))
    179           is = new GZIPInputStream(new FileInputStream(file));
    180         else
    181           is = new FileInputStream(file);
    182       }
    183       final GpxReader r = new GpxReader(is);
    184       final boolean parsedProperly = r.parse(true);
    185       data = r.getGpxData();
    186 
    187       if (!parsedProperly)
    188       {
    189         JOptionPane.showMessageDialog(null, tr("Error occurred while parsing gpx file {0}. Only a part of the file will be available.", file.getName()));
    190       }
    191     }
    192     catch (FileNotFoundException e)
    193     {
    194       e.printStackTrace();
    195       JOptionPane.showMessageDialog(null, tr("File \"{0}\" does not exist", file.getName()));
    196     }
    197     catch (SAXException e)
    198     {
    199       e.printStackTrace();
    200       JOptionPane.showMessageDialog(null, tr("Parsing file \"{0}\" failed", file.getName()));
    201     }
    202     catch (IOException e)
    203     {
    204       e.printStackTrace();
    205       JOptionPane.showMessageDialog(null, tr("IOException \"{0}\" occurred", e.toString()));
    206     }
    207   }
    208 
    209   private void refreshData()
    210   {
    211     tracksListModel.clear();
    212     if (data != null)
    213     {
    214       Vector< TrackReference > trackRefs = new Vector< TrackReference >();
    215       Iterator< GpxTrack > trackIter = data.tracks.iterator();
    216       while (trackIter.hasNext())
    217       {
    218         GpxTrack track = trackIter.next();
    219         trackRefs.add(new TrackReference(track, this));
    220       }
    221 
    222       Collections.sort(trackRefs);
    223 
    224       Iterator< TrackReference > iter = trackRefs.iterator();
    225       while (iter.hasNext())
    226         tracksListModel.addElement(iter.next());
    227 
    228       waypointTM = new WaypointTableModel(this);
    229       Iterator< WayPoint > waypointIter = data.waypoints.iterator();
    230       while (waypointIter.hasNext())
    231       {
    232         WayPoint waypoint = waypointIter.next();
    233         waypointTM.addRow(waypoint);
    234       }
    235       dialog.setWaypointsTableModel(waypointTM);
    236     }
    237     else
    238     {
    239       JOptionPane.showMessageDialog
    240       (null, tr("The GPX file contained no tracks or waypoints."), tr("No data found"),
    241        JOptionPane.ERROR_MESSAGE);
    242     }
    243   }
    244 
    245   public void tracksSelectionChanged(int selectedPos)
    246   {
    247     if (selectedPos >= 0)
    248     {
    249       currentTrack = (tracksListModel.elementAt(selectedPos));
    250       dialog.setTrackValid(true);
    251 
    252       //Prepare Settings
    253       dialog.setSettings
    254       (currentTrack.gpsSyncTime, currentTrack.stopwatchStart,
    255        currentTrack.timeWindow, currentTrack.threshold);
    256 
    257       //Prepare Stoplist
    258       dialog.setStoplistTableModel
    259           (tracksListModel.elementAt(selectedPos).stoplistTM);
    260     }
    261     else
    262     {
    263       currentTrack = null;
    264       dialog.setTrackValid(false);
    265     }
    266   }
    267 
    268   public Node createNode(LatLon latLon, String name)
    269   {
    270     return createNode(latLon, dialog.getStoptype(), name);
    271   }
    272 
    273   public static Node createNode(LatLon latLon, String type, String name)
    274   {
    275     Node node = new Node(latLon);
    276     setTagsWrtType(node, type);
    277     node.put("name", name);
    278     if (Main.main.getCurrentDataSet() == null)
    279     {
    280       JOptionPane.showMessageDialog(null, tr("There exists no dataset."
    281       + " Try to download data from the server or open an OSM file."),
    282      tr("No data found"), JOptionPane.ERROR_MESSAGE);
    283 
    284       return null;
    285     }
    286     Main.main.getCurrentDataSet().addPrimitive(node);
    287     return node;
    288   }
    289 
    290   /* sets the tags of the node according to the type */
    291   public static void setTagsWrtType(Node node, String type)
    292   {
    293     node.remove("highway");
    294     node.remove("railway");
    295     if ("bus".equals(type))
    296       node.put("highway", "bus_stop");
    297     else if ("tram".equals(type))
    298       node.put("railway", "tram_stop");
    299     else if ("light_rail".equals(type))
    300       node.put("railway", "station");
    301     else if ("subway".equals(type))
    302       node.put("railway", "station");
    303     else if ("rail".equals(type))
    304       node.put("railway", "station");
    305   }
    306 
    307   /* returns a collection of all selected lines or
    308      a collection of all lines otherwise */
    309   public static Vector< Integer > getConsideredLines(JTable table)
    310   {
    311     int[] selectedLines = table.getSelectedRows();
    312     Vector< Integer > consideredLines = new Vector< Integer >();
    313     if (selectedLines.length > 0)
    314     {
    315       for (int i = 0; i < selectedLines.length; ++i)
    316         consideredLines.add(selectedLines[i]);
    317     }
    318     else
    319     {
    320       for (int i = 0; i < table.getRowCount(); ++i)
    321         consideredLines.add(new Integer(i));
    322     }
    323     return consideredLines;
    324   }
    325 
    326   /* marks the table items whose nodes are marked on the map */
    327   public static void findNodesInTable(JTable table, Vector< Node > nodes)
    328   {
    329     if (Main.main.getCurrentDataSet() == null)
    330       return;
    331 
    332     table.clearSelection();
    333 
    334     for (int i = 0; i < table.getRowCount(); ++i)
    335     {
    336       if ((nodes.elementAt(i) != null) &&
    337       (Main.main.getCurrentDataSet().isSelected(nodes.elementAt(i))))
    338         table.addRowSelectionInterval(i, i);
    339     }
    340   }
    341 
    342   /* shows the nodes that correspond to the marked lines in the table.
    343      If no lines are marked in the table, show all nodes from the vector */
    344   public static void showNodesFromTable(JTable table, Vector< Node > nodes)
    345   {
    346     BoundingXYVisitor box = new BoundingXYVisitor();
    347     Vector< Integer > consideredLines = getConsideredLines(table);
    348     for (int i = 0; i < consideredLines.size(); ++i)
    349     {
    350       int j = consideredLines.elementAt(i);
    351       if (nodes.elementAt(j) != null)
    352         nodes.elementAt(j).accept(box);
    353     }
    354     if (box.getBounds() == null)
    355       return;
    356     box.enlargeBoundingBox();
    357     Main.map.mapView.zoomTo(box);
    358   }
    359 
    360   /* marks the nodes that correspond to the marked lines in the table.
    361   If no lines are marked in the table, mark all nodes from the vector */
    362   public static void markNodesFromTable(JTable table, Vector< Node > nodes)
    363   {
    364     OsmPrimitive[] osmp = { null };
    365     Main.main.getCurrentDataSet().setSelected(osmp);
    366     Vector< Integer > consideredLines = getConsideredLines(table);
    367     for (int i = 0; i < consideredLines.size(); ++i)
    368     {
    369       int j = consideredLines.elementAt(i);
    370       if (nodes.elementAt(j) != null)
    371         Main.main.getCurrentDataSet().addSelected(nodes.elementAt(j));
    372     }
    373   }
    374 
    375   public static String timeOf(double t)
    376   {
    377     t -= Math.floor(t/24/60/60)*24*60*60;
    378 
    379     int hour = (int)Math.floor(t/60/60);
    380     t -=  Math.floor(t/60/60)*60*60;
    381     int minute = (int)Math.floor(t/60);
    382     t -=  Math.floor(t/60)*60;
    383     double second = t;
    384 
    385     Format format = new DecimalFormat("00");
    386     Format formatS = new DecimalFormat("00.###");
    387     return (format.format(hour) + ":" + format.format(minute) + ":"
    388     + formatS.format(second));
    389   }
    390 
    391   public Action getFocusWaypointNameAction()
    392   {
    393     return new FocusWaypointNameAction();
    394   }
    395 
    396   public Action getFocusWaypointShelterAction(String shelter)
    397   {
    398     return new FocusWaypointShelterAction(shelter);
    399   }
    400 
    401   public Action getFocusWaypointDeleteAction()
    402   {
    403     return new AbstractAction()
    404     {
    405       @Override
    406     public void actionPerformed(ActionEvent e)
    407       {
    408         JTable table = dialog.getWaypointsTable();
    409         int row = table.getEditingRow();
    410         if (row < 0)
    411           return;
     38public class StopImporterAction extends JosmAction {
     39    private static StopImporterDialog dialog = null;
     40
     41    private static DefaultListModel<TrackReference> tracksListModel = null;
     42
     43    private static GpxData data = null;
     44
     45    private static TrackReference currentTrack = null;
     46
     47    private static WaypointTableModel waypointTM = null;
     48
     49    public boolean inEvent = false;
     50
     51    /**
     52     * Constructs a new {@code StopImporterAction}.
     53     */
     54    public StopImporterAction() {
     55        super(tr("Create Stops from GPX ..."), null, tr("Create Stops from a GPX file"), null,
     56                false);
     57        putValue("toolbar", "publictransport/stopimporter");
     58        Main.toolbar.register(this);
     59    }
     60
     61    public WaypointTableModel getWaypointTableModel() {
     62        return waypointTM;
     63    }
     64
     65    public StopImporterDialog getDialog() {
     66        return dialog;
     67    }
     68
     69    public DefaultListModel<TrackReference> getTracksListModel() {
     70        if (tracksListModel == null)
     71            tracksListModel = new DefaultListModel<>();
     72        return tracksListModel;
     73    }
     74
     75    public TrackReference getCurrentTrack() {
     76        return currentTrack;
     77    }
     78
     79    @Override
     80    public void actionPerformed(ActionEvent event) {
     81        if (dialog == null)
     82            dialog = new StopImporterDialog(this);
     83
     84        dialog.setVisible(true);
     85
     86        if (tr("Create Stops from GPX ...").equals(event.getActionCommand())) {
     87            String curDir = Main.pref.get("lastDirectory");
     88            if (curDir.equals("")) {
     89                curDir = ".";
     90            }
     91            JFileChooser fc = new JFileChooser(new File(curDir));
     92            fc.setDialogTitle(tr("Select GPX file"));
     93            fc.setMultiSelectionEnabled(false);
     94
     95            int answer = fc.showOpenDialog(Main.parent);
     96            if (answer != JFileChooser.APPROVE_OPTION)
     97                return;
     98
     99            if (!fc.getCurrentDirectory().getAbsolutePath().equals(curDir))
     100                Main.pref.put("lastDirectory", fc.getCurrentDirectory().getAbsolutePath());
     101
     102            importData(fc.getSelectedFile());
     103
     104            refreshData();
     105        } else if ("stopImporter.settingsGPSTimeStart".equals(event.getActionCommand())) {
     106            if ((!inEvent) && (dialog.gpsTimeStartValid()) && (currentTrack != null))
     107                Main.main.undoRedo.add(new TrackStoplistRelocateCommand(this));
     108        } else if ("stopImporter.settingsStopwatchStart".equals(event.getActionCommand())) {
     109            if ((!inEvent) && (dialog.stopwatchStartValid()) && (currentTrack != null))
     110                Main.main.undoRedo.add(new TrackStoplistRelocateCommand(this));
     111        } else if ("stopImporter.settingsTimeWindow".equals(event.getActionCommand())) {
     112            if (currentTrack != null)
     113                currentTrack.timeWindow = dialog.getTimeWindow();
     114        } else if ("stopImporter.settingsThreshold".equals(event.getActionCommand())) {
     115            if (currentTrack != null)
     116                currentTrack.threshold = dialog.getThreshold();
     117        } else if ("stopImporter.settingsSuggestStops".equals(event.getActionCommand()))
     118            Main.main.undoRedo.add(new TrackSuggestStopsCommand(this));
     119        else if ("stopImporter.stoplistFind".equals(event.getActionCommand()))
     120            findNodesInTable(dialog.getStoplistTable(), currentTrack.stoplistTM.getNodes());
     121        else if ("stopImporter.stoplistShow".equals(event.getActionCommand()))
     122            showNodesFromTable(dialog.getStoplistTable(), currentTrack.stoplistTM.getNodes());
     123        else if ("stopImporter.stoplistMark".equals(event.getActionCommand()))
     124            markNodesFromTable(dialog.getStoplistTable(), currentTrack.stoplistTM.getNodes());
     125        else if ("stopImporter.stoplistDetach".equals(event.getActionCommand())) {
     126            Main.main.undoRedo.add(new TrackStoplistDetachCommand(this));
     127            dialog.getStoplistTable().clearSelection();
     128        } else if ("stopImporter.stoplistAdd".equals(event.getActionCommand()))
     129            Main.main.undoRedo.add(new TrackStoplistAddCommand(this));
     130        else if ("stopImporter.stoplistDelete".equals(event.getActionCommand()))
     131            Main.main.undoRedo.add(new TrackStoplistDeleteCommand(this));
     132        else if ("stopImporter.stoplistSort".equals(event.getActionCommand()))
     133            Main.main.undoRedo.add(new TrackStoplistSortCommand(this));
     134        else if ("stopImporter.waypointsFind".equals(event.getActionCommand()))
     135            findNodesInTable(dialog.getWaypointsTable(), waypointTM.nodes);
     136        else if ("stopImporter.waypointsShow".equals(event.getActionCommand()))
     137            showNodesFromTable(dialog.getWaypointsTable(), waypointTM.nodes);
     138        else if ("stopImporter.waypointsMark".equals(event.getActionCommand()))
     139            markNodesFromTable(dialog.getWaypointsTable(), waypointTM.nodes);
     140        else if ("stopImporter.waypointsDetach".equals(event.getActionCommand())) {
     141            Main.main.undoRedo.add(new WaypointsDetachCommand(this));
     142            dialog.getWaypointsTable().clearSelection();
     143        } else if ("stopImporter.waypointsAdd".equals(event.getActionCommand()))
     144            Main.main.undoRedo.add(new WaypointsEnableCommand(this));
     145        else if ("stopImporter.waypointsDelete".equals(event.getActionCommand()))
     146            Main.main.undoRedo.add(new WaypointsDisableCommand(this));
     147        else if ("stopImporter.settingsStoptype".equals(event.getActionCommand()))
     148            Main.main.undoRedo.add(new SettingsStoptypeCommand(this));
     149    }
     150
     151    private void importData(final File file) {
     152        try {
     153            InputStream is;
     154            if (file.getName().endsWith(".gpx.gz"))
     155                is = new GZIPInputStream(new FileInputStream(file));
     156            else
     157                is = new FileInputStream(file);
     158            // Workaround for SAX BOM bug
     159            // https://bugs.openjdk.java.net/browse/JDK-6206835
     160            if (!((is.read() == 0xef) && (is.read() == 0xbb) && (is.read() == 0xbf))) {
     161                is.close();
     162                if (file.getName().endsWith(".gpx.gz"))
     163                    is = new GZIPInputStream(new FileInputStream(file));
     164                else
     165                    is = new FileInputStream(file);
     166            }
     167            final GpxReader r = new GpxReader(is);
     168            final boolean parsedProperly = r.parse(true);
     169            data = r.getGpxData();
     170
     171            if (!parsedProperly) {
     172                JOptionPane.showMessageDialog(null,
     173                        tr("Error occurred while parsing gpx file {0}. Only a part of the file will be available.",
     174                                file.getName()));
     175            }
     176        } catch (FileNotFoundException e) {
     177            e.printStackTrace();
     178            JOptionPane.showMessageDialog(null, tr("File \"{0}\" does not exist", file.getName()));
     179        } catch (SAXException e) {
     180            e.printStackTrace();
     181            JOptionPane.showMessageDialog(null, tr("Parsing file \"{0}\" failed", file.getName()));
     182        } catch (IOException e) {
     183            e.printStackTrace();
     184            JOptionPane.showMessageDialog(null, tr("IOException \"{0}\" occurred", e.toString()));
     185        }
     186    }
     187
     188    private void refreshData() {
     189        tracksListModel.clear();
     190        if (data != null) {
     191            Vector<TrackReference> trackRefs = new Vector<>();
     192            Iterator<GpxTrack> trackIter = data.tracks.iterator();
     193            while (trackIter.hasNext()) {
     194                GpxTrack track = trackIter.next();
     195                trackRefs.add(new TrackReference(track, this));
     196            }
     197
     198            Collections.sort(trackRefs);
     199
     200            Iterator<TrackReference> iter = trackRefs.iterator();
     201            while (iter.hasNext())
     202                tracksListModel.addElement(iter.next());
     203
     204            waypointTM = new WaypointTableModel(this);
     205            Iterator<WayPoint> waypointIter = data.waypoints.iterator();
     206            while (waypointIter.hasNext()) {
     207                WayPoint waypoint = waypointIter.next();
     208                waypointTM.addRow(waypoint);
     209            }
     210            dialog.setWaypointsTableModel(waypointTM);
     211        } else {
     212            JOptionPane.showMessageDialog(null,
     213                    tr("The GPX file contained no tracks or waypoints."), tr("No data found"),
     214                    JOptionPane.ERROR_MESSAGE);
     215        }
     216    }
     217
     218    public void tracksSelectionChanged(int selectedPos) {
     219        if (selectedPos >= 0) {
     220            currentTrack = (tracksListModel.elementAt(selectedPos));
     221            dialog.setTrackValid(true);
     222
     223            // Prepare Settings
     224            dialog.setSettings(currentTrack.gpsSyncTime, currentTrack.stopwatchStart,
     225                    currentTrack.timeWindow, currentTrack.threshold);
     226
     227            // Prepare Stoplist
     228            dialog.setStoplistTableModel(tracksListModel.elementAt(selectedPos).stoplistTM);
     229        } else {
     230            currentTrack = null;
     231            dialog.setTrackValid(false);
     232        }
     233    }
     234
     235    public Node createNode(LatLon latLon, String name) {
     236        return createNode(latLon, dialog.getStoptype(), name);
     237    }
     238
     239    public static Node createNode(LatLon latLon, String type, String name) {
     240        Node node = new Node(latLon);
     241        setTagsWrtType(node, type);
     242        node.put("name", name);
     243        DataSet ds = Main.getLayerManager().getEditDataSet();
     244        if (ds == null) {
     245            JOptionPane.showMessageDialog(null,
     246                    tr("There exists no dataset."
     247                            + " Try to download data from the server or open an OSM file."),
     248                    tr("No data found"), JOptionPane.ERROR_MESSAGE);
     249
     250            return null;
     251        }
     252        ds.addPrimitive(node);
     253        return node;
     254    }
     255
     256    /** sets the tags of the node according to the type */
     257    public static void setTagsWrtType(Node node, String type) {
     258        node.remove("highway");
     259        node.remove("railway");
     260        if ("bus".equals(type))
     261            node.put("highway", "bus_stop");
     262        else if ("tram".equals(type))
     263            node.put("railway", "tram_stop");
     264        else if ("light_rail".equals(type))
     265            node.put("railway", "station");
     266        else if ("subway".equals(type))
     267            node.put("railway", "station");
     268        else if ("rail".equals(type))
     269            node.put("railway", "station");
     270    }
     271
     272    /**
     273     * returns a collection of all selected lines or a collection of all lines otherwise
     274     */
     275    public static Vector<Integer> getConsideredLines(JTable table) {
     276        int[] selectedLines = table.getSelectedRows();
     277        Vector<Integer> consideredLines = new Vector<>();
     278        if (selectedLines.length > 0) {
     279            for (int i = 0; i < selectedLines.length; ++i)
     280                consideredLines.add(selectedLines[i]);
     281        } else {
     282            for (int i = 0; i < table.getRowCount(); ++i)
     283                consideredLines.add(new Integer(i));
     284        }
     285        return consideredLines;
     286    }
     287
     288    /** marks the table items whose nodes are marked on the map */
     289    public static void findNodesInTable(JTable table, Vector<Node> nodes) {
     290        DataSet ds = Main.getLayerManager().getEditDataSet();
     291        if (ds == null)
     292            return;
     293
    412294        table.clearSelection();
    413         table.addRowSelectionInterval(row, row);
    414         Main.main.undoRedo.add
    415         (new WaypointsDisableCommand(StopImporterAction.this));
    416       }
    417     };
    418   }
    419 
    420   public Action getFocusTrackStoplistNameAction()
    421   {
    422     return new FocusTrackStoplistNameAction();
    423   }
    424 
    425   public Action getFocusTrackStoplistShelterAction(String shelter)
    426   {
    427     return new FocusTrackStoplistShelterAction(shelter);
    428   }
    429 
    430   public Action getFocusStoplistDeleteAction()
    431   {
    432     return new AbstractAction()
    433     {
    434       @Override
    435     public void actionPerformed(ActionEvent e)
    436       {
    437         JTable table = dialog.getStoplistTable();
    438         int row = table.getEditingRow();
    439         if (row < 0)
    440           return;
    441         table.clearSelection();
    442         table.addRowSelectionInterval(row, row);
    443         Main.main.undoRedo.add
    444             (new TrackStoplistDeleteCommand(StopImporterAction.this));
    445       }
    446     };
    447   }
    448 
    449   private class FocusWaypointNameAction extends AbstractAction
    450   {
    451     @Override
    452     public void actionPerformed(ActionEvent e)
    453     {
    454       JTable table = dialog.getWaypointsTable();
    455       showNodesFromTable(table, waypointTM.nodes);
    456       markNodesFromTable(table, waypointTM.nodes);
    457       int row = table.getEditingRow();
    458       if (row < 0)
    459         row = 0;
    460       waypointTM.inEvent = true;
    461       if (table.getCellEditor() != null)
    462       {
    463         if (!table.getCellEditor().stopCellEditing())
    464           table.getCellEditor().cancelCellEditing();
    465       }
    466       table.editCellAt(row, 1);
    467       table.getCellEditor().getTableCellEditorComponent
    468       (table, "", true, row, 1);
    469       waypointTM.inEvent = false;
    470     }
    471   };
    472 
    473   private class FocusWaypointShelterAction extends AbstractAction
    474   {
    475     private String defaultShelter = null;
    476 
    477     public FocusWaypointShelterAction(String defaultShelter)
    478     {
    479       this.defaultShelter = defaultShelter;
    480     }
    481 
    482     @Override
    483     public void actionPerformed(ActionEvent e)
    484     {
    485       JTable table = dialog.getWaypointsTable();
    486       showNodesFromTable(table, waypointTM.nodes);
    487       markNodesFromTable(table, waypointTM.nodes);
    488       int row = table.getEditingRow();
    489       if (row < 0)
    490         row = 0;
    491       waypointTM.inEvent = true;
    492       if (table.getCellEditor() != null)
    493       {
    494         if (!table.getCellEditor().stopCellEditing())
    495           table.getCellEditor().cancelCellEditing();
    496       }
    497       table.editCellAt(row, 2);
    498       waypointTM.inEvent = false;
    499       table.getCellEditor().getTableCellEditorComponent
    500           (table, defaultShelter, true, row, 2);
    501     }
    502   };
    503 
    504   private class FocusTrackStoplistNameAction extends AbstractAction
    505   {
    506     @Override
    507     public void actionPerformed(ActionEvent e)
    508     {
    509       JTable table = dialog.getStoplistTable();
    510       showNodesFromTable(table, currentTrack.stoplistTM.getNodes());
    511       markNodesFromTable(table, currentTrack.stoplistTM.getNodes());
    512       int row = table.getEditingRow();
    513       if (row < 0)
    514         row = 0;
    515       currentTrack.inEvent = true;
    516       if (table.getCellEditor() != null)
    517       {
    518         if (!table.getCellEditor().stopCellEditing())
    519           table.getCellEditor().cancelCellEditing();
    520       }
    521       table.editCellAt(row, 1);
    522       table.getCellEditor().getTableCellEditorComponent
    523           (table, "", true, row, 1);
    524       currentTrack.inEvent = false;
    525     }
    526   };
    527 
    528   private class FocusTrackStoplistShelterAction extends AbstractAction
    529   {
    530     private String defaultShelter = null;
    531 
    532     public FocusTrackStoplistShelterAction(String defaultShelter)
    533     {
    534       this.defaultShelter = defaultShelter;
    535     }
    536 
    537     @Override
    538     public void actionPerformed(ActionEvent e)
    539     {
    540       JTable table = dialog.getStoplistTable();
    541       showNodesFromTable(table, currentTrack.stoplistTM.getNodes());
    542       markNodesFromTable(table, currentTrack.stoplistTM.getNodes());
    543       int row = table.getEditingRow();
    544       if (row < 0)
    545         row = 0;
    546       currentTrack.inEvent = true;
    547       if (table.getCellEditor() != null)
    548       {
    549         if (!table.getCellEditor().stopCellEditing())
    550           table.getCellEditor().cancelCellEditing();
    551       }
    552       table.editCellAt(row, 2);
    553       currentTrack.inEvent = false;
    554       table.getCellEditor().getTableCellEditorComponent
    555           (table, defaultShelter, true, row, 2);
    556     }
    557   };
     295
     296        for (int i = 0; i < table.getRowCount(); ++i) {
     297            if ((nodes.elementAt(i) != null) && (ds.isSelected(nodes.elementAt(i))))
     298                table.addRowSelectionInterval(i, i);
     299        }
     300    }
     301
     302    /**
     303     * shows the nodes that correspond to the marked lines in the table. If no lines are marked in the table, show all nodes from the vector
     304     */
     305    public static void showNodesFromTable(JTable table, Vector<Node> nodes) {
     306        BoundingXYVisitor box = new BoundingXYVisitor();
     307        Vector<Integer> consideredLines = getConsideredLines(table);
     308        for (int i = 0; i < consideredLines.size(); ++i) {
     309            int j = consideredLines.elementAt(i);
     310            if (nodes.elementAt(j) != null)
     311                nodes.elementAt(j).accept(box);
     312        }
     313        if (box.getBounds() == null)
     314            return;
     315        box.enlargeBoundingBox();
     316        Main.map.mapView.zoomTo(box);
     317    }
     318
     319    /**
     320     * marks the nodes that correspond to the marked lines in the table. If no lines are marked in the table, mark all nodes from the vector
     321     */
     322    public static void markNodesFromTable(JTable table, Vector<Node> nodes) {
     323        OsmPrimitive[] osmp = { null };
     324        DataSet ds = Main.getLayerManager().getEditDataSet();
     325        ds.setSelected(osmp);
     326        Vector<Integer> consideredLines = getConsideredLines(table);
     327        for (int i = 0; i < consideredLines.size(); ++i) {
     328            int j = consideredLines.elementAt(i);
     329            if (nodes.elementAt(j) != null)
     330                ds.addSelected(nodes.elementAt(j));
     331        }
     332    }
     333
     334    public static String timeOf(double t) {
     335        t -= Math.floor(t / 24 / 60 / 60) * 24 * 60 * 60;
     336
     337        int hour = (int) Math.floor(t / 60 / 60);
     338        t -= Math.floor(t / 60 / 60) * 60 * 60;
     339        int minute = (int) Math.floor(t / 60);
     340        t -= Math.floor(t / 60) * 60;
     341        double second = t;
     342
     343        Format format = new DecimalFormat("00");
     344        Format formatS = new DecimalFormat("00.###");
     345        return (format.format(hour) + ":" + format.format(minute) + ":" + formatS.format(second));
     346    }
     347
     348    public Action getFocusWaypointNameAction() {
     349        return new FocusWaypointNameAction();
     350    }
     351
     352    public Action getFocusWaypointShelterAction(String shelter) {
     353        return new FocusWaypointShelterAction(shelter);
     354    }
     355
     356    public Action getFocusWaypointDeleteAction() {
     357        return new AbstractAction() {
     358            @Override
     359            public void actionPerformed(ActionEvent e) {
     360                JTable table = dialog.getWaypointsTable();
     361                int row = table.getEditingRow();
     362                if (row < 0)
     363                    return;
     364                table.clearSelection();
     365                table.addRowSelectionInterval(row, row);
     366                Main.main.undoRedo.add(new WaypointsDisableCommand(StopImporterAction.this));
     367            }
     368        };
     369    }
     370
     371    public Action getFocusTrackStoplistNameAction() {
     372        return new FocusTrackStoplistNameAction();
     373    }
     374
     375    public Action getFocusTrackStoplistShelterAction(String shelter) {
     376        return new FocusTrackStoplistShelterAction(shelter);
     377    }
     378
     379    public Action getFocusStoplistDeleteAction() {
     380        return new AbstractAction() {
     381            @Override
     382            public void actionPerformed(ActionEvent e) {
     383                JTable table = dialog.getStoplistTable();
     384                int row = table.getEditingRow();
     385                if (row < 0)
     386                    return;
     387                table.clearSelection();
     388                table.addRowSelectionInterval(row, row);
     389                Main.main.undoRedo.add(new TrackStoplistDeleteCommand(StopImporterAction.this));
     390            }
     391        };
     392    }
     393
     394    private class FocusWaypointNameAction extends AbstractAction {
     395        @Override
     396        public void actionPerformed(ActionEvent e) {
     397            JTable table = dialog.getWaypointsTable();
     398            showNodesFromTable(table, waypointTM.nodes);
     399            markNodesFromTable(table, waypointTM.nodes);
     400            int row = table.getEditingRow();
     401            if (row < 0)
     402                row = 0;
     403            waypointTM.inEvent = true;
     404            if (table.getCellEditor() != null) {
     405                if (!table.getCellEditor().stopCellEditing())
     406                    table.getCellEditor().cancelCellEditing();
     407            }
     408            table.editCellAt(row, 1);
     409            table.getCellEditor().getTableCellEditorComponent(table, "", true, row, 1);
     410            waypointTM.inEvent = false;
     411        }
     412    }
     413
     414    private class FocusWaypointShelterAction extends AbstractAction {
     415        private String defaultShelter = null;
     416
     417        public FocusWaypointShelterAction(String defaultShelter) {
     418            this.defaultShelter = defaultShelter;
     419        }
     420
     421        @Override
     422        public void actionPerformed(ActionEvent e) {
     423            JTable table = dialog.getWaypointsTable();
     424            showNodesFromTable(table, waypointTM.nodes);
     425            markNodesFromTable(table, waypointTM.nodes);
     426            int row = table.getEditingRow();
     427            if (row < 0)
     428                row = 0;
     429            waypointTM.inEvent = true;
     430            if (table.getCellEditor() != null) {
     431                if (!table.getCellEditor().stopCellEditing())
     432                    table.getCellEditor().cancelCellEditing();
     433            }
     434            table.editCellAt(row, 2);
     435            waypointTM.inEvent = false;
     436            table.getCellEditor().getTableCellEditorComponent(table, defaultShelter, true, row, 2);
     437        }
     438    }
     439
     440    private class FocusTrackStoplistNameAction extends AbstractAction {
     441        @Override
     442        public void actionPerformed(ActionEvent e) {
     443            JTable table = dialog.getStoplistTable();
     444            showNodesFromTable(table, currentTrack.stoplistTM.getNodes());
     445            markNodesFromTable(table, currentTrack.stoplistTM.getNodes());
     446            int row = table.getEditingRow();
     447            if (row < 0)
     448                row = 0;
     449            currentTrack.inEvent = true;
     450            if (table.getCellEditor() != null) {
     451                if (!table.getCellEditor().stopCellEditing())
     452                    table.getCellEditor().cancelCellEditing();
     453            }
     454            table.editCellAt(row, 1);
     455            table.getCellEditor().getTableCellEditorComponent(table, "", true, row, 1);
     456            currentTrack.inEvent = false;
     457        }
     458    }
     459
     460    private class FocusTrackStoplistShelterAction extends AbstractAction {
     461        private String defaultShelter = null;
     462
     463        public FocusTrackStoplistShelterAction(String defaultShelter) {
     464            this.defaultShelter = defaultShelter;
     465        }
     466
     467        @Override
     468        public void actionPerformed(ActionEvent e) {
     469            JTable table = dialog.getStoplistTable();
     470            showNodesFromTable(table, currentTrack.stoplistTM.getNodes());
     471            markNodesFromTable(table, currentTrack.stoplistTM.getNodes());
     472            int row = table.getEditingRow();
     473            if (row < 0)
     474                row = 0;
     475            currentTrack.inEvent = true;
     476            if (table.getCellEditor() != null) {
     477                if (!table.getCellEditor().stopCellEditing())
     478                    table.getCellEditor().cancelCellEditing();
     479            }
     480            table.editCellAt(row, 2);
     481            currentTrack.inEvent = false;
     482            table.getCellEditor().getTableCellEditorComponent(table, defaultShelter, true, row, 2);
     483        }
     484    }
    558485}
  • applications/editors/josm/plugins/public_transport/src/public_transport/StopImporterDialog.java

    r31995 r32357  
    2222import javax.swing.event.ListSelectionListener;
    2323
    24 public class StopImporterDialog extends AbstractImporterDialog<StopImporterAction>
    25 {
    26   private JList<TrackReference> tracksList = null;
    27   private JTable stoplistTable = null;
    28   private JTable waypointTable = null;
    29 
    30   public StopImporterDialog(StopImporterAction controller)
    31   {
    32       super(controller, tr("Create Stops from GPX"), "stopImporter");
    33   }
    34  
    35   @Override
    36   protected void initDialog(StopImporterAction controller) {
    37     JPanel tabTracks = new JPanel();
    38     tabbedPane.addTab(tr("Tracks"), tabTracks);
    39     JPanel tabSettings = new JPanel();
    40     tabbedPane.addTab(tr("Settings"), tabSettings);
    41     JPanel tabStops = new JPanel();
    42     tabbedPane.addTab(tr("Stops"), tabStops);
    43     JPanel tabWaypoints = new JPanel();
    44     tabbedPane.addTab(tr("Waypoints"), tabWaypoints);
    45     tabbedPane.setEnabledAt(0, true);
    46     tabbedPane.setEnabledAt(1, true);
    47     tabbedPane.setEnabledAt(2, false);
    48     tabbedPane.setEnabledAt(3, true);
    49 
    50     //Tracks Tab
    51     JPanel contentPane = tabTracks;
    52     GridBagLayout gridbag = new GridBagLayout();
    53     GridBagConstraints layoutCons = new GridBagConstraints();
    54     contentPane.setLayout(gridbag);
    55 
    56     JLabel label = new JLabel(tr("Tracks in this GPX file:"));
    57 
    58     layoutCons.gridx = 0;
    59     layoutCons.gridy = 0;
    60     layoutCons.gridwidth = 3;
    61     layoutCons.weightx = 0.0;
    62     layoutCons.weighty = 0.0;
    63     layoutCons.fill = GridBagConstraints.BOTH;
    64     gridbag.setConstraints(label, layoutCons);
    65     contentPane.add(label);
    66 
    67     DefaultListModel<TrackReference> tracksListModel = controller.getTracksListModel();
    68     tracksList = new JList<>(tracksListModel);
    69     JScrollPane rpListSP = new JScrollPane(tracksList);
    70     String[] data = {"1", "2", "3", "4", "5", "6"};
    71     tracksListModel.copyInto(data);
    72     tracksList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    73     tracksList.addListSelectionListener(new TracksLSL(controller));
    74 
    75     layoutCons.gridx = 0;
    76     layoutCons.gridy = 1;
    77     layoutCons.gridwidth = 3;
    78     layoutCons.weightx = 1.0;
    79     layoutCons.weighty = 1.0;
    80     layoutCons.fill = GridBagConstraints.BOTH;
    81     gridbag.setConstraints(rpListSP, layoutCons);
    82     contentPane.add(rpListSP);
    83 
    84     //Settings Tab
    85     contentPane = tabSettings;
    86     gridbag = new GridBagLayout();
    87     layoutCons = new GridBagConstraints();
    88     contentPane.setLayout(gridbag);
    89 
    90     label = new JLabel(tr("Type of stops to add"));
    91 
    92     layoutCons.gridx = 0;
    93     layoutCons.gridy = 0;
    94     layoutCons.gridwidth = 2;
    95     layoutCons.weightx = 0.0;
    96     layoutCons.weighty = 0.0;
    97     layoutCons.fill = GridBagConstraints.BOTH;
    98     gridbag.setConstraints(label, layoutCons);
    99     contentPane.add(label);
    100 
    101     layoutCons.gridx = 0;
    102     layoutCons.gridy = 1;
    103     layoutCons.gridwidth = 1;
    104     layoutCons.weightx = 0.0;
    105     layoutCons.weighty = 0.0;
    106     layoutCons.fill = GridBagConstraints.BOTH;
    107     gridbag.setConstraints(cbStoptype, layoutCons);
    108     contentPane.add(cbStoptype);
    109 
    110     label = new JLabel(tr("Time on your GPS device"));
    111 
    112     layoutCons.gridx = 0;
    113     layoutCons.gridy = 2;
    114     layoutCons.gridwidth = 2;
    115     layoutCons.weightx = 0.0;
    116     layoutCons.weighty = 0.0;
    117     layoutCons.fill = GridBagConstraints.BOTH;
    118     gridbag.setConstraints(label, layoutCons);
    119     contentPane.add(label);
    120 
    121     layoutCons.gridx = 0;
    122     layoutCons.gridy = 3;
    123     layoutCons.gridwidth = 1;
    124     layoutCons.weightx = 0.0;
    125     layoutCons.weighty = 0.0;
    126     layoutCons.fill = GridBagConstraints.BOTH;
    127     gridbag.setConstraints(tfGPSTimeStart, layoutCons);
    128     contentPane.add(tfGPSTimeStart);
    129 
    130     label = new JLabel(tr("HH:MM:SS.sss"));
    131 
    132     layoutCons.gridx = 1;
    133     layoutCons.gridy = 3;
    134     layoutCons.gridwidth = 1;
    135     layoutCons.weightx = 0.0;
    136     layoutCons.weighty = 0.0;
    137     layoutCons.fill = GridBagConstraints.BOTH;
    138     gridbag.setConstraints(label, layoutCons);
    139     contentPane.add(label);
    140 
    141     label = new JLabel(tr("Time on your stopwatch"));
    142 
    143     layoutCons.gridx = 0;
    144     layoutCons.gridy = 4;
    145     layoutCons.gridwidth = 2;
    146     layoutCons.weightx = 0.0;
    147     layoutCons.weighty = 0.0;
    148     layoutCons.fill = GridBagConstraints.BOTH;
    149     gridbag.setConstraints(label, layoutCons);
    150     contentPane.add(label);
    151 
    152     layoutCons.gridx = 0;
    153     layoutCons.gridy = 5;
    154     layoutCons.gridwidth = 1;
    155     layoutCons.weightx = 0.0;
    156     layoutCons.weighty = 0.0;
    157     layoutCons.fill = GridBagConstraints.BOTH;
    158     gridbag.setConstraints(tfStopwatchStart, layoutCons);
    159     contentPane.add(tfStopwatchStart);
    160 
    161     label = new JLabel(tr("HH:MM:SS.sss"));
    162 
    163     layoutCons.gridx = 1;
    164     layoutCons.gridy = 5;
    165     layoutCons.gridwidth = 1;
    166     layoutCons.weightx = 0.0;
    167     layoutCons.weighty = 0.0;
    168     layoutCons.fill = GridBagConstraints.BOTH;
    169     gridbag.setConstraints(label, layoutCons);
    170     contentPane.add(label);
    171 
    172     label = new JLabel(tr("Time window"));
    173 
    174     layoutCons.gridx = 0;
    175     layoutCons.gridy = 6;
    176     layoutCons.gridwidth = 2;
    177     layoutCons.weightx = 0.0;
    178     layoutCons.weighty = 0.0;
    179     layoutCons.fill = GridBagConstraints.BOTH;
    180     gridbag.setConstraints(label, layoutCons);
    181     contentPane.add(label);
    182 
    183     layoutCons.gridx = 0;
    184     layoutCons.gridy = 7;
    185     layoutCons.gridwidth = 1;
    186     layoutCons.weightx = 0.0;
    187     layoutCons.weighty = 0.0;
    188     layoutCons.fill = GridBagConstraints.BOTH;
    189     gridbag.setConstraints(tfTimeWindow, layoutCons);
    190     contentPane.add(tfTimeWindow);
    191 
    192     label = new JLabel(tr("seconds"));
    193 
    194     layoutCons.gridx = 1;
    195     layoutCons.gridy = 7;
    196     layoutCons.gridwidth = 1;
    197     layoutCons.weightx = 0.0;
    198     layoutCons.weighty = 0.0;
    199     layoutCons.fill = GridBagConstraints.BOTH;
    200     gridbag.setConstraints(label, layoutCons);
    201     contentPane.add(label);
    202 
    203     label = new JLabel(tr("Move Threshold"));
    204 
    205     layoutCons.gridx = 0;
    206     layoutCons.gridy = 8;
    207     layoutCons.gridwidth = 2;
    208     layoutCons.weightx = 0.0;
    209     layoutCons.weighty = 0.0;
    210     layoutCons.fill = GridBagConstraints.BOTH;
    211     gridbag.setConstraints(label, layoutCons);
    212     contentPane.add(label);
    213 
    214     layoutCons.gridx = 0;
    215     layoutCons.gridy = 9;
    216     layoutCons.gridwidth = 1;
    217     layoutCons.weightx = 0.0;
    218     layoutCons.weighty = 0.0;
    219     layoutCons.fill = GridBagConstraints.BOTH;
    220     gridbag.setConstraints(tfThreshold, layoutCons);
    221     contentPane.add(tfThreshold);
    222 
    223     label = new JLabel(tr("meters"));
    224 
    225     layoutCons.gridx = 1;
    226     layoutCons.gridy = 9;
    227     layoutCons.gridwidth = 1;
    228     layoutCons.weightx = 0.0;
    229     layoutCons.weighty = 0.0;
    230     layoutCons.fill = GridBagConstraints.BOTH;
    231     gridbag.setConstraints(label, layoutCons);
    232     contentPane.add(label);
    233 
    234     JButton bSuggestStops = new JButton(tr("Suggest Stops"));
    235     bSuggestStops.setActionCommand("stopImporter.settingsSuggestStops");
    236     bSuggestStops.addActionListener(controller);
    237 
    238     layoutCons.gridx = 0;
    239     layoutCons.gridy = 10;
    240     layoutCons.gridwidth = 3;
    241     layoutCons.weightx = 1.0;
    242     layoutCons.weighty = 0.0;
    243     layoutCons.fill = GridBagConstraints.BOTH;
    244     gridbag.setConstraints(bSuggestStops, layoutCons);
    245     contentPane.add(bSuggestStops);
    246 
    247     //Stops Tab
    248     contentPane = tabStops;
    249     gridbag = new GridBagLayout();
    250     layoutCons = new GridBagConstraints();
    251     contentPane.setLayout(gridbag);
    252     contentPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put
    253         (KeyStroke.getKeyStroke("alt N"), "stopImporter.focusName");
    254     contentPane.getActionMap().put
    255     ("stopImporter.focusName", controller.getFocusTrackStoplistNameAction());
    256     contentPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put
    257         (KeyStroke.getKeyStroke("alt S"), "stopImporter.focusShelterYes");
    258     contentPane.getActionMap().put
    259     ("stopImporter.focusShelterYes",
    260      controller.getFocusTrackStoplistShelterAction("yes"));
    261     contentPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put
    262         (KeyStroke.getKeyStroke("alt T"), "stopImporter.focusShelterNo");
    263     contentPane.getActionMap().put
    264     ("stopImporter.focusShelterNo",
    265      controller.getFocusTrackStoplistShelterAction("no"));
    266     contentPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put
    267         (KeyStroke.getKeyStroke("alt U"), "stopImporter.focusShelterImplicit");
    268     contentPane.getActionMap().put
    269     ("stopImporter.focusShelterImplicit",
    270      controller.getFocusTrackStoplistShelterAction("implicit"));
    271     contentPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put
    272         (KeyStroke.getKeyStroke("alt D"), "stopImporter.stoplistDelete");
    273     contentPane.getActionMap().put
    274     ("stopImporter.stoplistDelete",
    275      controller.getFocusStoplistDeleteAction());
    276 
    277     stoplistTable = new JTable();
    278     JScrollPane tableSP = new JScrollPane(stoplistTable);
    279 
    280     layoutCons.gridx = 0;
    281     layoutCons.gridy = 0;
    282     layoutCons.gridwidth = 4;
    283     layoutCons.weightx = 1.0;
    284     layoutCons.weighty = 1.0;
    285     layoutCons.fill = GridBagConstraints.BOTH;
    286     gridbag.setConstraints(tableSP, layoutCons);
    287     contentPane.add(tableSP);
    288 
    289     JButton bFind = new JButton(tr("Find"));
    290     bFind.setActionCommand("stopImporter.stoplistFind");
    291     bFind.addActionListener(controller);
    292 
    293     layoutCons.gridx = 0;
    294     layoutCons.gridy = 1;
    295     layoutCons.gridwidth = 1;
    296     layoutCons.weightx = 1.0;
    297     layoutCons.weighty = 0.0;
    298     layoutCons.fill = GridBagConstraints.BOTH;
    299     gridbag.setConstraints(bFind, layoutCons);
    300     contentPane.add(bFind);
    301 
    302     JButton bShow = new JButton(tr("Show"));
    303     bShow.setActionCommand("stopImporter.stoplistShow");
    304     bShow.addActionListener(controller);
    305 
    306     layoutCons.gridx = 0;
    307     layoutCons.gridy = 2;
    308     layoutCons.gridwidth = 1;
    309     layoutCons.weightx = 1.0;
    310     layoutCons.weighty = 0.0;
    311     layoutCons.fill = GridBagConstraints.BOTH;
    312     gridbag.setConstraints(bShow, layoutCons);
    313     contentPane.add(bShow);
    314 
    315     JButton bMark = new JButton(tr("Mark"));
    316     bMark.setActionCommand("stopImporter.stoplistMark");
    317     bMark.addActionListener(controller);
    318 
    319     layoutCons.gridx = 1;
    320     layoutCons.gridy = 1;
    321     layoutCons.gridheight = 1;
    322     layoutCons.gridwidth = 1;
    323     layoutCons.weightx = 1.0;
    324     layoutCons.weighty = 0.0;
    325     layoutCons.fill = GridBagConstraints.BOTH;
    326     gridbag.setConstraints(bMark, layoutCons);
    327     contentPane.add(bMark);
    328 
    329     JButton bDetach = new JButton(tr("Detach"));
    330     bDetach.setActionCommand("stopImporter.stoplistDetach");
    331     bDetach.addActionListener(controller);
    332 
    333     layoutCons.gridx = 1;
    334     layoutCons.gridy = 2;
    335     layoutCons.gridheight = 1;
    336     layoutCons.gridwidth = 1;
    337     layoutCons.weightx = 1.0;
    338     layoutCons.weighty = 0.0;
    339     layoutCons.fill = GridBagConstraints.BOTH;
    340     gridbag.setConstraints(bDetach, layoutCons);
    341     contentPane.add(bDetach);
    342 
    343     JButton bAdd = new JButton(tr("Add"));
    344     bAdd.setActionCommand("stopImporter.stoplistAdd");
    345     bAdd.addActionListener(controller);
    346 
    347     layoutCons.gridx = 2;
    348     layoutCons.gridy = 1;
    349     layoutCons.gridheight = 1;
    350     layoutCons.gridwidth = 1;
    351     layoutCons.weightx = 1.0;
    352     layoutCons.weighty = 0.0;
    353     layoutCons.fill = GridBagConstraints.BOTH;
    354     gridbag.setConstraints(bAdd, layoutCons);
    355     contentPane.add(bAdd);
    356 
    357     JButton bDelete = new JButton(tr("Delete"));
    358     bDelete.setActionCommand("stopImporter.stoplistDelete");
    359     bDelete.addActionListener(controller);
    360 
    361     layoutCons.gridx = 2;
    362     layoutCons.gridy = 2;
    363     layoutCons.gridwidth = 1;
    364     layoutCons.weightx = 1.0;
    365     layoutCons.weighty = 0.0;
    366     layoutCons.fill = GridBagConstraints.BOTH;
    367     gridbag.setConstraints(bDelete, layoutCons);
    368     contentPane.add(bDelete);
    369 
    370     JButton bSort = new JButton(tr("Sort"));
    371     bSort.setActionCommand("stopImporter.stoplistSort");
    372     bSort.addActionListener(controller);
    373 
    374     layoutCons.gridx = 3;
    375     layoutCons.gridy = 1;
    376     layoutCons.gridheight = 2;
    377     layoutCons.gridwidth = 1;
    378     layoutCons.weightx = 1.0;
    379     layoutCons.weighty = 0.0;
    380     layoutCons.fill = GridBagConstraints.BOTH;
    381     gridbag.setConstraints(bSort, layoutCons);
    382     contentPane.add(bSort);
    383 
    384     //Waypoints Tab
    385     contentPane = tabWaypoints;
    386     gridbag = new GridBagLayout();
    387     layoutCons = new GridBagConstraints();
    388     contentPane.setLayout(gridbag);
    389     contentPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put
    390         (KeyStroke.getKeyStroke("alt N"), "stopImporter.focusName");
    391     contentPane.getActionMap().put
    392     ("stopImporter.focusName", controller.getFocusWaypointNameAction());
    393     contentPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put
    394         (KeyStroke.getKeyStroke("alt S"), "stopImporter.focusShelterYes");
    395     contentPane.getActionMap().put
    396     ("stopImporter.focusShelterYes",
    397      controller.getFocusWaypointShelterAction("yes"));
    398     contentPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put
    399         (KeyStroke.getKeyStroke("alt T"), "stopImporter.focusShelterNo");
    400     contentPane.getActionMap().put
    401     ("stopImporter.focusShelterNo",
    402      controller.getFocusWaypointShelterAction("no"));
    403     contentPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put
    404         (KeyStroke.getKeyStroke("alt U"), "stopImporter.focusShelterImplicit");
    405     contentPane.getActionMap().put
    406     ("stopImporter.focusShelterImplicit",
    407      controller.getFocusWaypointShelterAction("implicit"));
    408     contentPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put
    409         (KeyStroke.getKeyStroke("alt D"), "stopImporter.waypointsDelete");
    410     contentPane.getActionMap().put
    411     ("stopImporter.waypointsDelete",
    412      controller.getFocusWaypointDeleteAction());
    413 
    414     waypointTable = new JTable();
    415     tableSP = new JScrollPane(waypointTable);
    416 
    417     layoutCons.gridx = 0;
    418     layoutCons.gridy = 0;
    419     layoutCons.gridwidth = 3;
    420     layoutCons.weightx = 1.0;
    421     layoutCons.weighty = 1.0;
    422     layoutCons.fill = GridBagConstraints.BOTH;
    423     gridbag.setConstraints(tableSP, layoutCons);
    424     contentPane.add(tableSP);
    425 
    426     bFind = new JButton(tr("Find"));
    427     bFind.setActionCommand("stopImporter.waypointsFind");
    428     bFind.addActionListener(controller);
    429 
    430     layoutCons.gridx = 0;
    431     layoutCons.gridy = 1;
    432     layoutCons.gridwidth = 1;
    433     layoutCons.weightx = 1.0;
    434     layoutCons.weighty = 0.0;
    435     layoutCons.fill = GridBagConstraints.BOTH;
    436     gridbag.setConstraints(bFind, layoutCons);
    437     contentPane.add(bFind);
    438 
    439     bShow = new JButton(tr("Show"));
    440     bShow.setActionCommand("stopImporter.waypointsShow");
    441     bShow.addActionListener(controller);
    442 
    443     layoutCons.gridx = 0;
    444     layoutCons.gridy = 2;
    445     layoutCons.gridwidth = 1;
    446     layoutCons.weightx = 1.0;
    447     layoutCons.weighty = 0.0;
    448     layoutCons.fill = GridBagConstraints.BOTH;
    449     gridbag.setConstraints(bShow, layoutCons);
    450     contentPane.add(bShow);
    451 
    452     bMark = new JButton(tr("Mark"));
    453     bMark.setActionCommand("stopImporter.waypointsMark");
    454     bMark.addActionListener(controller);
    455 
    456     layoutCons.gridx = 1;
    457     layoutCons.gridy = 1;
    458     layoutCons.gridheight = 1;
    459     layoutCons.gridwidth = 1;
    460     layoutCons.weightx = 1.0;
    461     layoutCons.weighty = 0.0;
    462     layoutCons.fill = GridBagConstraints.BOTH;
    463     gridbag.setConstraints(bMark, layoutCons);
    464     contentPane.add(bMark);
    465 
    466     bDetach = new JButton(tr("Detach"));
    467     bDetach.setActionCommand("stopImporter.waypointsDetach");
    468     bDetach.addActionListener(controller);
    469 
    470     layoutCons.gridx = 1;
    471     layoutCons.gridy = 2;
    472     layoutCons.gridheight = 1;
    473     layoutCons.gridwidth = 1;
    474     layoutCons.weightx = 1.0;
    475     layoutCons.weighty = 0.0;
    476     layoutCons.fill = GridBagConstraints.BOTH;
    477     gridbag.setConstraints(bDetach, layoutCons);
    478     contentPane.add(bDetach);
    479 
    480     bAdd = new JButton(tr("Enable"));
    481     bAdd.setActionCommand("stopImporter.waypointsAdd");
    482     bAdd.addActionListener(controller);
    483 
    484     layoutCons.gridx = 2;
    485     layoutCons.gridy = 1;
    486     layoutCons.gridheight = 1;
    487     layoutCons.gridwidth = 1;
    488     layoutCons.weightx = 1.0;
    489     layoutCons.weighty = 0.0;
    490     layoutCons.fill = GridBagConstraints.BOTH;
    491     gridbag.setConstraints(bAdd, layoutCons);
    492     contentPane.add(bAdd);
    493 
    494     bDelete = new JButton(tr("Disable"));
    495     bDelete.setActionCommand("stopImporter.waypointsDelete");
    496     bDelete.addActionListener(controller);
    497 
    498     layoutCons.gridx = 2;
    499     layoutCons.gridy = 2;
    500     layoutCons.gridwidth = 1;
    501     layoutCons.weightx = 1.0;
    502     layoutCons.weighty = 0.0;
    503     layoutCons.fill = GridBagConstraints.BOTH;
    504     gridbag.setConstraints(bDelete, layoutCons);
    505     contentPane.add(bDelete);
    506   }
    507 
    508   public JTable getStoplistTable()
    509   {
    510     return stoplistTable;
    511   }
    512 
    513   public void setStoplistTableModel(TrackStoplistTableModel model)
    514   {
    515     stoplistTable.setModel(model);
    516     JComboBox<TransText> comboBox = new JComboBox<>();
    517     comboBox.addItem(new TransText(null));
    518     comboBox.addItem(new TransText(marktr("yes")));
    519     comboBox.addItem(new TransText(marktr("no")));
    520     comboBox.addItem(new TransText(marktr("implicit")));
    521     stoplistTable.getColumnModel().getColumn(2)
    522     .setCellEditor(new DefaultCellEditor(comboBox));
    523     int width = stoplistTable.getPreferredSize().width;
    524     stoplistTable.getColumnModel().getColumn(0).setPreferredWidth((int)(width * 0.4));
    525     stoplistTable.getColumnModel().getColumn(1).setPreferredWidth((int)(width * 0.5));
    526     stoplistTable.getColumnModel().getColumn(2).setPreferredWidth((int)(width * 0.1));
    527   }
    528 
    529   public JTable getWaypointsTable()
    530   {
    531     return waypointTable;
    532   }
    533 
    534   public void setWaypointsTableModel(WaypointTableModel model)
    535   {
    536     waypointTable.setModel(model);
    537     JComboBox<TransText> comboBox = new JComboBox<>();
    538     comboBox.addItem(new TransText(null));
    539     comboBox.addItem(new TransText(marktr("yes")));
    540     comboBox.addItem(new TransText(marktr("no")));
    541     comboBox.addItem(new TransText(marktr("implicit")));
    542     waypointTable.getColumnModel().getColumn(2)
    543     .setCellEditor(new DefaultCellEditor(comboBox));
    544     int width = waypointTable.getPreferredSize().width;
    545     waypointTable.getColumnModel().getColumn(0).setPreferredWidth((int)(width * 0.4));
    546     waypointTable.getColumnModel().getColumn(1).setPreferredWidth((int)(width * 0.5));
    547     waypointTable.getColumnModel().getColumn(2).setPreferredWidth((int)(width * 0.1));
    548   }
    549 
    550   private class TracksLSL implements ListSelectionListener
    551   {
    552     StopImporterAction root = null;
    553 
    554     public TracksLSL(StopImporterAction sia)
    555     {
    556       root = sia;
     24public class StopImporterDialog extends AbstractImporterDialog<StopImporterAction> {
     25    private JList<TrackReference> tracksList = null;
     26
     27    private JTable stoplistTable = null;
     28
     29    private JTable waypointTable = null;
     30
     31    public StopImporterDialog(StopImporterAction controller) {
     32        super(controller, tr("Create Stops from GPX"), "stopImporter");
    55733    }
    55834
    55935    @Override
    560     public void valueChanged(ListSelectionEvent e)
    561     {
    562       int selectedPos = tracksList.getAnchorSelectionIndex();
    563       if (tracksList.isSelectedIndex(selectedPos))
    564         root.tracksSelectionChanged(selectedPos);
    565       else
    566         root.tracksSelectionChanged(-1);
     36    protected void initDialog(StopImporterAction controller) {
     37        JPanel tabTracks = new JPanel();
     38        tabbedPane.addTab(tr("Tracks"), tabTracks);
     39        JPanel tabSettings = new JPanel();
     40        tabbedPane.addTab(tr("Settings"), tabSettings);
     41        JPanel tabStops = new JPanel();
     42        tabbedPane.addTab(tr("Stops"), tabStops);
     43        JPanel tabWaypoints = new JPanel();
     44        tabbedPane.addTab(tr("Waypoints"), tabWaypoints);
     45        tabbedPane.setEnabledAt(0, true);
     46        tabbedPane.setEnabledAt(1, true);
     47        tabbedPane.setEnabledAt(2, false);
     48        tabbedPane.setEnabledAt(3, true);
     49
     50        // Tracks Tab
     51        JPanel contentPane = tabTracks;
     52        GridBagLayout gridbag = new GridBagLayout();
     53        GridBagConstraints layoutCons = new GridBagConstraints();
     54        contentPane.setLayout(gridbag);
     55
     56        JLabel label = new JLabel(tr("Tracks in this GPX file:"));
     57
     58        layoutCons.gridx = 0;
     59        layoutCons.gridy = 0;
     60        layoutCons.gridwidth = 3;
     61        layoutCons.weightx = 0.0;
     62        layoutCons.weighty = 0.0;
     63        layoutCons.fill = GridBagConstraints.BOTH;
     64        gridbag.setConstraints(label, layoutCons);
     65        contentPane.add(label);
     66
     67        DefaultListModel<TrackReference> tracksListModel = controller.getTracksListModel();
     68        tracksList = new JList<>(tracksListModel);
     69        JScrollPane rpListSP = new JScrollPane(tracksList);
     70        String[] data = { "1", "2", "3", "4", "5", "6" };
     71        tracksListModel.copyInto(data);
     72        tracksList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
     73        tracksList.addListSelectionListener(new TracksLSL(controller));
     74
     75        layoutCons.gridx = 0;
     76        layoutCons.gridy = 1;
     77        layoutCons.gridwidth = 3;
     78        layoutCons.weightx = 1.0;
     79        layoutCons.weighty = 1.0;
     80        layoutCons.fill = GridBagConstraints.BOTH;
     81        gridbag.setConstraints(rpListSP, layoutCons);
     82        contentPane.add(rpListSP);
     83
     84        // Settings Tab
     85        contentPane = tabSettings;
     86        gridbag = new GridBagLayout();
     87        layoutCons = new GridBagConstraints();
     88        contentPane.setLayout(gridbag);
     89
     90        label = new JLabel(tr("Type of stops to add"));
     91
     92        layoutCons.gridx = 0;
     93        layoutCons.gridy = 0;
     94        layoutCons.gridwidth = 2;
     95        layoutCons.weightx = 0.0;
     96        layoutCons.weighty = 0.0;
     97        layoutCons.fill = GridBagConstraints.BOTH;
     98        gridbag.setConstraints(label, layoutCons);
     99        contentPane.add(label);
     100
     101        layoutCons.gridx = 0;
     102        layoutCons.gridy = 1;
     103        layoutCons.gridwidth = 1;
     104        layoutCons.weightx = 0.0;
     105        layoutCons.weighty = 0.0;
     106        layoutCons.fill = GridBagConstraints.BOTH;
     107        gridbag.setConstraints(cbStoptype, layoutCons);
     108        contentPane.add(cbStoptype);
     109
     110        label = new JLabel(tr("Time on your GPS device"));
     111
     112        layoutCons.gridx = 0;
     113        layoutCons.gridy = 2;
     114        layoutCons.gridwidth = 2;
     115        layoutCons.weightx = 0.0;
     116        layoutCons.weighty = 0.0;
     117        layoutCons.fill = GridBagConstraints.BOTH;
     118        gridbag.setConstraints(label, layoutCons);
     119        contentPane.add(label);
     120
     121        layoutCons.gridx = 0;
     122        layoutCons.gridy = 3;
     123        layoutCons.gridwidth = 1;
     124        layoutCons.weightx = 0.0;
     125        layoutCons.weighty = 0.0;
     126        layoutCons.fill = GridBagConstraints.BOTH;
     127        gridbag.setConstraints(tfGPSTimeStart, layoutCons);
     128        contentPane.add(tfGPSTimeStart);
     129
     130        label = new JLabel(tr("HH:MM:SS.sss"));
     131
     132        layoutCons.gridx = 1;
     133        layoutCons.gridy = 3;
     134        layoutCons.gridwidth = 1;
     135        layoutCons.weightx = 0.0;
     136        layoutCons.weighty = 0.0;
     137        layoutCons.fill = GridBagConstraints.BOTH;
     138        gridbag.setConstraints(label, layoutCons);
     139        contentPane.add(label);
     140
     141        label = new JLabel(tr("Time on your stopwatch"));
     142
     143        layoutCons.gridx = 0;
     144        layoutCons.gridy = 4;
     145        layoutCons.gridwidth = 2;
     146        layoutCons.weightx = 0.0;
     147        layoutCons.weighty = 0.0;
     148        layoutCons.fill = GridBagConstraints.BOTH;
     149        gridbag.setConstraints(label, layoutCons);
     150        contentPane.add(label);
     151
     152        layoutCons.gridx = 0;
     153        layoutCons.gridy = 5;
     154        layoutCons.gridwidth = 1;
     155        layoutCons.weightx = 0.0;
     156        layoutCons.weighty = 0.0;
     157        layoutCons.fill = GridBagConstraints.BOTH;
     158        gridbag.setConstraints(tfStopwatchStart, layoutCons);
     159        contentPane.add(tfStopwatchStart);
     160
     161        label = new JLabel(tr("HH:MM:SS.sss"));
     162
     163        layoutCons.gridx = 1;
     164        layoutCons.gridy = 5;
     165        layoutCons.gridwidth = 1;
     166        layoutCons.weightx = 0.0;
     167        layoutCons.weighty = 0.0;
     168        layoutCons.fill = GridBagConstraints.BOTH;
     169        gridbag.setConstraints(label, layoutCons);
     170        contentPane.add(label);
     171
     172        label = new JLabel(tr("Time window"));
     173
     174        layoutCons.gridx = 0;
     175        layoutCons.gridy = 6;
     176        layoutCons.gridwidth = 2;
     177        layoutCons.weightx = 0.0;
     178        layoutCons.weighty = 0.0;
     179        layoutCons.fill = GridBagConstraints.BOTH;
     180        gridbag.setConstraints(label, layoutCons);
     181        contentPane.add(label);
     182
     183        layoutCons.gridx = 0;
     184        layoutCons.gridy = 7;
     185        layoutCons.gridwidth = 1;
     186        layoutCons.weightx = 0.0;
     187        layoutCons.weighty = 0.0;
     188        layoutCons.fill = GridBagConstraints.BOTH;
     189        gridbag.setConstraints(tfTimeWindow, layoutCons);
     190        contentPane.add(tfTimeWindow);
     191
     192        label = new JLabel(tr("seconds"));
     193
     194        layoutCons.gridx = 1;
     195        layoutCons.gridy = 7;
     196        layoutCons.gridwidth = 1;
     197        layoutCons.weightx = 0.0;
     198        layoutCons.weighty = 0.0;
     199        layoutCons.fill = GridBagConstraints.BOTH;
     200        gridbag.setConstraints(label, layoutCons);
     201        contentPane.add(label);
     202
     203        label = new JLabel(tr("Move Threshold"));
     204
     205        layoutCons.gridx = 0;
     206        layoutCons.gridy = 8;
     207        layoutCons.gridwidth = 2;
     208        layoutCons.weightx = 0.0;
     209        layoutCons.weighty = 0.0;
     210        layoutCons.fill = GridBagConstraints.BOTH;
     211        gridbag.setConstraints(label, layoutCons);
     212        contentPane.add(label);
     213
     214        layoutCons.gridx = 0;
     215        layoutCons.gridy = 9;
     216        layoutCons.gridwidth = 1;
     217        layoutCons.weightx = 0.0;
     218        layoutCons.weighty = 0.0;
     219        layoutCons.fill = GridBagConstraints.BOTH;
     220        gridbag.setConstraints(tfThreshold, layoutCons);
     221        contentPane.add(tfThreshold);
     222
     223        label = new JLabel(tr("meters"));
     224
     225        layoutCons.gridx = 1;
     226        layoutCons.gridy = 9;
     227        layoutCons.gridwidth = 1;
     228        layoutCons.weightx = 0.0;
     229        layoutCons.weighty = 0.0;
     230        layoutCons.fill = GridBagConstraints.BOTH;
     231        gridbag.setConstraints(label, layoutCons);
     232        contentPane.add(label);
     233
     234        JButton bSuggestStops = new JButton(tr("Suggest Stops"));
     235        bSuggestStops.setActionCommand("stopImporter.settingsSuggestStops");
     236        bSuggestStops.addActionListener(controller);
     237
     238        layoutCons.gridx = 0;
     239        layoutCons.gridy = 10;
     240        layoutCons.gridwidth = 3;
     241        layoutCons.weightx = 1.0;
     242        layoutCons.weighty = 0.0;
     243        layoutCons.fill = GridBagConstraints.BOTH;
     244        gridbag.setConstraints(bSuggestStops, layoutCons);
     245        contentPane.add(bSuggestStops);
     246
     247        // Stops Tab
     248        contentPane = tabStops;
     249        gridbag = new GridBagLayout();
     250        layoutCons = new GridBagConstraints();
     251        contentPane.setLayout(gridbag);
     252        contentPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
     253                .put(KeyStroke.getKeyStroke("alt N"), "stopImporter.focusName");
     254        contentPane.getActionMap().put("stopImporter.focusName",
     255                controller.getFocusTrackStoplistNameAction());
     256        contentPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
     257                .put(KeyStroke.getKeyStroke("alt S"), "stopImporter.focusShelterYes");
     258        contentPane.getActionMap().put("stopImporter.focusShelterYes",
     259                controller.getFocusTrackStoplistShelterAction("yes"));
     260        contentPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
     261                .put(KeyStroke.getKeyStroke("alt T"), "stopImporter.focusShelterNo");
     262        contentPane.getActionMap().put("stopImporter.focusShelterNo",
     263                controller.getFocusTrackStoplistShelterAction("no"));
     264        contentPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
     265                .put(KeyStroke.getKeyStroke("alt U"), "stopImporter.focusShelterImplicit");
     266        contentPane.getActionMap().put("stopImporter.focusShelterImplicit",
     267                controller.getFocusTrackStoplistShelterAction("implicit"));
     268        contentPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
     269                .put(KeyStroke.getKeyStroke("alt D"), "stopImporter.stoplistDelete");
     270        contentPane.getActionMap().put("stopImporter.stoplistDelete",
     271                controller.getFocusStoplistDeleteAction());
     272
     273        stoplistTable = new JTable();
     274        JScrollPane tableSP = new JScrollPane(stoplistTable);
     275
     276        layoutCons.gridx = 0;
     277        layoutCons.gridy = 0;
     278        layoutCons.gridwidth = 4;
     279        layoutCons.weightx = 1.0;
     280        layoutCons.weighty = 1.0;
     281        layoutCons.fill = GridBagConstraints.BOTH;
     282        gridbag.setConstraints(tableSP, layoutCons);
     283        contentPane.add(tableSP);
     284
     285        JButton bFind = new JButton(tr("Find"));
     286        bFind.setActionCommand("stopImporter.stoplistFind");
     287        bFind.addActionListener(controller);
     288
     289        layoutCons.gridx = 0;
     290        layoutCons.gridy = 1;
     291        layoutCons.gridwidth = 1;
     292        layoutCons.weightx = 1.0;
     293        layoutCons.weighty = 0.0;
     294        layoutCons.fill = GridBagConstraints.BOTH;
     295        gridbag.setConstraints(bFind, layoutCons);
     296        contentPane.add(bFind);
     297
     298        JButton bShow = new JButton(tr("Show"));
     299        bShow.setActionCommand("stopImporter.stoplistShow");
     300        bShow.addActionListener(controller);
     301
     302        layoutCons.gridx = 0;
     303        layoutCons.gridy = 2;
     304        layoutCons.gridwidth = 1;
     305        layoutCons.weightx = 1.0;
     306        layoutCons.weighty = 0.0;
     307        layoutCons.fill = GridBagConstraints.BOTH;
     308        gridbag.setConstraints(bShow, layoutCons);
     309        contentPane.add(bShow);
     310
     311        JButton bMark = new JButton(tr("Mark"));
     312        bMark.setActionCommand("stopImporter.stoplistMark");
     313        bMark.addActionListener(controller);
     314
     315        layoutCons.gridx = 1;
     316        layoutCons.gridy = 1;
     317        layoutCons.gridheight = 1;
     318        layoutCons.gridwidth = 1;
     319        layoutCons.weightx = 1.0;
     320        layoutCons.weighty = 0.0;
     321        layoutCons.fill = GridBagConstraints.BOTH;
     322        gridbag.setConstraints(bMark, layoutCons);
     323        contentPane.add(bMark);
     324
     325        JButton bDetach = new JButton(tr("Detach"));
     326        bDetach.setActionCommand("stopImporter.stoplistDetach");
     327        bDetach.addActionListener(controller);
     328
     329        layoutCons.gridx = 1;
     330        layoutCons.gridy = 2;
     331        layoutCons.gridheight = 1;
     332        layoutCons.gridwidth = 1;
     333        layoutCons.weightx = 1.0;
     334        layoutCons.weighty = 0.0;
     335        layoutCons.fill = GridBagConstraints.BOTH;
     336        gridbag.setConstraints(bDetach, layoutCons);
     337        contentPane.add(bDetach);
     338
     339        JButton bAdd = new JButton(tr("Add"));
     340        bAdd.setActionCommand("stopImporter.stoplistAdd");
     341        bAdd.addActionListener(controller);
     342
     343        layoutCons.gridx = 2;
     344        layoutCons.gridy = 1;
     345        layoutCons.gridheight = 1;
     346        layoutCons.gridwidth = 1;
     347        layoutCons.weightx = 1.0;
     348        layoutCons.weighty = 0.0;
     349        layoutCons.fill = GridBagConstraints.BOTH;
     350        gridbag.setConstraints(bAdd, layoutCons);
     351        contentPane.add(bAdd);
     352
     353        JButton bDelete = new JButton(tr("Delete"));
     354        bDelete.setActionCommand("stopImporter.stoplistDelete");
     355        bDelete.addActionListener(controller);
     356
     357        layoutCons.gridx = 2;
     358        layoutCons.gridy = 2;
     359        layoutCons.gridwidth = 1;
     360        layoutCons.weightx = 1.0;
     361        layoutCons.weighty = 0.0;
     362        layoutCons.fill = GridBagConstraints.BOTH;
     363        gridbag.setConstraints(bDelete, layoutCons);
     364        contentPane.add(bDelete);
     365
     366        JButton bSort = new JButton(tr("Sort"));
     367        bSort.setActionCommand("stopImporter.stoplistSort");
     368        bSort.addActionListener(controller);
     369
     370        layoutCons.gridx = 3;
     371        layoutCons.gridy = 1;
     372        layoutCons.gridheight = 2;
     373        layoutCons.gridwidth = 1;
     374        layoutCons.weightx = 1.0;
     375        layoutCons.weighty = 0.0;
     376        layoutCons.fill = GridBagConstraints.BOTH;
     377        gridbag.setConstraints(bSort, layoutCons);
     378        contentPane.add(bSort);
     379
     380        // Waypoints Tab
     381        contentPane = tabWaypoints;
     382        gridbag = new GridBagLayout();
     383        layoutCons = new GridBagConstraints();
     384        contentPane.setLayout(gridbag);
     385        contentPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
     386                .put(KeyStroke.getKeyStroke("alt N"), "stopImporter.focusName");
     387        contentPane.getActionMap().put("stopImporter.focusName",
     388                controller.getFocusWaypointNameAction());
     389        contentPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
     390                .put(KeyStroke.getKeyStroke("alt S"), "stopImporter.focusShelterYes");
     391        contentPane.getActionMap().put("stopImporter.focusShelterYes",
     392                controller.getFocusWaypointShelterAction("yes"));
     393        contentPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
     394                .put(KeyStroke.getKeyStroke("alt T"), "stopImporter.focusShelterNo");
     395        contentPane.getActionMap().put("stopImporter.focusShelterNo",
     396                controller.getFocusWaypointShelterAction("no"));
     397        contentPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
     398                .put(KeyStroke.getKeyStroke("alt U"), "stopImporter.focusShelterImplicit");
     399        contentPane.getActionMap().put("stopImporter.focusShelterImplicit",
     400                controller.getFocusWaypointShelterAction("implicit"));
     401        contentPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
     402                .put(KeyStroke.getKeyStroke("alt D"), "stopImporter.waypointsDelete");
     403        contentPane.getActionMap().put("stopImporter.waypointsDelete",
     404                controller.getFocusWaypointDeleteAction());
     405
     406        waypointTable = new JTable();
     407        tableSP = new JScrollPane(waypointTable);
     408
     409        layoutCons.gridx = 0;
     410        layoutCons.gridy = 0;
     411        layoutCons.gridwidth = 3;
     412        layoutCons.weightx = 1.0;
     413        layoutCons.weighty = 1.0;
     414        layoutCons.fill = GridBagConstraints.BOTH;
     415        gridbag.setConstraints(tableSP, layoutCons);
     416        contentPane.add(tableSP);
     417
     418        bFind = new JButton(tr("Find"));
     419        bFind.setActionCommand("stopImporter.waypointsFind");
     420        bFind.addActionListener(controller);
     421
     422        layoutCons.gridx = 0;
     423        layoutCons.gridy = 1;
     424        layoutCons.gridwidth = 1;
     425        layoutCons.weightx = 1.0;
     426        layoutCons.weighty = 0.0;
     427        layoutCons.fill = GridBagConstraints.BOTH;
     428        gridbag.setConstraints(bFind, layoutCons);
     429        contentPane.add(bFind);
     430
     431        bShow = new JButton(tr("Show"));
     432        bShow.setActionCommand("stopImporter.waypointsShow");
     433        bShow.addActionListener(controller);
     434
     435        layoutCons.gridx = 0;
     436        layoutCons.gridy = 2;
     437        layoutCons.gridwidth = 1;
     438        layoutCons.weightx = 1.0;
     439        layoutCons.weighty = 0.0;
     440        layoutCons.fill = GridBagConstraints.BOTH;
     441        gridbag.setConstraints(bShow, layoutCons);
     442        contentPane.add(bShow);
     443
     444        bMark = new JButton(tr("Mark"));
     445        bMark.setActionCommand("stopImporter.waypointsMark");
     446        bMark.addActionListener(controller);
     447
     448        layoutCons.gridx = 1;
     449        layoutCons.gridy = 1;
     450        layoutCons.gridheight = 1;
     451        layoutCons.gridwidth = 1;
     452        layoutCons.weightx = 1.0;
     453        layoutCons.weighty = 0.0;
     454        layoutCons.fill = GridBagConstraints.BOTH;
     455        gridbag.setConstraints(bMark, layoutCons);
     456        contentPane.add(bMark);
     457
     458        bDetach = new JButton(tr("Detach"));
     459        bDetach.setActionCommand("stopImporter.waypointsDetach");
     460        bDetach.addActionListener(controller);
     461
     462        layoutCons.gridx = 1;
     463        layoutCons.gridy = 2;
     464        layoutCons.gridheight = 1;
     465        layoutCons.gridwidth = 1;
     466        layoutCons.weightx = 1.0;
     467        layoutCons.weighty = 0.0;
     468        layoutCons.fill = GridBagConstraints.BOTH;
     469        gridbag.setConstraints(bDetach, layoutCons);
     470        contentPane.add(bDetach);
     471
     472        bAdd = new JButton(tr("Enable"));
     473        bAdd.setActionCommand("stopImporter.waypointsAdd");
     474        bAdd.addActionListener(controller);
     475
     476        layoutCons.gridx = 2;
     477        layoutCons.gridy = 1;
     478        layoutCons.gridheight = 1;
     479        layoutCons.gridwidth = 1;
     480        layoutCons.weightx = 1.0;
     481        layoutCons.weighty = 0.0;
     482        layoutCons.fill = GridBagConstraints.BOTH;
     483        gridbag.setConstraints(bAdd, layoutCons);
     484        contentPane.add(bAdd);
     485
     486        bDelete = new JButton(tr("Disable"));
     487        bDelete.setActionCommand("stopImporter.waypointsDelete");
     488        bDelete.addActionListener(controller);
     489
     490        layoutCons.gridx = 2;
     491        layoutCons.gridy = 2;
     492        layoutCons.gridwidth = 1;
     493        layoutCons.weightx = 1.0;
     494        layoutCons.weighty = 0.0;
     495        layoutCons.fill = GridBagConstraints.BOTH;
     496        gridbag.setConstraints(bDelete, layoutCons);
     497        contentPane.add(bDelete);
    567498    }
    568   };
     499
     500    public JTable getStoplistTable() {
     501        return stoplistTable;
     502    }
     503
     504    public void setStoplistTableModel(TrackStoplistTableModel model) {
     505        stoplistTable.setModel(model);
     506        JComboBox<TransText> comboBox = new JComboBox<>();
     507        comboBox.addItem(new TransText(null));
     508        comboBox.addItem(new TransText(marktr("yes")));
     509        comboBox.addItem(new TransText(marktr("no")));
     510        comboBox.addItem(new TransText(marktr("implicit")));
     511        stoplistTable.getColumnModel().getColumn(2).setCellEditor(new DefaultCellEditor(comboBox));
     512        int width = stoplistTable.getPreferredSize().width;
     513        stoplistTable.getColumnModel().getColumn(0).setPreferredWidth((int) (width * 0.4));
     514        stoplistTable.getColumnModel().getColumn(1).setPreferredWidth((int) (width * 0.5));
     515        stoplistTable.getColumnModel().getColumn(2).setPreferredWidth((int) (width * 0.1));
     516    }
     517
     518    public JTable getWaypointsTable() {
     519        return waypointTable;
     520    }
     521
     522    public void setWaypointsTableModel(WaypointTableModel model) {
     523        waypointTable.setModel(model);
     524        JComboBox<TransText> comboBox = new JComboBox<>();
     525        comboBox.addItem(new TransText(null));
     526        comboBox.addItem(new TransText(marktr("yes")));
     527        comboBox.addItem(new TransText(marktr("no")));
     528        comboBox.addItem(new TransText(marktr("implicit")));
     529        waypointTable.getColumnModel().getColumn(2).setCellEditor(new DefaultCellEditor(comboBox));
     530        int width = waypointTable.getPreferredSize().width;
     531        waypointTable.getColumnModel().getColumn(0).setPreferredWidth((int) (width * 0.4));
     532        waypointTable.getColumnModel().getColumn(1).setPreferredWidth((int) (width * 0.5));
     533        waypointTable.getColumnModel().getColumn(2).setPreferredWidth((int) (width * 0.1));
     534    }
     535
     536    private class TracksLSL implements ListSelectionListener {
     537        StopImporterAction root = null;
     538
     539        public TracksLSL(StopImporterAction sia) {
     540            root = sia;
     541        }
     542
     543        @Override
     544        public void valueChanged(ListSelectionEvent e) {
     545            int selectedPos = tracksList.getAnchorSelectionIndex();
     546            if (tracksList.isSelectedIndex(selectedPos))
     547                root.tracksSelectionChanged(selectedPos);
     548            else
     549                root.tracksSelectionChanged(-1);
     550        }
     551    };
    569552}
  • applications/editors/josm/plugins/public_transport/src/public_transport/TrackReference.java

    r29854 r32357  
    1818import org.openstreetmap.josm.data.osm.Node;
    1919
    20 public class TrackReference
    21     implements Comparable< TrackReference >, TableModelListener
    22 {
    23   public GpxTrack track;
    24   public TrackStoplistTableModel stoplistTM;
    25   public String stopwatchStart;
    26   public String gpsStartTime;
    27   public String gpsSyncTime;
    28   public double timeWindow;
    29   public double threshold;
    30   private StopImporterAction controller = null;
    31   public boolean inEvent = false;
     20public class TrackReference implements Comparable<TrackReference>, TableModelListener {
     21    public GpxTrack track;
    3222
    33   public TrackReference(GpxTrack track, StopImporterAction controller)
    34   {
    35     this.track = track;
    36     this.stoplistTM = new TrackStoplistTableModel(this);
    37     this.stopwatchStart = "00:00:00";
    38     this.gpsStartTime = null;
    39     this.gpsSyncTime = null;
    40     this.controller = controller;
    41     if (track != null)
    42     {
    43       Iterator< GpxTrackSegment > siter = track.getSegments().iterator();
    44       while ((siter.hasNext()) && (this.gpsSyncTime == null))
    45       {
    46     Iterator< WayPoint > witer = siter.next().getWayPoints().iterator();
    47     if (witer.hasNext())
    48     {
    49       this.gpsStartTime = witer.next().getString("time");
    50       if (this.gpsStartTime != null)
    51         this.gpsSyncTime = this.gpsStartTime.substring(11, 19);
    52     }
    53       }
    54       if (this.gpsSyncTime == null)
    55       {
    56     JOptionPane.showMessageDialog
    57         (null, tr("The GPX file doesn''t contain valid trackpoints. "
    58         + "Please use a GPX file that has trackpoints."), tr("GPX File Trouble"),
    59      JOptionPane.ERROR_MESSAGE);
     23    public TrackStoplistTableModel stoplistTM;
    6024
    61     this.gpsStartTime = "1970-01-01T00:00:00Z";
    62     this.gpsSyncTime = this.stopwatchStart;
    63       }
    64     }
    65     else
    66       this.gpsSyncTime = this.stopwatchStart;
    67     this.timeWindow = 20;
    68     this.threshold = 20;
    69   }
     25    public String stopwatchStart;
    7026
    71   public GpxTrack getGpxTrack()
    72   {
    73     return track;
    74   }
     27    public String gpsStartTime;
    7528
    76   public int compareTo(TrackReference tr)
    77   {
    78     String name = (String)track.getAttributes().get("name");
    79     String tr_name = (String)tr.track.getAttributes().get("name");
    80     if (name != null)
    81     {
    82       if (tr_name == null)
    83     return -1;
    84       return name.compareTo(tr_name);
    85     }
    86     return 1;
    87   }
     29    public String gpsSyncTime;
    8830
    89   public String toString()
    90   {
    91     String buf = (String)track.getAttributes().get("name");
    92     if (buf == null)
    93       return tr("unnamed");
    94     return buf;
    95   }
     31    public double timeWindow;
    9632
    97   public void tableChanged(TableModelEvent e)
    98   {
    99     if ((e.getType() == TableModelEvent.UPDATE) && (e.getFirstRow() >= 0))
    100     {
    101       if (inEvent)
    102     return;
     33    public double threshold;
    10334
    104       double time = StopImporterDialog.parseTime
    105         ((String)stoplistTM.getValueAt(e.getFirstRow(), 0));
    106       if (time < 0)
    107       {
    108     stoplistTM.setValueAt
    109         (stoplistTM.timeAt(e.getFirstRow()), e.getFirstRow(), 0);
    110     JOptionPane.showMessageDialog
    111         (null, tr("Can''t parse a time from this string."), tr("Invalid value"),
    112          JOptionPane.ERROR_MESSAGE);
    113     return;
    114       }
     35    private StopImporterAction controller = null;
    11536
    116       Main.main.undoRedo.add(new TrackStoplistNameCommand
    117               (this, e.getFirstRow()));
    118       stoplistTM.setTimeAt
    119       (e.getFirstRow(), (String)stoplistTM.getValueAt(e.getFirstRow(), 0));
    120     }
    121   }
     37    public boolean inEvent = false;
    12238
    123   public LatLon computeCoor(double time)
    124   {
    125     double gpsSyncTime = StopImporterDialog.parseTime(this.gpsSyncTime);
    126     double dGpsStartTime = StopImporterDialog.parseTime(gpsStartTime);
    127     if (gpsSyncTime < dGpsStartTime - 12*60*60)
    128       gpsSyncTime += 24*60*60;
    129     double timeDelta = gpsSyncTime - StopImporterDialog.parseTime(stopwatchStart);
    130     time += timeDelta;
     39    public TrackReference(GpxTrack track, StopImporterAction controller) {
     40        this.track = track;
     41        this.stoplistTM = new TrackStoplistTableModel(this);
     42        this.stopwatchStart = "00:00:00";
     43        this.gpsStartTime = null;
     44        this.gpsSyncTime = null;
     45        this.controller = controller;
     46        if (track != null) {
     47            Iterator<GpxTrackSegment> siter = track.getSegments().iterator();
     48            while ((siter.hasNext()) && (this.gpsSyncTime == null)) {
     49                Iterator<WayPoint> witer = siter.next().getWayPoints().iterator();
     50                if (witer.hasNext()) {
     51                    this.gpsStartTime = witer.next().getString("time");
     52                    if (this.gpsStartTime != null)
     53                        this.gpsSyncTime = this.gpsStartTime.substring(11, 19);
     54                }
     55            }
     56            if (this.gpsSyncTime == null) {
     57                JOptionPane.showMessageDialog(null,
     58                        tr("The GPX file doesn''t contain valid trackpoints. "
     59                                + "Please use a GPX file that has trackpoints."),
     60                        tr("GPX File Trouble"), JOptionPane.ERROR_MESSAGE);
    13161
    132     WayPoint wayPoint = null;
    133     WayPoint lastWayPoint = null;
    134     double wayPointTime = 0;
    135     double lastWayPointTime = 0;
    136     Iterator< GpxTrackSegment > siter = track.getSegments().iterator();
    137     while (siter.hasNext())
    138     {
    139       Iterator< WayPoint > witer = siter.next().getWayPoints().iterator();
    140       while (witer.hasNext())
    141       {
    142     wayPoint = witer.next();
    143     String startTime = wayPoint.getString("time");
    144     wayPointTime = StopImporterDialog.parseTime(startTime.substring(11, 19));
    145     if (startTime.substring(11, 19).compareTo(gpsStartTime.substring(11, 19)) == -1)
    146       wayPointTime += 24*60*60;
    147     if (wayPointTime >= time)
    148       break;
    149     lastWayPoint = wayPoint;
    150     lastWayPointTime = wayPointTime;
    151       }
    152       if (wayPointTime >= time)
    153     break;
     62                this.gpsStartTime = "1970-01-01T00:00:00Z";
     63                this.gpsSyncTime = this.stopwatchStart;
     64            }
     65        } else
     66            this.gpsSyncTime = this.stopwatchStart;
     67        this.timeWindow = 20;
     68        this.threshold = 20;
    15469    }
    15570
    156     double lat = 0;
    157     if ((wayPointTime == lastWayPointTime) || (lastWayPoint == null))
    158       lat = wayPoint.getCoor().lat();
    159     else
    160       lat = wayPoint.getCoor().lat()
    161       *(time - lastWayPointTime)/(wayPointTime - lastWayPointTime)
    162       + lastWayPoint.getCoor().lat()
    163       *(wayPointTime - time)/(wayPointTime - lastWayPointTime);
    164     double lon = 0;
    165     if ((wayPointTime == lastWayPointTime) || (lastWayPoint == null))
    166       lon = wayPoint.getCoor().lon();
    167     else
    168       lon = wayPoint.getCoor().lon()
    169       *(time - lastWayPointTime)/(wayPointTime - lastWayPointTime)
    170       + lastWayPoint.getCoor().lon()
    171       *(wayPointTime - time)/(wayPointTime - lastWayPointTime);
     71    public GpxTrack getGpxTrack() {
     72        return track;
     73    }
    17274
    173     return new LatLon(lat, lon);
    174   }
     75    @Override
     76    public int compareTo(TrackReference tr) {
     77        String name = (String) track.getAttributes().get("name");
     78        String tr_name = (String) tr.track.getAttributes().get("name");
     79        if (name != null) {
     80            if (tr_name == null)
     81                return -1;
     82            return name.compareTo(tr_name);
     83        }
     84        return 1;
     85    }
    17586
    176   public void relocateNodes()
    177   {
    178     for (int i = 0; i < stoplistTM.getNodes().size(); ++i)
    179     {
    180       Node node = stoplistTM.nodeAt(i);
    181       if (node == null)
    182     continue;
     87    @Override
     88    public String toString() {
     89        String buf = (String) track.getAttributes().get("name");
     90        if (buf == null)
     91            return tr("unnamed");
     92        return buf;
     93    }
    18394
    184       double time = StopImporterDialog.parseTime
    185         ((String)stoplistTM.getValueAt(i, 0));
    186       LatLon latLon = computeCoor(time);
     95    @Override
     96    public void tableChanged(TableModelEvent e) {
     97        if ((e.getType() == TableModelEvent.UPDATE) && (e.getFirstRow() >= 0)) {
     98            if (inEvent)
     99                return;
    187100
    188       Node newNode = new Node(node);
    189       newNode.setCoor(latLon);
    190       Command cmd = new ChangeCommand(node, newNode);
    191       if (cmd != null)
    192       {
    193     Main.main.undoRedo.add(cmd);
    194       }
     101            double time = StopImporterDialog
     102                    .parseTime((String) stoplistTM.getValueAt(e.getFirstRow(), 0));
     103            if (time < 0) {
     104                stoplistTM.setValueAt(stoplistTM.timeAt(e.getFirstRow()), e.getFirstRow(), 0);
     105                JOptionPane.showMessageDialog(null, tr("Can''t parse a time from this string."),
     106                        tr("Invalid value"), JOptionPane.ERROR_MESSAGE);
     107                return;
     108            }
     109
     110            Main.main.undoRedo.add(new TrackStoplistNameCommand(this, e.getFirstRow()));
     111            stoplistTM.setTimeAt(e.getFirstRow(),
     112                    (String) stoplistTM.getValueAt(e.getFirstRow(), 0));
     113        }
    195114    }
    196   }
     115
     116    public LatLon computeCoor(double time) {
     117        double gpsSyncTime = StopImporterDialog.parseTime(this.gpsSyncTime);
     118        double dGpsStartTime = StopImporterDialog.parseTime(gpsStartTime);
     119        if (gpsSyncTime < dGpsStartTime - 12 * 60 * 60)
     120            gpsSyncTime += 24 * 60 * 60;
     121        double timeDelta = gpsSyncTime - StopImporterDialog.parseTime(stopwatchStart);
     122        time += timeDelta;
     123
     124        WayPoint wayPoint = null;
     125        WayPoint lastWayPoint = null;
     126        double wayPointTime = 0;
     127        double lastWayPointTime = 0;
     128        Iterator<GpxTrackSegment> siter = track.getSegments().iterator();
     129        while (siter.hasNext()) {
     130            Iterator<WayPoint> witer = siter.next().getWayPoints().iterator();
     131            while (witer.hasNext()) {
     132                wayPoint = witer.next();
     133                String startTime = wayPoint.getString("time");
     134                wayPointTime = StopImporterDialog.parseTime(startTime.substring(11, 19));
     135                if (startTime.substring(11, 19).compareTo(gpsStartTime.substring(11, 19)) == -1)
     136                    wayPointTime += 24 * 60 * 60;
     137                if (wayPointTime >= time)
     138                    break;
     139                lastWayPoint = wayPoint;
     140                lastWayPointTime = wayPointTime;
     141            }
     142            if (wayPointTime >= time)
     143                break;
     144        }
     145
     146        double lat = 0;
     147        if ((wayPointTime == lastWayPointTime) || (lastWayPoint == null))
     148            lat = wayPoint.getCoor().lat();
     149        else
     150            lat = wayPoint.getCoor().lat() * (time - lastWayPointTime)
     151                    / (wayPointTime - lastWayPointTime)
     152                    + lastWayPoint.getCoor().lat() * (wayPointTime - time)
     153                            / (wayPointTime - lastWayPointTime);
     154        double lon = 0;
     155        if ((wayPointTime == lastWayPointTime) || (lastWayPoint == null))
     156            lon = wayPoint.getCoor().lon();
     157        else
     158            lon = wayPoint.getCoor().lon() * (time - lastWayPointTime)
     159                    / (wayPointTime - lastWayPointTime)
     160                    + lastWayPoint.getCoor().lon() * (wayPointTime - time)
     161                            / (wayPointTime - lastWayPointTime);
     162
     163        return new LatLon(lat, lon);
     164    }
     165
     166    public void relocateNodes() {
     167        for (int i = 0; i < stoplistTM.getNodes().size(); ++i) {
     168            Node node = stoplistTM.nodeAt(i);
     169            if (node == null)
     170                continue;
     171
     172            double time = StopImporterDialog.parseTime((String) stoplistTM.getValueAt(i, 0));
     173            LatLon latLon = computeCoor(time);
     174
     175            Node newNode = new Node(node);
     176            newNode.setCoor(latLon);
     177            Command cmd = new ChangeCommand(node, newNode);
     178            if (cmd != null) {
     179                Main.main.undoRedo.add(cmd);
     180            }
     181        }
     182    }
    197183};
  • applications/editors/josm/plugins/public_transport/src/public_transport/TrackStoplistAddCommand.java

    r29854 r32357  
    88import org.openstreetmap.josm.data.osm.OsmPrimitive;
    99
    10 public class TrackStoplistAddCommand extends Command
    11 {
    12   private int workingLine;
    13   private TrackStoplistTableModel stoplistTM = null;
     10public class TrackStoplistAddCommand extends Command {
     11    private int workingLine;
    1412
    15   public TrackStoplistAddCommand(StopImporterAction controller)
    16   {
    17     stoplistTM = controller.getCurrentTrack().stoplistTM;
    18     workingLine = controller.getDialog().getStoplistTable().getSelectedRow();
    19   }
     13    private TrackStoplistTableModel stoplistTM = null;
    2014
    21   public boolean executeCommand()
    22   {
    23     stoplistTM.insertRow(workingLine, "00:00:00");
    24     return true;
    25   }
     15    public TrackStoplistAddCommand(StopImporterAction controller) {
     16        stoplistTM = controller.getCurrentTrack().stoplistTM;
     17        workingLine = controller.getDialog().getStoplistTable().getSelectedRow();
     18    }
    2619
    27   public void undoCommand()
    28   {
    29     int workingLine = this.workingLine;
    30     if (workingLine < 0)
    31       workingLine = stoplistTM.getRowCount()-1;
    32     stoplistTM.removeRow(workingLine);
    33   }
     20    @Override
     21    public boolean executeCommand() {
     22        stoplistTM.insertRow(workingLine, "00:00:00");
     23        return true;
     24    }
    3425
    35   public void fillModifiedData
    36     (Collection< OsmPrimitive > modified, Collection< OsmPrimitive > deleted,
    37      Collection< OsmPrimitive > added)
    38   {
    39   }
     26    @Override
     27    public void undoCommand() {
     28        int workingLine = this.workingLine;
     29        if (workingLine < 0)
     30            workingLine = stoplistTM.getRowCount() - 1;
     31        stoplistTM.removeRow(workingLine);
     32    }
    4033
    41   @Override public String getDescriptionText()
    42   {
    43     return tr("Public Transport: Add track stop");
    44   }
    45 };
     34    @Override
     35    public void fillModifiedData(Collection<OsmPrimitive> modified,
     36            Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
     37    }
     38
     39    @Override
     40    public String getDescriptionText() {
     41        return tr("Public Transport: Add track stop");
     42    }
     43}
  • applications/editors/josm/plugins/public_transport/src/public_transport/TrackStoplistDeleteCommand.java

    r29854 r32357  
    1111import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1212
    13 public class TrackStoplistDeleteCommand extends Command
    14 {
    15   private class NodeTimeName
    16   {
    17     NodeTimeName(Node node, String time, String name, TransText shelter)
    18     {
    19       this.node = node;
    20       this.time = time;
    21       this.name = name;
    22       this.shelter = shelter;
     13public class TrackStoplistDeleteCommand extends Command {
     14    private class NodeTimeName {
     15        NodeTimeName(Node node, String time, String name, TransText shelter) {
     16            this.node = node;
     17            this.time = time;
     18            this.name = name;
     19            this.shelter = shelter;
     20        }
     21
     22        public Node node;
     23
     24        public String time;
     25
     26        public String name;
     27
     28        public TransText shelter;
    2329    }
    2430
    25     public Node node;
    26     public String time;
    27     public String name;
    28     public TransText shelter;
    29   };
     31    private Vector<Integer> workingLines = null;
    3032
    31   private Vector< Integer > workingLines = null;
    32   private Vector< NodeTimeName > nodesForUndo = null;
    33   private TrackStoplistTableModel stoplistTM = null;
     33    private Vector<NodeTimeName> nodesForUndo = null;
    3434
    35   public TrackStoplistDeleteCommand(StopImporterAction controller)
    36   {
    37     stoplistTM = controller.getCurrentTrack().stoplistTM;
    38     workingLines = new Vector< Integer >();
    39     nodesForUndo = new Vector< NodeTimeName >();
     35    private TrackStoplistTableModel stoplistTM = null;
    4036
    41     // use selected lines or all lines if no line is selected
    42     int[] selectedLines = controller.getDialog().getStoplistTable().getSelectedRows();
    43     if (selectedLines.length > 0)
    44     {
    45       for (int i = 0; i < selectedLines.length; ++i)
    46       {
    47         workingLines.add(selectedLines[i]);
    48       }
     37    public TrackStoplistDeleteCommand(StopImporterAction controller) {
     38        stoplistTM = controller.getCurrentTrack().stoplistTM;
     39        workingLines = new Vector<>();
     40        nodesForUndo = new Vector<>();
     41
     42        // use selected lines or all lines if no line is selected
     43        int[] selectedLines = controller.getDialog().getStoplistTable().getSelectedRows();
     44        if (selectedLines.length > 0) {
     45            for (int i = 0; i < selectedLines.length; ++i) {
     46                workingLines.add(selectedLines[i]);
     47            }
     48        } else {
     49            for (int i = 0; i < stoplistTM.getRowCount(); ++i)
     50                workingLines.add(new Integer(i));
     51        }
    4952    }
    50     else
    51     {
    52       for (int i = 0; i < stoplistTM.getRowCount(); ++i)
    53         workingLines.add(new Integer(i));
     53
     54    @Override
     55    public boolean executeCommand() {
     56        nodesForUndo.clear();
     57        for (int i = workingLines.size() - 1; i >= 0; --i) {
     58            int j = workingLines.elementAt(i).intValue();
     59            Node node = stoplistTM.nodeAt(j);
     60            nodesForUndo.add(new NodeTimeName(node, (String) stoplistTM.getValueAt(j, 0),
     61                    (String) stoplistTM.getValueAt(j, 1), (TransText) stoplistTM.getValueAt(j, 2)));
     62            stoplistTM.removeRow(j);
     63            if (node == null)
     64                continue;
     65            Main.getLayerManager().getEditDataSet().removePrimitive(node);
     66            node.setDeleted(true);
     67        }
     68        return true;
    5469    }
    55   }
    5670
    57   public boolean executeCommand()
    58   {
    59     nodesForUndo.clear();
    60     for (int i = workingLines.size()-1; i >= 0; --i)
    61     {
    62       int j = workingLines.elementAt(i).intValue();
    63       Node node = stoplistTM.nodeAt(j);
    64       nodesForUndo.add(new NodeTimeName
    65       (node, (String)stoplistTM.getValueAt(j, 0),
    66        (String)stoplistTM.getValueAt(j, 1),
    67        (TransText)stoplistTM.getValueAt(j, 2)));
    68       stoplistTM.removeRow(j);
    69       if (node == null)
    70         continue;
    71       Main.main.getCurrentDataSet().removePrimitive(node);
    72       node.setDeleted(true);
     71    @Override
     72    public void undoCommand() {
     73        for (int i = 0; i < workingLines.size(); ++i) {
     74            int j = workingLines.elementAt(i).intValue();
     75            NodeTimeName ntn = nodesForUndo.elementAt(workingLines.size() - i - 1);
     76            stoplistTM.insertRow(j, ntn.node, ntn.time, ntn.name, ntn.shelter);
     77            if (ntn.node == null)
     78                continue;
     79            ntn.node.setDeleted(false);
     80            Main.getLayerManager().getEditDataSet().addPrimitive(ntn.node);
     81        }
    7382    }
    74     return true;
    75   }
    7683
    77   public void undoCommand()
    78   {
    79     for (int i = 0; i < workingLines.size(); ++i)
    80     {
    81       int j = workingLines.elementAt(i).intValue();
    82       NodeTimeName ntn = nodesForUndo.elementAt(workingLines.size() - i - 1);
    83       stoplistTM.insertRow(j, ntn.node, ntn.time, ntn.name, ntn.shelter);
    84       if (ntn.node == null)
    85         continue;
    86       ntn.node.setDeleted(false);
    87       Main.main.getCurrentDataSet().addPrimitive(ntn.node);
     84    @Override
     85    public void fillModifiedData(Collection<OsmPrimitive> modified,
     86            Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
    8887    }
    89   }
    9088
    91   public void fillModifiedData
    92     (Collection< OsmPrimitive > modified, Collection< OsmPrimitive > deleted,
    93      Collection< OsmPrimitive > added)
    94   {
    95   }
    96 
    97   @Override public String getDescriptionText()
    98   {
    99     return tr("Public Transport: Delete track stop");
    100   }
     89    @Override
     90    public String getDescriptionText() {
     91        return tr("Public Transport: Delete track stop");
     92    }
    10193};
  • applications/editors/josm/plugins/public_transport/src/public_transport/TrackStoplistDetachCommand.java

    r29854 r32357  
    1010import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1111
    12 public class TrackStoplistDetachCommand extends Command
    13 {
    14   private Vector< Integer > workingLines = null;
    15   private Vector< Node > nodesForUndo = null;
    16   private TrackStoplistTableModel stoplistTM = null;
     12public class TrackStoplistDetachCommand extends Command {
     13    private Vector<Integer> workingLines = null;
    1714
    18   public TrackStoplistDetachCommand(StopImporterAction controller)
    19   {
    20     stoplistTM = controller.getCurrentTrack().stoplistTM;
    21     workingLines = new Vector< Integer >();
    22     nodesForUndo = new Vector< Node >();
     15    private Vector<Node> nodesForUndo = null;
    2316
    24     // use either selected lines or all lines if no line is selected
    25     int[] selectedLines = controller.getDialog().getStoplistTable().getSelectedRows();
    26     Vector< Integer > consideredLines = new Vector< Integer >();
    27     if (selectedLines.length > 0)
    28     {
    29       for (int i = 0; i < selectedLines.length; ++i)
    30         consideredLines.add(selectedLines[i]);
    31     }
    32     else
    33     {
    34       for (int i = 0; i < stoplistTM.getRowCount(); ++i)
    35         consideredLines.add(new Integer(i));
     17    private TrackStoplistTableModel stoplistTM = null;
     18
     19    public TrackStoplistDetachCommand(StopImporterAction controller) {
     20        stoplistTM = controller.getCurrentTrack().stoplistTM;
     21        workingLines = new Vector<>();
     22        nodesForUndo = new Vector<>();
     23
     24        // use either selected lines or all lines if no line is selected
     25        int[] selectedLines = controller.getDialog().getStoplistTable().getSelectedRows();
     26        Vector<Integer> consideredLines = new Vector<>();
     27        if (selectedLines.length > 0) {
     28            for (int i = 0; i < selectedLines.length; ++i)
     29                consideredLines.add(selectedLines[i]);
     30        } else {
     31            for (int i = 0; i < stoplistTM.getRowCount(); ++i)
     32                consideredLines.add(new Integer(i));
     33        }
     34
     35        // keep only lines where a node can be added
     36        for (int i = 0; i < consideredLines.size(); ++i) {
     37            if (stoplistTM.nodeAt(consideredLines.elementAt(i)) != null)
     38                workingLines.add(consideredLines.elementAt(i));
     39        }
    3640    }
    3741
    38     // keep only lines where a node can be added
    39     for (int i = 0; i < consideredLines.size(); ++i)
    40     {
    41       if (stoplistTM.nodeAt(consideredLines.elementAt(i)) != null)
    42         workingLines.add(consideredLines.elementAt(i));
     42    @Override
     43    public boolean executeCommand() {
     44        nodesForUndo.clear();
     45        for (int i = 0; i < workingLines.size(); ++i) {
     46            int j = workingLines.elementAt(i).intValue();
     47            Node node = stoplistTM.nodeAt(j);
     48            nodesForUndo.add(node);
     49            stoplistTM.setNodeAt(j, null);
     50        }
     51        return true;
    4352    }
    44   }
    4553
    46   public boolean executeCommand()
    47   {
    48     nodesForUndo.clear();
    49     for (int i = 0; i < workingLines.size(); ++i)
    50     {
    51       int j = workingLines.elementAt(i).intValue();
    52       Node node = stoplistTM.nodeAt(j);
    53       nodesForUndo.add(node);
    54       stoplistTM.setNodeAt(j, null);
     54    @Override
     55    public void undoCommand() {
     56        for (int i = 0; i < workingLines.size(); ++i) {
     57            int j = workingLines.elementAt(i).intValue();
     58            Node node = nodesForUndo.elementAt(i);
     59            stoplistTM.setNodeAt(j, node);
     60        }
    5561    }
    56     return true;
    57   }
    5862
    59   public void undoCommand()
    60   {
    61     for (int i = 0; i < workingLines.size(); ++i)
    62     {
    63       int j = workingLines.elementAt(i).intValue();
    64       Node node = nodesForUndo.elementAt(i);
    65       stoplistTM.setNodeAt(j, node);
     63    @Override
     64    public void fillModifiedData(Collection<OsmPrimitive> modified,
     65            Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
    6666    }
    67   }
    6867
    69   public void fillModifiedData
    70     (Collection< OsmPrimitive > modified, Collection< OsmPrimitive > deleted,
    71      Collection< OsmPrimitive > added)
    72   {
    73   }
    74 
    75   @Override public String getDescriptionText()
    76   {
    77     return tr("Public Transport: Detach track stop list");
    78   }
    79 };
     68    @Override
     69    public String getDescriptionText() {
     70        return tr("Public Transport: Detach track stop list");
     71    }
     72}
  • applications/editors/josm/plugins/public_transport/src/public_transport/TrackStoplistNameCommand.java

    r30358 r32357  
    1212public class TrackStoplistNameCommand extends Command {
    1313    private int workingLine = 0;
     14
    1415    private TrackReference trackref = null;
     16
    1517    private String oldName = null;
     18
    1619    private String name = null;
     20
    1721    private String oldTime = null;
     22
    1823    private String time = null;
     24
    1925    private String oldShelter = null;
     26
    2027    private TransText shelter = null;
     28
    2129    private LatLon oldLatLon = null;
    2230
     
    3846    }
    3947
     48    @Override
    4049    public boolean executeCommand() {
    4150        Node node = trackref.stoplistTM.nodeAt(workingLine);
     
    6069    }
    6170
     71    @Override
    6272    public void undoCommand() {
    6373        Node node = trackref.stoplistTM.nodeAt(workingLine);
     
    8090    }
    8191
    82     public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted,
    83             Collection<OsmPrimitive> added) {
     92    @Override
     93    public void fillModifiedData(Collection<OsmPrimitive> modified,
     94            Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
    8495    }
    8596
     
    8899        return tr("Public Transport: Edit track stop list");
    89100    }
    90 };
     101}
  • applications/editors/josm/plugins/public_transport/src/public_transport/TrackStoplistRelocateCommand.java

    r29854 r32357  
    99import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1010
    11 public class TrackStoplistRelocateCommand extends Command
    12 {
    13   private StopImporterAction controller = null;
    14   private TrackReference currentTrack = null;
    15   private String oldGpsSyncTime = null;
    16   private String oldStopwatchStart = null;
    17   private String gpsSyncTime = null;
    18   private String stopwatchStart = null;
     11public class TrackStoplistRelocateCommand extends Command {
     12    private StopImporterAction controller = null;
    1913
    20   public TrackStoplistRelocateCommand(StopImporterAction controller)
    21   {
    22     this.controller = controller;
    23     this.currentTrack = controller.getCurrentTrack();
    24     this.gpsSyncTime = controller.getDialog().getGpsTimeStart();
    25     this.stopwatchStart = controller.getDialog().getStopwatchStart();
    26     this.oldGpsSyncTime = currentTrack.gpsSyncTime;
    27     this.oldStopwatchStart = currentTrack.stopwatchStart;
    28   }
     14    private TrackReference currentTrack = null;
    2915
    30   public boolean executeCommand()
    31   {
    32     currentTrack.gpsSyncTime = gpsSyncTime;
    33     currentTrack.stopwatchStart = stopwatchStart;
    34     for (int i = 0; i < currentTrack.stoplistTM.getNodes().size(); ++i)
    35     {
    36       Node node = currentTrack.stoplistTM.nodeAt(i);
    37       if (node == null)
    38     continue;
     16    private String oldGpsSyncTime = null;
    3917
    40       double time = StopImporterDialog.parseTime
    41         ((String)currentTrack.stoplistTM.getValueAt(i, 0));
    42       node.setCoor(currentTrack.computeCoor(time));
    43     }
    44     if (currentTrack == controller.getCurrentTrack())
    45     {
    46       controller.inEvent = true;
    47       controller.getDialog().setGpsTimeStart(gpsSyncTime);
    48       controller.getDialog().setStopwatchStart(stopwatchStart);
    49       controller.inEvent = false;
     18    private String oldStopwatchStart = null;
     19
     20    private String gpsSyncTime = null;
     21
     22    private String stopwatchStart = null;
     23
     24    public TrackStoplistRelocateCommand(StopImporterAction controller) {
     25        this.controller = controller;
     26        this.currentTrack = controller.getCurrentTrack();
     27        this.gpsSyncTime = controller.getDialog().getGpsTimeStart();
     28        this.stopwatchStart = controller.getDialog().getStopwatchStart();
     29        this.oldGpsSyncTime = currentTrack.gpsSyncTime;
     30        this.oldStopwatchStart = currentTrack.stopwatchStart;
    5031    }
    5132
    52     return true;
    53   }
     33    @Override
     34    public boolean executeCommand() {
     35        currentTrack.gpsSyncTime = gpsSyncTime;
     36        currentTrack.stopwatchStart = stopwatchStart;
     37        for (int i = 0; i < currentTrack.stoplistTM.getNodes().size(); ++i) {
     38            Node node = currentTrack.stoplistTM.nodeAt(i);
     39            if (node == null)
     40                continue;
    5441
    55   public void undoCommand()
    56   {
    57     currentTrack.gpsSyncTime = oldGpsSyncTime;
    58     currentTrack.stopwatchStart = oldStopwatchStart;
    59     for (int i = 0; i < currentTrack.stoplistTM.getNodes().size(); ++i)
    60     {
    61       Node node = currentTrack.stoplistTM.nodeAt(i);
    62       if (node == null)
    63     continue;
     42            double time = StopImporterDialog
     43                    .parseTime((String) currentTrack.stoplistTM.getValueAt(i, 0));
     44            node.setCoor(currentTrack.computeCoor(time));
     45        }
     46        if (currentTrack == controller.getCurrentTrack()) {
     47            controller.inEvent = true;
     48            controller.getDialog().setGpsTimeStart(gpsSyncTime);
     49            controller.getDialog().setStopwatchStart(stopwatchStart);
     50            controller.inEvent = false;
     51        }
    6452
    65       double time = StopImporterDialog.parseTime
    66         ((String)currentTrack.stoplistTM.getValueAt(i, 0));
    67       node.setCoor(currentTrack.computeCoor(time));
     53        return true;
    6854    }
    69     if (currentTrack == controller.getCurrentTrack())
    70     {
    71       controller.inEvent = true;
    72       controller.getDialog().setGpsTimeStart(oldGpsSyncTime);
    73       controller.getDialog().setStopwatchStart(oldStopwatchStart);
    74       controller.inEvent = false;
     55
     56    @Override
     57    public void undoCommand() {
     58        currentTrack.gpsSyncTime = oldGpsSyncTime;
     59        currentTrack.stopwatchStart = oldStopwatchStart;
     60        for (int i = 0; i < currentTrack.stoplistTM.getNodes().size(); ++i) {
     61            Node node = currentTrack.stoplistTM.nodeAt(i);
     62            if (node == null)
     63                continue;
     64
     65            double time = StopImporterDialog
     66                    .parseTime((String) currentTrack.stoplistTM.getValueAt(i, 0));
     67            node.setCoor(currentTrack.computeCoor(time));
     68        }
     69        if (currentTrack == controller.getCurrentTrack()) {
     70            controller.inEvent = true;
     71            controller.getDialog().setGpsTimeStart(oldGpsSyncTime);
     72            controller.getDialog().setStopwatchStart(oldStopwatchStart);
     73            controller.inEvent = false;
     74        }
    7575    }
    76   }
    7776
    78   public void fillModifiedData
    79     (Collection< OsmPrimitive > modified, Collection< OsmPrimitive > deleted,
    80      Collection< OsmPrimitive > added)
    81   {
    82   }
     77    @Override
     78    public void fillModifiedData(Collection<OsmPrimitive> modified,
     79            Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
     80    }
    8381
    84   @Override public String getDescriptionText()
    85   {
    86     return tr("Public Transport: Relocate nodes in track stoplist");
    87   }
    88 };
     82    @Override
     83    public String getDescriptionText() {
     84        return tr("Public Transport: Relocate nodes in track stoplist");
     85    }
     86}
  • applications/editors/josm/plugins/public_transport/src/public_transport/TrackStoplistSortCommand.java

    r29854 r32357  
    1212import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1313
    14 public class TrackStoplistSortCommand extends Command
    15 {
    16   private TrackStoplistTableModel stoplistTM = null;
    17   private Vector< Vector< Object > > tableDataModel = null;
    18   private Vector< Node > nodes = null;
    19   private Vector< String > times = null;
    20   private Vector< Integer > workingLines = null;
    21   private int insPos;
    22   private String stopwatchStart;
     14public class TrackStoplistSortCommand extends Command {
     15    private TrackStoplistTableModel stoplistTM = null;
    2316
    24   public TrackStoplistSortCommand(StopImporterAction controller)
    25   {
    26     stoplistTM = controller.getCurrentTrack().stoplistTM;
    27     workingLines = new Vector< Integer >();
    28     insPos = controller.getDialog().getStoplistTable().getSelectedRow();
    29     stopwatchStart = controller.getCurrentTrack().stopwatchStart;
     17    private Vector<Vector<Object>> tableDataModel = null;
    3018
    31     // use either selected lines or all lines if no line is selected
    32     int[] selectedLines = controller.getDialog().getStoplistTable().getSelectedRows();
    33     if (selectedLines.length > 0)
    34     {
    35       for (int i = 0; i < selectedLines.length; ++i)
    36         workingLines.add(selectedLines[i]);
    37     }
    38     else
    39     {
    40       for (int i = 0; i < stoplistTM.getRowCount(); ++i)
    41         workingLines.add(new Integer(i));
    42     }
    43   }
     19    private Vector<Node> nodes = null;
    4420
    45   @SuppressWarnings("unchecked")
    46   public boolean executeCommand()
    47   {
    48     tableDataModel = (Vector< Vector< Object > >)stoplistTM.getDataVector()
    49     .clone();
    50     nodes = (Vector< Node >)stoplistTM.getNodes().clone();
    51     times = (Vector< String >)stoplistTM.getTimes().clone();
     21    private Vector<String> times = null;
    5222
    53     Vector< NodeSortEntry > nodesToSort = new Vector< NodeSortEntry >();
    54     for (int i = workingLines.size()-1; i >= 0; --i)
    55     {
    56       int j = workingLines.elementAt(i).intValue();
    57       nodesToSort.add(new NodeSortEntry
    58       (stoplistTM.nodeAt(j), (String)stoplistTM.getValueAt(j, 0),
    59         (String)stoplistTM.getValueAt(j, 1),
    60         (TransText)stoplistTM.getValueAt(j, 2),
    61          StopImporterDialog.parseTime(stopwatchStart)));
    62       stoplistTM.removeRow(j);
     23    private Vector<Integer> workingLines = null;
     24
     25    private int insPos;
     26
     27    private String stopwatchStart;
     28
     29    public TrackStoplistSortCommand(StopImporterAction controller) {
     30        stoplistTM = controller.getCurrentTrack().stoplistTM;
     31        workingLines = new Vector<>();
     32        insPos = controller.getDialog().getStoplistTable().getSelectedRow();
     33        stopwatchStart = controller.getCurrentTrack().stopwatchStart;
     34
     35        // use either selected lines or all lines if no line is selected
     36        int[] selectedLines = controller.getDialog().getStoplistTable().getSelectedRows();
     37        if (selectedLines.length > 0) {
     38            for (int i = 0; i < selectedLines.length; ++i)
     39                workingLines.add(selectedLines[i]);
     40        } else {
     41            for (int i = 0; i < stoplistTM.getRowCount(); ++i)
     42                workingLines.add(new Integer(i));
     43        }
    6344    }
    6445
    65     Collections.sort(nodesToSort);
     46    @Override
     47    @SuppressWarnings("unchecked")
     48    public boolean executeCommand() {
     49        tableDataModel = (Vector<Vector<Object>>) stoplistTM.getDataVector().clone();
     50        nodes = (Vector<Node>) stoplistTM.getNodes().clone();
     51        times = (Vector<String>) stoplistTM.getTimes().clone();
    6652
    67     int insPos = this.insPos;
    68     Iterator< NodeSortEntry > iter = nodesToSort.iterator();
    69     while (iter.hasNext())
    70     {
    71       NodeSortEntry nse = iter.next();
    72       stoplistTM.insertRow(insPos, nse.node, nse.time, nse.name, nse.shelter);
    73       if (insPos >= 0)
    74         ++insPos;
    75     }
    76     return true;
    77   }
     53        Vector<NodeSortEntry> nodesToSort = new Vector<>();
     54        for (int i = workingLines.size() - 1; i >= 0; --i) {
     55            int j = workingLines.elementAt(i).intValue();
     56            nodesToSort.add(new NodeSortEntry(stoplistTM.nodeAt(j),
     57                    (String) stoplistTM.getValueAt(j, 0), (String) stoplistTM.getValueAt(j, 1),
     58                    (TransText) stoplistTM.getValueAt(j, 2),
     59                    StopImporterDialog.parseTime(stopwatchStart)));
     60            stoplistTM.removeRow(j);
     61        }
    7862
    79   public void undoCommand()
    80   {
    81     stoplistTM.setDataVector(tableDataModel);
    82     stoplistTM.setNodes(nodes);
    83     stoplistTM.setTimes(times);
    84   }
     63        Collections.sort(nodesToSort);
    8564
    86   public void fillModifiedData
    87     (Collection< OsmPrimitive > modified, Collection< OsmPrimitive > deleted,
    88      Collection< OsmPrimitive > added)
    89   {
    90   }
    91 
    92   @Override public String getDescriptionText()
    93   {
    94     return tr("Public Transport: sort track stop list");
    95   }
    96 
    97   private class NodeSortEntry implements Comparable< NodeSortEntry >
    98   {
    99     public Node node = null;
    100     public String time = null;
    101     public String name = null;
    102     public TransText shelter = null;
    103     public double startTime = 0;
    104 
    105     public NodeSortEntry
    106         (Node node, String time, String name, TransText shelter, double startTime)
    107     {
    108       this.node = node;
    109       this.time = time;
    110       this.name = name;
    111       this.shelter = shelter;
     65        int insPos = this.insPos;
     66        Iterator<NodeSortEntry> iter = nodesToSort.iterator();
     67        while (iter.hasNext()) {
     68            NodeSortEntry nse = iter.next();
     69            stoplistTM.insertRow(insPos, nse.node, nse.time, nse.name, nse.shelter);
     70            if (insPos >= 0)
     71                ++insPos;
     72        }
     73        return true;
    11274    }
    11375
    114     public int compareTo(NodeSortEntry nse)
    115     {
    116       double time = StopImporterDialog.parseTime(this.time);
    117       if (time - startTime > 12*60*60)
    118         time -= 24*60*60;
     76    @Override
     77    public void undoCommand() {
     78        stoplistTM.setDataVector(tableDataModel);
     79        stoplistTM.setNodes(nodes);
     80        stoplistTM.setTimes(times);
     81    }
    11982
    120       double nseTime = StopImporterDialog.parseTime(nse.time);
    121       if (nseTime - startTime > 12*60*60)
    122         nseTime -= 24*60*60;
     83    @Override
     84    public void fillModifiedData(Collection<OsmPrimitive> modified,
     85            Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
     86    }
    12387
    124       if (time < nseTime)
    125         return -1;
    126       else if (time > nseTime)
    127         return 1;
    128       else
    129         return 0;
     88    @Override
     89    public String getDescriptionText() {
     90        return tr("Public Transport: sort track stop list");
    13091    }
    131   };
    132 };
     92
     93    private class NodeSortEntry implements Comparable<NodeSortEntry> {
     94        public Node node = null;
     95
     96        public String time = null;
     97
     98        public String name = null;
     99
     100        public TransText shelter = null;
     101
     102        public double startTime = 0;
     103
     104        public NodeSortEntry(Node node, String time, String name, TransText shelter,
     105                double startTime) {
     106            this.node = node;
     107            this.time = time;
     108            this.name = name;
     109            this.shelter = shelter;
     110        }
     111
     112        @Override
     113        public int compareTo(NodeSortEntry nse) {
     114            double time = StopImporterDialog.parseTime(this.time);
     115            if (time - startTime > 12 * 60 * 60)
     116                time -= 24 * 60 * 60;
     117
     118            double nseTime = StopImporterDialog.parseTime(nse.time);
     119            if (nseTime - startTime > 12 * 60 * 60)
     120                nseTime -= 24 * 60 * 60;
     121
     122            if (time < nseTime)
     123                return -1;
     124            else if (time > nseTime)
     125                return 1;
     126            else
     127                return 0;
     128        }
     129    }
     130}
  • applications/editors/josm/plugins/public_transport/src/public_transport/TrackStoplistTableModel.java

    r29854 r32357  
    99import org.openstreetmap.josm.data.osm.Node;
    1010
    11 public class TrackStoplistTableModel extends DefaultTableModel
    12 {
    13   private Vector< Node > nodes = null;
    14   private Vector< String > times = null;
    15   private static Vector< String > columns = null;
     11public class TrackStoplistTableModel extends DefaultTableModel {
     12    private Vector<Node> nodes = null;
    1613
    17   public TrackStoplistTableModel(TrackReference tr)
    18   {
    19     if (columns == null)
    20     {
    21       columns = new Vector< String >();
    22       columns.add(tr("Time"));
    23       columns.add(tr("Name"));
    24       columns.add(tr("Shelter"));
     14    private Vector<String> times = null;
     15
     16    private static Vector<String> columns = null;
     17
     18    public TrackStoplistTableModel(TrackReference tr) {
     19        if (columns == null) {
     20            columns = new Vector<>();
     21            columns.add(tr("Time"));
     22            columns.add(tr("Name"));
     23            columns.add(tr("Shelter"));
     24        }
     25        nodes = new Vector<>();
     26        times = new Vector<>();
     27
     28        setColumnIdentifiers(columns);
     29        addTableModelListener(tr);
    2530    }
    26     nodes = new Vector< Node >();
    27     times = new Vector< String >();
    2831
    29     setColumnIdentifiers(columns);
    30     addTableModelListener(tr);
    31   }
     32    @Override
     33    public boolean isCellEditable(int row, int column) {
     34        return true;
     35    }
    3236
    33   public boolean isCellEditable(int row, int column) {
    34     return true;
    35   }
     37    @Override
     38    public void addRow(Object[] obj) {
     39        throw new UnsupportedOperationException();
     40    }
    3641
    37   public void addRow(Object[] obj) {
    38     throw new UnsupportedOperationException();
    39   }
     42    @Override
     43    public void insertRow(int insPos, Object[] obj) {
     44        throw new UnsupportedOperationException();
     45    }
    4046
    41   public void insertRow(int insPos, Object[] obj) {
    42     throw new UnsupportedOperationException();
    43   }
     47    public void addRow(String time) {
     48        insertRow(-1, time);
     49    }
    4450
    45   public void addRow(String time) {
    46     insertRow(-1, time);
    47   }
     51    public void insertRow(int insPos, String time) {
     52        insertRow(insPos, null, time, "", new TransText(null));
     53    }
    4854
    49   public void insertRow(int insPos, String time)
    50   {
    51     insertRow(insPos, null, time, "", new TransText(null));
    52   }
     55    @Override
     56    public void removeRow(int pos) {
     57        super.removeRow(pos);
     58        nodes.removeElementAt(pos);
     59        times.removeElementAt(pos);
     60    }
    5361
    54   public void removeRow(int pos)
    55   {
    56     super.removeRow(pos);
    57     nodes.removeElementAt(pos);
    58     times.removeElementAt(pos);
    59   }
     62    public Node nodeAt(int i) {
     63        return nodes.elementAt(i);
     64    }
    6065
    61   public Node nodeAt(int i)
    62   {
    63     return nodes.elementAt(i);
    64   }
     66    public void setNodeAt(int i, Node node) {
     67        nodes.set(i, node);
     68    }
    6569
    66   public void setNodeAt(int i, Node node)
    67   {
    68     nodes.set(i, node);
    69   }
     70    public final Vector<Node> getNodes() {
     71        return nodes;
     72    }
    7073
    71   public final Vector< Node > getNodes()
    72   {
    73     return nodes;
    74   }
     74    public void setNodes(Vector<Node> nodes) {
     75        this.nodes = nodes;
     76    }
    7577
    76   public void setNodes(Vector< Node > nodes)
    77   {
    78     this.nodes = nodes;
    79   }
     78    public String timeAt(int i) {
     79        return times.elementAt(i);
     80    }
    8081
    81   public String timeAt(int i)
    82   {
    83     return times.elementAt(i);
    84   }
     82    public void setTimeAt(int i, String time) {
     83        times.set(i, time);
     84    }
    8585
    86   public void setTimeAt(int i, String time)
    87   {
    88     times.set(i, time);
    89   }
     86    public final Vector<String> getTimes() {
     87        return times;
     88    }
    9089
    91   public final Vector< String > getTimes()
    92   {
    93     return times;
    94   }
     90    public void setTimes(Vector<String> times) {
     91        this.times = times;
     92    }
    9593
    96   public void setTimes(Vector< String > times)
    97   {
    98     this.times = times;
    99   }
     94    public void insertRow(int insPos, Node node, String time, String name, TransText shelter) {
     95        Object[] buf = { time, name, shelter };
     96        if (insPos == -1) {
     97            nodes.addElement(node);
     98            times.addElement(time);
     99            super.addRow(buf);
     100        } else {
     101            nodes.insertElementAt(node, insPos);
     102            times.insertElementAt(time, insPos);
     103            super.insertRow(insPos, buf);
     104        }
     105    }
    100106
    101   public void insertRow
    102       (int insPos, Node node, String time, String name, TransText shelter)
    103   {
    104     Object[] buf = { time, name, shelter };
    105     if (insPos == -1)
    106     {
    107       nodes.addElement(node);
    108       times.addElement(time);
    109       super.addRow(buf);
     107    public void clear() {
     108        nodes.clear();
     109        times.clear();
     110        super.setRowCount(0);
    110111    }
    111     else
    112     {
    113       nodes.insertElementAt(node, insPos);
    114       times.insertElementAt(time, insPos);
    115       super.insertRow(insPos, buf);
     112
     113    public void setDataVector(Vector<Vector<Object>> dataVector) {
     114        setDataVector(dataVector, columns);
    116115    }
    117   }
    118 
    119   public void clear()
    120   {
    121     nodes.clear();
    122     times.clear();
    123     super.setRowCount(0);
    124   }
    125 
    126   public void setDataVector(Vector< Vector< Object > > dataVector)
    127   {
    128     setDataVector(dataVector, columns);
    129   }
    130 };
     116}
  • applications/editors/josm/plugins/public_transport/src/public_transport/TrackSuggestStopsCommand.java

    r29854 r32357  
    1515import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1616
    17 public class TrackSuggestStopsCommand extends Command
    18 {
    19   private TrackStoplistTableModel stoplistTM = null;
    20   private String type = null;
    21   private String stopwatchStart;
    22   private String gpsStartTime;
    23   private String gpsSyncTime;
    24   private double timeWindow;
    25   private double threshold;
    26   private Collection< GpxTrackSegment > segments = null;
    27   private Vector< Vector< Object > > tableDataModel = null;
    28   private Vector< Node > nodes = null;
    29   private Vector< String > times = null;
    30 
    31   public TrackSuggestStopsCommand(StopImporterAction controller)
    32   {
    33     if (controller.getCurrentTrack() == null)
    34       return;
    35     stoplistTM = controller.getCurrentTrack().stoplistTM;
    36     type = controller.getDialog().getStoptype();
    37     stopwatchStart = controller.getCurrentTrack().stopwatchStart;
    38     gpsStartTime = controller.getCurrentTrack().gpsStartTime;
    39     gpsSyncTime = controller.getCurrentTrack().gpsSyncTime;
    40     timeWindow = controller.getCurrentTrack().timeWindow;
    41     threshold = controller.getCurrentTrack().threshold;
    42     segments = controller.getCurrentTrack().getGpxTrack().getSegments();
    43   }
    44 
    45   @SuppressWarnings("unchecked")
    46   public boolean executeCommand()
    47   {
    48     if (stoplistTM == null)
    49       return false;
    50     tableDataModel = (Vector< Vector< Object > >)stoplistTM.getDataVector()
    51     .clone();
    52     nodes = (Vector< Node >)stoplistTM.getNodes().clone();
    53     times = (Vector< String >)stoplistTM.getTimes().clone();
    54 
    55     for (int i = 0; i < stoplistTM.getNodes().size(); ++i)
    56     {
    57       Node node = stoplistTM.nodeAt(i);
    58       if (node == null)
    59         continue;
    60       Main.main.getCurrentDataSet().removePrimitive(node);
    61       node.setDeleted(true);
    62     }
    63     stoplistTM.clear();
    64 
    65     Vector< WayPoint > wayPoints = new Vector< WayPoint >();
    66     Iterator< GpxTrackSegment > siter = segments.iterator();
    67     while (siter.hasNext())
    68     {
    69       Iterator< WayPoint > witer = siter.next().getWayPoints().iterator();
    70       while (witer.hasNext())
    71         wayPoints.add(witer.next());
    72     }
    73     Vector< Double > wayPointsDist = new Vector< Double >(wayPoints.size());
    74 
    75     int i = 0;
    76     double time = -48*60*60;
    77     double dGpsStartTime = StopImporterDialog.parseTime(gpsStartTime);
    78     while ((i < wayPoints.size()) && (time < dGpsStartTime + timeWindow/2))
    79     {
    80       if (wayPoints.elementAt(i).getString("time") != null)
    81         time = StopImporterDialog.parseTime(wayPoints.elementAt(i)
    82             .getString("time").substring(11,19));
    83       if (time < dGpsStartTime)
    84         time += 24*60*60;
    85       wayPointsDist.add(Double.valueOf(Double.POSITIVE_INFINITY));
    86       ++i;
    87     }
    88     while (i < wayPoints.size())
    89     {
    90       int j = i;
    91       double time2 = time;
    92       while ((j > 0) && (time - timeWindow/2 < time2))
    93       {
    94         --j;
    95         if (wayPoints.elementAt(j).getString("time") != null)
    96           time2 = StopImporterDialog.parseTime(wayPoints.elementAt(j)
    97               .getString("time").substring(11,19));
    98         if (time2 < dGpsStartTime)
    99           time2 += 24*60*60;
    100       }
    101       int k = i + 1;
    102       time2 = time;
    103       while ((k < wayPoints.size()) && (time + timeWindow/2 > time2))
    104       {
    105         if (wayPoints.elementAt(k).getString("time") != null)
    106           time2 = StopImporterDialog.parseTime(wayPoints.elementAt(k)
    107               .getString("time").substring(11,19));
    108         if (time2 < dGpsStartTime)
    109           time2 += 24*60*60;
    110         ++k;
    111       }
    112 
    113       if (j < k)
    114       {
    115         double dist = 0;
    116         LatLon latLonI = wayPoints.elementAt(i).getCoor();
    117         for (int l = j; l < k; ++l)
    118         {
    119           double distL = latLonI.greatCircleDistance(wayPoints.elementAt(l).getCoor());
    120           if (distL > dist)
    121             dist = distL;
    122         }
    123         wayPointsDist.add(Double.valueOf(dist));
    124       }
    125       else
    126         wayPointsDist.add(Double.valueOf(Double.POSITIVE_INFINITY));
    127 
    128       if (wayPoints.elementAt(i).getString("time") != null)
    129         time = StopImporterDialog.parseTime(wayPoints.elementAt(i)
    130             .getString("time").substring(11,19));
    131       if (time < dGpsStartTime)
    132         time += 24*60*60;
    133       ++i;
    134     }
    135 
    136     LatLon lastStopCoor = null;
    137     for (i = 1; i < wayPoints.size()-1; ++i)
    138     {
    139       if (wayPointsDist.elementAt(i).doubleValue() >= threshold)
    140         continue;
    141       if ((wayPointsDist.elementAt(i).compareTo(wayPointsDist.elementAt(i-1)) != -1)
    142        || (wayPointsDist.elementAt(i).compareTo(wayPointsDist.elementAt(i+1)) != -1))
    143         continue;
    144 
    145       LatLon latLon = wayPoints.elementAt(i).getCoor();
    146       if ((lastStopCoor != null) &&  (lastStopCoor.greatCircleDistance(latLon) < threshold))
    147         continue;
    148 
    149       if (wayPoints.elementAt(i).getString("time") != null)
    150       {
    151         time = StopImporterDialog.parseTime(wayPoints.elementAt(i)
    152             .getString("time").substring(11,19));
    153         double gpsSyncTime = StopImporterDialog.parseTime(this.gpsSyncTime);
    154         if (gpsSyncTime < dGpsStartTime - 12*60*60)
    155           gpsSyncTime += 24*60*60;
    156         double timeDelta = gpsSyncTime - StopImporterDialog.parseTime(stopwatchStart);
    157         time -= timeDelta;
    158         Node node = StopImporterAction.createNode(latLon, type, "");
    159         stoplistTM.insertRow(-1, node, StopImporterAction.timeOf(time), "", new TransText(null));
    160       }
    161 
    162       lastStopCoor = latLon;
    163     }
    164 
    165     return true;
    166   }
    167 
    168   public void undoCommand()
    169   {
    170     if (stoplistTM == null)
    171       return;
    172     for (int i = 0; i < stoplistTM.getNodes().size(); ++i)
    173     {
    174       Node node = stoplistTM.nodeAt(i);
    175       if (node == null)
    176         continue;
    177       Main.main.getCurrentDataSet().removePrimitive(node);
    178       node.setDeleted(true);
    179     }
    180 
    181     stoplistTM.setDataVector(tableDataModel);
    182     stoplistTM.setNodes(nodes);
    183     stoplistTM.setTimes(times);
    184 
    185     for (int i = 0; i < stoplistTM.getNodes().size(); ++i)
    186     {
    187       Node node = stoplistTM.nodeAt(i);
    188       if (node == null)
    189         continue;
    190       node.setDeleted(false);
    191       Main.main.getCurrentDataSet().addPrimitive(node);
    192     }
    193   }
    194 
    195   public void fillModifiedData
    196     (Collection< OsmPrimitive > modified, Collection< OsmPrimitive > deleted,
    197      Collection< OsmPrimitive > added)
    198   {
    199   }
    200 
    201   @Override public String getDescriptionText()
    202   {
    203     return tr("Public Transport: Suggest stops");
    204   }
    205 
    206   private class NodeSortEntry implements Comparable< NodeSortEntry >
    207   {
    208     public Node node = null;
    209     public String time = null;
    210     public String name = null;
    211     public double startTime = 0;
    212 
    213     public NodeSortEntry(Node node, String time, String name, double startTime)
    214     {
    215       this.node = node;
    216       this.time = time;
    217       this.name = name;
    218     }
    219 
    220     public int compareTo(NodeSortEntry nse)
    221     {
    222       double time = StopImporterDialog.parseTime(this.time);
    223       if (time - startTime > 12*60*60)
    224         time -= 24*60*60;
    225 
    226       double nseTime = StopImporterDialog.parseTime(nse.time);
    227       if (nseTime - startTime > 12*60*60)
    228         nseTime -= 24*60*60;
    229 
    230       if (time < nseTime)
    231         return -1;
    232       else if (time > nseTime)
    233         return 1;
    234       else
    235         return 0;
    236     }
    237   };
    238 };
     17public class TrackSuggestStopsCommand extends Command {
     18    private TrackStoplistTableModel stoplistTM = null;
     19
     20    private String type = null;
     21
     22    private String stopwatchStart;
     23
     24    private String gpsStartTime;
     25
     26    private String gpsSyncTime;
     27
     28    private double timeWindow;
     29
     30    private double threshold;
     31
     32    private Collection<GpxTrackSegment> segments = null;
     33
     34    private Vector<Vector<Object>> tableDataModel = null;
     35
     36    private Vector<Node> nodes = null;
     37
     38    private Vector<String> times = null;
     39
     40    public TrackSuggestStopsCommand(StopImporterAction controller) {
     41        if (controller.getCurrentTrack() == null)
     42            return;
     43        stoplistTM = controller.getCurrentTrack().stoplistTM;
     44        type = controller.getDialog().getStoptype();
     45        stopwatchStart = controller.getCurrentTrack().stopwatchStart;
     46        gpsStartTime = controller.getCurrentTrack().gpsStartTime;
     47        gpsSyncTime = controller.getCurrentTrack().gpsSyncTime;
     48        timeWindow = controller.getCurrentTrack().timeWindow;
     49        threshold = controller.getCurrentTrack().threshold;
     50        segments = controller.getCurrentTrack().getGpxTrack().getSegments();
     51    }
     52
     53    @Override
     54    @SuppressWarnings("unchecked")
     55    public boolean executeCommand() {
     56        if (stoplistTM == null)
     57            return false;
     58        tableDataModel = (Vector<Vector<Object>>) stoplistTM.getDataVector().clone();
     59        nodes = (Vector<Node>) stoplistTM.getNodes().clone();
     60        times = (Vector<String>) stoplistTM.getTimes().clone();
     61
     62        for (int i = 0; i < stoplistTM.getNodes().size(); ++i) {
     63            Node node = stoplistTM.nodeAt(i);
     64            if (node == null)
     65                continue;
     66            Main.getLayerManager().getEditDataSet().removePrimitive(node);
     67            node.setDeleted(true);
     68        }
     69        stoplistTM.clear();
     70
     71        Vector<WayPoint> wayPoints = new Vector<>();
     72        Iterator<GpxTrackSegment> siter = segments.iterator();
     73        while (siter.hasNext()) {
     74            Iterator<WayPoint> witer = siter.next().getWayPoints().iterator();
     75            while (witer.hasNext())
     76                wayPoints.add(witer.next());
     77        }
     78        Vector<Double> wayPointsDist = new Vector<>(wayPoints.size());
     79
     80        int i = 0;
     81        double time = -48 * 60 * 60;
     82        double dGpsStartTime = StopImporterDialog.parseTime(gpsStartTime);
     83        while ((i < wayPoints.size()) && (time < dGpsStartTime + timeWindow / 2)) {
     84            if (wayPoints.elementAt(i).getString("time") != null)
     85                time = StopImporterDialog
     86                        .parseTime(wayPoints.elementAt(i).getString("time").substring(11, 19));
     87            if (time < dGpsStartTime)
     88                time += 24 * 60 * 60;
     89            wayPointsDist.add(Double.valueOf(Double.POSITIVE_INFINITY));
     90            ++i;
     91        }
     92        while (i < wayPoints.size()) {
     93            int j = i;
     94            double time2 = time;
     95            while ((j > 0) && (time - timeWindow / 2 < time2)) {
     96                --j;
     97                if (wayPoints.elementAt(j).getString("time") != null)
     98                    time2 = StopImporterDialog
     99                            .parseTime(wayPoints.elementAt(j).getString("time").substring(11, 19));
     100                if (time2 < dGpsStartTime)
     101                    time2 += 24 * 60 * 60;
     102            }
     103            int k = i + 1;
     104            time2 = time;
     105            while ((k < wayPoints.size()) && (time + timeWindow / 2 > time2)) {
     106                if (wayPoints.elementAt(k).getString("time") != null)
     107                    time2 = StopImporterDialog
     108                            .parseTime(wayPoints.elementAt(k).getString("time").substring(11, 19));
     109                if (time2 < dGpsStartTime)
     110                    time2 += 24 * 60 * 60;
     111                ++k;
     112            }
     113
     114            if (j < k) {
     115                double dist = 0;
     116                LatLon latLonI = wayPoints.elementAt(i).getCoor();
     117                for (int l = j; l < k; ++l) {
     118                    double distL = latLonI.greatCircleDistance(wayPoints.elementAt(l).getCoor());
     119                    if (distL > dist)
     120                        dist = distL;
     121                }
     122                wayPointsDist.add(Double.valueOf(dist));
     123            } else
     124                wayPointsDist.add(Double.valueOf(Double.POSITIVE_INFINITY));
     125
     126            if (wayPoints.elementAt(i).getString("time") != null)
     127                time = StopImporterDialog
     128                        .parseTime(wayPoints.elementAt(i).getString("time").substring(11, 19));
     129            if (time < dGpsStartTime)
     130                time += 24 * 60 * 60;
     131            ++i;
     132        }
     133
     134        LatLon lastStopCoor = null;
     135        for (i = 1; i < wayPoints.size() - 1; ++i) {
     136            if (wayPointsDist.elementAt(i).doubleValue() >= threshold)
     137                continue;
     138            if ((wayPointsDist.elementAt(i).compareTo(wayPointsDist.elementAt(i - 1)) != -1)
     139                    || (wayPointsDist.elementAt(i).compareTo(wayPointsDist.elementAt(i + 1)) != -1))
     140                continue;
     141
     142            LatLon latLon = wayPoints.elementAt(i).getCoor();
     143            if ((lastStopCoor != null) && (lastStopCoor.greatCircleDistance(latLon) < threshold))
     144                continue;
     145
     146            if (wayPoints.elementAt(i).getString("time") != null) {
     147                time = StopImporterDialog
     148                        .parseTime(wayPoints.elementAt(i).getString("time").substring(11, 19));
     149                double gpsSyncTime = StopImporterDialog.parseTime(this.gpsSyncTime);
     150                if (gpsSyncTime < dGpsStartTime - 12 * 60 * 60)
     151                    gpsSyncTime += 24 * 60 * 60;
     152                double timeDelta = gpsSyncTime - StopImporterDialog.parseTime(stopwatchStart);
     153                time -= timeDelta;
     154                Node node = StopImporterAction.createNode(latLon, type, "");
     155                stoplistTM.insertRow(-1, node, StopImporterAction.timeOf(time), "",
     156                        new TransText(null));
     157            }
     158
     159            lastStopCoor = latLon;
     160        }
     161
     162        return true;
     163    }
     164
     165    @Override
     166    public void undoCommand() {
     167        if (stoplistTM == null)
     168            return;
     169        for (int i = 0; i < stoplistTM.getNodes().size(); ++i) {
     170            Node node = stoplistTM.nodeAt(i);
     171            if (node == null)
     172                continue;
     173            Main.getLayerManager().getEditDataSet().removePrimitive(node);
     174            node.setDeleted(true);
     175        }
     176
     177        stoplistTM.setDataVector(tableDataModel);
     178        stoplistTM.setNodes(nodes);
     179        stoplistTM.setTimes(times);
     180
     181        for (int i = 0; i < stoplistTM.getNodes().size(); ++i) {
     182            Node node = stoplistTM.nodeAt(i);
     183            if (node == null)
     184                continue;
     185            node.setDeleted(false);
     186            Main.getLayerManager().getEditDataSet().addPrimitive(node);
     187        }
     188    }
     189
     190    @Override
     191    public void fillModifiedData(Collection<OsmPrimitive> modified,
     192            Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
     193    }
     194
     195    @Override
     196    public String getDescriptionText() {
     197        return tr("Public Transport: Suggest stops");
     198    }
     199/*
     200    private class NodeSortEntry implements Comparable<NodeSortEntry> {
     201        public Node node = null;
     202
     203        public String time = null;
     204
     205        public String name = null;
     206
     207        public double startTime = 0;
     208
     209        public NodeSortEntry(Node node, String time, String name, double startTime) {
     210            this.node = node;
     211            this.time = time;
     212            this.name = name;
     213        }
     214
     215        @Override
     216        public int compareTo(NodeSortEntry nse) {
     217            double time = StopImporterDialog.parseTime(this.time);
     218            if (time - startTime > 12 * 60 * 60)
     219                time -= 24 * 60 * 60;
     220
     221            double nseTime = StopImporterDialog.parseTime(nse.time);
     222            if (nseTime - startTime > 12 * 60 * 60)
     223                nseTime -= 24 * 60 * 60;
     224
     225            if (time < nseTime)
     226                return -1;
     227            else if (time > nseTime)
     228                return 1;
     229            else
     230                return 0;
     231        }
     232    }*/
     233}
  • applications/editors/josm/plugins/public_transport/src/public_transport/TransText.java

    r26168 r32357  
    33import static org.openstreetmap.josm.tools.I18n.tr;
    44
    5 public class TransText
    6 {
     5public class TransText {
    76    public String text;
    8     public TransText(String t)
    9     {
     7
     8    public TransText(String t) {
    109        text = t;
    1110    }
    12     public String toString()
    13     {
     11
     12    @Override
     13    public String toString() {
    1414        return text == null ? "" : tr(text);
    1515    }
  • applications/editors/josm/plugins/public_transport/src/public_transport/WaypointTableModel.java

    r29854 r32357  
    1414import org.openstreetmap.josm.data.osm.Node;
    1515
    16 public class WaypointTableModel extends DefaultTableModel
    17       implements TableModelListener
    18 {
    19   private StopImporterAction controller = null;
    20   public boolean inEvent = false;
    21   public Vector< Node > nodes = new Vector< Node >();
    22   public Vector< LatLon > coors = new Vector< LatLon >();
     16public class WaypointTableModel extends DefaultTableModel implements TableModelListener {
     17    private StopImporterAction controller = null;
    2318
    24   public WaypointTableModel(StopImporterAction controller)
    25   {
    26     this.controller = controller;
    27     addColumn(tr("Time"));
    28     addColumn(tr("Stopname"));
    29     addColumn(tr("Shelter"));
    30     addTableModelListener(this);
    31   }
     19    public boolean inEvent = false;
    3220
    33   public boolean isCellEditable(int row, int column)
    34   {
    35     if (column >= 1)
    36       return true;
    37     return false;
    38   }
     21    public Vector<Node> nodes = new Vector<>();
    3922
    40   public void addRow(Object[] obj)
    41   {
    42     throw new UnsupportedOperationException();
    43   }
     23    public Vector<LatLon> coors = new Vector<>();
    4424
    45   public void insertRow(int insPos, Object[] obj)
    46   {
    47     throw new UnsupportedOperationException();
    48   }
     25    public WaypointTableModel(StopImporterAction controller) {
     26        this.controller = controller;
     27        addColumn(tr("Time"));
     28        addColumn(tr("Stopname"));
     29        addColumn(tr("Shelter"));
     30        addTableModelListener(this);
     31    }
    4932
    50   public void addRow(WayPoint wp)
    51   {
    52     insertRow(-1, wp);
    53   }
     33    @Override
     34    public boolean isCellEditable(int row, int column) {
     35        if (column >= 1)
     36            return true;
     37        return false;
     38    }
    5439
    55   public void insertRow(int insPos, WayPoint wp)
    56   {
    57     String time = wp.getString("time");
    58     if (time == null)
    59       time = "";
    60     String name = wp.getString("name");
    61     if (name == null)
    62       name = "";
     40    @Override
     41    public void addRow(Object[] obj) {
     42        throw new UnsupportedOperationException();
     43    }
    6344
    64     Node node = controller.createNode(wp.getCoor(), name);
     45    @Override
     46    public void insertRow(int insPos, Object[] obj) {
     47        throw new UnsupportedOperationException();
     48    }
    6549
    66     Object[] buf = { time, name, new TransText(null) };
    67     if (insPos == -1)
    68     {
    69       nodes.addElement(node);
    70       coors.addElement(wp.getCoor());
    71       super.addRow(buf);
     50    public void addRow(WayPoint wp) {
     51        insertRow(-1, wp);
    7252    }
    73     else
    74     {
    75       nodes.insertElementAt(node, insPos);
    76       coors.insertElementAt(wp.getCoor(), insPos);
    77       super.insertRow(insPos, buf);
     53
     54    public void insertRow(int insPos, WayPoint wp) {
     55        String time = wp.getString("time");
     56        if (time == null)
     57            time = "";
     58        String name = wp.getString("name");
     59        if (name == null)
     60            name = "";
     61
     62        Node node = controller.createNode(wp.getCoor(), name);
     63
     64        Object[] buf = { time, name, new TransText(null) };
     65        if (insPos == -1) {
     66            nodes.addElement(node);
     67            coors.addElement(wp.getCoor());
     68            super.addRow(buf);
     69        } else {
     70            nodes.insertElementAt(node, insPos);
     71            coors.insertElementAt(wp.getCoor(), insPos);
     72            super.insertRow(insPos, buf);
     73        }
    7874    }
    79   }
    8075
    81   public void clear()
    82   {
    83     nodes.clear();
    84     super.setRowCount(0);
    85   }
     76    public void clear() {
     77        nodes.clear();
     78        super.setRowCount(0);
     79    }
    8680
    87   public void tableChanged(TableModelEvent e)
    88   {
    89     if (e.getType() == TableModelEvent.UPDATE)
    90     {
    91       if (inEvent)
    92         return;
    93       Main.main.undoRedo.add(new WaypointsNameCommand
    94       (this, e.getFirstRow(), (String)getValueAt(e.getFirstRow(), 1),
    95        (TransText)getValueAt(e.getFirstRow(), 2)));
     81    @Override
     82    public void tableChanged(TableModelEvent e) {
     83        if (e.getType() == TableModelEvent.UPDATE) {
     84            if (inEvent)
     85                return;
     86            Main.main.undoRedo.add(new WaypointsNameCommand(this, e.getFirstRow(),
     87                    (String) getValueAt(e.getFirstRow(), 1),
     88                    (TransText) getValueAt(e.getFirstRow(), 2)));
     89        }
    9690    }
    97   }
    98 };
     91}
  • applications/editors/josm/plugins/public_transport/src/public_transport/WaypointsDetachCommand.java

    r29854 r32357  
    1010import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1111
    12 public class WaypointsDetachCommand extends Command
    13 {
    14   private Vector< Integer > workingLines = null;
    15   private Vector< Node > nodesForUndo = null;
    16   private WaypointTableModel waypointTM = null;
     12public class WaypointsDetachCommand extends Command {
     13    private Vector<Integer> workingLines = null;
    1714
    18   public WaypointsDetachCommand(StopImporterAction controller)
    19   {
    20     waypointTM = controller.getWaypointTableModel();
    21     workingLines = new Vector< Integer >();
    22     nodesForUndo = new Vector< Node >();
     15    private Vector<Node> nodesForUndo = null;
    2316
    24     // use either selected lines or all lines if no line is selected
    25     int[] selectedLines = controller.getDialog().getWaypointsTable().getSelectedRows();
    26     Vector< Integer > consideredLines = new Vector< Integer >();
    27     if (selectedLines.length > 0)
    28     {
    29       for (int i = 0; i < selectedLines.length; ++i)
    30     consideredLines.add(selectedLines[i]);
    31     }
    32     else
    33     {
    34       for (int i = 0; i < waypointTM.getRowCount(); ++i)
    35     consideredLines.add(new Integer(i));
     17    private WaypointTableModel waypointTM = null;
     18
     19    public WaypointsDetachCommand(StopImporterAction controller) {
     20        waypointTM = controller.getWaypointTableModel();
     21        workingLines = new Vector<>();
     22        nodesForUndo = new Vector<>();
     23
     24        // use either selected lines or all lines if no line is selected
     25        int[] selectedLines = controller.getDialog().getWaypointsTable().getSelectedRows();
     26        Vector<Integer> consideredLines = new Vector<>();
     27        if (selectedLines.length > 0) {
     28            for (int i = 0; i < selectedLines.length; ++i)
     29                consideredLines.add(selectedLines[i]);
     30        } else {
     31            for (int i = 0; i < waypointTM.getRowCount(); ++i)
     32                consideredLines.add(new Integer(i));
     33        }
     34
     35        // keep only lines where a node can be added
     36        for (int i = 0; i < consideredLines.size(); ++i) {
     37            if (waypointTM.nodes.elementAt(consideredLines.elementAt(i)) != null)
     38                workingLines.add(consideredLines.elementAt(i));
     39        }
    3640    }
    3741
    38     // keep only lines where a node can be added
    39     for (int i = 0; i < consideredLines.size(); ++i)
    40     {
    41       if (waypointTM.nodes.elementAt(consideredLines.elementAt(i)) != null)
    42     workingLines.add(consideredLines.elementAt(i));
     42    @Override
     43    public boolean executeCommand() {
     44        nodesForUndo.clear();
     45        for (int i = 0; i < workingLines.size(); ++i) {
     46            int j = workingLines.elementAt(i).intValue();
     47            Node node = waypointTM.nodes.elementAt(j);
     48            nodesForUndo.add(node);
     49            waypointTM.nodes.set(j, null);
     50        }
     51        return true;
    4352    }
    44   }
    4553
    46   public boolean executeCommand()
    47   {
    48     nodesForUndo.clear();
    49     for (int i = 0; i < workingLines.size(); ++i)
    50     {
    51       int j = workingLines.elementAt(i).intValue();
    52       Node node = waypointTM.nodes.elementAt(j);
    53       nodesForUndo.add(node);
    54       waypointTM.nodes.set(j, null);
     54    @Override
     55    public void undoCommand() {
     56        for (int i = 0; i < workingLines.size(); ++i) {
     57            int j = workingLines.elementAt(i).intValue();
     58            Node node = nodesForUndo.elementAt(i);
     59            waypointTM.nodes.set(j, node);
     60        }
    5561    }
    56     return true;
    57   }
    5862
    59   public void undoCommand()
    60   {
    61     for (int i = 0; i < workingLines.size(); ++i)
    62     {
    63       int j = workingLines.elementAt(i).intValue();
    64       Node node = nodesForUndo.elementAt(i);
    65       waypointTM.nodes.set(j, node);
     63    @Override
     64    public void fillModifiedData(Collection<OsmPrimitive> modified,
     65            Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
    6666    }
    67   }
    6867
    69   public void fillModifiedData
    70     (Collection< OsmPrimitive > modified, Collection< OsmPrimitive > deleted,
    71      Collection< OsmPrimitive > added)
    72   {
    73   }
    74 
    75   @Override public String getDescriptionText()
    76   {
    77     return tr("Public Transport: Detach waypoints");
    78   }
    79 };
     68    @Override
     69    public String getDescriptionText() {
     70        return tr("Public Transport: Detach waypoints");
     71    }
     72}
  • applications/editors/josm/plugins/public_transport/src/public_transport/WaypointsDisableCommand.java

    r29854 r32357  
    1111import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1212
    13 public class WaypointsDisableCommand extends Command
    14 {
    15   private Vector< Integer > workingLines = null;
    16   private Vector< Node > nodesForUndo = null;
    17   private WaypointTableModel waypointTM = null;
     13public class WaypointsDisableCommand extends Command {
     14    private Vector<Integer> workingLines = null;
    1815
    19   public WaypointsDisableCommand(StopImporterAction controller)
    20   {
    21     waypointTM = controller.getWaypointTableModel();
    22     workingLines = new Vector< Integer >();
    23     nodesForUndo = new Vector< Node >();
     16    private Vector<Node> nodesForUndo = null;
    2417
    25     // use either selected lines or all lines if no line is selected
    26     int[] selectedLines = controller.getDialog().getWaypointsTable().getSelectedRows();
    27     Vector< Integer > consideredLines = new Vector< Integer >();
    28     if (selectedLines.length > 0)
    29     {
    30       for (int i = 0; i < selectedLines.length; ++i)
    31     consideredLines.add(selectedLines[i]);
    32     }
    33     else
    34     {
    35       for (int i = 0; i < waypointTM.getRowCount(); ++i)
    36     consideredLines.add(new Integer(i));
     18    private WaypointTableModel waypointTM = null;
     19
     20    public WaypointsDisableCommand(StopImporterAction controller) {
     21        waypointTM = controller.getWaypointTableModel();
     22        workingLines = new Vector<>();
     23        nodesForUndo = new Vector<>();
     24
     25        // use either selected lines or all lines if no line is selected
     26        int[] selectedLines = controller.getDialog().getWaypointsTable().getSelectedRows();
     27        Vector<Integer> consideredLines = new Vector<>();
     28        if (selectedLines.length > 0) {
     29            for (int i = 0; i < selectedLines.length; ++i)
     30                consideredLines.add(selectedLines[i]);
     31        } else {
     32            for (int i = 0; i < waypointTM.getRowCount(); ++i)
     33                consideredLines.add(new Integer(i));
     34        }
     35
     36        // keep only lines where a node can be added
     37        for (int i = 0; i < consideredLines.size(); ++i) {
     38            if (waypointTM.nodes.elementAt(consideredLines.elementAt(i)) != null)
     39                workingLines.add(consideredLines.elementAt(i));
     40        }
    3741    }
    3842
    39     // keep only lines where a node can be added
    40     for (int i = 0; i < consideredLines.size(); ++i)
    41     {
    42       if (waypointTM.nodes.elementAt(consideredLines.elementAt(i)) != null)
    43     workingLines.add(consideredLines.elementAt(i));
     43    @Override
     44    public boolean executeCommand() {
     45        nodesForUndo.clear();
     46        for (int i = 0; i < workingLines.size(); ++i) {
     47            int j = workingLines.elementAt(i).intValue();
     48            Node node = waypointTM.nodes.elementAt(j);
     49            nodesForUndo.add(node);
     50            if (node == null)
     51                continue;
     52            waypointTM.nodes.set(j, null);
     53            Main.getLayerManager().getEditDataSet().removePrimitive(node);
     54            node.setDeleted(true);
     55        }
     56        return true;
    4457    }
    45   }
    4658
    47   public boolean executeCommand()
    48   {
    49     nodesForUndo.clear();
    50     for (int i = 0; i < workingLines.size(); ++i)
    51     {
    52       int j = workingLines.elementAt(i).intValue();
    53       Node node = waypointTM.nodes.elementAt(j);
    54       nodesForUndo.add(node);
    55       if (node == null)
    56     continue;
    57       waypointTM.nodes.set(j, null);
    58       Main.main.getCurrentDataSet().removePrimitive(node);
    59       node.setDeleted(true);
     59    @Override
     60    public void undoCommand() {
     61        for (int i = 0; i < workingLines.size(); ++i) {
     62            int j = workingLines.elementAt(i).intValue();
     63            Node node = nodesForUndo.elementAt(i);
     64            waypointTM.nodes.set(j, node);
     65            if (node == null)
     66                continue;
     67            node.setDeleted(false);
     68            Main.getLayerManager().getEditDataSet().addPrimitive(node);
     69        }
    6070    }
    61     return true;
    62   }
    6371
    64   public void undoCommand()
    65   {
    66     for (int i = 0; i < workingLines.size(); ++i)
    67     {
    68       int j = workingLines.elementAt(i).intValue();
    69       Node node = nodesForUndo.elementAt(i);
    70       waypointTM.nodes.set(j, node);
    71       if (node == null)
    72     continue;
    73       node.setDeleted(false);
    74       Main.main.getCurrentDataSet().addPrimitive(node);
     72    @Override
     73    public void fillModifiedData(Collection<OsmPrimitive> modified,
     74            Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
    7575    }
    76   }
    7776
    78   public void fillModifiedData
    79     (Collection< OsmPrimitive > modified, Collection< OsmPrimitive > deleted,
    80      Collection< OsmPrimitive > added)
    81   {
    82   }
    83 
    84   @Override public String getDescriptionText()
    85   {
    86     return tr("Public Transport: Disable waypoints");
    87   }
     77    @Override
     78    public String getDescriptionText() {
     79        return tr("Public Transport: Disable waypoints");
     80    }
    8881};
  • applications/editors/josm/plugins/public_transport/src/public_transport/WaypointsEnableCommand.java

    r29854 r32357  
    1111import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1212
    13 public class WaypointsEnableCommand extends Command
    14 {
    15   private Vector< Integer > workingLines = null;
    16   private WaypointTableModel waypointTM = null;
    17   private String type = null;
     13public class WaypointsEnableCommand extends Command {
     14    private Vector<Integer> workingLines = null;
    1815
    19   public WaypointsEnableCommand(StopImporterAction controller)
    20   {
    21     waypointTM = controller.getWaypointTableModel();
    22     type = controller.getDialog().getStoptype();
    23     workingLines = new Vector< Integer >();
     16    private WaypointTableModel waypointTM = null;
    2417
    25     // use either selected lines or all lines if no line is selected
    26     int[] selectedLines = controller.getDialog().getWaypointsTable().getSelectedRows();
    27     Vector< Integer > consideredLines = new Vector< Integer >();
    28     if (selectedLines.length > 0)
    29     {
    30       for (int i = 0; i < selectedLines.length; ++i)
    31         consideredLines.add(selectedLines[i]);
    32     }
    33     else
    34     {
    35       for (int i = 0; i < waypointTM.getRowCount(); ++i)
    36         consideredLines.add(new Integer(i));
     18    private String type = null;
     19
     20    public WaypointsEnableCommand(StopImporterAction controller) {
     21        waypointTM = controller.getWaypointTableModel();
     22        type = controller.getDialog().getStoptype();
     23        workingLines = new Vector<>();
     24
     25        // use either selected lines or all lines if no line is selected
     26        int[] selectedLines = controller.getDialog().getWaypointsTable().getSelectedRows();
     27        Vector<Integer> consideredLines = new Vector<>();
     28        if (selectedLines.length > 0) {
     29            for (int i = 0; i < selectedLines.length; ++i)
     30                consideredLines.add(selectedLines[i]);
     31        } else {
     32            for (int i = 0; i < waypointTM.getRowCount(); ++i)
     33                consideredLines.add(new Integer(i));
     34        }
     35
     36        // keep only lines where a node can be added
     37        for (int i = 0; i < consideredLines.size(); ++i) {
     38            if (waypointTM.nodes.elementAt(consideredLines.elementAt(i)) == null)
     39                workingLines.add(consideredLines.elementAt(i));
     40        }
    3741    }
    3842
    39     // keep only lines where a node can be added
    40     for (int i = 0; i < consideredLines.size(); ++i)
    41     {
    42       if (waypointTM.nodes.elementAt(consideredLines.elementAt(i)) == null)
    43         workingLines.add(consideredLines.elementAt(i));
     43    @Override
     44    public boolean executeCommand() {
     45        for (int i = 0; i < workingLines.size(); ++i) {
     46            int j = workingLines.elementAt(i).intValue();
     47            Node node = StopImporterAction.createNode(waypointTM.coors.elementAt(j), type,
     48                    (String) waypointTM.getValueAt(j, 1));
     49            TransText shelter = (TransText) waypointTM.getValueAt(j, 2);
     50            node.put("shelter", shelter.text);
     51            waypointTM.nodes.set(j, node);
     52        }
     53        return true;
    4454    }
    45   }
    4655
    47   public boolean executeCommand()
    48   {
    49     for (int i = 0; i < workingLines.size(); ++i)
    50     {
    51       int j = workingLines.elementAt(i).intValue();
    52       Node node = StopImporterAction.createNode
    53         (waypointTM.coors.elementAt(j), type, (String)waypointTM.getValueAt(j, 1));
    54       TransText shelter = (TransText)waypointTM.getValueAt(j, 2);
    55       node.put("shelter", shelter.text);
    56       waypointTM.nodes.set(j, node);
     56    @Override
     57    public void undoCommand() {
     58        for (int i = 0; i < workingLines.size(); ++i) {
     59            int j = workingLines.elementAt(i).intValue();
     60            Node node = waypointTM.nodes.elementAt(j);
     61            waypointTM.nodes.set(j, null);
     62            if (node == null)
     63                continue;
     64            Main.getLayerManager().getEditDataSet().removePrimitive(node);
     65            node.setDeleted(true);
     66        }
    5767    }
    58     return true;
    59   }
    6068
    61   public void undoCommand()
    62   {
    63     for (int i = 0; i < workingLines.size(); ++i)
    64     {
    65       int j = workingLines.elementAt(i).intValue();
    66       Node node = waypointTM.nodes.elementAt(j);
    67       waypointTM.nodes.set(j, null);
    68       if (node == null)
    69         continue;
    70       Main.main.getCurrentDataSet().removePrimitive(node);
    71       node.setDeleted(true);
     69    @Override
     70    public void fillModifiedData(Collection<OsmPrimitive> modified,
     71            Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
    7272    }
    73   }
    7473
    75   public void fillModifiedData
    76     (Collection< OsmPrimitive > modified, Collection< OsmPrimitive > deleted,
    77      Collection< OsmPrimitive > added)
    78   {
    79   }
    80 
    81   @Override public String getDescriptionText()
    82   {
    83     return tr("Public Transport: Enable waypoints");
    84   }
    85 };
     74    @Override
     75    public String getDescriptionText() {
     76        return tr("Public Transport: Enable waypoints");
     77    }
     78}
  • applications/editors/josm/plugins/public_transport/src/public_transport/WaypointsNameCommand.java

    r29854 r32357  
    88import org.openstreetmap.josm.data.osm.OsmPrimitive;
    99
    10 public class WaypointsNameCommand extends Command
    11 {
    12   private int workingLine = 0;
    13   private WaypointTableModel waypointTM = null;
    14   private String oldName = null;
    15   private String name = null;
    16   private String oldShelter = null;
    17   private TransText shelter;
     10public class WaypointsNameCommand extends Command {
     11    private int workingLine = 0;
    1812
    19   public WaypointsNameCommand
    20       (WaypointTableModel waypointTM, int workingLine, String name, TransText shelter)
    21   {
    22     this.waypointTM = waypointTM;
    23     this.workingLine = workingLine;
    24     if (waypointTM.nodes.elementAt(workingLine) != null)
    25     {
    26       oldName = waypointTM.nodes.elementAt(workingLine).get("name");
    27       oldShelter = waypointTM.nodes.elementAt(workingLine).get("shelter");
     13    private WaypointTableModel waypointTM = null;
     14
     15    private String oldName = null;
     16
     17    private String name = null;
     18
     19    private String oldShelter = null;
     20
     21    private TransText shelter;
     22
     23    public WaypointsNameCommand(WaypointTableModel waypointTM, int workingLine, String name,
     24            TransText shelter) {
     25        this.waypointTM = waypointTM;
     26        this.workingLine = workingLine;
     27        if (waypointTM.nodes.elementAt(workingLine) != null) {
     28            oldName = waypointTM.nodes.elementAt(workingLine).get("name");
     29            oldShelter = waypointTM.nodes.elementAt(workingLine).get("shelter");
     30        }
     31        this.name = name;
     32        this.shelter = shelter;
    2833    }
    29     this.name = name;
    30     this.shelter = shelter;
    31   }
    3234
    33   public boolean executeCommand()
    34   {
    35     if (waypointTM.nodes.elementAt(workingLine) != null)
    36     {
    37       waypointTM.nodes.elementAt(workingLine).put("name", name);
    38       waypointTM.nodes.elementAt(workingLine).put("shelter", shelter.text);
     35    @Override
     36    public boolean executeCommand() {
     37        if (waypointTM.nodes.elementAt(workingLine) != null) {
     38            waypointTM.nodes.elementAt(workingLine).put("name", name);
     39            waypointTM.nodes.elementAt(workingLine).put("shelter", shelter.text);
     40        }
     41        waypointTM.inEvent = true;
     42        if (name == null)
     43            waypointTM.setValueAt("", workingLine, 1);
     44        else
     45            waypointTM.setValueAt(name, workingLine, 1);
     46        waypointTM.setValueAt(shelter, workingLine, 2);
     47        waypointTM.inEvent = false;
     48        return true;
    3949    }
    40     waypointTM.inEvent = true;
    41     if (name == null)
    42       waypointTM.setValueAt("", workingLine, 1);
    43     else
    44       waypointTM.setValueAt(name, workingLine, 1);
    45     waypointTM.setValueAt(shelter, workingLine, 2);
    46     waypointTM.inEvent = false;
    47     return true;
    48   }
    4950
    50   public void undoCommand()
    51   {
    52     if (waypointTM.nodes.elementAt(workingLine) != null)
    53     {
    54       waypointTM.nodes.elementAt(workingLine).put("name", oldName);
    55       waypointTM.nodes.elementAt(workingLine).put("shelter", oldShelter);
     51    @Override
     52    public void undoCommand() {
     53        if (waypointTM.nodes.elementAt(workingLine) != null) {
     54            waypointTM.nodes.elementAt(workingLine).put("name", oldName);
     55            waypointTM.nodes.elementAt(workingLine).put("shelter", oldShelter);
     56        }
     57        waypointTM.inEvent = true;
     58        if (oldName == null)
     59            waypointTM.setValueAt("", workingLine, 1);
     60        else
     61            waypointTM.setValueAt(oldName, workingLine, 1);
     62        waypointTM.setValueAt(new TransText(oldShelter), workingLine, 2);
     63        waypointTM.inEvent = false;
    5664    }
    57     waypointTM.inEvent = true;
    58     if (oldName == null)
    59       waypointTM.setValueAt("", workingLine, 1);
    60     else
    61       waypointTM.setValueAt(oldName, workingLine, 1);
    62     waypointTM.setValueAt(new TransText(oldShelter), workingLine, 2);
    63     waypointTM.inEvent = false;
    64   }
    6565
    66   public void fillModifiedData
    67     (Collection< OsmPrimitive > modified, Collection< OsmPrimitive > deleted,
    68      Collection< OsmPrimitive > added)
    69   {
    70   }
     66    @Override
     67    public void fillModifiedData(Collection<OsmPrimitive> modified,
     68            Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
     69    }
    7170
    72   @Override public String getDescriptionText()
    73   {
    74     return tr("Public Transport: Edit waypoint name");
    75   }
    76 };
     71    @Override
     72    public String getDescriptionText() {
     73        return tr("Public Transport: Edit waypoint name");
     74    }
     75}
Note: See TracChangeset for help on using the changeset viewer.