Changeset 23189 in osm


Ignore:
Timestamp:
2010-09-15T18:53:09+02:00 (14 years ago)
Author:
stoecker
Message:

remove tabs

Location:
applications/editors/josm/plugins
Files:
177 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/alignways/src/org/openstreetmap/josm/plugins/alignways/AlignWaysAction.java

    r23082 r23189  
    2424public class AlignWaysAction extends JosmAction {
    2525
    26         /**
    27         *
    28         */
    29         private static final long serialVersionUID = -1540319652562985458L;
     26    /**
     27    *
     28    */
     29    private static final long serialVersionUID = -1540319652562985458L;
    3030
    31         public AlignWaysAction() {
    32                 super(tr("Align Way Segments"), "alignways",
    33                                 tr("Makes a pair of selected way segments parallel by rotating one of them " +
    34                                 "around a chosen pivot."),
    35                                 Shortcut.registerShortcut("tools:alignways", tr("Tool: {0}",
    36                                                 tr("Align Ways")), KeyEvent.VK_A, Shortcut.GROUP_EDIT,
    37                                                 Shortcut.SHIFT_DEFAULT), true);
    38                 setEnabled(false);
    39         }
     31    public AlignWaysAction() {
     32        super(tr("Align Way Segments"), "alignways",
     33                tr("Makes a pair of selected way segments parallel by rotating one of them " +
     34                "around a chosen pivot."),
     35                Shortcut.registerShortcut("tools:alignways", tr("Tool: {0}",
     36                        tr("Align Ways")), KeyEvent.VK_A, Shortcut.GROUP_EDIT,
     37                        Shortcut.SHIFT_DEFAULT), true);
     38        setEnabled(false);
     39    }
    4040
    41         public void actionPerformed(ActionEvent e) {
    42                 if (!isEnabled())
    43                         return;
    44                 if (getCurrentDataSet() == null)
    45                         return;
     41    public void actionPerformed(ActionEvent e) {
     42        if (!isEnabled())
     43            return;
     44        if (getCurrentDataSet() == null)
     45            return;
    4646
    47                 Collection<Node> affectedNodes = AlignWaysSegmentMgr.getInstance(Main.map.mapView).getSelectedNodes();
     47        Collection<Node> affectedNodes = AlignWaysSegmentMgr.getInstance(Main.map.mapView).getSelectedNodes();
    4848
    49                 Command c = !Main.main.undoRedo.commands.isEmpty() ? Main.main.undoRedo.commands
    50                                 .getLast()
    51                                 : null;
     49        Command c = !Main.main.undoRedo.commands.isEmpty() ? Main.main.undoRedo.commands
     50                .getLast()
     51                : null;
    5252
    53                                 if (!(c instanceof AlignWaysRotateCommand &&
    54                                                 affectedNodes.equals(((AlignWaysRotateCommand) c).getRotatedNodes()))) {
    55                                         c = new AlignWaysRotateCommand();
    56                                         if (actionValid((AlignWaysRotateCommand)c, affectedNodes)) {
    57                                                 Main.main.undoRedo.add(c);
    58                                         }
    59                                 }
     53                if (!(c instanceof AlignWaysRotateCommand &&
     54                        affectedNodes.equals(((AlignWaysRotateCommand) c).getRotatedNodes()))) {
     55                    c = new AlignWaysRotateCommand();
     56                    if (actionValid((AlignWaysRotateCommand)c, affectedNodes)) {
     57                        Main.main.undoRedo.add(c);
     58                    }
     59                }
    6060
    61                                 Main.map.mapView.repaint();
     61                Main.map.mapView.repaint();
    6262
    63                                 return;
    64         }
     63                return;
     64    }
    6565
    6666
    67         /**
    68         * Validates the circumstances of the alignment (rotation) command to be executed.
    69         * @param c Command to be verified.
    70         * @param affectedNodes Nodes to be affected by the action.
    71         * @return true if the aligning action can be done, false otherwise.
    72         */
    73         private boolean actionValid(AlignWaysRotateCommand c, Collection<Node> affectedNodes) {
    74                 // Deny action if reference and alignee segment cannot be aligned
    75                 if (!c.areSegsAlignable()) {
    76                         JOptionPane.showMessageDialog(Main.parent,
    77                                         tr("Please select two segments that don''t share any nodes\n"
    78                                                         + " or put the pivot on their common node.\n"),
    79                                                         tr("AlignWayS: Alignment not possible"), JOptionPane.WARNING_MESSAGE);
    80                         return false;
    81                 }
     67    /**
     68    * Validates the circumstances of the alignment (rotation) command to be executed.
     69    * @param c Command to be verified.
     70    * @param affectedNodes Nodes to be affected by the action.
     71    * @return true if the aligning action can be done, false otherwise.
     72    */
     73    private boolean actionValid(AlignWaysRotateCommand c, Collection<Node> affectedNodes) {
     74        // Deny action if reference and alignee segment cannot be aligned
     75        if (!c.areSegsAlignable()) {
     76            JOptionPane.showMessageDialog(Main.parent,
     77                    tr("Please select two segments that don''t share any nodes\n"
     78                            + " or put the pivot on their common node.\n"),
     79                            tr("AlignWayS: Alignment not possible"), JOptionPane.WARNING_MESSAGE);
     80            return false;
     81        }
    8282
    83                 // Deny action if the nodes would end up outside world
    84                 for (Node n : affectedNodes) {
    85                         if (n.getCoor().isOutSideWorld()) {
    86                                 // Revert move
    87                                 (c).undoCommand();
    88                                 JOptionPane.showMessageDialog(Main.parent,
    89                                                 tr("Aligning would result nodes outside the world.\n"),
    90                                                 tr("AlignWayS: Alignment not possible"), JOptionPane.WARNING_MESSAGE);
    91                                 return false;
    92                         }
     83        // Deny action if the nodes would end up outside world
     84        for (Node n : affectedNodes) {
     85            if (n.getCoor().isOutSideWorld()) {
     86                // Revert move
     87                (c).undoCommand();
     88                JOptionPane.showMessageDialog(Main.parent,
     89                        tr("Aligning would result nodes outside the world.\n"),
     90                        tr("AlignWayS: Alignment not possible"), JOptionPane.WARNING_MESSAGE);
     91                return false;
     92            }
    9393
    94                 }
     94        }
    9595
    96                 // Action valid
    97                 return true;
    98         }
     96        // Action valid
     97        return true;
     98    }
    9999
    100100}
  • applications/editors/josm/plugins/alignways/src/org/openstreetmap/josm/plugins/alignways/AlignWaysAlgnSegment.java

    r21613 r23189  
    2626public class AlignWaysAlgnSegment extends AlignWaysSegment {
    2727
    28         private enum PivotLocations {
    29                 NONE, NODE1, NODE2, CENTRE
    30         };
    31 
    32         private PivotLocations currPivot;
    33         Map<PivotLocations, EastNorth> pivotList = new EnumMap<PivotLocations, EastNorth>(
    34                         PivotLocations.class);
    35         private final Color pivotColor = Color.YELLOW;
    36         private final Color crossColor = pivotColor;
    37 
    38         public AlignWaysAlgnSegment(MapView mapview, Point p)
    39         throws IllegalArgumentException {
    40                 super(mapview, p);
    41                 setSegment(getNearestWaySegment(p));
    42                 segmentColor = Color.ORANGE;
    43         }
    44 
    45         /**
    46         * Sets segment and initialises its pivot list and activates the centre
    47         * rotation pivot.
    48         */
    49         @Override
    50         public void setSegment(WaySegment segment) {
    51                 super.setSegment(segment);
    52                 setPivots();
    53         }
    54 
    55         /**
    56         * Useful when segments moves (or e.g. rotates) on the map. Updates the end
    57         * segment points and the pivot coordinates without changing the current
    58         * pivot.
    59         */
    60         public void updatePivotsEndpoints() {
    61                 setPivots(currPivot);
    62                 setSegmentEndpoints(segment);
    63         }
    64 
    65         /**
    66         * Updates the segment's pivot list and sets the rotation pivot to centre.
    67         */
    68         private void setPivots(PivotLocations pivotRef) {
    69                 if (segment != null) {
    70                         for (PivotLocations pl : PivotLocations.values()) {
    71                                 pivotList.put(pl, getPivotCoord(pl));
    72                         }
    73                         setPivotReference(pivotRef);
    74                 } else {
    75                         setPivotReference(PivotLocations.NONE);
    76                 }
    77         }
    78 
    79         private void setPivots() {
    80                 setPivots(PivotLocations.CENTRE);
    81         }
    82 
    83         private void setPivotReference(PivotLocations pp) {
    84                 currPivot = pp;
    85         }
    86 
    87         /**
    88         * Returns the EastNorth of the specified pivot point pp. It always returns
    89         * up-to-date data from dataset. Assumes segment is not null.
    90         *
    91         * @param pp
    92         *            The pivot location
    93         */
    94         private EastNorth getPivotCoord(PivotLocations pp) {
    95                 switch (pp) {
    96                 case NONE:
    97                         return null;
    98                 case NODE1:
    99                         return segment.way.getNode(segment.lowerIndex).getEastNorth();
    100                 case NODE2:
    101                         return segment.way.getNode(segment.lowerIndex + 1).getEastNorth();
    102                 case CENTRE:
    103                         return getPivotCoord(PivotLocations.NODE1).getCenter(
    104                                         getPivotCoord(PivotLocations.NODE2));
    105                 default:
    106                         // Should never happen
    107                         return null;
    108                 }
    109         }
    110 
    111         /**
    112         * @return The EastNorth of the currently selected pivot.
    113         */
    114         public EastNorth getCurrPivotCoord() {
    115                 if (segment != null)
    116                         return getPivotCoord(currPivot);
    117                 return null;
    118         }
    119 
    120         /**
    121         * @param clickedPoint
    122         *            Pivot may be updated in the vicinity of this point
    123         * @return true if a pivot is within reach on the segment, false otherwise
    124         */
    125         public boolean updatePivot(Point clickedPoint) {
    126                 // tHQ Done.
    127                 PivotLocations tmpPivot = findNearbyPivot(clickedPoint);
    128                 if (tmpPivot != PivotLocations.NONE) {
    129                         setPivotReference(tmpPivot);
    130                         return true;
    131                 } else
    132                         return false;
    133         }
    134 
    135         private PivotLocations findNearbyPivot(Point clickedPoint) {
    136                 PivotLocations nearest = PivotLocations.NONE;
    137                 int snapDistance = NavigatableComponent.snapDistance;
    138 
    139                 // If no alignee selected yet, there's no point to carry on
    140                 if (segment == null)
    141                         return PivotLocations.NONE;
    142 
    143                 for (PivotLocations pl : PivotLocations.values()) {
    144                         if (pl.equals(PivotLocations.NONE)) {
    145                                 continue;
    146                         }
    147                         if (mapview.getPoint(pivotList.get(pl)).distance(clickedPoint) <= snapDistance) {
    148                                 nearest = pl;
    149                                 break;
    150                         }
    151                 }
    152                 return nearest;
    153         }
    154 
    155         /*
    156         * (non-Javadoc)
    157         *
    158         * @see
    159         * org.openstreetmap.josm.plugins.alignways.AlignWaysRefSegment#paint(java
    160         * .awt.Graphics2D, org.openstreetmap.josm.gui.MapView,
    161         * org.openstreetmap.josm.data.Bounds)
    162         */
    163         @Override
    164         public void paint(Graphics2D g, MapView mv, Bounds bbox) {
    165                 // Note: segment should never be null here
    166                 super.paint(g, mv, bbox);
    167 
    168                 // Highlight potential pivot points
    169                 for (PivotLocations pl : PivotLocations.values()) {
    170                         if (pl != PivotLocations.NONE) {
    171                                 highlightCross(g, mv, pivotList.get(pl));
    172                         }
    173                 }
    174 
    175                 // Highlight active pivot
    176                 highlightPivot(g, mv, getPivotCoord(currPivot));
    177 
    178         }
    179 
    180         private void highlightPivot(Graphics2D g, MapView mv, EastNorth pivot) {
    181                 g.setColor(pivotColor);
    182                 g.setStroke(new BasicStroke());
    183 
    184                 Shape pvCentrePoint = new Ellipse2D.Double(
    185                                 mv.getPoint(pivot).getX() - 5.0f,
    186                                 mv.getPoint(pivot).getY() - 5.0f, 10.0f, 10.0f);
    187                 g.fill(pvCentrePoint);
    188                 Shape pvPoint = new Ellipse2D.Double(mv.getPoint(pivot).getX() - 8.0f,
    189                                 mv.getPoint(pivot).getY() - 8.0f, 16.0f, 16.0f);
    190 
    191                 g.draw(pvCentrePoint);
    192                 g.draw(pvPoint);
    193         }
    194 
    195         private void highlightCross(Graphics2D g, MapView mv, EastNorth en) {
    196 
    197                 double crossX = mv.getPoint(en).getX();
    198                 double crossY = mv.getPoint(en).getY();
    199                 double crossSize = 10.0;
    200 
    201                 Line2D crossV = new Line2D.Double(crossX, crossY - crossSize, crossX,
    202                                 crossY + crossSize);
    203                 Line2D crossH = new Line2D.Double(crossX - crossSize, crossY, crossX
    204                                 + crossSize, crossY);
    205 
    206                 g.setColor(crossColor);
    207                 g.setStroke(new BasicStroke());
    208                 g.draw(crossV);
    209                 g.draw(crossH);
    210 
    211         }
     28    private enum PivotLocations {
     29        NONE, NODE1, NODE2, CENTRE
     30    };
     31
     32    private PivotLocations currPivot;
     33    Map<PivotLocations, EastNorth> pivotList = new EnumMap<PivotLocations, EastNorth>(
     34            PivotLocations.class);
     35    private final Color pivotColor = Color.YELLOW;
     36    private final Color crossColor = pivotColor;
     37
     38    public AlignWaysAlgnSegment(MapView mapview, Point p)
     39    throws IllegalArgumentException {
     40        super(mapview, p);
     41        setSegment(getNearestWaySegment(p));
     42        segmentColor = Color.ORANGE;
     43    }
     44
     45    /**
     46    * Sets segment and initialises its pivot list and activates the centre
     47    * rotation pivot.
     48    */
     49    @Override
     50    public void setSegment(WaySegment segment) {
     51        super.setSegment(segment);
     52        setPivots();
     53    }
     54
     55    /**
     56    * Useful when segments moves (or e.g. rotates) on the map. Updates the end
     57    * segment points and the pivot coordinates without changing the current
     58    * pivot.
     59    */
     60    public void updatePivotsEndpoints() {
     61        setPivots(currPivot);
     62        setSegmentEndpoints(segment);
     63    }
     64
     65    /**
     66    * Updates the segment's pivot list and sets the rotation pivot to centre.
     67    */
     68    private void setPivots(PivotLocations pivotRef) {
     69        if (segment != null) {
     70            for (PivotLocations pl : PivotLocations.values()) {
     71                pivotList.put(pl, getPivotCoord(pl));
     72            }
     73            setPivotReference(pivotRef);
     74        } else {
     75            setPivotReference(PivotLocations.NONE);
     76        }
     77    }
     78
     79    private void setPivots() {
     80        setPivots(PivotLocations.CENTRE);
     81    }
     82
     83    private void setPivotReference(PivotLocations pp) {
     84        currPivot = pp;
     85    }
     86
     87    /**
     88    * Returns the EastNorth of the specified pivot point pp. It always returns
     89    * up-to-date data from dataset. Assumes segment is not null.
     90    *
     91    * @param pp
     92    *            The pivot location
     93    */
     94    private EastNorth getPivotCoord(PivotLocations pp) {
     95        switch (pp) {
     96        case NONE:
     97            return null;
     98        case NODE1:
     99            return segment.way.getNode(segment.lowerIndex).getEastNorth();
     100        case NODE2:
     101            return segment.way.getNode(segment.lowerIndex + 1).getEastNorth();
     102        case CENTRE:
     103            return getPivotCoord(PivotLocations.NODE1).getCenter(
     104                    getPivotCoord(PivotLocations.NODE2));
     105        default:
     106            // Should never happen
     107            return null;
     108        }
     109    }
     110
     111    /**
     112    * @return The EastNorth of the currently selected pivot.
     113    */
     114    public EastNorth getCurrPivotCoord() {
     115        if (segment != null)
     116            return getPivotCoord(currPivot);
     117        return null;
     118    }
     119
     120    /**
     121    * @param clickedPoint
     122    *            Pivot may be updated in the vicinity of this point
     123    * @return true if a pivot is within reach on the segment, false otherwise
     124    */
     125    public boolean updatePivot(Point clickedPoint) {
     126        // tHQ Done.
     127        PivotLocations tmpPivot = findNearbyPivot(clickedPoint);
     128        if (tmpPivot != PivotLocations.NONE) {
     129            setPivotReference(tmpPivot);
     130            return true;
     131        } else
     132            return false;
     133    }
     134
     135    private PivotLocations findNearbyPivot(Point clickedPoint) {
     136        PivotLocations nearest = PivotLocations.NONE;
     137        int snapDistance = NavigatableComponent.snapDistance;
     138
     139        // If no alignee selected yet, there's no point to carry on
     140        if (segment == null)
     141            return PivotLocations.NONE;
     142
     143        for (PivotLocations pl : PivotLocations.values()) {
     144            if (pl.equals(PivotLocations.NONE)) {
     145                continue;
     146            }
     147            if (mapview.getPoint(pivotList.get(pl)).distance(clickedPoint) <= snapDistance) {
     148                nearest = pl;
     149                break;
     150            }
     151        }
     152        return nearest;
     153    }
     154
     155    /*
     156    * (non-Javadoc)
     157    *
     158    * @see
     159    * org.openstreetmap.josm.plugins.alignways.AlignWaysRefSegment#paint(java
     160    * .awt.Graphics2D, org.openstreetmap.josm.gui.MapView,
     161    * org.openstreetmap.josm.data.Bounds)
     162    */
     163    @Override
     164    public void paint(Graphics2D g, MapView mv, Bounds bbox) {
     165        // Note: segment should never be null here
     166        super.paint(g, mv, bbox);
     167
     168        // Highlight potential pivot points
     169        for (PivotLocations pl : PivotLocations.values()) {
     170            if (pl != PivotLocations.NONE) {
     171                highlightCross(g, mv, pivotList.get(pl));
     172            }
     173        }
     174
     175        // Highlight active pivot
     176        highlightPivot(g, mv, getPivotCoord(currPivot));
     177
     178    }
     179
     180    private void highlightPivot(Graphics2D g, MapView mv, EastNorth pivot) {
     181        g.setColor(pivotColor);
     182        g.setStroke(new BasicStroke());
     183
     184        Shape pvCentrePoint = new Ellipse2D.Double(
     185                mv.getPoint(pivot).getX() - 5.0f,
     186                mv.getPoint(pivot).getY() - 5.0f, 10.0f, 10.0f);
     187        g.fill(pvCentrePoint);
     188        Shape pvPoint = new Ellipse2D.Double(mv.getPoint(pivot).getX() - 8.0f,
     189                mv.getPoint(pivot).getY() - 8.0f, 16.0f, 16.0f);
     190
     191        g.draw(pvCentrePoint);
     192        g.draw(pvPoint);
     193    }
     194
     195    private void highlightCross(Graphics2D g, MapView mv, EastNorth en) {
     196
     197        double crossX = mv.getPoint(en).getX();
     198        double crossY = mv.getPoint(en).getY();
     199        double crossSize = 10.0;
     200
     201        Line2D crossV = new Line2D.Double(crossX, crossY - crossSize, crossX,
     202                crossY + crossSize);
     203        Line2D crossH = new Line2D.Double(crossX - crossSize, crossY, crossX
     204                + crossSize, crossY);
     205
     206        g.setColor(crossColor);
     207        g.setStroke(new BasicStroke());
     208        g.draw(crossV);
     209        g.draw(crossH);
     210
     211    }
    212212
    213213}
  • applications/editors/josm/plugins/alignways/src/org/openstreetmap/josm/plugins/alignways/AlignWaysPlugin.java

    r21613 r23189  
    2020public class AlignWaysPlugin extends Plugin {
    2121
    22         static AlignWaysMode awMode;
    23         private final IconToggleButton btn;
    24         static JMenuItem alignWaysMenuItem;
    25         static JosmAction awAction;
     22    static AlignWaysMode awMode;
     23    private final IconToggleButton btn;
     24    static JMenuItem alignWaysMenuItem;
     25    static JosmAction awAction;
    2626
    27         /**
    28         *
    29         */
    30         public AlignWaysPlugin(PluginInformation info) {
    31                 super(info);
    32                 awMode = new AlignWaysMode(Main.map, "alignways", tr("Align Ways mode"));
    33                 btn = new IconToggleButton(awMode);
    34                 btn.setVisible(true);
    35                 Main.main.menu.toolsMenu.addSeparator();
    36                 awAction = new AlignWaysAction();
    37                 alignWaysMenuItem = MainMenu.add(Main.main.menu.toolsMenu, awAction);
    38                 Main.main.menu.toolsMenu.addSeparator();
     27    /**
     28    *
     29    */
     30    public AlignWaysPlugin(PluginInformation info) {
     31        super(info);
     32        awMode = new AlignWaysMode(Main.map, "alignways", tr("Align Ways mode"));
     33        btn = new IconToggleButton(awMode);
     34        btn.setVisible(true);
     35        Main.main.menu.toolsMenu.addSeparator();
     36        awAction = new AlignWaysAction();
     37        alignWaysMenuItem = MainMenu.add(Main.main.menu.toolsMenu, awAction);
     38        Main.main.menu.toolsMenu.addSeparator();
    3939
    40         }
     40    }
    4141
    42         @Override
    43         public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {
    44                 if (Main.map != null) {
    45                         Main.map.addMapMode(btn);
    46                 }
    47         }
     42    @Override
     43    public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {
     44        if (Main.map != null) {
     45            Main.map.addMapMode(btn);
     46        }
     47    }
    4848
    49         /**
    50         * @return the awAction
    51         */
    52         public static JosmAction getAwAction() {
    53                 return awAction;
    54         }
     49    /**
     50    * @return the awAction
     51    */
     52    public static JosmAction getAwAction() {
     53        return awAction;
     54    }
    5555
    56         /**
    57         * @return the awMode
    58         */
    59         public static AlignWaysMode getAwMode() {
    60                 return awMode;
    61         }
     56    /**
     57    * @return the awMode
     58    */
     59    public static AlignWaysMode getAwMode() {
     60        return awMode;
     61    }
    6262
    6363}
  • applications/editors/josm/plugins/alignways/src/org/openstreetmap/josm/plugins/alignways/AlignWaysRefSegment.java

    r21613 r23189  
    1515public class AlignWaysRefSegment extends AlignWaysSegment {
    1616
    17         // Note: segment may be null. This is normal.
     17    // Note: segment may be null. This is normal.
    1818
    19         public AlignWaysRefSegment(MapView mapview, Point p)
    20         throws IllegalArgumentException {
    21                 super(mapview, p);
    22                 setSegment(getNearestWaySegment(p));
    23                 segmentColor = Color.GREEN;
     19    public AlignWaysRefSegment(MapView mapview, Point p)
     20    throws IllegalArgumentException {
     21        super(mapview, p);
     22        setSegment(getNearestWaySegment(p));
     23        segmentColor = Color.GREEN;
    2424
    25         }
     25    }
    2626
    2727}
  • applications/editors/josm/plugins/alignways/src/org/openstreetmap/josm/plugins/alignways/AlignWaysRotateCommand.java

    r22758 r23189  
    3232public class AlignWaysRotateCommand extends Command {
    3333
    34         private final AlignWaysAlgnSegment algnSeg;
    35 
    36         /**
    37         * The objects to rotate.
    38         */
    39         private Collection<Node> nodes = new HashSet<Node>();
    40 
    41         /**
    42         * pivot point
    43         */
    44         private final EastNorth pivot;
    45 
    46         /**
    47         * Small helper for holding the interesting part of the old data state of
    48         * the objects.
    49         */
    50         public static class OldState {
    51                 LatLon latlon;
    52                 EastNorth eastNorth;
    53                 WaySegment ws;
    54                 boolean modified;
    55         }
    56 
    57         /**
    58         * computed rotation angle to rotate the segment
    59         *
    60         */
    61         private final double rotationAngle;
    62 
    63         /**
    64         * List of all old states of the objects.
    65         */
    66         private final Map<Node, OldState> oldState = new HashMap<Node, OldState>();
    67         private final Stack<WaySegment> oldWS = new Stack<WaySegment>();
    68 
    69         /**
    70         * Creates an AlignWaysRotateCommand.
    71         */
    72         public AlignWaysRotateCommand() {
    73 
    74                 algnSeg = AlignWaysSegmentMgr.getInstance(Main.map.mapView)
    75                 .getAlgnSeg();
    76                 WaySegment algnWS = algnSeg.getSegment();
    77                 WaySegment refWS = AlignWaysSegmentMgr.getInstance(Main.map.mapView)
    78                 .getRefSeg().getSegment();
    79 
    80                 this.pivot = algnSeg.getCurrPivotCoord();
    81                 this.nodes = algnSeg.getSegmentEndPoints();
    82 
    83                 EastNorth enRefNode1 = refWS.way.getNode(refWS.lowerIndex)
    84                 .getEastNorth();
    85                 EastNorth enRefNode2 = refWS.way.getNode(refWS.lowerIndex + 1)
    86                 .getEastNorth();
    87 
    88                 EastNorth enAlgnNode1 = algnWS.way.getNode(algnWS.lowerIndex)
    89                 .getEastNorth();
    90                 EastNorth enAlgnNode2 = algnWS.way.getNode(algnWS.lowerIndex + 1)
    91                 .getEastNorth();
    92 
    93                 // Calculate the rotation angle
    94                 double refAngle = Math.atan2(enRefNode1.north() - enRefNode2.north(),
    95                                 enRefNode1.east() - enRefNode2.east());
    96                 double algnAngle = Math.atan2(
    97                                 enAlgnNode1.north() - enAlgnNode2.north(), enAlgnNode1.east()
    98                                 - enAlgnNode2.east());
    99 
    100                 rotationAngle = normalise_angle(refAngle - algnAngle);
    101 
    102                 /* For debug only
    103                 String s = "Ref Angle: " + refAngle + " (" + Math.toDegrees(refAngle)
    104                                 + ")\n";
    105                 s += "Algn Angle: " + algnAngle + " (" + Math.toDegrees(algnAngle)
    106                                 + ")\n";
    107                 s += "Rotation angle: " + rotationAngle + " ("
    108                                 + Math.toDegrees(rotationAngle) + ")";
    109                 */
    110 
    111                 // rotateNodes(true);
    112 
    113         }
    114 
    115         /**
    116         * Helper for actually rotating the nodes.
    117         *
    118         * @param setModified
    119         *            - true if rotated nodes should be flagged "modified"
    120         */
    121         private void rotateNodes(boolean setModified) {
    122 
    123                 // "Backup" state
    124                 WaySegment algnWS = algnSeg.getSegment();
    125                 for (Node n : this.nodes) {
    126                         OldState os = new OldState();
    127                         os.latlon = new LatLon(n.getCoor());
    128                         os.eastNorth = n.getEastNorth();
    129                         os.ws = algnWS;
    130                         os.modified = n.isModified();
    131                         oldState.put(n, os);
    132                 }
    133                 oldWS.push(algnWS);
    134 
    135                 // Rotate
    136                 for (Node n : nodes) {
    137                         double cosPhi = Math.cos(rotationAngle);
    138                         double sinPhi = Math.sin(rotationAngle);
    139                         EastNorth oldEastNorth = oldState.get(n).eastNorth;
    140                         double x = oldEastNorth.east() - pivot.east();
    141                         double y = oldEastNorth.north() - pivot.north();
    142                         double nx = cosPhi * x - sinPhi * y + pivot.east();
    143                         double ny = sinPhi * x + cosPhi * y + pivot.north();
    144                         n.setEastNorth(new EastNorth(nx, ny));
    145                         if (setModified) {
    146                                 n.setModified(true);
    147                         }
    148                 }
    149                 algnSeg.updatePivotsEndpoints();
    150         }
    151 
    152         /**
    153         * Make sure angle is in interval ( -Pi/2, Pi/2 ].
    154         */
    155         private static double normalise_angle(double a) {
    156                 while (a > Math.PI) {
    157                         a -= 2 * Math.PI;
    158                 }
    159                 while (a <= -Math.PI) {
    160                         a += 2 * Math.PI;
    161                 }
    162 
    163                 if (a > Math.PI / 2) {
    164                         a -= Math.PI;
    165                 } else if (a < -Math.PI / 2) {
    166                         a += Math.PI;
    167                 }
    168                 return a;
    169         }
    170 
    171         @Override
    172         public JLabel getDescription() {
    173                 return new JLabel(tr("Align way segment"), ImageProvider.get(
    174                                 "", "alignways"), SwingConstants.HORIZONTAL);
    175         }
    176 
    177         /*
    178         * (non-Javadoc)
    179         *
    180         * @see
    181         * org.openstreetmap.josm.command.Command#fillModifiedData(java.util.Collection
    182         * , java.util.Collection, java.util.Collection)
    183         */
    184         @Override
    185         public void fillModifiedData(Collection<OsmPrimitive> modified,
    186                         Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
    187                 for (OsmPrimitive osm : nodes) {
    188                         modified.add(osm);
    189                 }
    190         }
    191 
    192         /*
    193         * (non-Javadoc)
    194         *
    195         * @see org.openstreetmap.josm.command.Command#executeCommand()
    196         */
    197         @Override
    198         public boolean executeCommand() {
    199                 rotateNodes(true);
    200                 return true;
    201         }
    202 
    203         /*
    204         * (non-Javadoc)
    205         *
    206         * @see org.openstreetmap.josm.command.Command#undoCommand()
    207         */
    208         @Override
    209         public void undoCommand() {
    210                 for (Node n : nodes) {
    211                         OldState os = oldState.get(n);
    212                         n.setCoor(os.latlon);
    213                         n.setModified(os.modified);
    214                 }
    215                 algnSeg.updatePivotsEndpoints();
    216         }
    217 
    218         public Collection<Node> getRotatedNodes() {
    219                 return nodes;
    220         }
    221 
    222         /** Returns true if the two selected segments are alignable.
    223         *  They are not if they are connected *and* the pivot is not the connection node.
    224         */
    225         public boolean areSegsAlignable() {
    226                 Collection<Node> algnNodes = nodes;
    227                 Collection<Node> refNodes = AlignWaysSegmentMgr.getInstance(Main.map.mapView)
    228                 .getRefSeg().getSegmentEndPoints();
    229 
    230                 // First check if the pivot node of the alignee exists in the reference:
    231                 // in this case the pivot is the shared node and alignment is possible
    232                 for (Node nR : refNodes) {
    233                         if (nR.getEastNorth().equals(pivot))
    234                                 return true;
    235                 }
    236 
    237                 // Otherwise if the segments are connected, alignment is not possible
    238                 for (Node nA : algnNodes) {
    239                         for (Node nR : refNodes) {
    240                                 if (nA.equals(nR))
    241                                         return false;
    242                         }
    243                 }
    244 
    245                 // In all other cases alignment is possible
    246                 return true;
    247         }
     34    private final AlignWaysAlgnSegment algnSeg;
     35
     36    /**
     37    * The objects to rotate.
     38    */
     39    private Collection<Node> nodes = new HashSet<Node>();
     40
     41    /**
     42    * pivot point
     43    */
     44    private final EastNorth pivot;
     45
     46    /**
     47    * Small helper for holding the interesting part of the old data state of
     48    * the objects.
     49    */
     50    public static class OldState {
     51        LatLon latlon;
     52        EastNorth eastNorth;
     53        WaySegment ws;
     54        boolean modified;
     55    }
     56
     57    /**
     58    * computed rotation angle to rotate the segment
     59    *
     60    */
     61    private final double rotationAngle;
     62
     63    /**
     64    * List of all old states of the objects.
     65    */
     66    private final Map<Node, OldState> oldState = new HashMap<Node, OldState>();
     67    private final Stack<WaySegment> oldWS = new Stack<WaySegment>();
     68
     69    /**
     70    * Creates an AlignWaysRotateCommand.
     71    */
     72    public AlignWaysRotateCommand() {
     73
     74        algnSeg = AlignWaysSegmentMgr.getInstance(Main.map.mapView)
     75        .getAlgnSeg();
     76        WaySegment algnWS = algnSeg.getSegment();
     77        WaySegment refWS = AlignWaysSegmentMgr.getInstance(Main.map.mapView)
     78        .getRefSeg().getSegment();
     79
     80        this.pivot = algnSeg.getCurrPivotCoord();
     81        this.nodes = algnSeg.getSegmentEndPoints();
     82
     83        EastNorth enRefNode1 = refWS.way.getNode(refWS.lowerIndex)
     84        .getEastNorth();
     85        EastNorth enRefNode2 = refWS.way.getNode(refWS.lowerIndex + 1)
     86        .getEastNorth();
     87
     88        EastNorth enAlgnNode1 = algnWS.way.getNode(algnWS.lowerIndex)
     89        .getEastNorth();
     90        EastNorth enAlgnNode2 = algnWS.way.getNode(algnWS.lowerIndex + 1)
     91        .getEastNorth();
     92
     93        // Calculate the rotation angle
     94        double refAngle = Math.atan2(enRefNode1.north() - enRefNode2.north(),
     95                enRefNode1.east() - enRefNode2.east());
     96        double algnAngle = Math.atan2(
     97                enAlgnNode1.north() - enAlgnNode2.north(), enAlgnNode1.east()
     98                - enAlgnNode2.east());
     99
     100        rotationAngle = normalise_angle(refAngle - algnAngle);
     101
     102        /* For debug only
     103        String s = "Ref Angle: " + refAngle + " (" + Math.toDegrees(refAngle)
     104                + ")\n";
     105        s += "Algn Angle: " + algnAngle + " (" + Math.toDegrees(algnAngle)
     106                + ")\n";
     107        s += "Rotation angle: " + rotationAngle + " ("
     108                + Math.toDegrees(rotationAngle) + ")";
     109        */
     110
     111        // rotateNodes(true);
     112
     113    }
     114
     115    /**
     116    * Helper for actually rotating the nodes.
     117    *
     118    * @param setModified
     119    *            - true if rotated nodes should be flagged "modified"
     120    */
     121    private void rotateNodes(boolean setModified) {
     122
     123        // "Backup" state
     124        WaySegment algnWS = algnSeg.getSegment();
     125        for (Node n : this.nodes) {
     126            OldState os = new OldState();
     127            os.latlon = new LatLon(n.getCoor());
     128            os.eastNorth = n.getEastNorth();
     129            os.ws = algnWS;
     130            os.modified = n.isModified();
     131            oldState.put(n, os);
     132        }
     133        oldWS.push(algnWS);
     134
     135        // Rotate
     136        for (Node n : nodes) {
     137            double cosPhi = Math.cos(rotationAngle);
     138            double sinPhi = Math.sin(rotationAngle);
     139            EastNorth oldEastNorth = oldState.get(n).eastNorth;
     140            double x = oldEastNorth.east() - pivot.east();
     141            double y = oldEastNorth.north() - pivot.north();
     142            double nx = cosPhi * x - sinPhi * y + pivot.east();
     143            double ny = sinPhi * x + cosPhi * y + pivot.north();
     144            n.setEastNorth(new EastNorth(nx, ny));
     145            if (setModified) {
     146                n.setModified(true);
     147            }
     148        }
     149        algnSeg.updatePivotsEndpoints();
     150    }
     151
     152    /**
     153    * Make sure angle is in interval ( -Pi/2, Pi/2 ].
     154    */
     155    private static double normalise_angle(double a) {
     156        while (a > Math.PI) {
     157            a -= 2 * Math.PI;
     158        }
     159        while (a <= -Math.PI) {
     160            a += 2 * Math.PI;
     161        }
     162
     163        if (a > Math.PI / 2) {
     164            a -= Math.PI;
     165        } else if (a < -Math.PI / 2) {
     166            a += Math.PI;
     167        }
     168        return a;
     169    }
     170
     171    @Override
     172    public JLabel getDescription() {
     173        return new JLabel(tr("Align way segment"), ImageProvider.get(
     174                "", "alignways"), SwingConstants.HORIZONTAL);
     175    }
     176
     177    /*
     178    * (non-Javadoc)
     179    *
     180    * @see
     181    * org.openstreetmap.josm.command.Command#fillModifiedData(java.util.Collection
     182    * , java.util.Collection, java.util.Collection)
     183    */
     184    @Override
     185    public void fillModifiedData(Collection<OsmPrimitive> modified,
     186            Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) {
     187        for (OsmPrimitive osm : nodes) {
     188            modified.add(osm);
     189        }
     190    }
     191
     192    /*
     193    * (non-Javadoc)
     194    *
     195    * @see org.openstreetmap.josm.command.Command#executeCommand()
     196    */
     197    @Override
     198    public boolean executeCommand() {
     199        rotateNodes(true);
     200        return true;
     201    }
     202
     203    /*
     204    * (non-Javadoc)
     205    *
     206    * @see org.openstreetmap.josm.command.Command#undoCommand()
     207    */
     208    @Override
     209    public void undoCommand() {
     210        for (Node n : nodes) {
     211            OldState os = oldState.get(n);
     212            n.setCoor(os.latlon);
     213            n.setModified(os.modified);
     214        }
     215        algnSeg.updatePivotsEndpoints();
     216    }
     217
     218    public Collection<Node> getRotatedNodes() {
     219        return nodes;
     220    }
     221
     222    /** Returns true if the two selected segments are alignable.
     223    *  They are not if they are connected *and* the pivot is not the connection node.
     224    */
     225    public boolean areSegsAlignable() {
     226        Collection<Node> algnNodes = nodes;
     227        Collection<Node> refNodes = AlignWaysSegmentMgr.getInstance(Main.map.mapView)
     228        .getRefSeg().getSegmentEndPoints();
     229
     230        // First check if the pivot node of the alignee exists in the reference:
     231        // in this case the pivot is the shared node and alignment is possible
     232        for (Node nR : refNodes) {
     233            if (nR.getEastNorth().equals(pivot))
     234                return true;
     235        }
     236
     237        // Otherwise if the segments are connected, alignment is not possible
     238        for (Node nA : algnNodes) {
     239            for (Node nR : refNodes) {
     240                if (nA.equals(nR))
     241                    return false;
     242            }
     243        }
     244
     245        // In all other cases alignment is possible
     246        return true;
     247    }
    248248
    249249}
  • applications/editors/josm/plugins/alignways/src/org/openstreetmap/josm/plugins/alignways/AlignWaysSegment.java

    r21613 r23189  
    2727public class AlignWaysSegment implements MapViewPaintable {
    2828
    29         protected WaySegment segment;
    30         protected MapView mapview;
    31         protected Color segmentColor = Color.WHITE;
    32         protected Collection<Node> segmentEndPoints;
     29    protected WaySegment segment;
     30    protected MapView mapview;
     31    protected Color segmentColor = Color.WHITE;
     32    protected Collection<Node> segmentEndPoints;
    3333
    34         public AlignWaysSegment(MapView mapview, Point p)
    35         throws IllegalArgumentException {
    36                 if (mapview == null)
    37                         throw new IllegalArgumentException(tr(
    38                                         "Parameter ''{0}'' must not be null", "mapview"));
    39                 if (p == null)
    40                         throw new IllegalArgumentException(tr(
    41                                         "Parameter ''{0}'' must not be null", "p"));
     34    public AlignWaysSegment(MapView mapview, Point p)
     35    throws IllegalArgumentException {
     36        if (mapview == null)
     37            throw new IllegalArgumentException(tr(
     38                    "Parameter ''{0}'' must not be null", "mapview"));
     39        if (p == null)
     40            throw new IllegalArgumentException(tr(
     41                    "Parameter ''{0}'' must not be null", "p"));
    4242
    43                 this.mapview = mapview;
    44         }
     43        this.mapview = mapview;
     44    }
    4545
    46         void setSegment(WaySegment segment) {
    47                 this.segment = segment;
    48                 if (segment != null) {
    49                         setSegmentEndpoints(segment);
    50                         mapview.addTemporaryLayer(this);
    51                 }
    52         }
     46    void setSegment(WaySegment segment) {
     47        this.segment = segment;
     48        if (segment != null) {
     49            setSegmentEndpoints(segment);
     50            mapview.addTemporaryLayer(this);
     51        }
     52    }
    5353
    5454
    55         void setSegmentEndpoints(WaySegment segment) {
    56                 if (segment != null) {
    57                         Node node1 = segment.way.getNode(segment.lowerIndex);
    58                         Node node2 = segment.way.getNode(segment.lowerIndex + 1);
     55    void setSegmentEndpoints(WaySegment segment) {
     56        if (segment != null) {
     57            Node node1 = segment.way.getNode(segment.lowerIndex);
     58            Node node2 = segment.way.getNode(segment.lowerIndex + 1);
    5959
    60                         segmentEndPoints = new HashSet<Node>();
    61                         segmentEndPoints.add(node1);
    62                         segmentEndPoints.add(node2);
     60            segmentEndPoints = new HashSet<Node>();
     61            segmentEndPoints.add(node1);
     62            segmentEndPoints.add(node2);
    6363
    64                 }
    65         }
     64        }
     65    }
    6666
    67         protected WaySegment getNearestWaySegment(Point p) {
     67    protected WaySegment getNearestWaySegment(Point p) {
    6868
    69                 return mapview.getNearestWaySegment(p, OsmPrimitive.isUsablePredicate);
     69        return mapview.getNearestWaySegment(p, OsmPrimitive.isUsablePredicate);
    7070
    71         }
     71    }
    7272
    73         public void destroy() {
    74                 if (segment != null) {
    75                         mapview.removeTemporaryLayer(this);
    76                 }
    77         }
     73    public void destroy() {
     74        if (segment != null) {
     75            mapview.removeTemporaryLayer(this);
     76        }
     77    }
    7878
    79         public WaySegment getSegment() {
    80                 return segment;
    81         }
     79    public WaySegment getSegment() {
     80        return segment;
     81    }
    8282
    83         public Collection<Node> getSegmentEndPoints() {
    84                 return segmentEndPoints;
    85         }
     83    public Collection<Node> getSegmentEndPoints() {
     84        return segmentEndPoints;
     85    }
    8686
    87         public void paint(Graphics2D g, MapView mv, Bounds bbox) {
    88                 highlightSegment(segmentColor, g, mv);
    89         }
     87    public void paint(Graphics2D g, MapView mv, Bounds bbox) {
     88        highlightSegment(segmentColor, g, mv);
     89    }
    9090
    91         protected void highlightSegment(Color c, Graphics2D g, MapView mv) {
     91    protected void highlightSegment(Color c, Graphics2D g, MapView mv) {
    9292
    93                 g.setColor(c);
    94                 g.setStroke(new BasicStroke(6, BasicStroke.CAP_ROUND,
    95                                 BasicStroke.JOIN_ROUND));
    96                 drawSegment(g, mv);
     93        g.setColor(c);
     94        g.setStroke(new BasicStroke(6, BasicStroke.CAP_ROUND,
     95                BasicStroke.JOIN_ROUND));
     96        drawSegment(g, mv);
    9797
    98         }
     98    }
    9999
    100         protected void drawSegment(Graphics2D g, MapView mv) {
    101                 Node n1 = segment.way.getNode(segment.lowerIndex);
    102                 Node n2 = segment.way.getNode(segment.lowerIndex + 1);
     100    protected void drawSegment(Graphics2D g, MapView mv) {
     101        Node n1 = segment.way.getNode(segment.lowerIndex);
     102        Node n2 = segment.way.getNode(segment.lowerIndex + 1);
    103103
    104                 Line2D newline = new Line2D.Double(mv.getPoint(n1), mv.getPoint(n2));
    105                 g.draw(newline);
    106         }
     104        Line2D newline = new Line2D.Double(mv.getPoint(n1), mv.getPoint(n2));
     105        g.draw(newline);
     106    }
    107107
    108         /*
    109         * (non-Javadoc)
    110         *
    111         * @see java.lang.Object#hashCode()
    112         */
    113         @Override
    114         public int hashCode() {
    115                 final int prime = 31;
    116                 int result = 1;
    117                 result = prime * result + ((segment == null) ? 0 : segment.hashCode());
    118                 result = prime * result
    119                 + ((segmentColor == null) ? 0 : segmentColor.hashCode());
    120                 return result;
    121         }
     108    /*
     109    * (non-Javadoc)
     110    *
     111    * @see java.lang.Object#hashCode()
     112    */
     113    @Override
     114    public int hashCode() {
     115        final int prime = 31;
     116        int result = 1;
     117        result = prime * result + ((segment == null) ? 0 : segment.hashCode());
     118        result = prime * result
     119        + ((segmentColor == null) ? 0 : segmentColor.hashCode());
     120        return result;
     121    }
    122122
    123         /*
    124         * (non-Javadoc)
    125         *
    126         * @see java.lang.Object#equals(java.lang.Object)
    127         */
    128         @Override
    129         public boolean equals(Object obj) {
    130                 if (this == obj)
    131                         return true;
    132                 if (obj == null)
    133                         return false;
    134                 if (!(obj instanceof AlignWaysSegment))
    135                         return false;
    136                 AlignWaysSegment other = (AlignWaysSegment) obj;
    137                 if (segment == null) {
    138                         if (other.segment != null)
    139                                 return false;
    140                 } else if (!segment.equals(other.segment))
    141                         return false;
    142                 /* Segment colour is ignored in comparison
    143                 if (segmentColor == null) {
    144                         if (other.segmentColor != null)
    145                                 return false;
    146                 } else if (!segmentColor.equals(other.segmentColor))
    147                         return false;
    148                 */
    149                 return true;
    150         }
     123    /*
     124    * (non-Javadoc)
     125    *
     126    * @see java.lang.Object#equals(java.lang.Object)
     127    */
     128    @Override
     129    public boolean equals(Object obj) {
     130        if (this == obj)
     131            return true;
     132        if (obj == null)
     133            return false;
     134        if (!(obj instanceof AlignWaysSegment))
     135            return false;
     136        AlignWaysSegment other = (AlignWaysSegment) obj;
     137        if (segment == null) {
     138            if (other.segment != null)
     139                return false;
     140        } else if (!segment.equals(other.segment))
     141            return false;
     142        /* Segment colour is ignored in comparison
     143        if (segmentColor == null) {
     144            if (other.segmentColor != null)
     145                return false;
     146        } else if (!segmentColor.equals(other.segmentColor))
     147            return false;
     148        */
     149        return true;
     150    }
    151151}
  • applications/editors/josm/plugins/alignways/src/org/openstreetmap/josm/plugins/alignways/AlignWaysSegmentMgr.java

    r21613 r23189  
    2222public class AlignWaysSegmentMgr {
    2323
    24         private volatile static AlignWaysSegmentMgr singleton;
    25         private AlignWaysRefSegment refSeg = null;
    26         private AlignWaysAlgnSegment algnSeg = null;
    27         private final MapView mv;
     24    private volatile static AlignWaysSegmentMgr singleton;
     25    private AlignWaysRefSegment refSeg = null;
     26    private AlignWaysAlgnSegment algnSeg = null;
     27    private final MapView mv;
    2828
    29         private AlignWaysSegmentMgr(MapView mapView) {
    30                 mv = mapView;
    31         }
     29    private AlignWaysSegmentMgr(MapView mapView) {
     30        mv = mapView;
     31    }
    3232
    33         public static AlignWaysSegmentMgr getInstance(MapView mapView) {
    34                 if (singleton == null) {
    35                         synchronized (AlignWaysSegmentMgr.class) {
    36                                 if (singleton == null) {
    37                                         singleton = new AlignWaysSegmentMgr(mapView);
    38                                 }
    39                         }
    40                 }
    41                 return singleton;
    42         }
     33    public static AlignWaysSegmentMgr getInstance(MapView mapView) {
     34        if (singleton == null) {
     35            synchronized (AlignWaysSegmentMgr.class) {
     36                if (singleton == null) {
     37                    singleton = new AlignWaysSegmentMgr(mapView);
     38                }
     39            }
     40        }
     41        return singleton;
     42    }
    4343
    44         /**
    45         * @param clickedPoint
    46         *            Point nearby where user probably clicked
    47         * @return true, if alignee changed, false otherwise
    48         */
    49         public boolean algnUpdate(Point clickedPoint) {
     44    /**
     45    * @param clickedPoint
     46    *            Point nearby where user probably clicked
     47    * @return true, if alignee changed, false otherwise
     48    */
     49    public boolean algnUpdate(Point clickedPoint) {
    5050
    51                 if (algnSeg != null) {
    52                         // Check first if there is a pivot point nearby that needs selection
    53                         if (algnSeg.updatePivot(clickedPoint))
    54                                 // Updated pivot, alignee reference unchanged
    55                                 return false;
    56                 }
     51        if (algnSeg != null) {
     52            // Check first if there is a pivot point nearby that needs selection
     53            if (algnSeg.updatePivot(clickedPoint))
     54                // Updated pivot, alignee reference unchanged
     55                return false;
     56        }
    5757
    58                 // Previous attempt of pivot update unsuccessful, check alignee update
    59                 AlignWaysAlgnSegment tmpAlgnSeg = new AlignWaysAlgnSegment(mv,
    60                                 clickedPoint);
    61                 if (tmpAlgnSeg.getSegment() == null)
    62                         return false;
    63                 else {
    64                         // Found a segment
    65                         // It may happen that the new segment is identical with the already
    66                         // selected reference:
    67                         if ((refSeg != null) && (tmpAlgnSeg.equals(refSeg))) {
    68                                 // This action is then ignored (we won't clear the reference
    69                                 // segment)
    70                                 JOptionPane.showMessageDialog(Main.parent,
    71                                                 tr("Segment to be aligned cannot be the same with the reference segment.\n" +
    72                                                 "Please choose a different segment to be aligned."),
    73                                                 tr("AlignWayS message"), JOptionPane.WARNING_MESSAGE);
    74                                 return false;
    75                         }
    76                         // This will be a new alignee, old alignee (if any) will be lost:
    77                         if (algnSeg != null) {
    78                                 algnSeg.destroy();
    79                         }
     58        // Previous attempt of pivot update unsuccessful, check alignee update
     59        AlignWaysAlgnSegment tmpAlgnSeg = new AlignWaysAlgnSegment(mv,
     60                clickedPoint);
     61        if (tmpAlgnSeg.getSegment() == null)
     62            return false;
     63        else {
     64            // Found a segment
     65            // It may happen that the new segment is identical with the already
     66            // selected reference:
     67            if ((refSeg != null) && (tmpAlgnSeg.equals(refSeg))) {
     68                // This action is then ignored (we won't clear the reference
     69                // segment)
     70                JOptionPane.showMessageDialog(Main.parent,
     71                        tr("Segment to be aligned cannot be the same with the reference segment.\n" +
     72                        "Please choose a different segment to be aligned."),
     73                        tr("AlignWayS message"), JOptionPane.WARNING_MESSAGE);
     74                return false;
     75            }
     76            // This will be a new alignee, old alignee (if any) will be lost:
     77            if (algnSeg != null) {
     78                algnSeg.destroy();
     79            }
    8080
    81                         // Update alignee
    82                         algnSeg = tmpAlgnSeg;
     81            // Update alignee
     82            algnSeg = tmpAlgnSeg;
    8383
    84                         return true;
    85                 }
     84            return true;
     85        }
    8686
    87         }
     87    }
    8888
    89         /**
    90         * @param clickedPoint
    91         *            Point nearby where user probably clicked
    92         * @return true, if reference changed, false otherwise
    93         */
    94         public boolean refUpdate(Point clickedPoint) {
     89    /**
     90    * @param clickedPoint
     91    *            Point nearby where user probably clicked
     92    * @return true, if reference changed, false otherwise
     93    */
     94    public boolean refUpdate(Point clickedPoint) {
    9595
    96                 AlignWaysRefSegment tmpRefSeg = new AlignWaysRefSegment(mv,
    97                                 clickedPoint);
    98                 // TODO Have to check what happens when refSeg wasn't null previously
    99                 if (tmpRefSeg.getSegment() == null)
    100                         return false;
    101                 else {
    102                         // Found a segment
    103                         // It may happen that the new segment is identical with the already
    104                         // selected alignee:
    105                         if ((algnSeg != null) && (tmpRefSeg.equals(algnSeg))) {
    106                                 // This action is then ignored (we won't clear the alignee
    107                                 // segment)
    108                                 JOptionPane.showMessageDialog(Main.parent,
    109                                                 tr("Reference segment cannot be the same with the segment to be aligned.\n" +
    110                                                 "Please choose a different reference segment."),
    111                                                 tr("AlignWayS message"), JOptionPane.WARNING_MESSAGE);
    112                                 return false;
    113                         }
    114                         // This will be a new reference, old reference (if any) will be lost:
    115                         if (refSeg != null) {
    116                                 refSeg.destroy();
    117                         }
     96        AlignWaysRefSegment tmpRefSeg = new AlignWaysRefSegment(mv,
     97                clickedPoint);
     98        // TODO Have to check what happens when refSeg wasn't null previously
     99        if (tmpRefSeg.getSegment() == null)
     100            return false;
     101        else {
     102            // Found a segment
     103            // It may happen that the new segment is identical with the already
     104            // selected alignee:
     105            if ((algnSeg != null) && (tmpRefSeg.equals(algnSeg))) {
     106                // This action is then ignored (we won't clear the alignee
     107                // segment)
     108                JOptionPane.showMessageDialog(Main.parent,
     109                        tr("Reference segment cannot be the same with the segment to be aligned.\n" +
     110                        "Please choose a different reference segment."),
     111                        tr("AlignWayS message"), JOptionPane.WARNING_MESSAGE);
     112                return false;
     113            }
     114            // This will be a new reference, old reference (if any) will be lost:
     115            if (refSeg != null) {
     116                refSeg.destroy();
     117            }
    118118
    119                         // Update reference
    120                         refSeg = tmpRefSeg;
    121                         return true;
     119            // Update reference
     120            refSeg = tmpRefSeg;
     121            return true;
    122122
    123                 }
     123        }
    124124
    125         }
     125    }
    126126
    127         /**
    128         * @return Collection of the nodes that belong to the selected alignee.
    129         */
    130         public Collection<Node> getSelectedNodes() {
    131                 if (algnSeg != null)
    132                         return algnSeg.getSegmentEndPoints();
    133                 return null;
    134         }
     127    /**
     128    * @return Collection of the nodes that belong to the selected alignee.
     129    */
     130    public Collection<Node> getSelectedNodes() {
     131        if (algnSeg != null)
     132            return algnSeg.getSegmentEndPoints();
     133        return null;
     134    }
    135135
    136         /**
    137         * Performs "clean-up" on the initialised segments
    138         */
    139         public void cleanupWays() {
    140                 if (algnSeg != null) {
    141                         algnSeg.destroy();
    142                         algnSeg = null;
    143                 }
    144                 if (refSeg != null) {
    145                         refSeg.destroy();
    146                         refSeg = null;
    147                 }
    148         }
     136    /**
     137    * Performs "clean-up" on the initialised segments
     138    */
     139    public void cleanupWays() {
     140        if (algnSeg != null) {
     141            algnSeg.destroy();
     142            algnSeg = null;
     143        }
     144        if (refSeg != null) {
     145            refSeg.destroy();
     146            refSeg = null;
     147        }
     148    }
    149149
    150         public AlignWaysAlgnSegment getAlgnSeg() {
    151                 return algnSeg;
    152         }
     150    public AlignWaysAlgnSegment getAlgnSeg() {
     151        return algnSeg;
     152    }
    153153
    154         /**
    155         * @return the refSeg
    156         */
    157         public AlignWaysRefSegment getRefSeg() {
    158                 return refSeg;
    159         }
     154    /**
     155    * @return the refSeg
     156    */
     157    public AlignWaysRefSegment getRefSeg() {
     158        return refSeg;
     159    }
    160160
    161161}
  • applications/editors/josm/plugins/alignways/src/org/openstreetmap/josm/plugins/alignways/AlignWaysSelAlgnState.java

    r21613 r23189  
    1212public class AlignWaysSelAlgnState extends AlignWaysState {
    1313
    14         @Override
    15         public void leftClick(AlignWaysMode alignWaysMode) {
    16                 // No state change, nothing to do
    17         }
     14    @Override
     15    public void leftClick(AlignWaysMode alignWaysMode) {
     16        // No state change, nothing to do
     17    }
    1818
    19         @Override
    20         public void ctrlLClick(AlignWaysMode alignWaysMode) {
    21                 alignWaysMode.setCurrentState(alignWaysMode.getBothSelected());
    22         }
     19    @Override
     20    public void ctrlLClick(AlignWaysMode alignWaysMode) {
     21        alignWaysMode.setCurrentState(alignWaysMode.getBothSelected());
     22    }
    2323
    24         @Override
    25         public void setHelpText() {
    26                 Main.map.statusLine
    27                                 .setHelpText("Ctrl-Click: select reference way segment; Alt-click: Clear selection");
    28         }
     24    @Override
     25    public void setHelpText() {
     26        Main.map.statusLine
     27                .setHelpText("Ctrl-Click: select reference way segment; Alt-click: Clear selection");
     28    }
    2929
    3030}
  • applications/editors/josm/plugins/alignways/src/org/openstreetmap/josm/plugins/alignways/AlignWaysSelBothState.java

    r22758 r23189  
    1212public class AlignWaysSelBothState extends AlignWaysState {
    1313
    14         @Override
    15         public void leftClick(AlignWaysMode alignWaysMode) {
    16                 // No state change, nothing to do
    17         }
     14    @Override
     15    public void leftClick(AlignWaysMode alignWaysMode) {
     16        // No state change, nothing to do
     17    }
    1818
    19         @Override
    20         public void ctrlLClick(AlignWaysMode alignWaysMode) {
    21                 // No state change, nothing to do
    22         }
     19    @Override
     20    public void ctrlLClick(AlignWaysMode alignWaysMode) {
     21        // No state change, nothing to do
     22    }
    2323
    24         @Override
    25         public void setHelpText() {
    26                 Main.map.statusLine
    27                 .setHelpText(AlignWaysPlugin.getAwAction().getShortcut().getKeyText() +
    28                                 ": Align segments; Alt-click: Clear selection");
    29         }
     24    @Override
     25    public void setHelpText() {
     26        Main.map.statusLine
     27        .setHelpText(AlignWaysPlugin.getAwAction().getShortcut().getKeyText() +
     28                ": Align segments; Alt-click: Clear selection");
     29    }
    3030
    3131}
  • applications/editors/josm/plugins/alignways/src/org/openstreetmap/josm/plugins/alignways/AlignWaysSelNoneState.java

    r21613 r23189  
    1212public class AlignWaysSelNoneState extends AlignWaysState {
    1313
    14         @Override
    15         public void leftClick(AlignWaysMode alignWaysMode) {
    16                 // Reference way segment selected successfully
    17                 alignWaysMode.setCurrentState(alignWaysMode.getAligneeSelected());
     14    @Override
     15    public void leftClick(AlignWaysMode alignWaysMode) {
     16        // Reference way segment selected successfully
     17        alignWaysMode.setCurrentState(alignWaysMode.getAligneeSelected());
    1818
    19         }
     19    }
    2020
    21         @Override
    22         public void ctrlLClick(AlignWaysMode alignWaysMode) {
    23                 // Reference way segment selected successfully
    24                 alignWaysMode.setCurrentState(alignWaysMode.getReferenceSelected());
    25         }
     21    @Override
     22    public void ctrlLClick(AlignWaysMode alignWaysMode) {
     23        // Reference way segment selected successfully
     24        alignWaysMode.setCurrentState(alignWaysMode.getReferenceSelected());
     25    }
    2626
    27         @Override
    28         public void setHelpText() {
    29                 Main.map.statusLine
    30                 .setHelpText("Ctrl-click: select reference way segment; Click: select way segment to be aligned");
    31         }
     27    @Override
     28    public void setHelpText() {
     29        Main.map.statusLine
     30        .setHelpText("Ctrl-click: select reference way segment; Click: select way segment to be aligned");
     31    }
    3232
    3333}
  • applications/editors/josm/plugins/alignways/src/org/openstreetmap/josm/plugins/alignways/AlignWaysSelRefState.java

    r21613 r23189  
    1212public class AlignWaysSelRefState extends AlignWaysState {
    1313
    14         @Override
    15         public void leftClick(AlignWaysMode alignWaysMode) {
    16                 alignWaysMode.setCurrentState(alignWaysMode.getBothSelected());
    17         }
     14    @Override
     15    public void leftClick(AlignWaysMode alignWaysMode) {
     16        alignWaysMode.setCurrentState(alignWaysMode.getBothSelected());
     17    }
    1818
    19         @Override
    20         public void ctrlLClick(AlignWaysMode alignWaysMode) {
    21                 // No state change, nothing to do
    22         }
     19    @Override
     20    public void ctrlLClick(AlignWaysMode alignWaysMode) {
     21        // No state change, nothing to do
     22    }
    2323
    24         @Override
    25         public void setHelpText() {
    26                 Main.map.statusLine
    27                                 .setHelpText("Click: select way segment to be aligned; Alt-click: Clear selection");
    28         }
     24    @Override
     25    public void setHelpText() {
     26        Main.map.statusLine
     27                .setHelpText("Click: select way segment to be aligned; Alt-click: Clear selection");
     28    }
    2929
    3030}
  • applications/editors/josm/plugins/alignways/src/org/openstreetmap/josm/plugins/alignways/AlignWaysState.java

    r21613 r23189  
    1212public abstract class AlignWaysState {
    1313
    14         public abstract void leftClick(AlignWaysMode alignWaysMode);
     14    public abstract void leftClick(AlignWaysMode alignWaysMode);
    1515
    16         public abstract void ctrlLClick(AlignWaysMode alignWaysMode);
     16    public abstract void ctrlLClick(AlignWaysMode alignWaysMode);
    1717
    18         public abstract void setHelpText();
     18    public abstract void setHelpText();
    1919
    20         public void altLClick(AlignWaysMode alignWaysMode) {
    21                 alignWaysMode.setCurrentState(alignWaysMode.getNoneSelected());
    22                 Main.map.statusLine
    23                 .setHelpText("Ctrl-Click: select reference way segment; Click: select way segment to be aligned");
    24         }
     20    public void altLClick(AlignWaysMode alignWaysMode) {
     21        alignWaysMode.setCurrentState(alignWaysMode.getNoneSelected());
     22        Main.map.statusLine
     23        .setHelpText("Ctrl-Click: select reference way segment; Click: select way segment to be aligned");
     24    }
    2525
    2626}
  • applications/editors/josm/plugins/alignways/src/org/openstreetmap/josm/plugins/alignways/AlignWaysTipsPanel.java

    r22842 r23189  
    2727public class AlignWaysTipsPanel extends javax.swing.JPanel {
    2828
    29         private static final long serialVersionUID = -8583989497599985140L;
    30 
    31         public AlignWaysTipsPanel() {
    32                 initComponents();
    33         }
    34 
    35         private void initComponents() {
    36 
    37                 Title = new JPanel();
    38                 WelcomeTo = new JLabel();
    39                 Icon = new JLabel();
    40                 separator = new JSeparator();
    41                 Intro = new JPanel();
    42                 introText = new JLabel();
    43                 scrollableSteps = new JScrollPane();
    44                 steps = new JPanel();
    45                 step01 = new JLabel();
    46                 step02 = new JLabel();
    47                 step03 = new JLabel();
    48                 step04 = new JLabel();
    49                 lastHint = new JLabel();
    50                 dontShow = new JCheckBox();
    51 
    52                 setAutoscrolls(true);
    53 
    54                 WelcomeTo.setText(tr("<html>\n<div style=\"font-family: 'sans-serif'; font-weight: bold; font-style: italic;\">\n<span style=\"font-size: large;\">Welcome to the</span><br>\n<span style=\"font-size: xx-large;\">AlignWay<span style=\"color: rgb(204, 85, 0);\">S</span> Plugin<br>\n</span><span style=\"font-size: medium;\"><br>\n...or it rather should be called <br>\n<span style=\"font-size: large;\">AlignWayS(egments)</span> Plugin...</span>\n</div>\n</html>"));
    55 
    56                 WelcomeTo.setVerticalAlignment(SwingConstants.TOP);
    57                 WelcomeTo.setPreferredSize(new Dimension(400, 128));
    58 
    59                 Icon.setIcon(new ImageIcon(getClass().getResource("/images/tipsdialog/alignways128.png"))); // NOI18N
    60                 GroupLayout TitleLayout = new GroupLayout(Title);
    61                 Title.setLayout(TitleLayout);
    62                 TitleLayout.setHorizontalGroup(
    63                                 TitleLayout.createParallelGroup(GroupLayout.LEADING)
    64                                 .add(GroupLayout.TRAILING, TitleLayout.createSequentialGroup()
    65                                                 .add(WelcomeTo, GroupLayout.DEFAULT_SIZE, 396, Short.MAX_VALUE)
    66                                                 .addPreferredGap(LayoutStyle.RELATED)
    67                                                 .add(Icon, GroupLayout.PREFERRED_SIZE, 132, GroupLayout.PREFERRED_SIZE))
    68                 );
    69                 TitleLayout.setVerticalGroup(
    70                                 TitleLayout.createParallelGroup(GroupLayout.LEADING)
    71                                 .add(TitleLayout.createSequentialGroup()
    72                                                 .add(Icon)
    73                                                 .addContainerGap())
    74                                                 .add(WelcomeTo, GroupLayout.DEFAULT_SIZE, 146, Short.MAX_VALUE)
    75                 );
    76 
    77                 Intro.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
    78 
    79                 introText.setText(tr("<html>\n<p style=\"font-family: sans-serif; font-weight: bold;\">AlignWays will\nhelp you to align two way segments. This can be handy when for instance\nyou sketch the outlines of a building and want its side to be parallel\nwith a street or road.<br>\n<br>\nSome tips may help before you start:\n</p>\n</html>\n\n"));
    80                 introText.setVerticalAlignment(SwingConstants.TOP);
    81 
    82                 scrollableSteps.setBorder(null);
    83                 scrollableSteps.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
    84 
    85                 step01.setIcon(new ImageIcon(getClass().getResource("/images/tipsdialog/hlpRefSel.png"))); // NOI18N
    86                 step01.setText(tr("<html>\n<div style=\"font-family: sans-serif;\">\n<ul>\n<li><b>Select a reference segment.</b> You can do this by <b><i><span style=\"color:green\">Ctrl-click</span></i></b>ing\non a segment. The other, to be aligned segment will become parallel to\nthis one. </li>\n</ul>\n</div>\n</html>\n\n"));
    87                 step01.setVerticalAlignment(SwingConstants.TOP);
    88 
    89                 step02.setIcon(new ImageIcon(getClass().getResource("/images/tipsdialog/hlpAlgSel.png"))); // NOI18N
    90                 step02.setText(tr("<html>\n<div style=\"font-family:sans-serif\">\n<ul>\n  <li><b>Select the to be aligned segment.</b> You can do this by simply <b><i><span style=\"color:green\">click</span></i></b>ing on a different segment. \nThe rotation pivot will be highlighted by default in the centre of the segment.\n  </li>\n</ul>\n</div>\n</html>\n\n"));
    91                 step02.setVerticalAlignment(SwingConstants.TOP);
    92 
    93                 step03.setIcon(new ImageIcon(getClass().getResource("/images/tipsdialog/hlpPvtSel.png"))); // NOI18N
    94                 step03.setText(tr("<html>\n<div style=\"font-family:sans-serif\">\n<ul>\n  <li>Optionally <b>change the rotation pivot point</b>. In order to get parallel with the reference segment, the to be aligned segment will rotate around this point. You can choose the two extremities or the centre of the segment by <b><i><span style=\"color:green\">click</span></i></b>ing nearby. \n  </li>\n</ul>\n</div>\n</html>\n\n"));
    95                 step03.setVerticalAlignment(SwingConstants.TOP);
    96 
    97                 step04.setIcon(new ImageIcon(getClass().getResource("/images/tipsdialog/hlpAlgCmd.png"))); // NOI18N
    98                 step04.setText(tr("<html>\n<div style=\"font-family:sans-serif\">\n<ul>\n  <li><b>Align the segments.</b> Press <b><i><span style=\"color:green\">"
    99                                 + AlignWaysPlugin.awAction.getShortcut().getKeyText()
    100                                 + "</span></i></b>. Alternatively you''ll find the command in the <b>Tools</b>\n menu or may want to place the action on the <b>toolbar</b>.\n  </li>\n</ul>\n</div>\n</html>\n\n"));
    101                 step04.setVerticalAlignment(SwingConstants.TOP);
    102 
    103                 lastHint.setText(tr("<html>\n<div style=\"font-family:sans-serif\">\n<b>Last hint:</b> There is an easy way to start over your selections if you want: <b><i><span style=\"color:green\">Alt-Click</span></i></b> somewhere on the map.\n</div>\n</html>\n\n"));
    104                 lastHint.setVerticalAlignment(SwingConstants.TOP);
    105 
    106                 GroupLayout stepsLayout = new GroupLayout(steps);
    107                 steps.setLayout(stepsLayout);
    108                 stepsLayout.setHorizontalGroup(
    109                                 stepsLayout.createParallelGroup(GroupLayout.LEADING)
    110                                 .add(stepsLayout.createSequentialGroup()
    111                                                 .addContainerGap()
    112                                                 .add(stepsLayout.createParallelGroup(GroupLayout.TRAILING)
    113                                                                 .add(GroupLayout.LEADING, lastHint, 0, 0, Short.MAX_VALUE)
    114                                                                 .add(GroupLayout.LEADING, step04, 0, 0, Short.MAX_VALUE)
    115                                                                 .add(GroupLayout.LEADING, step03, 0, 0, Short.MAX_VALUE)
    116                                                                 .add(GroupLayout.LEADING, step02, 0, 0, Short.MAX_VALUE)
    117                                                                 .add(GroupLayout.LEADING, step01, GroupLayout.DEFAULT_SIZE, 496, Short.MAX_VALUE))
    118                                                                 .add(18, 18, 18))
    119                 );
    120                 stepsLayout.setVerticalGroup(
    121                                 stepsLayout.createParallelGroup(GroupLayout.LEADING)
    122                                 .add(stepsLayout.createSequentialGroup()
    123                                                 .add(step01, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
    124                                                 .addPreferredGap(LayoutStyle.RELATED)
    125                                                 .add(step02, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
    126                                                 .addPreferredGap(LayoutStyle.RELATED)
    127                                                 .add(step03, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
    128                                                 .addPreferredGap(LayoutStyle.RELATED)
    129                                                 .add(step04, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
    130                                                 .addPreferredGap(LayoutStyle.RELATED)
    131                                                 .add(lastHint, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
    132                                                 .addContainerGap(22, Short.MAX_VALUE))
    133                 );
    134 
    135                 scrollableSteps.setViewportView(steps);
    136 
    137                 dontShow.setText(tr("Don''t show this again"));
    138 
    139                 GroupLayout IntroLayout = new GroupLayout(Intro);
    140                 Intro.setLayout(IntroLayout);
    141                 IntroLayout.setHorizontalGroup(
    142                                 IntroLayout.createParallelGroup(GroupLayout.LEADING)
    143                                 .add(IntroLayout.createSequentialGroup()
    144                                                 .addContainerGap()
    145                                                 .add(dontShow, GroupLayout.PREFERRED_SIZE, 245, GroupLayout.PREFERRED_SIZE)
    146                                                 .addContainerGap(283, Short.MAX_VALUE))
    147                                                 .add(scrollableSteps, GroupLayout.DEFAULT_SIZE, 534, Short.MAX_VALUE)
    148                                                 .add(introText, GroupLayout.DEFAULT_SIZE, 534, Short.MAX_VALUE)
    149                 );
    150                 IntroLayout.setVerticalGroup(
    151                                 IntroLayout.createParallelGroup(GroupLayout.LEADING)
    152                                 .add(GroupLayout.TRAILING, IntroLayout.createSequentialGroup()
    153                                                 .add(introText, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
    154                                                 .addPreferredGap(LayoutStyle.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
    155                                                 .add(scrollableSteps, GroupLayout.PREFERRED_SIZE, 209, GroupLayout.PREFERRED_SIZE)
    156                                                 .addPreferredGap(LayoutStyle.UNRELATED)
    157                                                 .add(dontShow)
    158                                                 .addContainerGap())
    159                 );
    160 
    161                 GroupLayout layout = new GroupLayout(this);
    162                 this.setLayout(layout);
    163                 layout.setHorizontalGroup(
    164                                 layout.createParallelGroup(GroupLayout.LEADING)
    165                                 .add(GroupLayout.TRAILING, layout.createSequentialGroup()
    166                                                 .addContainerGap()
    167                                                 .add(layout.createParallelGroup(GroupLayout.TRAILING)
    168                                                                 .add(GroupLayout.LEADING, separator, GroupLayout.DEFAULT_SIZE, 534, Short.MAX_VALUE)
    169                                                                 .add(Title, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
    170                                                                 .add(Intro, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
    171                                                                 .addContainerGap())
    172                 );
    173                 layout.setVerticalGroup(
    174                                 layout.createParallelGroup(GroupLayout.LEADING)
    175                                 .add(layout.createSequentialGroup()
    176                                                 .addContainerGap()
    177                                                 .add(Title, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
    178                                                 .addPreferredGap(LayoutStyle.UNRELATED)
    179                                                 .add(separator, GroupLayout.PREFERRED_SIZE, 17, GroupLayout.PREFERRED_SIZE)
    180                                                 .addPreferredGap(LayoutStyle.RELATED)
    181                                                 .add(Intro, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
    182                                                 .addContainerGap(45, Short.MAX_VALUE))
    183                 );
    184         }
    185 
    186 
    187         private JLabel Icon;
    188         private JPanel Intro;
    189         private JPanel Title;
    190         private JLabel WelcomeTo;
    191         private JCheckBox dontShow;
    192         private JLabel introText;
    193         private JLabel lastHint;
    194         private JScrollPane scrollableSteps;
    195         private JSeparator separator;
    196         private JLabel step01;
    197         private JLabel step02;
    198         private JLabel step03;
    199         private JLabel step04;
    200         private JPanel steps;
    201 
    202         public boolean isChkBoxSelected() {
    203                 return dontShow.isSelected();
    204         }
     29    private static final long serialVersionUID = -8583989497599985140L;
     30
     31    public AlignWaysTipsPanel() {
     32        initComponents();
     33    }
     34
     35    private void initComponents() {
     36
     37        Title = new JPanel();
     38        WelcomeTo = new JLabel();
     39        Icon = new JLabel();
     40        separator = new JSeparator();
     41        Intro = new JPanel();
     42        introText = new JLabel();
     43        scrollableSteps = new JScrollPane();
     44        steps = new JPanel();
     45        step01 = new JLabel();
     46        step02 = new JLabel();
     47        step03 = new JLabel();
     48        step04 = new JLabel();
     49        lastHint = new JLabel();
     50        dontShow = new JCheckBox();
     51
     52        setAutoscrolls(true);
     53
     54        WelcomeTo.setText(tr("<html>\n<div style=\"font-family: 'sans-serif'; font-weight: bold; font-style: italic;\">\n<span style=\"font-size: large;\">Welcome to the</span><br>\n<span style=\"font-size: xx-large;\">AlignWay<span style=\"color: rgb(204, 85, 0);\">S</span> Plugin<br>\n</span><span style=\"font-size: medium;\"><br>\n...or it rather should be called <br>\n<span style=\"font-size: large;\">AlignWayS(egments)</span> Plugin...</span>\n</div>\n</html>"));
     55
     56        WelcomeTo.setVerticalAlignment(SwingConstants.TOP);
     57        WelcomeTo.setPreferredSize(new Dimension(400, 128));
     58
     59        Icon.setIcon(new ImageIcon(getClass().getResource("/images/tipsdialog/alignways128.png"))); // NOI18N
     60        GroupLayout TitleLayout = new GroupLayout(Title);
     61        Title.setLayout(TitleLayout);
     62        TitleLayout.setHorizontalGroup(
     63                TitleLayout.createParallelGroup(GroupLayout.LEADING)
     64                .add(GroupLayout.TRAILING, TitleLayout.createSequentialGroup()
     65                        .add(WelcomeTo, GroupLayout.DEFAULT_SIZE, 396, Short.MAX_VALUE)
     66                        .addPreferredGap(LayoutStyle.RELATED)
     67                        .add(Icon, GroupLayout.PREFERRED_SIZE, 132, GroupLayout.PREFERRED_SIZE))
     68        );
     69        TitleLayout.setVerticalGroup(
     70                TitleLayout.createParallelGroup(GroupLayout.LEADING)
     71                .add(TitleLayout.createSequentialGroup()
     72                        .add(Icon)
     73                        .addContainerGap())
     74                        .add(WelcomeTo, GroupLayout.DEFAULT_SIZE, 146, Short.MAX_VALUE)
     75        );
     76
     77        Intro.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
     78
     79        introText.setText(tr("<html>\n<p style=\"font-family: sans-serif; font-weight: bold;\">AlignWays will\nhelp you to align two way segments. This can be handy when for instance\nyou sketch the outlines of a building and want its side to be parallel\nwith a street or road.<br>\n<br>\nSome tips may help before you start:\n</p>\n</html>\n\n"));
     80        introText.setVerticalAlignment(SwingConstants.TOP);
     81
     82        scrollableSteps.setBorder(null);
     83        scrollableSteps.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
     84
     85        step01.setIcon(new ImageIcon(getClass().getResource("/images/tipsdialog/hlpRefSel.png"))); // NOI18N
     86        step01.setText(tr("<html>\n<div style=\"font-family: sans-serif;\">\n<ul>\n<li><b>Select a reference segment.</b> You can do this by <b><i><span style=\"color:green\">Ctrl-click</span></i></b>ing\non a segment. The other, to be aligned segment will become parallel to\nthis one. </li>\n</ul>\n</div>\n</html>\n\n"));
     87        step01.setVerticalAlignment(SwingConstants.TOP);
     88
     89        step02.setIcon(new ImageIcon(getClass().getResource("/images/tipsdialog/hlpAlgSel.png"))); // NOI18N
     90        step02.setText(tr("<html>\n<div style=\"font-family:sans-serif\">\n<ul>\n  <li><b>Select the to be aligned segment.</b> You can do this by simply <b><i><span style=\"color:green\">click</span></i></b>ing on a different segment. \nThe rotation pivot will be highlighted by default in the centre of the segment.\n  </li>\n</ul>\n</div>\n</html>\n\n"));
     91        step02.setVerticalAlignment(SwingConstants.TOP);
     92
     93        step03.setIcon(new ImageIcon(getClass().getResource("/images/tipsdialog/hlpPvtSel.png"))); // NOI18N
     94        step03.setText(tr("<html>\n<div style=\"font-family:sans-serif\">\n<ul>\n  <li>Optionally <b>change the rotation pivot point</b>. In order to get parallel with the reference segment, the to be aligned segment will rotate around this point. You can choose the two extremities or the centre of the segment by <b><i><span style=\"color:green\">click</span></i></b>ing nearby. \n  </li>\n</ul>\n</div>\n</html>\n\n"));
     95        step03.setVerticalAlignment(SwingConstants.TOP);
     96
     97        step04.setIcon(new ImageIcon(getClass().getResource("/images/tipsdialog/hlpAlgCmd.png"))); // NOI18N
     98        step04.setText(tr("<html>\n<div style=\"font-family:sans-serif\">\n<ul>\n  <li><b>Align the segments.</b> Press <b><i><span style=\"color:green\">"
     99                + AlignWaysPlugin.awAction.getShortcut().getKeyText()
     100                + "</span></i></b>. Alternatively you''ll find the command in the <b>Tools</b>\n menu or may want to place the action on the <b>toolbar</b>.\n  </li>\n</ul>\n</div>\n</html>\n\n"));
     101        step04.setVerticalAlignment(SwingConstants.TOP);
     102
     103        lastHint.setText(tr("<html>\n<div style=\"font-family:sans-serif\">\n<b>Last hint:</b> There is an easy way to start over your selections if you want: <b><i><span style=\"color:green\">Alt-Click</span></i></b> somewhere on the map.\n</div>\n</html>\n\n"));
     104        lastHint.setVerticalAlignment(SwingConstants.TOP);
     105
     106        GroupLayout stepsLayout = new GroupLayout(steps);
     107        steps.setLayout(stepsLayout);
     108        stepsLayout.setHorizontalGroup(
     109                stepsLayout.createParallelGroup(GroupLayout.LEADING)
     110                .add(stepsLayout.createSequentialGroup()
     111                        .addContainerGap()
     112                        .add(stepsLayout.createParallelGroup(GroupLayout.TRAILING)
     113                                .add(GroupLayout.LEADING, lastHint, 0, 0, Short.MAX_VALUE)
     114                                .add(GroupLayout.LEADING, step04, 0, 0, Short.MAX_VALUE)
     115                                .add(GroupLayout.LEADING, step03, 0, 0, Short.MAX_VALUE)
     116                                .add(GroupLayout.LEADING, step02, 0, 0, Short.MAX_VALUE)
     117                                .add(GroupLayout.LEADING, step01, GroupLayout.DEFAULT_SIZE, 496, Short.MAX_VALUE))
     118                                .add(18, 18, 18))
     119        );
     120        stepsLayout.setVerticalGroup(
     121                stepsLayout.createParallelGroup(GroupLayout.LEADING)
     122                .add(stepsLayout.createSequentialGroup()
     123                        .add(step01, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
     124                        .addPreferredGap(LayoutStyle.RELATED)
     125                        .add(step02, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
     126                        .addPreferredGap(LayoutStyle.RELATED)
     127                        .add(step03, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
     128                        .addPreferredGap(LayoutStyle.RELATED)
     129                        .add(step04, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
     130                        .addPreferredGap(LayoutStyle.RELATED)
     131                        .add(lastHint, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
     132                        .addContainerGap(22, Short.MAX_VALUE))
     133        );
     134
     135        scrollableSteps.setViewportView(steps);
     136
     137        dontShow.setText(tr("Don''t show this again"));
     138
     139        GroupLayout IntroLayout = new GroupLayout(Intro);
     140        Intro.setLayout(IntroLayout);
     141        IntroLayout.setHorizontalGroup(
     142                IntroLayout.createParallelGroup(GroupLayout.LEADING)
     143                .add(IntroLayout.createSequentialGroup()
     144                        .addContainerGap()
     145                        .add(dontShow, GroupLayout.PREFERRED_SIZE, 245, GroupLayout.PREFERRED_SIZE)
     146                        .addContainerGap(283, Short.MAX_VALUE))
     147                        .add(scrollableSteps, GroupLayout.DEFAULT_SIZE, 534, Short.MAX_VALUE)
     148                        .add(introText, GroupLayout.DEFAULT_SIZE, 534, Short.MAX_VALUE)
     149        );
     150        IntroLayout.setVerticalGroup(
     151                IntroLayout.createParallelGroup(GroupLayout.LEADING)
     152                .add(GroupLayout.TRAILING, IntroLayout.createSequentialGroup()
     153                        .add(introText, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
     154                        .addPreferredGap(LayoutStyle.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
     155                        .add(scrollableSteps, GroupLayout.PREFERRED_SIZE, 209, GroupLayout.PREFERRED_SIZE)
     156                        .addPreferredGap(LayoutStyle.UNRELATED)
     157                        .add(dontShow)
     158                        .addContainerGap())
     159        );
     160
     161        GroupLayout layout = new GroupLayout(this);
     162        this.setLayout(layout);
     163        layout.setHorizontalGroup(
     164                layout.createParallelGroup(GroupLayout.LEADING)
     165                .add(GroupLayout.TRAILING, layout.createSequentialGroup()
     166                        .addContainerGap()
     167                        .add(layout.createParallelGroup(GroupLayout.TRAILING)
     168                                .add(GroupLayout.LEADING, separator, GroupLayout.DEFAULT_SIZE, 534, Short.MAX_VALUE)
     169                                .add(Title, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
     170                                .add(Intro, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
     171                                .addContainerGap())
     172        );
     173        layout.setVerticalGroup(
     174                layout.createParallelGroup(GroupLayout.LEADING)
     175                .add(layout.createSequentialGroup()
     176                        .addContainerGap()
     177                        .add(Title, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
     178                        .addPreferredGap(LayoutStyle.UNRELATED)
     179                        .add(separator, GroupLayout.PREFERRED_SIZE, 17, GroupLayout.PREFERRED_SIZE)
     180                        .addPreferredGap(LayoutStyle.RELATED)
     181                        .add(Intro, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
     182                        .addContainerGap(45, Short.MAX_VALUE))
     183        );
     184    }
     185
     186
     187    private JLabel Icon;
     188    private JPanel Intro;
     189    private JPanel Title;
     190    private JLabel WelcomeTo;
     191    private JCheckBox dontShow;
     192    private JLabel introText;
     193    private JLabel lastHint;
     194    private JScrollPane scrollableSteps;
     195    private JSeparator separator;
     196    private JLabel step01;
     197    private JLabel step02;
     198    private JLabel step03;
     199    private JLabel step04;
     200    private JPanel steps;
     201
     202    public boolean isChkBoxSelected() {
     203        return dontShow.isSelected();
     204    }
    205205
    206206}
  • applications/editors/josm/plugins/editgpx/src/org/openstreetmap/josm/plugins/editgpx/EditGpxLayer.java

    r22548 r23189  
    3535public class EditGpxLayer extends Layer {
    3636
    37         private static Icon icon = new ImageIcon(Toolkit.getDefaultToolkit().createImage(EditGpxPlugin.class.getResource("/images/editgpx_layer.png")));
    38         public final EditGpxData data;
    39         private GPXLayerImportAction layerImport;
     37    private static Icon icon = new ImageIcon(Toolkit.getDefaultToolkit().createImage(EditGpxPlugin.class.getResource("/images/editgpx_layer.png")));
     38    public final EditGpxData data;
     39    private GPXLayerImportAction layerImport;
    4040
    41         public EditGpxLayer(String str, EditGpxData gpxData) {
    42                 super(str);
    43                 data = gpxData;
    44                 layerImport = new GPXLayerImportAction(data);
    45         }
     41    public EditGpxLayer(String str, EditGpxData gpxData) {
     42        super(str);
     43        data = gpxData;
     44        layerImport = new GPXLayerImportAction(data);
     45    }
    4646
    47         /**
    48         * check if dataSet is empty
    49         * if so show import dialog to user
    50         */
    51         public void initializeImport() {
    52                 try {
    53                         if(data.isEmpty()) {
    54                                 layerImport.activateImport();
    55                         }
    56                 } catch (Exception e) {
    57                         System.out.println(e.getMessage());
    58                         e.printStackTrace();
    59                 }
    60         }
     47    /**
     48    * check if dataSet is empty
     49    * if so show import dialog to user
     50    */
     51    public void initializeImport() {
     52        try {
     53            if(data.isEmpty()) {
     54                layerImport.activateImport();
     55            }
     56        } catch (Exception e) {
     57            System.out.println(e.getMessage());
     58            e.printStackTrace();
     59        }
     60    }
    6161
    62         @Override
    63         public Icon getIcon() {
    64                 return icon;
    65         }
     62    @Override
     63    public Icon getIcon() {
     64        return icon;
     65    }
    6666
    67         @Override
    68         public Object getInfoComponent() {
    69                 return getToolTipText();
    70         }
     67    @Override
     68    public Object getInfoComponent() {
     69        return getToolTipText();
     70    }
    7171
    72         @Override
    73         public Action[] getMenuEntries() {
    74                 return new Action[] {
    75                                 LayerListDialog.getInstance().createShowHideLayerAction(),
    76                                 LayerListDialog.getInstance().createDeleteLayerAction(),
    77                                 SeparatorLayerAction.INSTANCE,
    78                                 layerImport,
    79                                 new ConvertToGpxLayerAction(),
    80                                 new ConvertToAnonTimeGpxLayerAction(),
    81                                 SeparatorLayerAction.INSTANCE,
    82                                 new LayerListPopup.InfoAction(this)};
    83         }
     72    @Override
     73    public Action[] getMenuEntries() {
     74        return new Action[] {
     75                LayerListDialog.getInstance().createShowHideLayerAction(),
     76                LayerListDialog.getInstance().createDeleteLayerAction(),
     77                SeparatorLayerAction.INSTANCE,
     78                layerImport,
     79                new ConvertToGpxLayerAction(),
     80                new ConvertToAnonTimeGpxLayerAction(),
     81                SeparatorLayerAction.INSTANCE,
     82                new LayerListPopup.InfoAction(this)};
     83    }
    8484
    85         @Override
    86         public String getToolTipText() {
    87                 return tr("Layer for editing GPX tracks");
    88         }
     85    @Override
     86    public String getToolTipText() {
     87        return tr("Layer for editing GPX tracks");
     88    }
    8989
    90         @Override
    91         public boolean isMergable(Layer other) {
    92                 // TODO
    93                 return false;
    94         }
     90    @Override
     91    public boolean isMergable(Layer other) {
     92        // TODO
     93        return false;
     94    }
    9595
    96         @Override
    97         public void mergeFrom(Layer from) {
    98                 // TODO
    99         }
     96    @Override
     97    public void mergeFrom(Layer from) {
     98        // TODO
     99    }
    100100
    101         @Override
    102         public void paint(Graphics2D g, MapView mv, Bounds bounds) {
    103                 g.setColor(Color.yellow);
     101    @Override
     102    public void paint(Graphics2D g, MapView mv, Bounds bounds) {
     103        g.setColor(Color.yellow);
    104104
    105                 //don't iterate through dataSet whiling making changes
    106                 synchronized(layerImport.importing) {
    107                         for (EditGpxTrack track: data.getTracks()) {
    108                                 for (EditGpxTrackSegment segment: track.getSegments()) {
    109                                         for (EditGpxWayPoint wayPoint: segment.getWayPoints()) {
    110                                                 if (!wayPoint.isDeleted()) {
    111                                                         Point pnt = Main.map.mapView.getPoint(wayPoint.getCoor().getEastNorth());
    112                                                         g.drawOval(pnt.x - 2, pnt.y - 2, 4, 4);
    113                                                 }
    114                                         }
    115                                 }
    116                         }
    117                 }
    118         }
     105        //don't iterate through dataSet whiling making changes
     106        synchronized(layerImport.importing) {
     107            for (EditGpxTrack track: data.getTracks()) {
     108                for (EditGpxTrackSegment segment: track.getSegments()) {
     109                    for (EditGpxWayPoint wayPoint: segment.getWayPoints()) {
     110                        if (!wayPoint.isDeleted()) {
     111                            Point pnt = Main.map.mapView.getPoint(wayPoint.getCoor().getEastNorth());
     112                            g.drawOval(pnt.x - 2, pnt.y - 2, 4, 4);
     113                        }
     114                    }
     115                }
     116            }
     117        }
     118    }
    119119
    120120
    121         public void reset(){
    122                 //TODO implement a reset
    123         }
     121    public void reset(){
     122        //TODO implement a reset
     123    }
    124124
    125125
    126         @Override
    127         public void visitBoundingBox(BoundingXYVisitor v) {
    128                 // TODO Auto-generated method stub
    129         }
     126    @Override
     127    public void visitBoundingBox(BoundingXYVisitor v) {
     128        // TODO Auto-generated method stub
     129    }
    130130
    131131
    132         /**
    133         * convert a DataSet to GPX
    134         *
    135         * @param boolean anonTime If true set all time and date in GPX to 01/01/1970 00:00 ?
    136         * @return GPXData
    137         */
    138         private GpxData toGpxData(boolean anonTime) {
    139                 return data.createGpxData();
    140         }
     132    /**
     133    * convert a DataSet to GPX
     134    *
     135    * @param boolean anonTime If true set all time and date in GPX to 01/01/1970 00:00 ?
     136    * @return GPXData
     137    */
     138    private GpxData toGpxData(boolean anonTime) {
     139        return data.createGpxData();
     140    }
    141141
    142         //context item "Convert to GPX layer"
    143         public class ConvertToGpxLayerAction extends AbstractAction {
    144                 public ConvertToGpxLayerAction() {
    145                         super(tr("Convert to GPX layer"), ImageProvider.get("converttogpx"));
    146                 }
    147                 public void actionPerformed(ActionEvent e) {
    148                         Main.main.addLayer(new GpxLayer(toGpxData(false), tr("Converted from: {0}", getName())));
    149                         Main.main.removeLayer(EditGpxLayer.this);
    150                         if(Main.map.mapMode instanceof EditGpxMode)
    151                                 Main.map.selectSelectTool(false);
    152                 }
    153         }
     142    //context item "Convert to GPX layer"
     143    public class ConvertToGpxLayerAction extends AbstractAction {
     144        public ConvertToGpxLayerAction() {
     145            super(tr("Convert to GPX layer"), ImageProvider.get("converttogpx"));
     146        }
     147        public void actionPerformed(ActionEvent e) {
     148            Main.main.addLayer(new GpxLayer(toGpxData(false), tr("Converted from: {0}", getName())));
     149            Main.main.removeLayer(EditGpxLayer.this);
     150            if(Main.map.mapMode instanceof EditGpxMode)
     151                Main.map.selectSelectTool(false);
     152        }
     153    }
    154154
    155         //context item "Convert to GPX layer with anonymised time"
    156         public class ConvertToAnonTimeGpxLayerAction extends AbstractAction {
    157                 public ConvertToAnonTimeGpxLayerAction() {
    158                         super(tr("Convert to GPX layer with anonymised time"), ImageProvider.get("converttogpx"));
    159                 }
    160                 public void actionPerformed(ActionEvent e) {
    161                         Main.main.addLayer(new GpxLayer(toGpxData(true), tr("Converted from: {0}", getName())));
    162                         Main.main.removeLayer(EditGpxLayer.this);
    163                         if(Main.map.mapMode instanceof EditGpxMode)
    164                                 Main.map.selectSelectTool(false);
    165                 }
    166         }
     155    //context item "Convert to GPX layer with anonymised time"
     156    public class ConvertToAnonTimeGpxLayerAction extends AbstractAction {
     157        public ConvertToAnonTimeGpxLayerAction() {
     158            super(tr("Convert to GPX layer with anonymised time"), ImageProvider.get("converttogpx"));
     159        }
     160        public void actionPerformed(ActionEvent e) {
     161            Main.main.addLayer(new GpxLayer(toGpxData(true), tr("Converted from: {0}", getName())));
     162            Main.main.removeLayer(EditGpxLayer.this);
     163            if(Main.map.mapMode instanceof EditGpxMode)
     164                Main.map.selectSelectTool(false);
     165        }
     166    }
    167167}
  • applications/editors/josm/plugins/editgpx/src/org/openstreetmap/josm/plugins/editgpx/EditGpxMode.java

    r21582 r23189  
    2929public class EditGpxMode extends MapMode implements LayerChangeListener {
    3030
    31         private static final long serialVersionUID = 7940589057093872411L;
    32         Point pointPressed;
    33         MapFrame mapFrame;
    34         Rectangle oldRect;
    35         MapFrame frame;
    36         EditGpxLayer currentEditLayer;
     31    private static final long serialVersionUID = 7940589057093872411L;
     32    Point pointPressed;
     33    MapFrame mapFrame;
     34    Rectangle oldRect;
     35    MapFrame frame;
     36    EditGpxLayer currentEditLayer;
    3737
    38         public EditGpxMode(MapFrame mapFrame, String name, String desc) {
    39                 super(name, "editgpx_mode.png", desc, mapFrame, Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
    40         }
     38    public EditGpxMode(MapFrame mapFrame, String name, String desc) {
     39        super(name, "editgpx_mode.png", desc, mapFrame, Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
     40    }
    4141
    42         @Override public void enterMode() {
    43                 super.enterMode();
    44                 Main.map.mapView.addMouseListener(this);
    45                 Main.map.mapView.addMouseMotionListener(this);
    46                 MapView.addLayerChangeListener(this);
    47                 updateLayer();
    48         }
     42    @Override public void enterMode() {
     43        super.enterMode();
     44        Main.map.mapView.addMouseListener(this);
     45        Main.map.mapView.addMouseMotionListener(this);
     46        MapView.addLayerChangeListener(this);
     47        updateLayer();
     48    }
    4949
    50         @Override public void exitMode() {
    51                 super.exitMode();
    52                 Main.map.mapView.removeMouseListener(this);
    53                 Main.map.mapView.removeMouseMotionListener(this);
    54         }
     50    @Override public void exitMode() {
     51        super.exitMode();
     52        Main.map.mapView.removeMouseListener(this);
     53        Main.map.mapView.removeMouseMotionListener(this);
     54    }
    5555
    5656
    57         @Override public void mousePressed(MouseEvent e) {
    58                 pointPressed = new Point(e.getPoint());
    59         }
     57    @Override public void mousePressed(MouseEvent e) {
     58        pointPressed = new Point(e.getPoint());
     59    }
    6060
    6161
    62         @Override public void mouseDragged(MouseEvent e) {
    63                 if ( (e.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK) ==  InputEvent.BUTTON1_DOWN_MASK) {
    64                         //if button1 is hold, draw the rectangle.
    65                         paintRect(pointPressed, e.getPoint());
    66                 }
    67         }
     62    @Override public void mouseDragged(MouseEvent e) {
     63        if ( (e.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK) ==  InputEvent.BUTTON1_DOWN_MASK) {
     64            //if button1 is hold, draw the rectangle.
     65            paintRect(pointPressed, e.getPoint());
     66        }
     67    }
    6868
    69         @Override public void mouseReleased(MouseEvent e) {
    70                 if (e.getButton() != MouseEvent.BUTTON1) {
    71                         return;
    72                 }
     69    @Override public void mouseReleased(MouseEvent e) {
     70        if (e.getButton() != MouseEvent.BUTTON1) {
     71            return;
     72        }
    7373
    74                 Point pointReleased = e.getPoint();
     74        Point pointReleased = e.getPoint();
    7575
    76                 Rectangle r = createRect(pointReleased, pointPressed);
     76        Rectangle r = createRect(pointReleased, pointPressed);
    7777
    78                 //go through nodes and mark the ones in the selection rect as deleted
    79                 if (currentEditLayer != null) {
    80                         for (EditGpxTrack track: currentEditLayer.data.getTracks()) {
    81                                 for (EditGpxTrackSegment segment: track.getSegments()) {
    82                                         for (EditGpxWayPoint wayPoint: segment.getWayPoints()) {
    83                                                 Point p = Main.map.mapView.getPoint(wayPoint.getCoor().getEastNorth());
    84                                                 if (r.contains(p)) {
    85                                                         wayPoint.setDeleted(true);
    86                                                 }
    87                                         }
    88                                 }
    89                         }
    90                 }
    91                 oldRect = null;
    92                 Main.map.mapView.repaint();
     78        //go through nodes and mark the ones in the selection rect as deleted
     79        if (currentEditLayer != null) {
     80            for (EditGpxTrack track: currentEditLayer.data.getTracks()) {
     81                for (EditGpxTrackSegment segment: track.getSegments()) {
     82                    for (EditGpxWayPoint wayPoint: segment.getWayPoints()) {
     83                        Point p = Main.map.mapView.getPoint(wayPoint.getCoor().getEastNorth());
     84                        if (r.contains(p)) {
     85                            wayPoint.setDeleted(true);
     86                        }
     87                    }
     88                }
     89            }
     90        }
     91        oldRect = null;
     92        Main.map.mapView.repaint();
    9393
    94         }
     94    }
    9595
    96         /**
    97         * create rectangle out of two given corners
    98         */
    99         public Rectangle createRect(Point p1, Point p2) {
    100                 int x,y,w,h;
    101                 if (p1.x == p2.x && p1.y == p2.y) {
    102                         //if p1 and p2 same points draw a small rectangle around them
    103                         x = p1.x -1;
    104                         y = p1.y -1;
    105                         w = 3;
    106                         h = 3;
    107                 } else {
    108                         if (p1.x < p2.x){
    109                                 x = p1.x;
    110                                 w = p2.x-p1.x;
    111                         } else {
    112                                 x = p2.x;
    113                                 w = p1.x-p2.x;
    114                         }
    115                         if (p1.y < p2.y) {
    116                                 y = p1.y;
    117                                 h = p2.y-p1.y;
    118                         } else {
    119                                 y = p2.y;
    120                                 h = p1.y-p2.y;
    121                         }
    122                 }
    123                 return new Rectangle(x,y,w,h);
    124         }
     96    /**
     97    * create rectangle out of two given corners
     98    */
     99    public Rectangle createRect(Point p1, Point p2) {
     100        int x,y,w,h;
     101        if (p1.x == p2.x && p1.y == p2.y) {
     102            //if p1 and p2 same points draw a small rectangle around them
     103            x = p1.x -1;
     104            y = p1.y -1;
     105            w = 3;
     106            h = 3;
     107        } else {
     108            if (p1.x < p2.x){
     109                x = p1.x;
     110                w = p2.x-p1.x;
     111            } else {
     112                x = p2.x;
     113                w = p1.x-p2.x;
     114            }
     115            if (p1.y < p2.y) {
     116                y = p1.y;
     117                h = p2.y-p1.y;
     118            } else {
     119                y = p2.y;
     120                h = p1.y-p2.y;
     121            }
     122        }
     123        return new Rectangle(x,y,w,h);
     124    }
    125125
    126         /**
    127         * Draw a selection rectangle on screen.
    128         */
    129         private void paintRect(Point p1, Point p2) {
    130                 Graphics g = frame.getGraphics();//Main.map.mapView.getGraphics();
     126    /**
     127    * Draw a selection rectangle on screen.
     128    */
     129    private void paintRect(Point p1, Point p2) {
     130        Graphics g = frame.getGraphics();//Main.map.mapView.getGraphics();
    131131
    132                 Rectangle r = oldRect;
    133                 if (r != null) {
    134                         //overwrite old rct
    135                         g.setXORMode(Color.BLACK);
    136                         g.setColor(Color.WHITE);
    137                         g.drawRect(r.x,r.y,r.width,r.height);
    138                 }
     132        Rectangle r = oldRect;
     133        if (r != null) {
     134            //overwrite old rct
     135            g.setXORMode(Color.BLACK);
     136            g.setColor(Color.WHITE);
     137            g.drawRect(r.x,r.y,r.width,r.height);
     138        }
    139139
    140                 g.setXORMode(Color.BLACK);
    141                 g.setColor(Color.WHITE);
    142                 r = createRect(p1,p2);
    143                 g.drawRect(r.x,r.y,r.width,r.height);
    144                 oldRect = r;
    145         }
     140        g.setXORMode(Color.BLACK);
     141        g.setColor(Color.WHITE);
     142        r = createRect(p1,p2);
     143        g.drawRect(r.x,r.y,r.width,r.height);
     144        oldRect = r;
     145    }
    146146
    147147
    148         public void setFrame(MapFrame mapFrame) {
    149                 frame = mapFrame;
    150         }
     148    public void setFrame(MapFrame mapFrame) {
     149        frame = mapFrame;
     150    }
    151151
    152         /**
    153         * create new layer, add listeners and try importing gpx data.
    154         */
    155         private void updateLayer() {
     152    /**
     153    * create new layer, add listeners and try importing gpx data.
     154    */
     155    private void updateLayer() {
    156156
    157                 List<EditGpxLayer> layers = Main.map.mapView.getLayersOfType(EditGpxLayer.class);
    158                 currentEditLayer = layers.isEmpty()?null:layers.get(0);
     157        List<EditGpxLayer> layers = Main.map.mapView.getLayersOfType(EditGpxLayer.class);
     158        currentEditLayer = layers.isEmpty()?null:layers.get(0);
    159159
    160                 if(currentEditLayer == null) {
    161                         currentEditLayer = new EditGpxLayer(tr("EditGpx"), new EditGpxData());
    162                         Main.main.addLayer(currentEditLayer);
    163                         currentEditLayer.initializeImport();
    164                 }
    165                 Main.map.mapView.repaint();
    166         }
     160        if(currentEditLayer == null) {
     161            currentEditLayer = new EditGpxLayer(tr("EditGpx"), new EditGpxData());
     162            Main.main.addLayer(currentEditLayer);
     163            currentEditLayer.initializeImport();
     164        }
     165        Main.map.mapView.repaint();
     166    }
    167167
    168         public void activeLayerChange(Layer oldLayer, Layer newLayer) { }
     168    public void activeLayerChange(Layer oldLayer, Layer newLayer) { }
    169169
    170         public void layerAdded(Layer newLayer) { }
     170    public void layerAdded(Layer newLayer) { }
    171171
    172         public void layerRemoved(Layer oldLayer) {
    173                 if (oldLayer instanceof EditGpxLayer) {
    174                         currentEditLayer = null;
    175                         if(Main.map.mapMode instanceof EditGpxMode)
    176                                 Main.map.selectSelectTool(false);
    177                 }
    178         }
     172    public void layerRemoved(Layer oldLayer) {
     173        if (oldLayer instanceof EditGpxLayer) {
     174            currentEditLayer = null;
     175            if(Main.map.mapMode instanceof EditGpxMode)
     176                Main.map.selectSelectTool(false);
     177        }
     178    }
    179179
    180180}
  • applications/editors/josm/plugins/editgpx/src/org/openstreetmap/josm/plugins/editgpx/EditGpxPlugin.java

    r22548 r23189  
    3131public class EditGpxPlugin extends Plugin {
    3232
    33         private IconToggleButton btn;
    34         private EditGpxMode mode;
     33    private IconToggleButton btn;
     34    private EditGpxMode mode;
    3535
    36         public EditGpxPlugin(PluginInformation info) {
    37                 super(info);
    38                 mode = new EditGpxMode(Main.map, "editgpx", tr("edit gpx tracks"));
     36    public EditGpxPlugin(PluginInformation info) {
     37        super(info);
     38        mode = new EditGpxMode(Main.map, "editgpx", tr("edit gpx tracks"));
    3939
    40                 btn = new IconToggleButton(mode);
    41                 btn.setVisible(true);
    42         }
     40        btn = new IconToggleButton(mode);
     41        btn.setVisible(true);
     42    }
    4343
    44         /**
    45         * initialize button. if button is pressed create new layer.
    46         */
    47         @Override
    48         public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {
    49                 if(oldFrame == null && newFrame != null) {
    50                         mode.setFrame(newFrame);
     44    /**
     45    * initialize button. if button is pressed create new layer.
     46    */
     47    @Override
     48    public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {
     49        if(oldFrame == null && newFrame != null) {
     50            mode.setFrame(newFrame);
    5151
    52                         if(Main.map != null)
    53                                 Main.map.addMapMode(btn);
    54                 }
    55         }
     52            if(Main.map != null)
     53                Main.map.addMapMode(btn);
     54        }
     55    }
    5656
    57         public static ImageIcon loadIcon(String name) {
    58                 URL url = EditGpxPlugin.class.getResource("/images/editgpx.png");
    59                 return new ImageIcon(url);
    60         }
     57    public static ImageIcon loadIcon(String name) {
     58        URL url = EditGpxPlugin.class.getResource("/images/editgpx.png");
     59        return new ImageIcon(url);
     60    }
    6161}
  • applications/editors/josm/plugins/editgpx/src/org/openstreetmap/josm/plugins/editgpx/GPXLayerImportAction.java

    r21582 r23189  
    3838
    3939
    40         private static final long serialVersionUID = 5794897888911798168L;
    41         private EditGpxData data;
    42         public Object importing = new Object(); //used for synchronization
     40    private static final long serialVersionUID = 5794897888911798168L;
     41    private EditGpxData data;
     42    public Object importing = new Object(); //used for synchronization
    4343
    44         public GPXLayerImportAction(EditGpxData data) {
    45                 //TODO what is icon at the end?
    46                 super(tr("Import path from GPX layer"), ImageProvider.get("dialogs", "edit"));
    47                 this.data = data;
    48         }
     44    public GPXLayerImportAction(EditGpxData data) {
     45        //TODO what is icon at the end?
     46        super(tr("Import path from GPX layer"), ImageProvider.get("dialogs", "edit"));
     47        this.data = data;
     48    }
    4949
    50         /**
    51         * shows a list of GPX layers. if user selects one the data from this layer is
    52         * imported.
    53         */
    54         public void activateImport() {
    55                 Box panel = Box.createVerticalBox();
    56                 DefaultListModel dModel= new DefaultListModel();
     50    /**
     51    * shows a list of GPX layers. if user selects one the data from this layer is
     52    * imported.
     53    */
     54    public void activateImport() {
     55        Box panel = Box.createVerticalBox();
     56        DefaultListModel dModel= new DefaultListModel();
    5757
    58                 final JList layerList = new JList(dModel);
    59                 Collection<Layer> data = Main.map.mapView.getAllLayers();
    60                 Layer lastLayer = null;
    61                 int layerCnt = 0;
     58        final JList layerList = new JList(dModel);
     59        Collection<Layer> data = Main.map.mapView.getAllLayers();
     60        Layer lastLayer = null;
     61        int layerCnt = 0;
    6262
    63                 for (Layer l : data){
    64                         if(l instanceof GpxLayer){
    65                                 dModel.addElement(l);
    66                                 lastLayer = l;
    67                                 layerCnt++;
    68                         }
    69                 }
    70                 if(layerCnt == 1){
    71                         layerList.setSelectedValue(lastLayer, true);
    72                 }
    73                 if(layerCnt > 0){
    74                         layerList.setCellRenderer(new DefaultListCellRenderer(){
    75                                 @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
    76                                         Layer layer = (Layer)value;
    77                                         JLabel label = (JLabel)super.getListCellRendererComponent(list,
    78                                                         layer.getName(), index, isSelected, cellHasFocus);
    79                                         Icon icon = layer.getIcon();
    80                                         label.setIcon(icon);
    81                                         label.setToolTipText(layer.getToolTipText());
    82                                         return label;
    83                                 }
    84                         });
     63        for (Layer l : data){
     64            if(l instanceof GpxLayer){
     65                dModel.addElement(l);
     66                lastLayer = l;
     67                layerCnt++;
     68            }
     69        }
     70        if(layerCnt == 1){
     71            layerList.setSelectedValue(lastLayer, true);
     72        }
     73        if(layerCnt > 0){
     74            layerList.setCellRenderer(new DefaultListCellRenderer(){
     75                @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
     76                    Layer layer = (Layer)value;
     77                    JLabel label = (JLabel)super.getListCellRendererComponent(list,
     78                            layer.getName(), index, isSelected, cellHasFocus);
     79                    Icon icon = layer.getIcon();
     80                    label.setIcon(icon);
     81                    label.setToolTipText(layer.getToolTipText());
     82                    return label;
     83                }
     84            });
    8585
    86                         JCheckBox dropFirst = new JCheckBox(tr("Drop existing path"));
     86            JCheckBox dropFirst = new JCheckBox(tr("Drop existing path"));
    8787
    88                         panel.add(layerList);
    89                         panel.add(dropFirst);
     88            panel.add(layerList);
     89            panel.add(dropFirst);
    9090
    91                         final JOptionPane optionPane = new JOptionPane(panel, JOptionPane.QUESTION_MESSAGE, JOptionPane.OK_CANCEL_OPTION){
    92                                 @Override public void selectInitialValue() {
    93                                         layerList.requestFocusInWindow();
    94                                 }
    95                         };
    96                         final JDialog dlg = optionPane.createDialog(Main.parent, tr("Import path from GPX layer"));
    97                         dlg.setVisible(true);
     91            final JOptionPane optionPane = new JOptionPane(panel, JOptionPane.QUESTION_MESSAGE, JOptionPane.OK_CANCEL_OPTION){
     92                @Override public void selectInitialValue() {
     93                    layerList.requestFocusInWindow();
     94                }
     95            };
     96            final JDialog dlg = optionPane.createDialog(Main.parent, tr("Import path from GPX layer"));
     97            dlg.setVisible(true);
    9898
    99                         Object answer = optionPane.getValue();
    100                         if (answer == null || answer == JOptionPane.UNINITIALIZED_VALUE ||
    101                                         (answer instanceof Integer && (Integer)answer != JOptionPane.OK_OPTION)) {
    102                                 return;
    103                         }
     99            Object answer = optionPane.getValue();
     100            if (answer == null || answer == JOptionPane.UNINITIALIZED_VALUE ||
     101                    (answer instanceof Integer && (Integer)answer != JOptionPane.OK_OPTION)) {
     102                return;
     103            }
    104104
    105                         GpxLayer gpx = (GpxLayer)layerList.getSelectedValue();
     105            GpxLayer gpx = (GpxLayer)layerList.getSelectedValue();
    106106
    107                         synchronized(importing) {
    108                                 this.data.load(gpx.data, dropFirst.isSelected());
    109                         }
    110                         Main.map.mapView.repaint();
     107            synchronized(importing) {
     108                this.data.load(gpx.data, dropFirst.isSelected());
     109            }
     110            Main.map.mapView.repaint();
    111111
    112                 } else {
    113                         // no gps layer
    114                         JOptionPane.showMessageDialog(Main.parent,tr("No GPX data layer found."));
    115                 }
    116         }
     112        } else {
     113            // no gps layer
     114            JOptionPane.showMessageDialog(Main.parent,tr("No GPX data layer found."));
     115        }
     116    }
    117117
    118         /**
    119         * called when pressing "Import.." from context menu of EditGpx layer
    120         *
    121         */
    122         public void actionPerformed(ActionEvent arg0) {
    123                 activateImport();
    124         }
     118    /**
     119    * called when pressing "Import.." from context menu of EditGpx layer
     120    *
     121    */
     122    public void actionPerformed(ActionEvent arg0) {
     123        activateImport();
     124    }
    125125}
  • applications/editors/josm/plugins/editgpx/src/org/openstreetmap/josm/plugins/editgpx/data/EditGpxData.java

    r21582 r23189  
    1111public class EditGpxData {
    1212
    13         private final List<EditGpxTrack> tracks = new ArrayList<EditGpxTrack>();
    14         // Only copy of routes and waypoints to preserve all info when converting back to gpx track
    15         private final List<GpxRoute> routes = new ArrayList<GpxRoute>();
    16         private final List<WayPoint> waypoints = new ArrayList<WayPoint>();
     13    private final List<EditGpxTrack> tracks = new ArrayList<EditGpxTrack>();
     14    // Only copy of routes and waypoints to preserve all info when converting back to gpx track
     15    private final List<GpxRoute> routes = new ArrayList<GpxRoute>();
     16    private final List<WayPoint> waypoints = new ArrayList<WayPoint>();
    1717
    18         public void load(GpxData data, boolean drop) {
    19                 if(drop)
    20                         tracks.clear();
    21                 for (GpxTrack track: data.tracks) {
    22                         tracks.add(new EditGpxTrack(track));
    23                 }
    24                 routes.clear();
    25                 routes.addAll(data.routes);
    26                 waypoints.clear();
    27                 waypoints.addAll(data.waypoints);
    28         }
     18    public void load(GpxData data, boolean drop) {
     19        if(drop)
     20            tracks.clear();
     21        for (GpxTrack track: data.tracks) {
     22            tracks.add(new EditGpxTrack(track));
     23        }
     24        routes.clear();
     25        routes.addAll(data.routes);
     26        waypoints.clear();
     27        waypoints.addAll(data.waypoints);
     28    }
    2929
    30         public boolean isEmpty() {
    31                 for (EditGpxTrack track: tracks) {
    32                         for (EditGpxTrackSegment segment: track.getSegments()) {
    33                                 if (!segment.getWayPoints().isEmpty()) {
    34                                         return false;
    35                                 }
    36                         }
    37                 }
    38                 return true;
    39         }
     30    public boolean isEmpty() {
     31        for (EditGpxTrack track: tracks) {
     32            for (EditGpxTrackSegment segment: track.getSegments()) {
     33                if (!segment.getWayPoints().isEmpty()) {
     34                    return false;
     35                }
     36            }
     37        }
     38        return true;
     39    }
    4040
    41         public List<EditGpxTrack> getTracks() {
    42                 return tracks;
    43         }
     41    public List<EditGpxTrack> getTracks() {
     42        return tracks;
     43    }
    4444
    45         public GpxData createGpxData() {
    46                 GpxData result = new GpxData();
     45    public GpxData createGpxData() {
     46        GpxData result = new GpxData();
    4747
    48                 for (EditGpxTrack track: tracks) {
    49                         if (!track.isDeleted()) {
    50                                 GpxTrack newTrack = track.createGpxTrack();
    51                                 if (!newTrack.getSegments().isEmpty()) {
    52                                         result.tracks.add(newTrack);
    53                                 }
    54                         }
    55                 }
     48        for (EditGpxTrack track: tracks) {
     49            if (!track.isDeleted()) {
     50                GpxTrack newTrack = track.createGpxTrack();
     51                if (!newTrack.getSegments().isEmpty()) {
     52                    result.tracks.add(newTrack);
     53                }
     54            }
     55        }
    5656
    57                 result.routes.addAll(routes);
    58                 result.waypoints.addAll(waypoints);
    59                 return result;
    60         }
     57        result.routes.addAll(routes);
     58        result.waypoints.addAll(waypoints);
     59        return result;
     60    }
    6161
    6262}
  • applications/editors/josm/plugins/editgpx/src/org/openstreetmap/josm/plugins/editgpx/data/EditGpxTrack.java

    r21472 r23189  
    1414public class EditGpxTrack {
    1515
    16         private final List<EditGpxTrackSegment> segments = new ArrayList<EditGpxTrackSegment>();
    17         private final Map<String, Object> attributes = new HashMap<String, Object>();
    18         private boolean isDeleted;
     16    private final List<EditGpxTrackSegment> segments = new ArrayList<EditGpxTrackSegment>();
     17    private final Map<String, Object> attributes = new HashMap<String, Object>();
     18    private boolean isDeleted;
    1919
    20         public EditGpxTrack(GpxTrack track) {
    21                 attributes.putAll(track.getAttributes());
    22                 for (GpxTrackSegment segment: track.getSegments()) {
    23                         segments.add(new EditGpxTrackSegment(segment));
    24                 }
    25         }
     20    public EditGpxTrack(GpxTrack track) {
     21        attributes.putAll(track.getAttributes());
     22        for (GpxTrackSegment segment: track.getSegments()) {
     23            segments.add(new EditGpxTrackSegment(segment));
     24        }
     25    }
    2626
    27         public List<EditGpxTrackSegment> getSegments() {
    28                 return segments;
    29         }
    30         public Map<String, Object> getAttributes() {
    31                 return attributes;
    32         }
     27    public List<EditGpxTrackSegment> getSegments() {
     28        return segments;
     29    }
     30    public Map<String, Object> getAttributes() {
     31        return attributes;
     32    }
    3333
    34         public GpxTrack createGpxTrack() {
     34    public GpxTrack createGpxTrack() {
    3535
    36                 Collection<Collection<WayPoint>> wayPoints = new ArrayList<Collection<WayPoint>>();
     36        Collection<Collection<WayPoint>> wayPoints = new ArrayList<Collection<WayPoint>>();
    3737
    38                 for (EditGpxTrackSegment segment: segments) {
    39                         if (!segment.isDeleted()) {
    40                                 List<WayPoint> points = segment.getNonDeletedWaypoints();
    41                                 if (!points.isEmpty()) {
    42                                         wayPoints.add(points);
    43                                 }
    44                         }
    45                 }
     38        for (EditGpxTrackSegment segment: segments) {
     39            if (!segment.isDeleted()) {
     40                List<WayPoint> points = segment.getNonDeletedWaypoints();
     41                if (!points.isEmpty()) {
     42                    wayPoints.add(points);
     43                }
     44            }
     45        }
    4646
    47                 return new ImmutableGpxTrack(wayPoints, attributes);
    48         }
     47        return new ImmutableGpxTrack(wayPoints, attributes);
     48    }
    4949
    50         public void setDeleted(boolean isDeleted) {
    51                 this.isDeleted = isDeleted;
    52         }
     50    public void setDeleted(boolean isDeleted) {
     51        this.isDeleted = isDeleted;
     52    }
    5353
    54         public boolean isDeleted() {
    55                 return isDeleted;
    56         }
     54    public boolean isDeleted() {
     55        return isDeleted;
     56    }
    5757}
  • applications/editors/josm/plugins/editgpx/src/org/openstreetmap/josm/plugins/editgpx/data/EditGpxTrackSegment.java

    r21472 r23189  
    99public class EditGpxTrackSegment {
    1010
    11         private final List<EditGpxWayPoint> wayPoints = new ArrayList<EditGpxWayPoint>();
    12         private boolean deleted;
     11    private final List<EditGpxWayPoint> wayPoints = new ArrayList<EditGpxWayPoint>();
     12    private boolean deleted;
    1313
    14         public EditGpxTrackSegment(GpxTrackSegment segment) {
    15                 for (WayPoint wayPoint: segment.getWayPoints()) {
    16                         wayPoints.add(new EditGpxWayPoint(wayPoint));
    17                 }
    18         }
     14    public EditGpxTrackSegment(GpxTrackSegment segment) {
     15        for (WayPoint wayPoint: segment.getWayPoints()) {
     16            wayPoints.add(new EditGpxWayPoint(wayPoint));
     17        }
     18    }
    1919
    20         public List<EditGpxWayPoint> getWayPoints() {
    21                 return wayPoints;
    22         }
     20    public List<EditGpxWayPoint> getWayPoints() {
     21        return wayPoints;
     22    }
    2323
    24         public List<WayPoint> getNonDeletedWaypoints() {
    25                 List<WayPoint> result = new ArrayList<WayPoint>();
     24    public List<WayPoint> getNonDeletedWaypoints() {
     25        List<WayPoint> result = new ArrayList<WayPoint>();
    2626
    27                 for (EditGpxWayPoint wp: wayPoints) {
    28                         if (!wp.isDeleted()) {
    29                                 result.add(wp.createWayPoint());
    30                         }
    31                 }
     27        for (EditGpxWayPoint wp: wayPoints) {
     28            if (!wp.isDeleted()) {
     29                result.add(wp.createWayPoint());
     30            }
     31        }
    3232
    33                 return result;
    34         }
     33        return result;
     34    }
    3535
    36         public void setDeleted(boolean deleted) {
    37                 this.deleted = deleted;
    38         }
     36    public void setDeleted(boolean deleted) {
     37        this.deleted = deleted;
     38    }
    3939
    40         public boolean isDeleted() {
    41                 return deleted;
    42         }
     40    public boolean isDeleted() {
     41        return deleted;
     42    }
    4343
    4444}
  • applications/editors/josm/plugins/editgpx/src/org/openstreetmap/josm/plugins/editgpx/data/EditGpxWayPoint.java

    r21472 r23189  
    88
    99public class EditGpxWayPoint {
    10         private final double time;
    11         private final CachedLatLon coor;
    12         private boolean deleted;
    13         private Map<String, Object> attributes;
     10    private final double time;
     11    private final CachedLatLon coor;
     12    private boolean deleted;
     13    private Map<String, Object> attributes;
    1414
    15         public EditGpxWayPoint(WayPoint wayPoint) {
    16                 this.time = wayPoint.time;
    17                 this.coor = new CachedLatLon(wayPoint.getCoor());
    18                 this.attributes = new HashMap<String, Object>(wayPoint.attr);
    19         }
     15    public EditGpxWayPoint(WayPoint wayPoint) {
     16        this.time = wayPoint.time;
     17        this.coor = new CachedLatLon(wayPoint.getCoor());
     18        this.attributes = new HashMap<String, Object>(wayPoint.attr);
     19    }
    2020
    21         public WayPoint createWayPoint() {
    22                 WayPoint result = new WayPoint(getCoor());
    23                 result.time = time;
    24                 result.attr = attributes;
    25                 return result;
    26         }
     21    public WayPoint createWayPoint() {
     22        WayPoint result = new WayPoint(getCoor());
     23        result.time = time;
     24        result.attr = attributes;
     25        return result;
     26    }
    2727
    28         public void setDeleted(boolean deleted) {
    29                 this.deleted = deleted;
    30         }
     28    public void setDeleted(boolean deleted) {
     29        this.deleted = deleted;
     30    }
    3131
    32         public boolean isDeleted() {
    33                 return deleted;
    34         }
     32    public boolean isDeleted() {
     33        return deleted;
     34    }
    3535
    36         public CachedLatLon getCoor() {
    37                 return coor;
    38         }
     36    public CachedLatLon getCoor() {
     37        return coor;
     38    }
    3939}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/access/AccessEvaluator.java

    r16520 r23189  
    1919public interface AccessEvaluator<N, W> {
    2020
    21         /**
    22         * checks whether a way may be accessed in the given direction
    23         *
    24         * @param way                object to be checked; != null
    25         * @param segmentProperties  map from road property types to their values for this way's
    26         *                           segments; each value must be a valid value for its property type;
    27         *                           != null
    28         */
    29         public boolean wayUsable(W way, boolean forward,
    30                         Map<RoadPropertyType<?>, Object> roadPropertyValues);
     21    /**
     22    * checks whether a way may be accessed in the given direction
     23    *
     24    * @param way                object to be checked; != null
     25    * @param segmentProperties  map from road property types to their values for this way's
     26    *                           segments; each value must be a valid value for its property type;
     27    *                           != null
     28    */
     29    public boolean wayUsable(W way, boolean forward,
     30            Map<RoadPropertyType<?>, Object> roadPropertyValues);
    3131
    32         /**
    33         * checks whether a node may be accessed/passed
    34         *
    35         * @param node               object to be checked; != null
    36         * @param segmentProperties  map from road property types to their values for SegmentNodes
    37         *                           based on this node, each value must be a valid value for its
    38         *                           property type; != null
    39         */
    40         public boolean nodeUsable(N node, Map<RoadPropertyType<?>, Object> roadPropertyValues);
     32    /**
     33    * checks whether a node may be accessed/passed
     34    *
     35    * @param node               object to be checked; != null
     36    * @param segmentProperties  map from road property types to their values for SegmentNodes
     37    *                           based on this node, each value must be a valid value for its
     38    *                           property type; != null
     39    */
     40    public boolean nodeUsable(N node, Map<RoadPropertyType<?>, Object> roadPropertyValues);
    4141
    4242}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/access/AccessParameters.java

    r16520 r23189  
    1111public interface AccessParameters {
    1212
    13         public String getAccessClass();
     13    public String getAccessClass();
    1414
    15         /**
    16         * returns true iff a road with a given access type can be used
    17         * @param accessType  access type to check usablitly for; != null
    18         */
    19         public boolean getAccessTypeUsable(AccessType accessType);
     15    /**
     16    * returns true iff a road with a given access type can be used
     17    * @param accessType  access type to check usablitly for; != null
     18    */
     19    public boolean getAccessTypeUsable(AccessType accessType);
    2020
    21         /**
    22         * returns all {@link VehiclePropertyType}s a value is avaliable for.
    23         * The value can be accessed using {@link #getVehiclePropertyValue(VehiclePropertyType)}
    24         * @return  collection of property types; != null
    25         */
    26         public Collection<VehiclePropertyType<?>> getAvailableVehicleProperties();
     21    /**
     22    * returns all {@link VehiclePropertyType}s a value is avaliable for.
     23    * The value can be accessed using {@link #getVehiclePropertyValue(VehiclePropertyType)}
     24    * @return  collection of property types; != null
     25    */
     26    public Collection<VehiclePropertyType<?>> getAvailableVehicleProperties();
    2727
    28         /**
    29         * returns the value for a vehicle property.
    30         *
    31         * @param <V>              type of property value
    32         * @param vehicleProperty  property to get value for; != null
    33         * @return                 value for vehicleProperty, null if no value is available.
    34         *                         Guaranteed to be valid according to vehicleProperty's
    35         *                         {@link VehiclePropertyType#isValidValue(Object)} method.
    36         */
    37         public <V> V getVehiclePropertyValue(VehiclePropertyType<V> vehicleProperty);
     28    /**
     29    * returns the value for a vehicle property.
     30    *
     31    * @param <V>              type of property value
     32    * @param vehicleProperty  property to get value for; != null
     33    * @return                 value for vehicleProperty, null if no value is available.
     34    *                         Guaranteed to be valid according to vehicleProperty's
     35    *                         {@link VehiclePropertyType#isValidValue(Object)} method.
     36    */
     37    public <V> V getVehiclePropertyValue(VehiclePropertyType<V> vehicleProperty);
    3838
    3939}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/access/AccessRuleset.java

    r16520 r23189  
    1212public interface AccessRuleset {
    1313
    14         /**
    15         * for a mode of transport, returns all transport categories it is a subset of.
    16         * For example, the returned collection for "motorcycle" might include "motor_vehicle" and "vehicle".
    17         *
    18         * @param transportMode  mode of transport to get "supertypes" for; != null
    19         * @return parameters superset categories, including the parameter itself,
    20         *         in the order of decreasing specificness
    21         *         empty if the parameter was no known mode of transport; != null
    22         */
    23         public List<String> getAccessHierarchyAncestors(String transportMode);
     14    /**
     15    * for a mode of transport, returns all transport categories it is a subset of.
     16    * For example, the returned collection for "motorcycle" might include "motor_vehicle" and "vehicle".
     17    *
     18    * @param transportMode  mode of transport to get "supertypes" for; != null
     19    * @return parameters superset categories, including the parameter itself,
     20    *         in the order of decreasing specificness
     21    *         empty if the parameter was no known mode of transport; != null
     22    */
     23    public List<String> getAccessHierarchyAncestors(String transportMode);
    2424
    25         /**
    26         * returns all base tags.
    27         * Base tags are tags that make an object "eligible" for access evaluation
    28         * (commonly things like highway=* or barrier=*)
    29         */
    30         public Collection<Tag> getBaseTags();
     25    /**
     26    * returns all base tags.
     27    * Base tags are tags that make an object "eligible" for access evaluation
     28    * (commonly things like highway=* or barrier=*)
     29    */
     30    public Collection<Tag> getBaseTags();
    3131
    32         /**
    33         * returns ruleset-specific implications
    34         * @return  list of implications in the order they are expected to be applied; != null
    35         */
    36         public List<Implication> getImplications();
     32    /**
     33    * returns ruleset-specific implications
     34    * @return  list of implications in the order they are expected to be applied; != null
     35    */
     36    public List<Implication> getImplications();
    3737
    3838}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/access/AccessRulesetReader.java

    r16836 r23189  
    2020public class AccessRulesetReader {
    2121
    22         public static class AccessRulesetSyntaxException extends IOException {
    23                 private static final long serialVersionUID = 1L;
    24                 public AccessRulesetSyntaxException(String message) {
    25                         super(message);
    26                 };
    27                 public AccessRulesetSyntaxException(Throwable t) {
    28                         super(t.toString());
    29                 }
    30         }
    31 
    32         /** private constructor to prevent instantiation */
    33         private AccessRulesetReader() { }
    34 
    35         public static AccessRuleset readAccessRuleset(InputStream inputStream)
    36         throws AccessRulesetSyntaxException, IOException {
    37 
    38                 RulesetHandler rulesetHandler = new RulesetHandler();
    39 
    40                 try {
    41                         XMLReader reader = XMLReaderFactory.createXMLReader();
    42                         InputSource input = new InputSource(inputStream);
    43                         reader.setContentHandler(rulesetHandler);
    44                         reader.setErrorHandler(null);
    45                         reader.parse(input);
    46                 } catch (SAXException e) {
    47                         throw new AccessRulesetSyntaxException(e);
    48                 }
    49 
    50                 return rulesetHandler.getAccessRuleset();
    51         }
    52 
    53         private static class RulesetHandler extends DefaultHandler {
    54 
    55                 private static class AccessClass {
    56                         final String name;
    57                         final AccessClass parent;
    58                         public AccessClass(String name, AccessClass parent) {
    59                                 this.name = name;
    60                                 this.parent = parent;
    61                         }
    62                         List<String> getAncestorHierarchy() {
    63                                 List<String> names;
    64                                 if (parent == null) {
    65                                         names = new LinkedList<String>();
    66                                 } else {
    67                                         names = parent.getAncestorHierarchy();
    68                                 }
    69                                 names.add(0, name);
    70                                 return names;
    71                         }
    72                 }
    73 
    74                 private final Collection<AccessClass> accessClasses = new LinkedList<AccessClass>();
    75                 private final Collection<Tag> baseTags = new LinkedList<Tag>();
    76 
    77                 private static enum Section {NONE, CLASSES, BASETAGS, IMPLICATIONS};
    78                 private Section currentSection = Section.NONE;
    79 
    80                 private AccessClass currentAccessClass = null;
    81 
    82                 private ImplicationXMLReader implicationReader = null;
    83                 private final List<Implication> implications = new LinkedList<Implication>();
    84 
    85                 /** returns the AccessRuleset that was read */
    86                 AccessRuleset getAccessRuleset() {
    87 
    88                         return new AccessRuleset() {
    89 
    90                                 public List<String> getAccessHierarchyAncestors(String transportMode) {
    91                                         for (AccessClass accessClass : accessClasses) {
    92                                                 if (accessClass.name.equals(transportMode)) {
    93                                                         return accessClass.getAncestorHierarchy();
    94                                                 }
    95                                         }
    96                                         return new LinkedList<String>();
    97                                 }
    98 
    99                                 public Collection<Tag> getBaseTags() {
    100                                         return baseTags;
    101                                 }
    102 
    103                                 public List<Implication> getImplications() {
    104                                         return implications;
    105                                 }
    106 
    107                         };
    108                 }
    109 
    110                 @Override
    111                 public void startElement(String uri, String localName, String name,
    112                                 Attributes attributes) throws SAXException {
    113 
    114                         if (implicationReader != null) {
    115                                 implicationReader.startElement(uri, localName, name, attributes);
    116                                 return;
    117                         }
    118 
    119                         if ("classes".equals(name)) {
    120 
    121                                 if (currentSection != Section.NONE) {
    122                                         throw new SAXException("classes element below root child level");
    123                                 }
    124 
    125                                 currentSection = Section.CLASSES;
    126 
    127                         } else if ("class".equals(name)) {
    128 
    129                                 String className = attributes.getValue("name");
    130 
    131                                 if (currentSection != Section.CLASSES) {
    132                                         throw new SAXException("class element (" + className + ") outside classes element");
    133                                 } else if (className == null) {
    134                                         throw new SAXException("class element without name");
    135                                 }
    136 
    137                                 AccessClass newAccessClass = new AccessClass(className, currentAccessClass);
    138 
    139                                 accessClasses.add(newAccessClass);
    140 
    141                                 currentAccessClass = newAccessClass;
    142 
    143                         } else if ("basetags".equals(name)) {
    144 
    145                                 if (currentSection != Section.NONE) {
    146                                         throw new SAXException("classes element below root child level");
    147                                 }
    148 
    149                                 currentSection = Section.BASETAGS;
    150 
    151                         } else if ("tag".equals(name)) {
    152 
    153                                 if (currentSection == Section.BASETAGS) {
    154                                         baseTags.add(readTag(attributes));
    155                                 } else {
    156                                         throw new SAXException("tag element outside basetag and implication elements");
    157                                 }
    158 
    159                         } else if ("implications".equals(name)) {
    160 
    161                                 if (currentSection != Section.NONE) {
    162                                         throw new SAXException("implications element below root child level");
    163                                 }
    164 
    165                                 implicationReader = new ImplicationXMLReader();
    166                                 currentSection = Section.IMPLICATIONS;
    167 
    168                         }
    169 
    170                 }
    171 
    172                 private static Tag readTag(Attributes attributes) throws SAXException {
    173 
    174                         String key = attributes.getValue("k");
    175                         String value = attributes.getValue("v");
    176 
    177                         if (key == null) {
    178                                 throw new SAXException("tag without key");
    179                         } else if (value == null) {
    180                                 throw new SAXException("tag without value (key is " + key + ")");
    181                         }
    182 
    183                         return new Tag(key, value);
    184                 }
    185 
    186                 @Override
    187                 public void endElement(String uri, String localName, String name)
    188                 throws SAXException {
    189 
    190                         if (implicationReader != null && !"implications".equals(name)) {
    191                                 implicationReader.endElement(uri, localName, name);
    192                         }
    193 
    194                         if ("classes".equals(name)) {
    195 
    196                                 if (currentSection != Section.CLASSES) {
    197                                         throw new SAXException("closed classes while it wasn't open");
    198                                 } else if (currentAccessClass != null) {
    199                                         throw new SAXException("closed classes element before all class elements were closed");
    200                                 }
    201 
    202                                 currentSection = Section.NONE;
    203 
    204                         } else if ("class".equals(name)) {
    205 
    206                                 if (currentAccessClass == null) {
    207                                         throw new SAXException("closed class element while none was open");
    208                                 }
    209 
    210                                 currentAccessClass = currentAccessClass.parent;
    211 
    212                         } else if ("basetags".equals(name)) {
    213 
    214                                 if (currentSection != Section.BASETAGS) {
    215                                         throw new SAXException("closed basetags while it wasn't open");
    216                                 }
    217 
    218                                 currentSection = Section.NONE;
    219 
    220                         } else if ("implications".equals(name)) {
    221 
    222                                 if (currentSection != Section.IMPLICATIONS) {
    223                                         throw new SAXException("closed implications while it wasn't open");
    224                                 }
    225 
    226                                 implications.addAll(implicationReader.getImplications());
    227                                 implicationReader = null;
    228                                 currentSection = Section.NONE;
    229 
    230                         }
    231 
    232                 }
    233 
    234         };
     22    public static class AccessRulesetSyntaxException extends IOException {
     23        private static final long serialVersionUID = 1L;
     24        public AccessRulesetSyntaxException(String message) {
     25            super(message);
     26        };
     27        public AccessRulesetSyntaxException(Throwable t) {
     28            super(t.toString());
     29        }
     30    }
     31
     32    /** private constructor to prevent instantiation */
     33    private AccessRulesetReader() { }
     34
     35    public static AccessRuleset readAccessRuleset(InputStream inputStream)
     36    throws AccessRulesetSyntaxException, IOException {
     37
     38        RulesetHandler rulesetHandler = new RulesetHandler();
     39
     40        try {
     41            XMLReader reader = XMLReaderFactory.createXMLReader();
     42            InputSource input = new InputSource(inputStream);
     43            reader.setContentHandler(rulesetHandler);
     44            reader.setErrorHandler(null);
     45            reader.parse(input);
     46        } catch (SAXException e) {
     47            throw new AccessRulesetSyntaxException(e);
     48        }
     49
     50        return rulesetHandler.getAccessRuleset();
     51    }
     52
     53    private static class RulesetHandler extends DefaultHandler {
     54
     55        private static class AccessClass {
     56            final String name;
     57            final AccessClass parent;
     58            public AccessClass(String name, AccessClass parent) {
     59                this.name = name;
     60                this.parent = parent;
     61            }
     62            List<String> getAncestorHierarchy() {
     63                List<String> names;
     64                if (parent == null) {
     65                    names = new LinkedList<String>();
     66                } else {
     67                    names = parent.getAncestorHierarchy();
     68                }
     69                names.add(0, name);
     70                return names;
     71            }
     72        }
     73
     74        private final Collection<AccessClass> accessClasses = new LinkedList<AccessClass>();
     75        private final Collection<Tag> baseTags = new LinkedList<Tag>();
     76
     77        private static enum Section {NONE, CLASSES, BASETAGS, IMPLICATIONS};
     78        private Section currentSection = Section.NONE;
     79
     80        private AccessClass currentAccessClass = null;
     81
     82        private ImplicationXMLReader implicationReader = null;
     83        private final List<Implication> implications = new LinkedList<Implication>();
     84
     85        /** returns the AccessRuleset that was read */
     86        AccessRuleset getAccessRuleset() {
     87
     88            return new AccessRuleset() {
     89
     90                public List<String> getAccessHierarchyAncestors(String transportMode) {
     91                    for (AccessClass accessClass : accessClasses) {
     92                        if (accessClass.name.equals(transportMode)) {
     93                            return accessClass.getAncestorHierarchy();
     94                        }
     95                    }
     96                    return new LinkedList<String>();
     97                }
     98
     99                public Collection<Tag> getBaseTags() {
     100                    return baseTags;
     101                }
     102
     103                public List<Implication> getImplications() {
     104                    return implications;
     105                }
     106
     107            };
     108        }
     109
     110        @Override
     111        public void startElement(String uri, String localName, String name,
     112                Attributes attributes) throws SAXException {
     113
     114            if (implicationReader != null) {
     115                implicationReader.startElement(uri, localName, name, attributes);
     116                return;
     117            }
     118
     119            if ("classes".equals(name)) {
     120
     121                if (currentSection != Section.NONE) {
     122                    throw new SAXException("classes element below root child level");
     123                }
     124
     125                currentSection = Section.CLASSES;
     126
     127            } else if ("class".equals(name)) {
     128
     129                String className = attributes.getValue("name");
     130
     131                if (currentSection != Section.CLASSES) {
     132                    throw new SAXException("class element (" + className + ") outside classes element");
     133                } else if (className == null) {
     134                    throw new SAXException("class element without name");
     135                }
     136
     137                AccessClass newAccessClass = new AccessClass(className, currentAccessClass);
     138
     139                accessClasses.add(newAccessClass);
     140
     141                currentAccessClass = newAccessClass;
     142
     143            } else if ("basetags".equals(name)) {
     144
     145                if (currentSection != Section.NONE) {
     146                    throw new SAXException("classes element below root child level");
     147                }
     148
     149                currentSection = Section.BASETAGS;
     150
     151            } else if ("tag".equals(name)) {
     152
     153                if (currentSection == Section.BASETAGS) {
     154                    baseTags.add(readTag(attributes));
     155                } else {
     156                    throw new SAXException("tag element outside basetag and implication elements");
     157                }
     158
     159            } else if ("implications".equals(name)) {
     160
     161                if (currentSection != Section.NONE) {
     162                    throw new SAXException("implications element below root child level");
     163                }
     164
     165                implicationReader = new ImplicationXMLReader();
     166                currentSection = Section.IMPLICATIONS;
     167
     168            }
     169
     170        }
     171
     172        private static Tag readTag(Attributes attributes) throws SAXException {
     173
     174            String key = attributes.getValue("k");
     175            String value = attributes.getValue("v");
     176
     177            if (key == null) {
     178                throw new SAXException("tag without key");
     179            } else if (value == null) {
     180                throw new SAXException("tag without value (key is " + key + ")");
     181            }
     182
     183            return new Tag(key, value);
     184        }
     185
     186        @Override
     187        public void endElement(String uri, String localName, String name)
     188        throws SAXException {
     189
     190            if (implicationReader != null && !"implications".equals(name)) {
     191                implicationReader.endElement(uri, localName, name);
     192            }
     193
     194            if ("classes".equals(name)) {
     195
     196                if (currentSection != Section.CLASSES) {
     197                    throw new SAXException("closed classes while it wasn't open");
     198                } else if (currentAccessClass != null) {
     199                    throw new SAXException("closed classes element before all class elements were closed");
     200                }
     201
     202                currentSection = Section.NONE;
     203
     204            } else if ("class".equals(name)) {
     205
     206                if (currentAccessClass == null) {
     207                    throw new SAXException("closed class element while none was open");
     208                }
     209
     210                currentAccessClass = currentAccessClass.parent;
     211
     212            } else if ("basetags".equals(name)) {
     213
     214                if (currentSection != Section.BASETAGS) {
     215                    throw new SAXException("closed basetags while it wasn't open");
     216                }
     217
     218                currentSection = Section.NONE;
     219
     220            } else if ("implications".equals(name)) {
     221
     222                if (currentSection != Section.IMPLICATIONS) {
     223                    throw new SAXException("closed implications while it wasn't open");
     224                }
     225
     226                implications.addAll(implicationReader.getImplications());
     227                implicationReader = null;
     228                currentSection = Section.NONE;
     229
     230            }
     231
     232        }
     233
     234    };
    235235}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/access/AccessType.java

    r16520 r23189  
    33public enum AccessType {
    44
    5         YES("yes"),
    6         PERMISSIVE("permissive"),
    7         DESIGNATED("designated"),
    8         DESTINATION("destination"),
    9         AGRICULTURAL("agricultural"),
    10         FORESTRY("forestry"),
    11         DELIVERY("delivery"),
    12         PRIVATE("private"),
    13         NO("no"),
    14         UNDEFINED();
     5    YES("yes"),
     6    PERMISSIVE("permissive"),
     7    DESIGNATED("designated"),
     8    DESTINATION("destination"),
     9    AGRICULTURAL("agricultural"),
     10    FORESTRY("forestry"),
     11    DELIVERY("delivery"),
     12    PRIVATE("private"),
     13    NO("no"),
     14    UNDEFINED();
    1515
    16         private String[] valueStrings;
    17         private AccessType(String... valueStrings) {
    18                 this.valueStrings = valueStrings;
    19         }
     16    private String[] valueStrings;
     17    private AccessType(String... valueStrings) {
     18        this.valueStrings = valueStrings;
     19    }
    2020
    21         /**
    22         * returns the AccessType that fits for a tag's value
    23         *
    24         * @param valueString  a tag's value; != null
    25         * @return             AccessType for the value; != null, will be UNDEFINED for unknown values
    26         */
    27         public static AccessType getAccessType(String valueString) {
    28                 for (AccessType accessType : AccessType.values()) {
    29                         for (String typeValueString : accessType.valueStrings) {
    30                                 if (typeValueString.equals(valueString)) {
    31                                         return accessType;
    32                                 }
    33                         }
    34                 }
    35                 return UNDEFINED;
    36         }
     21    /**
     22    * returns the AccessType that fits for a tag's value
     23    *
     24    * @param valueString  a tag's value; != null
     25    * @return             AccessType for the value; != null, will be UNDEFINED for unknown values
     26    */
     27    public static AccessType getAccessType(String valueString) {
     28        for (AccessType accessType : AccessType.values()) {
     29            for (String typeValueString : accessType.valueStrings) {
     30                if (typeValueString.equals(valueString)) {
     31                    return accessType;
     32                }
     33            }
     34        }
     35        return UNDEFINED;
     36    }
    3737
    3838}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/access/Implication.java

    r16520 r23189  
    1515public final class Implication {
    1616
    17         private final TagCondition condition;
    18         private final Collection<Tag> impliedTags;
     17    private final TagCondition condition;
     18    private final Collection<Tag> impliedTags;
    1919
    20         public Implication(TagCondition condition, Collection<Tag> impliedTags) {
    21                 this.condition = condition;
    22                 this.impliedTags = impliedTags;
    23         }
     20    public Implication(TagCondition condition, Collection<Tag> impliedTags) {
     21        this.condition = condition;
     22        this.impliedTags = impliedTags;
     23    }
    2424
    25         /**
    26         * applies this implication to a tag group.
    27         * The resulting tag group will contain all tags from the original group
    28         * and all implied tags with a key that didn't occur in the original group.
    29         *
    30         * @param tags  tag group to apply implications to; != null
    31         */
    32         public TagGroup apply(TagGroup tags) {
     25    /**
     26    * applies this implication to a tag group.
     27    * The resulting tag group will contain all tags from the original group
     28    * and all implied tags with a key that didn't occur in the original group.
     29    *
     30    * @param tags  tag group to apply implications to; != null
     31    */
     32    public TagGroup apply(TagGroup tags) {
    3333
    34                 if (condition.matches(tags)) {
     34        if (condition.matches(tags)) {
    3535
    36                         Map<String, String> newTagMap = new HashMap<String, String>();
     36            Map<String, String> newTagMap = new HashMap<String, String>();
    3737
    38                         for (Tag tag : tags) {
    39                                 newTagMap.put(tag.key, tag.value);
    40                         }
     38            for (Tag tag : tags) {
     39                newTagMap.put(tag.key, tag.value);
     40            }
    4141
    42                         for (Tag impliedTag : impliedTags) {
    43                                 if (!newTagMap.containsKey(impliedTag.key)) {
    44                                         newTagMap.put(impliedTag.key, impliedTag.value);
    45                                 }
    46                         }
     42            for (Tag impliedTag : impliedTags) {
     43                if (!newTagMap.containsKey(impliedTag.key)) {
     44                    newTagMap.put(impliedTag.key, impliedTag.value);
     45                }
     46            }
    4747
    48                         return new MapBasedTagGroup(newTagMap);
     48            return new MapBasedTagGroup(newTagMap);
    4949
    50                 } else {
    51                         return tags;
    52                 }
     50        } else {
     51            return tags;
     52        }
    5353
    54         }
     54    }
    5555
    56         @Override
    57         public String toString() {
    58                 return condition.toString() + " => " + impliedTags.toString();
    59         }
     56    @Override
     57    public String toString() {
     58        return condition.toString() + " => " + impliedTags.toString();
     59    }
    6060
    6161}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/access/ImplicationXMLReader.java

    r16520 r23189  
    1717public class ImplicationXMLReader {
    1818
    19         private final List<Implication> implications = new LinkedList<Implication>();
    20 
    21         private static enum State {BEFORE_IMPLICATION, BEFORE_CONDITION, CONDITION, BEFORE_IMPLIES, IMPLIES, AFTER_IMPLIES};
    22         private State state = State.BEFORE_IMPLICATION;
    23 
    24         private ConditionReader currentConditionReader;
    25         private TagCondition currentCondition;
    26         private Collection<Tag> currentImpliedTags;
    27 
    28         boolean tagOpen = false;
    29 
    30         public void startElement(String uri, String localName, String name, Attributes attributes)
    31         throws SAXException {
    32 
    33                 switch (state) {
    34 
    35                         case BEFORE_IMPLICATION:
    36 
    37                                 if ("implication".equals(name)) {
    38                                         state = State.BEFORE_CONDITION;
    39                                         return;
    40                                 }
    41                                 break;
    42 
    43                         case BEFORE_CONDITION:
    44 
    45                                 if ("condition".equals(name)) {
    46                                         currentConditionReader = new ConditionReader();
    47                                         state = State.CONDITION;
    48                                         return;
    49                                 }
    50                                 break;
    51 
    52                         case CONDITION:
    53                                 currentConditionReader.startElement(uri, localName, name, attributes);
    54                                 return;
    55 
    56                         case BEFORE_IMPLIES:
    57 
    58                                 if ("implies".equals(name)) {
    59                                         currentImpliedTags = new LinkedList<Tag>();
    60                                         state = State.IMPLIES;
    61                                         return;
    62                                 }
    63                                 break;
    64 
    65                         case IMPLIES:
    66 
    67                                 if ("tag".equals(name)) {
    68                                         if (tagOpen) {
    69                                                 throw new SAXException("tag element inside other tag element");
    70                                         }
    71                                         currentImpliedTags.add(readTag(attributes));
    72                                         tagOpen = true;
    73                                         return;
    74                                 }
    75                                 break;
    76 
    77                 }
    78 
    79                 //all vaild paths end with return; reaching this indicates an invalid tag
    80                 throw new SAXException("invalid opening xml tag <" + name + "> in state " + state);
    81 
    82         }
    83 
    84         public void endElement(String uri, String localName, String name)
    85         throws SAXException {
    86 
    87                 switch (state) {
    88 
    89                         case CONDITION:
    90 
    91                                 if (name.equals("condition")) {
    92                                         if (!currentConditionReader.isFinished()) {
    93                                                 throw new SAXException("condition isn't finished at </condition> tag");
    94                                         } else {
    95                                                 currentCondition = currentConditionReader.getCondition();
    96                                                 currentConditionReader = null;
    97                                                 state = State.BEFORE_IMPLIES;
    98                                                 return;
    99                                         }
    100                                 } else {
    101                                         currentConditionReader.endElement(uri, localName, name);
    102                                         return;
    103                                 }
    104 
    105                         case IMPLIES:
    106 
    107                                 if (name.equals("implies")) {
    108                                         state = State.AFTER_IMPLIES;
    109                                         return;
    110                                 } else if (name.equals("tag")) {
    111                                         if (!tagOpen) {
    112                                                 throw new SAXException("closing tag element that was not open");
    113                                         }
    114                                         tagOpen = false;
    115                                         return;
    116                                 }
    117                                 break;
    118 
    119                         case AFTER_IMPLIES:
    120 
    121                                 if (name.equals("implication")) {
    122                                         implications.add(new Implication(currentCondition, currentImpliedTags));
    123                                         currentCondition = null;
    124                                         currentImpliedTags = null;
    125                                         state = State.BEFORE_IMPLICATION;
    126                                         return;
    127                                 }
    128                                 break;
    129 
    130                 }
    131 
    132                 //all vaild paths end with return; reaching this indicates an invalid tag
    133                 throw new SAXException("invalid closing xml tag </" + name + "> in state " + state);
    134 
    135         }
    136 
    137         public List<Implication> getImplications() throws SAXException {
    138 
    139                 if (state != State.BEFORE_IMPLICATION) {
    140                         throw new SAXException("some tags not been closed; now in state " + state);
    141                 } else {
    142                         return new ArrayList<Implication>(implications);
    143                 }
    144         }
    145 
    146         private static Tag readTag(Attributes attributes) throws SAXException {
    147 
    148                 String key = attributes.getValue("k");
    149                 String value = attributes.getValue("v");
    150 
    151                 if (key == null) {
    152                         throw new SAXException("tag without key");
    153                 } else if (value == null) {
    154                         throw new SAXException("tag without value (key is " + key + ")");
    155                 }
    156 
    157                 return new Tag(key, value);
    158         }
    159 
    160         private static String readKey(Attributes attributes) throws SAXException {
    161 
    162                 String key = attributes.getValue("k");
    163 
    164                 if (key == null) {
    165                         throw new SAXException("key element without attribute k");
    166                 }
    167 
    168                 return key;
    169         }
    170 
    171         /**
    172         * class to be used for reading tag condition sections of xml files
    173         */
    174         private static class ConditionReader {
    175 
    176                 String openingName;
    177                 TagCondition condition;
    178                 boolean finished;
    179 
    180                 private final List<ConditionReader> childReaders = new LinkedList<ConditionReader>();
    181                 private ConditionReader currentChildReader = null;
    182 
    183                 public void startElement(String uri, String localName, String name, Attributes attributes)
    184                 throws SAXException {
    185 
    186                         if (finished) {
    187                                 throw new SAXException("condition is already finished at <" + name + ">");
    188                         }
    189 
    190                         if (currentChildReader != null) {
    191                                 currentChildReader.startElement(uri, localName, name, attributes);
    192                                 return;
    193                         }
    194 
    195                         //first tag is start tag of this condition
    196                         if (openingName == null) {
    197 
    198                                 openingName = name;
    199 
    200                                 if ("tag".equals(name)) {
    201                                         condition = TagConditionLogic.tag(readTag(attributes));
    202                                 } else if ("key".equals(name)) {
    203                                         condition = TagConditionLogic.key(readKey(attributes));
    204                                 } else if (!("or".equals(name)) && !("and".equals(name)) && !("not".equals(name))) {
    205                                         throw new SAXException("unknown tag for condition: " + name);
    206                                 }
    207 
    208                                 //all tags after the first are start tags of child conditions
    209                         } else {
    210 
    211                                 if ("tag".equals(openingName) || "key".equals(openingName)) {
    212                                         throw new SAXException("element must not have childs: " + openingName);
    213                                 }
    214 
    215                                 currentChildReader = new ConditionReader();
    216                                 currentChildReader.startElement(uri, localName, name, attributes);
    217 
    218                         }
    219 
    220                 }
    221 
    222                 public void endElement(String uri, String localName, String name)
    223                 throws SAXException {
    224 
    225                         if (finished) {
    226                                 throw new SAXException("condition is already finished at </" + name + ">");
    227                         }
    228 
    229                         /* if active child reader exists, pass parameter to it. */
    230                         if (currentChildReader != null) {
    231 
    232                                 currentChildReader.endElement(uri, localName, name);
    233 
    234                                 if (currentChildReader.isFinished()) {
    235                                         childReaders.add(currentChildReader);
    236                                         currentChildReader = null;
    237                                 }
    238 
    239                         } else {
    240 
    241                                 if (openingName.equals(name)) {
    242 
    243                                         List<TagCondition> childConditions = new ArrayList<TagCondition>();
    244                                         for (ConditionReader childReader : childReaders) {
    245                                                 childConditions.add(childReader.getCondition());
    246                                         }
    247 
    248                                         if ("and".equals(openingName)) {
    249                                                 if (childConditions.size() > 0) {
    250                                                         condition = TagConditionLogic.and(childConditions);
    251                                                 } else {
    252                                                         throw new SAXException("<and> needs at least one child");
    253                                                 }
    254                                         } else if ("or".equals(openingName)) {
    255                                                 if (childConditions.size() > 0) {
    256                                                         condition = TagConditionLogic.or(childConditions);
    257                                                 } else {
    258                                                         throw new SAXException("<or> needs at least one child");
    259                                                 }
    260                                         } else if ("not".equals(openingName)) {
    261                                                 if (childConditions.size() == 1) {
    262                                                         condition = TagConditionLogic.not(childConditions.get(0));
    263                                                 } else {
    264                                                         throw new SAXException("<not> needs at least one child");
    265                                                 }
    266                                         }
    267 
    268                                         finished = true;
    269 
    270                                 } else {
    271                                         throw new SAXException("wrong closing tag " + name +
    272                                                         " (</" + openingName + "> expected");
    273                                 }
    274 
    275                         }
    276 
    277                 }
    278 
    279                 public boolean isFinished() {
    280                         return finished;
    281                 }
    282 
    283                 public TagCondition getCondition() {
    284                         if (!finished) {
    285                                 throw new IllegalStateException("condition " + openingName + " not yet finished");
    286                         } else {
    287                                 assert condition != null;
    288                                 return condition;
    289                         }
    290                 }
    291 
    292         }
     19    private final List<Implication> implications = new LinkedList<Implication>();
     20
     21    private static enum State {BEFORE_IMPLICATION, BEFORE_CONDITION, CONDITION, BEFORE_IMPLIES, IMPLIES, AFTER_IMPLIES};
     22    private State state = State.BEFORE_IMPLICATION;
     23
     24    private ConditionReader currentConditionReader;
     25    private TagCondition currentCondition;
     26    private Collection<Tag> currentImpliedTags;
     27
     28    boolean tagOpen = false;
     29
     30    public void startElement(String uri, String localName, String name, Attributes attributes)
     31    throws SAXException {
     32
     33        switch (state) {
     34
     35            case BEFORE_IMPLICATION:
     36
     37                if ("implication".equals(name)) {
     38                    state = State.BEFORE_CONDITION;
     39                    return;
     40                }
     41                break;
     42
     43            case BEFORE_CONDITION:
     44
     45                if ("condition".equals(name)) {
     46                    currentConditionReader = new ConditionReader();
     47                    state = State.CONDITION;
     48                    return;
     49                }
     50                break;
     51
     52            case CONDITION:
     53                currentConditionReader.startElement(uri, localName, name, attributes);
     54                return;
     55
     56            case BEFORE_IMPLIES:
     57
     58                if ("implies".equals(name)) {
     59                    currentImpliedTags = new LinkedList<Tag>();
     60                    state = State.IMPLIES;
     61                    return;
     62                }
     63                break;
     64
     65            case IMPLIES:
     66
     67                if ("tag".equals(name)) {
     68                    if (tagOpen) {
     69                        throw new SAXException("tag element inside other tag element");
     70                    }
     71                    currentImpliedTags.add(readTag(attributes));
     72                    tagOpen = true;
     73                    return;
     74                }
     75                break;
     76
     77        }
     78
     79        //all vaild paths end with return; reaching this indicates an invalid tag
     80        throw new SAXException("invalid opening xml tag <" + name + "> in state " + state);
     81
     82    }
     83
     84    public void endElement(String uri, String localName, String name)
     85    throws SAXException {
     86
     87        switch (state) {
     88
     89            case CONDITION:
     90
     91                if (name.equals("condition")) {
     92                    if (!currentConditionReader.isFinished()) {
     93                        throw new SAXException("condition isn't finished at </condition> tag");
     94                    } else {
     95                        currentCondition = currentConditionReader.getCondition();
     96                        currentConditionReader = null;
     97                        state = State.BEFORE_IMPLIES;
     98                        return;
     99                    }
     100                } else {
     101                    currentConditionReader.endElement(uri, localName, name);
     102                    return;
     103                }
     104
     105            case IMPLIES:
     106
     107                if (name.equals("implies")) {
     108                    state = State.AFTER_IMPLIES;
     109                    return;
     110                } else if (name.equals("tag")) {
     111                    if (!tagOpen) {
     112                        throw new SAXException("closing tag element that was not open");
     113                    }
     114                    tagOpen = false;
     115                    return;
     116                }
     117                break;
     118
     119            case AFTER_IMPLIES:
     120
     121                if (name.equals("implication")) {
     122                    implications.add(new Implication(currentCondition, currentImpliedTags));
     123                    currentCondition = null;
     124                    currentImpliedTags = null;
     125                    state = State.BEFORE_IMPLICATION;
     126                    return;
     127                }
     128                break;
     129
     130        }
     131
     132        //all vaild paths end with return; reaching this indicates an invalid tag
     133        throw new SAXException("invalid closing xml tag </" + name + "> in state " + state);
     134
     135    }
     136
     137    public List<Implication> getImplications() throws SAXException {
     138
     139        if (state != State.BEFORE_IMPLICATION) {
     140            throw new SAXException("some tags not been closed; now in state " + state);
     141        } else {
     142            return new ArrayList<Implication>(implications);
     143        }
     144    }
     145
     146    private static Tag readTag(Attributes attributes) throws SAXException {
     147
     148        String key = attributes.getValue("k");
     149        String value = attributes.getValue("v");
     150
     151        if (key == null) {
     152            throw new SAXException("tag without key");
     153        } else if (value == null) {
     154            throw new SAXException("tag without value (key is " + key + ")");
     155        }
     156
     157        return new Tag(key, value);
     158    }
     159
     160    private static String readKey(Attributes attributes) throws SAXException {
     161
     162        String key = attributes.getValue("k");
     163
     164        if (key == null) {
     165            throw new SAXException("key element without attribute k");
     166        }
     167
     168        return key;
     169    }
     170
     171    /**
     172    * class to be used for reading tag condition sections of xml files
     173    */
     174    private static class ConditionReader {
     175
     176        String openingName;
     177        TagCondition condition;
     178        boolean finished;
     179
     180        private final List<ConditionReader> childReaders = new LinkedList<ConditionReader>();
     181        private ConditionReader currentChildReader = null;
     182
     183        public void startElement(String uri, String localName, String name, Attributes attributes)
     184        throws SAXException {
     185
     186            if (finished) {
     187                throw new SAXException("condition is already finished at <" + name + ">");
     188            }
     189
     190            if (currentChildReader != null) {
     191                currentChildReader.startElement(uri, localName, name, attributes);
     192                return;
     193            }
     194
     195            //first tag is start tag of this condition
     196            if (openingName == null) {
     197
     198                openingName = name;
     199
     200                if ("tag".equals(name)) {
     201                    condition = TagConditionLogic.tag(readTag(attributes));
     202                } else if ("key".equals(name)) {
     203                    condition = TagConditionLogic.key(readKey(attributes));
     204                } else if (!("or".equals(name)) && !("and".equals(name)) && !("not".equals(name))) {
     205                    throw new SAXException("unknown tag for condition: " + name);
     206                }
     207
     208                //all tags after the first are start tags of child conditions
     209            } else {
     210
     211                if ("tag".equals(openingName) || "key".equals(openingName)) {
     212                    throw new SAXException("element must not have childs: " + openingName);
     213                }
     214
     215                currentChildReader = new ConditionReader();
     216                currentChildReader.startElement(uri, localName, name, attributes);
     217
     218            }
     219
     220        }
     221
     222        public void endElement(String uri, String localName, String name)
     223        throws SAXException {
     224
     225            if (finished) {
     226                throw new SAXException("condition is already finished at </" + name + ">");
     227            }
     228
     229            /* if active child reader exists, pass parameter to it. */
     230            if (currentChildReader != null) {
     231
     232                currentChildReader.endElement(uri, localName, name);
     233
     234                if (currentChildReader.isFinished()) {
     235                    childReaders.add(currentChildReader);
     236                    currentChildReader = null;
     237                }
     238
     239            } else {
     240
     241                if (openingName.equals(name)) {
     242
     243                    List<TagCondition> childConditions = new ArrayList<TagCondition>();
     244                    for (ConditionReader childReader : childReaders) {
     245                        childConditions.add(childReader.getCondition());
     246                    }
     247
     248                    if ("and".equals(openingName)) {
     249                        if (childConditions.size() > 0) {
     250                            condition = TagConditionLogic.and(childConditions);
     251                        } else {
     252                            throw new SAXException("<and> needs at least one child");
     253                        }
     254                    } else if ("or".equals(openingName)) {
     255                        if (childConditions.size() > 0) {
     256                            condition = TagConditionLogic.or(childConditions);
     257                        } else {
     258                            throw new SAXException("<or> needs at least one child");
     259                        }
     260                    } else if ("not".equals(openingName)) {
     261                        if (childConditions.size() == 1) {
     262                            condition = TagConditionLogic.not(childConditions.get(0));
     263                        } else {
     264                            throw new SAXException("<not> needs at least one child");
     265                        }
     266                    }
     267
     268                    finished = true;
     269
     270                } else {
     271                    throw new SAXException("wrong closing tag " + name +
     272                            " (</" + openingName + "> expected");
     273                }
     274
     275            }
     276
     277        }
     278
     279        public boolean isFinished() {
     280            return finished;
     281        }
     282
     283        public TagCondition getCondition() {
     284            if (!finished) {
     285                throw new IllegalStateException("condition " + openingName + " not yet finished");
     286            } else {
     287                assert condition != null;
     288                return condition;
     289            }
     290        }
     291
     292    }
    293293
    294294}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/access/RulesetAccessEvaluator.java

    r19216 r23189  
    1818public class RulesetAccessEvaluator<N, W, R, M> implements AccessEvaluator<N, W> {
    1919
    20         private final DataSource<N, W, R, M> dataSource;
    21         private final AccessRuleset ruleset;
    22         private final AccessParameters parameters;
     20    private final DataSource<N, W, R, M> dataSource;
     21    private final AccessRuleset ruleset;
     22    private final AccessParameters parameters;
    2323
    24         /**
    25         * @param dataSource  object that allows access to data objects and tags/members; != null
    26         * @param ruleset     ruleset that is used for evaluation; != null
    27         * @param parameters  parameters object that describes the vehicle
    28         *                    and situation to evaluate access for; != null
    29         */
    30         public RulesetAccessEvaluator(DataSource<N, W, R, M> dataSource, AccessRuleset ruleset, AccessParameters parameters) {
    31                 assert dataSource != null && ruleset != null && parameters != null;
     24    /**
     25    * @param dataSource  object that allows access to data objects and tags/members; != null
     26    * @param ruleset     ruleset that is used for evaluation; != null
     27    * @param parameters  parameters object that describes the vehicle
     28    *                    and situation to evaluate access for; != null
     29    */
     30    public RulesetAccessEvaluator(DataSource<N, W, R, M> dataSource, AccessRuleset ruleset, AccessParameters parameters) {
     31        assert dataSource != null && ruleset != null && parameters != null;
    3232
    33                 this.dataSource = dataSource;
    34                 this.ruleset = ruleset;
    35                 this.parameters = parameters;
     33        this.dataSource = dataSource;
     34        this.ruleset = ruleset;
     35        this.parameters = parameters;
    3636
    37         }
     37    }
    3838
    39         public boolean wayUsable(W way, boolean forward,
    40                         Map<RoadPropertyType<?>, Object> segmentPropertyValues) {
     39    public boolean wayUsable(W way, boolean forward,
     40            Map<RoadPropertyType<?>, Object> segmentPropertyValues) {
    4141
    42                 TagGroup wayTags = dataSource.getTagsW(way);
     42        TagGroup wayTags = dataSource.getTagsW(way);
    4343
    44                 TagGroup wayTagsWithImplications = new MapBasedTagGroup(wayTags);
    45                 for (Implication implication : ruleset.getImplications()) {
    46                         wayTagsWithImplications = implication.apply(wayTagsWithImplications);
    47                 }
     44        TagGroup wayTagsWithImplications = new MapBasedTagGroup(wayTags);
     45        for (Implication implication : ruleset.getImplications()) {
     46            wayTagsWithImplications = implication.apply(wayTagsWithImplications);
     47        }
    4848
    49                 /* check base tagging */
     49        /* check base tagging */
    5050
    51                 boolean usableWay = false;
    52                 for (Tag tag : ruleset.getBaseTags()) {
    53                         if (wayTags.contains(tag)) {
    54                                 usableWay = true;
    55                                 break;
    56                         }
    57                 }
     51        boolean usableWay = false;
     52        for (Tag tag : ruleset.getBaseTags()) {
     53            if (wayTags.contains(tag)) {
     54                usableWay = true;
     55                break;
     56            }
     57        }
    5858
    59                 if (!usableWay) {
    60                         return false;
    61                 }
     59        if (!usableWay) {
     60            return false;
     61        }
    6262
    63                 /* evaluate one-way tagging */
     63        /* evaluate one-way tagging */
    6464
    65                 String onewayValue =  wayTagsWithImplications.getValue("oneway");
     65        String onewayValue =  wayTagsWithImplications.getValue("oneway");
    6666
    67                 if (forward && "-1".equals(onewayValue)
    68                                 && !"foot".equals(parameters.getAccessClass())) {
    69                         return false;
    70                 }
     67        if (forward && "-1".equals(onewayValue)
     68                && !"foot".equals(parameters.getAccessClass())) {
     69            return false;
     70        }
    7171
    72                 if (!forward
    73                                 && ("1".equals(onewayValue) || "yes".equals(onewayValue) || "true".equals(onewayValue))
    74                                 && !"foot".equals(parameters.getAccessClass())) {
    75                         return false;
    76                 }
     72        if (!forward
     73                && ("1".equals(onewayValue) || "yes".equals(onewayValue) || "true".equals(onewayValue))
     74                && !"foot".equals(parameters.getAccessClass())) {
     75            return false;
     76        }
    7777
    78                 /* evaluate properties and access tagging */
     78        /* evaluate properties and access tagging */
    7979
    80                 return objectUsable(segmentPropertyValues, wayTags);
    81         }
     80        return objectUsable(segmentPropertyValues, wayTags);
     81    }
    8282
    83         public boolean nodeUsable(N node, Map<RoadPropertyType<?>,Object> roadPropertyValues) {
     83    public boolean nodeUsable(N node, Map<RoadPropertyType<?>,Object> roadPropertyValues) {
    8484
    85                 TagGroup nodeTags = dataSource.getTagsN(node);
     85        TagGroup nodeTags = dataSource.getTagsN(node);
    8686
    87                 return objectUsable(roadPropertyValues, nodeTags);
    88         };
     87        return objectUsable(roadPropertyValues, nodeTags);
     88    };
    8989
    90         private boolean objectUsable(Map<RoadPropertyType<?>, Object> roadPropertyValues,
    91                         TagGroup tags) {
     90    private boolean objectUsable(Map<RoadPropertyType<?>, Object> roadPropertyValues,
     91            TagGroup tags) {
    9292
    93                 /* evaluate road properties */
     93        /* evaluate road properties */
    9494
    95                 for (RoadPropertyType<?> property : roadPropertyValues.keySet()) {
    96                         if (!property.isUsable(roadPropertyValues.get(property), parameters)) {
    97                                 return false;
    98                         }
    99                 }
     95        for (RoadPropertyType<?> property : roadPropertyValues.keySet()) {
     96            if (!property.isUsable(roadPropertyValues.get(property), parameters)) {
     97                return false;
     98            }
     99        }
    100100
    101                 /* evaluate access type */
     101        /* evaluate access type */
    102102
    103                 AccessType accessType = UNDEFINED;
     103        AccessType accessType = UNDEFINED;
    104104
    105                 if (tags.size() > 0) {
     105        if (tags.size() > 0) {
    106106
    107                         Map<String, AccessType> accessTypePerClass =
    108                                 createAccessTypePerClassMap(tags, ruleset.getAccessHierarchyAncestors(parameters.getAccessClass()));
     107            Map<String, AccessType> accessTypePerClass =
     108                createAccessTypePerClassMap(tags, ruleset.getAccessHierarchyAncestors(parameters.getAccessClass()));
    109109
    110                         for (String accessClass : ruleset.getAccessHierarchyAncestors(parameters.getAccessClass())) {
    111                                 accessType = accessTypePerClass.get(accessClass);
    112                                 if (accessType != UNDEFINED) { break; }
    113                         }
     110            for (String accessClass : ruleset.getAccessHierarchyAncestors(parameters.getAccessClass())) {
     111                accessType = accessTypePerClass.get(accessClass);
     112                if (accessType != UNDEFINED) { break; }
     113            }
    114114
    115                 }
     115        }
    116116
    117                 return parameters.getAccessTypeUsable(accessType);
    118         }
     117        return parameters.getAccessTypeUsable(accessType);
     118    }
    119119
    120         private Map<String, AccessType> createAccessTypePerClassMap(
    121                         TagGroup wayTags, Collection<String> accessClasses) {
     120    private Map<String, AccessType> createAccessTypePerClassMap(
     121            TagGroup wayTags, Collection<String> accessClasses) {
    122122
    123                 /*
    124                 * create map and fill with UNDEFINED values
    125                 * (this also allows to use keySet instead of accessClasses later)
    126                 */
     123        /*
     124        * create map and fill with UNDEFINED values
     125        * (this also allows to use keySet instead of accessClasses later)
     126        */
    127127
    128                 Map<String, AccessType> accessTypePerClass = new HashMap<String, AccessType>();
     128        Map<String, AccessType> accessTypePerClass = new HashMap<String, AccessType>();
    129129
    130                 for (String accessClass : accessClasses) {
    131                         accessTypePerClass.put(accessClass, AccessType.UNDEFINED);
    132                 }
     130        for (String accessClass : accessClasses) {
     131            accessTypePerClass.put(accessClass, AccessType.UNDEFINED);
     132        }
    133133
    134                 /* evaluate implied tagging of base tag */
     134        /* evaluate implied tagging of base tag */
    135135
    136                 Tag baseTag = null;
    137                 for (Tag tag : wayTags) {
    138                         if (ruleset.getBaseTags().contains(tag)) {
    139                                 baseTag = tag;
    140                                 break;
    141                         }
    142                 }
     136        Tag baseTag = null;
     137        for (Tag tag : wayTags) {
     138            if (ruleset.getBaseTags().contains(tag)) {
     139                baseTag = tag;
     140                break;
     141            }
     142        }
    143143
    144                 if (baseTag != null) {
     144        if (baseTag != null) {
    145145
    146                         TagGroup tagsWithBaseImplications = new MapBasedTagGroup(baseTag);
    147                         for (Implication implication : ruleset.getImplications()) {
    148                                 tagsWithBaseImplications = implication.apply(tagsWithBaseImplications);
    149                         }
     146            TagGroup tagsWithBaseImplications = new MapBasedTagGroup(baseTag);
     147            for (Implication implication : ruleset.getImplications()) {
     148                tagsWithBaseImplications = implication.apply(tagsWithBaseImplications);
     149            }
    150150
    151                         setAccessTypesFromTags(accessTypePerClass, tagsWithBaseImplications);
     151            setAccessTypesFromTags(accessTypePerClass, tagsWithBaseImplications);
    152152
    153                 }
     153        }
    154154
    155                 /* evaluate implied tagging of other tags */
     155        /* evaluate implied tagging of other tags */
    156156
    157                 Map<String, String> tagMap = new HashMap<String, String>();
    158                 for (Tag tag : wayTags) {
    159                         if (!tag.equals(baseTag)) {
    160                                 tagMap.put(tag.key, tag.value);
    161                         }
    162                 }
     157        Map<String, String> tagMap = new HashMap<String, String>();
     158        for (Tag tag : wayTags) {
     159            if (!tag.equals(baseTag)) {
     160                tagMap.put(tag.key, tag.value);
     161            }
     162        }
    163163
    164                 TagGroup tagsWithOtherImplications = new MapBasedTagGroup(tagMap);
    165                 for (Implication implication : ruleset.getImplications()) {
    166                         tagsWithOtherImplications = implication.apply(tagsWithOtherImplications);
    167                 }
     164        TagGroup tagsWithOtherImplications = new MapBasedTagGroup(tagMap);
     165        for (Implication implication : ruleset.getImplications()) {
     166            tagsWithOtherImplications = implication.apply(tagsWithOtherImplications);
     167        }
    168168
    169                 setAccessTypesFromTags(accessTypePerClass, tagsWithOtherImplications);
     169        setAccessTypesFromTags(accessTypePerClass, tagsWithOtherImplications);
    170170
    171                 /* evaluate explicit access tagging */
     171        /* evaluate explicit access tagging */
    172172
    173                 for (String key : ruleset.getAccessHierarchyAncestors(parameters.getAccessClass())) {
    174                         String value = wayTags.getValue(key);
    175                         if (value != null) {
    176                                 AccessType accessType = AccessType.getAccessType(value);
    177                                 accessTypePerClass.put(key, accessType);
    178                         }
    179                 }
     173        for (String key : ruleset.getAccessHierarchyAncestors(parameters.getAccessClass())) {
     174            String value = wayTags.getValue(key);
     175            if (value != null) {
     176                AccessType accessType = AccessType.getAccessType(value);
     177                accessTypePerClass.put(key, accessType);
     178            }
     179        }
    180180
    181                 return accessTypePerClass;
    182         }
     181        return accessTypePerClass;
     182    }
    183183
    184         /**
    185         * adds all access information from a collection of tags to a [access class -> access type] map.
    186         * Existing entries will be replaced.
    187         */
    188         private void setAccessTypesFromTags(Map<String, AccessType> accessTypePerClass, TagGroup tags) {
    189                 for (String accessClass : accessTypePerClass.keySet()) {
    190                         String value = tags.getValue(accessClass);
    191                         if (value != null) {
    192                                 AccessType accessType = AccessType.getAccessType(value);
    193                                 accessTypePerClass.put(accessClass, accessType);
    194                         }
    195                 }
    196         }
     184    /**
     185    * adds all access information from a collection of tags to a [access class -> access type] map.
     186    * Existing entries will be replaced.
     187    */
     188    private void setAccessTypesFromTags(Map<String, AccessType> accessTypePerClass, TagGroup tags) {
     189        for (String accessClass : accessTypePerClass.keySet()) {
     190            String value = tags.getValue(accessClass);
     191            if (value != null) {
     192                AccessType accessType = AccessType.getAccessType(value);
     193                accessTypePerClass.put(accessClass, accessType);
     194            }
     195        }
     196    }
    197197
    198198}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/data/DataSource.java

    r19216 r23189  
    99 */
    1010public interface DataSource<N, W, R, M> {
    11        
    12         /** returns all nodes */
    13         public Iterable<N> getNodes();
    1411
    15         /** returns all ways */
    16         public Iterable<W> getWays();
     12    /** returns all nodes */
     13    public Iterable<N> getNodes();
    1714
    18         /** returns all relations */
    19         public Iterable<R> getRelations();
     15    /** returns all ways */
     16    public Iterable<W> getWays();
    2017
    21         /** returns a node's latitude */
    22         public double getLat(N node);
     18    /** returns all relations */
     19    public Iterable<R> getRelations();
    2320
    24         /** returns a node's longitude */
    25         public double getLon(N node);
     21    /** returns a node's latitude */
     22    public double getLat(N node);
    2623
    27         /** returns a way's nodes */
    28         public Iterable<N> getNodes(W way);
     24    /** returns a node's longitude */
     25    public double getLon(N node);
    2926
    30         /** returns a relation's members */
    31         public Iterable<M> getMembers(R relation);
     27    /** returns a way's nodes */
     28    public Iterable<N> getNodes(W way);
    3229
    33         /** returns a node's tags */
    34         public TagGroup getTagsN(N node);
     30    /** returns a relation's members */
     31    public Iterable<M> getMembers(R relation);
    3532
    36         /** returns a way's tags */
    37         public TagGroup getTagsW(W way);
     33    /** returns a node's tags */
     34    public TagGroup getTagsN(N node);
    3835
    39         /** returns a relation's tags */
    40         public TagGroup getTagsR(R relation);
     36    /** returns a way's tags */
     37    public TagGroup getTagsW(W way);
    4138
    42         /** returns a relation member's role */
    43         public String getRole(M member);
     39    /** returns a relation's tags */
     40    public TagGroup getTagsR(R relation);
    4441
    45         /** returns a relation member's member object */
    46         public Object getMember(M member);
    47        
    48         /** returns whether a relation member is a node */
    49         public boolean isNMember(M member);
    50        
    51         /** returns whether a relation member is a way */
    52         public boolean isWMember(M member);
    53        
    54         /** returns whether a relation member is a relation */
    55         public boolean isRMember(M member);
    56        
    57         /**
    58          * adds an observer.
    59          * Does nothing if the parameter is already an observer of this DataSource.
    60          *
    61          * @param observer  observer object, != null
    62          */
    63         public void addObserver(DataSourceObserver observer);
     42    /** returns a relation member's role */
     43    public String getRole(M member);
    6444
    65         /**
    66          * deletes an observer that has been added using {@link #addObserver(DataSourceObserver)}.
    67          * Does nothing if the parameter isn't currently an observer of this DataSource.
    68          *
    69          * @param observer  observer object, != null
    70          */
    71         public void deleteObserver(DataSourceObserver observer);
     45    /** returns a relation member's member object */
     46    public Object getMember(M member);
     47
     48    /** returns whether a relation member is a node */
     49    public boolean isNMember(M member);
     50
     51    /** returns whether a relation member is a way */
     52    public boolean isWMember(M member);
     53
     54    /** returns whether a relation member is a relation */
     55    public boolean isRMember(M member);
     56
     57    /**
     58     * adds an observer.
     59     * Does nothing if the parameter is already an observer of this DataSource.
     60     *
     61     * @param observer  observer object, != null
     62     */
     63    public void addObserver(DataSourceObserver observer);
     64
     65    /**
     66     * deletes an observer that has been added using {@link #addObserver(DataSourceObserver)}.
     67     * Does nothing if the parameter isn't currently an observer of this DataSource.
     68     *
     69     * @param observer  observer object, != null
     70     */
     71    public void deleteObserver(DataSourceObserver observer);
    7272
    7373}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/data/DataSourceObserver.java

    r19216 r23189  
    88public interface DataSourceObserver {
    99
    10         /**
    11         * informs this observer about changes in an observed data source
    12         * @param dataSource  observed data source that has changed; != null
    13         */
    14         public void update(DataSource<?, ?, ?, ?> dataSource);
     10    /**
     11    * informs this observer about changes in an observed data source
     12    * @param dataSource  observed data source that has changed; != null
     13    */
     14    public void update(DataSource<?, ?, ?, ?> dataSource);
    1515
    1616}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/data/MapBasedTagGroup.java

    r16520 r23189  
    1313public class MapBasedTagGroup implements TagGroup {
    1414
    15         private final Map<String, String> tagMap;
     15    private final Map<String, String> tagMap;
    1616
    17         /**
    18         * @param tagMap  map from keys to values; != null;
    19         *                must not be modified after being used as parameter
    20         */
    21         public MapBasedTagGroup(Map<String, String> tagMap) {
    22                 if (tagMap == null) {
    23                         throw new IllegalArgumentException();
    24                 }
     17    /**
     18    * @param tagMap  map from keys to values; != null;
     19    *                must not be modified after being used as parameter
     20    */
     21    public MapBasedTagGroup(Map<String, String> tagMap) {
     22        if (tagMap == null) {
     23            throw new IllegalArgumentException();
     24        }
    2525
    26                 this.tagMap = tagMap;
    27         }
     26        this.tagMap = tagMap;
     27    }
    2828
    29         /**
    30         * @param tags  tags to add to the group; != null, each != null
    31         */
    32         public MapBasedTagGroup(Iterable<Tag> tags) {
    33                 if (tags == null) {
    34                         throw new IllegalArgumentException();
    35                 }
    36                 this.tagMap = new HashMap<String, String>();
    37                 for (Tag tag : tags) {
    38                         if (tag == null) {
    39                                 throw new IllegalArgumentException();
    40                         } else {
    41                                 this.tagMap.put(tag.key, tag.value);
    42                         }
    43                 }
    44         }
     29    /**
     30    * @param tags  tags to add to the group; != null, each != null
     31    */
     32    public MapBasedTagGroup(Iterable<Tag> tags) {
     33        if (tags == null) {
     34            throw new IllegalArgumentException();
     35        }
     36        this.tagMap = new HashMap<String, String>();
     37        for (Tag tag : tags) {
     38            if (tag == null) {
     39                throw new IllegalArgumentException();
     40            } else {
     41                this.tagMap.put(tag.key, tag.value);
     42            }
     43        }
     44    }
    4545
    46         /**
    47         * @param tags  tags to add to the group; each != null
    48         */
    49         public MapBasedTagGroup(Tag... tags) {
    50                 this.tagMap = new HashMap<String, String>(tags.length);
    51                 for (Tag tag : tags) {
    52                         if (tag == null) {
    53                                 throw new IllegalArgumentException();
    54                         } else {
    55                                 this.tagMap.put(tag.key, tag.value);
    56                         }
    57                 }
    58         }
     46    /**
     47    * @param tags  tags to add to the group; each != null
     48    */
     49    public MapBasedTagGroup(Tag... tags) {
     50        this.tagMap = new HashMap<String, String>(tags.length);
     51        for (Tag tag : tags) {
     52            if (tag == null) {
     53                throw new IllegalArgumentException();
     54            } else {
     55                this.tagMap.put(tag.key, tag.value);
     56            }
     57        }
     58    }
    5959
    60         public String getValue(String key) {
    61                 assert key != null;
    62                 return tagMap.get(key);
    63         }
     60    public String getValue(String key) {
     61        assert key != null;
     62        return tagMap.get(key);
     63    }
    6464
    65         public boolean containsKey(String key) {
    66                 assert key != null;
    67                 return tagMap.containsKey(key);
    68         }
     65    public boolean containsKey(String key) {
     66        assert key != null;
     67        return tagMap.containsKey(key);
     68    }
    6969
    70         public boolean containsValue(String value) {
    71                 assert value != null;
    72                 return tagMap.containsValue(value);
    73         }
     70    public boolean containsValue(String value) {
     71        assert value != null;
     72        return tagMap.containsValue(value);
     73    }
    7474
    75         public boolean contains(Tag tag) {
    76                 assert tag != null;
    77                 return tag.value.equals(tagMap.get(tag.key));
    78         }
     75    public boolean contains(Tag tag) {
     76        assert tag != null;
     77        return tag.value.equals(tagMap.get(tag.key));
     78    }
    7979
    80         public int size() {
    81                 return tagMap.size();
    82         }
     80    public int size() {
     81        return tagMap.size();
     82    }
    8383
    84         /**
    85         * returns an Iterator providing access to all Tags.
    86         * The Iterator does not support the {@link Iterator#remove()} method.
    87         */
    88         public Iterator<Tag> iterator() {
     84    /**
     85    * returns an Iterator providing access to all Tags.
     86    * The Iterator does not support the {@link Iterator#remove()} method.
     87    */
     88    public Iterator<Tag> iterator() {
    8989
    90                 Collection<Tag> tagCollection = new LinkedList<Tag>();
     90        Collection<Tag> tagCollection = new LinkedList<Tag>();
    9191
    92                 for (String key : tagMap.keySet()) {
    93                         tagCollection.add(new Tag(key, tagMap.get(key)));
    94                 }
     92        for (String key : tagMap.keySet()) {
     93            tagCollection.add(new Tag(key, tagMap.get(key)));
     94        }
    9595
    96                 return Collections.unmodifiableCollection(tagCollection).iterator();
     96        return Collections.unmodifiableCollection(tagCollection).iterator();
    9797
    98         }
     98    }
    9999
    100         @Override
    101         public String toString() {
    102                 return tagMap.toString();
    103         }
     100    @Override
     101    public String toString() {
     102        return tagMap.toString();
     103    }
    104104
    105105}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/data/Tag.java

    r16520 r23189  
    66public class Tag {
    77
    8         /** key of the tag; != null */
    9         public final String key;
     8    /** key of the tag; != null */
     9    public final String key;
    1010
    11         /** value of the tag; != null */
    12         public final String value;
     11    /** value of the tag; != null */
     12    public final String value;
    1313
    14         public Tag(String key, String value) {
    15                 assert key != null && value != null;
    16                 this.key = key;
    17                 this.value = value;
    18         }
     14    public Tag(String key, String value) {
     15        assert key != null && value != null;
     16        this.key = key;
     17        this.value = value;
     18    }
    1919
    20         @Override
    21         public boolean equals(Object obj) {
    22                 if (!(obj instanceof Tag)) {
    23                         return false;
    24                 } else {
    25                         Tag otherTag = (Tag)obj;
    26                         return key.equals(otherTag.key) && value.equals(otherTag.value);
    27                 }
    28         }
     20    @Override
     21    public boolean equals(Object obj) {
     22        if (!(obj instanceof Tag)) {
     23            return false;
     24        } else {
     25            Tag otherTag = (Tag)obj;
     26            return key.equals(otherTag.key) && value.equals(otherTag.value);
     27        }
     28    }
    2929
    30         @Override
    31         public int hashCode() {
    32                 return key.hashCode() + value.hashCode();
    33         }
     30    @Override
     31    public int hashCode() {
     32        return key.hashCode() + value.hashCode();
     33    }
    3434
    35         @Override
    36         public String toString() {
    37                 return key + "=" + value;
    38         }
     35    @Override
     36    public String toString() {
     37        return key + "=" + value;
     38    }
    3939
    4040}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/data/TagGroup.java

    r16520 r23189  
    88public interface TagGroup extends Iterable<Tag> {
    99
    10         /**
    11         * returns the value for the given key or null if no tag in this group uses that key
    12         * @param key  key whose value will be returned; != null
    13         */
    14         public String getValue(String key);
     10    /**
     11    * returns the value for the given key or null if no tag in this group uses that key
     12    * @param key  key whose value will be returned; != null
     13    */
     14    public String getValue(String key);
    1515
    16         /**
    17         * returns true if this tag group contains a tag with the given key
    18         * @param key  key to check for; != null
    19         */
    20         public boolean containsKey(String key);
     16    /**
     17    * returns true if this tag group contains a tag with the given key
     18    * @param key  key to check for; != null
     19    */
     20    public boolean containsKey(String key);
    2121
    22         /**
    23         * returns true if this tag group contains at least one tag with the given value
    24         * @param value  value to check for; != null
    25         */
    26         public boolean containsValue(String value);
     22    /**
     23    * returns true if this tag group contains at least one tag with the given value
     24    * @param value  value to check for; != null
     25    */
     26    public boolean containsValue(String value);
    2727
    28         /**
    29         * returns true if this tag group contains the given tag
    30         * @param tag  tag to check for; != null
    31         */
    32         public boolean contains(Tag tag);
     28    /**
     29    * returns true if this tag group contains the given tag
     30    * @param tag  tag to check for; != null
     31    */
     32    public boolean contains(Tag tag);
    3333
    34         /**
    35         * returns the number of tags in this group
    36         */
    37         public int size();
     34    /**
     35    * returns the number of tags in this group
     36    */
     37    public int size();
    3838
    3939}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/graph/ConnectorEvaluationGroup.java

    r18130 r23189  
    1616public class ConnectorEvaluationGroup extends EvaluationGroup {
    1717
    18         private final Set<Segment> segments;
    19         private final List<SegmentNode> borderNodes;
     18    private final Set<Segment> segments;
     19    private final List<SegmentNode> borderNodes;
    2020
    21         /**
    22         * @param segments     set of Segments, must not be modified
    23         *                     after being used as constructor parameter; != null
    24         * @param borderNodes  nodes that are used as starting/target nodes for sequences; != null
    25         */
    26         public ConnectorEvaluationGroup(Set<Segment> segments, Set<SegmentNode> borderNodes) {
    27                 assert segments != null && borderNodes != null;
     21    /**
     22    * @param segments     set of Segments, must not be modified
     23    *                     after being used as constructor parameter; != null
     24    * @param borderNodes  nodes that are used as starting/target nodes for sequences; != null
     25    */
     26    public ConnectorEvaluationGroup(Set<Segment> segments, Set<SegmentNode> borderNodes) {
     27        assert segments != null && borderNodes != null;
    2828
    29                 this.segments = segments;
    30                 this.borderNodes = new ArrayList<SegmentNode>(borderNodes);
    31         }
     29        this.segments = segments;
     30        this.borderNodes = new ArrayList<SegmentNode>(borderNodes);
     31    }
    3232
    33         /**
    34         * returns all nodes that can be used as start/target nodes
    35         * @return  border nodes; != null
    36         */
    37         public Collection<SegmentNode> getBorderNodes() {
    38                 return borderNodes;
    39         }
     33    /**
     34    * returns all nodes that can be used as start/target nodes
     35    * @return  border nodes; != null
     36    */
     37    public Collection<SegmentNode> getBorderNodes() {
     38        return borderNodes;
     39    }
    4040
    41         /**
    42         * returns all segments in the group
    43         * @return  segment set; != null
    44         */
    45         public Set<Segment> getSegments() {
    46                 return segments;
    47         }
     41    /**
     42    * returns all segments in the group
     43    * @return  segment set; != null
     44    */
     45    public Set<Segment> getSegments() {
     46        return segments;
     47    }
    4848
    49         /**
    50         * returns a segment sequence that runs from an inbound to an outbound
    51         * segment or null if no connection is possible.
    52         * {@link EvaluationGroup#evaluate(Collection)} needs be called before this method.
    53         *
    54         * @param  startNode   start of the potential sequence; must be border node; != null
    55         * @param  targetNode  target of the potential sequence; must be border node; != null
    56         * @return             sequence of segments or null
    57         */
    58         public List<Segment> getSegmentSequence(SegmentNode startNode, SegmentNode targetNode) {
    59                 assert startNode != null && borderNodes.contains(startNode);
    60                 assert targetNode != null && borderNodes.contains(targetNode);
     49    /**
     50    * returns a segment sequence that runs from an inbound to an outbound
     51    * segment or null if no connection is possible.
     52    * {@link EvaluationGroup#evaluate(Collection)} needs be called before this method.
     53    *
     54    * @param  startNode   start of the potential sequence; must be border node; != null
     55    * @param  targetNode  target of the potential sequence; must be border node; != null
     56    * @return             sequence of segments or null
     57    */
     58    public List<Segment> getSegmentSequence(SegmentNode startNode, SegmentNode targetNode) {
     59        assert startNode != null && borderNodes.contains(startNode);
     60        assert targetNode != null && borderNodes.contains(targetNode);
    6161
    62                 if (!evaluated) { throw new IllegalStateException("group not yet evaluated"); }
     62        if (!evaluated) { throw new IllegalStateException("group not yet evaluated"); }
    6363
    64                 int inboundIndex = borderNodes.indexOf(startNode);
    65                 int outboundIndex = borderNodes.indexOf(targetNode);
     64        int inboundIndex = borderNodes.indexOf(startNode);
     65        int outboundIndex = borderNodes.indexOf(targetNode);
    6666
    67                 return segmentSequences[inboundIndex][outboundIndex];
    68         }
     67        return segmentSequences[inboundIndex][outboundIndex];
     68    }
    6969
    70         @Override
    71         protected void evaluateImpl(Collection<Restriction> restrictions) {
     70    @Override
     71    protected void evaluateImpl(Collection<Restriction> restrictions) {
    7272
    73                 /* find segment sequences from inbound to outbound segments */
     73        /* find segment sequences from inbound to outbound segments */
    7474
    75                 @SuppressWarnings("unchecked") //cannot create generic array without cast
    76                 List<Segment>[][] sequenceArray = new List[borderNodes.size()][borderNodes.size()];
     75        @SuppressWarnings("unchecked") //cannot create generic array without cast
     76        List<Segment>[][] sequenceArray = new List[borderNodes.size()][borderNodes.size()];
    7777
    78                 for (int startIndex = 0; startIndex < borderNodes.size(); startIndex ++) {
    79                         for (int targetIndex = 0; targetIndex < borderNodes.size(); targetIndex ++) {
     78        for (int startIndex = 0; startIndex < borderNodes.size(); startIndex ++) {
     79            for (int targetIndex = 0; targetIndex < borderNodes.size(); targetIndex ++) {
    8080
    81                                 List<Segment> sequence =
    82                                         findSegmentSequence(borderNodes.get(startIndex),
    83                                                         borderNodes.get(targetIndex), restrictions);
     81                List<Segment> sequence =
     82                    findSegmentSequence(borderNodes.get(startIndex),
     83                            borderNodes.get(targetIndex), restrictions);
    8484
    85                                 sequenceArray[startIndex][targetIndex] = sequence;
     85                sequenceArray[startIndex][targetIndex] = sequence;
    8686
    87                         }
    88                 }
     87            }
     88        }
    8989
    90                 segmentSequences = sequenceArray;
    91         }
     90        segmentSequences = sequenceArray;
     91    }
    9292
    93         @Override
    94         protected boolean isUsableNode(SegmentNode node) {
    95                 return shareElement(segments, node.getInboundSegments())
    96                 || shareElement(segments, node.getOutboundSegments());
    97         }
     93    @Override
     94    protected boolean isUsableNode(SegmentNode node) {
     95        return shareElement(segments, node.getInboundSegments())
     96        || shareElement(segments, node.getOutboundSegments());
     97    }
    9898
    99         @Override
    100         protected boolean isUsableSegment(Segment segment) {
    101                 return segments.contains(segment);
    102         }
     99    @Override
     100    protected boolean isUsableSegment(Segment segment) {
     101        return segments.contains(segment);
     102    }
    103103
    104         @Override
    105         public String toString() {
    106                 return "ConnectorEG " + segments;
    107         }
     104    @Override
     105    public String toString() {
     106        return "ConnectorEG " + segments;
     107    }
    108108
    109109}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/graph/EvaluationGroup.java

    r16520 r23189  
    1919abstract class EvaluationGroup {
    2020
    21         protected boolean evaluated = false;
    22 
    23         /**
    24         * array of sequences.
    25         * First index is inbound segment/start node index,
    26         * second index is outbound segment/target node index.
    27         * Will contain the segment sequence after evaluation or null if none exists.
    28         */
    29         protected List<Segment>[][] segmentSequences;
    30 
    31         private static final List<Segment> EMPTY_SEGMENT_LIST =
    32                 Collections.unmodifiableList(new ArrayList<Segment>(0));
    33 
    34         private static final List<Restriction> EMPTY_RESTRICTION_LIST =
    35                 Collections.unmodifiableList(new ArrayList<Restriction>(0));
    36 
    37         private static class State {
    38                 SegmentNode currentNode;
    39                 Set<SegmentNode> visitedNodes;
    40                 Collection<Restriction> activeRestrictions;
    41                 List<Segment> segmentHistory;
    42         }
    43 
    44 
    45         /**
    46         * tries to find a legal sequence of segments between two segment nodes.
    47         *
    48         * @return  list of segments if connection is possible, null otherwise.
    49         */
    50         protected List<Segment> findSegmentSequence(
    51                         SegmentNode firstNode, SegmentNode lastNode,
    52                         Collection<Restriction> restrictions) {
    53 
    54                 return findSegmentSequence(firstNode, lastNode, restrictions,
    55                                 EMPTY_RESTRICTION_LIST, EMPTY_RESTRICTION_LIST);
    56 
    57         }
    58 
    59         /**
    60         * tries to find a legal sequence of segments between two segments.
    61         *
    62         * @return  list of segments if connection is possible, null otherwise.
    63         *          The list does NOT include firstSegment and lastSegment,
    64         *          but they are considered for restrictions.
    65         */
    66         protected List<Segment> findSegmentSequence(
    67                         Segment firstSegment, Segment lastSegment,
    68                         Collection<Restriction> restrictions) {
    69 
    70                 if (firstSegment == lastSegment) {
    71 
    72                         return EMPTY_SEGMENT_LIST;
    73 
    74                 } else {
    75 
    76                         Collection<Restriction> initiallyActiveRestrictions =
    77                                 activeRestrictionsAfterSegment(firstSegment, EMPTY_RESTRICTION_LIST, restrictions);
    78 
    79                         Collection<Restriction> restrictionsForbiddenAtLastNode = new HashSet<Restriction>();
    80                         for (Restriction restriction : restrictions) {
    81                                 if (restriction.getTos().contains(lastSegment)) {
    82                                         restrictionsForbiddenAtLastNode.add(restriction);
    83                                 }
    84                         }
    85 
    86                         return findSegmentSequence(
    87                                         firstSegment.getNode2(), lastSegment.getNode1(), restrictions,
    88                                         initiallyActiveRestrictions, restrictionsForbiddenAtLastNode);
    89                 }
    90 
    91         }
    92 
    93         /**
    94         * tries to find a legal sequence of segments between two segment nodes.
    95         *
    96         * @param restrictions  all restrictions that have to be taken into account
    97         * @param initiallyActiveRestrictions  restrictions that are already active at firstNode
    98         * @param restrictionsForbiddenAtLastNode  restrictions that must NOT be active at lastNode
    99         * @return  list of segments if connection is possible, null otherwise.
    100         */
    101         private List<Segment> findSegmentSequence(
    102                         SegmentNode firstNode, SegmentNode lastNode,
    103                         Collection<Restriction> restrictions,
    104                         Collection<Restriction> initiallyActiveRestrictions,
    105                         Collection<Restriction> restrictionsForbiddenAtLastNode) {
    106 
    107                 if (firstNode == lastNode
    108                                 && !shareElement(initiallyActiveRestrictions, restrictionsForbiddenAtLastNode)) {
    109                         return EMPTY_SEGMENT_LIST;
    110                 }
    111 
    112                 Queue<State> stateQueue = new LinkedList<State>();
    113                 stateQueue.add(createStartingState(firstNode, initiallyActiveRestrictions));
    114 
    115                 /* search for a possible segment sequence */
    116 
    117                 while (stateQueue.size() > 0) {
    118 
    119                         State state = stateQueue.poll();
    120 
    121                         Collection<State> subsequentStates = createSubsequentStates(state, restrictions);
    122 
    123                         for (State subsequentState : subsequentStates) {
    124                                 if (subsequentState.currentNode == lastNode
    125                                                 && !shareElement(subsequentState.activeRestrictions,
    126                                                                 restrictionsForbiddenAtLastNode)) {
    127                                         return subsequentState.segmentHistory;
    128                                 }
    129                         }
    130 
    131                         stateQueue.addAll(subsequentStates);
    132 
    133                 }
    134 
    135                 return null;
    136         }
    137 
    138         private static State createStartingState(SegmentNode firstNode,
    139                         Collection<Restriction> initiallyActiveRestrictions) {
    140 
    141                 State startingState = new State();
    142                 startingState.currentNode = firstNode;
    143                 startingState.activeRestrictions = initiallyActiveRestrictions;
    144                 startingState.segmentHistory = EMPTY_SEGMENT_LIST;
    145                 startingState.visitedNodes = new HashSet<SegmentNode>();
    146                 startingState.visitedNodes.add(firstNode);
    147 
    148                 return startingState;
    149         }
    150 
    151         private List<State> createSubsequentStates(State state, Collection<Restriction> allRestrictions) {
    152 
    153                 List<State> subsequentStates = new ArrayList<State>();
    154 
    155                 for (Segment segment : state.currentNode.getOutboundSegments()) {
    156 
    157                         if (isUsableSegment(segment) &&
    158                                         isLegalSegment(segment, state.activeRestrictions)) {
    159 
    160                                 State newState = new State();
    161 
    162                                 newState.activeRestrictions = activeRestrictionsAfterSegment(
    163                                                 segment, state.activeRestrictions, allRestrictions);
    164 
    165                                 newState.segmentHistory = new ArrayList<Segment>(state.segmentHistory.size() + 1);
    166                                 newState.segmentHistory.addAll(state.segmentHistory);
    167                                 newState.segmentHistory.add(segment);
    168 
    169                                 newState.currentNode = segment.getNode2();
    170 
    171                                 newState.visitedNodes = new HashSet<SegmentNode>(state.visitedNodes);
    172                                 newState.visitedNodes.add(newState.currentNode);
    173 
    174                                 /* add state to queue,
    175                                 * but avoid cycles as well as leaving the node set
    176                                 */
    177 
    178                                 if (!state.visitedNodes.contains(newState.currentNode)
    179                                                 && isUsableNode(newState.currentNode)) {
    180 
    181                                         subsequentStates.add(newState);
    182 
    183                                 }
    184                         }
    185                 }
    186 
    187                 return subsequentStates;
    188         }
    189 
    190         /**
    191         * returns all restrictions from a collection that have a segment as from member
    192         * @return  segment list; != null; must not be modified.
    193         *          May throw an exception when modifying is attempted.
    194         */
    195         private static List<Restriction> getRestrictionsStartedBySegment(
    196                         Collection<Restriction> restrictions, Segment segment) {
    197 
    198                 List<Restriction> result = EMPTY_RESTRICTION_LIST;
    199                 for (Restriction restriction : restrictions) {
    200                         if (restriction.getFrom() == segment) {
    201                                 if (result == EMPTY_RESTRICTION_LIST) {
    202                                         result = new ArrayList<Restriction>(restrictions.size());
    203                                 }
    204                                 result.add(restriction);
    205                         }
    206                 }
    207 
    208                 return result;
    209         }
    210 
    211         private static Collection<Restriction> activeRestrictionsAfterSegment(Segment segment,
    212                         Collection<Restriction> activeRestrictionsBeforeSegment,
    213                         Collection<Restriction> allRestrictions) {
    214 
    215                 Collection<Restriction> result = EMPTY_RESTRICTION_LIST;
    216 
    217                 for (Restriction restriction : activeRestrictionsBeforeSegment) {
    218                         if (restriction.getVias().contains(segment)) {
    219                                 if (result == EMPTY_RESTRICTION_LIST) {
    220                                         result = new ArrayList<Restriction>(allRestrictions.size());
    221                                 }
    222                                 result.add(restriction);
    223                         }
    224                 }
    225 
    226                 Collection<Restriction> newRestrictions =
    227                         getRestrictionsStartedBySegment(allRestrictions, segment);
    228 
    229                 if (newRestrictions.size() > 0) {
    230                         if (result == EMPTY_RESTRICTION_LIST) {
    231                                 result = newRestrictions;
    232                         } else {
    233                                 result.addAll(newRestrictions);
    234                         }
    235                 }
    236 
    237                 return result;
    238         }
    239 
    240         private static boolean isLegalSegment(
    241                         Segment segment, Collection<Restriction> activeRestrictions) {
    242 
    243                 for (Restriction restriction : activeRestrictions) {
    244                         if (restriction.getTos().contains(segment)) {
    245                                 return false;
    246                         }
    247                 }
    248 
    249                 return true;
    250         }
    251 
    252         /** returns true iff at least one element is contained in both collections */
    253         protected static boolean shareElement(
    254                         Collection<?> collection1, Collection<?> collection2) {
    255                 for (Object element : collection1) {
    256                         if (collection2.contains(element)) {
    257                                 return true;
    258                         }
    259                 }
    260                 return false;
    261         }
    262 
    263         public final void evaluate(Collection<Restriction> restrictions) {
    264 
    265                 if (evaluated) { return; }
    266 
    267                 evaluateImpl(restrictions);
    268 
    269                 evaluated = true;
    270         }
    271 
    272         /**
    273         * finds in- and outbound segments (if necessary) and segment sequences.
    274         * After calling this method, the group must be correctly evaluated
    275         * (see {@link #isCorrectlyEvaluated()}).
    276         *
    277         * @param restrictions  restrictions that are used when determining possible connections,
    278         *                      will not be modified; != null
    279         */
    280         abstract protected void evaluateImpl(Collection<Restriction> restrictions);
    281 
    282         /**
    283         * returns whether a node can be used while finding a segment sequence
    284         * @param node  node to check; != null
    285         */
    286         abstract protected boolean isUsableNode(SegmentNode node);
    287 
    288         /**
    289         * returns whether a segment can be used while finding a segment sequence
    290         * @param segment  segment to check; != null
    291         */
    292         abstract protected boolean isUsableSegment(Segment segment);
     21    protected boolean evaluated = false;
     22
     23    /**
     24    * array of sequences.
     25    * First index is inbound segment/start node index,
     26    * second index is outbound segment/target node index.
     27    * Will contain the segment sequence after evaluation or null if none exists.
     28    */
     29    protected List<Segment>[][] segmentSequences;
     30
     31    private static final List<Segment> EMPTY_SEGMENT_LIST =
     32        Collections.unmodifiableList(new ArrayList<Segment>(0));
     33
     34    private static final List<Restriction> EMPTY_RESTRICTION_LIST =
     35        Collections.unmodifiableList(new ArrayList<Restriction>(0));
     36
     37    private static class State {
     38        SegmentNode currentNode;
     39        Set<SegmentNode> visitedNodes;
     40        Collection<Restriction> activeRestrictions;
     41        List<Segment> segmentHistory;
     42    }
     43
     44
     45    /**
     46    * tries to find a legal sequence of segments between two segment nodes.
     47    *
     48    * @return  list of segments if connection is possible, null otherwise.
     49    */
     50    protected List<Segment> findSegmentSequence(
     51            SegmentNode firstNode, SegmentNode lastNode,
     52            Collection<Restriction> restrictions) {
     53
     54        return findSegmentSequence(firstNode, lastNode, restrictions,
     55                EMPTY_RESTRICTION_LIST, EMPTY_RESTRICTION_LIST);
     56
     57    }
     58
     59    /**
     60    * tries to find a legal sequence of segments between two segments.
     61    *
     62    * @return  list of segments if connection is possible, null otherwise.
     63    *          The list does NOT include firstSegment and lastSegment,
     64    *          but they are considered for restrictions.
     65    */
     66    protected List<Segment> findSegmentSequence(
     67            Segment firstSegment, Segment lastSegment,
     68            Collection<Restriction> restrictions) {
     69
     70        if (firstSegment == lastSegment) {
     71
     72            return EMPTY_SEGMENT_LIST;
     73
     74        } else {
     75
     76            Collection<Restriction> initiallyActiveRestrictions =
     77                activeRestrictionsAfterSegment(firstSegment, EMPTY_RESTRICTION_LIST, restrictions);
     78
     79            Collection<Restriction> restrictionsForbiddenAtLastNode = new HashSet<Restriction>();
     80            for (Restriction restriction : restrictions) {
     81                if (restriction.getTos().contains(lastSegment)) {
     82                    restrictionsForbiddenAtLastNode.add(restriction);
     83                }
     84            }
     85
     86            return findSegmentSequence(
     87                    firstSegment.getNode2(), lastSegment.getNode1(), restrictions,
     88                    initiallyActiveRestrictions, restrictionsForbiddenAtLastNode);
     89        }
     90
     91    }
     92
     93    /**
     94    * tries to find a legal sequence of segments between two segment nodes.
     95    *
     96    * @param restrictions  all restrictions that have to be taken into account
     97    * @param initiallyActiveRestrictions  restrictions that are already active at firstNode
     98    * @param restrictionsForbiddenAtLastNode  restrictions that must NOT be active at lastNode
     99    * @return  list of segments if connection is possible, null otherwise.
     100    */
     101    private List<Segment> findSegmentSequence(
     102            SegmentNode firstNode, SegmentNode lastNode,
     103            Collection<Restriction> restrictions,
     104            Collection<Restriction> initiallyActiveRestrictions,
     105            Collection<Restriction> restrictionsForbiddenAtLastNode) {
     106
     107        if (firstNode == lastNode
     108                && !shareElement(initiallyActiveRestrictions, restrictionsForbiddenAtLastNode)) {
     109            return EMPTY_SEGMENT_LIST;
     110        }
     111
     112        Queue<State> stateQueue = new LinkedList<State>();
     113        stateQueue.add(createStartingState(firstNode, initiallyActiveRestrictions));
     114
     115        /* search for a possible segment sequence */
     116
     117        while (stateQueue.size() > 0) {
     118
     119            State state = stateQueue.poll();
     120
     121            Collection<State> subsequentStates = createSubsequentStates(state, restrictions);
     122
     123            for (State subsequentState : subsequentStates) {
     124                if (subsequentState.currentNode == lastNode
     125                        && !shareElement(subsequentState.activeRestrictions,
     126                                restrictionsForbiddenAtLastNode)) {
     127                    return subsequentState.segmentHistory;
     128                }
     129            }
     130
     131            stateQueue.addAll(subsequentStates);
     132
     133        }
     134
     135        return null;
     136    }
     137
     138    private static State createStartingState(SegmentNode firstNode,
     139            Collection<Restriction> initiallyActiveRestrictions) {
     140
     141        State startingState = new State();
     142        startingState.currentNode = firstNode;
     143        startingState.activeRestrictions = initiallyActiveRestrictions;
     144        startingState.segmentHistory = EMPTY_SEGMENT_LIST;
     145        startingState.visitedNodes = new HashSet<SegmentNode>();
     146        startingState.visitedNodes.add(firstNode);
     147
     148        return startingState;
     149    }
     150
     151    private List<State> createSubsequentStates(State state, Collection<Restriction> allRestrictions) {
     152
     153        List<State> subsequentStates = new ArrayList<State>();
     154
     155        for (Segment segment : state.currentNode.getOutboundSegments()) {
     156
     157            if (isUsableSegment(segment) &&
     158                    isLegalSegment(segment, state.activeRestrictions)) {
     159
     160                State newState = new State();
     161
     162                newState.activeRestrictions = activeRestrictionsAfterSegment(
     163                        segment, state.activeRestrictions, allRestrictions);
     164
     165                newState.segmentHistory = new ArrayList<Segment>(state.segmentHistory.size() + 1);
     166                newState.segmentHistory.addAll(state.segmentHistory);
     167                newState.segmentHistory.add(segment);
     168
     169                newState.currentNode = segment.getNode2();
     170
     171                newState.visitedNodes = new HashSet<SegmentNode>(state.visitedNodes);
     172                newState.visitedNodes.add(newState.currentNode);
     173
     174                /* add state to queue,
     175                * but avoid cycles as well as leaving the node set
     176                */
     177
     178                if (!state.visitedNodes.contains(newState.currentNode)
     179                        && isUsableNode(newState.currentNode)) {
     180
     181                    subsequentStates.add(newState);
     182
     183                }
     184            }
     185        }
     186
     187        return subsequentStates;
     188    }
     189
     190    /**
     191    * returns all restrictions from a collection that have a segment as from member
     192    * @return  segment list; != null; must not be modified.
     193    *          May throw an exception when modifying is attempted.
     194    */
     195    private static List<Restriction> getRestrictionsStartedBySegment(
     196            Collection<Restriction> restrictions, Segment segment) {
     197
     198        List<Restriction> result = EMPTY_RESTRICTION_LIST;
     199        for (Restriction restriction : restrictions) {
     200            if (restriction.getFrom() == segment) {
     201                if (result == EMPTY_RESTRICTION_LIST) {
     202                    result = new ArrayList<Restriction>(restrictions.size());
     203                }
     204                result.add(restriction);
     205            }
     206        }
     207
     208        return result;
     209    }
     210
     211    private static Collection<Restriction> activeRestrictionsAfterSegment(Segment segment,
     212            Collection<Restriction> activeRestrictionsBeforeSegment,
     213            Collection<Restriction> allRestrictions) {
     214
     215        Collection<Restriction> result = EMPTY_RESTRICTION_LIST;
     216
     217        for (Restriction restriction : activeRestrictionsBeforeSegment) {
     218            if (restriction.getVias().contains(segment)) {
     219                if (result == EMPTY_RESTRICTION_LIST) {
     220                    result = new ArrayList<Restriction>(allRestrictions.size());
     221                }
     222                result.add(restriction);
     223            }
     224        }
     225
     226        Collection<Restriction> newRestrictions =
     227            getRestrictionsStartedBySegment(allRestrictions, segment);
     228
     229        if (newRestrictions.size() > 0) {
     230            if (result == EMPTY_RESTRICTION_LIST) {
     231                result = newRestrictions;
     232            } else {
     233                result.addAll(newRestrictions);
     234            }
     235        }
     236
     237        return result;
     238    }
     239
     240    private static boolean isLegalSegment(
     241            Segment segment, Collection<Restriction> activeRestrictions) {
     242
     243        for (Restriction restriction : activeRestrictions) {
     244            if (restriction.getTos().contains(segment)) {
     245                return false;
     246            }
     247        }
     248
     249        return true;
     250    }
     251
     252    /** returns true iff at least one element is contained in both collections */
     253    protected static boolean shareElement(
     254            Collection<?> collection1, Collection<?> collection2) {
     255        for (Object element : collection1) {
     256            if (collection2.contains(element)) {
     257                return true;
     258            }
     259        }
     260        return false;
     261    }
     262
     263    public final void evaluate(Collection<Restriction> restrictions) {
     264
     265        if (evaluated) { return; }
     266
     267        evaluateImpl(restrictions);
     268
     269        evaluated = true;
     270    }
     271
     272    /**
     273    * finds in- and outbound segments (if necessary) and segment sequences.
     274    * After calling this method, the group must be correctly evaluated
     275    * (see {@link #isCorrectlyEvaluated()}).
     276    *
     277    * @param restrictions  restrictions that are used when determining possible connections,
     278    *                      will not be modified; != null
     279    */
     280    abstract protected void evaluateImpl(Collection<Restriction> restrictions);
     281
     282    /**
     283    * returns whether a node can be used while finding a segment sequence
     284    * @param node  node to check; != null
     285    */
     286    abstract protected boolean isUsableNode(SegmentNode node);
     287
     288    /**
     289    * returns whether a segment can be used while finding a segment sequence
     290    * @param segment  segment to check; != null
     291    */
     292    abstract protected boolean isUsableSegment(Segment segment);
    293293
    294294}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/graph/GraphEdge.java

    r18130 r23189  
    1212public interface GraphEdge {
    1313
    14         /** returns the node this edge starts at; != null */
    15         GraphNode getStartNode();
     14    /** returns the node this edge starts at; != null */
     15    GraphNode getStartNode();
    1616
    17         /** returns the node this edge leads to; != null */
    18         GraphNode getTargetNode();
     17    /** returns the node this edge leads to; != null */
     18    GraphNode getTargetNode();
    1919
    20         /** returns all property types for which property values are available */
    21         Collection<GraphEdgePropertyType<?>> getAvailableProperties();
    22        
    23         /** TODO */
    24         <V> V getPropertyValue(GraphEdgePropertyType<V> property);
    25        
     20    /** returns all property types for which property values are available */
     21    Collection<GraphEdgePropertyType<?>> getAvailableProperties();
     22
     23    /** TODO */
     24    <V> V getPropertyValue(GraphEdgePropertyType<V> property);
     25
    2626}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/graph/GraphNode.java

    r16520 r23189  
    1313public interface GraphNode {
    1414
    15         /**
    16         * returns all edges that lead to this GraphNode; != null
    17         */
    18         public Collection<GraphEdge> getInboundEdges();
     15    /**
     16    * returns all edges that lead to this GraphNode; != null
     17    */
     18    public Collection<GraphEdge> getInboundEdges();
    1919
    20         /**
    21         * returns all edges that start at this GraphNode; != null
    22         */
    23         public Collection<GraphEdge> getOutboundEdges();
     20    /**
     21    * returns all edges that start at this GraphNode; != null
     22    */
     23    public Collection<GraphEdge> getOutboundEdges();
    2424
    25         /**
    26         * returns the SegmentNode this GraphNode is based on
    27         *
    28         * @return  SegmentNode, must be one of the nodes of the Segment returned
    29         *          by {@link #getSegment()}; != null
    30         */
    31         public SegmentNode getSegmentNode();
     25    /**
     26    * returns the SegmentNode this GraphNode is based on
     27    *
     28    * @return  SegmentNode, must be one of the nodes of the Segment returned
     29    *          by {@link #getSegment()}; != null
     30    */
     31    public SegmentNode getSegmentNode();
    3232
    33         /**
    34         * returns the Segment this GraphNode is based on
    35         *
    36         * @return  Segment; != null
    37         */
    38         public Segment getSegment();
     33    /**
     34    * returns the Segment this GraphNode is based on
     35    *
     36    * @return  Segment; != null
     37    */
     38    public Segment getSegment();
    3939
    4040}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/graph/JunctionEvaluationGroup.java

    r18130 r23189  
    1515public class JunctionEvaluationGroup extends EvaluationGroup {
    1616
    17         private final Set<SegmentNode> segmentNodes;
     17    private final Set<SegmentNode> segmentNodes;
    1818
    19         protected List<Segment> inboundSegments;
    20         protected List<Segment> outboundSegments;
     19    protected List<Segment> inboundSegments;
     20    protected List<Segment> outboundSegments;
    2121
    22         /**
    23         * @param segmentNodes  set of SegmentNodes, must not be modified
    24         *                      after being used as constructor parameter; != null
    25         */
    26         public JunctionEvaluationGroup(Set<SegmentNode> segmentNodes) {
    27                 assert segmentNodes != null;
    28                 this.segmentNodes = segmentNodes;
    29         }
     22    /**
     23    * @param segmentNodes  set of SegmentNodes, must not be modified
     24    *                      after being used as constructor parameter; != null
     25    */
     26    public JunctionEvaluationGroup(Set<SegmentNode> segmentNodes) {
     27        assert segmentNodes != null;
     28        this.segmentNodes = segmentNodes;
     29    }
    3030
    31         /**
    32         * returns all segments that can be used to enter this group.
    33         * {@link #evaluate(Iterable)} needs be called before this method.
    34         *
    35         * @return  segment collection; != null
    36         */
    37         public Collection<Segment> getInboundSegments() {
    38                 if (!evaluated) { throw new IllegalStateException("group not yet evaluated"); }
    39                 return inboundSegments;
    40         }
     31    /**
     32    * returns all segments that can be used to enter this group.
     33    * {@link #evaluate(Iterable)} needs be called before this method.
     34    *
     35    * @return  segment collection; != null
     36    */
     37    public Collection<Segment> getInboundSegments() {
     38        if (!evaluated) { throw new IllegalStateException("group not yet evaluated"); }
     39        return inboundSegments;
     40    }
    4141
    42         /**
    43         * returns all segments that can be used to leave this group.
    44         * {@link #evaluate(Iterable)} needs be called before this method.
    45         *
    46         * @return  segment collection; != null
    47         */
    48         public Collection<Segment> getOutboundSegments() {
    49                 if (!evaluated) { throw new IllegalStateException("group not yet evaluated"); }
    50                 return outboundSegments;
    51         }
     42    /**
     43    * returns all segments that can be used to leave this group.
     44    * {@link #evaluate(Iterable)} needs be called before this method.
     45    *
     46    * @return  segment collection; != null
     47    */
     48    public Collection<Segment> getOutboundSegments() {
     49        if (!evaluated) { throw new IllegalStateException("group not yet evaluated"); }
     50        return outboundSegments;
     51    }
    5252
    53         /**
    54         * returns a segment sequence that runs from an inbound to an outbound
    55         * segment or null if no connection is possible.
    56         * {@link EvaluationGroup#evaluate(Collection)} needs be called before this method.
    57         *
    58         * @param  inboundSegment  start of the potential sequence;
    59         *                         must be inbound segment; != null
    60         * @param  outboundSegment target of the potential sequence;
    61         *                         must be outbound segment; != null
    62         * @return  sequence of segments or null
    63         */
    64         public List<Segment> getSegmentSequence(Segment inboundSegment, Segment outboundSegment) {
    65                 assert inboundSegment != null && inboundSegments.contains(inboundSegment);
    66                 assert outboundSegment != null && outboundSegments.contains(outboundSegment);
     53    /**
     54    * returns a segment sequence that runs from an inbound to an outbound
     55    * segment or null if no connection is possible.
     56    * {@link EvaluationGroup#evaluate(Collection)} needs be called before this method.
     57    *
     58    * @param  inboundSegment  start of the potential sequence;
     59    *                         must be inbound segment; != null
     60    * @param  outboundSegment target of the potential sequence;
     61    *                         must be outbound segment; != null
     62    * @return  sequence of segments or null
     63    */
     64    public List<Segment> getSegmentSequence(Segment inboundSegment, Segment outboundSegment) {
     65        assert inboundSegment != null && inboundSegments.contains(inboundSegment);
     66        assert outboundSegment != null && outboundSegments.contains(outboundSegment);
    6767
    68                 if (!evaluated) { throw new IllegalStateException("group not yet evaluated"); }
     68        if (!evaluated) { throw new IllegalStateException("group not yet evaluated"); }
    6969
    70                 int inboundIndex = inboundSegments.indexOf(inboundSegment);
    71                 int outboundIndex = outboundSegments.indexOf(outboundSegment);
     70        int inboundIndex = inboundSegments.indexOf(inboundSegment);
     71        int outboundIndex = outboundSegments.indexOf(outboundSegment);
    7272
    73                 return segmentSequences[inboundIndex][outboundIndex];
    74         }
     73        return segmentSequences[inboundIndex][outboundIndex];
     74    }
    7575
    76         @Override
    77         protected void evaluateImpl(final Collection<Restriction> restrictions) {
     76    @Override
     77    protected void evaluateImpl(final Collection<Restriction> restrictions) {
    7878
    79                 assert restrictions != null;
     79        assert restrictions != null;
    8080
    81                 /* find inbound and outbound segments. An inbound segment is a segment whose target
    82                 * is in the set and whose start node isn't (analogous for outbound segments)       */
     81        /* find inbound and outbound segments. An inbound segment is a segment whose target
     82        * is in the set and whose start node isn't (analogous for outbound segments)       */
    8383
    84                 inboundSegments = new ArrayList<Segment>();
    85                 outboundSegments = new ArrayList<Segment>();
     84        inboundSegments = new ArrayList<Segment>();
     85        outboundSegments = new ArrayList<Segment>();
    8686
    87                 for (SegmentNode segmentNode : segmentNodes) {
    88                         for (Segment segment : segmentNode.getInboundSegments()) {
    89                                 if (!segmentNodes.contains(segment.getNode1())) {
    90                                         inboundSegments.add(segment);
    91                                 }
    92                         }
    93                         for (Segment segment : segmentNode.getOutboundSegments()) {
    94                                 if (!segmentNodes.contains(segment.getNode2())) {
    95                                         outboundSegments.add(segment);
    96                                 }
    97                         }
    98                 }
     87        for (SegmentNode segmentNode : segmentNodes) {
     88            for (Segment segment : segmentNode.getInboundSegments()) {
     89                if (!segmentNodes.contains(segment.getNode1())) {
     90                    inboundSegments.add(segment);
     91                }
     92            }
     93            for (Segment segment : segmentNode.getOutboundSegments()) {
     94                if (!segmentNodes.contains(segment.getNode2())) {
     95                    outboundSegments.add(segment);
     96                }
     97            }
     98        }
    9999
    100                 /* find segment sequences from inbound to outbound segments */
     100        /* find segment sequences from inbound to outbound segments */
    101101
    102                 @SuppressWarnings("unchecked") //cannot create generic array without cast
    103                 List<Segment>[][] sequenceArray = new List[inboundSegments.size()][outboundSegments.size()];
     102        @SuppressWarnings("unchecked") //cannot create generic array without cast
     103        List<Segment>[][] sequenceArray = new List[inboundSegments.size()][outboundSegments.size()];
    104104
    105                 for (int inboundIndex = 0; inboundIndex < inboundSegments.size(); inboundIndex ++) {
    106                         for (int outboundIndex = 0; outboundIndex < outboundSegments.size(); outboundIndex ++) {
     105        for (int inboundIndex = 0; inboundIndex < inboundSegments.size(); inboundIndex ++) {
     106            for (int outboundIndex = 0; outboundIndex < outboundSegments.size(); outboundIndex ++) {
    107107
    108                                 List<Segment> sequence =
    109                                         findSegmentSequence(inboundSegments.get(inboundIndex),
    110                                                         outboundSegments.get(outboundIndex), restrictions);
     108                List<Segment> sequence =
     109                    findSegmentSequence(inboundSegments.get(inboundIndex),
     110                            outboundSegments.get(outboundIndex), restrictions);
    111111
    112                                 sequenceArray[inboundIndex][outboundIndex] = sequence;
     112                sequenceArray[inboundIndex][outboundIndex] = sequence;
    113113
    114                         }
    115                 }
     114            }
     115        }
    116116
    117                 segmentSequences = sequenceArray;
     117        segmentSequences = sequenceArray;
    118118
    119         }
     119    }
    120120
    121         @Override
    122         protected boolean isUsableNode(SegmentNode node) {
    123                 return segmentNodes.contains(node);
    124         }
     121    @Override
     122    protected boolean isUsableNode(SegmentNode node) {
     123        return segmentNodes.contains(node);
     124    }
    125125
    126         @Override
    127         protected boolean isUsableSegment(Segment segment) {
    128                 return segmentNodes.contains(segment.getNode1())
    129                 && segmentNodes.contains(segment.getNode2());
    130         }
     126    @Override
     127    protected boolean isUsableSegment(Segment segment) {
     128        return segmentNodes.contains(segment.getNode1())
     129        && segmentNodes.contains(segment.getNode2());
     130    }
    131131
    132         @Override
    133         public String toString() {
    134                 return "JunctionEG " + segmentNodes;
    135         }
     132    @Override
     133    public String toString() {
     134        return "JunctionEG " + segmentNodes;
     135    }
    136136}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/graph/TSBasedWayGraph.java

    r18130 r23189  
    2323public class TSBasedWayGraph implements WayGraph, TransitionStructureObserver {
    2424
    25         private static final GraphEdgePropertyType<?>[] PROPERTY_TYPES =
    26                 {GraphEdgeSegments.PROPERTY};
    27                 //TODO: -> parameter
    28        
    29         private static class GraphNodeImpl implements GraphNode {
    30                 private final SegmentNode node;
    31                 private final Segment segment;
    32                 private final List<GraphEdge> incomingEdges = new ArrayList<GraphEdge>();
    33                 private final List<GraphEdge> outgoingEdges = new ArrayList<GraphEdge>();
    34                 public GraphNodeImpl(SegmentNode node, Segment segment) {
    35                         assert node != null && segment != null;
    36                         assert segment.getNode1() == node || segment.getNode2() == node;
    37                         this.node = node;
    38                         this.segment = segment;
    39                 }
    40                 public SegmentNode getSegmentNode() {
    41                         return node;
    42                 }
    43                 public Segment getSegment() {
    44                         return segment;
    45                 }
    46                 public void addIncomingEdge(GraphEdge edge) {
    47                         assert edge != null;
    48                         incomingEdges.add(edge);
    49                 }
    50                 public Collection<GraphEdge> getInboundEdges() {
    51                         return incomingEdges;
    52                 }
    53                 public void addOutgoingEdge(GraphEdge edge) {
    54                         assert edge != null;
    55                         outgoingEdges.add(edge);
    56                 }
    57                 public Collection<GraphEdge> getOutboundEdges() {
    58                         return outgoingEdges;
    59                 }
    60                 @Override
    61                 public String toString() {
    62                         return "(" + node + "; " + segment + ")";
    63                 }
    64         }
    65 
    66         private static class GraphEdgeImpl implements GraphEdge {
    67                
    68                 private final GraphNode startNode;
    69                 private final GraphNode targetNode;
    70                 private final Map<GraphEdgePropertyType<?>, Object> properties;
    71                
    72                 public GraphEdgeImpl(GraphNode startNode, GraphNode targetNode,
    73                                 Map<GraphEdgePropertyType<?>, Object> properties) {
    74                         assert startNode != null && targetNode != null && properties != null;
    75                         this.startNode = startNode;
    76                         this.targetNode = targetNode;
    77                         this.properties = properties;
    78                 }
    79                
    80                 public GraphNode getStartNode() {
    81                         return startNode;
    82                 }
    83                 public GraphNode getTargetNode() {
    84                         return targetNode;
    85                 }
    86                
    87                 public Collection<GraphEdgePropertyType<?>> getAvailableProperties() {
    88                         return properties.keySet();
    89                 }
    90                 public <V> V getPropertyValue(GraphEdgePropertyType<V> property) {
    91                         V result = (V) properties.get(property);
    92                         return result;
    93                 }
    94                
    95                 @Override
    96                 public String toString() {
    97                         return "(" + startNode + "-->" + targetNode + ")";
    98                 }
    99                
    100         };
    101 
    102         private final Set<WayGraphObserver> observers = new HashSet<WayGraphObserver>();
    103 
    104         private final TransitionStructure transitionStructure;
    105 
    106         private Collection<GraphNode> nodes;
    107         private List<GraphEdge> edges;
    108 
    109         /**
    110         * create a WayGraph based on a {@link TransitionStructure}
    111         * @param transitionStructure  transition structure this graph is to be based on; != null
    112         */
    113         public TSBasedWayGraph(TransitionStructure transitionStructure) {
    114                 assert transitionStructure != null;
    115 
    116                 this.transitionStructure = transitionStructure;
    117                 transitionStructure.addObserver(this);
    118 
    119                 createNodesAndEdges();
    120         }
    121 
    122         public Collection<GraphEdge> getEdges() {
    123                 return edges;
    124         }
    125 
    126         public Collection<GraphNode> getNodes() {
    127                 return nodes;
    128         }
    129 
    130         private void createNodesAndEdges() {
    131 
    132                 Collection<EvaluationGroup> evaluationGroups =
    133                         createEvaluationGroups(transitionStructure);
    134 
    135                 for (EvaluationGroup evaluationGroup : evaluationGroups) {
    136                         evaluationGroup.evaluate(transitionStructure.getRestrictions());
    137                 }
    138 
    139                 createNodesAndEdgesFromEvaluationGroups(evaluationGroups);
    140 
    141                 evaluationGroups = null;
    142         }
    143 
    144         private static Collection<EvaluationGroup> createEvaluationGroups(
    145                         TransitionStructure transitionStructure) {
    146 
    147                 Map<SegmentNode, Set<SegmentNode>> nodeSetMap =
    148                         new HashMap<SegmentNode, Set<SegmentNode>>();
    149 
    150                 /* first step: everything that is part of the same restriction goes into the same set */
    151 
    152                 for (Restriction restriction : transitionStructure.getRestrictions()) {
    153 
    154                         /* group every node in via segments (which includes the
    155                         * last node of from and the first node of to) into a set */
    156 
    157                         SegmentNode firstNode = restriction.getFrom().getNode2();
    158                         createSetIfHasNone(firstNode, nodeSetMap);
    159 
    160                         for (Segment segment : restriction.getVias()) {
    161                                 putInSameSet(segment.getNode1(), firstNode, nodeSetMap);
    162                                 putInSameSet(segment.getNode2(), firstNode, nodeSetMap);
    163                         }
    164 
    165                         for (Segment segment : restriction.getTos()) {
    166                                 putInSameSet(segment.getNode1(), firstNode, nodeSetMap);
    167                         }
    168 
    169                 }
    170 
    171                 /* second step: create own sets for each junction and end point
    172                 * (node connected with more than / less than two nodes). */
    173 
    174                 for (SegmentNode node : transitionStructure.getNodes()) {
    175 
    176                         if (!nodeSetMap.containsKey(node)
    177                                         && !isConnectedWithExactly2Nodes(node)) {
    178 
    179                                 createSetIfHasNone(node, nodeSetMap);
    180 
    181                         }
    182 
    183                 }
    184 
    185                 /* third step: create segment sets for all segments that are not in one of the node sets
    186                 * (that is, at least one node is not part of a junction evaluation group
    187                 *  or the nodes are part of different junction evaluation groups)  */
    188 
    189                 Map<Segment, Set<Segment>> segmentSetMap =
    190                         new HashMap<Segment, Set<Segment>>();
    191 
    192                 for (Segment segment : transitionStructure.getSegments()) {
    193 
    194                         SegmentNode node1 = segment.getNode1();
    195                         SegmentNode node2 = segment.getNode2();
    196 
    197                         if (!nodeSetMap.containsKey(node1) || !nodeSetMap.containsKey(node2)
    198                                         || nodeSetMap.get(node1) != nodeSetMap.get(node2)) {
    199 
    200                                 createSetIfHasNone(segment, segmentSetMap);
    201 
    202                                 for (Segment subsequentSegment : segment.getNode2().getOutboundSegments()) {
    203                                         if (!nodeSetMap.containsKey(node2)
    204                                                         || subsequentSegment.getNode2() == node1) {
    205                                                 putInSameSet(subsequentSegment, segment, segmentSetMap);
    206                                         }
    207                                 }
    208                                 //note that segments leading to this segment will share sets anyway,
    209                                 //because this segment is a subsequent segment of them
    210 
    211 
    212                         }
    213 
    214                 }
    215 
    216                 /* create EvaluationGroup objects */
    217 
    218                 Collection<EvaluationGroup> evaluationGroups =
    219                         new ArrayList<EvaluationGroup>(nodeSetMap.size() + segmentSetMap.size());
    220 
    221                 Set<Set<SegmentNode>> nodeSets = new HashSet<Set<SegmentNode>>(nodeSetMap.values());
    222                 for (Set<SegmentNode> nodeSet : nodeSets) {
    223                         evaluationGroups.add(new JunctionEvaluationGroup(nodeSet));
    224                 }
    225 
    226                 HashSet<Set<Segment>> hashSets = new HashSet<Set<Segment>>(segmentSetMap.values());
    227                 for (Set<Segment> segmentSet : hashSets) {
    228                         Set<SegmentNode> borderNodes = new HashSet<SegmentNode>();
    229                         for (Segment segment : segmentSet) {
    230                                 if (nodeSetMap.containsKey(segment.getNode1())) {
    231                                         borderNodes.add(segment.getNode1());
    232                                 }
    233                                 if (nodeSetMap.containsKey(segment.getNode2())) {
    234                                         borderNodes.add(segment.getNode2());
    235                                 }
    236                         }
    237                         evaluationGroups.add(new ConnectorEvaluationGroup(segmentSet, borderNodes));
    238                 }
    239 
    240                 return evaluationGroups;
    241         }
    242 
    243         private void createNodesAndEdgesFromEvaluationGroups(
    244                         Collection<EvaluationGroup> evaluationGroups) {
    245 
    246                 nodes = new LinkedList<GraphNode>();
    247                 edges = new LinkedList<GraphEdge>();
    248 
    249                 //map from Segments to GraphNodes;
    250                 //for those GraphNodes representing an "approaching node on segment" state
    251                 final Map<Segment, GraphNodeImpl> segment2GNMap_approaching =
    252                         new HashMap<Segment, GraphNodeImpl>();
    253 
    254                 //map from Segments to GraphNodes;
    255                 //for those GraphNodes representing a "leaving node on segment" state
    256                 final Map<Segment, GraphNodeImpl> segment2GNMap_leaving =
    257                         new HashMap<Segment, GraphNodeImpl>();
    258 
    259                 //map from SegmentNodes to GraphNode collections;
    260                 //for those GraphNodes representing an "approaching node on segment" state
    261                 final Map<SegmentNode, Collection<GraphNodeImpl>> segNode2GNMap_approaching =
    262                         new HashMap<SegmentNode, Collection<GraphNodeImpl>>();
    263 
    264                 //map from SegmentNodes to GraphNodes collections;
    265                 //for those GraphNodes representing a "leaving node on segment" state
    266                 final Map<SegmentNode, Collection<GraphNodeImpl>> segNode2GNMap_leaving =
    267                         new HashMap<SegmentNode, Collection<GraphNodeImpl>>();
    268 
    269 
    270 
    271                 /* create graph nodes and edges for junction evaluation groups */
    272 
    273                 for (EvaluationGroup evaluationGroup : evaluationGroups) {
    274                         if (evaluationGroup instanceof JunctionEvaluationGroup) {
    275 
    276                                 JunctionEvaluationGroup junctionEG = (JunctionEvaluationGroup) evaluationGroup;
    277 
    278                                 //create graph nodes
    279                                 for (Segment segment : junctionEG.getInboundSegments()) {
    280                                         GraphNodeImpl graphNode = new GraphNodeImpl(segment.getNode2(), segment);
    281                                         nodes.add(graphNode);
    282                                         segment2GNMap_approaching.put(segment, graphNode);
    283                                         addToCollectionMap(segNode2GNMap_approaching, segment.getNode2(), graphNode);
    284                                 }
    285                                 for (Segment segment : junctionEG.getOutboundSegments()) {
    286                                         GraphNodeImpl graphNode = new GraphNodeImpl(segment.getNode1(), segment);
    287                                         nodes.add(graphNode);
    288                                         segment2GNMap_leaving.put(segment, graphNode);
    289                                         addToCollectionMap(segNode2GNMap_leaving, segment.getNode1(), graphNode);
    290                                 }
    291 
    292                                 //create graph edges for all segment sequences between in- and outbound edges
    293                                 for (Segment inboundSegment : junctionEG.getInboundSegments()) {
    294                                         for (Segment outboundSegment : junctionEG.getOutboundSegments()) {
    295 
    296                                                 List<Segment> segmentSequence =
    297                                                         junctionEG.getSegmentSequence(inboundSegment, outboundSegment);
    298 
    299                                                 if (segmentSequence != null) {
    300 
    301                                                         createGraphEdge(
    302                                                                         segment2GNMap_approaching.get(inboundSegment),
    303                                                                         segment2GNMap_leaving.get(outboundSegment),
    304                                                                         segmentSequence,
    305                                                                         junctionEG);
    306 
    307                                                 }
    308                                         }
    309                                 }
    310 
    311                         }
    312                 }
    313 
    314                 /* create graph edges for connector evaluation groups.
    315                 * Because GraphNodes are created for pairs of SegmentNodes (from connector groups)
    316                 * and Segments (from junction groups), the GraphNodes already exist.
    317                 */
    318 
    319                 for (EvaluationGroup evaluationGroup : evaluationGroups) {
    320                         if (evaluationGroup instanceof ConnectorEvaluationGroup) {
    321 
    322                                 ConnectorEvaluationGroup connectorEG = (ConnectorEvaluationGroup) evaluationGroup;
    323 
    324                                 for (SegmentNode startNode : connectorEG.getBorderNodes()) {
    325                                         for (SegmentNode targetNode : connectorEG.getBorderNodes()) {
    326 
    327                                                 if (segNode2GNMap_leaving.containsKey(startNode)
    328                                                                 && segNode2GNMap_approaching.containsKey(targetNode)) {
    329 
    330                                                         for (GraphNodeImpl startGraphNode : segNode2GNMap_leaving.get(startNode)) {
    331                                                                 for (GraphNodeImpl targetGraphNode : segNode2GNMap_approaching.get(targetNode)) {
    332 
    333                                                                         if (connectorEG.getSegments().contains(startGraphNode.getSegment())
    334                                                                                         && connectorEG.getSegments().contains(targetGraphNode.getSegment())) {
    335 
    336                                                                                 List<Segment> segmentSequence =
    337                                                                                         connectorEG.getSegmentSequence(startNode, targetNode);
    338 
    339                                                                                 if (segmentSequence != null) {
    340                                                                                         createGraphEdge(
    341                                                                                                         startGraphNode,
    342                                                                                                         targetGraphNode,
    343                                                                                                         segmentSequence,
    344                                                                                                         connectorEG);
    345                                                                                 }
    346 
    347                                                                         }
    348 
    349                                                                 }
    350                                                         }
    351 
    352                                                 }
    353 
    354                                         }
    355                                 }
    356 
    357                         }
    358                 }
    359 
    360         }
    361 
    362         private void createGraphEdge(
    363                         GraphNodeImpl startNode, GraphNodeImpl targetNode,
    364                         List<Segment> segments, ConnectorEvaluationGroup evaluationGroup) {
    365 
    366                 Map<GraphEdgePropertyType<?>, Object> properties =
    367                         new HashMap<GraphEdgePropertyType<?>, Object>(); //TODO: replace HashMap with List-based solution
    368                
    369                 for (GraphEdgePropertyType<?> propertyType : PROPERTY_TYPES) {
    370                         Object value = propertyType.evaluate(evaluationGroup, segments, transitionStructure);
    371                         properties.put(propertyType, value);
    372                 }
    373                
    374                 createGraphEdge(startNode, targetNode, properties);
    375 
    376         }
    377 
    378         private void createGraphEdge(
    379                         GraphNodeImpl startNode, GraphNodeImpl targetNode,
    380                         List<Segment> segments, JunctionEvaluationGroup evaluationGroup) {
    381 
    382                 Map<GraphEdgePropertyType<?>, Object> properties =
    383                         new HashMap<GraphEdgePropertyType<?>, Object>(); //TODO: replace HashMap with List-based solution
    384                
    385                 for (GraphEdgePropertyType<?> propertyType : PROPERTY_TYPES) {
    386                         Object value = propertyType.evaluate(evaluationGroup, segments, transitionStructure);
    387                         properties.put(propertyType, value);
    388                 }
    389                
    390                 createGraphEdge(startNode, targetNode, properties);
    391 
    392         }
    393 
    394         /**
    395         * creates a GraphEdge;
    396         * adds it to its nodes' collections and {@link #edges} collection.
    397         */
    398         private void createGraphEdge(GraphNodeImpl startNode, GraphNodeImpl targetNode,
    399                         Map<GraphEdgePropertyType<?>, Object> properties) {
    400 
    401                 GraphEdge newEdge = new GraphEdgeImpl(startNode, targetNode, properties);
    402 
    403                 startNode.addOutgoingEdge(newEdge);
    404                 targetNode.addIncomingEdge(newEdge);
    405 
    406                 edges.add(newEdge);
    407 
    408         }
    409        
    410         private static boolean isConnectedWithExactly2Nodes(SegmentNode node) {
    411 
    412                 Set<SegmentNode> connectedNodes = new HashSet<SegmentNode>(2);
    413 
    414                 for (Segment segment : node.getInboundSegments()) {
    415                         connectedNodes.add(segment.getNode1());
    416                 }
    417                 for (Segment segment : node.getOutboundSegments()) {
    418                         connectedNodes.add(segment.getNode2());
    419                 }
    420 
    421                 return connectedNodes.size() == 2;
    422         }
    423 
    424         /**
    425         * creates a set for an object if none exists in a map.
    426         * The set will contain the object and be added to the map with the object being its key.
    427         */
    428         private static <T> void createSetIfHasNone(T object, Map<T, Set<T>> objectSetMap) {
    429 
    430                 if (!objectSetMap.containsKey(object)) {
    431                         @SuppressWarnings("unchecked") //no set with generic parameter can be created directly
    432                         Set<T> set = new HashSet();
    433                         set.add(object);
    434                         objectSetMap.put(object, set);
    435                 }
    436 
    437         }
    438 
    439         /**
    440         * puts an object in another object's set.
    441         * If both nodes have sets already, these sets are merged.
    442         * The objectSetMap is modified accordingly.
    443         *
    444         * @param object        object that might or might not be in a set; != null
    445         * @param objectInSet   object that is guaranteed to be in a set; != null
    446         * @param objectSetMap  map from objects to the one set they are part of; != null
    447         */
    448         private static <T> void putInSameSet(T object, T objectInSet, Map<T, Set<T>> objectSetMap) {
    449                 assert object != null && objectInSet != null && objectSetMap != null;
    450                 assert objectSetMap.containsKey(objectInSet);
    451 
    452                 Set<T> set = objectSetMap.get(objectInSet);
    453 
    454                 if (objectSetMap.containsKey(object)) {
    455 
    456                         /* merge the two sets */
    457                         Set<T> oldSet = objectSetMap.get(object);
    458                         for (T objectFromOldSet : oldSet) {
    459                                 set.add(objectFromOldSet);
    460                                 objectSetMap.put(objectFromOldSet, set);
    461                         }
    462 
    463                 } else {
    464 
    465                         /* add object to objectInSet's set */
    466                         set.add(object);
    467                         objectSetMap.put(object, set);
    468 
    469                 }
    470 
    471         }
    472 
    473         private static <K, E> void addToCollectionMap(final Map<K, Collection<E>> map, K key, E entry) {
    474                 if (!map.containsKey(key)) {
    475                         Collection<E> newCollection = new ArrayList<E>();
    476                         map.put(key, newCollection);
    477                 }
    478                 map.get(key).add(entry);
    479         }
    480 
    481         public void update(TransitionStructure transitionStructure) {
    482                 createNodesAndEdges();
    483                 notifyObservers();
    484         }
    485 
    486         public void addObserver(WayGraphObserver observer) {
    487                 observers.add(observer);
    488         }
    489 
    490         public void deleteObserver(WayGraphObserver observer) {
    491                 observers.remove(observer);
    492         }
    493 
    494         private void notifyObservers() {
    495                 for (WayGraphObserver observer : observers) {
    496                         observer.update(this);
    497                 }
    498         }
     25    private static final GraphEdgePropertyType<?>[] PROPERTY_TYPES =
     26        {GraphEdgeSegments.PROPERTY};
     27        //TODO: -> parameter
     28
     29    private static class GraphNodeImpl implements GraphNode {
     30        private final SegmentNode node;
     31        private final Segment segment;
     32        private final List<GraphEdge> incomingEdges = new ArrayList<GraphEdge>();
     33        private final List<GraphEdge> outgoingEdges = new ArrayList<GraphEdge>();
     34        public GraphNodeImpl(SegmentNode node, Segment segment) {
     35            assert node != null && segment != null;
     36            assert segment.getNode1() == node || segment.getNode2() == node;
     37            this.node = node;
     38            this.segment = segment;
     39        }
     40        public SegmentNode getSegmentNode() {
     41            return node;
     42        }
     43        public Segment getSegment() {
     44            return segment;
     45        }
     46        public void addIncomingEdge(GraphEdge edge) {
     47            assert edge != null;
     48            incomingEdges.add(edge);
     49        }
     50        public Collection<GraphEdge> getInboundEdges() {
     51            return incomingEdges;
     52        }
     53        public void addOutgoingEdge(GraphEdge edge) {
     54            assert edge != null;
     55            outgoingEdges.add(edge);
     56        }
     57        public Collection<GraphEdge> getOutboundEdges() {
     58            return outgoingEdges;
     59        }
     60        @Override
     61        public String toString() {
     62            return "(" + node + "; " + segment + ")";
     63        }
     64    }
     65
     66    private static class GraphEdgeImpl implements GraphEdge {
     67
     68        private final GraphNode startNode;
     69        private final GraphNode targetNode;
     70        private final Map<GraphEdgePropertyType<?>, Object> properties;
     71
     72        public GraphEdgeImpl(GraphNode startNode, GraphNode targetNode,
     73                Map<GraphEdgePropertyType<?>, Object> properties) {
     74            assert startNode != null && targetNode != null && properties != null;
     75            this.startNode = startNode;
     76            this.targetNode = targetNode;
     77            this.properties = properties;
     78        }
     79
     80        public GraphNode getStartNode() {
     81            return startNode;
     82        }
     83        public GraphNode getTargetNode() {
     84            return targetNode;
     85        }
     86
     87        public Collection<GraphEdgePropertyType<?>> getAvailableProperties() {
     88            return properties.keySet();
     89        }
     90        public <V> V getPropertyValue(GraphEdgePropertyType<V> property) {
     91            V result = (V) properties.get(property);
     92            return result;
     93        }
     94
     95        @Override
     96        public String toString() {
     97            return "(" + startNode + "-->" + targetNode + ")";
     98        }
     99
     100    };
     101
     102    private final Set<WayGraphObserver> observers = new HashSet<WayGraphObserver>();
     103
     104    private final TransitionStructure transitionStructure;
     105
     106    private Collection<GraphNode> nodes;
     107    private List<GraphEdge> edges;
     108
     109    /**
     110    * create a WayGraph based on a {@link TransitionStructure}
     111    * @param transitionStructure  transition structure this graph is to be based on; != null
     112    */
     113    public TSBasedWayGraph(TransitionStructure transitionStructure) {
     114        assert transitionStructure != null;
     115
     116        this.transitionStructure = transitionStructure;
     117        transitionStructure.addObserver(this);
     118
     119        createNodesAndEdges();
     120    }
     121
     122    public Collection<GraphEdge> getEdges() {
     123        return edges;
     124    }
     125
     126    public Collection<GraphNode> getNodes() {
     127        return nodes;
     128    }
     129
     130    private void createNodesAndEdges() {
     131
     132        Collection<EvaluationGroup> evaluationGroups =
     133            createEvaluationGroups(transitionStructure);
     134
     135        for (EvaluationGroup evaluationGroup : evaluationGroups) {
     136            evaluationGroup.evaluate(transitionStructure.getRestrictions());
     137        }
     138
     139        createNodesAndEdgesFromEvaluationGroups(evaluationGroups);
     140
     141        evaluationGroups = null;
     142    }
     143
     144    private static Collection<EvaluationGroup> createEvaluationGroups(
     145            TransitionStructure transitionStructure) {
     146
     147        Map<SegmentNode, Set<SegmentNode>> nodeSetMap =
     148            new HashMap<SegmentNode, Set<SegmentNode>>();
     149
     150        /* first step: everything that is part of the same restriction goes into the same set */
     151
     152        for (Restriction restriction : transitionStructure.getRestrictions()) {
     153
     154            /* group every node in via segments (which includes the
     155            * last node of from and the first node of to) into a set */
     156
     157            SegmentNode firstNode = restriction.getFrom().getNode2();
     158            createSetIfHasNone(firstNode, nodeSetMap);
     159
     160            for (Segment segment : restriction.getVias()) {
     161                putInSameSet(segment.getNode1(), firstNode, nodeSetMap);
     162                putInSameSet(segment.getNode2(), firstNode, nodeSetMap);
     163            }
     164
     165            for (Segment segment : restriction.getTos()) {
     166                putInSameSet(segment.getNode1(), firstNode, nodeSetMap);
     167            }
     168
     169        }
     170
     171        /* second step: create own sets for each junction and end point
     172        * (node connected with more than / less than two nodes). */
     173
     174        for (SegmentNode node : transitionStructure.getNodes()) {
     175
     176            if (!nodeSetMap.containsKey(node)
     177                    && !isConnectedWithExactly2Nodes(node)) {
     178
     179                createSetIfHasNone(node, nodeSetMap);
     180
     181            }
     182
     183        }
     184
     185        /* third step: create segment sets for all segments that are not in one of the node sets
     186        * (that is, at least one node is not part of a junction evaluation group
     187        *  or the nodes are part of different junction evaluation groups)  */
     188
     189        Map<Segment, Set<Segment>> segmentSetMap =
     190            new HashMap<Segment, Set<Segment>>();
     191
     192        for (Segment segment : transitionStructure.getSegments()) {
     193
     194            SegmentNode node1 = segment.getNode1();
     195            SegmentNode node2 = segment.getNode2();
     196
     197            if (!nodeSetMap.containsKey(node1) || !nodeSetMap.containsKey(node2)
     198                    || nodeSetMap.get(node1) != nodeSetMap.get(node2)) {
     199
     200                createSetIfHasNone(segment, segmentSetMap);
     201
     202                for (Segment subsequentSegment : segment.getNode2().getOutboundSegments()) {
     203                    if (!nodeSetMap.containsKey(node2)
     204                            || subsequentSegment.getNode2() == node1) {
     205                        putInSameSet(subsequentSegment, segment, segmentSetMap);
     206                    }
     207                }
     208                //note that segments leading to this segment will share sets anyway,
     209                //because this segment is a subsequent segment of them
     210
     211
     212            }
     213
     214        }
     215
     216        /* create EvaluationGroup objects */
     217
     218        Collection<EvaluationGroup> evaluationGroups =
     219            new ArrayList<EvaluationGroup>(nodeSetMap.size() + segmentSetMap.size());
     220
     221        Set<Set<SegmentNode>> nodeSets = new HashSet<Set<SegmentNode>>(nodeSetMap.values());
     222        for (Set<SegmentNode> nodeSet : nodeSets) {
     223            evaluationGroups.add(new JunctionEvaluationGroup(nodeSet));
     224        }
     225
     226        HashSet<Set<Segment>> hashSets = new HashSet<Set<Segment>>(segmentSetMap.values());
     227        for (Set<Segment> segmentSet : hashSets) {
     228            Set<SegmentNode> borderNodes = new HashSet<SegmentNode>();
     229            for (Segment segment : segmentSet) {
     230                if (nodeSetMap.containsKey(segment.getNode1())) {
     231                    borderNodes.add(segment.getNode1());
     232                }
     233                if (nodeSetMap.containsKey(segment.getNode2())) {
     234                    borderNodes.add(segment.getNode2());
     235                }
     236            }
     237            evaluationGroups.add(new ConnectorEvaluationGroup(segmentSet, borderNodes));
     238        }
     239
     240        return evaluationGroups;
     241    }
     242
     243    private void createNodesAndEdgesFromEvaluationGroups(
     244            Collection<EvaluationGroup> evaluationGroups) {
     245
     246        nodes = new LinkedList<GraphNode>();
     247        edges = new LinkedList<GraphEdge>();
     248
     249        //map from Segments to GraphNodes;
     250        //for those GraphNodes representing an "approaching node on segment" state
     251        final Map<Segment, GraphNodeImpl> segment2GNMap_approaching =
     252            new HashMap<Segment, GraphNodeImpl>();
     253
     254        //map from Segments to GraphNodes;
     255        //for those GraphNodes representing a "leaving node on segment" state
     256        final Map<Segment, GraphNodeImpl> segment2GNMap_leaving =
     257            new HashMap<Segment, GraphNodeImpl>();
     258
     259        //map from SegmentNodes to GraphNode collections;
     260        //for those GraphNodes representing an "approaching node on segment" state
     261        final Map<SegmentNode, Collection<GraphNodeImpl>> segNode2GNMap_approaching =
     262            new HashMap<SegmentNode, Collection<GraphNodeImpl>>();
     263
     264        //map from SegmentNodes to GraphNodes collections;
     265        //for those GraphNodes representing a "leaving node on segment" state
     266        final Map<SegmentNode, Collection<GraphNodeImpl>> segNode2GNMap_leaving =
     267            new HashMap<SegmentNode, Collection<GraphNodeImpl>>();
     268
     269
     270
     271        /* create graph nodes and edges for junction evaluation groups */
     272
     273        for (EvaluationGroup evaluationGroup : evaluationGroups) {
     274            if (evaluationGroup instanceof JunctionEvaluationGroup) {
     275
     276                JunctionEvaluationGroup junctionEG = (JunctionEvaluationGroup) evaluationGroup;
     277
     278                //create graph nodes
     279                for (Segment segment : junctionEG.getInboundSegments()) {
     280                    GraphNodeImpl graphNode = new GraphNodeImpl(segment.getNode2(), segment);
     281                    nodes.add(graphNode);
     282                    segment2GNMap_approaching.put(segment, graphNode);
     283                    addToCollectionMap(segNode2GNMap_approaching, segment.getNode2(), graphNode);
     284                }
     285                for (Segment segment : junctionEG.getOutboundSegments()) {
     286                    GraphNodeImpl graphNode = new GraphNodeImpl(segment.getNode1(), segment);
     287                    nodes.add(graphNode);
     288                    segment2GNMap_leaving.put(segment, graphNode);
     289                    addToCollectionMap(segNode2GNMap_leaving, segment.getNode1(), graphNode);
     290                }
     291
     292                //create graph edges for all segment sequences between in- and outbound edges
     293                for (Segment inboundSegment : junctionEG.getInboundSegments()) {
     294                    for (Segment outboundSegment : junctionEG.getOutboundSegments()) {
     295
     296                        List<Segment> segmentSequence =
     297                            junctionEG.getSegmentSequence(inboundSegment, outboundSegment);
     298
     299                        if (segmentSequence != null) {
     300
     301                            createGraphEdge(
     302                                    segment2GNMap_approaching.get(inboundSegment),
     303                                    segment2GNMap_leaving.get(outboundSegment),
     304                                    segmentSequence,
     305                                    junctionEG);
     306
     307                        }
     308                    }
     309                }
     310
     311            }
     312        }
     313
     314        /* create graph edges for connector evaluation groups.
     315        * Because GraphNodes are created for pairs of SegmentNodes (from connector groups)
     316        * and Segments (from junction groups), the GraphNodes already exist.
     317        */
     318
     319        for (EvaluationGroup evaluationGroup : evaluationGroups) {
     320            if (evaluationGroup instanceof ConnectorEvaluationGroup) {
     321
     322                ConnectorEvaluationGroup connectorEG = (ConnectorEvaluationGroup) evaluationGroup;
     323
     324                for (SegmentNode startNode : connectorEG.getBorderNodes()) {
     325                    for (SegmentNode targetNode : connectorEG.getBorderNodes()) {
     326
     327                        if (segNode2GNMap_leaving.containsKey(startNode)
     328                                && segNode2GNMap_approaching.containsKey(targetNode)) {
     329
     330                            for (GraphNodeImpl startGraphNode : segNode2GNMap_leaving.get(startNode)) {
     331                                for (GraphNodeImpl targetGraphNode : segNode2GNMap_approaching.get(targetNode)) {
     332
     333                                    if (connectorEG.getSegments().contains(startGraphNode.getSegment())
     334                                            && connectorEG.getSegments().contains(targetGraphNode.getSegment())) {
     335
     336                                        List<Segment> segmentSequence =
     337                                            connectorEG.getSegmentSequence(startNode, targetNode);
     338
     339                                        if (segmentSequence != null) {
     340                                            createGraphEdge(
     341                                                    startGraphNode,
     342                                                    targetGraphNode,
     343                                                    segmentSequence,
     344                                                    connectorEG);
     345                                        }
     346
     347                                    }
     348
     349                                }
     350                            }
     351
     352                        }
     353
     354                    }
     355                }
     356
     357            }
     358        }
     359
     360    }
     361
     362    private void createGraphEdge(
     363            GraphNodeImpl startNode, GraphNodeImpl targetNode,
     364            List<Segment> segments, ConnectorEvaluationGroup evaluationGroup) {
     365
     366        Map<GraphEdgePropertyType<?>, Object> properties =
     367            new HashMap<GraphEdgePropertyType<?>, Object>(); //TODO: replace HashMap with List-based solution
     368
     369        for (GraphEdgePropertyType<?> propertyType : PROPERTY_TYPES) {
     370            Object value = propertyType.evaluate(evaluationGroup, segments, transitionStructure);
     371            properties.put(propertyType, value);
     372        }
     373
     374        createGraphEdge(startNode, targetNode, properties);
     375
     376    }
     377
     378    private void createGraphEdge(
     379            GraphNodeImpl startNode, GraphNodeImpl targetNode,
     380            List<Segment> segments, JunctionEvaluationGroup evaluationGroup) {
     381
     382        Map<GraphEdgePropertyType<?>, Object> properties =
     383            new HashMap<GraphEdgePropertyType<?>, Object>(); //TODO: replace HashMap with List-based solution
     384
     385        for (GraphEdgePropertyType<?> propertyType : PROPERTY_TYPES) {
     386            Object value = propertyType.evaluate(evaluationGroup, segments, transitionStructure);
     387            properties.put(propertyType, value);
     388        }
     389
     390        createGraphEdge(startNode, targetNode, properties);
     391
     392    }
     393
     394    /**
     395    * creates a GraphEdge;
     396    * adds it to its nodes' collections and {@link #edges} collection.
     397    */
     398    private void createGraphEdge(GraphNodeImpl startNode, GraphNodeImpl targetNode,
     399            Map<GraphEdgePropertyType<?>, Object> properties) {
     400
     401        GraphEdge newEdge = new GraphEdgeImpl(startNode, targetNode, properties);
     402
     403        startNode.addOutgoingEdge(newEdge);
     404        targetNode.addIncomingEdge(newEdge);
     405
     406        edges.add(newEdge);
     407
     408    }
     409
     410    private static boolean isConnectedWithExactly2Nodes(SegmentNode node) {
     411
     412        Set<SegmentNode> connectedNodes = new HashSet<SegmentNode>(2);
     413
     414        for (Segment segment : node.getInboundSegments()) {
     415            connectedNodes.add(segment.getNode1());
     416        }
     417        for (Segment segment : node.getOutboundSegments()) {
     418            connectedNodes.add(segment.getNode2());
     419        }
     420
     421        return connectedNodes.size() == 2;
     422    }
     423
     424    /**
     425    * creates a set for an object if none exists in a map.
     426    * The set will contain the object and be added to the map with the object being its key.
     427    */
     428    private static <T> void createSetIfHasNone(T object, Map<T, Set<T>> objectSetMap) {
     429
     430        if (!objectSetMap.containsKey(object)) {
     431            @SuppressWarnings("unchecked") //no set with generic parameter can be created directly
     432            Set<T> set = new HashSet();
     433            set.add(object);
     434            objectSetMap.put(object, set);
     435        }
     436
     437    }
     438
     439    /**
     440    * puts an object in another object's set.
     441    * If both nodes have sets already, these sets are merged.
     442    * The objectSetMap is modified accordingly.
     443    *
     444    * @param object        object that might or might not be in a set; != null
     445    * @param objectInSet   object that is guaranteed to be in a set; != null
     446    * @param objectSetMap  map from objects to the one set they are part of; != null
     447    */
     448    private static <T> void putInSameSet(T object, T objectInSet, Map<T, Set<T>> objectSetMap) {
     449        assert object != null && objectInSet != null && objectSetMap != null;
     450        assert objectSetMap.containsKey(objectInSet);
     451
     452        Set<T> set = objectSetMap.get(objectInSet);
     453
     454        if (objectSetMap.containsKey(object)) {
     455
     456            /* merge the two sets */
     457            Set<T> oldSet = objectSetMap.get(object);
     458            for (T objectFromOldSet : oldSet) {
     459                set.add(objectFromOldSet);
     460                objectSetMap.put(objectFromOldSet, set);
     461            }
     462
     463        } else {
     464
     465            /* add object to objectInSet's set */
     466            set.add(object);
     467            objectSetMap.put(object, set);
     468
     469        }
     470
     471    }
     472
     473    private static <K, E> void addToCollectionMap(final Map<K, Collection<E>> map, K key, E entry) {
     474        if (!map.containsKey(key)) {
     475            Collection<E> newCollection = new ArrayList<E>();
     476            map.put(key, newCollection);
     477        }
     478        map.get(key).add(entry);
     479    }
     480
     481    public void update(TransitionStructure transitionStructure) {
     482        createNodesAndEdges();
     483        notifyObservers();
     484    }
     485
     486    public void addObserver(WayGraphObserver observer) {
     487        observers.add(observer);
     488    }
     489
     490    public void deleteObserver(WayGraphObserver observer) {
     491        observers.remove(observer);
     492    }
     493
     494    private void notifyObservers() {
     495        for (WayGraphObserver observer : observers) {
     496            observer.update(this);
     497        }
     498    }
    499499
    500500}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/graph/WayGraph.java

    r16520 r23189  
    88public interface WayGraph {
    99
    10         Collection<GraphNode> getNodes();
    11         Collection<GraphEdge> getEdges();
     10    Collection<GraphNode> getNodes();
     11    Collection<GraphEdge> getEdges();
    1212
    13         /**
    14         * adds an observer.
    15         * Does nothing if the parameter is already an observer of this WayGraph.
    16         *
    17         * @param observer  observer object, != null
    18         */
    19         public void addObserver(WayGraphObserver observer);
     13    /**
     14    * adds an observer.
     15    * Does nothing if the parameter is already an observer of this WayGraph.
     16    *
     17    * @param observer  observer object, != null
     18    */
     19    public void addObserver(WayGraphObserver observer);
    2020
    21         /**
    22         * deletes an observer that has been added using {@link #addObserver(WayGraphObserver)}.
    23         * Does nothing if the parameter isn't currently an observer of this WayGraph.
    24         *
    25         * @param observer  observer object, != null
    26         */
    27         public void deleteObserver(WayGraphObserver observer);
     21    /**
     22    * deletes an observer that has been added using {@link #addObserver(WayGraphObserver)}.
     23    * Does nothing if the parameter isn't currently an observer of this WayGraph.
     24    *
     25    * @param observer  observer object, != null
     26    */
     27    public void deleteObserver(WayGraphObserver observer);
    2828
    2929}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/graph/WayGraphObserver.java

    r16520 r23189  
    77public interface WayGraphObserver {
    88
    9         /**
    10         * informs this observer about changes in an observed graph
    11         * @param wayGraph  observed graph that has changed; != null
    12         */
    13         public void update(WayGraph wayGraph);
     9    /**
     10    * informs this observer about changes in an observed graph
     11    * @param wayGraph  observed graph that has changed; != null
     12    */
     13    public void update(WayGraph wayGraph);
    1414
    1515}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/property/GraphEdgePropertyType.java

    r18130 r23189  
    1717 */
    1818public interface GraphEdgePropertyType<V> {
    19        
    20         /**
    21          * determines the property value for segments created from junction groups
    22          */
    23         public V evaluate(JunctionEvaluationGroup junctionGroup,
    24                         List<Segment> segmentSequence,
    25                         TransitionStructure transitionStructure);
    2619
    27         /**
    28          * determines the property value for segments created from connector groups
    29          */
    30         public V evaluate(ConnectorEvaluationGroup connectorGroup,
    31                         List<Segment> segmentSequence,
    32                         TransitionStructure transitionStructure);
    33        
     20    /**
     21     * determines the property value for segments created from junction groups
     22     */
     23    public V evaluate(JunctionEvaluationGroup junctionGroup,
     24            List<Segment> segmentSequence,
     25            TransitionStructure transitionStructure);
     26
     27    /**
     28     * determines the property value for segments created from connector groups
     29     */
     30    public V evaluate(ConnectorEvaluationGroup connectorGroup,
     31            List<Segment> segmentSequence,
     32            TransitionStructure transitionStructure);
     33
    3434}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/property/GraphEdgeSegments.java

    r18130 r23189  
    1212 * property for the graph that is being constructed will preserve information
    1313 * from the {@link TransitionStructure}.
    14  * 
     14 *
    1515 * TODO: for some purposes, segments are not needed (only coordinate lists;
    1616 * without properties etc.)
    1717 */
    1818public final class GraphEdgeSegments implements GraphEdgePropertyType<List<Segment>> {
    19        
    20         public static final GraphEdgeSegments PROPERTY = new GraphEdgeSegments();
    21        
    22         /**
    23         * private constructor to make sure that {@link #INSTANCE} is the only instance
    24         */
    25         private GraphEdgeSegments() { }
    26        
    27         public List<Segment> evaluate(JunctionEvaluationGroup junctionGroup,
    28                         List<Segment> segmentSequence, TransitionStructure transitionStructure) {
    29                 return segmentSequence;
    30         }
    31        
    32         public List<Segment> evaluate(ConnectorEvaluationGroup connectorGroup,
    33                         List<Segment> segmentSequence, TransitionStructure transitionStructure) {
    34                 return segmentSequence;
    35         }
    36        
     19
     20    public static final GraphEdgeSegments PROPERTY = new GraphEdgeSegments();
     21
     22    /**
     23    * private constructor to make sure that {@link #INSTANCE} is the only instance
     24    */
     25    private GraphEdgeSegments() { }
     26
     27    public List<Segment> evaluate(JunctionEvaluationGroup junctionGroup,
     28            List<Segment> segmentSequence, TransitionStructure transitionStructure) {
     29        return segmentSequence;
     30    }
     31
     32    public List<Segment> evaluate(ConnectorEvaluationGroup connectorGroup,
     33            List<Segment> segmentSequence, TransitionStructure transitionStructure) {
     34        return segmentSequence;
     35    }
     36
    3737}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/property/RoadIncline.java

    r19216 r23189  
    88public class RoadIncline implements RoadPropertyType<Float> {
    99
    10         public <N, W, R, M> Float evaluateN(N node, AccessParameters accessParameters,
    11                         DataSource<N,W,R,M> dataSource) {
    12                 return null;
    13         };
     10    public <N, W, R, M> Float evaluateN(N node, AccessParameters accessParameters,
     11            DataSource<N,W,R,M> dataSource) {
     12        return null;
     13    };
    1414
    15         public <N, W, R, M> Float evaluateW(W way, boolean forward, AccessParameters accessParameters,
    16                         DataSource<N,W,R,M> dataSource) {
    17                 assert way != null && accessParameters != null && dataSource != null;
     15    public <N, W, R, M> Float evaluateW(W way, boolean forward, AccessParameters accessParameters,
     16            DataSource<N,W,R,M> dataSource) {
     17        assert way != null && accessParameters != null && dataSource != null;
    1818
    19                 TagGroup tags = dataSource.getTagsW(way);
    20                 String inclineString = tags.getValue("incline");
     19        TagGroup tags = dataSource.getTagsW(way);
     20        String inclineString = tags.getValue("incline");
    2121
    22                 if (inclineString != null) {
    23                         Float incline = ValueStringParser.parseIncline(inclineString);
    24                         if (incline != null) {
    25                                 if (!forward) {
    26                                         incline = -incline;
    27                                 }
    28                                 return incline;
    29                         }
    30                 }
     22        if (inclineString != null) {
     23            Float incline = ValueStringParser.parseIncline(inclineString);
     24            if (incline != null) {
     25                if (!forward) {
     26                    incline = -incline;
     27                }
     28                return incline;
     29            }
     30        }
    3131
    32                 return null;
    33         };
     32        return null;
     33    };
    3434
    35         public boolean isUsable(Object propertyValue, AccessParameters accessParameters) {
    36                 assert propertyValue instanceof Float;
     35    public boolean isUsable(Object propertyValue, AccessParameters accessParameters) {
     36        assert propertyValue instanceof Float;
    3737
    38                 float incline = (Float)propertyValue;
     38        float incline = (Float)propertyValue;
    3939
    40                 Float maxInclineUp =
    41                         accessParameters.getVehiclePropertyValue(VehiclePropertyTypes.MAX_INCLINE_UP);
    42                 Float maxInclineDown =
    43                         accessParameters.getVehiclePropertyValue(VehiclePropertyTypes.MAX_INCLINE_DOWN);
     40        Float maxInclineUp =
     41            accessParameters.getVehiclePropertyValue(VehiclePropertyTypes.MAX_INCLINE_UP);
     42        Float maxInclineDown =
     43            accessParameters.getVehiclePropertyValue(VehiclePropertyTypes.MAX_INCLINE_DOWN);
    4444
    45                 if (maxInclineUp != null && incline > maxInclineUp) {
    46                         return false;
    47                 } else if (maxInclineDown != null && -incline > maxInclineDown) {
    48                         return false;
    49                 } else {
    50                         return true;
    51                 }
    52         }
     45        if (maxInclineUp != null && incline > maxInclineUp) {
     46            return false;
     47        } else if (maxInclineDown != null && -incline > maxInclineDown) {
     48            return false;
     49        } else {
     50            return true;
     51        }
     52    }
    5353
    5454}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/property/RoadMaxaxleload.java

    r20243 r23189  
    66
    77public class RoadMaxaxleload extends RoadValueLimit {
    8         public RoadMaxaxleload() {
    9                 super("maxaxleload", AXLELOAD, LimitType.MAXIMUM);
    10         }
    11         @Override
    12         protected Float parse(String valueString) {
    13                 return ValueStringParser.parseWeight(valueString);
    14         }
     8    public RoadMaxaxleload() {
     9        super("maxaxleload", AXLELOAD, LimitType.MAXIMUM);
     10    }
     11    @Override
     12    protected Float parse(String valueString) {
     13        return ValueStringParser.parseWeight(valueString);
     14    }
    1515}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/property/RoadMaxheight.java

    r20243 r23189  
    66
    77public class RoadMaxheight extends RoadValueLimit {
    8         public RoadMaxheight() {
    9                 super("maxheight", HEIGHT, LimitType.MAXIMUM);
    10         }
    11         @Override
    12         protected Float parse(String valueString) {
    13                 return ValueStringParser.parseMeasure(valueString);
    14         }
     8    public RoadMaxheight() {
     9        super("maxheight", HEIGHT, LimitType.MAXIMUM);
     10    }
     11    @Override
     12    protected Float parse(String valueString) {
     13        return ValueStringParser.parseMeasure(valueString);
     14    }
    1515}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/property/RoadMaxlength.java

    r20243 r23189  
    66
    77public class RoadMaxlength extends RoadValueLimit {
    8         public RoadMaxlength() {
    9                 super("maxlength", LENGTH, LimitType.MAXIMUM);
    10         }
    11         @Override
    12         protected Float parse(String valueString) {
    13                 return ValueStringParser.parseMeasure(valueString);
    14         }
     8    public RoadMaxlength() {
     9        super("maxlength", LENGTH, LimitType.MAXIMUM);
     10    }
     11    @Override
     12    protected Float parse(String valueString) {
     13        return ValueStringParser.parseMeasure(valueString);
     14    }
    1515}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/property/RoadMaxspeed.java

    r19216 r23189  
    88public class RoadMaxspeed implements RoadPropertyType<Float> {
    99
    10         private DataSource<?, ?, ?, ?> lastDataSource;
     10    private DataSource<?, ?, ?, ?> lastDataSource;
    1111
    12         /**
    13         * (re)creates information like boundaries if data source has changed
    14         * since last call to {@link #evaluate(Object, boolean, AccessParameters, DataSource)}
    15         */
    16         private <N, W, R, M> void initializeIfNecessary(DataSource<N, W, R, M> dataSource) {
     12    /**
     13    * (re)creates information like boundaries if data source has changed
     14    * since last call to {@link #evaluate(Object, boolean, AccessParameters, DataSource)}
     15    */
     16    private <N, W, R, M> void initializeIfNecessary(DataSource<N, W, R, M> dataSource) {
    1717
    18                 if (dataSource != lastDataSource) {
     18        if (dataSource != lastDataSource) {
    1919
    20                         /*
    21                         *
    22                         * currently no activities;
    23                         * place boundaries or similar features can be handled here
    24                         * once there is consensus on the topic of implicit maxspeeds, trafficzones etc.
    25                         *
    26                         */
     20            /*
     21            *
     22            * currently no activities;
     23            * place boundaries or similar features can be handled here
     24            * once there is consensus on the topic of implicit maxspeeds, trafficzones etc.
     25            *
     26            */
    2727
    28                         lastDataSource = dataSource;
    29                 }
    30         }
     28            lastDataSource = dataSource;
     29        }
     30    }
    3131
    32         public <N, W, R, M> Float evaluateN(N node, AccessParameters accessParameters,
    33                         DataSource<N, W, R, M> dataSource) {
    34                 assert node != null && accessParameters != null && dataSource != null;
     32    public <N, W, R, M> Float evaluateN(N node, AccessParameters accessParameters,
     33            DataSource<N, W, R, M> dataSource) {
     34        assert node != null && accessParameters != null && dataSource != null;
    3535
    36                 initializeIfNecessary(dataSource);
     36        initializeIfNecessary(dataSource);
    3737
    38                 return evaluateTags(dataSource.getTagsN(node));
    39         }
     38        return evaluateTags(dataSource.getTagsN(node));
     39    }
    4040
    41         public <N, W, R, M> Float evaluateW(W way, boolean forward, AccessParameters accessParameters,
    42                         DataSource<N, W, R, M> dataSource) {
    43                 assert way != null && accessParameters != null && dataSource != null;
     41    public <N, W, R, M> Float evaluateW(W way, boolean forward, AccessParameters accessParameters,
     42            DataSource<N, W, R, M> dataSource) {
     43        assert way != null && accessParameters != null && dataSource != null;
    4444
    45                 initializeIfNecessary(dataSource);
     45        initializeIfNecessary(dataSource);
    4646
    47                 return evaluateTags(dataSource.getTagsW(way));
    48         }
     47        return evaluateTags(dataSource.getTagsW(way));
     48    }
    4949
    50         private Float evaluateTags(TagGroup tags) {
    51                 String maxspeedString = tags.getValue("maxspeed");
     50    private Float evaluateTags(TagGroup tags) {
     51        String maxspeedString = tags.getValue("maxspeed");
    5252
    53                 if (maxspeedString != null) {
     53        if (maxspeedString != null) {
    5454
    55                         Float maxspeed = ValueStringParser.parseSpeed(maxspeedString);
    56                         if (maxspeed != null) {
    57                                 return maxspeed;
    58                         }
     55            Float maxspeed = ValueStringParser.parseSpeed(maxspeedString);
     56            if (maxspeed != null) {
     57                return maxspeed;
     58            }
    5959
    60                 }
     60        }
    6161
    62                 return null;
    63         }
     62        return null;
     63    }
    6464
    65         public boolean isUsable(Object propertyValue, AccessParameters accessParameters) {
    66                 assert propertyValue instanceof Float;
    67                 return true;
    68         }
     65    public boolean isUsable(Object propertyValue, AccessParameters accessParameters) {
     66        assert propertyValue instanceof Float;
     67        return true;
     68    }
    6969
    7070}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/property/RoadMaxweight.java

    r20243 r23189  
    66
    77public class RoadMaxweight extends RoadValueLimit {
    8         public RoadMaxweight() {
    9                 super("maxweight", WEIGHT, LimitType.MAXIMUM);
    10         }
    11         @Override
    12         protected Float parse(String valueString) {
    13                 return ValueStringParser.parseWeight(valueString);
    14         }
     8    public RoadMaxweight() {
     9        super("maxweight", WEIGHT, LimitType.MAXIMUM);
     10    }
     11    @Override
     12    protected Float parse(String valueString) {
     13        return ValueStringParser.parseWeight(valueString);
     14    }
    1515}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/property/RoadMaxwidth.java

    r20243 r23189  
    66
    77public class RoadMaxwidth extends RoadValueLimit {
    8         public RoadMaxwidth() {
    9                 super("maxwidth", WIDTH, LimitType.MAXIMUM);
    10         }
    11         @Override
    12         protected Float parse(String valueString) {
    13                 return ValueStringParser.parseMeasure(valueString);
    14         }
     8    public RoadMaxwidth() {
     9        super("maxwidth", WIDTH, LimitType.MAXIMUM);
     10    }
     11    @Override
     12    protected Float parse(String valueString) {
     13        return ValueStringParser.parseMeasure(valueString);
     14    }
    1515}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/property/RoadMinspeed.java

    r20243 r23189  
    66
    77public class RoadMinspeed extends RoadValueLimit {
    8         public RoadMinspeed() {
    9                 super("minspeed", SPEED, LimitType.MINIMUM);
    10         }
    11         @Override
    12         protected Float parse(String valueString) {
    13                 return ValueStringParser.parseSpeed(valueString);
    14         }
     8    public RoadMinspeed() {
     9        super("minspeed", SPEED, LimitType.MINIMUM);
     10    }
     11    @Override
     12    protected Float parse(String valueString) {
     13        return ValueStringParser.parseSpeed(valueString);
     14    }
    1515}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/property/RoadPropertyType.java

    r19216 r23189  
    1414public interface RoadPropertyType<V> {
    1515
    16         /**
    17         * determines the property value for way-based segments.
    18         * Uses the way the segment is created from.
    19         *
    20         * @param way               way that is to be evaluated; != null
    21         * @param forward           chooses whether the property is evaluated
    22         *                          in (true) or against (false) way direction
    23         * @param accessParameters  access parameters for properties that depend on vehicle/situation
    24         * @param dataSource        object providing access to all data; != null
    25         * @return                  value of this property for the way;
    26         *                          null if property cannot be determined / does not apply
    27         */
    28         public <N, W, R, M> V evaluateW(W way, boolean forward,
    29                         AccessParameters accessParameters, DataSource<N, W, R, M> dataSource);
     16    /**
     17    * determines the property value for way-based segments.
     18    * Uses the way the segment is created from.
     19    *
     20    * @param way               way that is to be evaluated; != null
     21    * @param forward           chooses whether the property is evaluated
     22    *                          in (true) or against (false) way direction
     23    * @param accessParameters  access parameters for properties that depend on vehicle/situation
     24    * @param dataSource        object providing access to all data; != null
     25    * @return                  value of this property for the way;
     26    *                          null if property cannot be determined / does not apply
     27    */
     28    public <N, W, R, M> V evaluateW(W way, boolean forward,
     29            AccessParameters accessParameters, DataSource<N, W, R, M> dataSource);
    3030
    31         /**
    32         * determines the property value for node-based segments.
    33         * Uses the node the segment is created from.
    34         *
    35         * @param way               node that is to be evaluated; != null
    36         * @param accessParameters  access parameters for properties that depend on vehicle/situation
    37         * @param dataSource        object providing access to all data; != null
    38         * @return                  value of this property for the way;
    39         *                          null if property cannot be determined / does not apply
    40         */
    41         public <N, W, R, M> V evaluateN(N node,
    42                         AccessParameters accessParameters, DataSource<N, W, R, M> dataSource);
     31    /**
     32    * determines the property value for node-based segments.
     33    * Uses the node the segment is created from.
     34    *
     35    * @param way               node that is to be evaluated; != null
     36    * @param accessParameters  access parameters for properties that depend on vehicle/situation
     37    * @param dataSource        object providing access to all data; != null
     38    * @return                  value of this property for the way;
     39    *                          null if property cannot be determined / does not apply
     40    */
     41    public <N, W, R, M> V evaluateN(N node,
     42            AccessParameters accessParameters, DataSource<N, W, R, M> dataSource);
    4343
    44         /**
    45         * checks whether a segment with a given value for this property can be used by a vehicle
    46         * with a certain set of access parameters
    47         *
    48         * @param object  value of this property for the segment;
    49         *                MUST be of type V; != null
    50         */
    51         public boolean isUsable(Object object, AccessParameters accessParameters);
     44    /**
     45    * checks whether a segment with a given value for this property can be used by a vehicle
     46    * with a certain set of access parameters
     47    *
     48    * @param object  value of this property for the segment;
     49    *                MUST be of type V; != null
     50    */
     51    public boolean isUsable(Object object, AccessParameters accessParameters);
    5252
    5353}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/property/RoadSurface.java

    r19216 r23189  
    99public class RoadSurface implements RoadPropertyType<String> {
    1010
    11         public <N, W, R, M> String evaluateN(N node, AccessParameters accessParameters,
    12                         DataSource<N,W,R,M> dataSource) {
    13                 return null;
    14         };
     11    public <N, W, R, M> String evaluateN(N node, AccessParameters accessParameters,
     12            DataSource<N,W,R,M> dataSource) {
     13        return null;
     14    };
    1515
    16         public <N, W, R, M> String evaluateW(W way, boolean forward, AccessParameters accessParameters,
    17                         DataSource<N,W,R,M> dataSource) {
    18                 assert way != null && accessParameters != null && dataSource != null;
     16    public <N, W, R, M> String evaluateW(W way, boolean forward, AccessParameters accessParameters,
     17            DataSource<N,W,R,M> dataSource) {
     18        assert way != null && accessParameters != null && dataSource != null;
    1919
    20                 TagGroup tags = dataSource.getTagsW(way);
    21                 return tags.getValue("surface");
     20        TagGroup tags = dataSource.getTagsW(way);
     21        return tags.getValue("surface");
    2222
    23         };
     23    };
    2424
    25         public boolean isUsable(Object propertyValue, AccessParameters accessParameters) {
    26                 assert propertyValue instanceof String;
     25    public boolean isUsable(Object propertyValue, AccessParameters accessParameters) {
     26        assert propertyValue instanceof String;
    2727
    28                 String surface = (String)propertyValue;
     28        String surface = (String)propertyValue;
    2929
    30                 Collection<String> surfaceBlacklist =
    31                         accessParameters.getVehiclePropertyValue(VehiclePropertyTypes.SURFACE_BLACKLIST);
     30        Collection<String> surfaceBlacklist =
     31            accessParameters.getVehiclePropertyValue(VehiclePropertyTypes.SURFACE_BLACKLIST);
    3232
    33                 if (surfaceBlacklist != null && surfaceBlacklist.contains(surface)) {
    34                         return false;
    35                 } else {
    36                         return true;
    37                 }
    38         }
     33        if (surfaceBlacklist != null && surfaceBlacklist.contains(surface)) {
     34            return false;
     35        } else {
     36            return true;
     37        }
     38    }
    3939
    4040}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/property/RoadTracktype.java

    r19216 r23189  
    77public class RoadTracktype implements RoadPropertyType<Integer> {
    88
    9         public <N, W, R, M> Integer evaluateN(N node, AccessParameters accessParameters,
    10                         DataSource<N,W,R,M> dataSource) {
    11                 return null;
    12         };
     9    public <N, W, R, M> Integer evaluateN(N node, AccessParameters accessParameters,
     10            DataSource<N,W,R,M> dataSource) {
     11        return null;
     12    };
    1313
    14         public <N, W, R, M> Integer evaluateW(W way, boolean forward, AccessParameters accessParameters,
    15                         DataSource<N,W,R,M> dataSource) {
    16                 assert way != null && accessParameters != null && dataSource != null;
     14    public <N, W, R, M> Integer evaluateW(W way, boolean forward, AccessParameters accessParameters,
     15            DataSource<N,W,R,M> dataSource) {
     16        assert way != null && accessParameters != null && dataSource != null;
    1717
    18                 TagGroup tags = dataSource.getTagsW(way);
    19                 String tracktypeString = tags.getValue("tracktype");
     18        TagGroup tags = dataSource.getTagsW(way);
     19        String tracktypeString = tags.getValue("tracktype");
    2020
    21                 if (tracktypeString != null) {
    22                         if        ("grade1".equals(tracktypeString)) {
    23                                 return 1;
    24                         } else if ("grade2".equals(tracktypeString)) {
    25                                 return 2;
    26                         } else if ("grade3".equals(tracktypeString)) {
    27                                 return 3;
    28                         } else if ("grade4".equals(tracktypeString)) {
    29                                 return 4;
    30                         } else if ("grade5".equals(tracktypeString)) {
    31                                 return 5;
    32                         }
    33                 }
     21        if (tracktypeString != null) {
     22            if        ("grade1".equals(tracktypeString)) {
     23                return 1;
     24            } else if ("grade2".equals(tracktypeString)) {
     25                return 2;
     26            } else if ("grade3".equals(tracktypeString)) {
     27                return 3;
     28            } else if ("grade4".equals(tracktypeString)) {
     29                return 4;
     30            } else if ("grade5".equals(tracktypeString)) {
     31                return 5;
     32            }
     33        }
    3434
    35                 return null;
    36         };
     35        return null;
     36    };
    3737
    38         public boolean isUsable(Object propertyValue, AccessParameters accessParameters) {
    39                 assert propertyValue instanceof Integer;
     38    public boolean isUsable(Object propertyValue, AccessParameters accessParameters) {
     39        assert propertyValue instanceof Integer;
    4040
    41                 int tracktype = (Integer)propertyValue;
     41        int tracktype = (Integer)propertyValue;
    4242
    43                 Integer maxTracktype =
    44                         accessParameters.getVehiclePropertyValue(VehiclePropertyTypes.MAX_TRACKTYPE);
     43        Integer maxTracktype =
     44            accessParameters.getVehiclePropertyValue(VehiclePropertyTypes.MAX_TRACKTYPE);
    4545
    46                 if (maxTracktype != null && tracktype > maxTracktype) {
    47                         return false;
    48                 } else {
    49                         return true;
    50                 }
    51         }
     46        if (maxTracktype != null && tracktype > maxTracktype) {
     47            return false;
     48        } else {
     49            return true;
     50        }
     51    }
    5252
    5353}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/property/RoadValueLimit.java

    r20243 r23189  
    1111abstract public class RoadValueLimit implements RoadPropertyType<Float> {
    1212
    13         protected static enum LimitType {MINIMUM, MAXIMUM};
     13    protected static enum LimitType {MINIMUM, MAXIMUM};
    1414
    15         private final String keyName;
    16         private final VehiclePropertyType<Float> vehicleProperty;
     15    private final String keyName;
     16    private final VehiclePropertyType<Float> vehicleProperty;
    1717
    18         private final LimitType upperLimit;
     18    private final LimitType upperLimit;
    1919
    20         /**
    21         * @param keyName          key that is used to add this property to a way; value must be in
    22         *                         format readable by {@link ValueStringParser#parseOsmDecimal(String)};
    23         *                         != null
    24         * @param vehicleProperty  vehicle property that is limited by this road property; != null
    25         * @param upperLimit       type of limit; != null
    26         */
    27         protected RoadValueLimit(String keyName, VehiclePropertyType<Float> vehicleProperty,
    28                         LimitType upperLimit) {
    29                 assert keyName != null && vehicleProperty != null && upperLimit != null;
     20    /**
     21    * @param keyName          key that is used to add this property to a way; value must be in
     22    *                         format readable by {@link ValueStringParser#parseOsmDecimal(String)};
     23    *                         != null
     24    * @param vehicleProperty  vehicle property that is limited by this road property; != null
     25    * @param upperLimit       type of limit; != null
     26    */
     27    protected RoadValueLimit(String keyName, VehiclePropertyType<Float> vehicleProperty,
     28            LimitType upperLimit) {
     29        assert keyName != null && vehicleProperty != null && upperLimit != null;
    3030
    31                 this.keyName = keyName;
    32                 this.vehicleProperty = vehicleProperty;
    33                 this.upperLimit = upperLimit;
    34         }
     31        this.keyName = keyName;
     32        this.vehicleProperty = vehicleProperty;
     33        this.upperLimit = upperLimit;
     34    }
    3535
    36         protected abstract Float parse(String valueString);
     36    protected abstract Float parse(String valueString);
    3737
    38         public <N, W, R, M> Float evaluateW(W way, boolean forward,
    39                         AccessParameters accessParameters, DataSource<N, W, R, M> dataSource) {
    40                 assert way != null && accessParameters != null && dataSource != null;
    41                 return evaluateTags(dataSource.getTagsW(way));
    42         }
     38    public <N, W, R, M> Float evaluateW(W way, boolean forward,
     39            AccessParameters accessParameters, DataSource<N, W, R, M> dataSource) {
     40        assert way != null && accessParameters != null && dataSource != null;
     41        return evaluateTags(dataSource.getTagsW(way));
     42    }
    4343
    44         public <N, W, R, M> Float evaluateN(N node,
    45                         AccessParameters accessParameters, DataSource<N, W, R, M> dataSource) {
    46                 assert node != null && accessParameters != null && dataSource != null;
    47                 return evaluateTags(dataSource.getTagsN(node));
    48         }
     44    public <N, W, R, M> Float evaluateN(N node,
     45            AccessParameters accessParameters, DataSource<N, W, R, M> dataSource) {
     46        assert node != null && accessParameters != null && dataSource != null;
     47        return evaluateTags(dataSource.getTagsN(node));
     48    }
    4949
    50         private final Float evaluateTags(TagGroup tags) {
    51                 String valueString = tags.getValue(keyName);
    52                 if (valueString != null) {
    53                         Float value = parse(valueString);
    54                         return value;
    55                 } else {
    56                         return null;
    57                 }
    58         }
     50    private final Float evaluateTags(TagGroup tags) {
     51        String valueString = tags.getValue(keyName);
     52        if (valueString != null) {
     53            Float value = parse(valueString);
     54            return value;
     55        } else {
     56            return null;
     57        }
     58    }
    5959
    60         public boolean isUsable(Object propertyValue, AccessParameters accessParameters) {
    61                 assert propertyValue instanceof Float;
     60    public boolean isUsable(Object propertyValue, AccessParameters accessParameters) {
     61        assert propertyValue instanceof Float;
    6262
    63                 Float vehicleValue = accessParameters.getVehiclePropertyValue(vehicleProperty);
     63        Float vehicleValue = accessParameters.getVehiclePropertyValue(vehicleProperty);
    6464
    65                 if (vehicleValue != null) {
    66                         switch(upperLimit) {
    67                                 case MINIMUM: return vehicleValue >= (Float) propertyValue;
    68                                 case MAXIMUM: return vehicleValue <= (Float) propertyValue;
    69                                 default:      throw new Error("unhandled LimitType");
    70                         }
    71                 } else {
    72                         return true;
    73                 }
    74         }
     65        if (vehicleValue != null) {
     66            switch(upperLimit) {
     67                case MINIMUM: return vehicleValue >= (Float) propertyValue;
     68                case MAXIMUM: return vehicleValue <= (Float) propertyValue;
     69                default:      throw new Error("unhandled LimitType");
     70            }
     71        } else {
     72            return true;
     73        }
     74    }
    7575
    7676}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/property/RoadWidth.java

    r20243 r23189  
    66
    77public class RoadWidth extends RoadValueLimit {
    8         public RoadWidth() {
    9                 super("width", WIDTH, LimitType.MAXIMUM);
    10         }
    11         @Override
    12         protected Float parse(String valueString) {
    13                 return ValueStringParser.parseMeasure(valueString);
    14         }
     8    public RoadWidth() {
     9        super("width", WIDTH, LimitType.MAXIMUM);
     10    }
     11    @Override
     12    protected Float parse(String valueString) {
     13        return ValueStringParser.parseMeasure(valueString);
     14    }
    1515}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/property/VehiclePropertyType.java

    r16520 r23189  
    1111public interface VehiclePropertyType<V> {
    1212
    13         /**
    14         * determines whether a value is valid.
    15         * null is never a valid value and must not be used as parameter.
    16         */
    17         public boolean isValidValue(Object value);
     13    /**
     14    * determines whether a value is valid.
     15    * null is never a valid value and must not be used as parameter.
     16    */
     17    public boolean isValidValue(Object value);
    1818
    1919}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/property/VehiclePropertyTypes.java

    r16520 r23189  
    99public final class VehiclePropertyTypes {
    1010
    11         /** prevents instantiation */
    12         private VehiclePropertyTypes() { }
     11    /** prevents instantiation */
     12    private VehiclePropertyTypes() { }
    1313
    14         private static final class NonnegativeFloatProperty implements VehiclePropertyType<Float> {
    15                 public boolean isValidValue(Object value) {
    16                         return value instanceof Float && (Float)value >= 0;
    17                 }
    18         }
     14    private static final class NonnegativeFloatProperty implements VehiclePropertyType<Float> {
     15        public boolean isValidValue(Object value) {
     16            return value instanceof Float && (Float)value >= 0;
     17        }
     18    }
    1919
    20         /** length of a vehicle in meters; negative values are invalid */
    21         public static final VehiclePropertyType<Float> LENGTH = new NonnegativeFloatProperty();
     20    /** length of a vehicle in meters; negative values are invalid */
     21    public static final VehiclePropertyType<Float> LENGTH = new NonnegativeFloatProperty();
    2222
    23         /** width of a vehicle in meters; negative values are invalid */
    24         public static final VehiclePropertyType<Float> WIDTH = new NonnegativeFloatProperty();
     23    /** width of a vehicle in meters; negative values are invalid */
     24    public static final VehiclePropertyType<Float> WIDTH = new NonnegativeFloatProperty();
    2525
    26         /** height of a vehicle in meters; negative values are invalid */
    27         public static final VehiclePropertyType<Float> HEIGHT = new NonnegativeFloatProperty();
     26    /** height of a vehicle in meters; negative values are invalid */
     27    public static final VehiclePropertyType<Float> HEIGHT = new NonnegativeFloatProperty();
    2828
    29         /** weight of a vehicle in tons; negative values are invalid */
    30         public static final VehiclePropertyType<Float> WEIGHT = new NonnegativeFloatProperty();
     29    /** weight of a vehicle in tons; negative values are invalid */
     30    public static final VehiclePropertyType<Float> WEIGHT = new NonnegativeFloatProperty();
    3131
    32         /** axleload of a vehicle in tons; negative values are invalid */
    33         public static final VehiclePropertyType<Float> AXLELOAD = new NonnegativeFloatProperty();
     32    /** axleload of a vehicle in tons; negative values are invalid */
     33    public static final VehiclePropertyType<Float> AXLELOAD = new NonnegativeFloatProperty();
    3434
    35         /** speed a vehicle can reach in km/h; negative values are invalid */
    36         public static final VehiclePropertyType<Float> SPEED = new NonnegativeFloatProperty();
     35    /** speed a vehicle can reach in km/h; negative values are invalid */
     36    public static final VehiclePropertyType<Float> SPEED = new NonnegativeFloatProperty();
    3737
    38         /** maximum incline a vehicle can go up; negative values are invalid */
    39         public static final VehiclePropertyType<Float> MAX_INCLINE_UP = new NonnegativeFloatProperty();
     38    /** maximum incline a vehicle can go up; negative values are invalid */
     39    public static final VehiclePropertyType<Float> MAX_INCLINE_UP = new NonnegativeFloatProperty();
    4040
    41         /** maximum incline a vehicle can go down; negative values are invalid */
    42         public static final VehiclePropertyType<Float> MAX_INCLINE_DOWN = new NonnegativeFloatProperty();
     41    /** maximum incline a vehicle can go down; negative values are invalid */
     42    public static final VehiclePropertyType<Float> MAX_INCLINE_DOWN = new NonnegativeFloatProperty();
    4343
    44         /** surface types ("surface" key values) the vehicle cannot use */
    45         public static final VehiclePropertyType<Collection<String>> SURFACE_BLACKLIST = new VehiclePropertyType<Collection<String>>() {
    46                 public boolean isValidValue(Object value) {
     44    /** surface types ("surface" key values) the vehicle cannot use */
     45    public static final VehiclePropertyType<Collection<String>> SURFACE_BLACKLIST = new VehiclePropertyType<Collection<String>>() {
     46        public boolean isValidValue(Object value) {
    4747
    48                         if (!(value instanceof Collection)) {
    49                                 return false;
    50                         }
     48            if (!(value instanceof Collection)) {
     49                return false;
     50            }
    5151
    52                         for (Object contentObject : (Collection<?>)value) {
    53                                 if (!(contentObject instanceof String)) {
    54                                         return false;
    55                                 }
    56                         }
     52            for (Object contentObject : (Collection<?>)value) {
     53                if (!(contentObject instanceof String)) {
     54                    return false;
     55                }
     56            }
    5757
    58                         return true;
    59                 }
    60         };
     58            return true;
     59        }
     60    };
    6161
    62         /**
    63         * maximum tracktype grade the vehicle can use;
    64         * values are integers from = to 5
    65         * (values of key "tracktype" without "grade_" prefix, 0 is for "none")
    66         */
    67         public static final VehiclePropertyType<Integer> MAX_TRACKTYPE = new VehiclePropertyType<Integer>() {
    68                 public boolean isValidValue(Object value) {
    69                         return value instanceof Integer && (Integer)value >= 0 && (Integer)value <= 5;
    70                 }
    71         };
     62    /**
     63    * maximum tracktype grade the vehicle can use;
     64    * values are integers from = to 5
     65    * (values of key "tracktype" without "grade_" prefix, 0 is for "none")
     66    */
     67    public static final VehiclePropertyType<Integer> MAX_TRACKTYPE = new VehiclePropertyType<Integer>() {
     68        public boolean isValidValue(Object value) {
     69            return value instanceof Integer && (Integer)value >= 0 && (Integer)value <= 5;
     70        }
     71    };
    7272
    7373}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/transition/GenericTransitionStructure.java

    r19216 r23189  
    3030public class GenericTransitionStructure<N, W, R, M> implements TransitionStructure, DataSourceObserver {
    3131
    32         private static final Collection<Segment> EMPTY_SEGMENT_LIST =
    33                 Collections.unmodifiableList(new ArrayList<Segment>(0));
    34         private static final Collection<Restriction> EMPTY_RESTRICTION_COLLECTION =
    35                 new ArrayList<Restriction>(0);
    36 
    37         private static class SegmentNodeImpl implements SegmentNode {
    38                 private final double lat;
    39                 private final double lon;
    40                 private final List<Segment> inboundSegments = new LinkedList<Segment>();
    41                 private final List<Segment> outboundSegments = new LinkedList<Segment>();
    42                 private final Map<RoadPropertyType<?>, Object> properties;
    43                 public SegmentNodeImpl(double lat, double lon, Map<RoadPropertyType<?>, Object> properties) {
    44                         assert properties != null;
    45                         this.lat = lat;
    46                         this.lon = lon;
    47                         this.properties = properties;
    48                 }
    49                 public double getLat() {
    50                         return lat;
    51                 }
    52                 public double getLon() {
    53                         return lon;
    54                 }
    55                 public void addInboundSegment(Segment segment) {
    56                         inboundSegments.add(segment);
    57                 }
    58                 public void addOutboundSegment(Segment segment) {
    59                         outboundSegments.add(segment);
    60                 }
    61                 public Collection<Segment> getOutboundSegments() {
    62                         return outboundSegments;
    63                 }
    64                 public Collection<Segment> getInboundSegments() {
    65                         return inboundSegments;
    66                 }
    67 
    68                 public <P> void setProperty(RoadPropertyType<P> property, P value) {
    69                         properties.put(property, value);
    70                 }
    71                 public Collection<RoadPropertyType<?>> getAvailableProperties() {
    72                         return properties.keySet();
    73                 }
    74                 public <P> P getPropertyValue(RoadPropertyType<P> property) {
    75                         @SuppressWarnings("unchecked") //cast is safe due to type parameter of setProperty
    76                         P result = (P) properties.get(property);
    77                         return result;
    78                 }
    79                 public Map<RoadPropertyType<?>, Object> getProperties() {
    80                         return properties;
    81                 }
    82 
    83                 @Override
    84                 public String toString() {
    85                         return "(" + lat + ", " + lon + ")";
    86                 }
    87         }
    88 
    89         private static class SegmentImpl implements Segment {
    90                 private final SegmentNode node1;
    91                 private final SegmentNode node2;
    92                 private final Map<RoadPropertyType<?>, Object> properties;
    93                 public SegmentImpl(SegmentNode node1, SegmentNode node2, Map<RoadPropertyType<?>, Object> properties) {
    94                         this.node1 = node1;
    95                         this.node2 = node2;
    96                         this.properties = properties;
    97                 }
    98                 public SegmentNode getNode1() {
    99                         return node1;
    100                 }
    101                 public SegmentNode getNode2() {
    102                         return node2;
    103                 }
    104                 public <P> void setProperty(RoadPropertyType<P> property, P value) {
    105                         properties.put(property, value);
    106                 }
    107                 public Collection<RoadPropertyType<?>> getAvailableProperties() {
    108                         return properties.keySet();
    109                 }
    110                 public <P> P getPropertyValue(RoadPropertyType<P> property) {
    111                         @SuppressWarnings("unchecked") //cast is safe due to type parameter of setProperty
    112                         P result = (P) properties.get(property);
    113                         return result;
    114                 }
    115 
    116                 @Override
    117                 public String toString() {
    118                         return "(" + node1 + "->" + node2 + ")";
    119                 }
    120         }
    121 
    122         private static class RestrictionImpl implements Restriction {
    123                 private final Segment from;
    124                 private final Collection<Segment> vias;
    125                 private final Collection<Segment> tos;
    126 
    127                 /** constructor, will directly use collection references, collections must not be changed after usage as constructor param */
    128                 public RestrictionImpl(Segment from, Collection<Segment> vias, Collection<Segment> tos) {
    129                         this.from = from;
    130                         this.vias = Collections.unmodifiableCollection(vias);
    131                         this.tos = Collections.unmodifiableCollection(tos);
    132                 }
    133 
    134                 public Segment getFrom() {
    135                         return from;
    136                 }
    137                 public Collection<Segment> getVias() {
    138                         return vias;
    139                 }
    140                 public Collection<Segment> getTos() {
    141                         return tos;
    142                 }
    143 
    144                 @Override
    145                 public String toString() {
    146                         return from + " -> " + vias + " -> " + tos;
    147                 }
    148         }
    149 
    150         private final Set<TransitionStructureObserver> observers = new HashSet<TransitionStructureObserver>();
    151 
    152         private final Collection<RoadPropertyType<?>> properties;
    153 
    154         private final DataSource<N, W, R, M> dataSource;
    155 
    156         private AccessParameters accessParameters;
    157         private AccessRuleset ruleset;
    158 
    159         private AccessEvaluator<N, W> accessEvaluator;
    160 
    161         private Collection<SegmentNode> nodes = null;
    162         private Collection<Segment> segments = new LinkedList<Segment>();
    163         private Collection<Restriction> restrictions = new LinkedList<Restriction>();
    164 
    165         public GenericTransitionStructure(
    166                         AccessParameters accessParameters, AccessRuleset ruleset,
    167                         DataSource<N, W, R, M> dataSource,
    168                         Collection<RoadPropertyType<?>> properties) {
    169 
    170                 assert accessParameters != null && ruleset != null;
    171                 assert dataSource != null;
    172                 assert properties != null;
    173 
    174                 this.dataSource = dataSource;
    175 
    176                 this.properties = properties;
    177 
    178                 setAccessParametersAndRuleset(accessParameters, ruleset);
    179 
    180                 dataSource.addObserver(this);
    181         }
    182 
    183         /**
    184         * sets new access parameters and/or a new ruleset.
    185         * Causes a data update if at least one is actually changed.
    186         *
    187         * @param accessParameters  new access parameters, null indicates no change
    188         * @param ruleset           new ruleset, null indicates no change
    189         */
    190         public void setAccessParametersAndRuleset(AccessParameters accessParameters, AccessRuleset ruleset) {
    191 
    192                 if (accessParameters != null) {
    193                         this.accessParameters = accessParameters;
    194                 }
    195                 if (ruleset != null) {
    196                         this.ruleset = ruleset;
    197                 }
    198 
    199                 if (accessParameters != null || ruleset != null) {
    200 
    201                         assert dataSource != null;
    202 
    203                         accessEvaluator = new RulesetAccessEvaluator<N, W, R, M>(
    204                                         dataSource,
    205                                         this.ruleset,
    206                                         this.accessParameters);
    207 
    208                         updateData();
    209                         notifyObservers();
    210 
    211                 }
    212 
    213         }
    214 
    215         public Collection<SegmentNode> getNodes() {
    216                 return nodes;
    217         }
    218 
    219         public Collection<Segment> getSegments() {
    220                 return segments;
    221         }
    222 
    223         public Collection<Restriction> getRestrictions() {
    224                 return restrictions;
    225         }
    226 
    227         /**
    228         * creates nodes, segments and restrictions based on the data source
    229         */
    230         protected void updateData() {
    231 
    232                 ArrayList<SegmentNode> nodes = new ArrayList<SegmentNode>();
    233                 ArrayList<Segment> segments = new ArrayList<Segment>();
    234 
    235                 Map<N, SegmentNodeImpl> nodeCreationMap = new HashMap<N, SegmentNodeImpl>();
    236                 Map<W, List<Segment>> waySegmentMap = new HashMap<W, List<Segment>>();
    237 
    238                 /* create segments (nodes are created only when included in a segment) */
    239 
    240                 for (W way : dataSource.getWays()) {
    241                         createSegmentsAndSegmentNodes(way, accessEvaluator, nodes, segments, nodeCreationMap, waySegmentMap);
    242                 }
    243 
    244                 nodes.trimToSize();
    245                 segments.trimToSize();
    246 
    247                 /* create restrictions */
    248 
    249                 Collection<Restriction> restrictions =
    250                         createRestrictionsFromTurnRestrictions(dataSource.getRelations(), nodeCreationMap, waySegmentMap);
    251 
    252                 restrictions.addAll(createRestrictionsFromBarrierNodes(nodeCreationMap, waySegmentMap));
    253 
    254                 /* keep data and inform observers */
    255 
    256                 this.nodes = nodes;
    257                 this.segments = segments;
    258                 this.restrictions = restrictions;
    259 
    260                 notifyObservers();
    261 
    262         }
    263 
    264         /**
    265         * creates all Segments and SegmentNodes for a way
    266         *
    267         * @param way                 way to create Segments and SegmentNodes from; != null
    268         * @param wayAccessEvaluator  evaluator object that decides whether way is usable; != null
    269         * @param nodes               collection of SegmentNodes, new SegmentNodes will be added here; != null
    270         * @param segments            collection of Segments, new Segments will be added here; != null
    271         * @param nodeCreationMap     map providing the SegmentNode that has been created from a Node,
    272         *                            if new SegmentNodes are created, they will be added appropriately; != null
    273         * @param waySegmentMap       map providing the Segments that have been created from a Way,
    274         *                            if new Segments are created, they will be added appropriately; != null
    275         */
    276         private void createSegmentsAndSegmentNodes(W way, AccessEvaluator<N, W> wayAccessEvaluator,
    277                         Collection<SegmentNode> nodes, Collection<Segment> segments,
    278                         Map<N, SegmentNodeImpl> nodeCreationMap, Map<W, List<Segment>> waySegmentMap) {
    279 
    280                 assert way != null && wayAccessEvaluator != null && nodes != null && segments != null && nodeCreationMap != null && waySegmentMap != null;
    281 
    282                 /* calculate property values */
    283 
    284                 Map<RoadPropertyType<?>, Object> forwardPropertyValues = getWayPropertyMap(way, true);
    285                 Map<RoadPropertyType<?>, Object> backwardPropertyValues = getWayPropertyMap(way, false);
    286 
    287                 /* create segments from the way if it can be accessed and isn't incomplete or deleted */
    288 
    289                 boolean forwardAccess = wayAccessEvaluator.wayUsable(way, true, forwardPropertyValues);
    290                 boolean backwardAccess = wayAccessEvaluator.wayUsable(way, false, backwardPropertyValues);
    291 
    292                 if (forwardAccess || backwardAccess) {
    293 
    294                         if (!waySegmentMap.containsKey(way)) {
    295                                 waySegmentMap.put(way, new LinkedList<Segment>());
    296                         }
    297 
    298                         /* create segments from all pairs of subsequent nodes */
    299 
    300                         N previousNode = null;
    301                         for (N node : dataSource.getNodes(way)) {
    302                                 if (previousNode != null) {
    303 
    304                                         SegmentNodeImpl node1 =
    305                                                 getOrCreateSegmentNodeForNode(previousNode, nodes, nodeCreationMap);
    306                                         SegmentNodeImpl node2 =
    307                                                 getOrCreateSegmentNodeForNode(node, nodes, nodeCreationMap);
    308 
    309                                         if (forwardAccess) {
    310                                                 SegmentImpl segment = new SegmentImpl(node1, node2, forwardPropertyValues);
    311                                                 segments.add(segment);
    312                                                 waySegmentMap.get(way).add(segment);
    313                                                 node1.addOutboundSegment(segment);
    314                                                 node2.addInboundSegment(segment);
    315                                         }
    316                                         if (backwardAccess) { //no "else if" because both can be valid
    317                                                 SegmentImpl segment = new SegmentImpl(node2, node1, backwardPropertyValues);
    318                                                 segments.add(segment);
    319                                                 waySegmentMap.get(way).add(segment);
    320                                                 node1.addInboundSegment(segment);
    321                                                 node2.addOutboundSegment(segment);
    322                                         }
    323 
    324                                 }
    325                                 previousNode = node;
    326                         }
    327 
    328                 }
    329         }
    330 
    331         /**
    332         * if no segment node for a node exists in the nodeCreationMap,
    333         * creates a segment node for it and adds it to the nodeCreationMap and the nodes collection
    334         * and returns it; otherwise returns the existing segment node.
    335         */
    336         private SegmentNodeImpl getOrCreateSegmentNodeForNode(N node,
    337                         Collection<SegmentNode> nodes, Map<N, SegmentNodeImpl> nodeCreationMap) {
    338 
    339                 SegmentNodeImpl segmentNode = nodeCreationMap.get(node);
    340 
    341                 if (segmentNode == null) {
    342 
    343                         Map<RoadPropertyType<?>, Object> nodePropertyValues = getNodePropertyMap(node);
    344                         segmentNode = new SegmentNodeImpl(dataSource.getLat(node), dataSource.getLon(node),
    345                                         nodePropertyValues);
    346 
    347                         nodeCreationMap.put(node, segmentNode);
    348                         nodes.add(segmentNode);
    349 
    350                 }
    351 
    352                 return segmentNode;
    353         }
    354 
    355         /**
    356         * creates all Restrictions from a collection of Relations.
    357         * Only "type=restriction" relations are relevant for restrictions.
    358         *
    359         * @param relations        Relations to create Restrictions from.
    360         *                         They can have any type key, as filtering is done inside this method.
    361         * @param nodeCreationMap  map providing the SegmentNode that has been created from a Node,
    362         *                         will not be modified; != null
    363         * @param waySegmentMap    map providing the Segments that have been created from a Way,
    364         *                         will not be modified; != null
    365         * @return                 Restrictions created from the Relations; != null, but may be empty
    366         */
    367         private Collection<Restriction> createRestrictionsFromTurnRestrictions(
    368                         Iterable<R> relations,
    369                         Map<N, SegmentNodeImpl> nodeCreationMap,
    370                         Map<W, List<Segment>> waySegmentMap) {
    371 
    372                 assert relations != null && nodeCreationMap != null && waySegmentMap != null;
    373 
    374                 Collection<Restriction> results = new LinkedList<Restriction>();
    375 
    376                 for (R relation : relations) {
    377 
    378                         TagGroup tags = dataSource.getTagsR(relation);
    379 
    380                         if ("restriction".equals(tags.getValue("type"))
    381                                         && tags.getValue("restriction") != null ) {
    382 
    383                                 //evaluate relation
    384                                 if (tags.getValue("restriction").startsWith("no_")) {
    385                                         results.addAll(createRestrictionsFromRestrictionRelation(relation, true, nodeCreationMap, waySegmentMap));
    386                                 } else if (tags.getValue("restriction").startsWith("only_")) {
    387                                         results.addAll(createRestrictionsFromRestrictionRelation(relation, false, nodeCreationMap, waySegmentMap));
    388                                 }
    389 
    390                         }
    391                 }
    392 
    393                 return results;
    394         }
    395 
    396         @SuppressWarnings("unchecked") //several generic casts that are checked with isInstance
    397         private Collection<Restriction> createRestrictionsFromRestrictionRelation(
    398                         R relation,
    399                         boolean restrictive,
    400                         Map<N, SegmentNodeImpl> nodeCreationMap,
    401                         Map<W, List<Segment>> waySegmentMap) {
    402 
    403                 /* collect information about the relation */
    404 
    405                 W fromWay = null;
    406                 Collection<N> viaNodes = new LinkedList<N>();
    407                 Collection<W> viaWays = new LinkedList<W>();
    408                 Collection<W> toWays = new LinkedList<W>();
    409 
    410                 for (M member : dataSource.getMembers(relation)) {
    411 
    412                         if ("from".equals(dataSource.getRole(member))) {
    413                                 if (fromWay != null || !dataSource.isWMember(member)) {
    414                                         //broken restriction
    415                                         return EMPTY_RESTRICTION_COLLECTION;
    416                                 } else {
    417                                         fromWay = (W)dataSource.getMember(member);
    418                                 }
    419                         } else if ("to".equals(dataSource.getRole(member))) {
    420                                 if (!dataSource.isWMember(member)) {
    421                                         //broken restriction
    422                                         return EMPTY_RESTRICTION_COLLECTION;
    423                                 } else {
    424                                         toWays.add((W)dataSource.getMember(member));
    425                                 }
    426                         } else if ("via".equals(dataSource.getRole(member))) {
    427                                 if (dataSource.isWMember(member)) {
    428                                         viaWays.add((W)dataSource.getMember(member));
    429                                 } else if (dataSource.isNMember(member)) {
    430                                         viaNodes.add((N)dataSource.getMember(member));
    431                                 }
    432                         }
    433 
    434                 }
    435 
    436                 if (fromWay != null && toWays.size() > 0 &&
    437                                 (viaNodes.size() > 0 || viaWays.size() > 0)) {
    438 
    439                         return createRestrictionsFromRestrictionRelationMembers(
    440                                         restrictive, nodeCreationMap, waySegmentMap,
    441                                         fromWay, viaNodes, viaWays, toWays);
    442 
    443                 } else {
    444                         return new ArrayList<Restriction>(0);
    445                 }
    446         }
    447 
    448         private Collection<Restriction> createRestrictionsFromRestrictionRelationMembers(
    449                         boolean restrictive,
    450                         Map<N, SegmentNodeImpl> nodeCreationMap, Map<W, List<Segment>> waySegmentMap,
    451                         W fromWay, Collection<N> viaNodes, Collection<W> viaWays, Collection<W> toWays) {
    452 
    453                 Collection<SegmentNode> nodesCreatedFromViaNodes = new ArrayList<SegmentNode>(viaNodes.size());
    454                 for (N viaNode : viaNodes) {
    455                         if (nodeCreationMap.containsKey(viaNode)) {
    456                                 nodesCreatedFromViaNodes.add(nodeCreationMap.get(viaNode));
    457                         }
    458                 }
    459 
    460                 /* check completeness of restriction to avoid dealing with incomplete restriction info */
    461 
    462                 if (!waySegmentMap.containsKey(fromWay)) {
    463                         //broken restriction
    464                         return EMPTY_RESTRICTION_COLLECTION;
    465                 }
    466 
    467                 for (W viaWay : viaWays) {
    468                         if (!waySegmentMap.containsKey(viaWay)) {
    469                                 //broken restriction
    470                                 return EMPTY_RESTRICTION_COLLECTION;
    471                         }
    472                 }
    473 
    474                 for (W toWay : toWays) {
    475                         if (!waySegmentMap.containsKey(toWay)) {
    476                                 //broken restriction
    477                                 return EMPTY_RESTRICTION_COLLECTION;
    478                         }
    479                 }
    480 
    481                 /* find all via segments:
    482                 * via segments are segments created from via ways
    483                 * or segments starting and ending with nodes created from via nodes */
    484 
    485                 ArrayList<Segment> viaSegments = new ArrayList<Segment>();
    486 
    487                 for (W viaWay : viaWays) {
    488                         viaSegments.addAll(waySegmentMap.get(viaWay));
    489                 }
    490 
    491                 for (SegmentNode nodeCreatedFromViaNode : nodesCreatedFromViaNodes) {
    492                         for (Segment segment : nodeCreatedFromViaNode.getOutboundSegments()) {
    493                                 if (nodesCreatedFromViaNodes.contains(segment.getNode2())) {
    494                                         viaSegments.add(segment);
    495                                 }
    496                         }
    497                 }
    498 
    499                 viaSegments.trimToSize();
    500 
    501                 /* create a set with all nodes that are based on via members */
    502 
    503                 Set<SegmentNode> nodesCreatedFromViaMembers
    504                 = new HashSet<SegmentNode>(nodesCreatedFromViaNodes);
    505 
    506                 for (W viaWay : viaWays) {
    507                         for (N viaWayNode : dataSource.getNodes(viaWay)) {
    508                                 nodesCreatedFromViaMembers.add(nodeCreationMap.get(viaWayNode));
    509                         }
    510                 }
    511 
    512                 /*
    513                 * find from segment and to segments:
    514                 * Such a segment contains a node based on a via member.
    515                 * Each way should contain only one possible segment
    516                 * connecting to via members (due to splitting).
    517                 */
    518 
    519                 Segment fromSegment = null;
    520                 Collection<Segment> toSegments = new ArrayList<Segment>();
    521 
    522                 for (Segment possibleFromSegment : waySegmentMap.get(fromWay)) {
    523                         if (nodesCreatedFromViaMembers.contains(possibleFromSegment.getNode2())) {
    524 
    525                                 if (fromSegment == null) {
    526                                         fromSegment = possibleFromSegment;
    527                                 } else {
    528                                         //broken restriction
    529                                         return EMPTY_RESTRICTION_COLLECTION;
    530                                 }
    531 
    532                         }
    533                 }
    534                 if (fromSegment == null) {
    535                         //broken restriction
    536                         return EMPTY_RESTRICTION_COLLECTION;
    537                 }
    538 
    539                 if (restrictive) {
    540 
    541                         for (W toWay : toWays) {
    542                                 if (waySegmentMap.containsKey(toWay)) {
    543                                         Segment toSegment = null;
    544                                         for (Segment possibleToSegment : waySegmentMap.get(toWay)) {
    545                                                 if (nodesCreatedFromViaMembers.contains(possibleToSegment.getNode1())) {
    546 
    547                                                         if (toSegment == null) {
    548                                                                 toSegment = possibleToSegment;
    549                                                         } else {
    550                                                                 //broken restriction
    551                                                                 return EMPTY_RESTRICTION_COLLECTION;
    552                                                         }
    553 
    554                                                 }
    555                                         }
    556                                         if (toSegment == null) {
    557                                                 //broken restriction
    558                                                 return EMPTY_RESTRICTION_COLLECTION;
    559                                         } else {
    560                                                 toSegments.add(toSegment);
    561                                         }
    562                                 }
    563                         }
    564 
    565                 } else { //!restrictive
    566 
    567                         /* forbidden "to" segments are all segments that start at a "via" node
    568                         * and are neither a via segment nor created from an allowed "to" way */
    569 
    570                         for (SegmentNode toStartingNode : nodesCreatedFromViaMembers) {
    571                                 for (Segment outboundSegment : toStartingNode.getOutboundSegments()) {
    572 
    573                                         if (!viaSegments.contains(outboundSegment)) {
    574 
    575                                                 boolean isAllowed = false;
    576 
    577                                                 for (W toWay : toWays) {
    578                                                         if (waySegmentMap.get(toWay).contains(outboundSegment)) {
    579                                                                 isAllowed = true;
    580                                                                 break;
    581                                                         }
    582                                                 }
    583 
    584                                                 if (!isAllowed) {
    585                                                         toSegments.add(outboundSegment);
    586                                                 }
    587 
    588                                         }
    589 
    590                                 }
    591                         }
    592 
    593                 }
    594 
    595                 /* create restriction */
    596 
    597                 Collection<Restriction> results = new ArrayList<Restriction>(1);
    598                 results.add(new RestrictionImpl(fromSegment, viaSegments, toSegments));
    599                 return results;
    600         }
    601 
    602         /**
    603         * creates Restrictions from barrier nodes (nodes that are considered impassable by the
    604         * {@link #accessEvaluator}). These restrictions prevent moving from a segment before the
    605         * barrier node to a segment after the barrier node.
    606         *
    607         * @param nodeCreationMap  map providing the SegmentNode that has been created from a node,
    608         *                         will not be modified; != null
    609         * @param waySegmentMap    map providing the Segments that have been created from a way,
    610         *                         will not be modified; != null
    611         * @return                 Restrictions created from barrier nodes; != null, but may be empty
    612         */
    613         private Collection<Restriction> createRestrictionsFromBarrierNodes(
    614                         Map<N, SegmentNodeImpl> nodeCreationMap,
    615                         Map<W, List<Segment>> waySegmentMap) {
    616 
    617                 assert nodeCreationMap != null;
    618                 assert waySegmentMap != null;
    619 
    620                 Collection<Restriction> results = new LinkedList<Restriction>();
    621 
    622                 for (N node : nodeCreationMap.keySet()) {
    623 
    624                         if (!accessEvaluator.nodeUsable(node, nodeCreationMap.get(node).getProperties())) {
    625 
    626                                 SegmentNode barrierNode = nodeCreationMap.get(node);
    627 
    628                                 for (Segment inboundSegment : barrierNode.getInboundSegments()) {
    629                                         for (Segment outboundSegment : barrierNode.getOutboundSegments()) {
    630                                                 results.add(new RestrictionImpl(inboundSegment, EMPTY_SEGMENT_LIST, Arrays.asList(outboundSegment)));
    631                                         }
    632                                 }
    633 
    634                         }
    635 
    636                 }
    637 
    638                 return results;
    639         }
    640 
    641         /**
    642         * determines the values of all RoadPropertyTypes from {@link #properties} for a way and
    643         * creates a map with the types that have non-null values as keys, property values as content
    644         */
    645         private Map<RoadPropertyType<?>, Object> getWayPropertyMap(W way, boolean forward) {
    646                 Map<RoadPropertyType<?>, Object> propertyValues;
    647                 propertyValues = new HashMap<RoadPropertyType<?>, Object>();
    648                 for (RoadPropertyType<?> property : properties) {
    649                         Object value = property.evaluateW(way, forward, accessParameters, dataSource);
    650                         if (value != null) {
    651                                 propertyValues.put(property, value);
    652                         }
    653                 }
    654                 return propertyValues;
    655         }
    656 
    657         /**
    658         * determines the values of all RoadPropertyTypes from {@link #properties} for a node and
    659         * creates a map with the types that have non-null values as keys, property values as content
    660         */
    661         private Map<RoadPropertyType<?>, Object> getNodePropertyMap(N node) {
    662                 Map<RoadPropertyType<?>, Object> propertyValues;
    663                 propertyValues = new HashMap<RoadPropertyType<?>, Object>();
    664                 for (RoadPropertyType<?> property : properties) {
    665                         Object value = property.evaluateN(node, accessParameters, dataSource);
    666                         if (value != null) {
    667                                 propertyValues.put(property, value);
    668                         }
    669                 }
    670                 return propertyValues;
    671         }
    672 
    673         public void update(DataSource<?, ?, ?, ?> dataSource) {
    674                 assert this.dataSource == dataSource;
    675                 updateData();
    676         }
    677 
    678         public void addObserver(TransitionStructureObserver observer) {
    679                 observers.add(observer);
    680         }
    681 
    682         public void deleteObserver(TransitionStructureObserver observer) {
    683                 observers.remove(observer);
    684         }
    685 
    686         protected void notifyObservers() {
    687                 for (TransitionStructureObserver observer : observers) {
    688                         observer.update(this);
    689                 }
    690         }
     32    private static final Collection<Segment> EMPTY_SEGMENT_LIST =
     33        Collections.unmodifiableList(new ArrayList<Segment>(0));
     34    private static final Collection<Restriction> EMPTY_RESTRICTION_COLLECTION =
     35        new ArrayList<Restriction>(0);
     36
     37    private static class SegmentNodeImpl implements SegmentNode {
     38        private final double lat;
     39        private final double lon;
     40        private final List<Segment> inboundSegments = new LinkedList<Segment>();
     41        private final List<Segment> outboundSegments = new LinkedList<Segment>();
     42        private final Map<RoadPropertyType<?>, Object> properties;
     43        public SegmentNodeImpl(double lat, double lon, Map<RoadPropertyType<?>, Object> properties) {
     44            assert properties != null;
     45            this.lat = lat;
     46            this.lon = lon;
     47            this.properties = properties;
     48        }
     49        public double getLat() {
     50            return lat;
     51        }
     52        public double getLon() {
     53            return lon;
     54        }
     55        public void addInboundSegment(Segment segment) {
     56            inboundSegments.add(segment);
     57        }
     58        public void addOutboundSegment(Segment segment) {
     59            outboundSegments.add(segment);
     60        }
     61        public Collection<Segment> getOutboundSegments() {
     62            return outboundSegments;
     63        }
     64        public Collection<Segment> getInboundSegments() {
     65            return inboundSegments;
     66        }
     67
     68        public <P> void setProperty(RoadPropertyType<P> property, P value) {
     69            properties.put(property, value);
     70        }
     71        public Collection<RoadPropertyType<?>> getAvailableProperties() {
     72            return properties.keySet();
     73        }
     74        public <P> P getPropertyValue(RoadPropertyType<P> property) {
     75            @SuppressWarnings("unchecked") //cast is safe due to type parameter of setProperty
     76            P result = (P) properties.get(property);
     77            return result;
     78        }
     79        public Map<RoadPropertyType<?>, Object> getProperties() {
     80            return properties;
     81        }
     82
     83        @Override
     84        public String toString() {
     85            return "(" + lat + ", " + lon + ")";
     86        }
     87    }
     88
     89    private static class SegmentImpl implements Segment {
     90        private final SegmentNode node1;
     91        private final SegmentNode node2;
     92        private final Map<RoadPropertyType<?>, Object> properties;
     93        public SegmentImpl(SegmentNode node1, SegmentNode node2, Map<RoadPropertyType<?>, Object> properties) {
     94            this.node1 = node1;
     95            this.node2 = node2;
     96            this.properties = properties;
     97        }
     98        public SegmentNode getNode1() {
     99            return node1;
     100        }
     101        public SegmentNode getNode2() {
     102            return node2;
     103        }
     104        public <P> void setProperty(RoadPropertyType<P> property, P value) {
     105            properties.put(property, value);
     106        }
     107        public Collection<RoadPropertyType<?>> getAvailableProperties() {
     108            return properties.keySet();
     109        }
     110        public <P> P getPropertyValue(RoadPropertyType<P> property) {
     111            @SuppressWarnings("unchecked") //cast is safe due to type parameter of setProperty
     112            P result = (P) properties.get(property);
     113            return result;
     114        }
     115
     116        @Override
     117        public String toString() {
     118            return "(" + node1 + "->" + node2 + ")";
     119        }
     120    }
     121
     122    private static class RestrictionImpl implements Restriction {
     123        private final Segment from;
     124        private final Collection<Segment> vias;
     125        private final Collection<Segment> tos;
     126
     127        /** constructor, will directly use collection references, collections must not be changed after usage as constructor param */
     128        public RestrictionImpl(Segment from, Collection<Segment> vias, Collection<Segment> tos) {
     129            this.from = from;
     130            this.vias = Collections.unmodifiableCollection(vias);
     131            this.tos = Collections.unmodifiableCollection(tos);
     132        }
     133
     134        public Segment getFrom() {
     135            return from;
     136        }
     137        public Collection<Segment> getVias() {
     138            return vias;
     139        }
     140        public Collection<Segment> getTos() {
     141            return tos;
     142        }
     143
     144        @Override
     145        public String toString() {
     146            return from + " -> " + vias + " -> " + tos;
     147        }
     148    }
     149
     150    private final Set<TransitionStructureObserver> observers = new HashSet<TransitionStructureObserver>();
     151
     152    private final Collection<RoadPropertyType<?>> properties;
     153
     154    private final DataSource<N, W, R, M> dataSource;
     155
     156    private AccessParameters accessParameters;
     157    private AccessRuleset ruleset;
     158
     159    private AccessEvaluator<N, W> accessEvaluator;
     160
     161    private Collection<SegmentNode> nodes = null;
     162    private Collection<Segment> segments = new LinkedList<Segment>();
     163    private Collection<Restriction> restrictions = new LinkedList<Restriction>();
     164
     165    public GenericTransitionStructure(
     166            AccessParameters accessParameters, AccessRuleset ruleset,
     167            DataSource<N, W, R, M> dataSource,
     168            Collection<RoadPropertyType<?>> properties) {
     169
     170        assert accessParameters != null && ruleset != null;
     171        assert dataSource != null;
     172        assert properties != null;
     173
     174        this.dataSource = dataSource;
     175
     176        this.properties = properties;
     177
     178        setAccessParametersAndRuleset(accessParameters, ruleset);
     179
     180        dataSource.addObserver(this);
     181    }
     182
     183    /**
     184    * sets new access parameters and/or a new ruleset.
     185    * Causes a data update if at least one is actually changed.
     186    *
     187    * @param accessParameters  new access parameters, null indicates no change
     188    * @param ruleset           new ruleset, null indicates no change
     189    */
     190    public void setAccessParametersAndRuleset(AccessParameters accessParameters, AccessRuleset ruleset) {
     191
     192        if (accessParameters != null) {
     193            this.accessParameters = accessParameters;
     194        }
     195        if (ruleset != null) {
     196            this.ruleset = ruleset;
     197        }
     198
     199        if (accessParameters != null || ruleset != null) {
     200
     201            assert dataSource != null;
     202
     203            accessEvaluator = new RulesetAccessEvaluator<N, W, R, M>(
     204                    dataSource,
     205                    this.ruleset,
     206                    this.accessParameters);
     207
     208            updateData();
     209            notifyObservers();
     210
     211        }
     212
     213    }
     214
     215    public Collection<SegmentNode> getNodes() {
     216        return nodes;
     217    }
     218
     219    public Collection<Segment> getSegments() {
     220        return segments;
     221    }
     222
     223    public Collection<Restriction> getRestrictions() {
     224        return restrictions;
     225    }
     226
     227    /**
     228    * creates nodes, segments and restrictions based on the data source
     229    */
     230    protected void updateData() {
     231
     232        ArrayList<SegmentNode> nodes = new ArrayList<SegmentNode>();
     233        ArrayList<Segment> segments = new ArrayList<Segment>();
     234
     235        Map<N, SegmentNodeImpl> nodeCreationMap = new HashMap<N, SegmentNodeImpl>();
     236        Map<W, List<Segment>> waySegmentMap = new HashMap<W, List<Segment>>();
     237
     238        /* create segments (nodes are created only when included in a segment) */
     239
     240        for (W way : dataSource.getWays()) {
     241            createSegmentsAndSegmentNodes(way, accessEvaluator, nodes, segments, nodeCreationMap, waySegmentMap);
     242        }
     243
     244        nodes.trimToSize();
     245        segments.trimToSize();
     246
     247        /* create restrictions */
     248
     249        Collection<Restriction> restrictions =
     250            createRestrictionsFromTurnRestrictions(dataSource.getRelations(), nodeCreationMap, waySegmentMap);
     251
     252        restrictions.addAll(createRestrictionsFromBarrierNodes(nodeCreationMap, waySegmentMap));
     253
     254        /* keep data and inform observers */
     255
     256        this.nodes = nodes;
     257        this.segments = segments;
     258        this.restrictions = restrictions;
     259
     260        notifyObservers();
     261
     262    }
     263
     264    /**
     265    * creates all Segments and SegmentNodes for a way
     266    *
     267    * @param way                 way to create Segments and SegmentNodes from; != null
     268    * @param wayAccessEvaluator  evaluator object that decides whether way is usable; != null
     269    * @param nodes               collection of SegmentNodes, new SegmentNodes will be added here; != null
     270    * @param segments            collection of Segments, new Segments will be added here; != null
     271    * @param nodeCreationMap     map providing the SegmentNode that has been created from a Node,
     272    *                            if new SegmentNodes are created, they will be added appropriately; != null
     273    * @param waySegmentMap       map providing the Segments that have been created from a Way,
     274    *                            if new Segments are created, they will be added appropriately; != null
     275    */
     276    private void createSegmentsAndSegmentNodes(W way, AccessEvaluator<N, W> wayAccessEvaluator,
     277            Collection<SegmentNode> nodes, Collection<Segment> segments,
     278            Map<N, SegmentNodeImpl> nodeCreationMap, Map<W, List<Segment>> waySegmentMap) {
     279
     280        assert way != null && wayAccessEvaluator != null && nodes != null && segments != null && nodeCreationMap != null && waySegmentMap != null;
     281
     282        /* calculate property values */
     283
     284        Map<RoadPropertyType<?>, Object> forwardPropertyValues = getWayPropertyMap(way, true);
     285        Map<RoadPropertyType<?>, Object> backwardPropertyValues = getWayPropertyMap(way, false);
     286
     287        /* create segments from the way if it can be accessed and isn't incomplete or deleted */
     288
     289        boolean forwardAccess = wayAccessEvaluator.wayUsable(way, true, forwardPropertyValues);
     290        boolean backwardAccess = wayAccessEvaluator.wayUsable(way, false, backwardPropertyValues);
     291
     292        if (forwardAccess || backwardAccess) {
     293
     294            if (!waySegmentMap.containsKey(way)) {
     295                waySegmentMap.put(way, new LinkedList<Segment>());
     296            }
     297
     298            /* create segments from all pairs of subsequent nodes */
     299
     300            N previousNode = null;
     301            for (N node : dataSource.getNodes(way)) {
     302                if (previousNode != null) {
     303
     304                    SegmentNodeImpl node1 =
     305                        getOrCreateSegmentNodeForNode(previousNode, nodes, nodeCreationMap);
     306                    SegmentNodeImpl node2 =
     307                        getOrCreateSegmentNodeForNode(node, nodes, nodeCreationMap);
     308
     309                    if (forwardAccess) {
     310                        SegmentImpl segment = new SegmentImpl(node1, node2, forwardPropertyValues);
     311                        segments.add(segment);
     312                        waySegmentMap.get(way).add(segment);
     313                        node1.addOutboundSegment(segment);
     314                        node2.addInboundSegment(segment);
     315                    }
     316                    if (backwardAccess) { //no "else if" because both can be valid
     317                        SegmentImpl segment = new SegmentImpl(node2, node1, backwardPropertyValues);
     318                        segments.add(segment);
     319                        waySegmentMap.get(way).add(segment);
     320                        node1.addInboundSegment(segment);
     321                        node2.addOutboundSegment(segment);
     322                    }
     323
     324                }
     325                previousNode = node;
     326            }
     327
     328        }
     329    }
     330
     331    /**
     332    * if no segment node for a node exists in the nodeCreationMap,
     333    * creates a segment node for it and adds it to the nodeCreationMap and the nodes collection
     334    * and returns it; otherwise returns the existing segment node.
     335    */
     336    private SegmentNodeImpl getOrCreateSegmentNodeForNode(N node,
     337            Collection<SegmentNode> nodes, Map<N, SegmentNodeImpl> nodeCreationMap) {
     338
     339        SegmentNodeImpl segmentNode = nodeCreationMap.get(node);
     340
     341        if (segmentNode == null) {
     342
     343            Map<RoadPropertyType<?>, Object> nodePropertyValues = getNodePropertyMap(node);
     344            segmentNode = new SegmentNodeImpl(dataSource.getLat(node), dataSource.getLon(node),
     345                    nodePropertyValues);
     346
     347            nodeCreationMap.put(node, segmentNode);
     348            nodes.add(segmentNode);
     349
     350        }
     351
     352        return segmentNode;
     353    }
     354
     355    /**
     356    * creates all Restrictions from a collection of Relations.
     357    * Only "type=restriction" relations are relevant for restrictions.
     358    *
     359    * @param relations        Relations to create Restrictions from.
     360    *                         They can have any type key, as filtering is done inside this method.
     361    * @param nodeCreationMap  map providing the SegmentNode that has been created from a Node,
     362    *                         will not be modified; != null
     363    * @param waySegmentMap    map providing the Segments that have been created from a Way,
     364    *                         will not be modified; != null
     365    * @return                 Restrictions created from the Relations; != null, but may be empty
     366    */
     367    private Collection<Restriction> createRestrictionsFromTurnRestrictions(
     368            Iterable<R> relations,
     369            Map<N, SegmentNodeImpl> nodeCreationMap,
     370            Map<W, List<Segment>> waySegmentMap) {
     371
     372        assert relations != null && nodeCreationMap != null && waySegmentMap != null;
     373
     374        Collection<Restriction> results = new LinkedList<Restriction>();
     375
     376        for (R relation : relations) {
     377
     378            TagGroup tags = dataSource.getTagsR(relation);
     379
     380            if ("restriction".equals(tags.getValue("type"))
     381                    && tags.getValue("restriction") != null ) {
     382
     383                //evaluate relation
     384                if (tags.getValue("restriction").startsWith("no_")) {
     385                    results.addAll(createRestrictionsFromRestrictionRelation(relation, true, nodeCreationMap, waySegmentMap));
     386                } else if (tags.getValue("restriction").startsWith("only_")) {
     387                    results.addAll(createRestrictionsFromRestrictionRelation(relation, false, nodeCreationMap, waySegmentMap));
     388                }
     389
     390            }
     391        }
     392
     393        return results;
     394    }
     395
     396    @SuppressWarnings("unchecked") //several generic casts that are checked with isInstance
     397    private Collection<Restriction> createRestrictionsFromRestrictionRelation(
     398            R relation,
     399            boolean restrictive,
     400            Map<N, SegmentNodeImpl> nodeCreationMap,
     401            Map<W, List<Segment>> waySegmentMap) {
     402
     403        /* collect information about the relation */
     404
     405        W fromWay = null;
     406        Collection<N> viaNodes = new LinkedList<N>();
     407        Collection<W> viaWays = new LinkedList<W>();
     408        Collection<W> toWays = new LinkedList<W>();
     409
     410        for (M member : dataSource.getMembers(relation)) {
     411
     412            if ("from".equals(dataSource.getRole(member))) {
     413                if (fromWay != null || !dataSource.isWMember(member)) {
     414                    //broken restriction
     415                    return EMPTY_RESTRICTION_COLLECTION;
     416                } else {
     417                    fromWay = (W)dataSource.getMember(member);
     418                }
     419            } else if ("to".equals(dataSource.getRole(member))) {
     420                if (!dataSource.isWMember(member)) {
     421                    //broken restriction
     422                    return EMPTY_RESTRICTION_COLLECTION;
     423                } else {
     424                    toWays.add((W)dataSource.getMember(member));
     425                }
     426            } else if ("via".equals(dataSource.getRole(member))) {
     427                if (dataSource.isWMember(member)) {
     428                    viaWays.add((W)dataSource.getMember(member));
     429                } else if (dataSource.isNMember(member)) {
     430                    viaNodes.add((N)dataSource.getMember(member));
     431                }
     432            }
     433
     434        }
     435
     436        if (fromWay != null && toWays.size() > 0 &&
     437                (viaNodes.size() > 0 || viaWays.size() > 0)) {
     438
     439            return createRestrictionsFromRestrictionRelationMembers(
     440                    restrictive, nodeCreationMap, waySegmentMap,
     441                    fromWay, viaNodes, viaWays, toWays);
     442
     443        } else {
     444            return new ArrayList<Restriction>(0);
     445        }
     446    }
     447
     448    private Collection<Restriction> createRestrictionsFromRestrictionRelationMembers(
     449            boolean restrictive,
     450            Map<N, SegmentNodeImpl> nodeCreationMap, Map<W, List<Segment>> waySegmentMap,
     451            W fromWay, Collection<N> viaNodes, Collection<W> viaWays, Collection<W> toWays) {
     452
     453        Collection<SegmentNode> nodesCreatedFromViaNodes = new ArrayList<SegmentNode>(viaNodes.size());
     454        for (N viaNode : viaNodes) {
     455            if (nodeCreationMap.containsKey(viaNode)) {
     456                nodesCreatedFromViaNodes.add(nodeCreationMap.get(viaNode));
     457            }
     458        }
     459
     460        /* check completeness of restriction to avoid dealing with incomplete restriction info */
     461
     462        if (!waySegmentMap.containsKey(fromWay)) {
     463            //broken restriction
     464            return EMPTY_RESTRICTION_COLLECTION;
     465        }
     466
     467        for (W viaWay : viaWays) {
     468            if (!waySegmentMap.containsKey(viaWay)) {
     469                //broken restriction
     470                return EMPTY_RESTRICTION_COLLECTION;
     471            }
     472        }
     473
     474        for (W toWay : toWays) {
     475            if (!waySegmentMap.containsKey(toWay)) {
     476                //broken restriction
     477                return EMPTY_RESTRICTION_COLLECTION;
     478            }
     479        }
     480
     481        /* find all via segments:
     482        * via segments are segments created from via ways
     483        * or segments starting and ending with nodes created from via nodes */
     484
     485        ArrayList<Segment> viaSegments = new ArrayList<Segment>();
     486
     487        for (W viaWay : viaWays) {
     488            viaSegments.addAll(waySegmentMap.get(viaWay));
     489        }
     490
     491        for (SegmentNode nodeCreatedFromViaNode : nodesCreatedFromViaNodes) {
     492            for (Segment segment : nodeCreatedFromViaNode.getOutboundSegments()) {
     493                if (nodesCreatedFromViaNodes.contains(segment.getNode2())) {
     494                    viaSegments.add(segment);
     495                }
     496            }
     497        }
     498
     499        viaSegments.trimToSize();
     500
     501        /* create a set with all nodes that are based on via members */
     502
     503        Set<SegmentNode> nodesCreatedFromViaMembers
     504        = new HashSet<SegmentNode>(nodesCreatedFromViaNodes);
     505
     506        for (W viaWay : viaWays) {
     507            for (N viaWayNode : dataSource.getNodes(viaWay)) {
     508                nodesCreatedFromViaMembers.add(nodeCreationMap.get(viaWayNode));
     509            }
     510        }
     511
     512        /*
     513        * find from segment and to segments:
     514        * Such a segment contains a node based on a via member.
     515        * Each way should contain only one possible segment
     516        * connecting to via members (due to splitting).
     517        */
     518
     519        Segment fromSegment = null;
     520        Collection<Segment> toSegments = new ArrayList<Segment>();
     521
     522        for (Segment possibleFromSegment : waySegmentMap.get(fromWay)) {
     523            if (nodesCreatedFromViaMembers.contains(possibleFromSegment.getNode2())) {
     524
     525                if (fromSegment == null) {
     526                    fromSegment = possibleFromSegment;
     527                } else {
     528                    //broken restriction
     529                    return EMPTY_RESTRICTION_COLLECTION;
     530                }
     531
     532            }
     533        }
     534        if (fromSegment == null) {
     535            //broken restriction
     536            return EMPTY_RESTRICTION_COLLECTION;
     537        }
     538
     539        if (restrictive) {
     540
     541            for (W toWay : toWays) {
     542                if (waySegmentMap.containsKey(toWay)) {
     543                    Segment toSegment = null;
     544                    for (Segment possibleToSegment : waySegmentMap.get(toWay)) {
     545                        if (nodesCreatedFromViaMembers.contains(possibleToSegment.getNode1())) {
     546
     547                            if (toSegment == null) {
     548                                toSegment = possibleToSegment;
     549                            } else {
     550                                //broken restriction
     551                                return EMPTY_RESTRICTION_COLLECTION;
     552                            }
     553
     554                        }
     555                    }
     556                    if (toSegment == null) {
     557                        //broken restriction
     558                        return EMPTY_RESTRICTION_COLLECTION;
     559                    } else {
     560                        toSegments.add(toSegment);
     561                    }
     562                }
     563            }
     564
     565        } else { //!restrictive
     566
     567            /* forbidden "to" segments are all segments that start at a "via" node
     568            * and are neither a via segment nor created from an allowed "to" way */
     569
     570            for (SegmentNode toStartingNode : nodesCreatedFromViaMembers) {
     571                for (Segment outboundSegment : toStartingNode.getOutboundSegments()) {
     572
     573                    if (!viaSegments.contains(outboundSegment)) {
     574
     575                        boolean isAllowed = false;
     576
     577                        for (W toWay : toWays) {
     578                            if (waySegmentMap.get(toWay).contains(outboundSegment)) {
     579                                isAllowed = true;
     580                                break;
     581                            }
     582                        }
     583
     584                        if (!isAllowed) {
     585                            toSegments.add(outboundSegment);
     586                        }
     587
     588                    }
     589
     590                }
     591            }
     592
     593        }
     594
     595        /* create restriction */
     596
     597        Collection<Restriction> results = new ArrayList<Restriction>(1);
     598        results.add(new RestrictionImpl(fromSegment, viaSegments, toSegments));
     599        return results;
     600    }
     601
     602    /**
     603    * creates Restrictions from barrier nodes (nodes that are considered impassable by the
     604    * {@link #accessEvaluator}). These restrictions prevent moving from a segment before the
     605    * barrier node to a segment after the barrier node.
     606    *
     607    * @param nodeCreationMap  map providing the SegmentNode that has been created from a node,
     608    *                         will not be modified; != null
     609    * @param waySegmentMap    map providing the Segments that have been created from a way,
     610    *                         will not be modified; != null
     611    * @return                 Restrictions created from barrier nodes; != null, but may be empty
     612    */
     613    private Collection<Restriction> createRestrictionsFromBarrierNodes(
     614            Map<N, SegmentNodeImpl> nodeCreationMap,
     615            Map<W, List<Segment>> waySegmentMap) {
     616
     617        assert nodeCreationMap != null;
     618        assert waySegmentMap != null;
     619
     620        Collection<Restriction> results = new LinkedList<Restriction>();
     621
     622        for (N node : nodeCreationMap.keySet()) {
     623
     624            if (!accessEvaluator.nodeUsable(node, nodeCreationMap.get(node).getProperties())) {
     625
     626                SegmentNode barrierNode = nodeCreationMap.get(node);
     627
     628                for (Segment inboundSegment : barrierNode.getInboundSegments()) {
     629                    for (Segment outboundSegment : barrierNode.getOutboundSegments()) {
     630                        results.add(new RestrictionImpl(inboundSegment, EMPTY_SEGMENT_LIST, Arrays.asList(outboundSegment)));
     631                    }
     632                }
     633
     634            }
     635
     636        }
     637
     638        return results;
     639    }
     640
     641    /**
     642    * determines the values of all RoadPropertyTypes from {@link #properties} for a way and
     643    * creates a map with the types that have non-null values as keys, property values as content
     644    */
     645    private Map<RoadPropertyType<?>, Object> getWayPropertyMap(W way, boolean forward) {
     646        Map<RoadPropertyType<?>, Object> propertyValues;
     647        propertyValues = new HashMap<RoadPropertyType<?>, Object>();
     648        for (RoadPropertyType<?> property : properties) {
     649            Object value = property.evaluateW(way, forward, accessParameters, dataSource);
     650            if (value != null) {
     651                propertyValues.put(property, value);
     652            }
     653        }
     654        return propertyValues;
     655    }
     656
     657    /**
     658    * determines the values of all RoadPropertyTypes from {@link #properties} for a node and
     659    * creates a map with the types that have non-null values as keys, property values as content
     660    */
     661    private Map<RoadPropertyType<?>, Object> getNodePropertyMap(N node) {
     662        Map<RoadPropertyType<?>, Object> propertyValues;
     663        propertyValues = new HashMap<RoadPropertyType<?>, Object>();
     664        for (RoadPropertyType<?> property : properties) {
     665            Object value = property.evaluateN(node, accessParameters, dataSource);
     666            if (value != null) {
     667                propertyValues.put(property, value);
     668            }
     669        }
     670        return propertyValues;
     671    }
     672
     673    public void update(DataSource<?, ?, ?, ?> dataSource) {
     674        assert this.dataSource == dataSource;
     675        updateData();
     676    }
     677
     678    public void addObserver(TransitionStructureObserver observer) {
     679        observers.add(observer);
     680    }
     681
     682    public void deleteObserver(TransitionStructureObserver observer) {
     683        observers.remove(observer);
     684    }
     685
     686    protected void notifyObservers() {
     687        for (TransitionStructureObserver observer : observers) {
     688            observer.update(this);
     689        }
     690    }
    691691
    692692}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/transition/Restriction.java

    r16520 r23189  
    1010public interface Restriction {
    1111
    12         /**
    13         * returns the starting segment that will trigger the restriction when used;
    14         * != null
    15         */
    16         public Segment getFrom();
     12    /**
     13    * returns the starting segment that will trigger the restriction when used;
     14    * != null
     15    */
     16    public Segment getFrom();
    1717
    18         /**
    19         * returns the "via" segments.
    20         * The restriction will remain active as long as only via segments are used.
    21         *
    22         * @return  unmodifiable collection of segments; != null
    23         */
    24         public Collection<Segment> getVias();
     18    /**
     19    * returns the "via" segments.
     20    * The restriction will remain active as long as only via segments are used.
     21    *
     22    * @return  unmodifiable collection of segments; != null
     23    */
     24    public Collection<Segment> getVias();
    2525
    26         /**
    27         * returns the forbidden "to" segments.
    28         * The restriction prevents leaving the via segment set by using one of the to segments.
    29         *
    30         * @return  unmodifiable collection of segments; != null
    31         */
    32         public Collection<Segment> getTos();
     26    /**
     27    * returns the forbidden "to" segments.
     28    * The restriction prevents leaving the via segment set by using one of the to segments.
     29    *
     30    * @return  unmodifiable collection of segments; != null
     31    */
     32    public Collection<Segment> getTos();
    3333
    3434}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/transition/Segment.java

    r16520 r23189  
    66public interface Segment extends TransitionStructureElement {
    77
    8         /**
    9         * returns the node this segment starts at; != null
    10         */
    11         public SegmentNode getNode1();
     8    /**
     9    * returns the node this segment starts at; != null
     10    */
     11    public SegmentNode getNode1();
    1212
    13         /**
    14         * returns the node this segment leads to; != null
    15         */
    16         public SegmentNode getNode2();
     13    /**
     14    * returns the node this segment leads to; != null
     15    */
     16    public SegmentNode getNode2();
    1717
    1818}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/transition/SegmentNode.java

    r16520 r23189  
    88public interface SegmentNode extends TransitionStructureElement {
    99
    10         /** returns the node's latitude */
    11         public double getLat();
     10    /** returns the node's latitude */
     11    public double getLat();
    1212
    13         /** returns the node's longitude */
    14         public double getLon();
     13    /** returns the node's longitude */
     14    public double getLon();
    1515
    16         /** returns all segments that end at this node */
    17         Collection<Segment> getInboundSegments();
     16    /** returns all segments that end at this node */
     17    Collection<Segment> getInboundSegments();
    1818
    19         /** returns all segments that start at this node */
    20         Collection<Segment> getOutboundSegments();
     19    /** returns all segments that start at this node */
     20    Collection<Segment> getOutboundSegments();
    2121
    2222}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/transition/TransitionStructure.java

    r16520 r23189  
    99public interface TransitionStructure {
    1010
    11         public Collection<SegmentNode> getNodes();
    12         public Collection<Segment> getSegments();
    13         public Collection<Restriction> getRestrictions();
     11    public Collection<SegmentNode> getNodes();
     12    public Collection<Segment> getSegments();
     13    public Collection<Restriction> getRestrictions();
    1414
    15         /**
    16         * adds an observer.
    17         * Does nothing if the parameter is already an observer of this TransitionStructure.
    18         *
    19         * @param observer  observer object, != null
    20         */
    21         public void addObserver(TransitionStructureObserver observer);
     15    /**
     16    * adds an observer.
     17    * Does nothing if the parameter is already an observer of this TransitionStructure.
     18    *
     19    * @param observer  observer object, != null
     20    */
     21    public void addObserver(TransitionStructureObserver observer);
    2222
    23         /**
    24         * deletes an observer that has been added using {@link #addObserver(TransitionStructureObserver)}.
    25         * Does nothing if the parameter isn't currently an observer of this TransitionStructure.
    26         *
    27         * @param observer  observer object, != null
    28         */
    29         public void deleteObserver(TransitionStructureObserver observer);
     23    /**
     24    * deletes an observer that has been added using {@link #addObserver(TransitionStructureObserver)}.
     25    * Does nothing if the parameter isn't currently an observer of this TransitionStructure.
     26    *
     27    * @param observer  observer object, != null
     28    */
     29    public void deleteObserver(TransitionStructureObserver observer);
    3030
    3131}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/transition/TransitionStructureElement.java

    r16520 r23189  
    1010public interface TransitionStructureElement {
    1111
    12         /**
    13         * returns the types of this object's properties
    14         *
    15         * @return  property type collection; != null
    16         */
    17         public Collection<RoadPropertyType<?>> getAvailableProperties();
     12    /**
     13    * returns the types of this object's properties
     14    *
     15    * @return  property type collection; != null
     16    */
     17    public Collection<RoadPropertyType<?>> getAvailableProperties();
    1818
    19         /**
    20         * returns the value of a property for this object
    21         *
    22         * @param propertyType   property type to return value for; != null
    23         * @return property      value of the property for this segment; null if not available
    24         */
    25         public <P> P getPropertyValue(RoadPropertyType<P> propertyType);
     19    /**
     20    * returns the value of a property for this object
     21    *
     22    * @param propertyType   property type to return value for; != null
     23    * @return property      value of the property for this segment; null if not available
     24    */
     25    public <P> P getPropertyValue(RoadPropertyType<P> propertyType);
    2626
    2727}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/transition/TransitionStructureObserver.java

    r16520 r23189  
    77public interface TransitionStructureObserver {
    88
    9         /**
    10         * informs this observer about changes in an observed transition structure
    11         * @param transitionStructure  observed transition structure that has changed; != null
    12         */
    13         public void update(TransitionStructure transitionStructure);
     9    /**
     10    * informs this observer about changes in an observed transition structure
     11    * @param transitionStructure  observed transition structure that has changed; != null
     12    */
     13    public void update(TransitionStructure transitionStructure);
    1414
    1515}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/util/GraphUtil.java

    r16520 r23189  
    1111public final class GraphUtil {
    1212
    13         /** prevents instantiation */
    14         private GraphUtil() { }
     13    /** prevents instantiation */
     14    private GraphUtil() { }
    1515
    16         /**
    17         * checks whether a node is an "end node"
    18         * (a node whose {@link SegmentNode} is connected to at most one other {@link SegmentNode})
    19         */
    20         public static final boolean isEndNode(GraphNode node) {
     16    /**
     17    * checks whether a node is an "end node"
     18    * (a node whose {@link SegmentNode} is connected to at most one other {@link SegmentNode})
     19    */
     20    public static final boolean isEndNode(GraphNode node) {
    2121
    22                 SegmentNode ownSegmentNode = node.getSegmentNode();
     22        SegmentNode ownSegmentNode = node.getSegmentNode();
    2323
    24                 SegmentNode connectedNode = null;
     24        SegmentNode connectedNode = null;
    2525
    26                 for (Segment inboundSegment : node.getSegmentNode().getInboundSegments()) {
    27                         SegmentNode otherSegmentNode = inboundSegment.getNode1();
    28                         if (otherSegmentNode != ownSegmentNode) {
    29                                 if (connectedNode == null) {
    30                                         connectedNode = otherSegmentNode;
    31                                 } else if (connectedNode != otherSegmentNode) {
    32                                         return false;
    33                                 }
    34                         }
    35                 }
     26        for (Segment inboundSegment : node.getSegmentNode().getInboundSegments()) {
     27            SegmentNode otherSegmentNode = inboundSegment.getNode1();
     28            if (otherSegmentNode != ownSegmentNode) {
     29                if (connectedNode == null) {
     30                    connectedNode = otherSegmentNode;
     31                } else if (connectedNode != otherSegmentNode) {
     32                    return false;
     33                }
     34            }
     35        }
    3636
    37                 for (Segment outboundSegment : node.getSegmentNode().getOutboundSegments()) {
    38                         SegmentNode otherSegmentNode = outboundSegment.getNode2();
    39                         if (otherSegmentNode != ownSegmentNode) {
    40                                 if (connectedNode == null) {
    41                                         connectedNode = otherSegmentNode;
    42                                 } else if (connectedNode != otherSegmentNode) {
    43                                         return false;
    44                                 }
    45                         }
    46                 }
     37        for (Segment outboundSegment : node.getSegmentNode().getOutboundSegments()) {
     38            SegmentNode otherSegmentNode = outboundSegment.getNode2();
     39            if (otherSegmentNode != ownSegmentNode) {
     40                if (connectedNode == null) {
     41                    connectedNode = otherSegmentNode;
     42                } else if (connectedNode != otherSegmentNode) {
     43                    return false;
     44                }
     45            }
     46        }
    4747
    48                 return true;
     48        return true;
    4949
    50         }
     50    }
    5151
    5252}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/util/TagCondition.java

    r16520 r23189  
    99public interface TagCondition {
    1010
    11         /**
    12         * returns true if the tags match the condition
    13         *
    14         * @param tags  tags to check against the condition; != null
    15         */
    16         boolean matches(TagGroup tags);
     11    /**
     12    * returns true if the tags match the condition
     13    *
     14    * @param tags  tags to check against the condition; != null
     15    */
     16    boolean matches(TagGroup tags);
    1717
    1818}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/util/TagConditionLogic.java

    r16520 r23189  
    1111public final class TagConditionLogic {
    1212
    13         /** prevents instantiation */
    14         private TagConditionLogic(){ }
    15 
    16         /**
    17         * creates a condition that is fulfilled if the set of tags contains a given tag
    18         *
    19         * @param tag  tag that must be in the tag collection; != null
    20         */
    21         public static TagCondition tag(final Tag tag) {
    22                 assert tag != null;
    23                 return new TagCondition() {
    24                         public boolean matches(TagGroup tags) {
    25                                 return tags.contains(tag);
    26                         }
    27                         @Override
    28                         public String toString() {
    29                                 return tag.toString();
    30                         }
    31                 };
    32         }
    33 
    34         /**
    35         * creates a condition that is fulfilled if the set of tags contains a tag with the given key
    36         *
    37         * @param key  the key to look for; != null
    38         */
    39         public static TagCondition key(final String key) {
    40                 assert key != null;
    41                 return new TagCondition() {
    42                         public boolean matches(TagGroup tags) {
    43                                 return tags.containsKey(key);
    44                         }
    45                         @Override
    46                         public String toString() {
    47                                 return key;
    48                         }
    49                 };
    50         }
    51 
    52         /**
    53         * combines conditions using a boolean "and"
    54         *
    55         * @param condition   first condition; != null
    56         * @param conditions  more conditions; each != null
    57         */
    58         public static TagCondition and(final TagCondition condition, final TagCondition... conditions) {
    59                 return new TagCondition() {
    60                         public boolean matches(TagGroup tags) {
    61                                 for (TagCondition c : conditions) {
    62                                         if (!c.matches(tags)) {
    63                                                 return false;
    64                                         }
    65                                 }
    66                                 return condition.matches(tags);
    67                         }
    68                         @Override
    69                         public String toString() {
    70                                 StringBuilder result = new StringBuilder();
    71                                 result.append("(");
    72                                 result.append(condition);
    73                                 for (TagCondition c : conditions) {
    74                                         result.append(" && ");
    75                                         result.append(c);
    76                                 }
    77                                 result.append(")");
    78                                 return result.toString();
    79                         }
    80                 };
    81         }
    82 
    83         /**
    84         * combines conditions using a boolean "and"
    85         *
    86         * @param conditions   collection of conditions, must contain at least one element; != null
    87         */
    88         public static TagCondition and(final Collection<TagCondition> conditions) {
    89                 if (conditions.size() == 0) {
    90                         throw new IllegalArgumentException("collection must contain at least one condition");
    91                 }
    92                 return new TagCondition() {
    93                         public boolean matches(TagGroup tags) {
    94                                 for (TagCondition c : conditions) {
    95                                         if (!c.matches(tags)) {
    96                                                 return false;
    97                                         }
    98                                 }
    99                                 return true;
    100                         }
    101                         @Override
    102                         public String toString() {
    103                                 StringBuilder result = new StringBuilder();
    104                                 result.append("(");
    105                                 boolean firstCondition = true;
    106                                 for (TagCondition c : conditions) {
    107                                         if (!firstCondition) {
    108                                                 result.append(" && ");
    109                                         }
    110                                         firstCondition = false;
    111                                         result.append(c);
    112                                 }
    113                                 result.append(")");
    114                                 return result.toString();
    115                         }
    116                 };
    117         }
    118 
    119         /**
    120         * combines conditions using a boolean "or"
    121         *
    122         * @param condition   first condition; != null
    123         * @param conditions  more conditions; each != null
    124         */
    125         public static TagCondition or(final TagCondition condition, final TagCondition... conditions) {
    126                 return new TagCondition() {
    127                         public boolean matches(TagGroup tags) {
    128                                 for (TagCondition c : conditions) {
    129                                         if (c.matches(tags)) {
    130                                                 return true;
    131                                         }
    132                                 }
    133                                 return condition.matches(tags);
    134                         }
    135                         @Override
    136                         public String toString() {
    137                                 StringBuilder result = new StringBuilder();
    138                                 result.append("(");
    139                                 result.append(condition);
    140                                 for (TagCondition c : conditions) {
    141                                         result.append(" || ");
    142                                         result.append(c);
    143                                 }
    144                                 result.append(")");
    145                                 return result.toString();
    146                         }
    147                 };
    148         }
    149 
    150         /**
    151         * combines conditions using a boolean "or"
    152         *
    153         * @param conditions   collection of conditions, must contain at least one element; != null
    154         */
    155         public static TagCondition or(final Collection<TagCondition> conditions) {
    156                 if (conditions.size() == 0) {
    157                         throw new IllegalArgumentException("collection must contain at least one condition");
    158                 }
    159                 return new TagCondition() {
    160                         public boolean matches(TagGroup tags) {
    161                                 for (TagCondition c : conditions) {
    162                                         if (c.matches(tags)) {
    163                                                 return true;
    164                                         }
    165                                 }
    166                                 return false;
    167                         }
    168                         @Override
    169                         public String toString() {
    170                                 StringBuilder result = new StringBuilder();
    171                                 result.append("(");
    172                                 boolean firstCondition = true;
    173                                 for (TagCondition c : conditions) {
    174                                         if (!firstCondition) {
    175                                                 result.append(" || ");
    176                                         }
    177                                         firstCondition = false;
    178                                         result.append(c);
    179                                 }
    180                                 result.append(")");
    181                                 return result.toString();
    182                         }
    183                 };
    184         }
    185 
    186         /**
    187         * inverts a condition
    188         *
    189         * @param condition  condition to invert, != null
    190         */
    191         public static TagCondition not(final TagCondition condition) {
    192                 return new TagCondition() {
    193                         public boolean matches(TagGroup tags) {
    194                                 return !condition.matches(tags);
    195                         }
    196                         @Override
    197                         public String toString() {
    198                                 return "!" + condition;
    199                         }
    200                 };
    201         }
     13    /** prevents instantiation */
     14    private TagConditionLogic(){ }
     15
     16    /**
     17    * creates a condition that is fulfilled if the set of tags contains a given tag
     18    *
     19    * @param tag  tag that must be in the tag collection; != null
     20    */
     21    public static TagCondition tag(final Tag tag) {
     22        assert tag != null;
     23        return new TagCondition() {
     24            public boolean matches(TagGroup tags) {
     25                return tags.contains(tag);
     26            }
     27            @Override
     28            public String toString() {
     29                return tag.toString();
     30            }
     31        };
     32    }
     33
     34    /**
     35    * creates a condition that is fulfilled if the set of tags contains a tag with the given key
     36    *
     37    * @param key  the key to look for; != null
     38    */
     39    public static TagCondition key(final String key) {
     40        assert key != null;
     41        return new TagCondition() {
     42            public boolean matches(TagGroup tags) {
     43                return tags.containsKey(key);
     44            }
     45            @Override
     46            public String toString() {
     47                return key;
     48            }
     49        };
     50    }
     51
     52    /**
     53    * combines conditions using a boolean "and"
     54    *
     55    * @param condition   first condition; != null
     56    * @param conditions  more conditions; each != null
     57    */
     58    public static TagCondition and(final TagCondition condition, final TagCondition... conditions) {
     59        return new TagCondition() {
     60            public boolean matches(TagGroup tags) {
     61                for (TagCondition c : conditions) {
     62                    if (!c.matches(tags)) {
     63                        return false;
     64                    }
     65                }
     66                return condition.matches(tags);
     67            }
     68            @Override
     69            public String toString() {
     70                StringBuilder result = new StringBuilder();
     71                result.append("(");
     72                result.append(condition);
     73                for (TagCondition c : conditions) {
     74                    result.append(" && ");
     75                    result.append(c);
     76                }
     77                result.append(")");
     78                return result.toString();
     79            }
     80        };
     81    }
     82
     83    /**
     84    * combines conditions using a boolean "and"
     85    *
     86    * @param conditions   collection of conditions, must contain at least one element; != null
     87    */
     88    public static TagCondition and(final Collection<TagCondition> conditions) {
     89        if (conditions.size() == 0) {
     90            throw new IllegalArgumentException("collection must contain at least one condition");
     91        }
     92        return new TagCondition() {
     93            public boolean matches(TagGroup tags) {
     94                for (TagCondition c : conditions) {
     95                    if (!c.matches(tags)) {
     96                        return false;
     97                    }
     98                }
     99                return true;
     100            }
     101            @Override
     102            public String toString() {
     103                StringBuilder result = new StringBuilder();
     104                result.append("(");
     105                boolean firstCondition = true;
     106                for (TagCondition c : conditions) {
     107                    if (!firstCondition) {
     108                        result.append(" && ");
     109                    }
     110                    firstCondition = false;
     111                    result.append(c);
     112                }
     113                result.append(")");
     114                return result.toString();
     115            }
     116        };
     117    }
     118
     119    /**
     120    * combines conditions using a boolean "or"
     121    *
     122    * @param condition   first condition; != null
     123    * @param conditions  more conditions; each != null
     124    */
     125    public static TagCondition or(final TagCondition condition, final TagCondition... conditions) {
     126        return new TagCondition() {
     127            public boolean matches(TagGroup tags) {
     128                for (TagCondition c : conditions) {
     129                    if (c.matches(tags)) {
     130                        return true;
     131                    }
     132                }
     133                return condition.matches(tags);
     134            }
     135            @Override
     136            public String toString() {
     137                StringBuilder result = new StringBuilder();
     138                result.append("(");
     139                result.append(condition);
     140                for (TagCondition c : conditions) {
     141                    result.append(" || ");
     142                    result.append(c);
     143                }
     144                result.append(")");
     145                return result.toString();
     146            }
     147        };
     148    }
     149
     150    /**
     151    * combines conditions using a boolean "or"
     152    *
     153    * @param conditions   collection of conditions, must contain at least one element; != null
     154    */
     155    public static TagCondition or(final Collection<TagCondition> conditions) {
     156        if (conditions.size() == 0) {
     157            throw new IllegalArgumentException("collection must contain at least one condition");
     158        }
     159        return new TagCondition() {
     160            public boolean matches(TagGroup tags) {
     161                for (TagCondition c : conditions) {
     162                    if (c.matches(tags)) {
     163                        return true;
     164                    }
     165                }
     166                return false;
     167            }
     168            @Override
     169            public String toString() {
     170                StringBuilder result = new StringBuilder();
     171                result.append("(");
     172                boolean firstCondition = true;
     173                for (TagCondition c : conditions) {
     174                    if (!firstCondition) {
     175                        result.append(" || ");
     176                    }
     177                    firstCondition = false;
     178                    result.append(c);
     179                }
     180                result.append(")");
     181                return result.toString();
     182            }
     183        };
     184    }
     185
     186    /**
     187    * inverts a condition
     188    *
     189    * @param condition  condition to invert, != null
     190    */
     191    public static TagCondition not(final TagCondition condition) {
     192        return new TagCondition() {
     193            public boolean matches(TagGroup tags) {
     194                return !condition.matches(tags);
     195            }
     196            @Override
     197            public String toString() {
     198                return "!" + condition;
     199            }
     200        };
     201    }
    202202
    203203}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/util/ValueStringParser.java

    r20243 r23189  
    66public final class ValueStringParser {
    77
    8         /** prevents instantiation */
    9         private ValueStringParser() { }
    10 
    11         /** pattern that splits into a part before and after a decimal point */
    12         private static final Pattern DEC_POINT_PATTERN = Pattern.compile("^(\\-?\\d+)\\.(\\d+)$");
    13 
    14         public static final Float parseOsmDecimal(String value, boolean allowNegative) {
    15 
    16                 /* positive integer */
    17 
    18                 try {
    19 
    20                         int weight = Integer.parseInt(value);
    21                         if (weight >= 0 || allowNegative) {
    22                                 return (float)weight;
    23                         }
    24 
    25                 } catch (NumberFormatException nfe) {}
    26 
    27                 /* positive number with decimal point */
    28 
    29                 Matcher matcher = DEC_POINT_PATTERN.matcher(value);
    30 
    31                 if (matcher.matches()) {
    32 
    33                         String stringBeforePoint = matcher.group(1);
    34                         String stringAfterPoint = matcher.group(2);
    35 
    36                         if (stringBeforePoint.length() > 0 || stringAfterPoint.length() > 0) {
    37 
    38                                 try {
    39 
    40                                         float beforePoint = Integer.parseInt(stringBeforePoint);
    41                                         float afterPoint = Integer.parseInt(stringAfterPoint);
    42 
    43                                         double result = Math.signum(beforePoint) *
    44                                         (Math.abs(beforePoint)
    45                                                         + Math.pow(10, -stringAfterPoint.length()) * afterPoint);
    46 
    47                                         if (result >= 0 || allowNegative) {
    48                                                 return (float)result;
    49                                         }
    50 
    51                                 } catch (NumberFormatException nfe) {}
    52 
    53                         }
    54                 }
    55 
    56                 return null;
    57         }
    58 
    59         private static final Pattern KMH_PATTERN = Pattern.compile("^(\\d+)\\s*km/h$");
    60         private static final Pattern MPH_PATTERN = Pattern.compile("^(\\d+)\\s*mph$");
    61 
    62         private static final float KM_PER_MILE = 1.609344f;
    63 
    64         /**
    65         * parses a speed value given e.g. for the "maxspeed" key.
    66         *
    67         * @return  speed in km/h; null if value had syntax errors
    68         */
    69         public static final Float parseSpeed(String value) {
    70 
    71                 /* try numeric speed (implied km/h) */
    72 
    73                 Float speed = parseOsmDecimal(value, false);
    74                 if (speed != null) {
    75                         return speed;
    76                 }
    77 
    78                 /* try km/h speed */
    79 
    80                 Matcher kmhMatcher = KMH_PATTERN.matcher(value);
    81                 if (kmhMatcher.matches()) {
    82                         String kmhString = kmhMatcher.group(1);
    83                         try {
    84                                 return (float)Integer.parseInt(kmhString);
    85                         } catch (NumberFormatException nfe) {}
    86                 }
    87 
    88                 /* try mph speed */
    89 
    90                 Matcher mphMatcher = MPH_PATTERN.matcher(value);
    91                 if (mphMatcher.matches()) {
    92                         String mphString = mphMatcher.group(1);
    93                         try {
    94                                 int mph = Integer.parseInt(mphString);
    95                                 return KM_PER_MILE * mph;
    96                         } catch (NumberFormatException nfe) {}
    97                 }
    98 
    99                 /* all possibilities failed */
    100 
    101                 return null;
    102         }
    103 
    104         private static final Pattern M_PATTERN = Pattern.compile("^([\\d\\.]+)\\s*m$");
    105         private static final Pattern KM_PATTERN = Pattern.compile("^([\\d\\.]+)\\s*km$");
    106         private static final Pattern MI_PATTERN = Pattern.compile("^([\\d\\.]+)\\s*mi$");
    107         private static final Pattern FEET_INCHES_PATTERN = Pattern.compile("^([\\d]+)'\\s*([\\d]+)\"");
    108 
    109         private static final double M_PER_MI = 1609.344;
    110         private static final double M_PER_INCH = 0.0254f;
    111 
    112         /**
    113         * parses a measure value given e.g. for the "width" or "length" key.
    114         *
    115         * @return  measure in m; null if value had syntax errors
    116         */
    117         public static final Float parseMeasure(String value) {
    118 
    119                 /* try numeric measure (implied m) */
    120 
    121                 Float measure = parseOsmDecimal(value, false);
    122                 if (measure != null) {
    123                         return measure;
    124                 }
    125 
    126                 /* try m measure */
    127 
    128                 Matcher mMatcher = M_PATTERN.matcher(value);
    129                 if (mMatcher.matches()) {
    130                         String mString = mMatcher.group(1);
    131                         return parseOsmDecimal(mString, false);
    132                 }
    133 
    134                 /* try km measure */
    135 
    136                 Matcher kmMatcher = KM_PATTERN.matcher(value);
    137                 if (kmMatcher.matches()) {
    138                         String kmString = kmMatcher.group(1);
    139                         float km = parseOsmDecimal(kmString, false);
    140                         return 1000 * km;
    141                 }
    142 
    143                 /* try mi measure */
    144 
    145                 Matcher miMatcher = MI_PATTERN.matcher(value);
    146                 if (miMatcher.matches()) {
    147                         String miString = miMatcher.group(1);
    148                         float mi = parseOsmDecimal(miString, false);
    149                         return (float)(M_PER_MI * mi);
    150                 }
    151 
    152                 /* try feet/inches measure */
    153 
    154                 Matcher feetInchesMatcher = FEET_INCHES_PATTERN.matcher(value);
    155                 if (feetInchesMatcher.matches()) {
    156                         String feetString = feetInchesMatcher.group(1);
    157                         String inchesString = feetInchesMatcher.group(2);
    158                         try {
    159                                 int feet = Integer.parseInt(feetString);
    160                                 int inches = Integer.parseInt(inchesString);
    161                                 if (feet >= 0 && inches >= 0 && inches < 12) {
    162                                         return (float)(M_PER_INCH * (12 * feet + inches));
    163                                 }
    164                         } catch (NumberFormatException nfe) {}
    165                 }
    166 
    167                 /* all possibilities failed */
    168 
    169                 return null;
    170         }
    171 
    172         private static final Pattern T_PATTERN = Pattern.compile("^([\\d\\.]+)\\s*t$");
    173 
    174         /**
    175         * parses a weight value given e.g. for the "maxweight" or "maxaxleload" key.
    176         *
    177         * @return  weight in t; null if value had syntax errors
    178         */
    179         public static Float parseWeight(String value) {
    180 
    181                 /* try numeric weight (implied t) */
    182 
    183                 Float weight = parseOsmDecimal(value, false);
    184                 if (weight != null) {
    185                         return weight;
    186                 }
    187 
    188                 /* try t weight */
    189 
    190                 Matcher tMatcher = T_PATTERN.matcher(value);
    191                 if (tMatcher.matches()) {
    192                         String tString = tMatcher.group(1);
    193                         return parseOsmDecimal(tString, false);
    194                 }
    195 
    196                 /* all possibilities failed */
    197 
    198                 return null;
    199 
    200         }
    201 
    202         private static final Pattern INCLINE_PATTERN = Pattern.compile("^(\\-?\\d+(?:\\.\\d+)?)\\s*%$");
    203 
    204         /**
    205         * parses an incline value as given for the "incline" key.
    206         *
    207         * @return  incline in percents; null if value had syntax errors
    208         */
    209         public static final Float parseIncline(String value) {
    210 
    211                 Matcher inclineMatcher = INCLINE_PATTERN.matcher(value);
    212                 if (inclineMatcher.matches()) {
    213                         String inclineString = inclineMatcher.group(1);
    214                         return parseOsmDecimal(inclineString, true);
    215                 }
    216 
    217                 return null;
    218         }
     8    /** prevents instantiation */
     9    private ValueStringParser() { }
     10
     11    /** pattern that splits into a part before and after a decimal point */
     12    private static final Pattern DEC_POINT_PATTERN = Pattern.compile("^(\\-?\\d+)\\.(\\d+)$");
     13
     14    public static final Float parseOsmDecimal(String value, boolean allowNegative) {
     15
     16        /* positive integer */
     17
     18        try {
     19
     20            int weight = Integer.parseInt(value);
     21            if (weight >= 0 || allowNegative) {
     22                return (float)weight;
     23            }
     24
     25        } catch (NumberFormatException nfe) {}
     26
     27        /* positive number with decimal point */
     28
     29        Matcher matcher = DEC_POINT_PATTERN.matcher(value);
     30
     31        if (matcher.matches()) {
     32
     33            String stringBeforePoint = matcher.group(1);
     34            String stringAfterPoint = matcher.group(2);
     35
     36            if (stringBeforePoint.length() > 0 || stringAfterPoint.length() > 0) {
     37
     38                try {
     39
     40                    float beforePoint = Integer.parseInt(stringBeforePoint);
     41                    float afterPoint = Integer.parseInt(stringAfterPoint);
     42
     43                    double result = Math.signum(beforePoint) *
     44                    (Math.abs(beforePoint)
     45                            + Math.pow(10, -stringAfterPoint.length()) * afterPoint);
     46
     47                    if (result >= 0 || allowNegative) {
     48                        return (float)result;
     49                    }
     50
     51                } catch (NumberFormatException nfe) {}
     52
     53            }
     54        }
     55
     56        return null;
     57    }
     58
     59    private static final Pattern KMH_PATTERN = Pattern.compile("^(\\d+)\\s*km/h$");
     60    private static final Pattern MPH_PATTERN = Pattern.compile("^(\\d+)\\s*mph$");
     61
     62    private static final float KM_PER_MILE = 1.609344f;
     63
     64    /**
     65    * parses a speed value given e.g. for the "maxspeed" key.
     66    *
     67    * @return  speed in km/h; null if value had syntax errors
     68    */
     69    public static final Float parseSpeed(String value) {
     70
     71        /* try numeric speed (implied km/h) */
     72
     73        Float speed = parseOsmDecimal(value, false);
     74        if (speed != null) {
     75            return speed;
     76        }
     77
     78        /* try km/h speed */
     79
     80        Matcher kmhMatcher = KMH_PATTERN.matcher(value);
     81        if (kmhMatcher.matches()) {
     82            String kmhString = kmhMatcher.group(1);
     83            try {
     84                return (float)Integer.parseInt(kmhString);
     85            } catch (NumberFormatException nfe) {}
     86        }
     87
     88        /* try mph speed */
     89
     90        Matcher mphMatcher = MPH_PATTERN.matcher(value);
     91        if (mphMatcher.matches()) {
     92            String mphString = mphMatcher.group(1);
     93            try {
     94                int mph = Integer.parseInt(mphString);
     95                return KM_PER_MILE * mph;
     96            } catch (NumberFormatException nfe) {}
     97        }
     98
     99        /* all possibilities failed */
     100
     101        return null;
     102    }
     103
     104    private static final Pattern M_PATTERN = Pattern.compile("^([\\d\\.]+)\\s*m$");
     105    private static final Pattern KM_PATTERN = Pattern.compile("^([\\d\\.]+)\\s*km$");
     106    private static final Pattern MI_PATTERN = Pattern.compile("^([\\d\\.]+)\\s*mi$");
     107    private static final Pattern FEET_INCHES_PATTERN = Pattern.compile("^([\\d]+)'\\s*([\\d]+)\"");
     108
     109    private static final double M_PER_MI = 1609.344;
     110    private static final double M_PER_INCH = 0.0254f;
     111
     112    /**
     113    * parses a measure value given e.g. for the "width" or "length" key.
     114    *
     115    * @return  measure in m; null if value had syntax errors
     116    */
     117    public static final Float parseMeasure(String value) {
     118
     119        /* try numeric measure (implied m) */
     120
     121        Float measure = parseOsmDecimal(value, false);
     122        if (measure != null) {
     123            return measure;
     124        }
     125
     126        /* try m measure */
     127
     128        Matcher mMatcher = M_PATTERN.matcher(value);
     129        if (mMatcher.matches()) {
     130            String mString = mMatcher.group(1);
     131            return parseOsmDecimal(mString, false);
     132        }
     133
     134        /* try km measure */
     135
     136        Matcher kmMatcher = KM_PATTERN.matcher(value);
     137        if (kmMatcher.matches()) {
     138            String kmString = kmMatcher.group(1);
     139            float km = parseOsmDecimal(kmString, false);
     140            return 1000 * km;
     141        }
     142
     143        /* try mi measure */
     144
     145        Matcher miMatcher = MI_PATTERN.matcher(value);
     146        if (miMatcher.matches()) {
     147            String miString = miMatcher.group(1);
     148            float mi = parseOsmDecimal(miString, false);
     149            return (float)(M_PER_MI * mi);
     150        }
     151
     152        /* try feet/inches measure */
     153
     154        Matcher feetInchesMatcher = FEET_INCHES_PATTERN.matcher(value);
     155        if (feetInchesMatcher.matches()) {
     156            String feetString = feetInchesMatcher.group(1);
     157            String inchesString = feetInchesMatcher.group(2);
     158            try {
     159                int feet = Integer.parseInt(feetString);
     160                int inches = Integer.parseInt(inchesString);
     161                if (feet >= 0 && inches >= 0 && inches < 12) {
     162                    return (float)(M_PER_INCH * (12 * feet + inches));
     163                }
     164            } catch (NumberFormatException nfe) {}
     165        }
     166
     167        /* all possibilities failed */
     168
     169        return null;
     170    }
     171
     172    private static final Pattern T_PATTERN = Pattern.compile("^([\\d\\.]+)\\s*t$");
     173
     174    /**
     175    * parses a weight value given e.g. for the "maxweight" or "maxaxleload" key.
     176    *
     177    * @return  weight in t; null if value had syntax errors
     178    */
     179    public static Float parseWeight(String value) {
     180
     181        /* try numeric weight (implied t) */
     182
     183        Float weight = parseOsmDecimal(value, false);
     184        if (weight != null) {
     185            return weight;
     186        }
     187
     188        /* try t weight */
     189
     190        Matcher tMatcher = T_PATTERN.matcher(value);
     191        if (tMatcher.matches()) {
     192            String tString = tMatcher.group(1);
     193            return parseOsmDecimal(tString, false);
     194        }
     195
     196        /* all possibilities failed */
     197
     198        return null;
     199
     200    }
     201
     202    private static final Pattern INCLINE_PATTERN = Pattern.compile("^(\\-?\\d+(?:\\.\\d+)?)\\s*%$");
     203
     204    /**
     205    * parses an incline value as given for the "incline" key.
     206    *
     207    * @return  incline in percents; null if value had syntax errors
     208    */
     209    public static final Float parseIncline(String value) {
     210
     211        Matcher inclineMatcher = INCLINE_PATTERN.matcher(value);
     212        if (inclineMatcher.matches()) {
     213            String inclineString = inclineMatcher.group(1);
     214            return parseOsmDecimal(inclineString, true);
     215        }
     216
     217        return null;
     218    }
    219219
    220220}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/visualisation/ColorScheme.java

    r16520 r23189  
    1111public interface ColorScheme {
    1212
    13         /**
    14         * returns the color to be used for a node in a WayGraph
    15         * @param edge  GraphNode to determine the color for; != null
    16         */
    17         public Color getNodeColor(GraphNode node);
     13    /**
     14    * returns the color to be used for a node in a WayGraph
     15    * @param edge  GraphNode to determine the color for; != null
     16    */
     17    public Color getNodeColor(GraphNode node);
    1818
    19         /**
    20         * returns the color to be used for an edge in a WayGraph
    21         * @param segment  segment to determine the color for; != null
    22         */
    23         public Color getSegmentColor(Segment segment);
     19    /**
     20    * returns the color to be used for an edge in a WayGraph
     21    * @param segment  segment to determine the color for; != null
     22    */
     23    public Color getSegmentColor(Segment segment);
    2424
    2525}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/visualisation/DefaultNodePositioner.java

    r16520 r23189  
    1111public class DefaultNodePositioner implements NodePositioner {
    1212
    13         public LatLonCoords getPosition(GraphNode node) {
     13    public LatLonCoords getPosition(GraphNode node) {
    1414
    15                 SegmentNode segmentNode = node.getSegmentNode();
     15        SegmentNode segmentNode = node.getSegmentNode();
    1616
    17                 if (2 >= segmentNode.getInboundSegments().size()
    18                                 + segmentNode.getOutboundSegments().size() ) {
     17        if (2 >= segmentNode.getInboundSegments().size()
     18                + segmentNode.getOutboundSegments().size() ) {
    1919
    20                         return new LatLonCoords(
    21                                         node.getSegmentNode().getLat(),
    22                                         node.getSegmentNode().getLon());
     20            return new LatLonCoords(
     21                    node.getSegmentNode().getLat(),
     22                    node.getSegmentNode().getLon());
    2323
    24                 } else {
     24        } else {
    2525
    26                         SegmentNode node1 = node.getSegment().getNode1();
    27                         SegmentNode node2 = node.getSegment().getNode2();
     26            SegmentNode node1 = node.getSegment().getNode1();
     27            SegmentNode node2 = node.getSegment().getNode2();
    2828
    29                         assert segmentNode == node1 || segmentNode == node2;
     29            assert segmentNode == node1 || segmentNode == node2;
    3030
    31                         LatLonCoords result;
     31            LatLonCoords result;
    3232
    33                         if (segmentNode == node1) {
    34                                 result = new LatLonCoords(
    35                                                 (2 * node1.getLat() + node2.getLat()) / 3,
    36                                                 (2 * node1.getLon() + node2.getLon()) / 3);
    37                         } else {
    38                                 result = new LatLonCoords(
    39                                                 (node1.getLat() + 2 * node2.getLat()) / 3,
    40                                                 (node1.getLon() + 2 * node2.getLon()) / 3);
    41                         }
     33            if (segmentNode == node1) {
     34                result = new LatLonCoords(
     35                        (2 * node1.getLat() + node2.getLat()) / 3,
     36                        (2 * node1.getLon() + node2.getLon()) / 3);
     37            } else {
     38                result = new LatLonCoords(
     39                        (node1.getLat() + 2 * node2.getLat()) / 3,
     40                        (node1.getLon() + 2 * node2.getLon()) / 3);
     41            }
    4242
    43                         return result;
    44                 }
    45         }
     43            return result;
     44        }
     45    }
    4646
    4747}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/visualisation/EndNodeColorScheme.java

    r16520 r23189  
    1212public class EndNodeColorScheme implements ColorScheme {
    1313
    14         private final Color nodeColor;
    15         private final Color endNodeColor;
    16         private final Color segmentColor;
     14    private final Color nodeColor;
     15    private final Color endNodeColor;
     16    private final Color segmentColor;
    1717
    18         public EndNodeColorScheme(Color nodeColor, Color endNodeColor, Color segmentColor) {
    19                 this.nodeColor = nodeColor;
    20                 this.endNodeColor = endNodeColor;
    21                 this.segmentColor = segmentColor;
    22         }
     18    public EndNodeColorScheme(Color nodeColor, Color endNodeColor, Color segmentColor) {
     19        this.nodeColor = nodeColor;
     20        this.endNodeColor = endNodeColor;
     21        this.segmentColor = segmentColor;
     22    }
    2323
    24         public Color getNodeColor(GraphNode node) {
    25                 return GraphUtil.isEndNode(node) ? endNodeColor : nodeColor;
    26         }
     24    public Color getNodeColor(GraphNode node) {
     25        return GraphUtil.isEndNode(node) ? endNodeColor : nodeColor;
     26    }
    2727
    28         public Color getSegmentColor(Segment segment) {
    29                 return segmentColor;
    30         }
     28    public Color getSegmentColor(Segment segment) {
     29        return segmentColor;
     30    }
    3131
    3232}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/visualisation/FloatPropertyColorScheme.java

    r18130 r23189  
    2222public class FloatPropertyColorScheme implements ColorScheme {
    2323
    24         private final Class<? extends RoadPropertyType<Float>> propertyClass;
    25         private final Map<Float, Color> colorMap;
    26         private final Color defaultColor;
     24    private final Class<? extends RoadPropertyType<Float>> propertyClass;
     25    private final Map<Float, Color> colorMap;
     26    private final Color defaultColor;
    2727
    28         /**
    29         * @param propertyClass  property type to get values for; != null
    30         * @param colorMap       map from some values to colors.
    31         *                       Colors for all other values are interpolated.
    32         *                       This map will be copied and not used directly later. != null
    33         * @param defaultColor   color that is used when the property is not available; != null
    34         */
    35         public FloatPropertyColorScheme(Class<? extends RoadPropertyType<Float>> propertyClass,
    36                         Map<Float, Color> colorMap, Color defaultColor) {
    37                 assert propertyClass != null && colorMap != null && defaultColor != null;
     28    /**
     29    * @param propertyClass  property type to get values for; != null
     30    * @param colorMap       map from some values to colors.
     31    *                       Colors for all other values are interpolated.
     32    *                       This map will be copied and not used directly later. != null
     33    * @param defaultColor   color that is used when the property is not available; != null
     34    */
     35    public FloatPropertyColorScheme(Class<? extends RoadPropertyType<Float>> propertyClass,
     36            Map<Float, Color> colorMap, Color defaultColor) {
     37        assert propertyClass != null && colorMap != null && defaultColor != null;
    3838
    39                 this.propertyClass = propertyClass;
    40                 this.colorMap = new HashMap<Float, Color>(colorMap);
    41                 this.defaultColor = defaultColor;
    42         }
     39        this.propertyClass = propertyClass;
     40        this.colorMap = new HashMap<Float, Color>(colorMap);
     41        this.defaultColor = defaultColor;
     42    }
    4343
    44         public Color getSegmentColor(Segment segment) {
    45                 assert segment != null;
     44    public Color getSegmentColor(Segment segment) {
     45        assert segment != null;
    4646
    47                 Float propertyValue = null;
    48                 Collection<RoadPropertyType<?>> availableProperties = segment.getAvailableProperties();
    49                 for (RoadPropertyType<?> property : availableProperties) {
    50                         if (propertyClass.isInstance(property)) {
    51                                 @SuppressWarnings("unchecked") //has been checked using isInstance
    52                                 RoadPropertyType<Float> floatProperty = (RoadPropertyType<Float>)property;
    53                                 propertyValue = segment.getPropertyValue(floatProperty);
    54                                 break;
    55                         }
    56                 }
     47        Float propertyValue = null;
     48        Collection<RoadPropertyType<?>> availableProperties = segment.getAvailableProperties();
     49        for (RoadPropertyType<?> property : availableProperties) {
     50            if (propertyClass.isInstance(property)) {
     51                @SuppressWarnings("unchecked") //has been checked using isInstance
     52                RoadPropertyType<Float> floatProperty = (RoadPropertyType<Float>)property;
     53                propertyValue = segment.getPropertyValue(floatProperty);
     54                break;
     55            }
     56        }
    5757
    58                 if (propertyValue != null) {
    59                         return getColorForValue(propertyValue);
    60                 } else {
    61                         return defaultColor;
    62                 }
    63         }
     58        if (propertyValue != null) {
     59            return getColorForValue(propertyValue);
     60        } else {
     61            return defaultColor;
     62        }
     63    }
    6464
    65         public Color getNodeColor(GraphNode node) {
     65    public Color getNodeColor(GraphNode node) {
    6666
    67                 List<Color> segmentColors = new ArrayList<Color>();
     67        List<Color> segmentColors = new ArrayList<Color>();
    6868
    69                
    70                
    71                 for (GraphEdge edge : node.getInboundEdges()) {
    72                         List<Segment> edgeSegments = edge.getPropertyValue(GraphEdgeSegments.PROPERTY);
    73                         if (edgeSegments.size() > 0) {
    74                                 Segment firstSegment = edgeSegments.get(0);
    75                                 segmentColors.add(getSegmentColor(firstSegment));
    76                         }
    77                 }
    78                 for (GraphEdge edge : node.getOutboundEdges()) {
    79                         List<Segment> edgeSegments = edge.getPropertyValue(GraphEdgeSegments.PROPERTY);
    80                         if (edgeSegments.size() > 0) {
    81                                 Segment lastSegment = edgeSegments.get(edgeSegments.size()-1);
    82                                 segmentColors.add(getSegmentColor(lastSegment));
    83                         }
    84                 }
    8569
    86                 if (segmentColors.size() > 0) {
    87                         return averageColor(segmentColors);
    88                 } else {
    89                         return Color.WHITE;
    90                 }
    9170
    92         }
     71        for (GraphEdge edge : node.getInboundEdges()) {
     72            List<Segment> edgeSegments = edge.getPropertyValue(GraphEdgeSegments.PROPERTY);
     73            if (edgeSegments.size() > 0) {
     74                Segment firstSegment = edgeSegments.get(0);
     75                segmentColors.add(getSegmentColor(firstSegment));
     76            }
     77        }
     78        for (GraphEdge edge : node.getOutboundEdges()) {
     79            List<Segment> edgeSegments = edge.getPropertyValue(GraphEdgeSegments.PROPERTY);
     80            if (edgeSegments.size() > 0) {
     81                Segment lastSegment = edgeSegments.get(edgeSegments.size()-1);
     82                segmentColors.add(getSegmentColor(lastSegment));
     83            }
     84        }
    9385
    94         /**
    95          * returns the color for a value
    96          * @param value  value to get color for; != null
    97          * @return       color; != null
    98          */
    99         protected Color getColorForValue(Float value) {
    100                 assert value != null;
     86        if (segmentColors.size() > 0) {
     87            return averageColor(segmentColors);
     88        } else {
     89            return Color.WHITE;
     90        }
    10191
    102                 if (colorMap.containsKey(value)) {
     92    }
    10393
    104                         return colorMap.get(value);
     94    /**
     95     * returns the color for a value
     96     * @param value  value to get color for; != null
     97     * @return       color; != null
     98     */
     99    protected Color getColorForValue(Float value) {
     100        assert value != null;
    105101
    106                 } else {
     102        if (colorMap.containsKey(value)) {
    107103
    108                         LinkedList<Float> valuesWithDefinedColor = new LinkedList<Float>(colorMap.keySet());
    109                         Collections.sort(valuesWithDefinedColor);
     104            return colorMap.get(value);
    110105
    111                         if (value <= valuesWithDefinedColor.getFirst()) {
     106        } else {
    112107
    113                                 return colorMap.get(valuesWithDefinedColor.getFirst());
     108            LinkedList<Float> valuesWithDefinedColor = new LinkedList<Float>(colorMap.keySet());
     109            Collections.sort(valuesWithDefinedColor);
    114110
    115                         } else if (value >= valuesWithDefinedColor.getLast()) {
     111            if (value <= valuesWithDefinedColor.getFirst()) {
    116112
    117                                 return colorMap.get(valuesWithDefinedColor.getLast());
     113                return colorMap.get(valuesWithDefinedColor.getFirst());
    118114
    119                         } else {
     115            } else if (value >= valuesWithDefinedColor.getLast()) {
    120116
    121                                 /* interpolate */
     117                return colorMap.get(valuesWithDefinedColor.getLast());
    122118
    123                                 Float lowerValue = valuesWithDefinedColor.getFirst();
    124                                 Float higherValue = null;
     119            } else {
    125120
    126                                 for (Float v : valuesWithDefinedColor) {
    127                                         if (v >= value) {
    128                                                 higherValue = v;
    129                                                 break;
    130                                         }
    131                                         lowerValue = v;
    132                                 }
     121                /* interpolate */
    133122
    134                                 assert lowerValue != null && higherValue != null;
     123                Float lowerValue = valuesWithDefinedColor.getFirst();
     124                Float higherValue = null;
    135125
    136                                 Color lowerColor = colorMap.get(lowerValue);
    137                                 Color higherColor = colorMap.get(higherValue);
     126                for (Float v : valuesWithDefinedColor) {
     127                    if (v >= value) {
     128                        higherValue = v;
     129                        break;
     130                    }
     131                    lowerValue = v;
     132                }
    138133
    139                                 float weightHigherColor = (value - lowerValue) / (higherValue - lowerValue);
     134                assert lowerValue != null && higherValue != null;
    140135
    141                                 return weightedAverageColor(lowerColor, higherColor, weightHigherColor);
     136                Color lowerColor = colorMap.get(lowerValue);
     137                Color higherColor = colorMap.get(higherValue);
    142138
    143                         }
     139                float weightHigherColor = (value - lowerValue) / (higherValue - lowerValue);
    144140
    145                 }
     141                return weightedAverageColor(lowerColor, higherColor, weightHigherColor);
    146142
    147         }
     143            }
    148144
    149         /**
    150          * returns an average of all colors that have been passed as parameter
    151          *
    152          * @param colors  colors to calculate average from; not empty or null
    153          * @return        average color; != null
    154          */
    155         private static Color averageColor(List<Color> colors) {
    156                 assert colors != null && colors.size() > 0;
     145        }
    157146
    158                 float weightPerColor = 1.0f / colors.size();
     147    }
    159148
    160                 Color average = new Color(0,0,0);
     149    /**
     150     * returns an average of all colors that have been passed as parameter
     151     *
     152     * @param colors  colors to calculate average from; not empty or null
     153     * @return        average color; != null
     154     */
     155    private static Color averageColor(List<Color> colors) {
     156        assert colors != null && colors.size() > 0;
    161157
    162                 for (Color color : colors) {
    163                         average = new Color(
    164                                         Math.min(Math.round(average.getRed() + weightPerColor*color.getRed()), 255),
    165                                         Math.min(Math.round(average.getGreen() + weightPerColor*color.getGreen()), 255),
    166                                         Math.min(Math.round(average.getBlue() + weightPerColor*color.getBlue()), 255));
    167                 }
     158        float weightPerColor = 1.0f / colors.size();
    168159
    169                 return average;
    170         }
     160        Color average = new Color(0,0,0);
    171161
    172         /**
    173          * returns a weighted average of two colors
    174          *
    175          * @param color1        first color for the average; != null
    176          * @param color2        second color for the average; != null
    177          * @param weightColor2  weight of color2; must be in [0..1]
    178          * @return              average color; != null
    179          */
    180         private static Color weightedAverageColor(Color color1, Color color2, float weightColor2) {
    181                 assert color1 != null && color2 != null;
    182                 assert 0 <= weightColor2 && weightColor2 <= 1;
     162        for (Color color : colors) {
     163            average = new Color(
     164                    Math.min(Math.round(average.getRed() + weightPerColor*color.getRed()), 255),
     165                    Math.min(Math.round(average.getGreen() + weightPerColor*color.getGreen()), 255),
     166                    Math.min(Math.round(average.getBlue() + weightPerColor*color.getBlue()), 255));
     167        }
    183168
    184                 return new Color(
    185                                 Math.round((1 - weightColor2) * color1.getRed() + weightColor2 * color2.getRed()),
    186                                 Math.round((1 - weightColor2) * color1.getGreen() + weightColor2 * color2.getGreen()),
    187                                 Math.round((1 - weightColor2) * color1.getBlue() + weightColor2 * color2.getBlue()));
    188         }
     169        return average;
     170    }
     171
     172    /**
     173     * returns a weighted average of two colors
     174     *
     175     * @param color1        first color for the average; != null
     176     * @param color2        second color for the average; != null
     177     * @param weightColor2  weight of color2; must be in [0..1]
     178     * @return              average color; != null
     179     */
     180    private static Color weightedAverageColor(Color color1, Color color2, float weightColor2) {
     181        assert color1 != null && color2 != null;
     182        assert 0 <= weightColor2 && weightColor2 <= 1;
     183
     184        return new Color(
     185                Math.round((1 - weightColor2) * color1.getRed() + weightColor2 * color2.getRed()),
     186                Math.round((1 - weightColor2) * color1.getGreen() + weightColor2 * color2.getGreen()),
     187                Math.round((1 - weightColor2) * color1.getBlue() + weightColor2 * color2.getBlue()));
     188    }
    189189
    190190}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/visualisation/InclineColorScheme.java

    r16520 r23189  
    1212public class InclineColorScheme extends FloatPropertyColorScheme {
    1313
    14         private static final Map<Float, Color> COLOR_MAP;
     14    private static final Map<Float, Color> COLOR_MAP;
    1515
    16         static {
    17                 COLOR_MAP = new HashMap<Float, Color>();
    18                 COLOR_MAP.put(-30f, Color.BLUE);
    19                 COLOR_MAP.put(0f, Color.WHITE);
    20                 COLOR_MAP.put(30f, Color.RED);
    21         }
     16    static {
     17        COLOR_MAP = new HashMap<Float, Color>();
     18        COLOR_MAP.put(-30f, Color.BLUE);
     19        COLOR_MAP.put(0f, Color.WHITE);
     20        COLOR_MAP.put(30f, Color.RED);
     21    }
    2222
    23         public InclineColorScheme() {
    24                 super(RoadIncline.class, COLOR_MAP, Color.GRAY);
    25         }
     23    public InclineColorScheme() {
     24        super(RoadIncline.class, COLOR_MAP, Color.GRAY);
     25    }
    2626}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/visualisation/LatLonCoords.java

    r16520 r23189  
    66public final class LatLonCoords {
    77
    8         private final double lat;
    9         private final double lon;
     8    private final double lat;
     9    private final double lon;
    1010
    11         public LatLonCoords(double lat, double lon) {
    12                 this.lat = lat;
    13                 this.lon = lon;
    14         }
     11    public LatLonCoords(double lat, double lon) {
     12        this.lat = lat;
     13        this.lon = lon;
     14    }
    1515
    16         public double getLat() {
    17                 return lat;
    18         }
     16    public double getLat() {
     17        return lat;
     18    }
    1919
    20         public double getLon() {
    21                 return lon;
    22         }
     20    public double getLon() {
     21        return lon;
     22    }
    2323
    2424}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/visualisation/MaxheightColorScheme.java

    r16520 r23189  
    1212public class MaxheightColorScheme extends FloatPropertyColorScheme {
    1313
    14         private static final Map<Float, Color> COLOR_MAP;
     14    private static final Map<Float, Color> COLOR_MAP;
    1515
    16         static {
    17                 COLOR_MAP = new HashMap<Float, Color>();
    18                 COLOR_MAP.put(0f, new Color(0, 0, 50));
    19                 COLOR_MAP.put(10f, new Color(100, 100, 255));
    20                 COLOR_MAP.put(30f, new Color(200, 200, 255));
    21         }
     16    static {
     17        COLOR_MAP = new HashMap<Float, Color>();
     18        COLOR_MAP.put(0f, new Color(0, 0, 50));
     19        COLOR_MAP.put(10f, new Color(100, 100, 255));
     20        COLOR_MAP.put(30f, new Color(200, 200, 255));
     21    }
    2222
    23         public MaxheightColorScheme() {
    24                 super(RoadMaxheight.class, COLOR_MAP, Color.WHITE);
    25         }
     23    public MaxheightColorScheme() {
     24        super(RoadMaxheight.class, COLOR_MAP, Color.WHITE);
     25    }
    2626}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/visualisation/MaxspeedColorScheme.java

    r16520 r23189  
    1212public class MaxspeedColorScheme extends FloatPropertyColorScheme {
    1313
    14         private static final Map<Float, Color> COLOR_MAP;
     14    private static final Map<Float, Color> COLOR_MAP;
    1515
    16         static {
    17                 COLOR_MAP = new HashMap<Float, Color>();
    18                 COLOR_MAP.put(0f, new Color(50, 0, 0));
    19                 COLOR_MAP.put(30f, Color.RED);
    20                 COLOR_MAP.put(60f, Color.YELLOW);
    21                 COLOR_MAP.put(90f, Color.GREEN);
    22                 COLOR_MAP.put(150f, Color.BLUE);
    23         }
     16    static {
     17        COLOR_MAP = new HashMap<Float, Color>();
     18        COLOR_MAP.put(0f, new Color(50, 0, 0));
     19        COLOR_MAP.put(30f, Color.RED);
     20        COLOR_MAP.put(60f, Color.YELLOW);
     21        COLOR_MAP.put(90f, Color.GREEN);
     22        COLOR_MAP.put(150f, Color.BLUE);
     23    }
    2424
    25         public MaxspeedColorScheme() {
    26                 super(RoadMaxspeed.class, COLOR_MAP, Color.GRAY);
    27         }
     25    public MaxspeedColorScheme() {
     26        super(RoadMaxspeed.class, COLOR_MAP, Color.GRAY);
     27    }
    2828}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/visualisation/MaxweightColorScheme.java

    r16520 r23189  
    1212public class MaxweightColorScheme extends FloatPropertyColorScheme {
    1313
    14         private static final Map<Float, Color> COLOR_MAP;
     14    private static final Map<Float, Color> COLOR_MAP;
    1515
    16         static {
    17                 COLOR_MAP = new HashMap<Float, Color>();
    18                 COLOR_MAP.put(0f, new Color(0, 0, 50));
    19                 COLOR_MAP.put(20f, new Color(100, 100, 255));
    20                 COLOR_MAP.put(50f, new Color(200, 200, 255));
    21         }
     16    static {
     17        COLOR_MAP = new HashMap<Float, Color>();
     18        COLOR_MAP.put(0f, new Color(0, 0, 50));
     19        COLOR_MAP.put(20f, new Color(100, 100, 255));
     20        COLOR_MAP.put(50f, new Color(200, 200, 255));
     21    }
    2222
    23         public MaxweightColorScheme() {
    24                 super(RoadMaxweight.class, COLOR_MAP, Color.WHITE);
    25         }
     23    public MaxweightColorScheme() {
     24        super(RoadMaxweight.class, COLOR_MAP, Color.WHITE);
     25    }
    2626}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/visualisation/NodePositioner.java

    r16520 r23189  
    99public interface NodePositioner {
    1010
    11         LatLonCoords getPosition(GraphNode node);
     11    LatLonCoords getPosition(GraphNode node);
    1212
    1313}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/visualisation/NonMovingNodePositioner.java

    r16520 r23189  
    55public class NonMovingNodePositioner implements NodePositioner {
    66
    7         public LatLonCoords getPosition(GraphNode node) {
    8                 return new LatLonCoords(
    9                                 node.getSegmentNode().getLat(),
    10                                 node.getSegmentNode().getLon());
    11         }
     7    public LatLonCoords getPosition(GraphNode node) {
     8        return new LatLonCoords(
     9                node.getSegmentNode().getLat(),
     10                node.getSegmentNode().getLon());
     11    }
    1212
    1313}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/core/visualisation/SingleColorScheme.java

    r16520 r23189  
    1212public class SingleColorScheme implements ColorScheme {
    1313
    14         private final Color nodeColor;
    15         private final Color segmentColor;
     14    private final Color nodeColor;
     15    private final Color segmentColor;
    1616
    17         public SingleColorScheme(Color nodeColor, Color segmentColor) {
    18                 this.nodeColor = nodeColor;
    19                 this.segmentColor = segmentColor;
    20         }
     17    public SingleColorScheme(Color nodeColor, Color segmentColor) {
     18        this.nodeColor = nodeColor;
     19        this.segmentColor = segmentColor;
     20    }
    2121
    22         public Color getNodeColor(GraphNode node) {
    23                 return nodeColor;
    24         }
     22    public Color getNodeColor(GraphNode node) {
     23        return nodeColor;
     24    }
    2525
    26         public Color getSegmentColor(Segment segment) {
    27                 return segmentColor;
    28         }
     26    public Color getSegmentColor(Segment segment) {
     27        return segmentColor;
     28    }
    2929
    3030}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/plugin/GraphViewPlugin.java

    r19441 r23189  
    5252public class GraphViewPlugin extends Plugin implements LayerChangeListener, Observer {
    5353
    54         private static final Collection<RoadPropertyType<?>> PROPERTIES;
    55 
    56         static {
    57                 PROPERTIES = new LinkedList<RoadPropertyType<?>>();
    58                 PROPERTIES.add(new RoadIncline());
    59                 PROPERTIES.add(new RoadMaxaxleload());
    60                 PROPERTIES.add(new RoadMaxheight());
    61                 PROPERTIES.add(new RoadMaxlength());
    62                 PROPERTIES.add(new RoadMaxspeed());
    63                 PROPERTIES.add(new RoadMaxweight());
    64                 PROPERTIES.add(new RoadMaxwidth());
    65                 PROPERTIES.add(new RoadMinspeed());
    66                 PROPERTIES.add(new RoadSurface());
    67                 PROPERTIES.add(new RoadTracktype());
    68                 PROPERTIES.add(new RoadWidth());
    69         }
    70 
    71         private final GraphViewPreferences preferences;
    72 
    73         private JOSMTransitionStructure transitionStructure;
    74         private GraphViewLayer graphViewLayer;
    75 
    76         /** creates the plugin */
    77         public GraphViewPlugin(PluginInformation info) {
    78                 super(info);
    79                 preferences = GraphViewPreferences.getInstance();
    80                 this.preferences.addObserver(this);
    81 
    82         }
    83 
    84         /** allows creation/update of GraphViewLayer */
    85         public void createGraphViewLayer() {
    86 
    87                 try {
    88 
    89                         if (graphViewLayer != null) {
    90 
    91                                 AccessRuleset accessRuleset = getAccessRuleset();
    92 
    93                                 if (accessRuleset == null) {
    94                                         JOptionPane.showMessageDialog(Main.parent, "No ruleset has been selected!", "No ruleset", JOptionPane.ERROR_MESSAGE);
    95                                 } else {
    96                                         transitionStructure.setAccessParametersAndRuleset(preferences.getCurrentParameterBookmark(), accessRuleset);
    97                                         transitionStructure.forceUpdate();
    98                                 }
    99 
    100                         } else {
    101 
    102                                 AccessRuleset accessRuleset = getAccessRuleset();
    103 
    104                                 if (accessRuleset == null) {
    105                                         JOptionPane.showMessageDialog(Main.parent, "No ruleset has been selected!",
    106                                                         "No ruleset", JOptionPane.ERROR_MESSAGE);
    107                                 } else {
    108 
    109                                         transitionStructure = new JOSMTransitionStructure(
    110                                                         preferences.getCurrentParameterBookmark(),
    111                                                         accessRuleset,
    112                                                         PROPERTIES);
    113 
    114                                         WayGraph graph = new TSBasedWayGraph(transitionStructure);
    115 
    116                                         graphViewLayer = new GraphViewLayer();
    117                                         graphViewLayer.setWayGraph(graph);
    118                                         graphViewLayer.setColorScheme(preferences.getCurrentColorScheme());
    119                                         graphViewLayer.setNodePositioner(new DefaultNodePositioner());
    120 
    121                                         Main.main.addLayer(graphViewLayer);
    122 
    123                                 }
    124 
    125                         }
    126 
    127                 } catch (AccessRulesetSyntaxException e) {
    128                         JOptionPane.showMessageDialog(Main.parent, "syntax exception in access ruleset:\n" + e);
    129                         e.printStackTrace();
    130                 } catch (FileNotFoundException e) {
    131                         JOptionPane.showMessageDialog(Main.parent, "file not found:\n" + e);
    132                         e.printStackTrace();
    133                 } catch (IOException e) {
    134                         JOptionPane.showMessageDialog(Main.parent, "problem when accessing a file:\n" + e);
    135                         e.printStackTrace();
    136                 }
    137 
    138         }
    139 
    140         /** allows update of GraphViewLayer */
    141         public void updateGraphViewLayer() {
    142 
    143                 try {
    144 
    145                         if (graphViewLayer != null) {
    146 
    147                                 AccessRuleset accessRuleset = getAccessRuleset();
    148 
    149                                 if (accessRuleset == null) {
    150                                         JOptionPane.showMessageDialog(Main.parent, "No ruleset has been selected!",
    151                                                         "No ruleset", JOptionPane.ERROR_MESSAGE);
    152                                 } else {
    153                                         transitionStructure.setAccessParametersAndRuleset(
    154                                                         preferences.getCurrentParameterBookmark(), accessRuleset);
    155                                         transitionStructure.forceUpdate();
    156                                 }
    157 
    158                         }
    159 
    160                 } catch (AccessRulesetSyntaxException e) {
    161                         JOptionPane.showMessageDialog(Main.parent, "syntax exception in access ruleset:\n" + e);
    162                         e.printStackTrace();
    163                 } catch (FileNotFoundException e) {
    164                         JOptionPane.showMessageDialog(Main.parent, "file not found:\n" + e);
    165                         e.printStackTrace();
    166                 } catch (IOException e) {
    167                         JOptionPane.showMessageDialog(Main.parent, "problem when accessing a file:\n" + e);
    168                         e.printStackTrace();
    169                 }
    170 
    171         }
    172 
    173         /** repaints the GraphViewLayer without recalculating the graph (visual update) */
    174         public void repaintGraphViewLayer() {
    175 
    176                 if (graphViewLayer != null) {
    177                         Main.panel.repaint();
    178                 }
    179 
    180         }
    181 
    182         /**
    183         * @return ruleset read from a source as specified by preferences, null if the preferences
    184         *         don't specify a ruleset source
    185         * @throws AccessRulesetSyntaxException
    186         * @throws IOException
    187         * @throws FileNotFoundException
    188         */
    189         private AccessRuleset getAccessRuleset()
    190         throws AccessRulesetSyntaxException, IOException, FileNotFoundException {
    191 
    192                 InputStream rulesetInputStream;
    193 
    194                 if (preferences.getUseInternalRulesets()) {
    195 
    196                         InternalRuleset ruleset = preferences.getCurrentInternalRuleset();
    197 
    198                         if (ruleset == null) {
    199                                 return null;
    200                         }
    201 
    202                         ClassLoader classLoader = this.getClass().getClassLoader();
    203                         URL rulesetURL = classLoader.getResource(ruleset.getResourceName());
    204 
    205                         if (rulesetURL != null) {
    206                                 rulesetInputStream = rulesetURL.openStream();
    207                         } else {
    208                                 throw new FileNotFoundException("couldn't find built-in ruleset " + ruleset);
    209                         }
    210 
    211                 } else {
    212 
    213                         File rulesetFile = preferences.getCurrentRulesetFile();
    214 
    215                         if (rulesetFile == null) {
    216                                 return null;
    217                         }
    218 
    219                         rulesetInputStream = new FileInputStream(rulesetFile);
    220 
    221                 }
    222 
    223                 return AccessRulesetReader.readAccessRuleset(rulesetInputStream);
    224 
    225         }
    226 
    227         @Override
    228         public PreferenceSetting getPreferenceSetting() {
    229                 return new GraphViewPreferenceEditor();
    230         }
    231 
    232         @Override
    233         public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {
    234                 if (newFrame != null) {
    235                         if (oldFrame == null) {
    236                                 final GraphViewDialog laneDialog
    237                                         = new GraphViewDialog(this);
    238                                 newFrame.addToggleDialog(laneDialog);
    239                         }
    240                         MapView.addLayerChangeListener(this);
    241                 } else {
    242                         MapView.removeLayerChangeListener(this);
    243                 }
    244         }
    245 
    246         public void layerRemoved(Layer oldLayer) {
    247                 if (oldLayer == graphViewLayer) {
    248                         graphViewLayer = null;
    249                 } else if (oldLayer == Main.map.mapView.getEditLayer()) { //data layer removed
    250                         if (graphViewLayer != null) {
    251                                 Main.map.mapView.removeLayer(graphViewLayer);
    252                                 graphViewLayer = null;
    253                         }
    254                 }
    255         }
    256 
    257         public void activeLayerChange(Layer oldLayer, Layer newLayer) {
    258                 //do nothing
    259         }
    260 
    261         public void layerAdded(Layer newLayer) {
    262                 //do nothing
    263         }
    264 
    265         public void update(Observable arg0, Object arg1) {
    266                 if (arg0 == preferences) {
    267                         if (graphViewLayer != null) {
    268                                 graphViewLayer.setColorScheme(preferences.getCurrentColorScheme());
    269                         }
    270                 }
    271         }
     54    private static final Collection<RoadPropertyType<?>> PROPERTIES;
     55
     56    static {
     57        PROPERTIES = new LinkedList<RoadPropertyType<?>>();
     58        PROPERTIES.add(new RoadIncline());
     59        PROPERTIES.add(new RoadMaxaxleload());
     60        PROPERTIES.add(new RoadMaxheight());
     61        PROPERTIES.add(new RoadMaxlength());
     62        PROPERTIES.add(new RoadMaxspeed());
     63        PROPERTIES.add(new RoadMaxweight());
     64        PROPERTIES.add(new RoadMaxwidth());
     65        PROPERTIES.add(new RoadMinspeed());
     66        PROPERTIES.add(new RoadSurface());
     67        PROPERTIES.add(new RoadTracktype());
     68        PROPERTIES.add(new RoadWidth());
     69    }
     70
     71    private final GraphViewPreferences preferences;
     72
     73    private JOSMTransitionStructure transitionStructure;
     74    private GraphViewLayer graphViewLayer;
     75
     76    /** creates the plugin */
     77    public GraphViewPlugin(PluginInformation info) {
     78        super(info);
     79        preferences = GraphViewPreferences.getInstance();
     80        this.preferences.addObserver(this);
     81
     82    }
     83
     84    /** allows creation/update of GraphViewLayer */
     85    public void createGraphViewLayer() {
     86
     87        try {
     88
     89            if (graphViewLayer != null) {
     90
     91                AccessRuleset accessRuleset = getAccessRuleset();
     92
     93                if (accessRuleset == null) {
     94                    JOptionPane.showMessageDialog(Main.parent, "No ruleset has been selected!", "No ruleset", JOptionPane.ERROR_MESSAGE);
     95                } else {
     96                    transitionStructure.setAccessParametersAndRuleset(preferences.getCurrentParameterBookmark(), accessRuleset);
     97                    transitionStructure.forceUpdate();
     98                }
     99
     100            } else {
     101
     102                AccessRuleset accessRuleset = getAccessRuleset();
     103
     104                if (accessRuleset == null) {
     105                    JOptionPane.showMessageDialog(Main.parent, "No ruleset has been selected!",
     106                            "No ruleset", JOptionPane.ERROR_MESSAGE);
     107                } else {
     108
     109                    transitionStructure = new JOSMTransitionStructure(
     110                            preferences.getCurrentParameterBookmark(),
     111                            accessRuleset,
     112                            PROPERTIES);
     113
     114                    WayGraph graph = new TSBasedWayGraph(transitionStructure);
     115
     116                    graphViewLayer = new GraphViewLayer();
     117                    graphViewLayer.setWayGraph(graph);
     118                    graphViewLayer.setColorScheme(preferences.getCurrentColorScheme());
     119                    graphViewLayer.setNodePositioner(new DefaultNodePositioner());
     120
     121                    Main.main.addLayer(graphViewLayer);
     122
     123                }
     124
     125            }
     126
     127        } catch (AccessRulesetSyntaxException e) {
     128            JOptionPane.showMessageDialog(Main.parent, "syntax exception in access ruleset:\n" + e);
     129            e.printStackTrace();
     130        } catch (FileNotFoundException e) {
     131            JOptionPane.showMessageDialog(Main.parent, "file not found:\n" + e);
     132            e.printStackTrace();
     133        } catch (IOException e) {
     134            JOptionPane.showMessageDialog(Main.parent, "problem when accessing a file:\n" + e);
     135            e.printStackTrace();
     136        }
     137
     138    }
     139
     140    /** allows update of GraphViewLayer */
     141    public void updateGraphViewLayer() {
     142
     143        try {
     144
     145            if (graphViewLayer != null) {
     146
     147                AccessRuleset accessRuleset = getAccessRuleset();
     148
     149                if (accessRuleset == null) {
     150                    JOptionPane.showMessageDialog(Main.parent, "No ruleset has been selected!",
     151                            "No ruleset", JOptionPane.ERROR_MESSAGE);
     152                } else {
     153                    transitionStructure.setAccessParametersAndRuleset(
     154                            preferences.getCurrentParameterBookmark(), accessRuleset);
     155                    transitionStructure.forceUpdate();
     156                }
     157
     158            }
     159
     160        } catch (AccessRulesetSyntaxException e) {
     161            JOptionPane.showMessageDialog(Main.parent, "syntax exception in access ruleset:\n" + e);
     162            e.printStackTrace();
     163        } catch (FileNotFoundException e) {
     164            JOptionPane.showMessageDialog(Main.parent, "file not found:\n" + e);
     165            e.printStackTrace();
     166        } catch (IOException e) {
     167            JOptionPane.showMessageDialog(Main.parent, "problem when accessing a file:\n" + e);
     168            e.printStackTrace();
     169        }
     170
     171    }
     172
     173    /** repaints the GraphViewLayer without recalculating the graph (visual update) */
     174    public void repaintGraphViewLayer() {
     175
     176        if (graphViewLayer != null) {
     177            Main.panel.repaint();
     178        }
     179
     180    }
     181
     182    /**
     183    * @return ruleset read from a source as specified by preferences, null if the preferences
     184    *         don't specify a ruleset source
     185    * @throws AccessRulesetSyntaxException
     186    * @throws IOException
     187    * @throws FileNotFoundException
     188    */
     189    private AccessRuleset getAccessRuleset()
     190    throws AccessRulesetSyntaxException, IOException, FileNotFoundException {
     191
     192        InputStream rulesetInputStream;
     193
     194        if (preferences.getUseInternalRulesets()) {
     195
     196            InternalRuleset ruleset = preferences.getCurrentInternalRuleset();
     197
     198            if (ruleset == null) {
     199                return null;
     200            }
     201
     202            ClassLoader classLoader = this.getClass().getClassLoader();
     203            URL rulesetURL = classLoader.getResource(ruleset.getResourceName());
     204
     205            if (rulesetURL != null) {
     206                rulesetInputStream = rulesetURL.openStream();
     207            } else {
     208                throw new FileNotFoundException("couldn't find built-in ruleset " + ruleset);
     209            }
     210
     211        } else {
     212
     213            File rulesetFile = preferences.getCurrentRulesetFile();
     214
     215            if (rulesetFile == null) {
     216                return null;
     217            }
     218
     219            rulesetInputStream = new FileInputStream(rulesetFile);
     220
     221        }
     222
     223        return AccessRulesetReader.readAccessRuleset(rulesetInputStream);
     224
     225    }
     226
     227    @Override
     228    public PreferenceSetting getPreferenceSetting() {
     229        return new GraphViewPreferenceEditor();
     230    }
     231
     232    @Override
     233    public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {
     234        if (newFrame != null) {
     235            if (oldFrame == null) {
     236                final GraphViewDialog laneDialog
     237                    = new GraphViewDialog(this);
     238                newFrame.addToggleDialog(laneDialog);
     239            }
     240            MapView.addLayerChangeListener(this);
     241        } else {
     242            MapView.removeLayerChangeListener(this);
     243        }
     244    }
     245
     246    public void layerRemoved(Layer oldLayer) {
     247        if (oldLayer == graphViewLayer) {
     248            graphViewLayer = null;
     249        } else if (oldLayer == Main.map.mapView.getEditLayer()) { //data layer removed
     250            if (graphViewLayer != null) {
     251                Main.map.mapView.removeLayer(graphViewLayer);
     252                graphViewLayer = null;
     253            }
     254        }
     255    }
     256
     257    public void activeLayerChange(Layer oldLayer, Layer newLayer) {
     258        //do nothing
     259    }
     260
     261    public void layerAdded(Layer newLayer) {
     262        //do nothing
     263    }
     264
     265    public void update(Observable arg0, Object arg1) {
     266        if (arg0 == preferences) {
     267            if (graphViewLayer != null) {
     268                graphViewLayer.setColorScheme(preferences.getCurrentColorScheme());
     269            }
     270        }
     271    }
    272272
    273273}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/plugin/data/JOSMDataSource.java

    r21610 r23189  
    2626public class JOSMDataSource implements DataSource<Node, Way, Relation, RelationMember> {
    2727
    28         public double getLat(Node node) {
    29                 return node.getCoor().lat();
    30         }
    31 
    32         public double getLon(Node node) {
    33                 return node.getCoor().lon();
    34         }
    35 
    36         public Iterable<RelationMember> getMembers(Relation relation) {
    37                 return relation.getMembers();
    38         }
    39 
    40         public Iterable<Node> getNodes(Way way) {
    41                 return new FilteredOsmPrimitiveIterable<Node>(way.getNodes());
    42         }
    43 
    44         public Iterable<Node> getNodes() {
    45                 return new FilteredOsmPrimitiveIterable<Node>(Main.main.getCurrentDataSet().getNodes());
    46         }
    47 
    48         public Iterable<Relation> getRelations() {
    49                 return new FilteredRelationIterable(Main.main.getCurrentDataSet().getRelations());
    50         }
    51 
    52         public Iterable<Way> getWays() {
    53                 return new FilteredOsmPrimitiveIterable<Way>(Main.main.getCurrentDataSet().getWays());
    54         }
    55 
    56         public TagGroup getTagsN(Node node) {
    57                 return getTags(node);
    58         }
    59 
    60         public TagGroup getTagsW(Way way) {
    61                 return getTags(way);
    62         }
    63 
    64         public TagGroup getTagsR(Relation relation) {
    65                 return getTags(relation);
    66         }
    67 
    68         private TagGroup getTags(OsmPrimitive primitive) {
    69                 if (primitive.getKeys() == null) {
    70                         return EMPTY_TAG_GROUP;
    71                 } else {
    72                         return new MapBasedTagGroup(primitive.getKeys());
    73                 }
    74         }
    75 
    76         public Object getMember(RelationMember member) {
    77                 return member.getMember();
    78         }
    79 
    80         public String getRole(RelationMember member) {
    81                 return member.getRole();
    82         }
    83 
    84         public boolean isNMember(RelationMember member) {
    85                 return member.getMember() instanceof Node;
    86         }
    87 
    88         public boolean isWMember(RelationMember member) {
    89                 return member.getMember() instanceof Way;
    90         }
    91 
    92         public boolean isRMember(RelationMember member) {
    93                 return member.getMember() instanceof Relation;
    94         }
    95 
    96 
    97         private static final TagGroup EMPTY_TAG_GROUP;
    98         static {
    99                 Map<String, String> emptyMap = new HashMap<String, String>(0);
    100                 EMPTY_TAG_GROUP = new MapBasedTagGroup(emptyMap);
    101         }
    102 
    103         /**
    104         * Iterable of OsmPrimitive objects based on an existing Iterable,
    105         * will filter incomplete and deleted objects from the iterator.
    106         *
    107         * @param <P>  OsmPrimitive subtype
    108         */
    109         public static class FilteredOsmPrimitiveIterable<P extends OsmPrimitive> implements Iterable<P> {
    110 
    111                 private final Iterable<P> originalIterable;
    112 
    113                 public FilteredOsmPrimitiveIterable(Iterable<P> originalIterable) {
    114                         this.originalIterable = originalIterable;
    115                 }
    116 
    117                 /** returns an iterator. The iterator does not support {@link Iterator#remove()}. */
    118                 public Iterator<P> iterator() {
    119                         return new FilteredIterator(originalIterable.iterator());
    120                 }
    121 
    122                 private class FilteredIterator implements Iterator<P> {
    123 
    124                         private final Iterator<P> originalIterator;
    125 
    126                         private P next;
    127 
    128                         public FilteredIterator(Iterator<P> originalIterator) {
    129                                 this.originalIterator = originalIterator;
    130                                 updateNext();
    131                         }
    132 
    133                         public boolean hasNext() {
    134                                 return next != null;
    135                         }
    136 
    137                         public P next() {
    138                                 if (next != null) {
    139                                         P result = next;
    140                                         updateNext();
    141                                         return result;
    142                                 } else {
    143                                         throw new NoSuchElementException();
    144                                 }
    145                         }
    146 
    147                         public void remove() {
    148                                 throw new UnsupportedOperationException();
    149                         }
    150 
    151                         private void updateNext() {
    152                                 next = null;
    153                                 while (originalIterator.hasNext()) {
    154                                         P originalNext = originalIterator.next();
    155                                         if (accept(originalNext)) {
    156                                                 next = originalNext;
    157                                                 break;
    158                                         }
    159                                 }
    160                         }
    161 
    162                 }
    163 
    164                 protected boolean accept(P primitive) {
    165                         return !primitive.isDeleted() && !primitive.isIncomplete();
    166                 }
    167         }
    168 
    169         /**
    170         * Relation-specific variant of the FilteredOsmPrimitiveIterable,
    171         * also checks completeness of relation's members
    172         */
    173         public static class FilteredRelationIterable extends FilteredOsmPrimitiveIterable<Relation> {
    174 
    175                 public FilteredRelationIterable(Iterable<Relation> originalIterable) {
    176                         super(originalIterable);
    177                 }
    178 
    179                 @Override
    180                 protected boolean accept(Relation relation) {
    181                         boolean complete = true;
    182                         for (org.openstreetmap.josm.data.osm.RelationMember member : relation.getMembers()) {
    183                                 if (member.getMember() == null || member.getMember().isDeleted() || member.getMember().isIncomplete()) {
    184                                         complete = false;
    185                                 }
    186                         }
    187                         return complete && super.accept(relation);
    188                 }
    189         }
    190 
    191         static class RelationMemberImpl {
    192                 private final String role;
    193                 private final Object member;
    194                 public RelationMemberImpl(org.openstreetmap.josm.data.osm.RelationMember originalMember) {
    195                         this.role = originalMember.getRole();
    196                         this.member = originalMember.getMember();
    197                 }
    198                 public String getRole() {
    199                         return role;
    200                 }
    201                 public Object getMember() {
    202                         return member;
    203                 }
    204         }
    205 
    206         private final Set<DataSourceObserver> observers = new HashSet<DataSourceObserver>();
    207 
    208         public void addObserver(DataSourceObserver observer) {
    209                 observers.add(observer);
    210         }
    211 
    212         public void deleteObserver(DataSourceObserver observer) {
    213                 observers.remove(observer);
    214         }
     28    public double getLat(Node node) {
     29        return node.getCoor().lat();
     30    }
     31
     32    public double getLon(Node node) {
     33        return node.getCoor().lon();
     34    }
     35
     36    public Iterable<RelationMember> getMembers(Relation relation) {
     37        return relation.getMembers();
     38    }
     39
     40    public Iterable<Node> getNodes(Way way) {
     41        return new FilteredOsmPrimitiveIterable<Node>(way.getNodes());
     42    }
     43
     44    public Iterable<Node> getNodes() {
     45        return new FilteredOsmPrimitiveIterable<Node>(Main.main.getCurrentDataSet().getNodes());
     46    }
     47
     48    public Iterable<Relation> getRelations() {
     49        return new FilteredRelationIterable(Main.main.getCurrentDataSet().getRelations());
     50    }
     51
     52    public Iterable<Way> getWays() {
     53        return new FilteredOsmPrimitiveIterable<Way>(Main.main.getCurrentDataSet().getWays());
     54    }
     55
     56    public TagGroup getTagsN(Node node) {
     57        return getTags(node);
     58    }
     59
     60    public TagGroup getTagsW(Way way) {
     61        return getTags(way);
     62    }
     63
     64    public TagGroup getTagsR(Relation relation) {
     65        return getTags(relation);
     66    }
     67
     68    private TagGroup getTags(OsmPrimitive primitive) {
     69        if (primitive.getKeys() == null) {
     70            return EMPTY_TAG_GROUP;
     71        } else {
     72            return new MapBasedTagGroup(primitive.getKeys());
     73        }
     74    }
     75
     76    public Object getMember(RelationMember member) {
     77        return member.getMember();
     78    }
     79
     80    public String getRole(RelationMember member) {
     81        return member.getRole();
     82    }
     83
     84    public boolean isNMember(RelationMember member) {
     85        return member.getMember() instanceof Node;
     86    }
     87
     88    public boolean isWMember(RelationMember member) {
     89        return member.getMember() instanceof Way;
     90    }
     91
     92    public boolean isRMember(RelationMember member) {
     93        return member.getMember() instanceof Relation;
     94    }
     95
     96
     97    private static final TagGroup EMPTY_TAG_GROUP;
     98    static {
     99        Map<String, String> emptyMap = new HashMap<String, String>(0);
     100        EMPTY_TAG_GROUP = new MapBasedTagGroup(emptyMap);
     101    }
     102
     103    /**
     104    * Iterable of OsmPrimitive objects based on an existing Iterable,
     105    * will filter incomplete and deleted objects from the iterator.
     106    *
     107    * @param <P>  OsmPrimitive subtype
     108    */
     109    public static class FilteredOsmPrimitiveIterable<P extends OsmPrimitive> implements Iterable<P> {
     110
     111        private final Iterable<P> originalIterable;
     112
     113        public FilteredOsmPrimitiveIterable(Iterable<P> originalIterable) {
     114            this.originalIterable = originalIterable;
     115        }
     116
     117        /** returns an iterator. The iterator does not support {@link Iterator#remove()}. */
     118        public Iterator<P> iterator() {
     119            return new FilteredIterator(originalIterable.iterator());
     120        }
     121
     122        private class FilteredIterator implements Iterator<P> {
     123
     124            private final Iterator<P> originalIterator;
     125
     126            private P next;
     127
     128            public FilteredIterator(Iterator<P> originalIterator) {
     129                this.originalIterator = originalIterator;
     130                updateNext();
     131            }
     132
     133            public boolean hasNext() {
     134                return next != null;
     135            }
     136
     137            public P next() {
     138                if (next != null) {
     139                    P result = next;
     140                    updateNext();
     141                    return result;
     142                } else {
     143                    throw new NoSuchElementException();
     144                }
     145            }
     146
     147            public void remove() {
     148                throw new UnsupportedOperationException();
     149            }
     150
     151            private void updateNext() {
     152                next = null;
     153                while (originalIterator.hasNext()) {
     154                    P originalNext = originalIterator.next();
     155                    if (accept(originalNext)) {
     156                        next = originalNext;
     157                        break;
     158                    }
     159                }
     160            }
     161
     162        }
     163
     164        protected boolean accept(P primitive) {
     165            return !primitive.isDeleted() && !primitive.isIncomplete();
     166        }
     167    }
     168
     169    /**
     170    * Relation-specific variant of the FilteredOsmPrimitiveIterable,
     171    * also checks completeness of relation's members
     172    */
     173    public static class FilteredRelationIterable extends FilteredOsmPrimitiveIterable<Relation> {
     174
     175        public FilteredRelationIterable(Iterable<Relation> originalIterable) {
     176            super(originalIterable);
     177        }
     178
     179        @Override
     180        protected boolean accept(Relation relation) {
     181            boolean complete = true;
     182            for (org.openstreetmap.josm.data.osm.RelationMember member : relation.getMembers()) {
     183                if (member.getMember() == null || member.getMember().isDeleted() || member.getMember().isIncomplete()) {
     184                    complete = false;
     185                }
     186            }
     187            return complete && super.accept(relation);
     188        }
     189    }
     190
     191    static class RelationMemberImpl {
     192        private final String role;
     193        private final Object member;
     194        public RelationMemberImpl(org.openstreetmap.josm.data.osm.RelationMember originalMember) {
     195            this.role = originalMember.getRole();
     196            this.member = originalMember.getMember();
     197        }
     198        public String getRole() {
     199            return role;
     200        }
     201        public Object getMember() {
     202            return member;
     203        }
     204    }
     205
     206    private final Set<DataSourceObserver> observers = new HashSet<DataSourceObserver>();
     207
     208    public void addObserver(DataSourceObserver observer) {
     209        observers.add(observer);
     210    }
     211
     212    public void deleteObserver(DataSourceObserver observer) {
     213        observers.remove(observer);
     214    }
    215215
    216216}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/plugin/data/JOSMTransitionStructure.java

    r19216 r23189  
    1717public class JOSMTransitionStructure extends GenericTransitionStructure<Node, Way, Relation, RelationMember> {
    1818
    19         private static final JOSMDataSource DATA_SOURCE = new JOSMDataSource();
     19    private static final JOSMDataSource DATA_SOURCE = new JOSMDataSource();
    2020
    21         public JOSMTransitionStructure(AccessParameters accessParameters, AccessRuleset ruleset,
    22                         Collection<RoadPropertyType<?>> properties) {
     21    public JOSMTransitionStructure(AccessParameters accessParameters, AccessRuleset ruleset,
     22            Collection<RoadPropertyType<?>> properties) {
    2323
    24                 super(accessParameters, ruleset,
    25                                 DATA_SOURCE,
    26                                 properties);
     24        super(accessParameters, ruleset,
     25                DATA_SOURCE,
     26                properties);
    2727
    28         }
     28    }
    2929
    30         /** causes an update (as if the DataSource had noticed a change) */
    31         public void forceUpdate() {
    32                 super.update(DATA_SOURCE);
    33         }
     30    /** causes an update (as if the DataSource had noticed a change) */
     31    public void forceUpdate() {
     32        super.update(DATA_SOURCE);
     33    }
    3434
    3535}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/plugin/dialogs/AccessParameterDialog.java

    r16520 r23189  
    3838public class AccessParameterDialog extends JDialog {
    3939
    40         public static interface BookmarkAction {
    41                 public void execute(String name, PreferenceAccessParameters parameters);
    42         }
    43 
    44         /**
    45         * map that contains all float value vehicle properties (as those can be treated uniformly)
    46         * and their labels
    47         */
    48         private static final Map<VehiclePropertyType<Float>, String> FLOAT_PROPERTIES;
    49 
    50         static {
    51                 FLOAT_PROPERTIES = new LinkedHashMap<VehiclePropertyType<Float>, String>();
    52                 FLOAT_PROPERTIES.put(VehiclePropertyTypes.HEIGHT, "height (m)");
    53                 FLOAT_PROPERTIES.put(VehiclePropertyTypes.WIDTH, "width (m)");
    54                 FLOAT_PROPERTIES.put(VehiclePropertyTypes.LENGTH, "length (m)");
    55                 FLOAT_PROPERTIES.put(VehiclePropertyTypes.SPEED, "speed (km/h)");
    56                 FLOAT_PROPERTIES.put(VehiclePropertyTypes.WEIGHT, "weight (t)");
    57                 FLOAT_PROPERTIES.put(VehiclePropertyTypes.AXLELOAD, "axleload (t)");
    58         }
    59 
    60         private static final Collection<Character> FORBIDDEN_CHARS =
    61                 Arrays.asList(',', ';', '{', '}', '=', '|');
    62 
    63         private class BookmarkNamePanel extends JPanel {
    64 
    65                 private final JTextField bookmarkNameTextField;
    66 
    67                 public BookmarkNamePanel(String initialName) {
    68                         super();
    69                         this.setBorder(BorderFactory.createTitledBorder("bookmark name"));
    70 
    71                         this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
    72 
    73                         bookmarkNameTextField = new JTextField(initialName);
    74                         this.add(bookmarkNameTextField);
    75 
    76                 }
    77 
    78                 public String getBookmarkName() {
    79 
    80                         String name = bookmarkNameTextField.getText();
    81 
    82                         if (existingBookmarkNames.contains(name)) {
    83                                 JOptionPane.showMessageDialog(this, "Bookmark name already exists!");
    84                                 return null;
    85                         }
    86 
    87                         for (char nameChar : name.toCharArray()) {
    88                                 if (FORBIDDEN_CHARS.contains(nameChar)) {
    89                                         JOptionPane.showMessageDialog(this, "Bookmark name must not contain '" +
    90                                                         nameChar + "'!");
    91                                         return null;
    92                                 }
    93                         }
    94 
    95                         return name;
    96                 }
    97         }
    98 
    99         private static class AccessClassPanel extends JPanel {
    100 
    101                 private final JTextField accessClassTextField;
    102 
    103                 public AccessClassPanel(PreferenceAccessParameters initialParameters) {
    104                         super();
    105                         this.setBorder(BorderFactory.createTitledBorder("access class"));
    106 
    107                         this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
    108 
    109                         accessClassTextField = new JTextField(initialParameters.getAccessClass());
    110                         this.add(accessClassTextField);
    111 
    112                 }
    113 
    114                 public String getAccessClass() {
    115 
    116                         String name = accessClassTextField.getText();
    117 
    118                         for (char nameChar : name.toCharArray()) {
    119                                 if (FORBIDDEN_CHARS.contains(nameChar)) {
    120                                         JOptionPane.showMessageDialog(this, "Access class must not contain '" +
    121                                                         nameChar + "'!");
    122                                         return null;
    123                                 }
    124                         }
    125 
    126                         return name;
    127                 }
    128         }
    129 
    130         private static class AccessTypesPanel extends JPanel {
    131 
    132                 private static final int COLS = 4;
    133 
    134                 private final Map<AccessType, JCheckBox> accessTypeCheckBoxes =
    135                         new EnumMap<AccessType, JCheckBox>(AccessType.class);
    136 
    137                 public AccessTypesPanel(PreferenceAccessParameters initialParameters) {
    138                         super();
    139                         this.setBorder(BorderFactory.createTitledBorder("access types"));
    140 
    141                         this.setLayout(
    142                                         new GridLayout(((COLS-1 + AccessType.values().length) / COLS), COLS));
    143 
    144                         for (AccessType accessType : AccessType.values()) {
    145                                 JCheckBox checkBox = new JCheckBox(accessType.toString());
    146                                 checkBox.setSelected(initialParameters.getAccessTypeUsable(accessType));
    147                                 accessTypeCheckBoxes.put(accessType, checkBox);
    148                                 this.add(checkBox);
    149                         }
    150 
    151                 }
    152 
    153                 public Collection<AccessType> getUsableAccessTypes() {
    154 
    155                         Collection<AccessType> usableAccessTypes = new LinkedList<AccessType>();
    156 
    157                         for (AccessType accessType : AccessType.values()) {
    158                                 if (accessTypeCheckBoxes.get(accessType).isSelected()) {
    159                                         usableAccessTypes.add(accessType);
    160                                 }
    161                         }
    162 
    163                         return usableAccessTypes;
    164                 }
    165         }
    166 
    167         private static class VehiclePropertiesPanel extends JPanel {
    168 
    169                 private static final int COLS = 2;
    170 
    171                 private final Map<VehiclePropertyType<Float>, JTextField> floatPropertyTextFields =
    172                         new HashMap<VehiclePropertyType<Float>, JTextField>();
    173 
    174                 public VehiclePropertiesPanel(PreferenceAccessParameters initialParameters) {
    175                         super();
    176                         this.setBorder(BorderFactory.createTitledBorder("vehicle properties"));
    177 
    178                         this.setLayout(new GridLayout(((COLS-1 + FLOAT_PROPERTIES.size()) / COLS),
    179                                         2*COLS));
    180 
    181                         for (VehiclePropertyType<Float> vehicleProperty : FLOAT_PROPERTIES.keySet()) {
    182 
    183                                 JLabel label = new JLabel(FLOAT_PROPERTIES.get(vehicleProperty));
    184                                 this.add(label);
    185 
    186                                 JTextField textField = new JTextField();
    187 
    188                                 String vehiclePropertyString =
    189                                         initialParameters.getVehiclePropertyString(vehicleProperty);
    190                                 if (vehiclePropertyString != null) {
    191                                         textField.setText(vehiclePropertyString);
    192                                 }
    193 
    194                                 floatPropertyTextFields.put(vehicleProperty, textField);
    195                                 this.add(textField);
    196                         }
    197 
    198                 }
    199 
    200                 public Map<VehiclePropertyType<?>, String> getVehiclePropertyStrings() {
    201 
    202                         Map<VehiclePropertyType<?>, String> vehiclePropertyStrings =
    203                                 new HashMap<VehiclePropertyType<?>, String>();
    204 
    205                         for (VehiclePropertyType<Float> vehicleProperty : floatPropertyTextFields.keySet()) {
    206                                 String textFieldContent = floatPropertyTextFields.get(vehicleProperty).getText();
    207                                 if (textFieldContent.trim().length() > 0) {
    208                                         vehiclePropertyStrings.put(vehicleProperty, textFieldContent);
    209                                 }
    210                         }
    211 
    212                         return vehiclePropertyStrings;
    213                 }
    214         }
    215 
    216         private static class RoadQualityPanel extends JPanel {
    217 
    218                 private JTextField inclineUpTextField;
    219                 private JTextField inclineDownTextField;
    220                 private JTextField surfaceTextField;
    221                 private JTextField tracktypeTextField;
    222 
    223                 public RoadQualityPanel(PreferenceAccessParameters initialParameters) {
    224                         super();
    225                         this.setBorder(BorderFactory.createTitledBorder("road requirements"));
    226 
    227 
    228                         this.setLayout(new GridLayout(4, 2));
    229 
    230                         /* incline up */
    231                         {
    232                                 JLabel inclineUpLabel = new JLabel("max. incline up (%, pos.)");
    233                                 inclineUpLabel.setToolTipText("maximum incline the vehicle can go up");
    234                                 this.add(inclineUpLabel);
    235 
    236                                 inclineUpTextField = new JTextField();
    237 
    238                                 String vehiclePropertyString =
    239                                         initialParameters.getVehiclePropertyString(MAX_INCLINE_UP);
    240                                 if (vehiclePropertyString != null) {
    241                                         inclineUpTextField.setText(vehiclePropertyString);
    242                                 }
    243                                 inclineUpTextField.setToolTipText("maximum incline the vehicle can go up");
    244 
    245                                 this.add(inclineUpTextField);
    246                         }
    247 
    248                         /* incline down */
    249                         {
    250                                 JLabel inclineDownLabel = new JLabel("max. incline down (%, pos.)");
    251                                 inclineDownLabel.setToolTipText("maximum incline the vehicle can go down");
    252                                 this.add(inclineDownLabel);
    253 
    254                                 inclineDownTextField = new JTextField();
    255 
    256                                 String vehiclePropertyString =
    257                                         initialParameters.getVehiclePropertyString(MAX_INCLINE_DOWN);
    258                                 if (vehiclePropertyString != null) {
    259                                         inclineDownTextField.setText(vehiclePropertyString);
    260                                 }
    261                                 inclineDownTextField.setToolTipText("maximum incline the vehicle can go down");
    262 
    263                                 this.add(inclineDownTextField);
    264                         }
    265 
    266                         /* surface */
    267                         {
    268                                 JLabel surfaceLabel = new JLabel("surface blacklist");
    269                                 surfaceLabel.setToolTipText("list of surfaces the vehicle cannot use, "
    270                                                 + "values are separated by semicolons (;)");
    271                                 this.add(surfaceLabel);
    272 
    273                                 surfaceTextField = new JTextField();
    274 
    275                                 String vehiclePropertyString =
    276                                         initialParameters.getVehiclePropertyString(SURFACE_BLACKLIST);
    277 
    278                                 if (vehiclePropertyString != null) {
    279                                         surfaceTextField.setText(vehiclePropertyString);
    280                                 }
    281 
    282                                 surfaceTextField.setToolTipText("list of surfaces the vehicle cannot use, "
    283                                                 + "values are separated by semicolons (;)");
    284 
    285                                 this.add(surfaceTextField);
    286                         }
    287 
    288                         /* tracktype */
    289                         {
    290                                 JLabel tracktypeLabel = new JLabel("max. tracktype grade");
    291                                 tracktypeLabel.setToolTipText("worst tracktype (1-5) the vehicle can still use,"
    292                                                 + " 0 for none");
    293                                 this.add(tracktypeLabel);
    294 
    295                                 tracktypeTextField = new JTextField();
    296 
    297                                 String vehiclePropertyString =
    298                                         initialParameters.getVehiclePropertyString(MAX_TRACKTYPE);
    299                                 if (vehiclePropertyString != null) {
    300                                         tracktypeTextField.setText(vehiclePropertyString);
    301                                 }
    302                                 tracktypeTextField.setToolTipText("worst tracktype (1-5) the vehicle can still use,"
    303                                                 + " 0 for none");
    304 
    305                                 this.add(tracktypeTextField);
    306                         }
    307 
    308                 }
    309 
    310                 public Map<VehiclePropertyType<?>, String> getVehiclePropertyStrings() {
    311 
    312                         Map<VehiclePropertyType<?>, String> vehiclePropertyStrings =
    313                                 new HashMap<VehiclePropertyType<?>, String>();
    314 
    315                         String incUpString = inclineUpTextField.getText();
    316                         if (incUpString.trim().length() > 0) {
    317                                 vehiclePropertyStrings.put(MAX_INCLINE_UP, incUpString);
    318                         }
    319 
    320                         String incDownString = inclineDownTextField.getText();
    321                         if (incDownString.trim().length() > 0) {
    322                                 vehiclePropertyStrings.put(MAX_INCLINE_DOWN, incDownString);
    323                         }
    324 
    325                         String surfaceString = surfaceTextField.getText();
    326                         if (surfaceString.trim().length() > 0) {
    327                                 vehiclePropertyStrings.put(SURFACE_BLACKLIST, surfaceString);
    328                         }
    329 
    330                         String tracktypeString = tracktypeTextField.getText();
    331                         if (tracktypeString.trim().length() > 0) {
    332                                 vehiclePropertyStrings.put(MAX_TRACKTYPE, tracktypeString);
    333                         }
    334 
    335                         return vehiclePropertyStrings;
    336                 }
    337         }
    338 
    339         private class OkCancelPanel extends JPanel {
    340 
    341                 public OkCancelPanel() {
    342 
    343                         new BoxLayout(this, BoxLayout.X_AXIS);
    344 
    345                         JButton okButton = new JButton(existingBookmark?"Change bookmark":"Create bookmark");
    346                         okButton.addActionListener(new ActionListener() {
    347                                 public void actionPerformed(ActionEvent e) {
    348                                         String bookmarkName = bookmarkNamePanel.getBookmarkName();
    349                                         if (bookmarkName != null) {
    350                                                 PreferenceAccessParameters parameters = getAccessParameters();
    351                                                 if (parameters != null) {
    352                                                         okAction.execute(bookmarkName, parameters);
    353                                                         AccessParameterDialog.this.dispose();
    354                                                 }
    355                                         }
    356                                 }
    357                         });
    358                         this.add(okButton);
    359 
    360                         JButton cancelButton = new JButton("Cancel");
    361                         cancelButton.addActionListener(new ActionListener() {
    362                                 public void actionPerformed(ActionEvent e) {
    363                                         AccessParameterDialog.this.dispose();
    364                                 }
    365                         });
    366                         this.add(cancelButton);
    367 
    368                 }
    369 
    370         }
    371 
    372         private boolean existingBookmark = false;
    373         private final Collection<String> existingBookmarkNames;
    374 
    375         private final BookmarkAction okAction;
    376 
    377         private final BookmarkNamePanel bookmarkNamePanel;
    378         private final AccessClassPanel accessClassPanel;
    379         private final AccessTypesPanel accessTypesPanel;
    380         private final VehiclePropertiesPanel vehiclePropertiesPanel;
    381         private final RoadQualityPanel roadQualityPanel;
    382 
    383         public AccessParameterDialog(final Frame owner, boolean existingBookmark, String initialName,
    384                         Collection<String> existingBookmarkNames,
    385                         PreferenceAccessParameters initialAccessParameters, BookmarkAction okAction) {
    386                 super(owner, "edit access parameters", true);
    387 
    388                 this.existingBookmark = existingBookmark;
    389                 this.existingBookmarkNames = existingBookmarkNames;
    390                 this.okAction = okAction;
    391 
    392                 GridBagLayout layout = new GridBagLayout();
    393                 this.setLayout(layout);
    394 
    395                 GridBagConstraints gbc = new GridBagConstraints();
    396                 gbc.gridx = 0;
    397                 gbc.weighty = 1;
    398                 gbc.fill = GridBagConstraints.BOTH;
    399 
    400                 bookmarkNamePanel = new BookmarkNamePanel(initialName);
    401                 gbc.gridy = 0;
    402                 layout.setConstraints(bookmarkNamePanel, gbc);
    403                 this.add(bookmarkNamePanel);
    404 
    405                 accessClassPanel = new AccessClassPanel(initialAccessParameters);
    406                 gbc.gridy = 1;
    407                 layout.setConstraints(accessClassPanel, gbc);
    408                 this.add(accessClassPanel);
    409 
    410                 accessTypesPanel = new AccessTypesPanel(initialAccessParameters);
    411                 gbc.gridy = 2;
    412                 layout.setConstraints(accessTypesPanel, gbc);
    413                 this.add(accessTypesPanel);
    414 
    415                 vehiclePropertiesPanel = new VehiclePropertiesPanel(initialAccessParameters);
    416                 gbc.gridy = 3;
    417                 layout.setConstraints(vehiclePropertiesPanel, gbc);
    418                 this.add(vehiclePropertiesPanel);
    419 
    420                 roadQualityPanel = new RoadQualityPanel(initialAccessParameters);
    421                 gbc.gridy = 4;
    422                 layout.setConstraints(roadQualityPanel, gbc);
    423                 this.add(roadQualityPanel);
    424 
    425                 JPanel okCancelPanel = new OkCancelPanel();
    426                 gbc.gridy = 5;
    427                 gbc.weighty = 0;
    428                 gbc.fill = GridBagConstraints.HORIZONTAL;
    429                 layout.setConstraints(okCancelPanel, gbc);
    430                 this.add(okCancelPanel);
    431 
    432                 this.pack();
    433         }
    434 
    435         private PreferenceAccessParameters getAccessParameters() {
    436 
    437                 String accessClass = accessClassPanel.getAccessClass();
    438                 Collection<AccessType> usableAccessTypes = accessTypesPanel.getUsableAccessTypes();
    439                 Map<VehiclePropertyType<?>, String> vehiclePropertyStrings =
    440                         vehiclePropertiesPanel.getVehiclePropertyStrings();
    441                 Map<VehiclePropertyType<?>, String> additionalVehiclePropertyStrings =
    442                         roadQualityPanel.getVehiclePropertyStrings();
    443 
    444                 if (accessClass != null && usableAccessTypes != null && vehiclePropertyStrings != null
    445                                 && additionalVehiclePropertyStrings != null) {
    446 
    447                         vehiclePropertyStrings.putAll(additionalVehiclePropertyStrings);
    448 
    449                         try {
    450                                 return new PreferenceAccessParameters(accessClass, usableAccessTypes, vehiclePropertyStrings);
    451                         } catch (PropertyValueSyntaxException e) {
    452                                 JOptionPane.showMessageDialog(this, e.getMessage());
    453                                 return null;
    454                         }
    455 
    456                 } else {
    457                         return null;
    458                 }
    459         }
     40    public static interface BookmarkAction {
     41        public void execute(String name, PreferenceAccessParameters parameters);
     42    }
     43
     44    /**
     45    * map that contains all float value vehicle properties (as those can be treated uniformly)
     46    * and their labels
     47    */
     48    private static final Map<VehiclePropertyType<Float>, String> FLOAT_PROPERTIES;
     49
     50    static {
     51        FLOAT_PROPERTIES = new LinkedHashMap<VehiclePropertyType<Float>, String>();
     52        FLOAT_PROPERTIES.put(VehiclePropertyTypes.HEIGHT, "height (m)");
     53        FLOAT_PROPERTIES.put(VehiclePropertyTypes.WIDTH, "width (m)");
     54        FLOAT_PROPERTIES.put(VehiclePropertyTypes.LENGTH, "length (m)");
     55        FLOAT_PROPERTIES.put(VehiclePropertyTypes.SPEED, "speed (km/h)");
     56        FLOAT_PROPERTIES.put(VehiclePropertyTypes.WEIGHT, "weight (t)");
     57        FLOAT_PROPERTIES.put(VehiclePropertyTypes.AXLELOAD, "axleload (t)");
     58    }
     59
     60    private static final Collection<Character> FORBIDDEN_CHARS =
     61        Arrays.asList(',', ';', '{', '}', '=', '|');
     62
     63    private class BookmarkNamePanel extends JPanel {
     64
     65        private final JTextField bookmarkNameTextField;
     66
     67        public BookmarkNamePanel(String initialName) {
     68            super();
     69            this.setBorder(BorderFactory.createTitledBorder("bookmark name"));
     70
     71            this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
     72
     73            bookmarkNameTextField = new JTextField(initialName);
     74            this.add(bookmarkNameTextField);
     75
     76        }
     77
     78        public String getBookmarkName() {
     79
     80            String name = bookmarkNameTextField.getText();
     81
     82            if (existingBookmarkNames.contains(name)) {
     83                JOptionPane.showMessageDialog(this, "Bookmark name already exists!");
     84                return null;
     85            }
     86
     87            for (char nameChar : name.toCharArray()) {
     88                if (FORBIDDEN_CHARS.contains(nameChar)) {
     89                    JOptionPane.showMessageDialog(this, "Bookmark name must not contain '" +
     90                            nameChar + "'!");
     91                    return null;
     92                }
     93            }
     94
     95            return name;
     96        }
     97    }
     98
     99    private static class AccessClassPanel extends JPanel {
     100
     101        private final JTextField accessClassTextField;
     102
     103        public AccessClassPanel(PreferenceAccessParameters initialParameters) {
     104            super();
     105            this.setBorder(BorderFactory.createTitledBorder("access class"));
     106
     107            this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
     108
     109            accessClassTextField = new JTextField(initialParameters.getAccessClass());
     110            this.add(accessClassTextField);
     111
     112        }
     113
     114        public String getAccessClass() {
     115
     116            String name = accessClassTextField.getText();
     117
     118            for (char nameChar : name.toCharArray()) {
     119                if (FORBIDDEN_CHARS.contains(nameChar)) {
     120                    JOptionPane.showMessageDialog(this, "Access class must not contain '" +
     121                            nameChar + "'!");
     122                    return null;
     123                }
     124            }
     125
     126            return name;
     127        }
     128    }
     129
     130    private static class AccessTypesPanel extends JPanel {
     131
     132        private static final int COLS = 4;
     133
     134        private final Map<AccessType, JCheckBox> accessTypeCheckBoxes =
     135            new EnumMap<AccessType, JCheckBox>(AccessType.class);
     136
     137        public AccessTypesPanel(PreferenceAccessParameters initialParameters) {
     138            super();
     139            this.setBorder(BorderFactory.createTitledBorder("access types"));
     140
     141            this.setLayout(
     142                    new GridLayout(((COLS-1 + AccessType.values().length) / COLS), COLS));
     143
     144            for (AccessType accessType : AccessType.values()) {
     145                JCheckBox checkBox = new JCheckBox(accessType.toString());
     146                checkBox.setSelected(initialParameters.getAccessTypeUsable(accessType));
     147                accessTypeCheckBoxes.put(accessType, checkBox);
     148                this.add(checkBox);
     149            }
     150
     151        }
     152
     153        public Collection<AccessType> getUsableAccessTypes() {
     154
     155            Collection<AccessType> usableAccessTypes = new LinkedList<AccessType>();
     156
     157            for (AccessType accessType : AccessType.values()) {
     158                if (accessTypeCheckBoxes.get(accessType).isSelected()) {
     159                    usableAccessTypes.add(accessType);
     160                }
     161            }
     162
     163            return usableAccessTypes;
     164        }
     165    }
     166
     167    private static class VehiclePropertiesPanel extends JPanel {
     168
     169        private static final int COLS = 2;
     170
     171        private final Map<VehiclePropertyType<Float>, JTextField> floatPropertyTextFields =
     172            new HashMap<VehiclePropertyType<Float>, JTextField>();
     173
     174        public VehiclePropertiesPanel(PreferenceAccessParameters initialParameters) {
     175            super();
     176            this.setBorder(BorderFactory.createTitledBorder("vehicle properties"));
     177
     178            this.setLayout(new GridLayout(((COLS-1 + FLOAT_PROPERTIES.size()) / COLS),
     179                    2*COLS));
     180
     181            for (VehiclePropertyType<Float> vehicleProperty : FLOAT_PROPERTIES.keySet()) {
     182
     183                JLabel label = new JLabel(FLOAT_PROPERTIES.get(vehicleProperty));
     184                this.add(label);
     185
     186                JTextField textField = new JTextField();
     187
     188                String vehiclePropertyString =
     189                    initialParameters.getVehiclePropertyString(vehicleProperty);
     190                if (vehiclePropertyString != null) {
     191                    textField.setText(vehiclePropertyString);
     192                }
     193
     194                floatPropertyTextFields.put(vehicleProperty, textField);
     195                this.add(textField);
     196            }
     197
     198        }
     199
     200        public Map<VehiclePropertyType<?>, String> getVehiclePropertyStrings() {
     201
     202            Map<VehiclePropertyType<?>, String> vehiclePropertyStrings =
     203                new HashMap<VehiclePropertyType<?>, String>();
     204
     205            for (VehiclePropertyType<Float> vehicleProperty : floatPropertyTextFields.keySet()) {
     206                String textFieldContent = floatPropertyTextFields.get(vehicleProperty).getText();
     207                if (textFieldContent.trim().length() > 0) {
     208                    vehiclePropertyStrings.put(vehicleProperty, textFieldContent);
     209                }
     210            }
     211
     212            return vehiclePropertyStrings;
     213        }
     214    }
     215
     216    private static class RoadQualityPanel extends JPanel {
     217
     218        private JTextField inclineUpTextField;
     219        private JTextField inclineDownTextField;
     220        private JTextField surfaceTextField;
     221        private JTextField tracktypeTextField;
     222
     223        public RoadQualityPanel(PreferenceAccessParameters initialParameters) {
     224            super();
     225            this.setBorder(BorderFactory.createTitledBorder("road requirements"));
     226
     227
     228            this.setLayout(new GridLayout(4, 2));
     229
     230            /* incline up */
     231            {
     232                JLabel inclineUpLabel = new JLabel("max. incline up (%, pos.)");
     233                inclineUpLabel.setToolTipText("maximum incline the vehicle can go up");
     234                this.add(inclineUpLabel);
     235
     236                inclineUpTextField = new JTextField();
     237
     238                String vehiclePropertyString =
     239                    initialParameters.getVehiclePropertyString(MAX_INCLINE_UP);
     240                if (vehiclePropertyString != null) {
     241                    inclineUpTextField.setText(vehiclePropertyString);
     242                }
     243                inclineUpTextField.setToolTipText("maximum incline the vehicle can go up");
     244
     245                this.add(inclineUpTextField);
     246            }
     247
     248            /* incline down */
     249            {
     250                JLabel inclineDownLabel = new JLabel("max. incline down (%, pos.)");
     251                inclineDownLabel.setToolTipText("maximum incline the vehicle can go down");
     252                this.add(inclineDownLabel);
     253
     254                inclineDownTextField = new JTextField();
     255
     256                String vehiclePropertyString =
     257                    initialParameters.getVehiclePropertyString(MAX_INCLINE_DOWN);
     258                if (vehiclePropertyString != null) {
     259                    inclineDownTextField.setText(vehiclePropertyString);
     260                }
     261                inclineDownTextField.setToolTipText("maximum incline the vehicle can go down");
     262
     263                this.add(inclineDownTextField);
     264            }
     265
     266            /* surface */
     267            {
     268                JLabel surfaceLabel = new JLabel("surface blacklist");
     269                surfaceLabel.setToolTipText("list of surfaces the vehicle cannot use, "
     270                        + "values are separated by semicolons (;)");
     271                this.add(surfaceLabel);
     272
     273                surfaceTextField = new JTextField();
     274
     275                String vehiclePropertyString =
     276                    initialParameters.getVehiclePropertyString(SURFACE_BLACKLIST);
     277
     278                if (vehiclePropertyString != null) {
     279                    surfaceTextField.setText(vehiclePropertyString);
     280                }
     281
     282                surfaceTextField.setToolTipText("list of surfaces the vehicle cannot use, "
     283                        + "values are separated by semicolons (;)");
     284
     285                this.add(surfaceTextField);
     286            }
     287
     288            /* tracktype */
     289            {
     290                JLabel tracktypeLabel = new JLabel("max. tracktype grade");
     291                tracktypeLabel.setToolTipText("worst tracktype (1-5) the vehicle can still use,"
     292                        + " 0 for none");
     293                this.add(tracktypeLabel);
     294
     295                tracktypeTextField = new JTextField();
     296
     297                String vehiclePropertyString =
     298                    initialParameters.getVehiclePropertyString(MAX_TRACKTYPE);
     299                if (vehiclePropertyString != null) {
     300                    tracktypeTextField.setText(vehiclePropertyString);
     301                }
     302                tracktypeTextField.setToolTipText("worst tracktype (1-5) the vehicle can still use,"
     303                        + " 0 for none");
     304
     305                this.add(tracktypeTextField);
     306            }
     307
     308        }
     309
     310        public Map<VehiclePropertyType<?>, String> getVehiclePropertyStrings() {
     311
     312            Map<VehiclePropertyType<?>, String> vehiclePropertyStrings =
     313                new HashMap<VehiclePropertyType<?>, String>();
     314
     315            String incUpString = inclineUpTextField.getText();
     316            if (incUpString.trim().length() > 0) {
     317                vehiclePropertyStrings.put(MAX_INCLINE_UP, incUpString);
     318            }
     319
     320            String incDownString = inclineDownTextField.getText();
     321            if (incDownString.trim().length() > 0) {
     322                vehiclePropertyStrings.put(MAX_INCLINE_DOWN, incDownString);
     323            }
     324
     325            String surfaceString = surfaceTextField.getText();
     326            if (surfaceString.trim().length() > 0) {
     327                vehiclePropertyStrings.put(SURFACE_BLACKLIST, surfaceString);
     328            }
     329
     330            String tracktypeString = tracktypeTextField.getText();
     331            if (tracktypeString.trim().length() > 0) {
     332                vehiclePropertyStrings.put(MAX_TRACKTYPE, tracktypeString);
     333            }
     334
     335            return vehiclePropertyStrings;
     336        }
     337    }
     338
     339    private class OkCancelPanel extends JPanel {
     340
     341        public OkCancelPanel() {
     342
     343            new BoxLayout(this, BoxLayout.X_AXIS);
     344
     345            JButton okButton = new JButton(existingBookmark?"Change bookmark":"Create bookmark");
     346            okButton.addActionListener(new ActionListener() {
     347                public void actionPerformed(ActionEvent e) {
     348                    String bookmarkName = bookmarkNamePanel.getBookmarkName();
     349                    if (bookmarkName != null) {
     350                        PreferenceAccessParameters parameters = getAccessParameters();
     351                        if (parameters != null) {
     352                            okAction.execute(bookmarkName, parameters);
     353                            AccessParameterDialog.this.dispose();
     354                        }
     355                    }
     356                }
     357            });
     358            this.add(okButton);
     359
     360            JButton cancelButton = new JButton("Cancel");
     361            cancelButton.addActionListener(new ActionListener() {
     362                public void actionPerformed(ActionEvent e) {
     363                    AccessParameterDialog.this.dispose();
     364                }
     365            });
     366            this.add(cancelButton);
     367
     368        }
     369
     370    }
     371
     372    private boolean existingBookmark = false;
     373    private final Collection<String> existingBookmarkNames;
     374
     375    private final BookmarkAction okAction;
     376
     377    private final BookmarkNamePanel bookmarkNamePanel;
     378    private final AccessClassPanel accessClassPanel;
     379    private final AccessTypesPanel accessTypesPanel;
     380    private final VehiclePropertiesPanel vehiclePropertiesPanel;
     381    private final RoadQualityPanel roadQualityPanel;
     382
     383    public AccessParameterDialog(final Frame owner, boolean existingBookmark, String initialName,
     384            Collection<String> existingBookmarkNames,
     385            PreferenceAccessParameters initialAccessParameters, BookmarkAction okAction) {
     386        super(owner, "edit access parameters", true);
     387
     388        this.existingBookmark = existingBookmark;
     389        this.existingBookmarkNames = existingBookmarkNames;
     390        this.okAction = okAction;
     391
     392        GridBagLayout layout = new GridBagLayout();
     393        this.setLayout(layout);
     394
     395        GridBagConstraints gbc = new GridBagConstraints();
     396        gbc.gridx = 0;
     397        gbc.weighty = 1;
     398        gbc.fill = GridBagConstraints.BOTH;
     399
     400        bookmarkNamePanel = new BookmarkNamePanel(initialName);
     401        gbc.gridy = 0;
     402        layout.setConstraints(bookmarkNamePanel, gbc);
     403        this.add(bookmarkNamePanel);
     404
     405        accessClassPanel = new AccessClassPanel(initialAccessParameters);
     406        gbc.gridy = 1;
     407        layout.setConstraints(accessClassPanel, gbc);
     408        this.add(accessClassPanel);
     409
     410        accessTypesPanel = new AccessTypesPanel(initialAccessParameters);
     411        gbc.gridy = 2;
     412        layout.setConstraints(accessTypesPanel, gbc);
     413        this.add(accessTypesPanel);
     414
     415        vehiclePropertiesPanel = new VehiclePropertiesPanel(initialAccessParameters);
     416        gbc.gridy = 3;
     417        layout.setConstraints(vehiclePropertiesPanel, gbc);
     418        this.add(vehiclePropertiesPanel);
     419
     420        roadQualityPanel = new RoadQualityPanel(initialAccessParameters);
     421        gbc.gridy = 4;
     422        layout.setConstraints(roadQualityPanel, gbc);
     423        this.add(roadQualityPanel);
     424
     425        JPanel okCancelPanel = new OkCancelPanel();
     426        gbc.gridy = 5;
     427        gbc.weighty = 0;
     428        gbc.fill = GridBagConstraints.HORIZONTAL;
     429        layout.setConstraints(okCancelPanel, gbc);
     430        this.add(okCancelPanel);
     431
     432        this.pack();
     433    }
     434
     435    private PreferenceAccessParameters getAccessParameters() {
     436
     437        String accessClass = accessClassPanel.getAccessClass();
     438        Collection<AccessType> usableAccessTypes = accessTypesPanel.getUsableAccessTypes();
     439        Map<VehiclePropertyType<?>, String> vehiclePropertyStrings =
     440            vehiclePropertiesPanel.getVehiclePropertyStrings();
     441        Map<VehiclePropertyType<?>, String> additionalVehiclePropertyStrings =
     442            roadQualityPanel.getVehiclePropertyStrings();
     443
     444        if (accessClass != null && usableAccessTypes != null && vehiclePropertyStrings != null
     445                && additionalVehiclePropertyStrings != null) {
     446
     447            vehiclePropertyStrings.putAll(additionalVehiclePropertyStrings);
     448
     449            try {
     450                return new PreferenceAccessParameters(accessClass, usableAccessTypes, vehiclePropertyStrings);
     451            } catch (PropertyValueSyntaxException e) {
     452                JOptionPane.showMessageDialog(this, e.getMessage());
     453                return null;
     454            }
     455
     456        } else {
     457            return null;
     458        }
     459    }
    460460
    461461}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/plugin/dialogs/GraphViewDialog.java

    r16520 r23189  
    4444public class GraphViewDialog extends ToggleDialog implements Observer {
    4545
    46         private static final int HEIGHT = 150;
    47 
    48         /** map from labels to available color schemes */
    49         private final LinkedHashMap<String, ColorScheme> availableColorSchemes;
    50 
    51 
    52         private final GraphViewPreferences preferences;
    53         private final GraphViewPlugin plugin;
    54 
    55         private final JComboBox rulesetComboBox;
    56         private final JComboBox bookmarkComboBox;
    57         private final JComboBox colorSchemeComboBox;
    58 
    59         /**
    60         * list of ruleset files in the order currently used by rulesetComboBox;
    61         * null if internal rulesets are used
    62         */
    63         private List<File> rulesetFiles;
    64 
    65         public GraphViewDialog(final GraphViewPlugin plugin) {
    66 
    67                 super("Graph View Dialog", "graphview",
    68                                 "Open the dialog for graph view configuration.", (Shortcut)null, HEIGHT);
    69 
    70                 this.preferences = GraphViewPreferences.getInstance();
    71                 this.plugin = plugin;
    72 
    73                 availableColorSchemes = new LinkedHashMap<String, ColorScheme>();
    74 
    75                 availableColorSchemes.put("default",
    76                                 new PreferencesColorScheme(preferences));
    77                 availableColorSchemes.put("end nodes",
    78                                 new EndNodeColorScheme(Color.GRAY, Color.RED, Color.GRAY));
    79                 availableColorSchemes.put("maxspeed",
    80                                 new MaxspeedColorScheme());
    81                 availableColorSchemes.put("maxweight",
    82                                 new MaxweightColorScheme());
    83                 availableColorSchemes.put("maxheight",
    84                                 new MaxheightColorScheme());
    85                 availableColorSchemes.put("incline",
    86                                 new InclineColorScheme());
    87 
    88                 JPanel selectionPanel = new JPanel();
    89                 GridBagLayout selectionLayout = new GridBagLayout();
    90                 selectionPanel.setLayout(selectionLayout);
    91 
    92                 GridBagConstraints gbcLabel = new GridBagConstraints();
    93                 gbcLabel.gridx = 0;
    94                 gbcLabel.anchor = GridBagConstraints.WEST;
    95                 gbcLabel.insets = new Insets(0, 5, 0, 5);
    96 
    97                 GridBagConstraints gbcComboBox = new GridBagConstraints();
    98                 gbcComboBox.gridx = 1;
    99                 gbcComboBox.fill = GridBagConstraints.HORIZONTAL;
    100                 gbcComboBox.weightx = 1;
    101 
    102 
    103                 /* create ruleset label and combo box */
    104                 {
    105                         JLabel rulesetLabel = new JLabel("ruleset:");
    106                         gbcLabel.gridy = 0;
    107                         selectionLayout.setConstraints(rulesetLabel, gbcLabel);
    108                         selectionPanel.add(rulesetLabel);
    109 
    110                         rulesetComboBox = new JComboBox();
    111                         rulesetComboBox.addActionListener(rulesetActionListener);
    112                         gbcComboBox.gridy = 0;
    113                         selectionLayout.setConstraints(rulesetComboBox, gbcComboBox);
    114                         selectionPanel.add(rulesetComboBox);
    115                 }
    116 
    117                 /* create bookmark label and combo box */
    118                 {
    119                         JLabel bookmarkLabel = new JLabel("parameters:");
    120                         gbcLabel.gridy = 1;
    121                         selectionLayout.setConstraints(bookmarkLabel, gbcLabel);
    122                         selectionPanel.add(bookmarkLabel);
    123 
    124                         bookmarkComboBox = new JComboBox();
    125                         bookmarkComboBox.addActionListener(bookmarkActionListener);
    126                         gbcComboBox.gridy = 1;
    127                         selectionLayout.setConstraints(bookmarkComboBox, gbcComboBox);
    128                         selectionPanel.add(bookmarkComboBox);
    129                 }
    130 
    131                 /* create color scheme label and combo box */
    132                 {
    133                         JLabel colorSchemeLabel = new JLabel("coloring:");
    134                         gbcLabel.gridy = 2;
    135                         selectionLayout.setConstraints(colorSchemeLabel, gbcLabel);
    136                         selectionPanel.add(colorSchemeLabel);
    137 
    138                         colorSchemeComboBox = new JComboBox();
    139                         for (String colorSchemeName : availableColorSchemes.keySet()) {
    140                                 colorSchemeComboBox.addItem(colorSchemeName);
    141                                 ColorScheme colorScheme = availableColorSchemes.get(colorSchemeName);
    142                                 if (colorScheme.getClass().equals(preferences.getCurrentColorScheme().getClass())) {
    143                                         colorSchemeComboBox.setSelectedItem(colorSchemeName);
    144                                 }
    145                         }
    146                         colorSchemeComboBox.addActionListener(colorSchemeActionListener);
    147                         gbcComboBox.gridy = 2;
    148                         selectionLayout.setConstraints(colorSchemeComboBox, gbcComboBox);
    149                         selectionPanel.add(colorSchemeComboBox);
    150                 }
    151 
    152                 this.add(BorderLayout.CENTER, selectionPanel);
    153 
    154 
    155                 JPanel buttonPanel = new JPanel();
    156                 JButton showLayerButton = new JButton("create/update graph");
    157                 showLayerButton.addActionListener(new ActionListener() {
    158                         public void actionPerformed(ActionEvent e) {
    159                                 plugin.createGraphViewLayer();
    160                         }
    161                 });
    162                 buttonPanel.add(showLayerButton);
    163 
    164                 this.add(BorderLayout.SOUTH, buttonPanel);
    165 
    166                 updateSelections();
    167                 this.preferences.addObserver(this);
    168 
    169         }
    170 
    171         private final ActionListener rulesetActionListener = new ActionListener() {
    172                 public void actionPerformed(ActionEvent e) {
    173                         if (rulesetComboBox.getSelectedItem() != null) {
    174                                 int selectedRulesetIndex = rulesetComboBox.getSelectedIndex();
    175                                 if (rulesetFiles != null) {
    176                                         File selectedRulesetFile = rulesetFiles.get(selectedRulesetIndex);
    177                                         preferences.setCurrentRulesetFile(selectedRulesetFile);
    178                                         preferences.distributeChanges();
    179                                         plugin.updateGraphViewLayer();
    180                                 } else {
    181                                         if (selectedRulesetIndex < InternalRuleset.values().length) {
    182                                                 InternalRuleset selectedIRR = InternalRuleset.values()[selectedRulesetIndex];
    183                                                 preferences.setCurrentInternalRuleset(selectedIRR);
    184                                                 preferences.distributeChanges();
    185                                                 plugin.updateGraphViewLayer();
    186                                         }
    187                                 }
    188                         }
    189                 }
    190         };
    191 
    192         private final ActionListener bookmarkActionListener = new ActionListener() {
    193                 public void actionPerformed(ActionEvent e) {
    194                         String selectedBookmarkName = (String)bookmarkComboBox.getSelectedItem();
    195                         if (selectedBookmarkName != null) {
    196                                 preferences.setCurrentParameterBookmarkName(selectedBookmarkName);
    197                                 preferences.distributeChanges();
    198                                 plugin.updateGraphViewLayer();
    199                         }
    200                 }
    201         };
    202 
    203         private final ActionListener colorSchemeActionListener = new ActionListener() {
    204                 public void actionPerformed(ActionEvent e) {
    205                         assert availableColorSchemes.containsKey(colorSchemeComboBox.getSelectedItem());
    206                         String colorSchemeLabel = (String)colorSchemeComboBox.getSelectedItem();
    207                         preferences.setCurrentColorScheme(availableColorSchemes.get(colorSchemeLabel));
    208                         preferences.distributeChanges();
    209                         plugin.repaintGraphViewLayer();
    210                 }
    211         };
    212 
    213         public void update(Observable observable, Object param) {
    214                 if (observable == preferences) {
    215                         updateSelections();
    216                 }
    217         }
    218 
    219         protected void updateSelections() {
    220 
    221                 /* update rulesets */
    222 
    223                 rulesetComboBox.removeActionListener(rulesetActionListener);
    224 
    225                 if (preferences.getUseInternalRulesets()) {
    226 
    227                         rulesetFiles = null;
    228 
    229                         rulesetComboBox.removeAllItems();
    230                         for (int i=0; i < InternalRuleset.values().length; i++) {
    231                                 InternalRuleset ruleset = InternalRuleset.values()[i];
    232                                 rulesetComboBox.addItem(ruleset.toString());
    233                                 if (ruleset == preferences.getCurrentInternalRuleset()) {
    234                                         rulesetComboBox.setSelectedIndex(i);
    235                                 }
    236                         }
    237 
    238                         if (preferences.getCurrentInternalRuleset() == null) {
    239                                 rulesetComboBox.addItem("");
    240                                 rulesetComboBox.setSelectedIndex(InternalRuleset.values().length);
    241                         }
    242 
    243                 } else {
    244 
    245                         rulesetFiles = new LinkedList<File>();
    246 
    247                         File[] filesInRulesetFolder = preferences.getRulesetFolder().listFiles();
    248 
    249                         if (filesInRulesetFolder != null) {
    250                                 for (File possibleRulesetFile : filesInRulesetFolder) {
    251                                         try {
    252                                                 AccessRulesetReader.readAccessRuleset(new FileInputStream(possibleRulesetFile));
    253                                                 rulesetFiles.add(possibleRulesetFile);
    254                                         } catch (IOException ioe) {
    255                                                 //don't add to rulesetFiles
    256                                         }
    257                                 }
    258                         }
    259 
    260                         Collections.sort(rulesetFiles);
    261 
    262                         rulesetComboBox.removeAllItems();
    263                         for (int i=0; i < rulesetFiles.size(); i++) {
    264                                 File rulesetFile = rulesetFiles.get(i);
    265                                 rulesetComboBox.addItem(rulesetFile.getName());
    266                                 if (rulesetFile.equals(preferences.getCurrentRulesetFile())) {
    267                                         rulesetComboBox.setSelectedIndex(i);
    268                                 }
    269                         }
    270 
    271                 }
    272 
    273                 rulesetComboBox.addActionListener(rulesetActionListener);
    274 
    275                 /* update bookmarks */
    276 
    277                 bookmarkComboBox.removeActionListener(bookmarkActionListener);
    278 
    279                 String activeBookmarkName = preferences.getCurrentParameterBookmarkName();
    280                 Set<String> bookmarkNames = new HashSet<String>(preferences.getParameterBookmarks().keySet());
    281 
    282                 bookmarkComboBox.removeAllItems();
    283                 for (String bookmarkName : bookmarkNames) {
    284                         bookmarkComboBox.addItem(bookmarkName);
    285                         if (bookmarkName.equals(activeBookmarkName)) {
    286                                 bookmarkComboBox.setSelectedItem(bookmarkName);
    287                         }
    288                 }
    289 
    290                 bookmarkComboBox.addActionListener(bookmarkActionListener);
    291 
    292         }
     46    private static final int HEIGHT = 150;
     47
     48    /** map from labels to available color schemes */
     49    private final LinkedHashMap<String, ColorScheme> availableColorSchemes;
     50
     51
     52    private final GraphViewPreferences preferences;
     53    private final GraphViewPlugin plugin;
     54
     55    private final JComboBox rulesetComboBox;
     56    private final JComboBox bookmarkComboBox;
     57    private final JComboBox colorSchemeComboBox;
     58
     59    /**
     60    * list of ruleset files in the order currently used by rulesetComboBox;
     61    * null if internal rulesets are used
     62    */
     63    private List<File> rulesetFiles;
     64
     65    public GraphViewDialog(final GraphViewPlugin plugin) {
     66
     67        super("Graph View Dialog", "graphview",
     68                "Open the dialog for graph view configuration.", (Shortcut)null, HEIGHT);
     69
     70        this.preferences = GraphViewPreferences.getInstance();
     71        this.plugin = plugin;
     72
     73        availableColorSchemes = new LinkedHashMap<String, ColorScheme>();
     74
     75        availableColorSchemes.put("default",
     76                new PreferencesColorScheme(preferences));
     77        availableColorSchemes.put("end nodes",
     78                new EndNodeColorScheme(Color.GRAY, Color.RED, Color.GRAY));
     79        availableColorSchemes.put("maxspeed",
     80                new MaxspeedColorScheme());
     81        availableColorSchemes.put("maxweight",
     82                new MaxweightColorScheme());
     83        availableColorSchemes.put("maxheight",
     84                new MaxheightColorScheme());
     85        availableColorSchemes.put("incline",
     86                new InclineColorScheme());
     87
     88        JPanel selectionPanel = new JPanel();
     89        GridBagLayout selectionLayout = new GridBagLayout();
     90        selectionPanel.setLayout(selectionLayout);
     91
     92        GridBagConstraints gbcLabel = new GridBagConstraints();
     93        gbcLabel.gridx = 0;
     94        gbcLabel.anchor = GridBagConstraints.WEST;
     95        gbcLabel.insets = new Insets(0, 5, 0, 5);
     96
     97        GridBagConstraints gbcComboBox = new GridBagConstraints();
     98        gbcComboBox.gridx = 1;
     99        gbcComboBox.fill = GridBagConstraints.HORIZONTAL;
     100        gbcComboBox.weightx = 1;
     101
     102
     103        /* create ruleset label and combo box */
     104        {
     105            JLabel rulesetLabel = new JLabel("ruleset:");
     106            gbcLabel.gridy = 0;
     107            selectionLayout.setConstraints(rulesetLabel, gbcLabel);
     108            selectionPanel.add(rulesetLabel);
     109
     110            rulesetComboBox = new JComboBox();
     111            rulesetComboBox.addActionListener(rulesetActionListener);
     112            gbcComboBox.gridy = 0;
     113            selectionLayout.setConstraints(rulesetComboBox, gbcComboBox);
     114            selectionPanel.add(rulesetComboBox);
     115        }
     116
     117        /* create bookmark label and combo box */
     118        {
     119            JLabel bookmarkLabel = new JLabel("parameters:");
     120            gbcLabel.gridy = 1;
     121            selectionLayout.setConstraints(bookmarkLabel, gbcLabel);
     122            selectionPanel.add(bookmarkLabel);
     123
     124            bookmarkComboBox = new JComboBox();
     125            bookmarkComboBox.addActionListener(bookmarkActionListener);
     126            gbcComboBox.gridy = 1;
     127            selectionLayout.setConstraints(bookmarkComboBox, gbcComboBox);
     128            selectionPanel.add(bookmarkComboBox);
     129        }
     130
     131        /* create color scheme label and combo box */
     132        {
     133            JLabel colorSchemeLabel = new JLabel("coloring:");
     134            gbcLabel.gridy = 2;
     135            selectionLayout.setConstraints(colorSchemeLabel, gbcLabel);
     136            selectionPanel.add(colorSchemeLabel);
     137
     138            colorSchemeComboBox = new JComboBox();
     139            for (String colorSchemeName : availableColorSchemes.keySet()) {
     140                colorSchemeComboBox.addItem(colorSchemeName);
     141                ColorScheme colorScheme = availableColorSchemes.get(colorSchemeName);
     142                if (colorScheme.getClass().equals(preferences.getCurrentColorScheme().getClass())) {
     143                    colorSchemeComboBox.setSelectedItem(colorSchemeName);
     144                }
     145            }
     146            colorSchemeComboBox.addActionListener(colorSchemeActionListener);
     147            gbcComboBox.gridy = 2;
     148            selectionLayout.setConstraints(colorSchemeComboBox, gbcComboBox);
     149            selectionPanel.add(colorSchemeComboBox);
     150        }
     151
     152        this.add(BorderLayout.CENTER, selectionPanel);
     153
     154
     155        JPanel buttonPanel = new JPanel();
     156        JButton showLayerButton = new JButton("create/update graph");
     157        showLayerButton.addActionListener(new ActionListener() {
     158            public void actionPerformed(ActionEvent e) {
     159                plugin.createGraphViewLayer();
     160            }
     161        });
     162        buttonPanel.add(showLayerButton);
     163
     164        this.add(BorderLayout.SOUTH, buttonPanel);
     165
     166        updateSelections();
     167        this.preferences.addObserver(this);
     168
     169    }
     170
     171    private final ActionListener rulesetActionListener = new ActionListener() {
     172        public void actionPerformed(ActionEvent e) {
     173            if (rulesetComboBox.getSelectedItem() != null) {
     174                int selectedRulesetIndex = rulesetComboBox.getSelectedIndex();
     175                if (rulesetFiles != null) {
     176                    File selectedRulesetFile = rulesetFiles.get(selectedRulesetIndex);
     177                    preferences.setCurrentRulesetFile(selectedRulesetFile);
     178                    preferences.distributeChanges();
     179                    plugin.updateGraphViewLayer();
     180                } else {
     181                    if (selectedRulesetIndex < InternalRuleset.values().length) {
     182                        InternalRuleset selectedIRR = InternalRuleset.values()[selectedRulesetIndex];
     183                        preferences.setCurrentInternalRuleset(selectedIRR);
     184                        preferences.distributeChanges();
     185                        plugin.updateGraphViewLayer();
     186                    }
     187                }
     188            }
     189        }
     190    };
     191
     192    private final ActionListener bookmarkActionListener = new ActionListener() {
     193        public void actionPerformed(ActionEvent e) {
     194            String selectedBookmarkName = (String)bookmarkComboBox.getSelectedItem();
     195            if (selectedBookmarkName != null) {
     196                preferences.setCurrentParameterBookmarkName(selectedBookmarkName);
     197                preferences.distributeChanges();
     198                plugin.updateGraphViewLayer();
     199            }
     200        }
     201    };
     202
     203    private final ActionListener colorSchemeActionListener = new ActionListener() {
     204        public void actionPerformed(ActionEvent e) {
     205            assert availableColorSchemes.containsKey(colorSchemeComboBox.getSelectedItem());
     206            String colorSchemeLabel = (String)colorSchemeComboBox.getSelectedItem();
     207            preferences.setCurrentColorScheme(availableColorSchemes.get(colorSchemeLabel));
     208            preferences.distributeChanges();
     209            plugin.repaintGraphViewLayer();
     210        }
     211    };
     212
     213    public void update(Observable observable, Object param) {
     214        if (observable == preferences) {
     215            updateSelections();
     216        }
     217    }
     218
     219    protected void updateSelections() {
     220
     221        /* update rulesets */
     222
     223        rulesetComboBox.removeActionListener(rulesetActionListener);
     224
     225        if (preferences.getUseInternalRulesets()) {
     226
     227            rulesetFiles = null;
     228
     229            rulesetComboBox.removeAllItems();
     230            for (int i=0; i < InternalRuleset.values().length; i++) {
     231                InternalRuleset ruleset = InternalRuleset.values()[i];
     232                rulesetComboBox.addItem(ruleset.toString());
     233                if (ruleset == preferences.getCurrentInternalRuleset()) {
     234                    rulesetComboBox.setSelectedIndex(i);
     235                }
     236            }
     237
     238            if (preferences.getCurrentInternalRuleset() == null) {
     239                rulesetComboBox.addItem("");
     240                rulesetComboBox.setSelectedIndex(InternalRuleset.values().length);
     241            }
     242
     243        } else {
     244
     245            rulesetFiles = new LinkedList<File>();
     246
     247            File[] filesInRulesetFolder = preferences.getRulesetFolder().listFiles();
     248
     249            if (filesInRulesetFolder != null) {
     250                for (File possibleRulesetFile : filesInRulesetFolder) {
     251                    try {
     252                        AccessRulesetReader.readAccessRuleset(new FileInputStream(possibleRulesetFile));
     253                        rulesetFiles.add(possibleRulesetFile);
     254                    } catch (IOException ioe) {
     255                        //don't add to rulesetFiles
     256                    }
     257                }
     258            }
     259
     260            Collections.sort(rulesetFiles);
     261
     262            rulesetComboBox.removeAllItems();
     263            for (int i=0; i < rulesetFiles.size(); i++) {
     264                File rulesetFile = rulesetFiles.get(i);
     265                rulesetComboBox.addItem(rulesetFile.getName());
     266                if (rulesetFile.equals(preferences.getCurrentRulesetFile())) {
     267                    rulesetComboBox.setSelectedIndex(i);
     268                }
     269            }
     270
     271        }
     272
     273        rulesetComboBox.addActionListener(rulesetActionListener);
     274
     275        /* update bookmarks */
     276
     277        bookmarkComboBox.removeActionListener(bookmarkActionListener);
     278
     279        String activeBookmarkName = preferences.getCurrentParameterBookmarkName();
     280        Set<String> bookmarkNames = new HashSet<String>(preferences.getParameterBookmarks().keySet());
     281
     282        bookmarkComboBox.removeAllItems();
     283        for (String bookmarkName : bookmarkNames) {
     284            bookmarkComboBox.addItem(bookmarkName);
     285            if (bookmarkName.equals(activeBookmarkName)) {
     286                bookmarkComboBox.setSelectedItem(bookmarkName);
     287            }
     288        }
     289
     290        bookmarkComboBox.addActionListener(bookmarkActionListener);
     291
     292    }
    293293
    294294}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/plugin/dialogs/GraphViewPreferenceEditor.java

    r19292 r23189  
    3333public class GraphViewPreferenceEditor implements PreferenceSetting {
    3434
    35         private File rulesetFolder;
    36         private Map<String, PreferenceAccessParameters> parameterBookmarks;
    37 
    38         private JPanel preferencePanel;
    39 
    40         private JCheckBox internalRulesetCheckBox;
    41         private JLabel rulesetFolderLabel;
    42         private JTextField rulesetFolderTextField;
    43         private JButton selectRulesetFolderButton;
    44 
    45         private JComboBox bookmarkComboBox;
    46         private JButton editBookmarkButton;
    47         private JButton deleteBookmarkButton;
    48 
    49         private JCheckBox separateDirectionsCheckBox;
    50 
    51         public void addGui(PreferenceTabbedPane gui) {
    52 
    53                 readPreferences();
    54 
    55                 preferencePanel = gui.createPreferenceTab("graphview", "Graphview",
    56                 "Settings for the Graphview plugin that visualizes routing graphs.");
    57 
    58                 JPanel mainPanel = createMainPanel();
    59 
    60                 preferencePanel.add(mainPanel, GBC.eol().fill(GBC.BOTH));
    61 
    62                 updateVehiclePanel(GraphViewPreferences.getInstance().getCurrentParameterBookmarkName());
    63 
    64         }
    65 
    66         /**
    67         * creates local versions of preference information
    68         * that will only be written to real preferences if the OK button is pressed
    69         */
    70         private void readPreferences() {
    71 
    72                 GraphViewPreferences preferences = GraphViewPreferences.getInstance();
    73 
    74                 rulesetFolder = preferences.getRulesetFolder();
    75 
    76                 parameterBookmarks =
    77                         new HashMap<String, PreferenceAccessParameters>(preferences.getParameterBookmarks());
    78 
    79         }
    80 
    81         private JPanel createMainPanel() {
    82 
    83                 JPanel mainPanel = new JPanel();
    84 
    85                 GridBagLayout mainLayout = new GridBagLayout();
    86                 mainPanel.setLayout(mainLayout);
    87 
    88                 GridBagConstraints constraints = new GridBagConstraints();
    89                 constraints.fill = GridBagConstraints.HORIZONTAL;
    90                 constraints.weightx = 1;
    91                 constraints.gridx = 0;
    92 
    93                 {
    94                         JPanel rulesetPanel = createRulesetPanel();
    95                         constraints.gridy = 0;
    96                         mainLayout.setConstraints(rulesetPanel, constraints);
    97                         mainPanel.add(rulesetPanel);
    98                 } {
    99                         JPanel vehiclePanel = createVehiclePanel();
    100                         constraints.gridy = 1;
    101                         mainLayout.setConstraints(vehiclePanel, constraints);
    102                         mainPanel.add(vehiclePanel);
    103                 } {
    104                         JPanel visualizationPanel = createVisualizationPanel();
    105                         constraints.gridy = 2;
    106                         mainLayout.setConstraints(visualizationPanel, constraints);
    107                         mainPanel.add(visualizationPanel);
    108                 }
    109 
    110                 mainPanel.add(GBC.glue(0, 0));
    111 
    112                 return mainPanel;
    113 
    114         }
    115 
    116         private JPanel createRulesetPanel() {
    117 
    118                 JPanel rulesetPanel = new JPanel();
    119                 rulesetPanel.setBorder(BorderFactory.createTitledBorder("ruleset"));
    120                 rulesetPanel.setLayout(new BoxLayout(rulesetPanel, BoxLayout.Y_AXIS));
    121 
    122                 internalRulesetCheckBox = new JCheckBox("use built-in rulesets");
    123                 internalRulesetCheckBox.setSelected(GraphViewPreferences.getInstance().getUseInternalRulesets());
    124                 internalRulesetCheckBox.addActionListener(internalRulesetActionListener);
    125                 rulesetPanel.add(internalRulesetCheckBox);
    126 
    127                 rulesetFolderLabel = new JLabel("external ruleset directory:");
    128                 rulesetPanel.add(rulesetFolderLabel);
    129 
    130                 rulesetFolderTextField = new JTextField();
    131                 rulesetFolderTextField.setText(rulesetFolder.getPath());
    132                 rulesetFolderTextField.setEditable(false);
    133                 rulesetPanel.add(rulesetFolderTextField);
    134 
    135                 selectRulesetFolderButton = new JButton("select directory");
    136                 selectRulesetFolderButton.addActionListener(selectRulesetFolderActionListener);
    137                 rulesetPanel.add(selectRulesetFolderButton);
    138 
    139                 updateRulesetPanel();
    140 
    141                 return rulesetPanel;
    142         }
    143 
    144         private JPanel createVehiclePanel() {
    145 
    146                 JPanel vehiclePanel = new JPanel();
    147                 vehiclePanel.setBorder(BorderFactory.createTitledBorder("vehicle"));
    148                 vehiclePanel.setLayout(new BoxLayout(vehiclePanel, BoxLayout.Y_AXIS));
    149 
    150                 bookmarkComboBox = new JComboBox();
    151                 vehiclePanel.add(bookmarkComboBox);
    152 
    153                 JPanel buttonPanel = new JPanel();
    154                 buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS));
    155 
    156                 JButton createButton = new JButton("create");
    157                 createButton.addActionListener(createVehicleActionListener);
    158                 buttonPanel.add(createButton);
    159 
    160                 editBookmarkButton = new JButton("edit");
    161                 editBookmarkButton.addActionListener(editVehicleActionListener);
    162                 buttonPanel.add(editBookmarkButton);
    163 
    164                 deleteBookmarkButton = new JButton("delete");
    165                 deleteBookmarkButton.addActionListener(deleteVehicleActionListener);
    166                 buttonPanel.add(deleteBookmarkButton);
    167 
    168                 JButton restoreDefaultsButton = new JButton("restore defaults");
    169                 restoreDefaultsButton.addActionListener(restoreVehicleDefaultsActionListener);
    170                 buttonPanel.add(restoreDefaultsButton);
    171 
    172                 vehiclePanel.add(buttonPanel);
    173 
    174                 return vehiclePanel;
    175         }
    176 
    177         private JPanel createVisualizationPanel() {
    178 
    179                 JPanel visualizationPanel = new JPanel();
    180                 visualizationPanel.setBorder(BorderFactory.createTitledBorder("visualization"));
    181                 visualizationPanel.setLayout(new BoxLayout(visualizationPanel, BoxLayout.Y_AXIS));
    182 
    183                 separateDirectionsCheckBox = new JCheckBox("draw directions separately");
    184                 separateDirectionsCheckBox.setSelected(GraphViewPreferences.getInstance().getSeparateDirections());
    185                 visualizationPanel.add(separateDirectionsCheckBox);
    186 
    187                 return visualizationPanel;
    188         }
    189 
    190         public boolean ok() {
    191 
    192                 GraphViewPreferences preferences = GraphViewPreferences.getInstance();
    193 
    194                 preferences.setUseInternalRulesets(internalRulesetCheckBox.isSelected());
    195                 preferences.setRulesetFolder(rulesetFolder);
    196 
    197                 preferences.setParameterBookmarks(parameterBookmarks);
    198 
    199                 String selectedBookmarkName = (String)bookmarkComboBox.getSelectedItem();
    200                 preferences.setCurrentParameterBookmarkName(selectedBookmarkName);
    201 
    202                 preferences.setSeparateDirections(separateDirectionsCheckBox.isSelected());
    203 
    204                 preferences.distributeChanges();
    205 
    206                 return false;
    207         }
    208 
    209         private final ActionListener internalRulesetActionListener = new ActionListener() {
    210                 public void actionPerformed(ActionEvent e) {
    211                         updateRulesetPanel();
    212                 }
    213         };
    214 
    215         private final ActionListener selectRulesetFolderActionListener = new ActionListener() {
    216                 public void actionPerformed(ActionEvent e) {
    217 
    218                         File initialFCDirectory = rulesetFolder;
    219                         if (rulesetFolder.getParentFile() != null) {
    220                                 initialFCDirectory = rulesetFolder.getParentFile();
    221                         }
    222 
    223                         final JFileChooser fc = new JFileChooser();
    224                         fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
    225                         fc.setCurrentDirectory(initialFCDirectory);
    226 
    227                         int returnVal = fc.showOpenDialog(preferencePanel);
    228 
    229                         if (returnVal == JFileChooser.APPROVE_OPTION) {
    230                                 rulesetFolder = fc.getSelectedFile();
    231                                 rulesetFolderTextField.setText(rulesetFolder.getPath());
    232                         }
    233 
    234                 }
    235         };
    236 
    237         private final ActionListener createVehicleActionListener = new ActionListener() {
    238                 public void actionPerformed(ActionEvent e) {
    239 
    240                         PreferenceAccessParameters defaultBookmarkParameters =
    241                                 GraphViewPreferenceDefaults.createDefaultBookmarkAccessParameters();
    242 
    243                         AccessParameterDialog apd = new AccessParameterDialog(
    244                                         null,
    245                                         false,
    246                                         "new bookmark",
    247                                         parameterBookmarks.keySet(),
    248                                         defaultBookmarkParameters,
    249                                         new BookmarkAction() {
    250                                                 public void execute(String name, PreferenceAccessParameters parameters) {
    251                                                         parameterBookmarks.put(name, parameters);
    252                                                         updateVehiclePanel(name);
    253                                                 }
    254                                         });
    255 
    256                         apd.setVisible(true);
    257                 }
    258         };
    259 
    260         private final ActionListener editVehicleActionListener = new ActionListener() {
    261                 public void actionPerformed(ActionEvent e) {
    262                         if (bookmarkComboBox.getSelectedItem() != null) {
    263 
    264                                 final String selectedBookmarkName = (String)bookmarkComboBox.getSelectedItem();
    265                                 PreferenceAccessParameters parameters =
    266                                         parameterBookmarks.get(selectedBookmarkName);
    267 
    268                                 Collection<String> otherBookmarkNames = new LinkedList<String>();
    269                                 for (String bookmarkName : parameterBookmarks.keySet()) {
    270                                         if (!bookmarkName.equals(selectedBookmarkName)) {
    271                                                 otherBookmarkNames.add(bookmarkName);
    272                                         }
    273                                 }
    274 
    275                                 AccessParameterDialog apd = new AccessParameterDialog(
    276                                                 null,
    277                                                 true,
    278                                                 selectedBookmarkName,
    279                                                 otherBookmarkNames,
    280                                                 parameters,
    281                                                 new BookmarkAction() {
    282                                                         public void execute(String name, PreferenceAccessParameters parameters) {
    283                                                                 parameterBookmarks.remove(selectedBookmarkName);
    284                                                                 parameterBookmarks.put(name, parameters);
    285                                                                 updateVehiclePanel(name);
    286                                                         }
    287                                                 });
    288 
    289                                 apd.setVisible(true);
    290                         }
    291 
    292                 }
    293         };
    294 
    295         private final ActionListener deleteVehicleActionListener = new ActionListener() {
    296                 public void actionPerformed(ActionEvent e) {
    297                         if (bookmarkComboBox.getSelectedItem() != null) {
    298 
    299                                 String selectedBookmarkName = (String)bookmarkComboBox.getSelectedItem();
    300 
    301                                 int userChoice = JOptionPane.showConfirmDialog(
    302                                                 preferencePanel,
    303                                                 "Really delete \"" + selectedBookmarkName + "\"?",
    304                                                 "Bookmark deletion",
    305                                                 JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
    306 
    307                                 if (userChoice == JOptionPane.YES_OPTION) {
    308                                         parameterBookmarks.remove(selectedBookmarkName);
    309                                         updateVehiclePanel(null);
    310                                 }
    311 
    312                         }
    313                 }
    314         };
    315 
    316         private final ActionListener restoreVehicleDefaultsActionListener = new ActionListener() {
    317                 public void actionPerformed(ActionEvent e) {
    318 
    319                         int userChoice = JOptionPane.showConfirmDialog(
    320                                         preferencePanel,
    321                                         "Really restore default bookmarks?\n"
    322                                         + "All manually added or edited bookmarks will be lost!",
    323                                         "Bookmark reset",
    324                                         JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
    325 
    326                         if (userChoice == JOptionPane.YES_OPTION) {
    327                                 parameterBookmarks.clear();
    328                                 parameterBookmarks.putAll(
    329                                                 GraphViewPreferenceDefaults.createDefaultAccessParameterBookmarks());
    330                                 updateVehiclePanel(null);
    331                         }
    332 
    333                 }
    334         };
    335 
    336         private void updateRulesetPanel() {
    337 
    338                 rulesetFolderLabel.setEnabled(!internalRulesetCheckBox.isSelected());
    339                 rulesetFolderTextField.setEnabled(!internalRulesetCheckBox.isSelected());
    340                 selectRulesetFolderButton.setEnabled(!internalRulesetCheckBox.isSelected());
    341 
    342         }
    343 
    344         private void updateVehiclePanel(String selectedBookmarkName) {
    345 
    346                 bookmarkComboBox.removeAllItems();
    347                 for (String bookmarkName : parameterBookmarks.keySet()) {
    348                         bookmarkComboBox.addItem(bookmarkName);
    349                 }
    350 
    351                 if (selectedBookmarkName == null) {
    352                         if (bookmarkComboBox.getItemCount() > 0) {
    353                                 bookmarkComboBox.setSelectedIndex(0);
    354                         }
    355                 } else {
    356                         bookmarkComboBox.setSelectedItem(selectedBookmarkName);
    357                 }
    358 
    359                 editBookmarkButton.setEnabled(parameterBookmarks.size() > 0);
    360                 deleteBookmarkButton.setEnabled(parameterBookmarks.size() > 0);
    361 
    362         }
     35    private File rulesetFolder;
     36    private Map<String, PreferenceAccessParameters> parameterBookmarks;
     37
     38    private JPanel preferencePanel;
     39
     40    private JCheckBox internalRulesetCheckBox;
     41    private JLabel rulesetFolderLabel;
     42    private JTextField rulesetFolderTextField;
     43    private JButton selectRulesetFolderButton;
     44
     45    private JComboBox bookmarkComboBox;
     46    private JButton editBookmarkButton;
     47    private JButton deleteBookmarkButton;
     48
     49    private JCheckBox separateDirectionsCheckBox;
     50
     51    public void addGui(PreferenceTabbedPane gui) {
     52
     53        readPreferences();
     54
     55        preferencePanel = gui.createPreferenceTab("graphview", "Graphview",
     56        "Settings for the Graphview plugin that visualizes routing graphs.");
     57
     58        JPanel mainPanel = createMainPanel();
     59
     60        preferencePanel.add(mainPanel, GBC.eol().fill(GBC.BOTH));
     61
     62        updateVehiclePanel(GraphViewPreferences.getInstance().getCurrentParameterBookmarkName());
     63
     64    }
     65
     66    /**
     67    * creates local versions of preference information
     68    * that will only be written to real preferences if the OK button is pressed
     69    */
     70    private void readPreferences() {
     71
     72        GraphViewPreferences preferences = GraphViewPreferences.getInstance();
     73
     74        rulesetFolder = preferences.getRulesetFolder();
     75
     76        parameterBookmarks =
     77            new HashMap<String, PreferenceAccessParameters>(preferences.getParameterBookmarks());
     78
     79    }
     80
     81    private JPanel createMainPanel() {
     82
     83        JPanel mainPanel = new JPanel();
     84
     85        GridBagLayout mainLayout = new GridBagLayout();
     86        mainPanel.setLayout(mainLayout);
     87
     88        GridBagConstraints constraints = new GridBagConstraints();
     89        constraints.fill = GridBagConstraints.HORIZONTAL;
     90        constraints.weightx = 1;
     91        constraints.gridx = 0;
     92
     93        {
     94            JPanel rulesetPanel = createRulesetPanel();
     95            constraints.gridy = 0;
     96            mainLayout.setConstraints(rulesetPanel, constraints);
     97            mainPanel.add(rulesetPanel);
     98        } {
     99            JPanel vehiclePanel = createVehiclePanel();
     100            constraints.gridy = 1;
     101            mainLayout.setConstraints(vehiclePanel, constraints);
     102            mainPanel.add(vehiclePanel);
     103        } {
     104            JPanel visualizationPanel = createVisualizationPanel();
     105            constraints.gridy = 2;
     106            mainLayout.setConstraints(visualizationPanel, constraints);
     107            mainPanel.add(visualizationPanel);
     108        }
     109
     110        mainPanel.add(GBC.glue(0, 0));
     111
     112        return mainPanel;
     113
     114    }
     115
     116    private JPanel createRulesetPanel() {
     117
     118        JPanel rulesetPanel = new JPanel();
     119        rulesetPanel.setBorder(BorderFactory.createTitledBorder("ruleset"));
     120        rulesetPanel.setLayout(new BoxLayout(rulesetPanel, BoxLayout.Y_AXIS));
     121
     122        internalRulesetCheckBox = new JCheckBox("use built-in rulesets");
     123        internalRulesetCheckBox.setSelected(GraphViewPreferences.getInstance().getUseInternalRulesets());
     124        internalRulesetCheckBox.addActionListener(internalRulesetActionListener);
     125        rulesetPanel.add(internalRulesetCheckBox);
     126
     127        rulesetFolderLabel = new JLabel("external ruleset directory:");
     128        rulesetPanel.add(rulesetFolderLabel);
     129
     130        rulesetFolderTextField = new JTextField();
     131        rulesetFolderTextField.setText(rulesetFolder.getPath());
     132        rulesetFolderTextField.setEditable(false);
     133        rulesetPanel.add(rulesetFolderTextField);
     134
     135        selectRulesetFolderButton = new JButton("select directory");
     136        selectRulesetFolderButton.addActionListener(selectRulesetFolderActionListener);
     137        rulesetPanel.add(selectRulesetFolderButton);
     138
     139        updateRulesetPanel();
     140
     141        return rulesetPanel;
     142    }
     143
     144    private JPanel createVehiclePanel() {
     145
     146        JPanel vehiclePanel = new JPanel();
     147        vehiclePanel.setBorder(BorderFactory.createTitledBorder("vehicle"));
     148        vehiclePanel.setLayout(new BoxLayout(vehiclePanel, BoxLayout.Y_AXIS));
     149
     150        bookmarkComboBox = new JComboBox();
     151        vehiclePanel.add(bookmarkComboBox);
     152
     153        JPanel buttonPanel = new JPanel();
     154        buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS));
     155
     156        JButton createButton = new JButton("create");
     157        createButton.addActionListener(createVehicleActionListener);
     158        buttonPanel.add(createButton);
     159
     160        editBookmarkButton = new JButton("edit");
     161        editBookmarkButton.addActionListener(editVehicleActionListener);
     162        buttonPanel.add(editBookmarkButton);
     163
     164        deleteBookmarkButton = new JButton("delete");
     165        deleteBookmarkButton.addActionListener(deleteVehicleActionListener);
     166        buttonPanel.add(deleteBookmarkButton);
     167
     168        JButton restoreDefaultsButton = new JButton("restore defaults");
     169        restoreDefaultsButton.addActionListener(restoreVehicleDefaultsActionListener);
     170        buttonPanel.add(restoreDefaultsButton);
     171
     172        vehiclePanel.add(buttonPanel);
     173
     174        return vehiclePanel;
     175    }
     176
     177    private JPanel createVisualizationPanel() {
     178
     179        JPanel visualizationPanel = new JPanel();
     180        visualizationPanel.setBorder(BorderFactory.createTitledBorder("visualization"));
     181        visualizationPanel.setLayout(new BoxLayout(visualizationPanel, BoxLayout.Y_AXIS));
     182
     183        separateDirectionsCheckBox = new JCheckBox("draw directions separately");
     184        separateDirectionsCheckBox.setSelected(GraphViewPreferences.getInstance().getSeparateDirections());
     185        visualizationPanel.add(separateDirectionsCheckBox);
     186
     187        return visualizationPanel;
     188    }
     189
     190    public boolean ok() {
     191
     192        GraphViewPreferences preferences = GraphViewPreferences.getInstance();
     193
     194        preferences.setUseInternalRulesets(internalRulesetCheckBox.isSelected());
     195        preferences.setRulesetFolder(rulesetFolder);
     196
     197        preferences.setParameterBookmarks(parameterBookmarks);
     198
     199        String selectedBookmarkName = (String)bookmarkComboBox.getSelectedItem();
     200        preferences.setCurrentParameterBookmarkName(selectedBookmarkName);
     201
     202        preferences.setSeparateDirections(separateDirectionsCheckBox.isSelected());
     203
     204        preferences.distributeChanges();
     205
     206        return false;
     207    }
     208
     209    private final ActionListener internalRulesetActionListener = new ActionListener() {
     210        public void actionPerformed(ActionEvent e) {
     211            updateRulesetPanel();
     212        }
     213    };
     214
     215    private final ActionListener selectRulesetFolderActionListener = new ActionListener() {
     216        public void actionPerformed(ActionEvent e) {
     217
     218            File initialFCDirectory = rulesetFolder;
     219            if (rulesetFolder.getParentFile() != null) {
     220                initialFCDirectory = rulesetFolder.getParentFile();
     221            }
     222
     223            final JFileChooser fc = new JFileChooser();
     224            fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
     225            fc.setCurrentDirectory(initialFCDirectory);
     226
     227            int returnVal = fc.showOpenDialog(preferencePanel);
     228
     229            if (returnVal == JFileChooser.APPROVE_OPTION) {
     230                rulesetFolder = fc.getSelectedFile();
     231                rulesetFolderTextField.setText(rulesetFolder.getPath());
     232            }
     233
     234        }
     235    };
     236
     237    private final ActionListener createVehicleActionListener = new ActionListener() {
     238        public void actionPerformed(ActionEvent e) {
     239
     240            PreferenceAccessParameters defaultBookmarkParameters =
     241                GraphViewPreferenceDefaults.createDefaultBookmarkAccessParameters();
     242
     243            AccessParameterDialog apd = new AccessParameterDialog(
     244                    null,
     245                    false,
     246                    "new bookmark",
     247                    parameterBookmarks.keySet(),
     248                    defaultBookmarkParameters,
     249                    new BookmarkAction() {
     250                        public void execute(String name, PreferenceAccessParameters parameters) {
     251                            parameterBookmarks.put(name, parameters);
     252                            updateVehiclePanel(name);
     253                        }
     254                    });
     255
     256            apd.setVisible(true);
     257        }
     258    };
     259
     260    private final ActionListener editVehicleActionListener = new ActionListener() {
     261        public void actionPerformed(ActionEvent e) {
     262            if (bookmarkComboBox.getSelectedItem() != null) {
     263
     264                final String selectedBookmarkName = (String)bookmarkComboBox.getSelectedItem();
     265                PreferenceAccessParameters parameters =
     266                    parameterBookmarks.get(selectedBookmarkName);
     267
     268                Collection<String> otherBookmarkNames = new LinkedList<String>();
     269                for (String bookmarkName : parameterBookmarks.keySet()) {
     270                    if (!bookmarkName.equals(selectedBookmarkName)) {
     271                        otherBookmarkNames.add(bookmarkName);
     272                    }
     273                }
     274
     275                AccessParameterDialog apd = new AccessParameterDialog(
     276                        null,
     277                        true,
     278                        selectedBookmarkName,
     279                        otherBookmarkNames,
     280                        parameters,
     281                        new BookmarkAction() {
     282                            public void execute(String name, PreferenceAccessParameters parameters) {
     283                                parameterBookmarks.remove(selectedBookmarkName);
     284                                parameterBookmarks.put(name, parameters);
     285                                updateVehiclePanel(name);
     286                            }
     287                        });
     288
     289                apd.setVisible(true);
     290            }
     291
     292        }
     293    };
     294
     295    private final ActionListener deleteVehicleActionListener = new ActionListener() {
     296        public void actionPerformed(ActionEvent e) {
     297            if (bookmarkComboBox.getSelectedItem() != null) {
     298
     299                String selectedBookmarkName = (String)bookmarkComboBox.getSelectedItem();
     300
     301                int userChoice = JOptionPane.showConfirmDialog(
     302                        preferencePanel,
     303                        "Really delete \"" + selectedBookmarkName + "\"?",
     304                        "Bookmark deletion",
     305                        JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
     306
     307                if (userChoice == JOptionPane.YES_OPTION) {
     308                    parameterBookmarks.remove(selectedBookmarkName);
     309                    updateVehiclePanel(null);
     310                }
     311
     312            }
     313        }
     314    };
     315
     316    private final ActionListener restoreVehicleDefaultsActionListener = new ActionListener() {
     317        public void actionPerformed(ActionEvent e) {
     318
     319            int userChoice = JOptionPane.showConfirmDialog(
     320                    preferencePanel,
     321                    "Really restore default bookmarks?\n"
     322                    + "All manually added or edited bookmarks will be lost!",
     323                    "Bookmark reset",
     324                    JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
     325
     326            if (userChoice == JOptionPane.YES_OPTION) {
     327                parameterBookmarks.clear();
     328                parameterBookmarks.putAll(
     329                        GraphViewPreferenceDefaults.createDefaultAccessParameterBookmarks());
     330                updateVehiclePanel(null);
     331            }
     332
     333        }
     334    };
     335
     336    private void updateRulesetPanel() {
     337
     338        rulesetFolderLabel.setEnabled(!internalRulesetCheckBox.isSelected());
     339        rulesetFolderTextField.setEnabled(!internalRulesetCheckBox.isSelected());
     340        selectRulesetFolderButton.setEnabled(!internalRulesetCheckBox.isSelected());
     341
     342    }
     343
     344    private void updateVehiclePanel(String selectedBookmarkName) {
     345
     346        bookmarkComboBox.removeAllItems();
     347        for (String bookmarkName : parameterBookmarks.keySet()) {
     348            bookmarkComboBox.addItem(bookmarkName);
     349        }
     350
     351        if (selectedBookmarkName == null) {
     352            if (bookmarkComboBox.getItemCount() > 0) {
     353                bookmarkComboBox.setSelectedIndex(0);
     354            }
     355        } else {
     356            bookmarkComboBox.setSelectedItem(selectedBookmarkName);
     357        }
     358
     359        editBookmarkButton.setEnabled(parameterBookmarks.size() > 0);
     360        deleteBookmarkButton.setEnabled(parameterBookmarks.size() > 0);
     361
     362    }
    363363
    364364}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/plugin/layer/GraphViewLayer.java

    r22547 r23189  
    4646public class GraphViewLayer extends Layer implements LayerChangeListener, WayGraphObserver {
    4747
    48         private static final int NODE_RADIUS = 5;
    49 
    50         /**
    51         * offset from real position if {@link GraphViewPreferences#getSeparateDirections()} is active,
    52         * causes the graph nodes for the two directions to be visually distinguishable.
    53         * Positive values move "forward" direction to the right.
    54         */
    55         private static final double DIRECTIONAL_OFFSET = 20;
    56 
    57         private static final double OFFSET_ANGLE = 0.5 * Math.PI;
    58 
    59         private static final double MIN_QUAD_DISTANCE_FOR_OFFSET = 4;
    60 
    61         private static final boolean CONNECT_ALL_NODE_PAIRS = false;
    62 
    63         /** an arrow head that points along the x-axis to (0,0) */
    64         private static final Shape ARROW_HEAD;
    65 
    66         static {
    67 
    68                 Polygon head = new Polygon();
    69 
    70                 head.addPoint(  0,  0);
    71                 head.addPoint(-15, +4);
    72                 head.addPoint(-15, -4);
    73 
    74                 ARROW_HEAD = head;
    75         }
    76 
    77         private WayGraph wayGraph = null;
    78 
    79         private ColorScheme colorScheme = null;
    80         private NodePositioner nodePositioner = new NonMovingNodePositioner();
    81 
    82         public GraphViewLayer() {
    83                 super("Graph view");
    84                 MapView.addLayerChangeListener(this);
    85         }
    86 
    87         /** sets the WayGraph that is to be displayed by this layer, may be null */
    88         public void setWayGraph(WayGraph wayGraph) {
    89                 if (this.wayGraph != null) {
    90                         this.wayGraph.deleteObserver(this);
    91                 }
    92                 this.wayGraph = wayGraph;
    93                 if (wayGraph != null) {
    94                         wayGraph.addObserver(this);
    95                 }
    96         }
    97 
    98         /** sets the ColorScheme that is to be used for choosing colors, may be null */
    99         public void setColorScheme(ColorScheme colorScheme) {
    100                 this.colorScheme = colorScheme;
    101                 Main.panel.repaint();
    102         }
    103 
    104         /**
    105         * sets the NodePositioner that is to be used for determining node placement,
    106         * null will cause a {@link NonMovingNodePositioner} to be used.
    107         */
    108         public void setNodePositioner(NodePositioner nodePositioner) {
    109                 this.nodePositioner = nodePositioner;
    110                 if (nodePositioner == null) {
    111                         this.nodePositioner = new NonMovingNodePositioner();
    112                 }
    113                 Main.panel.repaint();
    114         }
    115 
    116         @Override
    117         public Icon getIcon() {
    118                 return ImageProvider.get("layer", "graphview");
    119         }
    120 
    121         private void paintGraphNode(final GraphNode node, final Graphics g, final MapView mv) {
    122 
    123                 Color color = colorScheme != null ? colorScheme.getNodeColor(node) : Color.LIGHT_GRAY;
    124 
    125                 Point p = getNodePoint(node, mv);
    126                 g.setColor(color);
    127                 g.fillOval(p.x - NODE_RADIUS, p.y - NODE_RADIUS, 2 * NODE_RADIUS, 2 * NODE_RADIUS);
    128 
    129         }
    130 
    131         private void paintGraphEdge(final GraphEdge e, final Graphics2D g2D, final MapView mv) {
    132 
    133                 if (!CONNECT_ALL_NODE_PAIRS && GraphViewPreferences.getInstance().getSeparateDirections()) {
    134 
    135                         //don't paint edges between nodes from the same SegmentNode and simply inverted Segment
    136                         if (e.getStartNode().getSegmentNode() == e.getTargetNode().getSegmentNode()
    137                                         && e.getStartNode().getSegment().getNode2() == e.getTargetNode().getSegment().getNode1()
    138                                         && e.getStartNode().getSegment().getNode1() == e.getTargetNode().getSegment().getNode2()) {
    139                                 return;
    140                         }
    141 
    142                 }
    143 
    144                 /* draw line(s) */
    145 
    146                 g2D.setStroke(new BasicStroke(3, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
    147 
    148                 List<Segment> edgeSegments = e.getPropertyValue(GraphEdgeSegments.PROPERTY);
    149 
    150                 if (edgeSegments.size() > 0) {
    151 
    152                         Segment firstSegment = edgeSegments.get(0);
    153                         Segment lastSegment = edgeSegments.get(edgeSegments.size() - 1);
    154 
    155                         //draw segments
    156 
    157                         for (Segment segment : edgeSegments) {
    158 
    159                                 Color color = Color.WHITE;
    160                                 if (colorScheme != null) {
    161                                         color = colorScheme.getSegmentColor(segment);
    162                                 }
    163                                 g2D.setColor(color);
    164 
    165                                 Point p1 = getNodePoint(segment.getNode1(), mv);
    166                                 Point p2 = getNodePoint(segment.getNode2(), mv);
    167 
    168                                 if (segment == firstSegment) {
    169                                         p1 = getNodePoint(e.getStartNode(), mv);
    170                                 }
    171                                 if (segment == lastSegment) {
    172                                         p2 = getNodePoint(e.getTargetNode(), mv);
    173                                 }
    174 
    175                                 g2D.draw(new Line2D.Float(p1.x, p1.y, p2.x, p2.y));
    176 
    177                         }
    178 
    179                 } else {
    180 
    181                         g2D.setColor(Color.WHITE);
    182 
    183                         Point p1 = getNodePoint(e.getStartNode(), mv);
    184                         Point p2 = getNodePoint(e.getTargetNode(), mv);
    185 
    186                         g2D.draw(new Line2D.Float(p1.x, p1.y, p2.x, p2.y));
    187 
    188                 }
    189 
    190                 /* draw arrow head (note: color of last segment is still set) */
    191 
    192                 {
    193                         Point p1 = getNodePoint(e.getStartNode(), mv);
    194                         Point p2 = getNodePoint(e.getTargetNode(), mv);
    195 
    196                         if (edgeSegments.size() > 0) {
    197                                 Segment lastSegment = edgeSegments.get(edgeSegments.size() - 1);
    198                                 p1 = getNodePoint(lastSegment.getNode1(), mv);
    199                         }
    200 
    201                         double angle = angleFromXAxis(p1, p2); // angle between x-axis and [p1,p2]
    202                         Shape head = ARROW_HEAD;
    203                         head = AffineTransform.getRotateInstance(angle).createTransformedShape(head);
    204                         head = AffineTransform.getTranslateInstance(p2.x, p2.y).createTransformedShape(head);
    205 
    206                         g2D.fill(head);
    207 
    208                 }
    209         }
    210 
    211         private Point getNodePoint(GraphNode node, MapView mv) {
    212 
    213                 Point nodePoint = getNodePoint(nodePositioner.getPosition(node), mv);
    214 
    215                 if (GraphViewPreferences.getInstance().getSeparateDirections()
    216                                 && !GraphUtil.isEndNode(node)) {
    217 
    218                         SegmentNode node1 = node.getSegment().getNode1();
    219                         SegmentNode node2 = node.getSegment().getNode2();
    220 
    221                         Point node1Point = getNodePoint(node1, mv);
    222                         Point node2Point = getNodePoint(node2, mv);
    223 
    224                         double segmentX = node2Point.getX() - node1Point.getX();
    225                         double segmentY = node2Point.getY() - node1Point.getY();
    226 
    227                         if (segmentX*segmentX + segmentY*segmentY >= MIN_QUAD_DISTANCE_FOR_OFFSET) {
    228 
    229                                 double rotatedX = Math.cos(OFFSET_ANGLE) * segmentX - Math.sin(OFFSET_ANGLE) * segmentY;
    230                                 double rotatedY = Math.sin(OFFSET_ANGLE) * segmentX + Math.cos(OFFSET_ANGLE) * segmentY;
    231 
    232                                 double segmentLength = Math.sqrt(rotatedX * rotatedX + rotatedY * rotatedY);
    233 
    234                                 double normalizedX = rotatedX / segmentLength;
    235                                 double normalizedY = rotatedY / segmentLength;
    236 
    237                                 nodePoint.x += DIRECTIONAL_OFFSET * normalizedX;
    238                                 nodePoint.y += DIRECTIONAL_OFFSET * normalizedY;
    239 
    240                         }
    241 
    242                 }
    243 
    244                 return nodePoint;
    245         }
    246         private Point getNodePoint(SegmentNode node, MapView mv) {
    247                 LatLonCoords coords = new LatLonCoords(node.getLat(), node.getLon());
    248                 return getNodePoint(coords, mv);
    249         }
    250         private Point getNodePoint(LatLonCoords coords, MapView mv) {
    251                 LatLon latLon = new LatLon(coords.getLat(), coords.getLon());
    252                 EastNorth eastNorth = Main.proj.latlon2eastNorth(latLon);
    253                 return mv.getPoint(eastNorth);
    254         }
    255 
    256         /**
    257         * calculates the angle between the x axis and a vector given by two points
    258         * @param p1  first point for vector; != null
    259         * @param p2  second point for vector; != null
    260         * @return  angle in radians, in range [-Pi .. +Pi]
    261         */
    262         private double angleFromXAxis(Point p1, Point p2) {
    263                 assert p1 != null && p2 != null;
    264 
    265                 final float vecX = p2.x - p1.x;
    266                 final float vecY = p2.y - p1.y;
    267 
    268                 final float vecLength = (float)Math.sqrt(vecX*vecX + vecY*vecY);
    269 
    270                 final float dotProductVecAxis = vecX;
    271 
    272                 float angle = (float)Math.acos(dotProductVecAxis / vecLength);
    273 
    274                 if (p2.y < p1.y) {
    275                         angle = -angle;
    276                 }
    277 
    278                 assert -Math.PI*0.5 < angle && angle <= Math.PI*0.5;
    279 
    280                 return angle;
    281         }
    282 
    283         @Override
    284         public void paint(final Graphics2D g, final MapView mv, Bounds bounds) {
    285                 if (wayGraph != null) {
    286 
    287                         for (GraphNode n : wayGraph.getNodes()) {
    288                                 paintGraphNode(n, g, mv);
    289                         }
    290 
    291                         for (GraphEdge e : wayGraph.getEdges()) {
    292                                 paintGraphEdge(e, g, mv);
    293                         }
    294 
    295                 }
    296 
    297         }
    298 
    299         @Override
    300         public String getToolTipText() {
    301                 return "routing graph calculated by the GraphView plugin";
    302         }
    303 
    304         @Override
    305         public void mergeFrom(Layer from) {
    306                 throw new AssertionError("GraphView layer is not mergable");
    307         }
    308 
    309         @Override
    310         public boolean isMergable(Layer other) {
    311                 return false;
    312         }
    313 
    314         @Override
    315         public void visitBoundingBox(BoundingXYVisitor v) {
    316         }
    317 
    318         @Override
    319         public Object getInfoComponent() {
    320                 return getToolTipText();
    321         }
    322 
    323         @Override
    324         public Action[] getMenuEntries() {
    325                 return new Action[] {
    326                                 LayerListDialog.getInstance().createShowHideLayerAction(),
    327                                 LayerListDialog.getInstance().createDeleteLayerAction(),
    328                                 SeparatorLayerAction.INSTANCE,
    329                                 new RenameLayerAction(null, this),
    330                                 SeparatorLayerAction.INSTANCE,
    331                                 new LayerListPopup.InfoAction(this)};
    332         }
    333 
    334         public void update(WayGraph wayGraph) {
    335                 assert wayGraph == this.wayGraph;
    336                 Main.panel.repaint();
    337         }
    338 
    339         public void activeLayerChange(Layer oldLayer, Layer newLayer) {
    340                 //do nothing
    341         }
    342         public void layerAdded(Layer newLayer) {
    343                 //do nothing
    344         }
    345         public void layerRemoved(Layer oldLayer) {
    346                 if (oldLayer == this) {
    347                         MapView.removeLayerChangeListener(this);
    348                 }
    349         }
     48    private static final int NODE_RADIUS = 5;
     49
     50    /**
     51    * offset from real position if {@link GraphViewPreferences#getSeparateDirections()} is active,
     52    * causes the graph nodes for the two directions to be visually distinguishable.
     53    * Positive values move "forward" direction to the right.
     54    */
     55    private static final double DIRECTIONAL_OFFSET = 20;
     56
     57    private static final double OFFSET_ANGLE = 0.5 * Math.PI;
     58
     59    private static final double MIN_QUAD_DISTANCE_FOR_OFFSET = 4;
     60
     61    private static final boolean CONNECT_ALL_NODE_PAIRS = false;
     62
     63    /** an arrow head that points along the x-axis to (0,0) */
     64    private static final Shape ARROW_HEAD;
     65
     66    static {
     67
     68        Polygon head = new Polygon();
     69
     70        head.addPoint(  0,  0);
     71        head.addPoint(-15, +4);
     72        head.addPoint(-15, -4);
     73
     74        ARROW_HEAD = head;
     75    }
     76
     77    private WayGraph wayGraph = null;
     78
     79    private ColorScheme colorScheme = null;
     80    private NodePositioner nodePositioner = new NonMovingNodePositioner();
     81
     82    public GraphViewLayer() {
     83        super("Graph view");
     84        MapView.addLayerChangeListener(this);
     85    }
     86
     87    /** sets the WayGraph that is to be displayed by this layer, may be null */
     88    public void setWayGraph(WayGraph wayGraph) {
     89        if (this.wayGraph != null) {
     90            this.wayGraph.deleteObserver(this);
     91        }
     92        this.wayGraph = wayGraph;
     93        if (wayGraph != null) {
     94            wayGraph.addObserver(this);
     95        }
     96    }
     97
     98    /** sets the ColorScheme that is to be used for choosing colors, may be null */
     99    public void setColorScheme(ColorScheme colorScheme) {
     100        this.colorScheme = colorScheme;
     101        Main.panel.repaint();
     102    }
     103
     104    /**
     105    * sets the NodePositioner that is to be used for determining node placement,
     106    * null will cause a {@link NonMovingNodePositioner} to be used.
     107    */
     108    public void setNodePositioner(NodePositioner nodePositioner) {
     109        this.nodePositioner = nodePositioner;
     110        if (nodePositioner == null) {
     111            this.nodePositioner = new NonMovingNodePositioner();
     112        }
     113        Main.panel.repaint();
     114    }
     115
     116    @Override
     117    public Icon getIcon() {
     118        return ImageProvider.get("layer", "graphview");
     119    }
     120
     121    private void paintGraphNode(final GraphNode node, final Graphics g, final MapView mv) {
     122
     123        Color color = colorScheme != null ? colorScheme.getNodeColor(node) : Color.LIGHT_GRAY;
     124
     125        Point p = getNodePoint(node, mv);
     126        g.setColor(color);
     127        g.fillOval(p.x - NODE_RADIUS, p.y - NODE_RADIUS, 2 * NODE_RADIUS, 2 * NODE_RADIUS);
     128
     129    }
     130
     131    private void paintGraphEdge(final GraphEdge e, final Graphics2D g2D, final MapView mv) {
     132
     133        if (!CONNECT_ALL_NODE_PAIRS && GraphViewPreferences.getInstance().getSeparateDirections()) {
     134
     135            //don't paint edges between nodes from the same SegmentNode and simply inverted Segment
     136            if (e.getStartNode().getSegmentNode() == e.getTargetNode().getSegmentNode()
     137                    && e.getStartNode().getSegment().getNode2() == e.getTargetNode().getSegment().getNode1()
     138                    && e.getStartNode().getSegment().getNode1() == e.getTargetNode().getSegment().getNode2()) {
     139                return;
     140            }
     141
     142        }
     143
     144        /* draw line(s) */
     145
     146        g2D.setStroke(new BasicStroke(3, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
     147
     148        List<Segment> edgeSegments = e.getPropertyValue(GraphEdgeSegments.PROPERTY);
     149
     150        if (edgeSegments.size() > 0) {
     151
     152            Segment firstSegment = edgeSegments.get(0);
     153            Segment lastSegment = edgeSegments.get(edgeSegments.size() - 1);
     154
     155            //draw segments
     156
     157            for (Segment segment : edgeSegments) {
     158
     159                Color color = Color.WHITE;
     160                if (colorScheme != null) {
     161                    color = colorScheme.getSegmentColor(segment);
     162                }
     163                g2D.setColor(color);
     164
     165                Point p1 = getNodePoint(segment.getNode1(), mv);
     166                Point p2 = getNodePoint(segment.getNode2(), mv);
     167
     168                if (segment == firstSegment) {
     169                    p1 = getNodePoint(e.getStartNode(), mv);
     170                }
     171                if (segment == lastSegment) {
     172                    p2 = getNodePoint(e.getTargetNode(), mv);
     173                }
     174
     175                g2D.draw(new Line2D.Float(p1.x, p1.y, p2.x, p2.y));
     176
     177            }
     178
     179        } else {
     180
     181            g2D.setColor(Color.WHITE);
     182
     183            Point p1 = getNodePoint(e.getStartNode(), mv);
     184            Point p2 = getNodePoint(e.getTargetNode(), mv);
     185
     186            g2D.draw(new Line2D.Float(p1.x, p1.y, p2.x, p2.y));
     187
     188        }
     189
     190        /* draw arrow head (note: color of last segment is still set) */
     191
     192        {
     193            Point p1 = getNodePoint(e.getStartNode(), mv);
     194            Point p2 = getNodePoint(e.getTargetNode(), mv);
     195
     196            if (edgeSegments.size() > 0) {
     197                Segment lastSegment = edgeSegments.get(edgeSegments.size() - 1);
     198                p1 = getNodePoint(lastSegment.getNode1(), mv);
     199            }
     200
     201            double angle = angleFromXAxis(p1, p2); // angle between x-axis and [p1,p2]
     202            Shape head = ARROW_HEAD;
     203            head = AffineTransform.getRotateInstance(angle).createTransformedShape(head);
     204            head = AffineTransform.getTranslateInstance(p2.x, p2.y).createTransformedShape(head);
     205
     206            g2D.fill(head);
     207
     208        }
     209    }
     210
     211    private Point getNodePoint(GraphNode node, MapView mv) {
     212
     213        Point nodePoint = getNodePoint(nodePositioner.getPosition(node), mv);
     214
     215        if (GraphViewPreferences.getInstance().getSeparateDirections()
     216                && !GraphUtil.isEndNode(node)) {
     217
     218            SegmentNode node1 = node.getSegment().getNode1();
     219            SegmentNode node2 = node.getSegment().getNode2();
     220
     221            Point node1Point = getNodePoint(node1, mv);
     222            Point node2Point = getNodePoint(node2, mv);
     223
     224            double segmentX = node2Point.getX() - node1Point.getX();
     225            double segmentY = node2Point.getY() - node1Point.getY();
     226
     227            if (segmentX*segmentX + segmentY*segmentY >= MIN_QUAD_DISTANCE_FOR_OFFSET) {
     228
     229                double rotatedX = Math.cos(OFFSET_ANGLE) * segmentX - Math.sin(OFFSET_ANGLE) * segmentY;
     230                double rotatedY = Math.sin(OFFSET_ANGLE) * segmentX + Math.cos(OFFSET_ANGLE) * segmentY;
     231
     232                double segmentLength = Math.sqrt(rotatedX * rotatedX + rotatedY * rotatedY);
     233
     234                double normalizedX = rotatedX / segmentLength;
     235                double normalizedY = rotatedY / segmentLength;
     236
     237                nodePoint.x += DIRECTIONAL_OFFSET * normalizedX;
     238                nodePoint.y += DIRECTIONAL_OFFSET * normalizedY;
     239
     240            }
     241
     242        }
     243
     244        return nodePoint;
     245    }
     246    private Point getNodePoint(SegmentNode node, MapView mv) {
     247        LatLonCoords coords = new LatLonCoords(node.getLat(), node.getLon());
     248        return getNodePoint(coords, mv);
     249    }
     250    private Point getNodePoint(LatLonCoords coords, MapView mv) {
     251        LatLon latLon = new LatLon(coords.getLat(), coords.getLon());
     252        EastNorth eastNorth = Main.proj.latlon2eastNorth(latLon);
     253        return mv.getPoint(eastNorth);
     254    }
     255
     256    /**
     257    * calculates the angle between the x axis and a vector given by two points
     258    * @param p1  first point for vector; != null
     259    * @param p2  second point for vector; != null
     260    * @return  angle in radians, in range [-Pi .. +Pi]
     261    */
     262    private double angleFromXAxis(Point p1, Point p2) {
     263        assert p1 != null && p2 != null;
     264
     265        final float vecX = p2.x - p1.x;
     266        final float vecY = p2.y - p1.y;
     267
     268        final float vecLength = (float)Math.sqrt(vecX*vecX + vecY*vecY);
     269
     270        final float dotProductVecAxis = vecX;
     271
     272        float angle = (float)Math.acos(dotProductVecAxis / vecLength);
     273
     274        if (p2.y < p1.y) {
     275            angle = -angle;
     276        }
     277
     278        assert -Math.PI*0.5 < angle && angle <= Math.PI*0.5;
     279
     280        return angle;
     281    }
     282
     283    @Override
     284    public void paint(final Graphics2D g, final MapView mv, Bounds bounds) {
     285        if (wayGraph != null) {
     286
     287            for (GraphNode n : wayGraph.getNodes()) {
     288                paintGraphNode(n, g, mv);
     289            }
     290
     291            for (GraphEdge e : wayGraph.getEdges()) {
     292                paintGraphEdge(e, g, mv);
     293            }
     294
     295        }
     296
     297    }
     298
     299    @Override
     300    public String getToolTipText() {
     301        return "routing graph calculated by the GraphView plugin";
     302    }
     303
     304    @Override
     305    public void mergeFrom(Layer from) {
     306        throw new AssertionError("GraphView layer is not mergable");
     307    }
     308
     309    @Override
     310    public boolean isMergable(Layer other) {
     311        return false;
     312    }
     313
     314    @Override
     315    public void visitBoundingBox(BoundingXYVisitor v) {
     316    }
     317
     318    @Override
     319    public Object getInfoComponent() {
     320        return getToolTipText();
     321    }
     322
     323    @Override
     324    public Action[] getMenuEntries() {
     325        return new Action[] {
     326                LayerListDialog.getInstance().createShowHideLayerAction(),
     327                LayerListDialog.getInstance().createDeleteLayerAction(),
     328                SeparatorLayerAction.INSTANCE,
     329                new RenameLayerAction(null, this),
     330                SeparatorLayerAction.INSTANCE,
     331                new LayerListPopup.InfoAction(this)};
     332    }
     333
     334    public void update(WayGraph wayGraph) {
     335        assert wayGraph == this.wayGraph;
     336        Main.panel.repaint();
     337    }
     338
     339    public void activeLayerChange(Layer oldLayer, Layer newLayer) {
     340        //do nothing
     341    }
     342    public void layerAdded(Layer newLayer) {
     343        //do nothing
     344    }
     345    public void layerRemoved(Layer oldLayer) {
     346        if (oldLayer == this) {
     347            MapView.removeLayerChangeListener(this);
     348        }
     349    }
    350350}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/plugin/layer/PreferencesColorScheme.java

    r16520 r23189  
    1313public class PreferencesColorScheme implements ColorScheme {
    1414
    15         private final GraphViewPreferences preferences;
     15    private final GraphViewPreferences preferences;
    1616
    17         public PreferencesColorScheme(GraphViewPreferences preferences) {
    18                 this.preferences = preferences;
    19         }
     17    public PreferencesColorScheme(GraphViewPreferences preferences) {
     18        this.preferences = preferences;
     19    }
    2020
    21         public Color getNodeColor(GraphNode node) {
    22                 return preferences.getNodeColor();
    23         }
     21    public Color getNodeColor(GraphNode node) {
     22        return preferences.getNodeColor();
     23    }
    2424
    25         public Color getSegmentColor(Segment segment) {
    26                 return preferences.getSegmentColor();
    27         }
     25    public Color getSegmentColor(Segment segment) {
     26        return preferences.getSegmentColor();
     27    }
    2828
    2929}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/plugin/preferences/GraphViewPreferenceDefaults.java

    r16520 r23189  
    2222public final class GraphViewPreferenceDefaults {
    2323
    24         /** prevents instantiation */
    25         private GraphViewPreferenceDefaults() { }
     24    /** prevents instantiation */
     25    private GraphViewPreferenceDefaults() { }
    2626
    27         /** creates a default "empty" bookmark */
    28         public static PreferenceAccessParameters createDefaultBookmarkAccessParameters() {
     27    /** creates a default "empty" bookmark */
     28    public static PreferenceAccessParameters createDefaultBookmarkAccessParameters() {
    2929
    30                 Collection<AccessType> accessTypes =
    31                         Arrays.asList(UNDEFINED, YES, PERMISSIVE, DESIGNATED);
     30        Collection<AccessType> accessTypes =
     31            Arrays.asList(UNDEFINED, YES, PERMISSIVE, DESIGNATED);
    3232
    33                 Map<VehiclePropertyType<?>, String> propertyStringMap =
    34                         new HashMap<VehiclePropertyType<?>, String>();
     33        Map<VehiclePropertyType<?>, String> propertyStringMap =
     34            new HashMap<VehiclePropertyType<?>, String>();
    3535
    36                 try {
    37                         return new PreferenceAccessParameters("", accessTypes, propertyStringMap);
    38                 } catch (PropertyValueSyntaxException e) {
    39                         throw new AssertionError(e);
    40                 }
     36        try {
     37            return new PreferenceAccessParameters("", accessTypes, propertyStringMap);
     38        } catch (PropertyValueSyntaxException e) {
     39            throw new AssertionError(e);
     40        }
    4141
    42         }
     42    }
    4343
    44         /** creates the default map of access parameter bookmarks */
    45         public static Map<String, PreferenceAccessParameters> createDefaultAccessParameterBookmarks() {
     44    /** creates the default map of access parameter bookmarks */
     45    public static Map<String, PreferenceAccessParameters> createDefaultAccessParameterBookmarks() {
    4646
    47                 try {
     47        try {
    4848
    49                         Map<String, PreferenceAccessParameters> result =
    50                                 new HashMap<String, PreferenceAccessParameters>();
     49            Map<String, PreferenceAccessParameters> result =
     50                new HashMap<String, PreferenceAccessParameters>();
    5151
    52                         Collection<AccessType> accessTypes =
    53                                 Arrays.asList(UNDEFINED, YES, PERMISSIVE, DESIGNATED);
     52            Collection<AccessType> accessTypes =
     53                Arrays.asList(UNDEFINED, YES, PERMISSIVE, DESIGNATED);
    5454
    55                         /* create motorcar bookmark */
    56                         {
    57                                 Map<VehiclePropertyType<?>, String> propertyMap =
    58                                         new HashMap<VehiclePropertyType<?>, String>();
     55            /* create motorcar bookmark */
     56            {
     57                Map<VehiclePropertyType<?>, String> propertyMap =
     58                    new HashMap<VehiclePropertyType<?>, String>();
    5959
    60                                 PreferenceAccessParameters accessParameters =
    61                                         new PreferenceAccessParameters("motorcar", accessTypes, propertyMap);
     60                PreferenceAccessParameters accessParameters =
     61                    new PreferenceAccessParameters("motorcar", accessTypes, propertyMap);
    6262
    63                                 result.put("motorcar", accessParameters);
    64                         }
     63                result.put("motorcar", accessParameters);
     64            }
    6565
    66                         /* create hgv bookmark */
    67                         {
    68                                 Map<VehiclePropertyType<?>, String> propertyMap =
    69                                         new HashMap<VehiclePropertyType<?>, String>();
    70                                 propertyMap.put(VehiclePropertyTypes.WEIGHT, "3.5");
     66            /* create hgv bookmark */
     67            {
     68                Map<VehiclePropertyType<?>, String> propertyMap =
     69                    new HashMap<VehiclePropertyType<?>, String>();
     70                propertyMap.put(VehiclePropertyTypes.WEIGHT, "3.5");
    7171
    72                                 PreferenceAccessParameters accessParameters =
    73                                         new PreferenceAccessParameters("hgv", accessTypes, propertyMap);
     72                PreferenceAccessParameters accessParameters =
     73                    new PreferenceAccessParameters("hgv", accessTypes, propertyMap);
    7474
    75                                 result.put("hgv (3.5 t)", accessParameters);
    76                         }
     75                result.put("hgv (3.5 t)", accessParameters);
     76            }
    7777
    78                         /* create bicycle bookmark */
    79                         {
    80                                 Map<VehiclePropertyType<?>, String> propertyMap =
    81                                         new HashMap<VehiclePropertyType<?>, String>();
     78            /* create bicycle bookmark */
     79            {
     80                Map<VehiclePropertyType<?>, String> propertyMap =
     81                    new HashMap<VehiclePropertyType<?>, String>();
    8282
    83                                 PreferenceAccessParameters accessParameters =
    84                                         new PreferenceAccessParameters("bicycle", accessTypes, propertyMap);
     83                PreferenceAccessParameters accessParameters =
     84                    new PreferenceAccessParameters("bicycle", accessTypes, propertyMap);
    8585
    86                                 result.put("bicycle", accessParameters);
    87                         }
     86                result.put("bicycle", accessParameters);
     87            }
    8888
    89                         /* create pedestrian bookmark */
    90                         {
    91                                 Map<VehiclePropertyType<?>, String> propertyMap =
    92                                         new HashMap<VehiclePropertyType<?>, String>();
     89            /* create pedestrian bookmark */
     90            {
     91                Map<VehiclePropertyType<?>, String> propertyMap =
     92                    new HashMap<VehiclePropertyType<?>, String>();
    9393
    94                                 PreferenceAccessParameters accessParameters =
    95                                         new PreferenceAccessParameters("foot", accessTypes, propertyMap);
     94                PreferenceAccessParameters accessParameters =
     95                    new PreferenceAccessParameters("foot", accessTypes, propertyMap);
    9696
    97                                 result.put("pedestrian", accessParameters);
    98                         }
     97                result.put("pedestrian", accessParameters);
     98            }
    9999
    100                         return result;
     100            return result;
    101101
    102                 } catch (PropertyValueSyntaxException e) {
    103                         throw new AssertionError(e);
    104                 }
    105         }
     102        } catch (PropertyValueSyntaxException e) {
     103            throw new AssertionError(e);
     104        }
     105    }
    106106
    107         public static File getDefaultRulesetFolder() {
    108                 return new File(System.getProperty("user.home"));
    109         }
     107    public static File getDefaultRulesetFolder() {
     108        return new File(System.getProperty("user.home"));
     109    }
    110110
    111111}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/plugin/preferences/GraphViewPreferences.java

    r16520 r23189  
    3939public class GraphViewPreferences extends Observable {
    4040
    41         private static GraphViewPreferences instance;
    42 
    43         /**
    44         * returns the single instance of GraphViewPreferences.
    45         * @param ignoreSyntaxErrors
    46         * @return
    47         */
    48         public static GraphViewPreferences getInstance() {
    49                 if (instance == null) {
    50                         instance = new GraphViewPreferences();
    51                 }
    52                 return instance;
    53         }
    54 
    55         private boolean useInternalRulesets;
    56         private File rulesetFolder;
    57         private File currentRulesetFile;
    58         private InternalRuleset currentInternalRuleset;
    59 
    60         private String currentParameterBookmarkName;
    61         private Map<String, PreferenceAccessParameters> parameterBookmarks;
    62 
    63         private ColorScheme currentColorScheme;
    64         private Color nodeColor;
    65         private Color segmentColor;
    66 
    67         private boolean separateDirections;
    68 
    69 
    70         public synchronized boolean getUseInternalRulesets() {
    71                 return useInternalRulesets;
    72         }
    73         public synchronized void setUseInternalRulesets(boolean useInternalRulesets) {
    74                 this.useInternalRulesets = useInternalRulesets;
    75         }
    76 
    77         public synchronized File getRulesetFolder() {
    78                 return rulesetFolder;
    79         }
    80         public synchronized void setRulesetFolder(File rulesetFolder) {
    81                 this.rulesetFolder = rulesetFolder;
    82         }
    83 
    84         public synchronized File getCurrentRulesetFile() {
    85                 return currentRulesetFile;
    86         }
    87         public synchronized void setCurrentRulesetFile(File currentRulesetFile) {
    88                 this.currentRulesetFile = currentRulesetFile;
    89         }
    90 
    91         public synchronized InternalRuleset getCurrentInternalRuleset() {
    92                 return currentInternalRuleset;
    93         }
    94         public synchronized void setCurrentInternalRuleset(InternalRuleset internalRuleset) {
    95                 this.currentInternalRuleset = internalRuleset;
    96         }
    97 
    98         /**
    99         * returns the name (map key) of the currently selected parameter bookmark
    100         * or null if none is selected.
    101         * If a name is returned, is has to be a key of the map returned by
    102         * {@link #getParameterBookmarks()}.
    103         */
    104         public synchronized String getCurrentParameterBookmarkName() {
    105                 assert parameterBookmarks.containsKey(currentParameterBookmarkName);
    106                 return currentParameterBookmarkName;
    107         }
    108 
    109         /**
    110         * returns the access parameters of the currently selected parameter bookmark
    111         * or null if none is selected.
    112         */
    113         public synchronized AccessParameters getCurrentParameterBookmark() {
    114                 if (currentParameterBookmarkName == null) {
    115                         return null;
    116                 } else {
    117                         assert parameterBookmarks.containsKey(currentParameterBookmarkName);
    118                         return parameterBookmarks.get(currentParameterBookmarkName);
    119                 }
    120         }
    121 
    122         /**
    123         * sets the active parameter bookmark using its name as an identifier
    124         * @param currentParameters  name of bookmark to set or null (no active bookmark).
    125         *                           Non-null values must be keys of the map returned by
    126         *                           {@link #getParameterBookmarks()}.
    127         */
    128         public synchronized void setCurrentParameterBookmarkName(String parameterBookmarkName) {
    129                 assert parameterBookmarks.containsKey(parameterBookmarkName);
    130                 this.currentParameterBookmarkName = parameterBookmarkName;
    131         }
    132 
    133         public synchronized Map<String, PreferenceAccessParameters> getParameterBookmarks() {
    134                 return Collections.unmodifiableMap(parameterBookmarks);
    135         }
    136         public synchronized void setParameterBookmarks(
    137                         Map<String, PreferenceAccessParameters> parameterBookmarks) {
    138                 assert parameterBookmarks != null;
    139 
    140                 this.parameterBookmarks =
    141                         new HashMap<String, PreferenceAccessParameters>(parameterBookmarks);
    142         }
    143 
    144         public synchronized ColorScheme getCurrentColorScheme() {
    145                 return currentColorScheme;
    146         }
    147         public synchronized void setCurrentColorScheme(ColorScheme currentColorScheme) {
    148                 this.currentColorScheme = currentColorScheme;
    149         }
    150 
    151         public synchronized Color getNodeColor() {
    152                 return nodeColor;
    153         }
    154         public synchronized void setNodeColor(Color nodeColor) {
    155                 this.nodeColor = nodeColor;
    156         }
    157 
    158         public synchronized Color getSegmentColor() {
    159                 return segmentColor;
    160         }
    161         public synchronized void setSegmentColor(Color segmentColor) {
    162                 this.segmentColor = segmentColor;
    163         }
    164 
    165         public synchronized boolean getSeparateDirections() {
    166                 return separateDirections;
    167         }
    168         public synchronized void setSeparateDirections(boolean separateDirections) {
    169                 this.separateDirections = separateDirections;
    170         }
    171 
    172         /**
    173         * writes changes to JOSM's preferences and notifies observers.
    174         * Must be called explicitly after setters (to prevent distributing incomplete changes).
    175         */
    176         public void distributeChanges() {
    177                 writePreferences();
    178                 setChanged();
    179                 notifyObservers();
    180         }
    181 
    182         private GraphViewPreferences() {
    183 
    184                 /* set defaults first (in case preferences are incomplete) */
    185 
    186                 fillDefaults();
    187 
    188                 /* read preferences and overwrite defaults */
    189 
    190                 readPreferences();
    191 
    192                 /* write preferences
    193                 * (this will restore missing/defect preferences,
    194                 *  but will simply rewrite valid preferences) */
    195 
    196                 writePreferences();
    197 
    198         }
    199 
    200         private void fillDefaults() {
    201 
    202                 parameterBookmarks = GraphViewPreferenceDefaults.createDefaultAccessParameterBookmarks();
    203 
    204                 if (parameterBookmarks.size() > 0) {
    205                         currentParameterBookmarkName = parameterBookmarks.keySet().iterator().next();
    206                 } else {
    207                         currentParameterBookmarkName = null;
    208                 }
    209 
    210                 useInternalRulesets = true;
    211                 rulesetFolder = GraphViewPreferenceDefaults.getDefaultRulesetFolder();
    212                 currentRulesetFile = null;
    213                 currentInternalRuleset = null;
    214 
    215                 nodeColor = Color.WHITE;
    216                 segmentColor = Color.WHITE;
    217                 currentColorScheme = new PreferencesColorScheme(this);
    218 
    219                 separateDirections = false;
    220 
    221         }
    222 
    223         private void writePreferences() {
    224 
    225                 Main.pref.put("graphview.parameterBookmarks",
    226                                 createAccessParameterBookmarksString(parameterBookmarks));
    227 
    228                 if (currentParameterBookmarkName != null) {
    229                         Main.pref.put("graphview.activeBookmark", currentParameterBookmarkName);
    230                 }
    231 
    232                 Main.pref.put("graphview.useInternalRulesets", useInternalRulesets);
    233 
    234                 Main.pref.put("graphview.rulesetFolder", rulesetFolder.getPath());
    235 
    236                 if (currentRulesetFile != null) {
    237                         Main.pref.put("graphview.rulesetFile", currentRulesetFile.getPath());
    238                 }
    239                 if (currentInternalRuleset != null) {
    240                         Main.pref.put("graphview.rulesetResource", currentInternalRuleset.toString());
    241                 }
    242 
    243                 Main.pref.put("graphview.defaultNodeColor", createColorString(nodeColor));
    244                 Main.pref.put("graphview.defaultSegmentColor", createColorString(segmentColor));
    245 
    246                 Main.pref.put("graphview.separateDirections", separateDirections);
    247 
    248         }
    249 
    250         private void readPreferences() {
    251 
    252                 if (Main.pref.hasKey("graphview.parameterBookmarks")) {
    253                         String bookmarksString = Main.pref.get("graphview.parameterBookmarks");
    254                         parameterBookmarks = parseAccessParameterBookmarksString(bookmarksString);
    255                 }
    256 
    257                 if (Main.pref.hasKey("graphview.activeBookmark")) {
    258                         currentParameterBookmarkName = Main.pref.get("graphview.activeBookmark");
    259                 }
    260                 if (!parameterBookmarks.containsKey(currentParameterBookmarkName)) {
    261                         currentParameterBookmarkName = null;
    262                 }
    263 
    264 
    265                 useInternalRulesets = Main.pref.getBoolean("graphview.useInternalRulesets", true);
    266 
    267                 if (Main.pref.hasKey("graphview.rulesetFolder")) {
    268                         String dirString = Main.pref.get("graphview.rulesetFolder");
    269                         rulesetFolder = new File(dirString);
    270                 }
    271                 if (Main.pref.hasKey("graphview.rulesetFile")) {
    272                         String fileString = Main.pref.get("graphview.rulesetFile");
    273                         currentRulesetFile = new File(fileString);
    274                 }
    275 
    276                 if (Main.pref.hasKey("graphview.rulesetResource")) {
    277                         String rulesetString = Main.pref.get("graphview.rulesetResource");
    278                         //get the enum value for the string
    279                         //(InternalRuleset.valueOf cannot be used because it cannot handle invalid strings well)
    280                         for (InternalRuleset ruleset : InternalRuleset.values()) {
    281                                 if (ruleset.toString().equals(rulesetString)) {
    282                                         currentInternalRuleset = ruleset;
    283                                         break;
    284                                 }
    285                         }
    286                 }
    287 
    288                 if (Main.pref.hasKey("graphview.defaultNodeColor")) {
    289                         Color color = parseColorString(Main.pref.get("graphview.defaultNodeColor"));
    290                         if (color != null) {
    291                                 nodeColor = color;
    292                         }
    293                 }
    294                 if (Main.pref.hasKey("graphview.defaultSegmentColor")) {
    295                         Color color = parseColorString(Main.pref.get("graphview.defaultSegmentColor"));
    296                         if (color != null) {
    297                                 segmentColor = color;
    298                         }
    299                 }
    300 
    301                 separateDirections = Main.pref.getBoolean("graphview.separateDirections", false);
    302 
    303         }
    304 
    305         private static final Pattern ACCESS_PARAM_PATTERN = Pattern.compile("^([^;]*);([^;]*);types=\\{([^\\}]*)\\};properties=\\{([^\\}]*)\\}$");
    306 
    307         private static final Pattern PROPERTY_MAP_ENTRY_PATTERN = Pattern.compile("^([^=]*)=(.*)$");
    308 
    309         private static final Map<VehiclePropertyType<?>, String> VEHICLE_PROPERTY_TYPE_NAME_MAP =
    310                 new HashMap<VehiclePropertyType<?>, String>();
    311 
    312 
    313         static {
    314                 VEHICLE_PROPERTY_TYPE_NAME_MAP.put(AXLELOAD, "AXLELOAD");
    315                 VEHICLE_PROPERTY_TYPE_NAME_MAP.put(HEIGHT, "HEIGHT");
    316                 VEHICLE_PROPERTY_TYPE_NAME_MAP.put(LENGTH, "LENGTH");
    317                 VEHICLE_PROPERTY_TYPE_NAME_MAP.put(MAX_INCLINE_DOWN, "MAX_INCLINE_DOWN");
    318                 VEHICLE_PROPERTY_TYPE_NAME_MAP.put(MAX_INCLINE_UP, "MAX_INCLINE_UP");
    319                 VEHICLE_PROPERTY_TYPE_NAME_MAP.put(MAX_TRACKTYPE, "MAX_TRACKTYPE");
    320                 VEHICLE_PROPERTY_TYPE_NAME_MAP.put(SPEED, "SPEED");
    321                 VEHICLE_PROPERTY_TYPE_NAME_MAP.put(SURFACE_BLACKLIST, "SURFACE_BLACKLIST");
    322                 VEHICLE_PROPERTY_TYPE_NAME_MAP.put(WEIGHT, "WEIGHT");
    323                 VEHICLE_PROPERTY_TYPE_NAME_MAP.put(WIDTH, "WIDTH");
    324         }
    325 
    326         private static String createAccessParameterBookmarksString(
    327                         Map<String, PreferenceAccessParameters> parameterBookmarks) {
    328 
    329                 StringBuilder stringBuilder = new StringBuilder();
    330 
    331                 boolean firstEntry = true;
    332 
    333                 for (String bookmarkName : parameterBookmarks.keySet()) {
    334 
    335                         if (!firstEntry) {
    336                                 stringBuilder.append("|");
    337                         } else {
    338                                 firstEntry = false;
    339                         }
    340 
    341                         stringBuilder.append(createAccessParameterBookmarkString(
    342                                         bookmarkName,
    343                                         parameterBookmarks.get(bookmarkName)));
    344 
    345                 }
    346 
    347                 return stringBuilder.toString();
    348         }
    349 
    350         private static String createAccessParameterBookmarkString(
    351                         String bookmarkName, PreferenceAccessParameters parameters) {
    352 
    353                 StringBuilder stringBuilder = new StringBuilder();
    354 
    355                 stringBuilder.append(bookmarkName).append(";");
    356 
    357                 stringBuilder.append(parameters.getAccessClass());
    358 
    359                 stringBuilder.append(";types={");
    360                 for (AccessType accessType : AccessType.values()) {
    361                         if (parameters.getAccessTypeUsable(accessType)) {
    362                                 stringBuilder.append(accessType).append(",");
    363                         }
    364                 }
    365 
    366                 if(stringBuilder.charAt(stringBuilder.length()-1) == ',') {
    367                         stringBuilder.deleteCharAt(stringBuilder.length()-1);
    368                 }
    369                 stringBuilder.append("}");
    370 
    371                 stringBuilder.append(";properties={");
    372 
    373                 for (VehiclePropertyType<?> vehiclePropertyType : VEHICLE_PROPERTY_TYPE_NAME_MAP.keySet()) {
    374                         String propertyString = parameters.getVehiclePropertyString(vehiclePropertyType);
    375                         if (propertyString != null) {
    376                                 stringBuilder.append(VEHICLE_PROPERTY_TYPE_NAME_MAP.get(vehiclePropertyType));
    377                                 stringBuilder.append("=");
    378                                 stringBuilder.append(propertyString);
    379                                 stringBuilder.append(",");
    380                         }
    381                 }
    382 
    383                 if(stringBuilder.charAt(stringBuilder.length()-1) == ',') {
    384                         stringBuilder.deleteCharAt(stringBuilder.length()-1);
    385                 }
    386                 stringBuilder.append("}");
    387 
    388                 assert ACCESS_PARAM_PATTERN.matcher(stringBuilder.toString()).matches();
    389 
    390                 return stringBuilder.toString();
    391         }
    392 
    393         private static Map<String, PreferenceAccessParameters> parseAccessParameterBookmarksString(
    394                         String string) {
    395 
    396                 Map<String, PreferenceAccessParameters> resultMap =
    397                         new HashMap<String, PreferenceAccessParameters>();
    398 
    399                 String[] bookmarkStrings = string.split("\\|");
    400 
    401                 for (String bookmarkString : bookmarkStrings) {
    402                         parseAccessParameterBookmarkString(bookmarkString, resultMap);
    403                 }
    404 
    405                 return resultMap;
    406         }
    407 
    408         private static void parseAccessParameterBookmarkString(String bookmarkString,
    409                         Map<String, PreferenceAccessParameters> resultMap) {
    410 
    411                 Matcher matcher = ACCESS_PARAM_PATTERN.matcher(bookmarkString);
    412 
    413                 if (matcher.matches()) {
    414 
    415                         String bookmarkName = matcher.group(1);
    416 
    417                         String accessClass = matcher.group(2);
    418 
    419                         String[] accessTypeStrings = matcher.group(3).split(",");
    420                         Collection<AccessType> accessTypes = new LinkedList<AccessType>();
    421                         for (String accessTypeString : accessTypeStrings) {
    422                                 AccessType accessType = AccessType.valueOf(accessTypeString);
    423                                 if (accessType != null) {
    424                                         accessTypes.add(accessType);
    425                                 }
    426                         }
    427 
    428 
    429                         String[] vehiclePropertyStrings = matcher.group(4).split(",");
    430                         Map<VehiclePropertyType<?>, String> vehiclePropertyMap =
    431                                 new HashMap<VehiclePropertyType<?>, String>();
    432 
    433                         for (String vehiclePropertyString : vehiclePropertyStrings) {
    434 
    435                                 Matcher entryMatcher = PROPERTY_MAP_ENTRY_PATTERN.matcher(vehiclePropertyString);
    436                                 if (entryMatcher.matches()) {
    437 
    438                                         String propertyTypeString = entryMatcher.group(1);
    439                                         String propertyValueString = entryMatcher.group(2);
    440 
    441                                         for (VehiclePropertyType<?> propertyType :
    442                                                 VEHICLE_PROPERTY_TYPE_NAME_MAP.keySet()) {
    443 
    444                                                 if (propertyTypeString.equals(
    445                                                                 VEHICLE_PROPERTY_TYPE_NAME_MAP.get(propertyType))) {
    446 
    447                                                         vehiclePropertyMap.put(propertyType, propertyValueString);
    448 
    449                                                 }
    450 
    451                                         }
    452 
    453                                 }
    454 
    455                         }
    456 
    457                         try {
    458 
    459                                 PreferenceAccessParameters accessParameters =
    460                                         new PreferenceAccessParameters(accessClass, accessTypes, vehiclePropertyMap);
    461 
    462                                 resultMap.put(bookmarkName, accessParameters);
    463 
    464                         } catch (PropertyValueSyntaxException e) {
    465                                 //don't add bookmark
    466                         }
    467 
    468                 }
    469         }
    470 
    471         private static final Pattern COLOR_PATTERN =
    472                 Pattern.compile("^(\\d{1,3}),\\s*(\\d{1,3}),\\s*(\\d{1,3})$");
    473         private String createColorString(Color color) {
    474                 return color.getRed() + ", " + color.getGreen() + ", " + color.getBlue();
    475         }
    476 
    477         private Color parseColorString(String string) {
    478                 Matcher matcher = COLOR_PATTERN.matcher(string);
    479                 if (!matcher.matches()) {
    480                         return null;
    481                 } else {
    482                         int r = Integer.parseInt(matcher.group(1));
    483                         int g = Integer.parseInt(matcher.group(2));
    484                         int b = Integer.parseInt(matcher.group(3));
    485                         return new Color(r, g, b);
    486                 }
    487         }
     41    private static GraphViewPreferences instance;
     42
     43    /**
     44    * returns the single instance of GraphViewPreferences.
     45    * @param ignoreSyntaxErrors
     46    * @return
     47    */
     48    public static GraphViewPreferences getInstance() {
     49        if (instance == null) {
     50            instance = new GraphViewPreferences();
     51        }
     52        return instance;
     53    }
     54
     55    private boolean useInternalRulesets;
     56    private File rulesetFolder;
     57    private File currentRulesetFile;
     58    private InternalRuleset currentInternalRuleset;
     59
     60    private String currentParameterBookmarkName;
     61    private Map<String, PreferenceAccessParameters> parameterBookmarks;
     62
     63    private ColorScheme currentColorScheme;
     64    private Color nodeColor;
     65    private Color segmentColor;
     66
     67    private boolean separateDirections;
     68
     69
     70    public synchronized boolean getUseInternalRulesets() {
     71        return useInternalRulesets;
     72    }
     73    public synchronized void setUseInternalRulesets(boolean useInternalRulesets) {
     74        this.useInternalRulesets = useInternalRulesets;
     75    }
     76
     77    public synchronized File getRulesetFolder() {
     78        return rulesetFolder;
     79    }
     80    public synchronized void setRulesetFolder(File rulesetFolder) {
     81        this.rulesetFolder = rulesetFolder;
     82    }
     83
     84    public synchronized File getCurrentRulesetFile() {
     85        return currentRulesetFile;
     86    }
     87    public synchronized void setCurrentRulesetFile(File currentRulesetFile) {
     88        this.currentRulesetFile = currentRulesetFile;
     89    }
     90
     91    public synchronized InternalRuleset getCurrentInternalRuleset() {
     92        return currentInternalRuleset;
     93    }
     94    public synchronized void setCurrentInternalRuleset(InternalRuleset internalRuleset) {
     95        this.currentInternalRuleset = internalRuleset;
     96    }
     97
     98    /**
     99    * returns the name (map key) of the currently selected parameter bookmark
     100    * or null if none is selected.
     101    * If a name is returned, is has to be a key of the map returned by
     102    * {@link #getParameterBookmarks()}.
     103    */
     104    public synchronized String getCurrentParameterBookmarkName() {
     105        assert parameterBookmarks.containsKey(currentParameterBookmarkName);
     106        return currentParameterBookmarkName;
     107    }
     108
     109    /**
     110    * returns the access parameters of the currently selected parameter bookmark
     111    * or null if none is selected.
     112    */
     113    public synchronized AccessParameters getCurrentParameterBookmark() {
     114        if (currentParameterBookmarkName == null) {
     115            return null;
     116        } else {
     117            assert parameterBookmarks.containsKey(currentParameterBookmarkName);
     118            return parameterBookmarks.get(currentParameterBookmarkName);
     119        }
     120    }
     121
     122    /**
     123    * sets the active parameter bookmark using its name as an identifier
     124    * @param currentParameters  name of bookmark to set or null (no active bookmark).
     125    *                           Non-null values must be keys of the map returned by
     126    *                           {@link #getParameterBookmarks()}.
     127    */
     128    public synchronized void setCurrentParameterBookmarkName(String parameterBookmarkName) {
     129        assert parameterBookmarks.containsKey(parameterBookmarkName);
     130        this.currentParameterBookmarkName = parameterBookmarkName;
     131    }
     132
     133    public synchronized Map<String, PreferenceAccessParameters> getParameterBookmarks() {
     134        return Collections.unmodifiableMap(parameterBookmarks);
     135    }
     136    public synchronized void setParameterBookmarks(
     137            Map<String, PreferenceAccessParameters> parameterBookmarks) {
     138        assert parameterBookmarks != null;
     139
     140        this.parameterBookmarks =
     141            new HashMap<String, PreferenceAccessParameters>(parameterBookmarks);
     142    }
     143
     144    public synchronized ColorScheme getCurrentColorScheme() {
     145        return currentColorScheme;
     146    }
     147    public synchronized void setCurrentColorScheme(ColorScheme currentColorScheme) {
     148        this.currentColorScheme = currentColorScheme;
     149    }
     150
     151    public synchronized Color getNodeColor() {
     152        return nodeColor;
     153    }
     154    public synchronized void setNodeColor(Color nodeColor) {
     155        this.nodeColor = nodeColor;
     156    }
     157
     158    public synchronized Color getSegmentColor() {
     159        return segmentColor;
     160    }
     161    public synchronized void setSegmentColor(Color segmentColor) {
     162        this.segmentColor = segmentColor;
     163    }
     164
     165    public synchronized boolean getSeparateDirections() {
     166        return separateDirections;
     167    }
     168    public synchronized void setSeparateDirections(boolean separateDirections) {
     169        this.separateDirections = separateDirections;
     170    }
     171
     172    /**
     173    * writes changes to JOSM's preferences and notifies observers.
     174    * Must be called explicitly after setters (to prevent distributing incomplete changes).
     175    */
     176    public void distributeChanges() {
     177        writePreferences();
     178        setChanged();
     179        notifyObservers();
     180    }
     181
     182    private GraphViewPreferences() {
     183
     184        /* set defaults first (in case preferences are incomplete) */
     185
     186        fillDefaults();
     187
     188        /* read preferences and overwrite defaults */
     189
     190        readPreferences();
     191
     192        /* write preferences
     193        * (this will restore missing/defect preferences,
     194        *  but will simply rewrite valid preferences) */
     195
     196        writePreferences();
     197
     198    }
     199
     200    private void fillDefaults() {
     201
     202        parameterBookmarks = GraphViewPreferenceDefaults.createDefaultAccessParameterBookmarks();
     203
     204        if (parameterBookmarks.size() > 0) {
     205            currentParameterBookmarkName = parameterBookmarks.keySet().iterator().next();
     206        } else {
     207            currentParameterBookmarkName = null;
     208        }
     209
     210        useInternalRulesets = true;
     211        rulesetFolder = GraphViewPreferenceDefaults.getDefaultRulesetFolder();
     212        currentRulesetFile = null;
     213        currentInternalRuleset = null;
     214
     215        nodeColor = Color.WHITE;
     216        segmentColor = Color.WHITE;
     217        currentColorScheme = new PreferencesColorScheme(this);
     218
     219        separateDirections = false;
     220
     221    }
     222
     223    private void writePreferences() {
     224
     225        Main.pref.put("graphview.parameterBookmarks",
     226                createAccessParameterBookmarksString(parameterBookmarks));
     227
     228        if (currentParameterBookmarkName != null) {
     229            Main.pref.put("graphview.activeBookmark", currentParameterBookmarkName);
     230        }
     231
     232        Main.pref.put("graphview.useInternalRulesets", useInternalRulesets);
     233
     234        Main.pref.put("graphview.rulesetFolder", rulesetFolder.getPath());
     235
     236        if (currentRulesetFile != null) {
     237            Main.pref.put("graphview.rulesetFile", currentRulesetFile.getPath());
     238        }
     239        if (currentInternalRuleset != null) {
     240            Main.pref.put("graphview.rulesetResource", currentInternalRuleset.toString());
     241        }
     242
     243        Main.pref.put("graphview.defaultNodeColor", createColorString(nodeColor));
     244        Main.pref.put("graphview.defaultSegmentColor", createColorString(segmentColor));
     245
     246        Main.pref.put("graphview.separateDirections", separateDirections);
     247
     248    }
     249
     250    private void readPreferences() {
     251
     252        if (Main.pref.hasKey("graphview.parameterBookmarks")) {
     253            String bookmarksString = Main.pref.get("graphview.parameterBookmarks");
     254            parameterBookmarks = parseAccessParameterBookmarksString(bookmarksString);
     255        }
     256
     257        if (Main.pref.hasKey("graphview.activeBookmark")) {
     258            currentParameterBookmarkName = Main.pref.get("graphview.activeBookmark");
     259        }
     260        if (!parameterBookmarks.containsKey(currentParameterBookmarkName)) {
     261            currentParameterBookmarkName = null;
     262        }
     263
     264
     265        useInternalRulesets = Main.pref.getBoolean("graphview.useInternalRulesets", true);
     266
     267        if (Main.pref.hasKey("graphview.rulesetFolder")) {
     268            String dirString = Main.pref.get("graphview.rulesetFolder");
     269            rulesetFolder = new File(dirString);
     270        }
     271        if (Main.pref.hasKey("graphview.rulesetFile")) {
     272            String fileString = Main.pref.get("graphview.rulesetFile");
     273            currentRulesetFile = new File(fileString);
     274        }
     275
     276        if (Main.pref.hasKey("graphview.rulesetResource")) {
     277            String rulesetString = Main.pref.get("graphview.rulesetResource");
     278            //get the enum value for the string
     279            //(InternalRuleset.valueOf cannot be used because it cannot handle invalid strings well)
     280            for (InternalRuleset ruleset : InternalRuleset.values()) {
     281                if (ruleset.toString().equals(rulesetString)) {
     282                    currentInternalRuleset = ruleset;
     283                    break;
     284                }
     285            }
     286        }
     287
     288        if (Main.pref.hasKey("graphview.defaultNodeColor")) {
     289            Color color = parseColorString(Main.pref.get("graphview.defaultNodeColor"));
     290            if (color != null) {
     291                nodeColor = color;
     292            }
     293        }
     294        if (Main.pref.hasKey("graphview.defaultSegmentColor")) {
     295            Color color = parseColorString(Main.pref.get("graphview.defaultSegmentColor"));
     296            if (color != null) {
     297                segmentColor = color;
     298            }
     299        }
     300
     301        separateDirections = Main.pref.getBoolean("graphview.separateDirections", false);
     302
     303    }
     304
     305    private static final Pattern ACCESS_PARAM_PATTERN = Pattern.compile("^([^;]*);([^;]*);types=\\{([^\\}]*)\\};properties=\\{([^\\}]*)\\}$");
     306
     307    private static final Pattern PROPERTY_MAP_ENTRY_PATTERN = Pattern.compile("^([^=]*)=(.*)$");
     308
     309    private static final Map<VehiclePropertyType<?>, String> VEHICLE_PROPERTY_TYPE_NAME_MAP =
     310        new HashMap<VehiclePropertyType<?>, String>();
     311
     312
     313    static {
     314        VEHICLE_PROPERTY_TYPE_NAME_MAP.put(AXLELOAD, "AXLELOAD");
     315        VEHICLE_PROPERTY_TYPE_NAME_MAP.put(HEIGHT, "HEIGHT");
     316        VEHICLE_PROPERTY_TYPE_NAME_MAP.put(LENGTH, "LENGTH");
     317        VEHICLE_PROPERTY_TYPE_NAME_MAP.put(MAX_INCLINE_DOWN, "MAX_INCLINE_DOWN");
     318        VEHICLE_PROPERTY_TYPE_NAME_MAP.put(MAX_INCLINE_UP, "MAX_INCLINE_UP");
     319        VEHICLE_PROPERTY_TYPE_NAME_MAP.put(MAX_TRACKTYPE, "MAX_TRACKTYPE");
     320        VEHICLE_PROPERTY_TYPE_NAME_MAP.put(SPEED, "SPEED");
     321        VEHICLE_PROPERTY_TYPE_NAME_MAP.put(SURFACE_BLACKLIST, "SURFACE_BLACKLIST");
     322        VEHICLE_PROPERTY_TYPE_NAME_MAP.put(WEIGHT, "WEIGHT");
     323        VEHICLE_PROPERTY_TYPE_NAME_MAP.put(WIDTH, "WIDTH");
     324    }
     325
     326    private static String createAccessParameterBookmarksString(
     327            Map<String, PreferenceAccessParameters> parameterBookmarks) {
     328
     329        StringBuilder stringBuilder = new StringBuilder();
     330
     331        boolean firstEntry = true;
     332
     333        for (String bookmarkName : parameterBookmarks.keySet()) {
     334
     335            if (!firstEntry) {
     336                stringBuilder.append("|");
     337            } else {
     338                firstEntry = false;
     339            }
     340
     341            stringBuilder.append(createAccessParameterBookmarkString(
     342                    bookmarkName,
     343                    parameterBookmarks.get(bookmarkName)));
     344
     345        }
     346
     347        return stringBuilder.toString();
     348    }
     349
     350    private static String createAccessParameterBookmarkString(
     351            String bookmarkName, PreferenceAccessParameters parameters) {
     352
     353        StringBuilder stringBuilder = new StringBuilder();
     354
     355        stringBuilder.append(bookmarkName).append(";");
     356
     357        stringBuilder.append(parameters.getAccessClass());
     358
     359        stringBuilder.append(";types={");
     360        for (AccessType accessType : AccessType.values()) {
     361            if (parameters.getAccessTypeUsable(accessType)) {
     362                stringBuilder.append(accessType).append(",");
     363            }
     364        }
     365
     366        if(stringBuilder.charAt(stringBuilder.length()-1) == ',') {
     367            stringBuilder.deleteCharAt(stringBuilder.length()-1);
     368        }
     369        stringBuilder.append("}");
     370
     371        stringBuilder.append(";properties={");
     372
     373        for (VehiclePropertyType<?> vehiclePropertyType : VEHICLE_PROPERTY_TYPE_NAME_MAP.keySet()) {
     374            String propertyString = parameters.getVehiclePropertyString(vehiclePropertyType);
     375            if (propertyString != null) {
     376                stringBuilder.append(VEHICLE_PROPERTY_TYPE_NAME_MAP.get(vehiclePropertyType));
     377                stringBuilder.append("=");
     378                stringBuilder.append(propertyString);
     379                stringBuilder.append(",");
     380            }
     381        }
     382
     383        if(stringBuilder.charAt(stringBuilder.length()-1) == ',') {
     384            stringBuilder.deleteCharAt(stringBuilder.length()-1);
     385        }
     386        stringBuilder.append("}");
     387
     388        assert ACCESS_PARAM_PATTERN.matcher(stringBuilder.toString()).matches();
     389
     390        return stringBuilder.toString();
     391    }
     392
     393    private static Map<String, PreferenceAccessParameters> parseAccessParameterBookmarksString(
     394            String string) {
     395
     396        Map<String, PreferenceAccessParameters> resultMap =
     397            new HashMap<String, PreferenceAccessParameters>();
     398
     399        String[] bookmarkStrings = string.split("\\|");
     400
     401        for (String bookmarkString : bookmarkStrings) {
     402            parseAccessParameterBookmarkString(bookmarkString, resultMap);
     403        }
     404
     405        return resultMap;
     406    }
     407
     408    private static void parseAccessParameterBookmarkString(String bookmarkString,
     409            Map<String, PreferenceAccessParameters> resultMap) {
     410
     411        Matcher matcher = ACCESS_PARAM_PATTERN.matcher(bookmarkString);
     412
     413        if (matcher.matches()) {
     414
     415            String bookmarkName = matcher.group(1);
     416
     417            String accessClass = matcher.group(2);
     418
     419            String[] accessTypeStrings = matcher.group(3).split(",");
     420            Collection<AccessType> accessTypes = new LinkedList<AccessType>();
     421            for (String accessTypeString : accessTypeStrings) {
     422                AccessType accessType = AccessType.valueOf(accessTypeString);
     423                if (accessType != null) {
     424                    accessTypes.add(accessType);
     425                }
     426            }
     427
     428
     429            String[] vehiclePropertyStrings = matcher.group(4).split(",");
     430            Map<VehiclePropertyType<?>, String> vehiclePropertyMap =
     431                new HashMap<VehiclePropertyType<?>, String>();
     432
     433            for (String vehiclePropertyString : vehiclePropertyStrings) {
     434
     435                Matcher entryMatcher = PROPERTY_MAP_ENTRY_PATTERN.matcher(vehiclePropertyString);
     436                if (entryMatcher.matches()) {
     437
     438                    String propertyTypeString = entryMatcher.group(1);
     439                    String propertyValueString = entryMatcher.group(2);
     440
     441                    for (VehiclePropertyType<?> propertyType :
     442                        VEHICLE_PROPERTY_TYPE_NAME_MAP.keySet()) {
     443
     444                        if (propertyTypeString.equals(
     445                                VEHICLE_PROPERTY_TYPE_NAME_MAP.get(propertyType))) {
     446
     447                            vehiclePropertyMap.put(propertyType, propertyValueString);
     448
     449                        }
     450
     451                    }
     452
     453                }
     454
     455            }
     456
     457            try {
     458
     459                PreferenceAccessParameters accessParameters =
     460                    new PreferenceAccessParameters(accessClass, accessTypes, vehiclePropertyMap);
     461
     462                resultMap.put(bookmarkName, accessParameters);
     463
     464            } catch (PropertyValueSyntaxException e) {
     465                //don't add bookmark
     466            }
     467
     468        }
     469    }
     470
     471    private static final Pattern COLOR_PATTERN =
     472        Pattern.compile("^(\\d{1,3}),\\s*(\\d{1,3}),\\s*(\\d{1,3})$");
     473    private String createColorString(Color color) {
     474        return color.getRed() + ", " + color.getGreen() + ", " + color.getBlue();
     475    }
     476
     477    private Color parseColorString(String string) {
     478        Matcher matcher = COLOR_PATTERN.matcher(string);
     479        if (!matcher.matches()) {
     480            return null;
     481        } else {
     482            int r = Integer.parseInt(matcher.group(1));
     483            int g = Integer.parseInt(matcher.group(2));
     484            int b = Integer.parseInt(matcher.group(3));
     485            return new Color(r, g, b);
     486        }
     487    }
    488488
    489489}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/plugin/preferences/InternalRuleset.java

    r16520 r23189  
    33public enum InternalRuleset {
    44
    5         DEFAULT("files/accessRuleset.xml"),
    6         GERMANY("files/accessRuleset_de.xml");
     5    DEFAULT("files/accessRuleset.xml"),
     6    GERMANY("files/accessRuleset_de.xml");
    77
    8         private String resourceName;
    9         private InternalRuleset(String resourceName) {
    10                 this.resourceName = resourceName;
    11         }
    12         public String getResourceName() {
    13                 return resourceName;
    14         }
     8    private String resourceName;
     9    private InternalRuleset(String resourceName) {
     10        this.resourceName = resourceName;
     11    }
     12    public String getResourceName() {
     13        return resourceName;
     14    }
    1515}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/plugin/preferences/PreferenceAccessParameters.java

    r16520 r23189  
    1717public class PreferenceAccessParameters implements AccessParameters {
    1818
    19         private final String accessClass;
    20         private final Map<AccessType, Boolean> accessTypeUsableMap;
    21         private final Map<VehiclePropertyType<?>, String> vehiclePropertyStrings;
    22         private final Map<VehiclePropertyType<?>, Object> vehiclePropertyValues;
     19    private final String accessClass;
     20    private final Map<AccessType, Boolean> accessTypeUsableMap;
     21    private final Map<VehiclePropertyType<?>, String> vehiclePropertyStrings;
     22    private final Map<VehiclePropertyType<?>, Object> vehiclePropertyValues;
    2323
    24         public String getAccessClass() {
    25                 return accessClass;
    26         }
     24    public String getAccessClass() {
     25        return accessClass;
     26    }
    2727
    28         public boolean getAccessTypeUsable(AccessType accessType) {
    29                 assert accessType != null;
    30                 return accessTypeUsableMap.get(accessType);
    31         }
     28    public boolean getAccessTypeUsable(AccessType accessType) {
     29        assert accessType != null;
     30        return accessTypeUsableMap.get(accessType);
     31    }
    3232
    33         public Collection<VehiclePropertyType<?>> getAvailableVehicleProperties() {
    34                 return vehiclePropertyValues.keySet();
    35         }
     33    public Collection<VehiclePropertyType<?>> getAvailableVehicleProperties() {
     34        return vehiclePropertyValues.keySet();
     35    }
    3636
    37         /**
    38         * returns the value for a vehicle property.
    39         *
    40         * @param <D>              type of property value
    41         * @param vehicleProperty  property to get value for; != null
    42         * @return                 value for vehicleProperty, null if no value is available.
    43         *                         Guaranteed to be valid according to vehicleProperty's
    44         *                         {@link VehiclePropertyType#isValidValue(Object)} method.
    45         */
    46         public <D> D getVehiclePropertyValue(VehiclePropertyType<D> vehicleProperty) {
    47                 assert vehicleProperty != null;
     37    /**
     38    * returns the value for a vehicle property.
     39    *
     40    * @param <D>              type of property value
     41    * @param vehicleProperty  property to get value for; != null
     42    * @return                 value for vehicleProperty, null if no value is available.
     43    *                         Guaranteed to be valid according to vehicleProperty's
     44    *                         {@link VehiclePropertyType#isValidValue(Object)} method.
     45    */
     46    public <D> D getVehiclePropertyValue(VehiclePropertyType<D> vehicleProperty) {
     47        assert vehicleProperty != null;
    4848
    49                 @SuppressWarnings("unchecked")
    50                 D value = (D)vehiclePropertyValues.get(vehicleProperty);
    51                 return value;
    52         }
     49        @SuppressWarnings("unchecked")
     50        D value = (D)vehiclePropertyValues.get(vehicleProperty);
     51        return value;
     52    }
    5353
    54         /**
    55         * returns the unparsed String for a vehicle property.
    56         *
    57         * @param vehicleProperty  property to get String for; != null
    58         * @return                 unparsed String, null if no value is available.
    59         */
    60         public String getVehiclePropertyString(VehiclePropertyType<?> vehicleProperty) {
    61                 assert vehicleProperty != null;
     54    /**
     55    * returns the unparsed String for a vehicle property.
     56    *
     57    * @param vehicleProperty  property to get String for; != null
     58    * @return                 unparsed String, null if no value is available.
     59    */
     60    public String getVehiclePropertyString(VehiclePropertyType<?> vehicleProperty) {
     61        assert vehicleProperty != null;
    6262
    63                 return vehiclePropertyStrings.get(vehicleProperty);
    64         }
     63        return vehiclePropertyStrings.get(vehicleProperty);
     64    }
    6565
    66         /**
    67         * @param vehiclePropertyStrings  map from vehicle properties to string representations
    68         *                                that will be parsed using {@link VehiclePropertyStringParser}
    69         *                                to get the property values; != null
    70         *
    71         * @throws VehiclePropertyStringParser.PropertyValueSyntaxException
    72         *         if a String from vehiclePropertyStrings contains a syntax error
    73         */
    74         public PreferenceAccessParameters(String accessClass,
    75                         Collection<AccessType> usableAccessTypes,
    76                         Map<VehiclePropertyType<?>, String> vehiclePropertyStrings)
    77         throws VehiclePropertyStringParser.PropertyValueSyntaxException {
     66    /**
     67    * @param vehiclePropertyStrings  map from vehicle properties to string representations
     68    *                                that will be parsed using {@link VehiclePropertyStringParser}
     69    *                                to get the property values; != null
     70    *
     71    * @throws VehiclePropertyStringParser.PropertyValueSyntaxException
     72    *         if a String from vehiclePropertyStrings contains a syntax error
     73    */
     74    public PreferenceAccessParameters(String accessClass,
     75            Collection<AccessType> usableAccessTypes,
     76            Map<VehiclePropertyType<?>, String> vehiclePropertyStrings)
     77    throws VehiclePropertyStringParser.PropertyValueSyntaxException {
    7878
    79                 this.accessClass = accessClass;
     79        this.accessClass = accessClass;
    8080
    81                 accessTypeUsableMap = new EnumMap<AccessType, Boolean>(AccessType.class);
    82                 for (AccessType accessType : AccessType.values()) {
    83                         accessTypeUsableMap.put(accessType, usableAccessTypes.contains(accessType));
    84                 }
     81        accessTypeUsableMap = new EnumMap<AccessType, Boolean>(AccessType.class);
     82        for (AccessType accessType : AccessType.values()) {
     83            accessTypeUsableMap.put(accessType, usableAccessTypes.contains(accessType));
     84        }
    8585
    86                 /* check and use vehicle properties */
     86        /* check and use vehicle properties */
    8787
    88                 this.vehiclePropertyStrings = Collections.unmodifiableMap(
    89                                 new HashMap<VehiclePropertyType<?>, String>(vehiclePropertyStrings));
     88        this.vehiclePropertyStrings = Collections.unmodifiableMap(
     89                new HashMap<VehiclePropertyType<?>, String>(vehiclePropertyStrings));
    9090
    91                 this.vehiclePropertyValues = new HashMap<VehiclePropertyType<?>, Object>();
    92                 for (VehiclePropertyType<?> vehiclePropertyType : vehiclePropertyStrings.keySet()) {
    93                         String propertyValueString = vehiclePropertyStrings.get(vehiclePropertyType);
    94                         Object propertyValue = VehiclePropertyStringParser.parsePropertyValue(
    95                                         vehiclePropertyType, propertyValueString);
    96                         this.vehiclePropertyValues.put(vehiclePropertyType, propertyValue);
    97                 }
     91        this.vehiclePropertyValues = new HashMap<VehiclePropertyType<?>, Object>();
     92        for (VehiclePropertyType<?> vehiclePropertyType : vehiclePropertyStrings.keySet()) {
     93            String propertyValueString = vehiclePropertyStrings.get(vehiclePropertyType);
     94            Object propertyValue = VehiclePropertyStringParser.parsePropertyValue(
     95                    vehiclePropertyType, propertyValueString);
     96            this.vehiclePropertyValues.put(vehiclePropertyType, propertyValue);
     97        }
    9898
    99         }
     99    }
    100100
    101101}
  • applications/editors/josm/plugins/graphview/src/org/openstreetmap/josm/plugins/graphview/plugin/preferences/VehiclePropertyStringParser.java

    r20243 r23189  
    1616public final class VehiclePropertyStringParser {
    1717
    18         /** prevents instantiation */
    19         private VehiclePropertyStringParser() { }
     18    /** prevents instantiation */
     19    private VehiclePropertyStringParser() { }
    2020
    21         /**
    22         * Exception class for syntax errors in property value Strings,
    23         * the message contains the reason using one of this utility class' public String constants.
    24         */
    25         public static class PropertyValueSyntaxException extends Exception {
    26                 private static final long serialVersionUID = 1L;
    27                 public PropertyValueSyntaxException(String message) {
    28                         super(message);
    29                 }
    30         }
     21    /**
     22    * Exception class for syntax errors in property value Strings,
     23    * the message contains the reason using one of this utility class' public String constants.
     24    */
     25    public static class PropertyValueSyntaxException extends Exception {
     26        private static final long serialVersionUID = 1L;
     27        public PropertyValueSyntaxException(String message) {
     28            super(message);
     29        }
     30    }
    3131
    32         public static final String ERROR_WEIGHT =
    33                 "Weights must be given as positive decimal numbers with unit \"t\" or without unit.";
    34         public static final String ERROR_LENGTH =
    35                 "Lengths must be given as positive decimal numbers with unit \"m\", \"km\", \"mi\"" +
    36                 " or without unit.\nAlternatively, the format FEET' INCHES\" can be used.";
    37         public static final String ERROR_SPEED =
    38                 "Speeds should be given as numbers without unit or "
    39                 + "as numbers followed by \"mph\".";
    40         public static final String ERROR_INCLINE =
    41                 "Inclines must be given as positive decimal numbers with followed by \"%\".";
    42         public static final String ERROR_TRACKTYPE =
    43                 "Tracktype grades must be given as integers between 0 and 5.";
    44         public static final String ERROR_SURFACE =
    45                 "Surface values must not contain any of the following characters: ',' '{' '}' '=' '|";
     32    public static final String ERROR_WEIGHT =
     33        "Weights must be given as positive decimal numbers with unit \"t\" or without unit.";
     34    public static final String ERROR_LENGTH =
     35        "Lengths must be given as positive decimal numbers with unit \"m\", \"km\", \"mi\"" +
     36        " or without unit.\nAlternatively, the format FEET' INCHES\" can be used.";
     37    public static final String ERROR_SPEED =
     38        "Speeds should be given as numbers without unit or "
     39        + "as numbers followed by \"mph\".";
     40    public static final String ERROR_INCLINE =
     41        "Inclines must be given as positive decimal numbers with followed by \"%\".";
     42    public static final String ERROR_TRACKTYPE =
     43        "Tracktype grades must be given as integers between 0 and 5.";
     44    public static final String ERROR_SURFACE =
     45        "Surface values must not contain any of the following characters: ',' '{' '}' '=' '|";
    4646
    47         private static final List<Character> FORBIDDEN_SURFACE_CHARS =
    48                 Arrays.asList(',', '{', '}', '=', '|');
     47    private static final List<Character> FORBIDDEN_SURFACE_CHARS =
     48        Arrays.asList(',', '{', '}', '=', '|');
    4949
    50         /**
    51         * returns the value represented by the propertyValueString
    52         *
    53         * @throws PropertyValueSyntaxException  if the string has syntax errors that prevent parsing
    54         * @throws InvalidParameterException     if an unknown property type was passed
    55         *
    56         * @param propertyType         type of the property; != null
    57         * @param propertyValueString  string to parse; != null
    58         * @return                     property value; != null.
    59         *                             Guaranteed to be valid according to propertyType's
    60         *                             {@link VehiclePropertyType#isValidValue(Object)} method.
    61         */
    62         public static final <V> V parsePropertyValue(
    63                         VehiclePropertyType<V> propertyType, String propertyValueString)
    64         throws PropertyValueSyntaxException {
     50    /**
     51    * returns the value represented by the propertyValueString
     52    *
     53    * @throws PropertyValueSyntaxException  if the string has syntax errors that prevent parsing
     54    * @throws InvalidParameterException     if an unknown property type was passed
     55    *
     56    * @param propertyType         type of the property; != null
     57    * @param propertyValueString  string to parse; != null
     58    * @return                     property value; != null.
     59    *                             Guaranteed to be valid according to propertyType's
     60    *                             {@link VehiclePropertyType#isValidValue(Object)} method.
     61    */
     62    public static final <V> V parsePropertyValue(
     63            VehiclePropertyType<V> propertyType, String propertyValueString)
     64    throws PropertyValueSyntaxException {
    6565
    66                 assert propertyType != null && propertyValueString != null;
     66        assert propertyType != null && propertyValueString != null;
    6767
    68                 if (propertyType == VehiclePropertyTypes.AXLELOAD
    69                                 || propertyType == VehiclePropertyTypes.WEIGHT) {
     68        if (propertyType == VehiclePropertyTypes.AXLELOAD
     69                || propertyType == VehiclePropertyTypes.WEIGHT) {
    7070
    71                         Float value = ValueStringParser.parseWeight(propertyValueString);
    72                         if (value != null && propertyType.isValidValue(value)) {
    73                                 @SuppressWarnings("unchecked") //V must be float because of propertyType condition
    74                                 V result = (V)value;
    75                                 return result;
    76                         } else {
    77                                 throw new PropertyValueSyntaxException(ERROR_WEIGHT);
    78                         }
     71            Float value = ValueStringParser.parseWeight(propertyValueString);
     72            if (value != null && propertyType.isValidValue(value)) {
     73                @SuppressWarnings("unchecked") //V must be float because of propertyType condition
     74                V result = (V)value;
     75                return result;
     76            } else {
     77                throw new PropertyValueSyntaxException(ERROR_WEIGHT);
     78            }
    7979
    80                 } else if (propertyType == VehiclePropertyTypes.HEIGHT
    81                                 || propertyType == VehiclePropertyTypes.LENGTH
    82                                 || propertyType == VehiclePropertyTypes.WIDTH) {
     80        } else if (propertyType == VehiclePropertyTypes.HEIGHT
     81                || propertyType == VehiclePropertyTypes.LENGTH
     82                || propertyType == VehiclePropertyTypes.WIDTH) {
    8383
    84                         Float value = ValueStringParser.parseMeasure(propertyValueString);
    85                         if (value != null && propertyType.isValidValue(value)) {
    86                                 @SuppressWarnings("unchecked") //V must be float because of propertyType condition
    87                                 V result = (V)value;
    88                                 return result;
    89                         } else {
    90                                 throw new PropertyValueSyntaxException(ERROR_LENGTH);
    91                         }
     84            Float value = ValueStringParser.parseMeasure(propertyValueString);
     85            if (value != null && propertyType.isValidValue(value)) {
     86                @SuppressWarnings("unchecked") //V must be float because of propertyType condition
     87                V result = (V)value;
     88                return result;
     89            } else {
     90                throw new PropertyValueSyntaxException(ERROR_LENGTH);
     91            }
    9292
    93                 } else if (propertyType == VehiclePropertyTypes.SPEED) {
     93        } else if (propertyType == VehiclePropertyTypes.SPEED) {
    9494
    95                         Float value = ValueStringParser.parseSpeed(propertyValueString);
    96                         if (value != null && propertyType.isValidValue(value)) {
    97                                 @SuppressWarnings("unchecked") //V must be float because of propertyType condition
    98                                 V result = (V)value;
    99                                 return result;
    100                         } else {
    101                                 throw new PropertyValueSyntaxException(ERROR_SPEED);
    102                         }
     95            Float value = ValueStringParser.parseSpeed(propertyValueString);
     96            if (value != null && propertyType.isValidValue(value)) {
     97                @SuppressWarnings("unchecked") //V must be float because of propertyType condition
     98                V result = (V)value;
     99                return result;
     100            } else {
     101                throw new PropertyValueSyntaxException(ERROR_SPEED);
     102            }
    103103
    104                 } else if (propertyType == VehiclePropertyTypes.MAX_INCLINE_DOWN
    105                                 || propertyType == VehiclePropertyTypes.MAX_INCLINE_UP) {
     104        } else if (propertyType == VehiclePropertyTypes.MAX_INCLINE_DOWN
     105                || propertyType == VehiclePropertyTypes.MAX_INCLINE_UP) {
    106106
    107                         Float value = ValueStringParser.parseIncline(propertyValueString);
    108                         if (value != null && propertyType.isValidValue(value)) {
    109                                 @SuppressWarnings("unchecked") //V must be float because of propertyType condition
    110                                 V result = (V)value;
    111                                 return result;
    112                         } else {
    113                                 throw new PropertyValueSyntaxException(ERROR_INCLINE);
    114                         }
     107            Float value = ValueStringParser.parseIncline(propertyValueString);
     108            if (value != null && propertyType.isValidValue(value)) {
     109                @SuppressWarnings("unchecked") //V must be float because of propertyType condition
     110                V result = (V)value;
     111                return result;
     112            } else {
     113                throw new PropertyValueSyntaxException(ERROR_INCLINE);
     114            }
    115115
    116                 } else if (propertyType == VehiclePropertyTypes.MAX_TRACKTYPE) {
     116        } else if (propertyType == VehiclePropertyTypes.MAX_TRACKTYPE) {
    117117
    118                         try {
    119                                 int value = Integer.parseInt(propertyValueString);
    120                                 if (0 <= value && value <= 5) {
    121                                         @SuppressWarnings("unchecked") //V must be int because of propertyType condition
    122                                         V result = (V)(Integer)value;
    123                                         return result;
    124                                 }
    125                         } catch (NumberFormatException e) {}
     118            try {
     119                int value = Integer.parseInt(propertyValueString);
     120                if (0 <= value && value <= 5) {
     121                    @SuppressWarnings("unchecked") //V must be int because of propertyType condition
     122                    V result = (V)(Integer)value;
     123                    return result;
     124                }
     125            } catch (NumberFormatException e) {}
    126126
    127                         throw new PropertyValueSyntaxException(ERROR_TRACKTYPE);
     127            throw new PropertyValueSyntaxException(ERROR_TRACKTYPE);
    128128
    129                 } else if (propertyType == VehiclePropertyTypes.SURFACE_BLACKLIST) {
     129        } else if (propertyType == VehiclePropertyTypes.SURFACE_BLACKLIST) {
    130130
    131                         String[] surfaces = propertyValueString.split(";\\s*");
    132                         Collection<String> surfaceBlacklist = new ArrayList<String>(surfaces.length);
    133                         for (String surface : surfaces) {
    134                                 for (char nameChar : surface.toCharArray()) {
    135                                         if (FORBIDDEN_SURFACE_CHARS.contains(nameChar)) {
    136                                                 throw new PropertyValueSyntaxException(ERROR_SURFACE);
    137                                         }
    138                                 }
    139                                 surfaceBlacklist.add(surface);
    140                         }
     131            String[] surfaces = propertyValueString.split(";\\s*");
     132            Collection<String> surfaceBlacklist = new ArrayList<String>(surfaces.length);
     133            for (String surface : surfaces) {
     134                for (char nameChar : surface.toCharArray()) {
     135                    if (FORBIDDEN_SURFACE_CHARS.contains(nameChar)) {
     136                        throw new PropertyValueSyntaxException(ERROR_SURFACE);
     137                    }
     138                }
     139                surfaceBlacklist.add(surface);
     140            }
    141141
    142                         @SuppressWarnings("unchecked") //V must be Collection because of propertyType condition
    143                         V result = (V)surfaceBlacklist;
    144                         return result;
     142            @SuppressWarnings("unchecked") //V must be Collection because of propertyType condition
     143            V result = (V)surfaceBlacklist;
     144            return result;
    145145
    146                 } else {
    147                         throw new InvalidParameterException("unknown property type: " + propertyType);
    148                 }
     146        } else {
     147            throw new InvalidParameterException("unknown property type: " + propertyType);
     148        }
    149149
    150         }
     150    }
    151151
    152152}
  • applications/editors/josm/plugins/graphview/test/org/openstreetmap/josm/plugins/graphview/core/FullGraphCreationTest.java

    r19216 r23189  
    3232public class FullGraphCreationTest {
    3333
    34         private static final AccessParameters ACCESS_PARAMS;
    35         static {
    36                 Map<VehiclePropertyType<?>, String> vehiclePropertyValues =
    37                         new HashMap<VehiclePropertyType<?>, String>();
    38                 vehiclePropertyValues.put(VehiclePropertyTypes.WIDTH, "3.0");
     34    private static final AccessParameters ACCESS_PARAMS;
     35    static {
     36        Map<VehiclePropertyType<?>, String> vehiclePropertyValues =
     37            new HashMap<VehiclePropertyType<?>, String>();
     38        vehiclePropertyValues.put(VehiclePropertyTypes.WIDTH, "3.0");
    3939
    40                 try {
    41                         ACCESS_PARAMS = new PreferenceAccessParameters(
    42                                         "test_vehicle",
    43                                         Arrays.asList(AccessType.UNDEFINED),
    44                                         vehiclePropertyValues);
    45                 } catch (PropertyValueSyntaxException e) {
    46                         throw new Error(e);
    47                 }
    48         }
     40        try {
     41            ACCESS_PARAMS = new PreferenceAccessParameters(
     42                    "test_vehicle",
     43                    Arrays.asList(AccessType.UNDEFINED),
     44                    vehiclePropertyValues);
     45        } catch (PropertyValueSyntaxException e) {
     46            throw new Error(e);
     47        }
     48    }
    4949
    50         private static final AccessRuleset TEST_RULESET = new AccessRuleset() {
    51                 public java.util.List<String> getAccessHierarchyAncestors(String transportMode) {
    52                         return Arrays.asList(transportMode);
    53                 }
    54                 public java.util.Collection<Tag> getBaseTags() {
    55                         return Arrays.asList(new Tag("highway", "test"));
    56                 }
    57                 public java.util.List<Implication> getImplications() {
    58                         return new LinkedList<Implication>();
    59                 }
    60         };
     50    private static final AccessRuleset TEST_RULESET = new AccessRuleset() {
     51        public java.util.List<String> getAccessHierarchyAncestors(String transportMode) {
     52            return Arrays.asList(transportMode);
     53        }
     54        public java.util.Collection<Tag> getBaseTags() {
     55            return Arrays.asList(new Tag("highway", "test"));
     56        }
     57        public java.util.List<Implication> getImplications() {
     58            return new LinkedList<Implication>();
     59        }
     60    };
    6161
    62         @Test
    63         public void testTJunction() {
     62    @Test
     63    public void testTJunction() {
    6464
    65                 TestDataSource ds = new TestDataSource();
     65        TestDataSource ds = new TestDataSource();
    6666
    67                 TestNode nodeN = new TestNode(2, 1);
    68                 TestNode nodeW = new TestNode(1, 0);
    69                 TestNode nodeS = new TestNode(0, 1);
    70                 TestNode nodeC = new TestNode(1, 1);
     67        TestNode nodeN = new TestNode(2, 1);
     68        TestNode nodeW = new TestNode(1, 0);
     69        TestNode nodeS = new TestNode(0, 1);
     70        TestNode nodeC = new TestNode(1, 1);
    7171
    72                 ds.nodes.addAll(Arrays.asList(nodeN, nodeW, nodeS, nodeC));
     72        ds.nodes.addAll(Arrays.asList(nodeN, nodeW, nodeS, nodeC));
    7373
    74                 TestWay wayNC = new TestWay();
    75                 wayNC.tags.put("highway", "test");
    76                 wayNC.nodes.addAll(Arrays.asList(nodeN, nodeC));
    77                 TestWay wayCS = new TestWay();
    78                 wayCS.tags.put("highway", "test");
    79                 wayCS.nodes.addAll(Arrays.asList(nodeC, nodeS));
    80                 TestWay wayCW = new TestWay();
    81                 wayCW.tags.put("highway", "test");
    82                 wayCW.nodes.addAll(Arrays.asList(nodeC, nodeW));
     74        TestWay wayNC = new TestWay();
     75        wayNC.tags.put("highway", "test");
     76        wayNC.nodes.addAll(Arrays.asList(nodeN, nodeC));
     77        TestWay wayCS = new TestWay();
     78        wayCS.tags.put("highway", "test");
     79        wayCS.nodes.addAll(Arrays.asList(nodeC, nodeS));
     80        TestWay wayCW = new TestWay();
     81        wayCW.tags.put("highway", "test");
     82        wayCW.nodes.addAll(Arrays.asList(nodeC, nodeW));
    8383
    84                 ds.ways.add(wayNC);
    85                 ds.ways.add(wayCS);
    86                 ds.ways.add(wayCW);
     84        ds.ways.add(wayNC);
     85        ds.ways.add(wayCS);
     86        ds.ways.add(wayCW);
    8787
    88                 /* variant 1: no restrictions */
    89                 {
    90                         TransitionStructure ts1 = createTestTransitionStructure(ds);
     88        /* variant 1: no restrictions */
     89        {
     90            TransitionStructure ts1 = createTestTransitionStructure(ds);
    9191
    92                         assertSame(4, size(ts1.getNodes()));
    93                         assertSame(6, size(ts1.getSegments()));
    94                         assertSame(0, size(ts1.getRestrictions()));
     92            assertSame(4, size(ts1.getNodes()));
     93            assertSame(6, size(ts1.getSegments()));
     94            assertSame(0, size(ts1.getRestrictions()));
    9595
    96                         WayGraph graph1 = new TSBasedWayGraph(ts1);
     96            WayGraph graph1 = new TSBasedWayGraph(ts1);
    9797
    98                         assertSame(12, graph1.getNodes().size());
    99                         assertSame(24, graph1.getEdges().size());
    100                 }
    101                 /* variant 2: no left turn from S to W */
    102                 {
    103                         ds.relations.add(createTurnRestrictionRelation(wayCS, nodeC, wayCW, "no_left_turn"));
    104                         TransitionStructure ts2 = createTestTransitionStructure(ds);
     98            assertSame(12, graph1.getNodes().size());
     99            assertSame(24, graph1.getEdges().size());
     100        }
     101        /* variant 2: no left turn from S to W */
     102        {
     103            ds.relations.add(createTurnRestrictionRelation(wayCS, nodeC, wayCW, "no_left_turn"));
     104            TransitionStructure ts2 = createTestTransitionStructure(ds);
    105105
    106                         assertSame(4, size(ts2.getNodes()));
    107                         assertSame(6, size(ts2.getSegments()));
    108                         assertSame(1, size(ts2.getRestrictions()));
     106            assertSame(4, size(ts2.getNodes()));
     107            assertSame(6, size(ts2.getSegments()));
     108            assertSame(1, size(ts2.getRestrictions()));
    109109
    110                         WayGraph graph2 = new TSBasedWayGraph(ts2);
     110            WayGraph graph2 = new TSBasedWayGraph(ts2);
    111111
    112                         assertSame(12, graph2.getNodes().size());
    113                         assertSame(23, graph2.getEdges().size());
    114                 }
     112            assertSame(12, graph2.getNodes().size());
     113            assertSame(23, graph2.getEdges().size());
     114        }
    115115
    116         }
     116    }
    117117
    118         @Test
    119         public void testBarrier() {
     118    @Test
     119    public void testBarrier() {
    120120
    121                 TestDataSource ds = new TestDataSource();
     121        TestDataSource ds = new TestDataSource();
    122122
    123                 TestNode node1 = new TestNode(0, 1);
    124                 TestNode nodeB = new TestNode(0, 2);
    125                 nodeB.tags.put("width", "1");
    126                 TestNode node2 = new TestNode(0, 3);
     123        TestNode node1 = new TestNode(0, 1);
     124        TestNode nodeB = new TestNode(0, 2);
     125        nodeB.tags.put("width", "1");
     126        TestNode node2 = new TestNode(0, 3);
    127127
    128                 ds.nodes.addAll(Arrays.asList(node1, nodeB, node2));
     128        ds.nodes.addAll(Arrays.asList(node1, nodeB, node2));
    129129
    130                 TestWay way = new TestWay();
    131                 way.tags.put("highway", "test");
    132                 way.tags.put("oneway", "yes");
    133                 way.nodes.addAll(Arrays.asList(node1, nodeB, node2));
    134                 ds.ways.add(way);
     130        TestWay way = new TestWay();
     131        way.tags.put("highway", "test");
     132        way.tags.put("oneway", "yes");
     133        way.nodes.addAll(Arrays.asList(node1, nodeB, node2));
     134        ds.ways.add(way);
    135135
    136                 /* variant 1: no restrictions */
     136        /* variant 1: no restrictions */
    137137
    138                 TransitionStructure ts = createTestTransitionStructure(ds);
     138        TransitionStructure ts = createTestTransitionStructure(ds);
    139139
    140                 assertSame(3, size(ts.getNodes()));
    141                 assertSame(2, size(ts.getSegments()));
    142                 assertSame(1, size(ts.getRestrictions()));
     140        assertSame(3, size(ts.getNodes()));
     141        assertSame(2, size(ts.getSegments()));
     142        assertSame(1, size(ts.getRestrictions()));
    143143
    144                 WayGraph graph = new TSBasedWayGraph(ts);
     144        WayGraph graph = new TSBasedWayGraph(ts);
    145145
    146                 assertSame(4, graph.getNodes().size());
    147                 assertSame(2, graph.getEdges().size());
     146        assertSame(4, graph.getNodes().size());
     147        assertSame(2, graph.getEdges().size());
    148148
    149         }
     149    }
    150150
    151         private TestRelation createTurnRestrictionRelation(
    152                         TestWay from, TestNode via, TestWay to, String restriction) {
    153                 TestRelation resultRelation = new TestRelation();
    154                 resultRelation.tags.put("type", "restriction");
    155                 resultRelation.tags.put("restriction", restriction);
    156                 resultRelation.members.add(new TestRelationMember("from", from));
    157                 resultRelation.members.add(new TestRelationMember("via", via));
    158                 resultRelation.members.add(new TestRelationMember("to", to));
    159                 return resultRelation;
    160         }
     151    private TestRelation createTurnRestrictionRelation(
     152            TestWay from, TestNode via, TestWay to, String restriction) {
     153        TestRelation resultRelation = new TestRelation();
     154        resultRelation.tags.put("type", "restriction");
     155        resultRelation.tags.put("restriction", restriction);
     156        resultRelation.members.add(new TestRelationMember("from", from));
     157        resultRelation.members.add(new TestRelationMember("via", via));
     158        resultRelation.members.add(new TestRelationMember("to", to));
     159        return resultRelation;
     160    }
    161161
    162         private TransitionStructure createTestTransitionStructure(TestDataSource dataSource) {
     162    private TransitionStructure createTestTransitionStructure(TestDataSource dataSource) {
    163163
    164                 LinkedList<RoadPropertyType<?>> properties = new LinkedList<RoadPropertyType<?>>();
    165                 properties.add(new RoadWidth());
     164        LinkedList<RoadPropertyType<?>> properties = new LinkedList<RoadPropertyType<?>>();
     165        properties.add(new RoadWidth());
    166166
    167                 return new GenericTransitionStructure<TestNode, TestWay, TestRelation, TestRelationMember>(
    168                                 ACCESS_PARAMS, TEST_RULESET, dataSource, properties);
    169         }
     167        return new GenericTransitionStructure<TestNode, TestWay, TestRelation, TestRelationMember>(
     168                ACCESS_PARAMS, TEST_RULESET, dataSource, properties);
     169    }
    170170
    171         private static int size(Iterable<?> iterable) {
    172                 Iterator<?> iterator = iterable.iterator();
    173                 int size = 0;
    174                 while (iterator.hasNext()) {
    175                         iterator.next();
    176                         size ++;
    177                 }
    178                 return size;
    179         }
     171    private static int size(Iterable<?> iterable) {
     172        Iterator<?> iterator = iterable.iterator();
     173        int size = 0;
     174        while (iterator.hasNext()) {
     175            iterator.next();
     176            size ++;
     177        }
     178        return size;
     179    }
    180180
    181181}
  • applications/editors/josm/plugins/graphview/test/org/openstreetmap/josm/plugins/graphview/core/TestDataSource.java

    r19216 r23189  
    1414public class TestDataSource implements DataSource<TestDataSource.TestNode, TestDataSource.TestWay, TestDataSource.TestRelation, TestDataSource.TestRelationMember> {
    1515
    16         public static class TestPrimitive {
    17                 public final Map<String, String> tags = new HashMap<String, String>();
    18         };
     16    public static class TestPrimitive {
     17        public final Map<String, String> tags = new HashMap<String, String>();
     18    };
    1919
    20         public static class TestNode extends TestPrimitive {
    21                 public final double lat;
    22                 public final double lon;
    23                 public TestNode() {
    24                         this(0, 0);
    25                 }
    26                 public TestNode(double lat, double lon) {
    27                         this.lat = lat;
    28                         this.lon = lon;
    29                 }
    30                 @Override
    31                 public String toString() {
    32                         return "(" + lat + ", " + lon + "); " + tags;
    33                 }
    34         }
     20    public static class TestNode extends TestPrimitive {
     21        public final double lat;
     22        public final double lon;
     23        public TestNode() {
     24            this(0, 0);
     25        }
     26        public TestNode(double lat, double lon) {
     27            this.lat = lat;
     28            this.lon = lon;
     29        }
     30        @Override
     31        public String toString() {
     32            return "(" + lat + ", " + lon + "); " + tags;
     33        }
     34    }
    3535
    36         public static class TestWay extends TestPrimitive {
    37                 public final List<TestNode> nodes = new LinkedList<TestNode>();
    38                 @Override
    39                 public String toString() {
    40                         return nodes + "; " + tags;
    41                 }
    42         }
     36    public static class TestWay extends TestPrimitive {
     37        public final List<TestNode> nodes = new LinkedList<TestNode>();
     38        @Override
     39        public String toString() {
     40            return nodes + "; " + tags;
     41        }
     42    }
    4343
    44         public static class TestRelation extends TestPrimitive {
    45                 public final Collection<TestRelationMember> members = new LinkedList<TestRelationMember>();
    46                 @Override
    47                 public String toString() {
    48                         return members + "; " + tags;
    49                 }
    50         }
     44    public static class TestRelation extends TestPrimitive {
     45        public final Collection<TestRelationMember> members = new LinkedList<TestRelationMember>();
     46        @Override
     47        public String toString() {
     48            return members + "; " + tags;
     49        }
     50    }
    5151
    52         public static class TestRelationMember {
    53                 public final String role;
    54                 public final TestPrimitive member;
    55                 public TestRelationMember(String role, TestPrimitive member) {
    56                         this.role = role;
    57                         this.member = member;
    58                 }
    59                 public TestPrimitive getMember() {
    60                         return member;
    61                 }
    62                 public String getRole() {
    63                         return role;
    64                 }
    65                 @Override
    66                 public String toString() {
    67                         return role + "=" + member;
    68                 }
    69         }
     52    public static class TestRelationMember {
     53        public final String role;
     54        public final TestPrimitive member;
     55        public TestRelationMember(String role, TestPrimitive member) {
     56            this.role = role;
     57            this.member = member;
     58        }
     59        public TestPrimitive getMember() {
     60            return member;
     61        }
     62        public String getRole() {
     63            return role;
     64        }
     65        @Override
     66        public String toString() {
     67            return role + "=" + member;
     68        }
     69    }
    7070
    7171
    72         public final Collection<TestNode> nodes = new LinkedList<TestNode>();
    73         public final Collection<TestWay> ways = new LinkedList<TestWay>();
    74         public final Collection<TestRelation> relations = new LinkedList<TestRelation>();
     72    public final Collection<TestNode> nodes = new LinkedList<TestNode>();
     73    public final Collection<TestWay> ways = new LinkedList<TestWay>();
     74    public final Collection<TestRelation> relations = new LinkedList<TestRelation>();
    7575
    7676
    77         public double getLat(TestNode node) {
    78                 return node.lat;
    79         }
    80         public double getLon(TestNode node) {
    81                 return node.lon;
    82         }
     77    public double getLat(TestNode node) {
     78        return node.lat;
     79    }
     80    public double getLon(TestNode node) {
     81        return node.lon;
     82    }
    8383
    84         public Iterable<TestRelationMember> getMembers(TestRelation relation) {
    85                 return relation.members;
    86         }
     84    public Iterable<TestRelationMember> getMembers(TestRelation relation) {
     85        return relation.members;
     86    }
    8787
    88         public Iterable<TestNode> getNodes() {
    89                 return nodes;
    90         }
     88    public Iterable<TestNode> getNodes() {
     89        return nodes;
     90    }
    9191
    92         public Iterable<TestNode> getNodes(TestWay way) {
    93                 return way.nodes;
    94         }
     92    public Iterable<TestNode> getNodes(TestWay way) {
     93        return way.nodes;
     94    }
    9595
    96         public Iterable<TestWay> getWays() {
    97                 return ways;
    98         }
     96    public Iterable<TestWay> getWays() {
     97        return ways;
     98    }
    9999
    100         public Iterable<TestRelation> getRelations() {
    101                 return relations;
    102         }
     100    public Iterable<TestRelation> getRelations() {
     101        return relations;
     102    }
    103103
    104         public TagGroup getTagsN(TestNode node) {
    105                 return new MapBasedTagGroup(node.tags);
    106         }
     104    public TagGroup getTagsN(TestNode node) {
     105        return new MapBasedTagGroup(node.tags);
     106    }
    107107
    108         public TagGroup getTagsW(TestWay way) {
    109                 return new MapBasedTagGroup(way.tags);
    110         }
     108    public TagGroup getTagsW(TestWay way) {
     109        return new MapBasedTagGroup(way.tags);
     110    }
    111111
    112         public TagGroup getTagsR(TestRelation relation) {
    113                 return new MapBasedTagGroup(relation.tags);
    114         }
    115        
    116         public Object getMember(TestRelationMember member) {
    117                 return member.getMember();
    118         }
    119        
    120         public String getRole(TestRelationMember member) {
    121                 return member.getRole();
    122         }
    123        
    124         public boolean isNMember(TestRelationMember member) {
    125                 return member.getMember() instanceof TestNode;
    126         }
    127        
    128         public boolean isWMember(TestRelationMember member) {
    129                 return member.getMember() instanceof TestWay;
    130         }
    131        
    132         public boolean isRMember(TestRelationMember member) {
    133                 return member.getMember() instanceof TestRelation;
    134         }
     112    public TagGroup getTagsR(TestRelation relation) {
     113        return new MapBasedTagGroup(relation.tags);
     114    }
    135115
    136         public void addObserver(DataSourceObserver observer) {
    137                 // not needed for test
    138         }
     116    public Object getMember(TestRelationMember member) {
     117        return member.getMember();
     118    }
    139119
    140         public void deleteObserver(DataSourceObserver observer) {
    141                 // not needed for test
    142         }
     120    public String getRole(TestRelationMember member) {
     121        return member.getRole();
     122    }
     123
     124    public boolean isNMember(TestRelationMember member) {
     125        return member.getMember() instanceof TestNode;
     126    }
     127
     128    public boolean isWMember(TestRelationMember member) {
     129        return member.getMember() instanceof TestWay;
     130    }
     131
     132    public boolean isRMember(TestRelationMember member) {
     133        return member.getMember() instanceof TestRelation;
     134    }
     135
     136    public void addObserver(DataSourceObserver observer) {
     137        // not needed for test
     138    }
     139
     140    public void deleteObserver(DataSourceObserver observer) {
     141        // not needed for test
     142    }
    143143
    144144}
  • applications/editors/josm/plugins/graphview/test/org/openstreetmap/josm/plugins/graphview/core/access/AccessRulesetReaderTest.java

    r16520 r23189  
    2222public class AccessRulesetReaderTest {
    2323
    24         @Test
    25         public void testReadAccessRuleset_valid_classes() throws IOException {
     24    @Test
     25    public void testReadAccessRuleset_valid_classes() throws IOException {
    2626
    27                 InputStream is = new FileInputStream("plugins/graphview/test/files/accessRuleset_valid.xml");
    28                 AccessRuleset ruleset = AccessRulesetReader.readAccessRuleset(is);
    29                 assertNotNull(ruleset);
     27        InputStream is = new FileInputStream("plugins/graphview/test/files/accessRuleset_valid.xml");
     28        AccessRuleset ruleset = AccessRulesetReader.readAccessRuleset(is);
     29        assertNotNull(ruleset);
    3030
    3131
    32                 assertEquals("vehicle", ruleset.getAccessHierarchyAncestors("vehicle").get(0));
     32        assertEquals("vehicle", ruleset.getAccessHierarchyAncestors("vehicle").get(0));
    3333
    34                 assertEquals("motor_vehicle", ruleset.getAccessHierarchyAncestors("motor_vehicle").get(0));
    35                 assertEquals("vehicle", ruleset.getAccessHierarchyAncestors("motor_vehicle").get(1));
     34        assertEquals("motor_vehicle", ruleset.getAccessHierarchyAncestors("motor_vehicle").get(0));
     35        assertEquals("vehicle", ruleset.getAccessHierarchyAncestors("motor_vehicle").get(1));
    3636
    37                 assertEquals("bus", ruleset.getAccessHierarchyAncestors("bus").get(0));
    38                 assertEquals("motor_vehicle", ruleset.getAccessHierarchyAncestors("bus").get(1));
    39                 assertEquals("vehicle", ruleset.getAccessHierarchyAncestors("bus").get(2));
     37        assertEquals("bus", ruleset.getAccessHierarchyAncestors("bus").get(0));
     38        assertEquals("motor_vehicle", ruleset.getAccessHierarchyAncestors("bus").get(1));
     39        assertEquals("vehicle", ruleset.getAccessHierarchyAncestors("bus").get(2));
    4040
    41                 assertEquals("bicycle", ruleset.getAccessHierarchyAncestors("bicycle").get(0));
    42                 assertEquals("vehicle", ruleset.getAccessHierarchyAncestors("bicycle").get(1));
     41        assertEquals("bicycle", ruleset.getAccessHierarchyAncestors("bicycle").get(0));
     42        assertEquals("vehicle", ruleset.getAccessHierarchyAncestors("bicycle").get(1));
    4343
    44                 assertFalse(ruleset.getAccessHierarchyAncestors("bus").contains("bicycle"));
     44        assertFalse(ruleset.getAccessHierarchyAncestors("bus").contains("bicycle"));
    4545
    46                 assertSame(ruleset.getAccessHierarchyAncestors("boat").size(), 0);
     46        assertSame(ruleset.getAccessHierarchyAncestors("boat").size(), 0);
    4747
    48         }
     48    }
    4949
    50         @Test
    51         public void testReadAccessRuleset_valid_basetags() throws IOException {
     50    @Test
     51    public void testReadAccessRuleset_valid_basetags() throws IOException {
    5252
    53                 InputStream is = new FileInputStream("plugins/graphview/test/files/accessRuleset_valid.xml");
    54                 AccessRuleset ruleset = AccessRulesetReader.readAccessRuleset(is);
    55                 assertNotNull(ruleset);
     53        InputStream is = new FileInputStream("plugins/graphview/test/files/accessRuleset_valid.xml");
     54        AccessRuleset ruleset = AccessRulesetReader.readAccessRuleset(is);
     55        assertNotNull(ruleset);
    5656
    57                 assertSame(2, ruleset.getBaseTags().size());
     57        assertSame(2, ruleset.getBaseTags().size());
    5858
    59                 assertTrue(ruleset.getBaseTags().contains(new Tag("highway", "residential")));
    60                 assertTrue(ruleset.getBaseTags().contains(new Tag("highway", "cycleway")));
    61                 assertFalse(ruleset.getBaseTags().contains(new Tag("building", "residential")));
    62                 assertFalse(ruleset.getBaseTags().contains(new Tag("highway", "stop")));
     59        assertTrue(ruleset.getBaseTags().contains(new Tag("highway", "residential")));
     60        assertTrue(ruleset.getBaseTags().contains(new Tag("highway", "cycleway")));
     61        assertFalse(ruleset.getBaseTags().contains(new Tag("building", "residential")));
     62        assertFalse(ruleset.getBaseTags().contains(new Tag("highway", "stop")));
    6363
    64         }
     64    }
    6565
    66         @Test
    67         public void testReadAccessRuleset_valid_implications() throws IOException {
     66    @Test
     67    public void testReadAccessRuleset_valid_implications() throws IOException {
    6868
    69                 InputStream is = new FileInputStream("plugins/graphview/test/files/accessRuleset_valid.xml");
    70                 AccessRuleset ruleset = AccessRulesetReader.readAccessRuleset(is);
    71                 assertNotNull(ruleset);
     69        InputStream is = new FileInputStream("plugins/graphview/test/files/accessRuleset_valid.xml");
     70        AccessRuleset ruleset = AccessRulesetReader.readAccessRuleset(is);
     71        assertNotNull(ruleset);
    7272
    73                 List<Implication> implications = ruleset.getImplications();
     73        List<Implication> implications = ruleset.getImplications();
    7474
    75                 assertSame(3, implications.size());
     75        assertSame(3, implications.size());
    7676
    77                 TagGroup[] tagGroups = new TagGroup[4];
    78                 tagGroups[0] = createTagGroup(new Tag("highway", "cycleway"));
    79                 tagGroups[1] = createTagGroup(new Tag("highway", "steps"));
    80                 tagGroups[2] = createTagGroup(new Tag("highway", "steps"), new Tag("escalator", "yes"));
    81                 tagGroups[3] = createTagGroup(new Tag("disused", "yes"), new Tag("construction", "no"));
     77        TagGroup[] tagGroups = new TagGroup[4];
     78        tagGroups[0] = createTagGroup(new Tag("highway", "cycleway"));
     79        tagGroups[1] = createTagGroup(new Tag("highway", "steps"));
     80        tagGroups[2] = createTagGroup(new Tag("highway", "steps"), new Tag("escalator", "yes"));
     81        tagGroups[3] = createTagGroup(new Tag("disused", "yes"), new Tag("construction", "no"));
    8282
    83                 for (Implication implication : implications) {
    84                         for (int i = 0; i < tagGroups.length; i++) {
    85                                 tagGroups[i] = implication.apply(tagGroups[i]);
    86                         }
    87                 }
     83        for (Implication implication : implications) {
     84            for (int i = 0; i < tagGroups.length; i++) {
     85                tagGroups[i] = implication.apply(tagGroups[i]);
     86            }
     87        }
    8888
    89                 assertSame(2, tagGroups[0].size());
    90                 assertTrue(tagGroups[0].contains(new Tag("bicycle", "designated")));
     89        assertSame(2, tagGroups[0].size());
     90        assertTrue(tagGroups[0].contains(new Tag("bicycle", "designated")));
    9191
    92                 assertSame(2, tagGroups[1].size());
    93                 assertTrue(tagGroups[1].contains(new Tag("normal_steps", "yes")));
     92        assertSame(2, tagGroups[1].size());
     93        assertTrue(tagGroups[1].contains(new Tag("normal_steps", "yes")));
    9494
    95                 assertSame(2, tagGroups[2].size());
    96                 assertFalse(tagGroups[2].contains(new Tag("normal_steps", "yes")));
     95        assertSame(2, tagGroups[2].size());
     96        assertFalse(tagGroups[2].contains(new Tag("normal_steps", "yes")));
    9797
    98                 assertSame(3, tagGroups[3].size());
    99                 assertTrue(tagGroups[3].contains(new Tag("usable", "no")));
    100         }
     98        assertSame(3, tagGroups[3].size());
     99        assertTrue(tagGroups[3].contains(new Tag("usable", "no")));
     100    }
    101101
    102         private static TagGroup createTagGroup(Tag... tags) {
    103                 Map<String, String> tagMap = new HashMap<String, String>();
    104                 for (Tag tag : tags) {
    105                         tagMap.put(tag.key, tag.value);
    106                 }
    107                 return new MapBasedTagGroup(tagMap);
    108         }
     102    private static TagGroup createTagGroup(Tag... tags) {
     103        Map<String, String> tagMap = new HashMap<String, String>();
     104        for (Tag tag : tags) {
     105            tagMap.put(tag.key, tag.value);
     106        }
     107        return new MapBasedTagGroup(tagMap);
     108    }
    109109
    110110}
  • applications/editors/josm/plugins/graphview/test/org/openstreetmap/josm/plugins/graphview/core/property/RoadInclineTest.java

    r16520 r23189  
    66public class RoadInclineTest extends RoadPropertyTest {
    77
    8         private static void testIncline(Float expectedInclineForward, Float expectedInclineBackward,
    9                         String inclineString) {
     8    private static void testIncline(Float expectedInclineForward, Float expectedInclineBackward,
     9            String inclineString) {
    1010
    11                 testEvaluateW(new RoadIncline(),
    12                                 expectedInclineForward, expectedInclineBackward,
    13                                 new Tag("incline", inclineString));
    14         }
     11        testEvaluateW(new RoadIncline(),
     12                expectedInclineForward, expectedInclineBackward,
     13                new Tag("incline", inclineString));
     14    }
    1515
    16         @Test
    17         public void testEvaluate() {
    18                 testIncline(5f, -5f, "5 %");
    19                 testIncline(9.5f, -9.5f, "9.5 %");
    20                 testIncline(-2.5f, 2.5f, "-2.5%");
    21                 testIncline(null, null, "steep");
    22         }
     16    @Test
     17    public void testEvaluate() {
     18        testIncline(5f, -5f, "5 %");
     19        testIncline(9.5f, -9.5f, "9.5 %");
     20        testIncline(-2.5f, 2.5f, "-2.5%");
     21        testIncline(null, null, "steep");
     22    }
    2323
    2424}
  • applications/editors/josm/plugins/graphview/test/org/openstreetmap/josm/plugins/graphview/core/property/RoadMaxspeedTest.java

    r21609 r23189  
    66public class RoadMaxspeedTest extends RoadPropertyTest {
    77
    8         private static void testMaxspeed(float expectedMaxspeed, String maxspeedString) {
    9                 testEvaluateBoth(new RoadMaxspeed(),    expectedMaxspeed, new Tag("maxspeed", maxspeedString));
    10         }
     8    private static void testMaxspeed(float expectedMaxspeed, String maxspeedString) {
     9        testEvaluateBoth(new RoadMaxspeed(),    expectedMaxspeed, new Tag("maxspeed", maxspeedString));
     10    }
    1111
    12         @Test
    13         public void testEvaluate_numeric() {
    14                 testMaxspeed(30, "30");
    15                 testMaxspeed(48.3f, "48.3");
    16         }
     12    @Test
     13    public void testEvaluate_numeric() {
     14        testMaxspeed(30, "30");
     15        testMaxspeed(48.3f, "48.3");
     16    }
    1717
    18         @Test
    19         public void testEvaluate_kmh() {
    20                 testMaxspeed(50, "50 km/h");
    21                 testMaxspeed(120, "120km/h");
    22                 testMaxspeed(30, "30    km/h");
    23         }
     18    @Test
     19    public void testEvaluate_kmh() {
     20        testMaxspeed(50, "50 km/h");
     21        testMaxspeed(120, "120km/h");
     22        testMaxspeed(30, "30    km/h");
     23    }
    2424
    25         @Test
    26         public void testEvaluate_mph() {
    27                 testMaxspeed(72.42048f, "45 mph");
    28                 testMaxspeed(64.373764f, "40mph");
    29                 testMaxspeed(24.14016f, "15     mph");
    30         }
     25    @Test
     26    public void testEvaluate_mph() {
     27        testMaxspeed(72.42048f, "45 mph");
     28        testMaxspeed(64.373764f, "40mph");
     29        testMaxspeed(24.14016f, "15 mph");
     30    }
    3131
    3232}
  • applications/editors/josm/plugins/graphview/test/org/openstreetmap/josm/plugins/graphview/core/property/RoadPropertyTest.java

    r16520 r23189  
    88abstract public class RoadPropertyTest {
    99
    10         protected static <P> void testEvaluateW(RoadPropertyType<P> property, P expectedForward, P expectedBackward, Tag... wayTags) {
     10    protected static <P> void testEvaluateW(RoadPropertyType<P> property, P expectedForward, P expectedBackward, Tag... wayTags) {
    1111
    12                 TestDataSource ds = new TestDataSource();
    13                 TestDataSource.TestWay testWay = new TestDataSource.TestWay();
    14                 for (Tag tag : wayTags) {
    15                         testWay.tags.put(tag.key, tag.value);
    16                 }
    17                 ds.ways.add(testWay);
     12        TestDataSource ds = new TestDataSource();
     13        TestDataSource.TestWay testWay = new TestDataSource.TestWay();
     14        for (Tag tag : wayTags) {
     15            testWay.tags.put(tag.key, tag.value);
     16        }
     17        ds.ways.add(testWay);
    1818
    19                 assertEquals(expectedForward, property.evaluateW(testWay, true, null, ds));
    20                 assertEquals(expectedBackward, property.evaluateW(testWay, false, null, ds));
     19        assertEquals(expectedForward, property.evaluateW(testWay, true, null, ds));
     20        assertEquals(expectedBackward, property.evaluateW(testWay, false, null, ds));
    2121
    22         }
     22    }
    2323
    24         protected static <P> void testEvaluateN(RoadPropertyType<P> property, P expected, Tag... nodeTags) {
     24    protected static <P> void testEvaluateN(RoadPropertyType<P> property, P expected, Tag... nodeTags) {
    2525
    26                 TestDataSource ds = new TestDataSource();
    27                 TestDataSource.TestNode testNode = new TestDataSource.TestNode();
    28                 for (Tag tag : nodeTags) {
    29                         testNode.tags.put(tag.key, tag.value);
    30                 }
    31                 ds.nodes.add(testNode);
     26        TestDataSource ds = new TestDataSource();
     27        TestDataSource.TestNode testNode = new TestDataSource.TestNode();
     28        for (Tag tag : nodeTags) {
     29            testNode.tags.put(tag.key, tag.value);
     30        }
     31        ds.nodes.add(testNode);
    3232
    33                 RoadMaxspeed m = new RoadMaxspeed();
     33        RoadMaxspeed m = new RoadMaxspeed();
    3434
    35                 assertEquals(expected, m.evaluateN(testNode, null, ds));
     35        assertEquals(expected, m.evaluateN(testNode, null, ds));
    3636
    37         }
     37    }
    3838
    39         protected static <P> void testEvaluateBoth(RoadPropertyType<P> property, P expected, Tag... nodeTags) {
    40                 testEvaluateW(property, expected, expected, nodeTags);
    41                 testEvaluateN(property, expected, nodeTags);
    42         }
     39    protected static <P> void testEvaluateBoth(RoadPropertyType<P> property, P expected, Tag... nodeTags) {
     40        testEvaluateW(property, expected, expected, nodeTags);
     41        testEvaluateN(property, expected, nodeTags);
     42    }
    4343
    4444}
  • applications/editors/josm/plugins/graphview/test/org/openstreetmap/josm/plugins/graphview/core/util/TagConditionLogicTest.java

    r16520 r23189  
    1515public class TagConditionLogicTest {
    1616
    17         TagGroup groupA;
    18         TagGroup groupB;
     17    TagGroup groupA;
     18    TagGroup groupB;
    1919
    20         @Before
    21         public void setUp() {
    22                 Map<String, String> mapA = new HashMap<String, String>();
    23                 mapA.put("key1", "value1");
    24                 mapA.put("key2", "value2");
    25                 mapA.put("key3", "value1");
    26                 groupA = new MapBasedTagGroup(mapA);
     20    @Before
     21    public void setUp() {
     22        Map<String, String> mapA = new HashMap<String, String>();
     23        mapA.put("key1", "value1");
     24        mapA.put("key2", "value2");
     25        mapA.put("key3", "value1");
     26        groupA = new MapBasedTagGroup(mapA);
    2727
    28                 Map<String, String> mapB = new HashMap<String, String>();
    29                 mapB.put("key1", "value1");
    30                 mapB.put("key4", "value4");
    31                 groupB = new MapBasedTagGroup(mapB);
    32         }
     28        Map<String, String> mapB = new HashMap<String, String>();
     29        mapB.put("key1", "value1");
     30        mapB.put("key4", "value4");
     31        groupB = new MapBasedTagGroup(mapB);
     32    }
    3333
    34         @Test
    35         public void testTag() {
    36                 TagCondition condition = TagConditionLogic.tag(new Tag("key3", "value1"));
    37                 assertTrue(condition.matches(groupA));
    38                 assertFalse(condition.matches(groupB));
    39         }
     34    @Test
     35    public void testTag() {
     36        TagCondition condition = TagConditionLogic.tag(new Tag("key3", "value1"));
     37        assertTrue(condition.matches(groupA));
     38        assertFalse(condition.matches(groupB));
     39    }
    4040
    41         @Test
    42         public void testKey() {
    43                 TagCondition condition = TagConditionLogic.key("key3");
    44                 assertTrue(condition.matches(groupA));
    45                 assertFalse(condition.matches(groupB));
    46         }
     41    @Test
     42    public void testKey() {
     43        TagCondition condition = TagConditionLogic.key("key3");
     44        assertTrue(condition.matches(groupA));
     45        assertFalse(condition.matches(groupB));
     46    }
    4747
    48         @Test
    49         public void testAnd() {
    50                 TagCondition condition1 = TagConditionLogic.tag(new Tag("key2", "value2"));
    51                 TagCondition conditionAnd1a = TagConditionLogic.and(condition1);
    52                 TagCondition conditionAnd1b = TagConditionLogic.and(Arrays.asList(condition1));
     48    @Test
     49    public void testAnd() {
     50        TagCondition condition1 = TagConditionLogic.tag(new Tag("key2", "value2"));
     51        TagCondition conditionAnd1a = TagConditionLogic.and(condition1);
     52        TagCondition conditionAnd1b = TagConditionLogic.and(Arrays.asList(condition1));
    5353
    54                 assertTrue(conditionAnd1a.matches(groupA));
    55                 assertTrue(conditionAnd1b.matches(groupA));
    56                 assertFalse(conditionAnd1a.matches(groupB));
    57                 assertFalse(conditionAnd1b.matches(groupB));
     54        assertTrue(conditionAnd1a.matches(groupA));
     55        assertTrue(conditionAnd1b.matches(groupA));
     56        assertFalse(conditionAnd1a.matches(groupB));
     57        assertFalse(conditionAnd1b.matches(groupB));
    5858
    59                 TagCondition condition2 = TagConditionLogic.tag(new Tag("key1", "value1"));
    60                 TagCondition conditionAnd2a = TagConditionLogic.and(condition1, condition2);
    61                 TagCondition conditionAnd2b = TagConditionLogic.and(Arrays.asList(condition1, condition2));
     59        TagCondition condition2 = TagConditionLogic.tag(new Tag("key1", "value1"));
     60        TagCondition conditionAnd2a = TagConditionLogic.and(condition1, condition2);
     61        TagCondition conditionAnd2b = TagConditionLogic.and(Arrays.asList(condition1, condition2));
    6262
    63                 assertTrue(conditionAnd2a.matches(groupA));
    64                 assertTrue(conditionAnd2b.matches(groupA));
    65                 assertFalse(conditionAnd2a.matches(groupB));
    66                 assertFalse(conditionAnd2b.matches(groupB));
     63        assertTrue(conditionAnd2a.matches(groupA));
     64        assertTrue(conditionAnd2b.matches(groupA));
     65        assertFalse(conditionAnd2a.matches(groupB));
     66        assertFalse(conditionAnd2b.matches(groupB));
    6767
    68                 TagCondition condition3 = TagConditionLogic.tag(new Tag("key4", "value4"));
    69                 TagCondition conditionAnd3a = TagConditionLogic.and(condition1, condition2, condition3);
    70                 TagCondition conditionAnd3b = TagConditionLogic.and(Arrays.asList(condition1, condition2, condition3));
     68        TagCondition condition3 = TagConditionLogic.tag(new Tag("key4", "value4"));
     69        TagCondition conditionAnd3a = TagConditionLogic.and(condition1, condition2, condition3);
     70        TagCondition conditionAnd3b = TagConditionLogic.and(Arrays.asList(condition1, condition2, condition3));
    7171
    72                 assertFalse(conditionAnd3a.matches(groupA));
    73                 assertFalse(conditionAnd3b.matches(groupA));
    74                 assertFalse(conditionAnd3a.matches(groupB));
    75                 assertFalse(conditionAnd3b.matches(groupB));
    76         }
     72        assertFalse(conditionAnd3a.matches(groupA));
     73        assertFalse(conditionAnd3b.matches(groupA));
     74        assertFalse(conditionAnd3a.matches(groupB));
     75        assertFalse(conditionAnd3b.matches(groupB));
     76    }
    7777
    78         @Test
    79         public void testOr() {
    80                 TagCondition condition1 = TagConditionLogic.tag(new Tag("key42", "value42"));
    81                 TagCondition conditionOr1a = TagConditionLogic.or(condition1);
    82                 TagCondition conditionOr1b = TagConditionLogic.or(Arrays.asList(condition1));
     78    @Test
     79    public void testOr() {
     80        TagCondition condition1 = TagConditionLogic.tag(new Tag("key42", "value42"));
     81        TagCondition conditionOr1a = TagConditionLogic.or(condition1);
     82        TagCondition conditionOr1b = TagConditionLogic.or(Arrays.asList(condition1));
    8383
    84                 assertFalse(conditionOr1a.matches(groupA));
    85                 assertFalse(conditionOr1b.matches(groupA));
    86                 assertFalse(conditionOr1a.matches(groupB));
    87                 assertFalse(conditionOr1b.matches(groupB));
     84        assertFalse(conditionOr1a.matches(groupA));
     85        assertFalse(conditionOr1b.matches(groupA));
     86        assertFalse(conditionOr1a.matches(groupB));
     87        assertFalse(conditionOr1b.matches(groupB));
    8888
    89                 TagCondition condition2 = TagConditionLogic.tag(new Tag("key3", "value1"));
    90                 TagCondition conditionOr2a = TagConditionLogic.or(condition1, condition2);
    91                 TagCondition conditionOr2b = TagConditionLogic.or(Arrays.asList(condition1, condition2));
     89        TagCondition condition2 = TagConditionLogic.tag(new Tag("key3", "value1"));
     90        TagCondition conditionOr2a = TagConditionLogic.or(condition1, condition2);
     91        TagCondition conditionOr2b = TagConditionLogic.or(Arrays.asList(condition1, condition2));
    9292
    93                 assertTrue(conditionOr2a.matches(groupA));
    94                 assertTrue(conditionOr2b.matches(groupA));
    95                 assertFalse(conditionOr2a.matches(groupB));
    96                 assertFalse(conditionOr2b.matches(groupB));
     93        assertTrue(conditionOr2a.matches(groupA));
     94        assertTrue(conditionOr2b.matches(groupA));
     95        assertFalse(conditionOr2a.matches(groupB));
     96        assertFalse(conditionOr2b.matches(groupB));
    9797
    98                 TagCondition condition3 = TagConditionLogic.tag(new Tag("key1", "value1"));
    99                 TagCondition conditionOr3a = TagConditionLogic.or(condition1, condition2, condition3);
    100                 TagCondition conditionOr3b = TagConditionLogic.or(Arrays.asList(condition1, condition2, condition3));
     98        TagCondition condition3 = TagConditionLogic.tag(new Tag("key1", "value1"));
     99        TagCondition conditionOr3a = TagConditionLogic.or(condition1, condition2, condition3);
     100        TagCondition conditionOr3b = TagConditionLogic.or(Arrays.asList(condition1, condition2, condition3));
    101101
    102                 assertTrue(conditionOr3a.matches(groupA));
    103                 assertTrue(conditionOr3b.matches(groupA));
    104                 assertTrue(conditionOr3a.matches(groupB));
    105                 assertTrue(conditionOr3b.matches(groupB));
    106         }
     102        assertTrue(conditionOr3a.matches(groupA));
     103        assertTrue(conditionOr3b.matches(groupA));
     104        assertTrue(conditionOr3a.matches(groupB));
     105        assertTrue(conditionOr3b.matches(groupB));
     106    }
    107107
    108         @Test
    109         public void testNot() {
    110                 TagCondition condition = TagConditionLogic.not(TagConditionLogic.key("key3"));
    111                 assertFalse(condition.matches(groupA));
    112                 assertTrue(condition.matches(groupB));
    113         }
     108    @Test
     109    public void testNot() {
     110        TagCondition condition = TagConditionLogic.not(TagConditionLogic.key("key3"));
     111        assertFalse(condition.matches(groupA));
     112        assertTrue(condition.matches(groupB));
     113    }
    114114
    115115}
  • applications/editors/josm/plugins/graphview/test/org/openstreetmap/josm/plugins/graphview/core/util/ValueStringParserTest.java

    r20244 r23189  
    1010public class ValueStringParserTest {
    1111
    12         /* speed */
     12    /* speed */
    1313
    14         @Test
    15         public void testParseSpeedDefault() {
    16                 assertClose(50, parseSpeed("50"));
    17         }
     14    @Test
     15    public void testParseSpeedDefault() {
     16        assertClose(50, parseSpeed("50"));
     17    }
    1818
    19         @Test
    20         public void testParseSpeedKmh() {
    21                 assertClose(30, parseSpeed("30 km/h"));
    22                 assertClose(100, parseSpeed("100km/h"));
    23         }
     19    @Test
     20    public void testParseSpeedKmh() {
     21        assertClose(30, parseSpeed("30 km/h"));
     22        assertClose(100, parseSpeed("100km/h"));
     23    }
    2424
    25         @Test
    26         public void testParseSpeedMph() {
    27                 assertClose(40.234f, parseSpeed("25mph"));
    28                 assertClose(40.234f, parseSpeed("25 mph"));
    29         }
     25    @Test
     26    public void testParseSpeedMph() {
     27        assertClose(40.234f, parseSpeed("25mph"));
     28        assertClose(40.234f, parseSpeed("25 mph"));
     29    }
    3030
    31         @Test
    32         public void testParseSpeedInvalid() {
    33                 assertNull(parseSpeed("lightspeed"));
    34         }
     31    @Test
     32    public void testParseSpeedInvalid() {
     33        assertNull(parseSpeed("lightspeed"));
     34    }
    3535
    36         /* measure */
     36    /* measure */
    3737
    38         @Test
    39         public void testParseMeasureDefault() {
    40                 assertClose(3.5f, parseMeasure("3.5"));
    41         }
     38    @Test
     39    public void testParseMeasureDefault() {
     40        assertClose(3.5f, parseMeasure("3.5"));
     41    }
    4242
    43         @Test
    44         public void testParseMeasureM() {
    45                 assertClose(2, parseMeasure("2m"));
    46                 assertClose(5.5f, parseMeasure("5.5 m"));
    47         }
     43    @Test
     44    public void testParseMeasureM() {
     45        assertClose(2, parseMeasure("2m"));
     46        assertClose(5.5f, parseMeasure("5.5 m"));
     47    }
    4848
    49         @Test
    50         public void testParseMeasureKm() {
    51                 assertClose(1000, parseMeasure("1 km"));
    52                 assertClose(7200, parseMeasure("7.2km"));
    53         }
     49    @Test
     50    public void testParseMeasureKm() {
     51        assertClose(1000, parseMeasure("1 km"));
     52        assertClose(7200, parseMeasure("7.2km"));
     53    }
    5454
    55         @Test
    56         public void testParseMeasureMi() {
    57                 assertClose(1609.344f, parseMeasure("1 mi"));
    58         }
     55    @Test
     56    public void testParseMeasureMi() {
     57        assertClose(1609.344f, parseMeasure("1 mi"));
     58    }
    5959
    60         @Test
    61         public void testParseMeasureFeetInches() {
    62                 assertClose(3.6576f, parseMeasure("12'0\""));
    63                 assertClose(1.9812f, parseMeasure("6' 6\""));
    64         }
     60    @Test
     61    public void testParseMeasureFeetInches() {
     62        assertClose(3.6576f, parseMeasure("12'0\""));
     63        assertClose(1.9812f, parseMeasure("6' 6\""));
     64    }
    6565
    66         @Test
    67         public void testParseMeasureInvalid() {
    68                 assertNull(parseMeasure("very long"));
    69                 assertNull(parseMeasure("6' 16\""));
    70         }
     66    @Test
     67    public void testParseMeasureInvalid() {
     68        assertNull(parseMeasure("very long"));
     69        assertNull(parseMeasure("6' 16\""));
     70    }
    7171
    72         /* weight */
     72    /* weight */
    7373
    74         @Test
    75         public void testParseWeightDefault() {
    76                 assertClose(3.6f, parseWeight("3.6"));
    77         }
     74    @Test
     75    public void testParseWeightDefault() {
     76        assertClose(3.6f, parseWeight("3.6"));
     77    }
    7878
    79         @Test
    80         public void testParseWeightT() {
    81                 assertClose(30, parseWeight("30t"));
    82                 assertClose(3.5f, parseWeight("3.5 t"));
    83         }
     79    @Test
     80    public void testParseWeightT() {
     81        assertClose(30, parseWeight("30t"));
     82        assertClose(3.5f, parseWeight("3.5 t"));
     83    }
    8484
    85         @Test
    86         public void testParseWeightInvalid() {
    87                 assertNull(parseWeight("heavy"));
    88         }
     85    @Test
     86    public void testParseWeightInvalid() {
     87        assertNull(parseWeight("heavy"));
     88    }
    8989
    90         private static final void assertClose(float expected, float actual) {
    91                 if (Math.abs(expected - actual) > 0.001) {
    92                         throw new AssertionError("expected " + expected + ", was " + actual);
    93                 }
    94         }
     90    private static final void assertClose(float expected, float actual) {
     91        if (Math.abs(expected - actual) > 0.001) {
     92            throw new AssertionError("expected " + expected + ", was " + actual);
     93        }
     94    }
    9595
    9696}
  • applications/editors/josm/plugins/graphview/test/org/openstreetmap/josm/plugins/graphview/core/visualisation/FloatPropertyColorSchemeTest.java

    r16520 r23189  
    1313public class FloatPropertyColorSchemeTest {
    1414
    15         private FloatPropertyColorScheme subject;
     15    private FloatPropertyColorScheme subject;
    1616
    17         @Before
    18         public void setUp() {
     17    @Before
     18    public void setUp() {
    1919
    20                 Map<Float, Color> colorMap = new HashMap<Float, Color>();
    21                 colorMap.put( 5f, new Color( 42,  42,  42));
    22                 colorMap.put(10f, new Color(100, 100, 100));
    23                 colorMap.put(20f, new Color(200, 200, 200));
     20        Map<Float, Color> colorMap = new HashMap<Float, Color>();
     21        colorMap.put( 5f, new Color( 42,  42,  42));
     22        colorMap.put(10f, new Color(100, 100, 100));
     23        colorMap.put(20f, new Color(200, 200, 200));
    2424
    25                 subject = new FloatPropertyColorScheme(RoadMaxweight.class, colorMap, Color.RED);
    26         }
     25        subject = new FloatPropertyColorScheme(RoadMaxweight.class, colorMap, Color.RED);
     26    }
    2727
    28         @Test
    29         public void testGetColorForValue_below() {
    30                 assertEquals(new Color(42, 42, 42), subject.getColorForValue(1f));
    31                 assertEquals(new Color(42, 42, 42), subject.getColorForValue(5f));
    32         }
     28    @Test
     29    public void testGetColorForValue_below() {
     30        assertEquals(new Color(42, 42, 42), subject.getColorForValue(1f));
     31        assertEquals(new Color(42, 42, 42), subject.getColorForValue(5f));
     32    }
    3333
    34         @Test
    35         public void testGetColorForValue_above() {
    36                 assertEquals(new Color(200, 200, 200), subject.getColorForValue(25f));
    37         }
     34    @Test
     35    public void testGetColorForValue_above() {
     36        assertEquals(new Color(200, 200, 200), subject.getColorForValue(25f));
     37    }
    3838
    39         @Test
    40         public void testGetColorForValue_value() {
    41                 assertEquals(new Color(100, 100, 100), subject.getColorForValue(10f));
    42         }
     39    @Test
     40    public void testGetColorForValue_value() {
     41        assertEquals(new Color(100, 100, 100), subject.getColorForValue(10f));
     42    }
    4343
    44         @Test
    45         public void testGetColorForValue_interpolate() {
    46                 assertEquals(new Color(150, 150, 150), subject.getColorForValue(15f));
    47         }
     44    @Test
     45    public void testGetColorForValue_interpolate() {
     46        assertEquals(new Color(150, 150, 150), subject.getColorForValue(15f));
     47    }
    4848
    4949}
  • applications/editors/josm/plugins/multipoly-convert/src/converttomultipoly/MultipolyAction.java

    r20416 r23189  
    2727/**
    2828 * Convert an area into an advance multipolygon.
    29  * 
     29 *
    3030 * New relation with type=multipolygon is created for each ways.
    31  * 
     31 *
    3232 * All the tags (except the source tag) will be moved into the relation.
    3333 */
     
    3535public class MultipolyAction extends JosmAction {
    3636
    37         public MultipolyAction() {
    38                 super(tr("Convert to multipolygon"), "multipoly_convert",
    39                                 tr("Convert to multipolygon."), Shortcut.registerShortcut(
    40                                                 "tools:multipolyconv", tr("Tool: {0}",
    41                                                                 tr("Convert to multipolygon")), KeyEvent.VK_M,
    42                                                 Shortcut.GROUP_EDIT, Shortcut.SHIFT_DEFAULT), true);
    43         }
     37    public MultipolyAction() {
     38        super(tr("Convert to multipolygon"), "multipoly_convert",
     39                tr("Convert to multipolygon."), Shortcut.registerShortcut(
     40                        "tools:multipolyconv", tr("Tool: {0}",
     41                                tr("Convert to multipolygon")), KeyEvent.VK_M,
     42                        Shortcut.GROUP_EDIT, Shortcut.SHIFT_DEFAULT), true);
     43    }
    4444
    45         /**
    46         * The action button has been clicked
    47          *
    48         * @param e
    49         *            Action Event
    50         */
    51         public void actionPerformed(ActionEvent e) {
     45    /**
     46    * The action button has been clicked
     47     *
     48    * @param e
     49    *            Action Event
     50    */
     51    public void actionPerformed(ActionEvent e) {
    5252
    53                 // Get all ways in some type=multipolygon relation
    54                 HashSet<OsmPrimitive> relationsInMulti = new HashSet<OsmPrimitive>();
    55                 for (Relation r : Main.main.getCurrentDataSet().getRelations()) {
    56                         if (!r.isUsable())
    57                                 continue;
    58                         if (r.get("type") != "multipolygon")
    59                                 continue;
    60                         for (RelationMember rm : r.getMembers()) {
    61                                 OsmPrimitive m = rm.getMember();
    62                                 if (m instanceof Way) {
    63                                         relationsInMulti.add(m);
    64                                 }
    65                         }
    66                 }
     53        // Get all ways in some type=multipolygon relation
     54        HashSet<OsmPrimitive> relationsInMulti = new HashSet<OsmPrimitive>();
     55        for (Relation r : Main.main.getCurrentDataSet().getRelations()) {
     56            if (!r.isUsable())
     57                continue;
     58            if (r.get("type") != "multipolygon")
     59                continue;
     60            for (RelationMember rm : r.getMembers()) {
     61                OsmPrimitive m = rm.getMember();
     62                if (m instanceof Way) {
     63                    relationsInMulti.add(m);
     64                }
     65            }
     66        }
    6767
    68                 // List of selected ways
    69                 ArrayList<Way> selectedWays = new ArrayList<Way>();
    70                
     68        // List of selected ways
     69        ArrayList<Way> selectedWays = new ArrayList<Way>();
    7170
    72                 // For every selected way
    73                 for (OsmPrimitive osm : Main.main.getCurrentDataSet().getSelected()) {
    74                         if (osm instanceof Way) {
    75                                 Way way = (Way) osm;
    76                                 // Check if way is already in another multipolygon
    77                                 if (relationsInMulti.contains(osm)) {
    78                                         JOptionPane
    79                                                         .showMessageDialog(
    80                                                                         Main.parent,
    81                                                                         tr("One of the selected ways is already part of another multipolygon."));
    82                                         return;
    83                                 }
    8471
    85                                 selectedWays.add(way);
    86                         }
    87                 }
     72        // For every selected way
     73        for (OsmPrimitive osm : Main.main.getCurrentDataSet().getSelected()) {
     74            if (osm instanceof Way) {
     75                Way way = (Way) osm;
     76                // Check if way is already in another multipolygon
     77                if (relationsInMulti.contains(osm)) {
     78                    JOptionPane
     79                            .showMessageDialog(
     80                                    Main.parent,
     81                                    tr("One of the selected ways is already part of another multipolygon."));
     82                    return;
     83                }
    8884
    89                 if (Main.map == null) {
    90                         JOptionPane.showMessageDialog(Main.parent, tr("No data loaded."));
    91                         return;
    92                 }
     85                selectedWays.add(way);
     86            }
     87        }
    9388
    94                 Collection<Command> cmds = new LinkedList<Command>();
    95                 // Add ways to it
    96                 for (int i = 0; i < selectedWays.size(); i++) {
    97                         Way way = selectedWays.get(i);
     89        if (Main.map == null) {
     90            JOptionPane.showMessageDialog(Main.parent, tr("No data loaded."));
     91            return;
     92        }
    9893
    99                         // Create new relation
    100                         Relation rel = new Relation();
    101                         rel.put("type", "multipolygon");
     94        Collection<Command> cmds = new LinkedList<Command>();
     95        // Add ways to it
     96        for (int i = 0; i < selectedWays.size(); i++) {
     97                Way way = selectedWays.get(i);
    10298
    103                         RelationMember rm = new RelationMember("outer", way);
    104                         rel.addMember(rm);
    105                        
    106                         for (Iterator<String> keyi = way.getKeys().keySet().iterator() ; keyi.hasNext() ; ) {
    107                                 String key = keyi.next();
    108                                 rel.put(key, way.get(key));
    109                                 System.out.println(key);
    110                                 if (key.compareTo("source") != 0) {
    111                                         way.remove(key);
    112                                 }
    113                         }
    114                         // Add relation
    115                         cmds.add(new AddCommand(rel));
    116                 }
    117                 // Commit
    118                 Main.main.undoRedo.add(new SequenceCommand(tr("Create multipolygon"), cmds));
    119                 Main.map.repaint();
    120         }
     99                // Create new relation
     100                    Relation rel = new Relation();
     101                    rel.put("type", "multipolygon");
    121102
    122         /** Enable this action only if something is selected */
    123         @Override
    124         protected void updateEnabledState() {
    125                 if (getCurrentDataSet() == null) {
    126                         setEnabled(false);
    127                 } else {
    128                         updateEnabledState(getCurrentDataSet().getSelected());
    129                 }
    130         }
     103            RelationMember rm = new RelationMember("outer", way);
     104            rel.addMember(rm);
    131105
    132         /** Enable this action only if something is selected */
    133         @Override
    134         protected void updateEnabledState(
    135                         Collection<? extends OsmPrimitive> selection) {
    136                 setEnabled(selection != null && !selection.isEmpty());
    137         }
     106            for (Iterator<String> keyi = way.getKeys().keySet().iterator() ; keyi.hasNext() ; ) {
     107                    String key = keyi.next();
     108                    rel.put(key, way.get(key));
     109                    System.out.println(key);
     110                    if (key.compareTo("source") != 0) {
     111                            way.remove(key);
     112                    }
     113            }
     114                    // Add relation
     115                    cmds.add(new AddCommand(rel));
     116        }
     117        // Commit
     118        Main.main.undoRedo.add(new SequenceCommand(tr("Create multipolygon"), cmds));
     119        Main.map.repaint();
     120    }
     121
     122    /** Enable this action only if something is selected */
     123    @Override
     124    protected void updateEnabledState() {
     125        if (getCurrentDataSet() == null) {
     126            setEnabled(false);
     127        } else {
     128            updateEnabledState(getCurrentDataSet().getSelected());
     129        }
     130    }
     131
     132    /** Enable this action only if something is selected */
     133    @Override
     134    protected void updateEnabledState(
     135            Collection<? extends OsmPrimitive> selection) {
     136        setEnabled(selection != null && !selection.isEmpty());
     137    }
    138138}
  • applications/editors/josm/plugins/multipoly-convert/src/converttomultipoly/MultipolyPlugin.java

    r20416 r23189  
    1515public class MultipolyPlugin extends Plugin {
    1616
    17         protected String name;
     17    protected String name;
    1818
    1919//        public MultipolyPlugin(PluginInformation info) {
    2020        public MultipolyPlugin(PluginInformation info) {
    21                 super(info);
    22                 name = tr("Convert to multipolygon");
    23                 JMenu toolsMenu = null;
    24                 for (int i = 0; i < Main.main.menu.getMenuCount() && toolsMenu == null; i++) {
    25                         JMenu menu = Main.main.menu.getMenu(i);
    26                         String name = menu.getText();
    27                         if (name != null && name.equals(tr("Tools"))) {
    28                                 toolsMenu = menu;
    29                         }
    30                 }
     21        super(info);
     22        name = tr("Convert to multipolygon");
     23        JMenu toolsMenu = null;
     24        for (int i = 0; i < Main.main.menu.getMenuCount() && toolsMenu == null; i++) {
     25            JMenu menu = Main.main.menu.getMenu(i);
     26            String name = menu.getText();
     27            if (name != null && name.equals(tr("Tools"))) {
     28                toolsMenu = menu;
     29            }
     30        }
    3131
    32                 if (toolsMenu == null) {
    33                         toolsMenu = new JMenu(name);
    34                         toolsMenu.add(new JMenuItem(new MultipolyAction()));
    35                         Main.main.menu.add(toolsMenu, 2);
    36                 } else {
    37                         toolsMenu.addSeparator();
    38                         toolsMenu.add(new JMenuItem(new MultipolyAction()));
    39                 }
    40         }
     32        if (toolsMenu == null) {
     33            toolsMenu = new JMenu(name);
     34            toolsMenu.add(new JMenuItem(new MultipolyAction()));
     35            Main.main.menu.add(toolsMenu, 2);
     36        } else {
     37            toolsMenu.addSeparator();
     38            toolsMenu.add(new JMenuItem(new MultipolyAction()));
     39        }
     40    }
    4141}
  • applications/editors/josm/plugins/multipoly/src/multipoly/MultipolyAction.java

    r19456 r23189  
    3030/**
    3131 * Create multipolygon from selected ways automatically.
    32  * 
     32 *
    3333 * New relation with type=multipolygon is created
    34  * 
     34 *
    3535 * If one or more of ways is already in relation with type=multipolygon or the
    3636 * way is not closed, then error is reported and no relation is created
    37  * 
     37 *
    3838 * The "inner" and "outer" roles are guessed automatically. First, bbox is
    3939 * calculated for each way. then the largest area is assumed to be outside and
     
    4545public class MultipolyAction extends JosmAction {
    4646
    47         public MultipolyAction() {
    48                 super(tr("Create multipolygon"), "multipoly_create",
    49                                 tr("Create multipolygon."), Shortcut.registerShortcut(
    50                                                 "tools:multipoly", tr("Tool: {0}",
    51                                                                 tr("Create multipolygon")), KeyEvent.VK_M,
    52                                                 Shortcut.GROUP_EDIT, Shortcut.SHIFT_DEFAULT), true);
    53         }
     47    public MultipolyAction() {
     48        super(tr("Create multipolygon"), "multipoly_create",
     49                tr("Create multipolygon."), Shortcut.registerShortcut(
     50                        "tools:multipoly", tr("Tool: {0}",
     51                                tr("Create multipolygon")), KeyEvent.VK_M,
     52                        Shortcut.GROUP_EDIT, Shortcut.SHIFT_DEFAULT), true);
     53    }
    5454
    55         /**
    56         * The action button has been clicked
    57          *
    58         * @param e
    59         *            Action Event
    60         */
    61         public void actionPerformed(ActionEvent e) {
     55    /**
     56    * The action button has been clicked
     57     *
     58    * @param e
     59    *            Action Event
     60    */
     61    public void actionPerformed(ActionEvent e) {
    6262
    63                 // Get all ways in some type=multipolygon relation
    64                 HashSet<OsmPrimitive> relationsInMulti = new HashSet<OsmPrimitive>();
    65                 for (Relation r : Main.main.getCurrentDataSet().getRelations()) {
    66                         if (!r.isUsable())
    67                                 continue;
    68                         if (r.get("type") != "multipolygon")
    69                                 continue;
    70                         for (RelationMember rm : r.getMembers()) {
    71                                 OsmPrimitive m = rm.getMember();
    72                                 if (m instanceof Way) {
    73                                         relationsInMulti.add(m);
    74                                 }
    75                         }
    76                 }
     63        // Get all ways in some type=multipolygon relation
     64        HashSet<OsmPrimitive> relationsInMulti = new HashSet<OsmPrimitive>();
     65        for (Relation r : Main.main.getCurrentDataSet().getRelations()) {
     66            if (!r.isUsable())
     67                continue;
     68            if (r.get("type") != "multipolygon")
     69                continue;
     70            for (RelationMember rm : r.getMembers()) {
     71                OsmPrimitive m = rm.getMember();
     72                if (m instanceof Way) {
     73                    relationsInMulti.add(m);
     74                }
     75            }
     76        }
    7777
    78                 // List of selected ways
    79                 List<Way> selectedWays = new ArrayList<Way>();
    80                 // Area of largest way (in square degrees)
    81                 double maxarea = 0;
    82                 // Which way is the largest one (outer)
    83                 Way maxWay = null;
     78        // List of selected ways
     79        List<Way> selectedWays = new ArrayList<Way>();
     80        // Area of largest way (in square degrees)
     81        double maxarea = 0;
     82        // Which way is the largest one (outer)
     83        Way maxWay = null;
    8484
    85                 // For every selected way
    86                 for (OsmPrimitive osm : Main.main.getCurrentDataSet().getSelected()) {
    87                         if (osm instanceof Way) {
    88                                 Way way = (Way) osm;
    89                                 // Check if way is already in another multipolygon
    90                                 if (relationsInMulti.contains(osm)) {
    91                                         JOptionPane
    92                                                         .showMessageDialog(
    93                                                                         Main.parent,
    94                                                                         tr("One of the selected ways is already part of another multipolygon."));
    95                                         return;
    96                                 }
    97                                 EastNorth first = null, last = null;
    98                                 // Boundingbox of way
    99                                 double minx = 9999, miny = 9999, maxx = -9999, maxy = -9999;
    100                                 for (Pair<Node, Node> seg : way.getNodePairs(false)) {
    101                                         if (first == null)
    102                                                 first = seg.a.getEastNorth();
    103                                         last = seg.b.getEastNorth();
    104                                         double x = seg.a.getEastNorth().east();
    105                                         double y = seg.a.getEastNorth().north();
    106                                         if (x < minx)
    107                                                 minx = x;
    108                                         if (y < miny)
    109                                                 miny = y;
    110                                         if (x > maxx)
    111                                                 maxx = x;
    112                                         if (y > maxy)
    113                                                 maxy = y;
    114                                 }
    115                                 // Check if first and last node are the same
    116                                 if (!first.equals(last)) {
    117                                         JOptionPane
    118                                                         .showMessageDialog(
    119                                                                         Main.parent,
    120                                                                         tr("Multipolygon must consist only of closed ways."));
    121                                         return;
    122                                 }
    123                                 // Determine area
    124                                 double area = (maxx - minx) * (maxy - miny);
    125                                 selectedWays.add(way);
    126                                 if (area > maxarea) {
    127                                         maxarea = area;
    128                                         maxWay = way;
    129                                 }
    130                         }
    131                 }
     85        // For every selected way
     86        for (OsmPrimitive osm : Main.main.getCurrentDataSet().getSelected()) {
     87            if (osm instanceof Way) {
     88                Way way = (Way) osm;
     89                // Check if way is already in another multipolygon
     90                if (relationsInMulti.contains(osm)) {
     91                    JOptionPane
     92                            .showMessageDialog(
     93                                    Main.parent,
     94                                    tr("One of the selected ways is already part of another multipolygon."));
     95                    return;
     96                }
     97                EastNorth first = null, last = null;
     98                // Boundingbox of way
     99                double minx = 9999, miny = 9999, maxx = -9999, maxy = -9999;
     100                for (Pair<Node, Node> seg : way.getNodePairs(false)) {
     101                    if (first == null)
     102                        first = seg.a.getEastNorth();
     103                    last = seg.b.getEastNorth();
     104                    double x = seg.a.getEastNorth().east();
     105                    double y = seg.a.getEastNorth().north();
     106                    if (x < minx)
     107                        minx = x;
     108                    if (y < miny)
     109                        miny = y;
     110                    if (x > maxx)
     111                        maxx = x;
     112                    if (y > maxy)
     113                        maxy = y;
     114                }
     115                // Check if first and last node are the same
     116                if (!first.equals(last)) {
     117                    JOptionPane
     118                            .showMessageDialog(
     119                                    Main.parent,
     120                                    tr("Multipolygon must consist only of closed ways."));
     121                    return;
     122                }
     123                // Determine area
     124                double area = (maxx - minx) * (maxy - miny);
     125                selectedWays.add(way);
     126                if (area > maxarea) {
     127                    maxarea = area;
     128                    maxWay = way;
     129                }
     130            }
     131        }
    132132
    133                 if (Main.map == null) {
    134                         JOptionPane.showMessageDialog(Main.parent, tr("No data loaded."));
    135                         return;
    136                 }
     133        if (Main.map == null) {
     134            JOptionPane.showMessageDialog(Main.parent, tr("No data loaded."));
     135            return;
     136        }
    137137
    138                 if (selectedWays.size() < 2) {
    139                         JOptionPane.showMessageDialog(Main.parent,
    140                                         tr("You must select at least two ways."));
    141                         return;
    142                 }
     138        if (selectedWays.size() < 2) {
     139            JOptionPane.showMessageDialog(Main.parent,
     140                    tr("You must select at least two ways."));
     141            return;
     142        }
    143143
    144                 Collection<Command> cmds = new LinkedList<Command>();
    145                 // Create new relation
    146                 Relation rel = new Relation();
    147                 rel.put("type", "multipolygon");
    148                 // Add ways to it
    149                 for (int i = 0; i < selectedWays.size(); i++) {
    150                         Way s = selectedWays.get(i);
    151                         String xrole = "inner";
    152                         if (s == maxWay)
    153                                 xrole = "outer";
    154                         RelationMember rm = new RelationMember(xrole, s);
    155                         rel.addMember(rm);
    156                 }
    157                 // Add relation
    158                 cmds.add(new AddCommand(rel));
    159                 // Commit
    160                 Main.main.undoRedo.add(new SequenceCommand(tr("Create multipolygon"),
    161                                 cmds));
    162                 Main.map.repaint();
    163         }
     144        Collection<Command> cmds = new LinkedList<Command>();
     145        // Create new relation
     146        Relation rel = new Relation();
     147        rel.put("type", "multipolygon");
     148        // Add ways to it
     149        for (int i = 0; i < selectedWays.size(); i++) {
     150            Way s = selectedWays.get(i);
     151            String xrole = "inner";
     152            if (s == maxWay)
     153                xrole = "outer";
     154            RelationMember rm = new RelationMember(xrole, s);
     155            rel.addMember(rm);
     156        }
     157        // Add relation
     158        cmds.add(new AddCommand(rel));
     159        // Commit
     160        Main.main.undoRedo.add(new SequenceCommand(tr("Create multipolygon"),
     161                cmds));
     162        Main.map.repaint();
     163    }
    164164
    165         /** Enable this action only if something is selected */
    166         @Override
    167         protected void updateEnabledState() {
    168                 if (getCurrentDataSet() == null) {
    169                         setEnabled(false);
    170                 } else {
    171                         updateEnabledState(getCurrentDataSet().getSelected());
    172                 }
    173         }
     165    /** Enable this action only if something is selected */
     166    @Override
     167    protected void updateEnabledState() {
     168        if (getCurrentDataSet() == null) {
     169            setEnabled(false);
     170        } else {
     171            updateEnabledState(getCurrentDataSet().getSelected());
     172        }
     173    }
    174174
    175         /** Enable this action only if something is selected */
    176         @Override
    177         protected void updateEnabledState(
    178                         Collection<? extends OsmPrimitive> selection) {
    179                 setEnabled(selection != null && !selection.isEmpty());
    180         }
     175    /** Enable this action only if something is selected */
     176    @Override
     177    protected void updateEnabledState(
     178            Collection<? extends OsmPrimitive> selection) {
     179        setEnabled(selection != null && !selection.isEmpty());
     180    }
    181181}
  • applications/editors/josm/plugins/multipoly/src/multipoly/MultipolyPlugin.java

    r19456 r23189  
    1515public class MultipolyPlugin extends Plugin {
    1616
    17         protected String name;
     17    protected String name;
    1818
    19         public MultipolyPlugin(PluginInformation info) {
    20                 super(info);
    21                 name = tr("Create multipolygon");
    22                 JMenu toolsMenu = null;
    23                 for (int i = 0; i < Main.main.menu.getMenuCount() && toolsMenu == null; i++) {
    24                         JMenu menu = Main.main.menu.getMenu(i);
    25                         String name = menu.getText();
    26                         if (name != null && name.equals(tr("Tools"))) {
    27                                 toolsMenu = menu;
    28                         }
    29                 }
     19    public MultipolyPlugin(PluginInformation info) {
     20        super(info);
     21        name = tr("Create multipolygon");
     22        JMenu toolsMenu = null;
     23        for (int i = 0; i < Main.main.menu.getMenuCount() && toolsMenu == null; i++) {
     24            JMenu menu = Main.main.menu.getMenu(i);
     25            String name = menu.getText();
     26            if (name != null && name.equals(tr("Tools"))) {
     27                toolsMenu = menu;
     28            }
     29        }
    3030
    31                 if (toolsMenu == null) {
    32                         toolsMenu = new JMenu(name);
    33                         toolsMenu.add(new JMenuItem(new MultipolyAction()));
    34                         Main.main.menu.add(toolsMenu, 2);
    35                 } else {
    36                         toolsMenu.addSeparator();
    37                         toolsMenu.add(new JMenuItem(new MultipolyAction()));
    38                 }
    39         }
     31        if (toolsMenu == null) {
     32            toolsMenu = new JMenu(name);
     33            toolsMenu.add(new JMenuItem(new MultipolyAction()));
     34            Main.main.menu.add(toolsMenu, 2);
     35        } else {
     36            toolsMenu.addSeparator();
     37            toolsMenu.add(new JMenuItem(new MultipolyAction()));
     38        }
     39    }
    4040}
  • applications/editors/josm/plugins/remotecontrol/src/org/openstreetmap/josm/plugins/remotecontrol/PermissionPref.java

    r22733 r23189  
    77 *
    88 * Use @see PermissionPrefWithDefault instead of this class.
    9  * 
     9 *
    1010 * @author Bodo Meissner
    1111 */
    1212 @Deprecated
    1313public class PermissionPref {
    14         /** name of the preference setting to permit the remote operation */
    15         String pref;
    16         /** message to be displayed if operation is not permitted */
    17         String message;
    18        
    19         public PermissionPref(String pref, String message)
    20         {
    21                 this.pref = pref;
    22                 this.message = message;
    23         }
     14    /** name of the preference setting to permit the remote operation */
     15    String pref;
     16    /** message to be displayed if operation is not permitted */
     17    String message;
     18
     19    public PermissionPref(String pref, String message)
     20    {
     21        this.pref = pref;
     22        this.message = message;
     23    }
    2424}
  • applications/editors/josm/plugins/remotecontrol/src/org/openstreetmap/josm/plugins/remotecontrol/PermissionPrefWithDefault.java

    r22733 r23189  
    22
    33/**
    4  * This class should replace PermissionPref because it allows explicit 
     4 * This class should replace PermissionPref because it allows explicit
    55 * specification of the permission's default value.
    6  * 
     6 *
    77 * @author Bodo Meissner
    88 */
     
    1010public class PermissionPrefWithDefault extends PermissionPref {
    1111
    12         boolean defaultVal = true;
     12    boolean defaultVal = true;
    1313
    14         public PermissionPrefWithDefault(String pref, boolean defaultVal, String message) {
    15                 super(pref, message);
    16                 this.defaultVal = defaultVal;
    17         }
     14    public PermissionPrefWithDefault(String pref, boolean defaultVal, String message) {
     15        super(pref, message);
     16        this.defaultVal = defaultVal;
     17    }
    1818
    19         public PermissionPrefWithDefault(PermissionPref prefWithoutDefault) {
    20                 super(prefWithoutDefault.pref, prefWithoutDefault.message);
    21         }
     19    public PermissionPrefWithDefault(PermissionPref prefWithoutDefault) {
     20        super(prefWithoutDefault.pref, prefWithoutDefault.message);
     21    }
    2222}
  • applications/editors/josm/plugins/remotecontrol/src/org/openstreetmap/josm/plugins/remotecontrol/RemoteControlPlugin.java

    r22733 r23189  
    88
    99/**
    10  * Base plugin for remote control operations. 
     10 * Base plugin for remote control operations.
    1111 * This plugin contains operations that use JOSM core only.
    12  * 
    13  * Other plugins can register additional operations by calling 
     12 *
     13 * Other plugins can register additional operations by calling
    1414 * @see addRequestHandler().
    1515 * To allow API changes this plugin contains a @see getVersion() method.
    16  * 
     16 *
    1717 * IMPORTANT! increment the minor version on compatible API extensions
    1818 * and increment the major version and set minor to 0 on incompatible changes.
     
    2020public class RemoteControlPlugin extends Plugin
    2121{
    22         /** API version
    23         * IMPORTANT! update the version number on API changes.
    24         */
    25         static final int apiMajorVersion = 1;
    26         static final int apiMinorVersion = 0;
    27        
    28         /**
    29         * RemoteControl HTTP protocol version. Change minor number for compatible
    30         * interface extensions. Change major number in case of incompatible
    31         * changes.
    32         */
    33         static final int protocolMajorVersion = 1;
    34         static final int protocolMinorVersion = 2;
    35        
     22    /** API version
     23    * IMPORTANT! update the version number on API changes.
     24    */
     25    static final int apiMajorVersion = 1;
     26    static final int apiMinorVersion = 0;
     27
     28    /**
     29    * RemoteControl HTTP protocol version. Change minor number for compatible
     30    * interface extensions. Change major number in case of incompatible
     31    * changes.
     32    */
     33    static final int protocolMajorVersion = 1;
     34    static final int protocolMinorVersion = 2;
     35
    3636    /** The HTTP server this plugin launches */
    3737    static HttpServer server;
    3838
    3939    /**
    40      * Returns an array of int values with major and minor API version 
     40     * Returns an array of int values with major and minor API version
    4141     * and major and minor HTTP protocol version.
    42      * 
     42     *
    4343     * The function returns an int[4] instead of an object with fields
    4444     * to avoid ClassNotFound errors with old versions of remotecontrol.
    45      * 
    46      * @return array of integer version numbers: 
     45     *
     46     * @return array of integer version numbers:
    4747     *    apiMajorVersion, apiMinorVersion, protocolMajorVersion, protocolMajorVersion
    4848     */
    4949    public int[] getVersion()
    5050    {
    51         int versions[] = {apiMajorVersion, apiMinorVersion, protocolMajorVersion, protocolMajorVersion};
    52         return versions;
     51        int versions[] = {apiMajorVersion, apiMinorVersion, protocolMajorVersion, protocolMajorVersion};
     52        return versions;
    5353    }
    54    
     54
    5555    /**
    5656     * Creates the plugin, and starts the HTTP server
     
    5858    public RemoteControlPlugin(PluginInformation info)
    5959    {
    60         super(info);
    61         /*
    62                 System.out.println("constructor " + this.getClass().getName() + " (" + info.name +
    63                                 " v " + info.version + " stage " + info.stage + ")");
    64                 */
     60        super(info);
     61        /*
     62        System.out.println("constructor " + this.getClass().getName() + " (" + info.name +
     63                " v " + info.version + " stage " + info.stage + ")");
     64        */
    6565        restartServer();
    6666    }
     
    103103        RequestProcessor.addRequestHandlerClass(command, handlerClass);
    104104    }
    105    
     105
    106106}
  • applications/editors/josm/plugins/remotecontrol/src/org/openstreetmap/josm/plugins/remotecontrol/RequestHandler.java

    r22733 r23189  
    1111
    1212/**
    13  * This is the parent of all classes that handle a specific command 
     13 * This is the parent of all classes that handle a specific command
    1414 * in remote control plug-in.
    15  *   
     15 *
    1616 * @author Bodo Meissner
    1717 */
    1818public abstract class RequestHandler
    1919{
    20         public static final String globalConfirmationKey = "remotecontrol.always-confirm";
    21         public static final boolean globalConfirmationDefault = false;
    22        
    23         /** The GET request arguments */
    24         protected HashMap<String,String> args;
    25        
    26         /** The request URL without "GET". */
     20    public static final String globalConfirmationKey = "remotecontrol.always-confirm";
     21    public static final boolean globalConfirmationDefault = false;
     22
     23    /** The GET request arguments */
     24    protected HashMap<String,String> args;
     25
     26    /** The request URL without "GET". */
    2727    protected String request;
    2828
     
    3434    /** will be filled with the command assigned to the subclass */
    3535    protected String myCommand;
    36    
     36
    3737    /**
    3838     * Check permission and parameters and handle request.
    39      * 
     39     *
    4040     * @throws RequestHandlerForbiddenException
    4141     * @throws RequestHandlerBadRequestException
     
    4444    final void handle() throws RequestHandlerForbiddenException, RequestHandlerBadRequestException, RequestHandlerErrorException
    4545    {
    46         checkPermission();
    47         checkMandatoryParams();
    48         handleRequest();
    49     }
    50    
     46        checkPermission();
     47        checkMandatoryParams();
     48        handleRequest();
     49    }
     50
    5151    /**
    5252     * Handle a specific command sent as remote control.
    53      * 
    54      * This method of the subclass will do the real work. 
    55      * 
     53     *
     54     * This method of the subclass will do the real work.
     55     *
    5656     * @throws RequestHandlerErrorException
    57      * @throws RequestHandlerBadRequestException 
     57     * @throws RequestHandlerBadRequestException
    5858     */
    5959    protected abstract void handleRequest() throws RequestHandlerErrorException, RequestHandlerBadRequestException;
     
    6262     * Get a specific message to ask the user for permission for the operation
    6363     * requested via remote control.
    64      * 
     64     *
    6565     * This message will be displayed to the user if the preference
    6666     * remotecontrol.always-confirm is true.
    67      * 
     67     *
    6868     * @return the message
    6969     */
     
    7474     * preference to individually allow the requested operation and an error
    7575     * message to be displayed when a disabled operation is requested.
    76      * 
    77      * Default is not to check any special preference. Override this in a 
     76     *
     77     * Default is not to check any special preference. Override this in a
    7878     * subclass to define permission preference and error message.
    79      * 
     79     *
    8080     * @return the preference name and error message or null
    8181     */
    82         @SuppressWarnings("deprecation")
    83         public PermissionPref getPermissionPref()
     82    @SuppressWarnings("deprecation")
     83    public PermissionPref getPermissionPref()
    8484    {
    8585        /* Example:
     
    9393    protected String[] getMandatoryParams()
    9494    {
    95         return null;
    96     }
    97    
    98     /**
    99      * Check permissions in preferences and display error message 
     95        return null;
     96    }
     97
     98    /**
     99     * Check permissions in preferences and display error message
    100100     * or ask for permission.
    101      * 
     101     *
    102102     * @throws RequestHandlerForbiddenException
    103103     */
    104104    @SuppressWarnings("deprecation")
    105         final public void checkPermission() throws RequestHandlerForbiddenException
    106     {
    107         /* 
     105    final public void checkPermission() throws RequestHandlerForbiddenException
     106    {
     107        /*
    108108         * If the subclass defines a specific preference and if this is set
    109109         * to false, abort with an error message.
    110          * 
     110         *
    111111         * Note: we use the deprecated class here for compatibility with
    112112         * older versions of WMSPlugin.
     
    118118            if(permissionPref instanceof PermissionPrefWithDefault)
    119119            {
    120                 permissionPrefWithDefault = (PermissionPrefWithDefault) permissionPref;
    121             }
    122             else 
     120                permissionPrefWithDefault = (PermissionPrefWithDefault) permissionPref;
     121            }
     122            else
    123123            {
    124                 permissionPrefWithDefault = new PermissionPrefWithDefault(permissionPref);
     124                permissionPrefWithDefault = new PermissionPrefWithDefault(permissionPref);
    125125            }
    126126            if (!Main.pref.getBoolean(permissionPrefWithDefault.pref,
    127                         permissionPrefWithDefault.defaultVal)) {
     127                    permissionPrefWithDefault.defaultVal)) {
    128128                System.out.println(permissionPrefWithDefault.message);
    129129                throw new RequestHandlerForbiddenException();
     
    147147    /**
    148148     * Set request URL and parse args.
    149      * 
     149     *
    150150     * @param url The request URL.
    151151     */
    152         public void setUrl(String url) {
    153                 this.request = url;
    154                 parseArgs();
    155         }
    156 
    157         /**
    158         * Parse the request parameters as key=value pairs.
    159         * The result will be stored in this.args.
    160          *
    161         * Can be overridden by subclass.
    162         */
    163         protected void parseArgs() {
    164                 StringTokenizer st = new StringTokenizer(this.request, "&?");
    165                 HashMap<String, String> args = new HashMap<String, String>();
    166                 // ignore first token which is the command
    167                 if(st.hasMoreTokens()) st.nextToken();
    168                 while (st.hasMoreTokens()) {
    169                         String param = st.nextToken();
    170                         int eq = param.indexOf("=");
    171                         if (eq > -1)
    172                                 args.put(param.substring(0, eq),
     152    public void setUrl(String url) {
     153        this.request = url;
     154        parseArgs();
     155    }
     156
     157    /**
     158    * Parse the request parameters as key=value pairs.
     159    * The result will be stored in this.args.
     160     *
     161    * Can be overridden by subclass.
     162    */
     163    protected void parseArgs() {
     164        StringTokenizer st = new StringTokenizer(this.request, "&?");
     165        HashMap<String, String> args = new HashMap<String, String>();
     166        // ignore first token which is the command
     167        if(st.hasMoreTokens()) st.nextToken();
     168        while (st.hasMoreTokens()) {
     169            String param = st.nextToken();
     170            int eq = param.indexOf("=");
     171            if (eq > -1)
     172                args.put(param.substring(0, eq),
    173173                         param.substring(eq + 1));
    174                 }
    175                 this.args = args;
    176         }
    177        
    178         void checkMandatoryParams() throws RequestHandlerBadRequestException
    179         {
    180                 String[] mandatory = getMandatoryParams();
    181                 if(mandatory == null) return;
    182                
    183                 boolean error = false;
    184                 for(int i = 0; i < mandatory.length; ++i)
    185                 {
    186                         String key = mandatory[i];
    187                         String value = args.get(key);
    188                         if((value == null) || (value.length() == 0))
    189                         {
    190                                 error = true;
    191                                 System.out.println("'" + myCommand + "' remote control request must have '" + key + "' parameter");
    192                         }
    193                 }
    194                 if(error) throw new RequestHandlerBadRequestException();
    195         }
    196        
    197         /**
    198         * Save command associated with this handler.
    199          *
    200         * @param command The command.
    201         */
    202         public void setCommand(String command)
    203         {
    204                 if(command.charAt(0) == '/') command = command.substring(1);
    205                 myCommand = command;
    206         }
     174        }
     175        this.args = args;
     176    }
     177
     178    void checkMandatoryParams() throws RequestHandlerBadRequestException
     179    {
     180        String[] mandatory = getMandatoryParams();
     181        if(mandatory == null) return;
     182
     183        boolean error = false;
     184        for(int i = 0; i < mandatory.length; ++i)
     185        {
     186            String key = mandatory[i];
     187            String value = args.get(key);
     188            if((value == null) || (value.length() == 0))
     189            {
     190                error = true;
     191                System.out.println("'" + myCommand + "' remote control request must have '" + key + "' parameter");
     192            }
     193        }
     194        if(error) throw new RequestHandlerBadRequestException();
     195    }
     196
     197    /**
     198    * Save command associated with this handler.
     199     *
     200    * @param command The command.
     201    */
     202    public void setCommand(String command)
     203    {
     204        if(command.charAt(0) == '/') command = command.substring(1);
     205        myCommand = command;
     206    }
    207207}
  • applications/editors/josm/plugins/remotecontrol/src/org/openstreetmap/josm/plugins/remotecontrol/RequestHandlerForbiddenException.java

    r22675 r23189  
    22
    33public class RequestHandlerForbiddenException extends RequestHandlerException {
    4         private static final long serialVersionUID = 2263904699747115423L;
     4    private static final long serialVersionUID = 2263904699747115423L;
    55}
  • applications/editors/josm/plugins/remotecontrol/src/org/openstreetmap/josm/plugins/remotecontrol/RequestProcessor.java

    r22734 r23189  
    2323 */
    2424public class RequestProcessor extends Thread {
    25         /**
    26         * RemoteControl protocol version. Change minor number for compatible
    27         * interface extensions. Change major number in case of incompatible
    28         * changes.
    29         */
    30         public static final String PROTOCOLVERSION = "{\"protocolversion\": {\"major\": " +
    31                 RemoteControlPlugin.protocolMajorVersion + ", \"minor\": " +
    32                 RemoteControlPlugin.protocolMinorVersion +
    33                 "}, \"application\": \"JOSM RemoteControl\"}";
    34 
    35         /** The socket this processor listens on */
    36         private Socket request;
    37 
    38         /**
    39         * Collection of request handlers.
    40         * Will be initialized with default handlers here. Other plug-ins
    41          * can extend this list by using @see addRequestHandler
    42         */
    43         private static HashMap<String, Class<? extends RequestHandler>> handlers = new HashMap<String, Class<? extends RequestHandler>>();
    44 
    45         /**
    46         * Constructor
    47          *
    48         * @param request A socket to read the request.
    49         */
    50         public RequestProcessor(Socket request) {
    51                 super("RemoteControl request processor");
    52                 this.setDaemon(true);
    53                 this.request = request;
    54         }
    55 
    56         /**
    57         * Spawns a new thread for the request
    58          *
    59         * @param request
    60         *            The WMS request
    61         */
    62         public static void processRequest(Socket request) {
    63                 RequestProcessor processor = new RequestProcessor(request);
    64                 processor.start();
    65         }
    66 
    67         /**
    68         * Add external request handler. Can be used by other plug-ins that
    69         * want to use remote control.
    70         * @param command The command to handle.
    71         * @param handler The additional request handler.
    72         */
    73         static void addRequestHandlerClass(String command,
    74                         Class<? extends RequestHandler> handler) {
    75                 addRequestHandlerClass(command, handler, false);
    76         }
    77 
    78         /**
    79         * Add external request handler. Message can be suppressed.
    80         * (for internal use)
    81         * @param command The command to handle.
    82         * @param handler The additional request handler.
    83         * @param silent Don't show message if true.
    84         */
    85         private static void addRequestHandlerClass(String command,
    86                                 Class<? extends RequestHandler> handler, boolean silent) {
    87                 if(command.charAt(0) == '/')
    88                 {
    89                         command = command.substring(1);
    90                 }
    91                 String commandWithSlash = "/" + command;
    92                 if (handlers.get(commandWithSlash) != null) {
    93                         System.out.println("RemoteControl: ignoring duplicate command " + command
    94                                         + " with handler " + handler.getName());
    95                 } else {
    96                         if(!silent) System.out.println("RemoteControl: adding command \"" +
    97                                         command + "\" (handled by " + handler.getSimpleName() + ")");
    98                         handlers.put(commandWithSlash, handler);
    99                 }
    100         }
    101 
    102         /** Add default request handlers */
    103         static {
    104                 addRequestHandlerClass(LoadAndZoomHandler.command,
    105                                 LoadAndZoomHandler.class, true);
    106                 addRequestHandlerClass(LoadAndZoomHandler.command2,
    107                                 LoadAndZoomHandler.class, true);
    108                 addRequestHandlerClass(AddNodeHandler.command, AddNodeHandler.class, true);
    109                 addRequestHandlerClass(ImportHandler.command, ImportHandler.class, true);
    110                 addRequestHandlerClass(VersionHandler.command, VersionHandler.class, true);
    111         }
    112 
    113         /**
    114         * The work is done here.
    115         */
    116         public void run() {
    117                 Writer out = null;
    118                 try {
    119                         OutputStream raw = new BufferedOutputStream(
    120                                         request.getOutputStream());
    121                         out = new OutputStreamWriter(raw);
    122                         Reader in = new InputStreamReader(new BufferedInputStream(
    123                                         request.getInputStream()), "ASCII");
    124 
    125                         StringBuffer requestLine = new StringBuffer();
    126                         while (requestLine.length() < 1024) {
    127                                 int c = in.read();
    128                                 if (c == '\r' || c == '\n')
    129                                         break;
    130                                 requestLine.append((char) c);
    131                         }
    132 
    133                         System.out.println("RemoteControl received: " + requestLine);
    134                         String get = requestLine.toString();
    135                         StringTokenizer st = new StringTokenizer(get);
    136                         if (!st.hasMoreTokens()) {
    137                                 sendError(out);
    138                                 return;
    139                         }
    140                         String method = st.nextToken();
    141                         if (!st.hasMoreTokens()) {
    142                                 sendError(out);
    143                                 return;
    144                         }
    145                         String url = st.nextToken();
    146 
    147                         if (!method.equals("GET")) {
    148                                 sendNotImplemented(out);
    149                                 return;
    150                         }
    151 
    152                         String command = null;
    153                         int questionPos = url.indexOf('?');
    154                         if(questionPos < 0)
    155                         {
    156                                 command = url;
    157                         }
    158                         else
    159                         {
    160                                 command = url.substring(0, questionPos);
    161                         }
    162 
    163                         // find a handler for this command
    164                         Class<? extends RequestHandler> handlerClass = handlers
    165                                         .get(command);
    166                         if (handlerClass == null) {
    167                                 // no handler found
    168                                 sendBadRequest(out);
    169                         } else {
    170                                 // create handler object
    171                                 RequestHandler handler = handlerClass.newInstance();
    172                                 try {
    173                                         handler.setCommand(command);
    174                                         handler.setUrl(url);
    175                                         handler.checkPermission();
    176                                         handler.handle();
    177                                         sendHeader(out, "200 OK", handler.contentType, false);
    178                                         out.write("Content-length: " + handler.content.length()
    179                                                         + "\r\n");
    180                                         out.write("\r\n");
    181                                         out.write(handler.content);
    182                                         out.flush();
    183                                 } catch (RequestHandlerErrorException ex) {
    184                                         sendError(out);
    185                                 } catch (RequestHandlerBadRequestException ex) {
    186                                         sendBadRequest(out);
    187                                 } catch (RequestHandlerForbiddenException ex) {
    188                                         sendForbidden(out);
    189                                 }
    190                         }
    191 
    192                 } catch (IOException ioe) {
    193                 } catch (Exception e) {
    194                         e.printStackTrace();
    195                         try {
    196                                 sendError(out);
    197                         } catch (IOException e1) {
    198                         }
    199                 } finally {
    200                         try {
    201                                 request.close();
    202                         } catch (IOException e) {
    203                         }
    204                 }
    205         }
    206 
    207         /**
    208         * Sends a 500 error: server error
    209          *
    210         * @param out
    211         *            The writer where the error is written
    212         * @throws IOException
    213         *             If the error can not be written
    214         */
    215         private void sendError(Writer out) throws IOException {
    216                 sendHeader(out, "500 Internal Server Error", "text/html", true);
    217                 out.write("<HTML>\r\n");
    218                 out.write("<HEAD><TITLE>Internal Error</TITLE>\r\n");
    219                 out.write("</HEAD>\r\n");
    220                 out.write("<BODY>");
    221                 out.write("<H1>HTTP Error 500: Internal Server Error</h2>\r\n");
    222                 out.write("</BODY></HTML>\r\n");
    223                 out.flush();
    224         }
    225 
    226         /**
    227         * Sends a 501 error: not implemented
    228          *
    229         * @param out
    230         *            The writer where the error is written
    231         * @throws IOException
    232         *             If the error can not be written
    233         */
    234         private void sendNotImplemented(Writer out) throws IOException {
    235                 sendHeader(out, "501 Not Implemented", "text/html", true);
    236                 out.write("<HTML>\r\n");
    237                 out.write("<HEAD><TITLE>Not Implemented</TITLE>\r\n");
    238                 out.write("</HEAD>\r\n");
    239                 out.write("<BODY>");
    240                 out.write("<H1>HTTP Error 501: Not Implemented</h2>\r\n");
    241                 out.write("</BODY></HTML>\r\n");
    242                 out.flush();
    243         }
    244 
    245         /**
    246         * Sends a 403 error: forbidden
    247          *
    248         * @param out
    249         *            The writer where the error is written
    250         * @throws IOException
    251         *             If the error can not be written
    252         */
    253         private void sendForbidden(Writer out) throws IOException {
    254                 sendHeader(out, "403 Forbidden", "text/html", true);
    255                 out.write("<HTML>\r\n");
    256                 out.write("<HEAD><TITLE>Forbidden</TITLE>\r\n");
    257                 out.write("</HEAD>\r\n");
    258                 out.write("<BODY>");
    259                 out.write("<H1>HTTP Error 403: Forbidden</h2>\r\n");
    260                 out.write("</BODY></HTML>\r\n");
    261                 out.flush();
    262         }
    263 
    264         /**
    265         * Sends a 403 error: forbidden
    266          *
    267         * @param out
    268         *            The writer where the error is written
    269         * @throws IOException
    270         *             If the error can not be written
    271         */
    272         private void sendBadRequest(Writer out) throws IOException {
    273                 sendHeader(out, "400 Bad Request", "text/html", true);
    274                 out.write("<HTML>\r\n");
    275                 out.write("<HEAD><TITLE>Bad Request</TITLE>\r\n");
    276                 out.write("</HEAD>\r\n");
    277                 out.write("<BODY>");
    278                 out.write("<H1>HTTP Error 400: Bad Request</h2>\r\n");
    279                 out.write("</BODY></HTML>\r\n");
    280                 out.flush();
    281         }
    282 
    283         /**
    284         * Send common HTTP headers to the client.
    285          *
    286         * @param out
    287         *            The Writer
    288         * @param status
    289         *            The status string ("200 OK", "500", etc)
    290         * @param contentType
    291         *            The content type of the data sent
    292         * @param endHeaders
    293         *            If true, adds a new line, ending the headers.
    294         * @throws IOException
    295         *             When error
    296         */
    297         private void sendHeader(Writer out, String status, String contentType,
    298                         boolean endHeaders) throws IOException {
    299                 out.write("HTTP/1.1 " + status + "\r\n");
    300                 Date now = new Date();
    301                 out.write("Date: " + now + "\r\n");
    302                 out.write("Server: JOSM RemoteControl\r\n");
    303                 out.write("Content-type: " + contentType + "\r\n");
    304                 out.write("Access-Control-Allow-Origin: *\r\n");
    305                 if (endHeaders)
    306                         out.write("\r\n");
    307         }
     25    /**
     26    * RemoteControl protocol version. Change minor number for compatible
     27    * interface extensions. Change major number in case of incompatible
     28    * changes.
     29    */
     30    public static final String PROTOCOLVERSION = "{\"protocolversion\": {\"major\": " +
     31        RemoteControlPlugin.protocolMajorVersion + ", \"minor\": " +
     32        RemoteControlPlugin.protocolMinorVersion +
     33        "}, \"application\": \"JOSM RemoteControl\"}";
     34
     35    /** The socket this processor listens on */
     36    private Socket request;
     37
     38    /**
     39    * Collection of request handlers.
     40    * Will be initialized with default handlers here. Other plug-ins
     41     * can extend this list by using @see addRequestHandler
     42    */
     43    private static HashMap<String, Class<? extends RequestHandler>> handlers = new HashMap<String, Class<? extends RequestHandler>>();
     44
     45    /**
     46    * Constructor
     47     *
     48    * @param request A socket to read the request.
     49    */
     50    public RequestProcessor(Socket request) {
     51        super("RemoteControl request processor");
     52        this.setDaemon(true);
     53        this.request = request;
     54    }
     55
     56    /**
     57    * Spawns a new thread for the request
     58     *
     59    * @param request
     60    *            The WMS request
     61    */
     62    public static void processRequest(Socket request) {
     63        RequestProcessor processor = new RequestProcessor(request);
     64        processor.start();
     65    }
     66
     67    /**
     68    * Add external request handler. Can be used by other plug-ins that
     69    * want to use remote control.
     70    * @param command The command to handle.
     71    * @param handler The additional request handler.
     72    */
     73    static void addRequestHandlerClass(String command,
     74            Class<? extends RequestHandler> handler) {
     75        addRequestHandlerClass(command, handler, false);
     76    }
     77
     78    /**
     79    * Add external request handler. Message can be suppressed.
     80    * (for internal use)
     81    * @param command The command to handle.
     82    * @param handler The additional request handler.
     83    * @param silent Don't show message if true.
     84    */
     85    private static void addRequestHandlerClass(String command,
     86                Class<? extends RequestHandler> handler, boolean silent) {
     87        if(command.charAt(0) == '/')
     88        {
     89            command = command.substring(1);
     90        }
     91        String commandWithSlash = "/" + command;
     92        if (handlers.get(commandWithSlash) != null) {
     93            System.out.println("RemoteControl: ignoring duplicate command " + command
     94                    + " with handler " + handler.getName());
     95        } else {
     96            if(!silent) System.out.println("RemoteControl: adding command \"" +
     97                    command + "\" (handled by " + handler.getSimpleName() + ")");
     98            handlers.put(commandWithSlash, handler);
     99        }
     100    }
     101
     102    /** Add default request handlers */
     103    static {
     104        addRequestHandlerClass(LoadAndZoomHandler.command,
     105                LoadAndZoomHandler.class, true);
     106        addRequestHandlerClass(LoadAndZoomHandler.command2,
     107                LoadAndZoomHandler.class, true);
     108        addRequestHandlerClass(AddNodeHandler.command, AddNodeHandler.class, true);
     109        addRequestHandlerClass(ImportHandler.command, ImportHandler.class, true);
     110        addRequestHandlerClass(VersionHandler.command, VersionHandler.class, true);
     111    }
     112
     113    /**
     114    * The work is done here.
     115    */
     116    public void run() {
     117        Writer out = null;
     118        try {
     119            OutputStream raw = new BufferedOutputStream(
     120                    request.getOutputStream());
     121            out = new OutputStreamWriter(raw);
     122            Reader in = new InputStreamReader(new BufferedInputStream(
     123                    request.getInputStream()), "ASCII");
     124
     125            StringBuffer requestLine = new StringBuffer();
     126            while (requestLine.length() < 1024) {
     127                int c = in.read();
     128                if (c == '\r' || c == '\n')
     129                    break;
     130                requestLine.append((char) c);
     131            }
     132
     133            System.out.println("RemoteControl received: " + requestLine);
     134            String get = requestLine.toString();
     135            StringTokenizer st = new StringTokenizer(get);
     136            if (!st.hasMoreTokens()) {
     137                sendError(out);
     138                return;
     139            }
     140            String method = st.nextToken();
     141            if (!st.hasMoreTokens()) {
     142                sendError(out);
     143                return;
     144            }
     145            String url = st.nextToken();
     146
     147            if (!method.equals("GET")) {
     148                sendNotImplemented(out);
     149                return;
     150            }
     151
     152            String command = null;
     153            int questionPos = url.indexOf('?');
     154            if(questionPos < 0)
     155            {
     156                command = url;
     157            }
     158            else
     159            {
     160                command = url.substring(0, questionPos);
     161            }
     162
     163            // find a handler for this command
     164            Class<? extends RequestHandler> handlerClass = handlers
     165                    .get(command);
     166            if (handlerClass == null) {
     167                // no handler found
     168                sendBadRequest(out);
     169            } else {
     170                // create handler object
     171                RequestHandler handler = handlerClass.newInstance();
     172                try {
     173                    handler.setCommand(command);
     174                    handler.setUrl(url);
     175                    handler.checkPermission();
     176                    handler.handle();
     177                    sendHeader(out, "200 OK", handler.contentType, false);
     178                    out.write("Content-length: " + handler.content.length()
     179                            + "\r\n");
     180                    out.write("\r\n");
     181                    out.write(handler.content);
     182                    out.flush();
     183                } catch (RequestHandlerErrorException ex) {
     184                    sendError(out);
     185                } catch (RequestHandlerBadRequestException ex) {
     186                    sendBadRequest(out);
     187                } catch (RequestHandlerForbiddenException ex) {
     188                    sendForbidden(out);
     189                }
     190            }
     191
     192        } catch (IOException ioe) {
     193        } catch (Exception e) {
     194            e.printStackTrace();
     195            try {
     196                sendError(out);
     197            } catch (IOException e1) {
     198            }
     199        } finally {
     200            try {
     201                request.close();
     202            } catch (IOException e) {
     203            }
     204        }
     205    }
     206
     207    /**
     208    * Sends a 500 error: server error
     209     *
     210    * @param out
     211    *            The writer where the error is written
     212    * @throws IOException
     213    *             If the error can not be written
     214    */
     215    private void sendError(Writer out) throws IOException {
     216        sendHeader(out, "500 Internal Server Error", "text/html", true);
     217        out.write("<HTML>\r\n");
     218        out.write("<HEAD><TITLE>Internal Error</TITLE>\r\n");
     219        out.write("</HEAD>\r\n");
     220        out.write("<BODY>");
     221        out.write("<H1>HTTP Error 500: Internal Server Error</h2>\r\n");
     222        out.write("</BODY></HTML>\r\n");
     223        out.flush();
     224    }
     225
     226    /**
     227    * Sends a 501 error: not implemented
     228     *
     229    * @param out
     230    *            The writer where the error is written
     231    * @throws IOException
     232    *             If the error can not be written
     233    */
     234    private void sendNotImplemented(Writer out) throws IOException {
     235        sendHeader(out, "501 Not Implemented", "text/html", true);
     236        out.write("<HTML>\r\n");
     237        out.write("<HEAD><TITLE>Not Implemented</TITLE>\r\n");
     238        out.write("</HEAD>\r\n");
     239        out.write("<BODY>");
     240        out.write("<H1>HTTP Error 501: Not Implemented</h2>\r\n");
     241        out.write("</BODY></HTML>\r\n");
     242        out.flush();
     243    }
     244
     245    /**
     246    * Sends a 403 error: forbidden
     247     *
     248    * @param out
     249    *            The writer where the error is written
     250    * @throws IOException
     251    *             If the error can not be written
     252    */
     253    private void sendForbidden(Writer out) throws IOException {
     254        sendHeader(out, "403 Forbidden", "text/html", true);
     255        out.write("<HTML>\r\n");
     256        out.write("<HEAD><TITLE>Forbidden</TITLE>\r\n");
     257        out.write("</HEAD>\r\n");
     258        out.write("<BODY>");
     259        out.write("<H1>HTTP Error 403: Forbidden</h2>\r\n");
     260        out.write("</BODY></HTML>\r\n");
     261        out.flush();
     262    }
     263
     264    /**
     265    * Sends a 403 error: forbidden
     266     *
     267    * @param out
     268    *            The writer where the error is written
     269    * @throws IOException
     270    *             If the error can not be written
     271    */
     272    private void sendBadRequest(Writer out) throws IOException {
     273        sendHeader(out, "400 Bad Request", "text/html", true);
     274        out.write("<HTML>\r\n");
     275        out.write("<HEAD><TITLE>Bad Request</TITLE>\r\n");
     276        out.write("</HEAD>\r\n");
     277        out.write("<BODY>");
     278        out.write("<H1>HTTP Error 400: Bad Request</h2>\r\n");
     279        out.write("</BODY></HTML>\r\n");
     280        out.flush();
     281    }
     282
     283    /**
     284    * Send common HTTP headers to the client.
     285     *
     286    * @param out
     287    *            The Writer
     288    * @param status
     289    *            The status string ("200 OK", "500", etc)
     290    * @param contentType
     291    *            The content type of the data sent
     292    * @param endHeaders
     293    *            If true, adds a new line, ending the headers.
     294    * @throws IOException
     295    *             When error
     296    */
     297    private void sendHeader(Writer out, String status, String contentType,
     298            boolean endHeaders) throws IOException {
     299        out.write("HTTP/1.1 " + status + "\r\n");
     300        Date now = new Date();
     301        out.write("Date: " + now + "\r\n");
     302        out.write("Server: JOSM RemoteControl\r\n");
     303        out.write("Content-type: " + contentType + "\r\n");
     304        out.write("Access-Control-Allow-Origin: *\r\n");
     305        if (endHeaders)
     306            out.write("\r\n");
     307    }
    308308}
  • applications/editors/josm/plugins/remotecontrol/src/org/openstreetmap/josm/plugins/remotecontrol/handler/AddNodeHandler.java

    r22733 r23189  
    1717public class AddNodeHandler extends RequestHandler {
    1818
    19         public static final String command = "add_node";
    20         public static final String permissionKey = "remotecontrol.permission.create-objects";
    21         public static final boolean permissionDefault = false;
     19    public static final String command = "add_node";
     20    public static final String permissionKey = "remotecontrol.permission.create-objects";
     21    public static final boolean permissionDefault = false;
    2222
    23         @Override
    24         protected void handleRequest() {
     23    @Override
     24    protected void handleRequest() {
    2525        addNode(args);
    26         }
     26    }
    2727
    28         @Override
    29         protected String[] getMandatoryParams()
    30         {
    31                 return new String[] { "lat", "lon" };
    32         }
    33        
    34         @Override
    35         public String getPermissionMessage() {
    36                 return tr("Remote Control has been asked to create a new node.");
    37         }
     28    @Override
     29    protected String[] getMandatoryParams()
     30    {
     31        return new String[] { "lat", "lon" };
     32    }
    3833
    39         @Override
    40         public PermissionPrefWithDefault getPermissionPref()
    41         {
    42                 return new PermissionPrefWithDefault(permissionKey, permissionDefault,
    43                                 "RemoteControl: creating objects forbidden by preferences");
    44         }
    45        
     34    @Override
     35    public String getPermissionMessage() {
     36        return tr("Remote Control has been asked to create a new node.");
     37    }
     38
     39    @Override
     40    public PermissionPrefWithDefault getPermissionPref()
     41    {
     42        return new PermissionPrefWithDefault(permissionKey, permissionDefault,
     43                "RemoteControl: creating objects forbidden by preferences");
     44    }
     45
    4646    /**
    4747     * Adds a node, implements the GET /add_node?lon=...&amp;lat=... request.
  • applications/editors/josm/plugins/remotecontrol/src/org/openstreetmap/josm/plugins/remotecontrol/handler/ImportHandler.java

    r22733 r23189  
    1616public class ImportHandler extends RequestHandler {
    1717
    18         public static final String command = "import";
    19         public static final String permissionKey = "remotecontrol.permission.import";
    20         public static final boolean permissionDefault = true;
     18    public static final String command = "import";
     19    public static final String permissionKey = "remotecontrol.permission.import";
     20    public static final boolean permissionDefault = true;
    2121
    22         @Override
    23         protected void handleRequest() throws RequestHandlerErrorException {
     22    @Override
     23    protected void handleRequest() throws RequestHandlerErrorException {
    2424        try {
    2525            DownloadTask osmTask = new DownloadOsmTask();
     
    3030            throw new RequestHandlerErrorException();
    3131        }
    32         }
     32    }
    3333
    34         @Override
    35         protected String[] getMandatoryParams()
    36         {
    37                 return new String[] { "url" };
    38         }
    39        
    40         @Override
    41         public String getPermissionMessage() {
    42                 return tr("Remote Control has been asked to import data from the following URL:") +
     34    @Override
     35    protected String[] getMandatoryParams()
     36    {
     37        return new String[] { "url" };
     38    }
     39
     40    @Override
     41    public String getPermissionMessage() {
     42        return tr("Remote Control has been asked to import data from the following URL:") +
    4343        "<br>" + request;
    44         }
     44    }
    4545
    46         @Override
    47         public PermissionPrefWithDefault getPermissionPref()
    48         {
    49                 return new PermissionPrefWithDefault(permissionKey, permissionDefault,
    50                                 "RemoteControl: import forbidden by preferences");
    51         }
     46    @Override
     47    public PermissionPrefWithDefault getPermissionPref()
     48    {
     49        return new PermissionPrefWithDefault(permissionKey, permissionDefault,
     50                "RemoteControl: import forbidden by preferences");
     51    }
    5252}
  • applications/editors/josm/plugins/remotecontrol/src/org/openstreetmap/josm/plugins/remotecontrol/handler/LoadAndZoomHandler.java

    r22733 r23189  
    2929public class LoadAndZoomHandler extends RequestHandler
    3030{
    31         public static final String command = "load_and_zoom";
    32         public static final String command2 = "zoom";
    33        
    34         public static final String loadDataPermissionKey = "remotecontrol.permission.load-data";
    35         public static final boolean loadDataPermissionDefault = true;
    36         public static final String changeSelectionPermissionKey = "remotecontrol.permission.change-selection";
    37         public static final boolean changeSelectionPermissionDefault = true;
    38         public static final String changeViewportPermissionKey = "remotecontrol.permission.change-viewport";
    39         public static final boolean changeViewportPermissionDefault = true;
    40        
     31    public static final String command = "load_and_zoom";
     32    public static final String command2 = "zoom";
     33
     34    public static final String loadDataPermissionKey = "remotecontrol.permission.load-data";
     35    public static final boolean loadDataPermissionDefault = true;
     36    public static final String changeSelectionPermissionKey = "remotecontrol.permission.change-selection";
     37    public static final boolean changeSelectionPermissionDefault = true;
     38    public static final String changeViewportPermissionKey = "remotecontrol.permission.change-viewport";
     39    public static final boolean changeViewportPermissionDefault = true;
     40
    4141    @Override
    4242    public String getPermissionMessage()
    4343    {
    44         return tr("Remote Control has been asked to load data from the API.") +
     44        return tr("Remote Control has been asked to load data from the API.") +
    4545        "<br>" + tr("Request details: {0}", request);
    4646    }
    4747
    48         @Override
    49         protected String[] getMandatoryParams()
    50         {
    51                 return new String[] { "bottom", "top", "left", "right" };
    52         }
    53        
    54         @Override
    55         protected void handleRequest() throws RequestHandlerErrorException
    56         {
    57                 DownloadTask osmTask = new DownloadOsmTask();
    58                 double minlat = 0;
    59                 double maxlat = 0;
    60                 double minlon = 0;
    61                 double maxlon = 0;
    62                 try {
    63                         minlat = Double.parseDouble(args.get("bottom"));
    64                         maxlat = Double.parseDouble(args.get("top"));
    65                         minlon = Double.parseDouble(args.get("left"));
    66                         maxlon = Double.parseDouble(args.get("right"));
     48    @Override
     49    protected String[] getMandatoryParams()
     50    {
     51        return new String[] { "bottom", "top", "left", "right" };
     52    }
    6753
    68                         if(command.equals(myCommand))
    69                         {
    70                                 if (!Main.pref.getBoolean(loadDataPermissionKey, loadDataPermissionDefault))
    71                                 {
    72                                         System.out.println("RemoteControl: download forbidden by preferences");
    73                                 }
    74                                 else
    75                                 {
    76        
    77                                         // find out whether some data has already been downloaded
    78                                         Area present = null;
    79                                         Area toDownload = null;
    80                                         DataSet ds = Main.main.getCurrentDataSet();
    81                                         if (ds != null)
    82                                                 present = ds.getDataSourceArea();
    83                                         if (present != null && !present.isEmpty()) {
    84                                                 toDownload = new Area(new Rectangle2D.Double(minlon,minlat,maxlon-minlon,maxlat-minlat));
    85                                                 toDownload.subtract(present);
    86                                                 if (!toDownload.isEmpty())
    87                                                 {
    88                                                         // the result might not be a rectangle (L shaped etc)
    89                                                         Rectangle2D downloadBounds = toDownload.getBounds2D();
    90                                                         minlat = downloadBounds.getMinY();
    91                                                         minlon = downloadBounds.getMinX();
    92                                                         maxlat = downloadBounds.getMaxY();
    93                                                         maxlon = downloadBounds.getMaxX();
    94                                                 }
    95                                         }
    96                                         if((toDownload != null) && toDownload.isEmpty())
    97                                         {
    98                                                 System.out.println("RemoteControl: no download necessary");
    99                                         }
    100                                         else
    101                                         {
    102                             Future<?> future = osmTask.download(false /*no new layer*/, new Bounds(minlat,minlon,maxlat,maxlon), null /* let the task manage the progress monitor */);
    103                             Main.worker.submit(new PostDownloadHandler(osmTask, future));
    104                                         }
    105                                 }
    106                         }
    107                 } catch (Exception ex) {
    108                         System.out.println("RemoteControl: Error parsing load_and_zoom remote control request:");
    109                         ex.printStackTrace();
    110                         throw new RequestHandlerErrorException();
    111                 }
    112                 if (args.containsKey("select") && Main.pref.getBoolean(changeSelectionPermissionKey, changeSelectionPermissionDefault)) {
    113                         // select objects after downloading, zoom to selection.
    114                         final String selection = args.get("select");
    115                         Main.worker.execute(new Runnable() {
    116                                 public void run() {
    117                                         HashSet<Long> ways = new HashSet<Long>();
    118                                         HashSet<Long> nodes = new HashSet<Long>();
    119                                         HashSet<Long> relations = new HashSet<Long>();
    120                                         HashSet<OsmPrimitive> newSel = new HashSet<OsmPrimitive>();
    121                                         for (String item : selection.split(",")) {
    122                                                 if (item.startsWith("way")) {
    123                                                         ways.add(Long.parseLong(item.substring(3)));
    124                                                 } else if (item.startsWith("node")) {
    125                                                         nodes.add(Long.parseLong(item.substring(4)));
    126                                                 } else if (item.startsWith("relation")) {
    127                                                         relations.add(Long.parseLong(item.substring(8)));
    128                                                 } else if (item.startsWith("rel")) {
    129                                                         relations.add(Long.parseLong(item.substring(3)));
    130                                                 } else {
    131                                                         System.out.println("RemoteControl: invalid selection '"+item+"' ignored");
    132                                                 }
    133                                         }
    134                                         DataSet ds = Main.main.getCurrentDataSet();
    135                                         if(ds == null) // e.g. download failed
    136                                                 return;
    137                                         for (Way w : ds.getWays()) if (ways.contains(w.getId())) newSel.add(w);
    138                                         for (Node n : ds.getNodes()) if (nodes.contains(n.getId())) newSel.add(n);
    139                                         for (Relation r : ds.getRelations()) if (relations.contains(r.getId())) newSel.add(r);
    140                                         ds.setSelected(newSel);
    141                                         if (Main.pref.getBoolean(changeViewportPermissionKey, changeViewportPermissionDefault))
    142                                                 new AutoScaleAction("selection").actionPerformed(null);
    143                                 }
    144                         });
    145                 } else if (Main.pref.getBoolean(changeViewportPermissionKey, changeViewportPermissionDefault)) {
    146                         // after downloading, zoom to downloaded area.
    147                         zoom(minlat, maxlat, minlon, maxlon);
    148                 }
    149         }
     54    @Override
     55    protected void handleRequest() throws RequestHandlerErrorException
     56    {
     57        DownloadTask osmTask = new DownloadOsmTask();
     58        double minlat = 0;
     59        double maxlat = 0;
     60        double minlon = 0;
     61        double maxlon = 0;
     62        try {
     63            minlat = Double.parseDouble(args.get("bottom"));
     64            maxlat = Double.parseDouble(args.get("top"));
     65            minlon = Double.parseDouble(args.get("left"));
     66            maxlon = Double.parseDouble(args.get("right"));
    15067
    151         protected void zoom(double minlat, double maxlat, double minlon, double maxlon) {
    152                 final Bounds bounds = new Bounds(new LatLon(minlat, minlon),
    153                                 new LatLon(maxlat, maxlon));
     68            if(command.equals(myCommand))
     69            {
     70                if (!Main.pref.getBoolean(loadDataPermissionKey, loadDataPermissionDefault))
     71                {
     72                    System.out.println("RemoteControl: download forbidden by preferences");
     73                }
     74                else
     75                {
    15476
    155                 // make sure this isn't called unless there *is* a MapView
    156                 //
    157                 if (Main.map != null && Main.map.mapView != null) {
    158                         Main.worker.execute(new Runnable() {
    159                                 public void run() {
    160                                         BoundingXYVisitor bbox = new BoundingXYVisitor();
    161                                         bbox.visit(bounds);
    162                                         Main.map.mapView.recalculateCenterScale(bbox);
    163                                 }
    164                         });
    165                 }
    166         }
     77                    // find out whether some data has already been downloaded
     78                    Area present = null;
     79                    Area toDownload = null;
     80                    DataSet ds = Main.main.getCurrentDataSet();
     81                    if (ds != null)
     82                        present = ds.getDataSourceArea();
     83                    if (present != null && !present.isEmpty()) {
     84                        toDownload = new Area(new Rectangle2D.Double(minlon,minlat,maxlon-minlon,maxlat-minlat));
     85                        toDownload.subtract(present);
     86                        if (!toDownload.isEmpty())
     87                        {
     88                            // the result might not be a rectangle (L shaped etc)
     89                            Rectangle2D downloadBounds = toDownload.getBounds2D();
     90                            minlat = downloadBounds.getMinY();
     91                            minlon = downloadBounds.getMinX();
     92                            maxlat = downloadBounds.getMaxY();
     93                            maxlon = downloadBounds.getMaxX();
     94                        }
     95                    }
     96                    if((toDownload != null) && toDownload.isEmpty())
     97                    {
     98                        System.out.println("RemoteControl: no download necessary");
     99                    }
     100                    else
     101                    {
     102                        Future<?> future = osmTask.download(false /*no new layer*/, new Bounds(minlat,minlon,maxlat,maxlon), null /* let the task manage the progress monitor */);
     103                        Main.worker.submit(new PostDownloadHandler(osmTask, future));
     104                    }
     105                }
     106            }
     107        } catch (Exception ex) {
     108            System.out.println("RemoteControl: Error parsing load_and_zoom remote control request:");
     109            ex.printStackTrace();
     110            throw new RequestHandlerErrorException();
     111        }
     112        if (args.containsKey("select") && Main.pref.getBoolean(changeSelectionPermissionKey, changeSelectionPermissionDefault)) {
     113            // select objects after downloading, zoom to selection.
     114            final String selection = args.get("select");
     115            Main.worker.execute(new Runnable() {
     116                public void run() {
     117                    HashSet<Long> ways = new HashSet<Long>();
     118                    HashSet<Long> nodes = new HashSet<Long>();
     119                    HashSet<Long> relations = new HashSet<Long>();
     120                    HashSet<OsmPrimitive> newSel = new HashSet<OsmPrimitive>();
     121                    for (String item : selection.split(",")) {
     122                        if (item.startsWith("way")) {
     123                            ways.add(Long.parseLong(item.substring(3)));
     124                        } else if (item.startsWith("node")) {
     125                            nodes.add(Long.parseLong(item.substring(4)));
     126                        } else if (item.startsWith("relation")) {
     127                            relations.add(Long.parseLong(item.substring(8)));
     128                        } else if (item.startsWith("rel")) {
     129                            relations.add(Long.parseLong(item.substring(3)));
     130                        } else {
     131                            System.out.println("RemoteControl: invalid selection '"+item+"' ignored");
     132                        }
     133                    }
     134                    DataSet ds = Main.main.getCurrentDataSet();
     135                    if(ds == null) // e.g. download failed
     136                        return;
     137                    for (Way w : ds.getWays()) if (ways.contains(w.getId())) newSel.add(w);
     138                    for (Node n : ds.getNodes()) if (nodes.contains(n.getId())) newSel.add(n);
     139                    for (Relation r : ds.getRelations()) if (relations.contains(r.getId())) newSel.add(r);
     140                    ds.setSelected(newSel);
     141                    if (Main.pref.getBoolean(changeViewportPermissionKey, changeViewportPermissionDefault))
     142                        new AutoScaleAction("selection").actionPerformed(null);
     143                }
     144            });
     145        } else if (Main.pref.getBoolean(changeViewportPermissionKey, changeViewportPermissionDefault)) {
     146            // after downloading, zoom to downloaded area.
     147            zoom(minlat, maxlat, minlon, maxlon);
     148        }
     149    }
     150
     151    protected void zoom(double minlat, double maxlat, double minlon, double maxlon) {
     152        final Bounds bounds = new Bounds(new LatLon(minlat, minlon),
     153                new LatLon(maxlat, maxlon));
     154
     155        // make sure this isn't called unless there *is* a MapView
     156        //
     157        if (Main.map != null && Main.map.mapView != null) {
     158            Main.worker.execute(new Runnable() {
     159                public void run() {
     160                    BoundingXYVisitor bbox = new BoundingXYVisitor();
     161                    bbox.visit(bounds);
     162                    Main.map.mapView.recalculateCenterScale(bbox);
     163                }
     164            });
     165        }
     166    }
    167167}
  • applications/editors/josm/plugins/remotecontrol/src/org/openstreetmap/josm/plugins/remotecontrol/handler/VersionHandler.java

    r22733 r23189  
    1414public class VersionHandler extends RequestHandler {
    1515
    16         public static final String command = "version";
    17         public static final String permissionKey = "remotecontrol.permission.read-protocolversion";
    18         public static final boolean permissionDefault = true;
     16    public static final String command = "version";
     17    public static final String permissionKey = "remotecontrol.permission.read-protocolversion";
     18    public static final boolean permissionDefault = true;
    1919
    20         @Override
    21         protected void handleRequest() throws RequestHandlerErrorException,
    22                         RequestHandlerBadRequestException {
    23                 content = RequestProcessor.PROTOCOLVERSION;
    24                 contentType = "application/json";
    25                 if (args.containsKey("jsonp")) {
    26                         content = args.get("jsonp")+ " && " + args.get("jsonp") + "(" + content + ")";
    27                 }
    28         }
     20    @Override
     21    protected void handleRequest() throws RequestHandlerErrorException,
     22            RequestHandlerBadRequestException {
     23        content = RequestProcessor.PROTOCOLVERSION;
     24        contentType = "application/json";
     25        if (args.containsKey("jsonp")) {
     26            content = args.get("jsonp")+ " && " + args.get("jsonp") + "(" + content + ")";
     27        }
     28    }
    2929
    30         @Override
    31         public String getPermissionMessage() {
    32                 return tr("Remote Control has been asked to report its protocol version. This enables web sites to detect a running JOSM.");
    33         }
     30    @Override
     31    public String getPermissionMessage() {
     32        return tr("Remote Control has been asked to report its protocol version. This enables web sites to detect a running JOSM.");
     33    }
    3434
    35         @Override
    36         public PermissionPrefWithDefault getPermissionPref()
    37         {
    38                 return new PermissionPrefWithDefault(permissionKey, permissionDefault,
    39                                 "RemoteControl: /version forbidden by preferences");
    40         }
     35    @Override
     36    public PermissionPrefWithDefault getPermissionPref()
     37    {
     38        return new PermissionPrefWithDefault(permissionKey, permissionDefault,
     39                "RemoteControl: /version forbidden by preferences");
     40    }
    4141}
  • applications/editors/josm/plugins/routes/src/org/openstreetmap/josm/plugins/routes/ConvertedWay.java

    r17380 r23189  
    1111
    1212public class ConvertedWay {
    13        
    14         public class WayEnd {
    15                 private Node end;
    16                
    17                 public WayEnd(Node end) {
    18                         this.end = end;
    19                 }
    20                
    21                 @Override
    22                 public boolean equals(Object o) {
    23                         if (o instanceof WayEnd) {
    24                                 WayEnd otherEnd = (WayEnd)o;
    25                                 return end.equals(otherEnd.end) && routes.equals(otherEnd.getRoutes());
    26                         } else {
    27                                 return false;
    28                         }
    29                 }
    30                
    31                 @Override
    32                 public int hashCode() {
    33                         return end.hashCode() + routes.hashCode();
    34                 }
    35                
    36                 public BitSet getRoutes() {
    37                         return routes;
    38                 }
    39                
    40                 public ConvertedWay getWay() {
    41                         return ConvertedWay.this;
    42                 }
    43         }
    44        
    45         private List<Node> nodes = new ArrayList<Node>();
    46         private BitSet routes;
    47        
    48         public ConvertedWay(BitSet routes, Way way) {
    49                 this.routes = routes;
    50                 nodes.addAll(way.getNodes());
    51         }
    52        
    53         public WayEnd getStart() {
    54                 return new WayEnd(nodes.get(0));
    55         }
    56        
    57         public WayEnd getStop() {
    58                 return new WayEnd(nodes.get(nodes.size() - 1));
    59         }
    60        
    61         /**
    62          * Connects way to this way. Other ways internal representation is destroyed!!!
    63          * @param way
    64          */
    65         public void connect(ConvertedWay way) {
    66                 for (int i=0; i<2; i++) {                       
    67                         if (way.nodes.get(0).equals(nodes.get(nodes.size() - 1))) {
    68                                 way.nodes.remove(0);
    69                                 nodes.addAll(way.nodes);
    70                                 return;
    71                         }
    72                        
    73                         if (way.nodes.get(way.nodes.size() - 1).equals(nodes.get(0))) {
    74                                 nodes.remove(0);
    75                                 way.nodes.addAll(nodes);
    76                                 nodes = way.nodes;
    77                                 return;
    78                         }
    79                         Collections.reverse(nodes);
    80                 }
    81         }
    8213
    83         public List<Node> getNodes() {
    84                 return nodes;
    85         }
     14    public class WayEnd {
     15        private Node end;
    8616
    87         public BitSet getRoutes() {
    88                 return routes;
    89         }
     17        public WayEnd(Node end) {
     18            this.end = end;
     19        }
     20
     21        @Override
     22        public boolean equals(Object o) {
     23            if (o instanceof WayEnd) {
     24                WayEnd otherEnd = (WayEnd)o;
     25                return end.equals(otherEnd.end) && routes.equals(otherEnd.getRoutes());
     26            } else {
     27                return false;
     28            }
     29        }
     30
     31        @Override
     32        public int hashCode() {
     33            return end.hashCode() + routes.hashCode();
     34        }
     35
     36        public BitSet getRoutes() {
     37            return routes;
     38        }
     39
     40        public ConvertedWay getWay() {
     41            return ConvertedWay.this;
     42        }
     43    }
     44
     45    private List<Node> nodes = new ArrayList<Node>();
     46    private BitSet routes;
     47
     48    public ConvertedWay(BitSet routes, Way way) {
     49        this.routes = routes;
     50        nodes.addAll(way.getNodes());
     51    }
     52
     53    public WayEnd getStart() {
     54        return new WayEnd(nodes.get(0));
     55    }
     56
     57    public WayEnd getStop() {
     58        return new WayEnd(nodes.get(nodes.size() - 1));
     59    }
     60
     61    /**
     62     * Connects way to this way. Other ways internal representation is destroyed!!!
     63     * @param way
     64     */
     65    public void connect(ConvertedWay way) {
     66        for (int i=0; i<2; i++) {
     67            if (way.nodes.get(0).equals(nodes.get(nodes.size() - 1))) {
     68                way.nodes.remove(0);
     69                nodes.addAll(way.nodes);
     70                return;
     71            }
     72
     73            if (way.nodes.get(way.nodes.size() - 1).equals(nodes.get(0))) {
     74                nodes.remove(0);
     75                way.nodes.addAll(nodes);
     76                nodes = way.nodes;
     77                return;
     78            }
     79            Collections.reverse(nodes);
     80        }
     81    }
     82
     83    public List<Node> getNodes() {
     84        return nodes;
     85    }
     86
     87    public BitSet getRoutes() {
     88        return routes;
     89    }
    9090
    9191
  • applications/editors/josm/plugins/routes/src/org/openstreetmap/josm/plugins/routes/PathBuilder.java

    r19532 r23189  
    1414public class PathBuilder {
    1515
    16         private Map<Way, BitSet> wayRoutes = new HashMap<Way, BitSet>();
    17         private Collection<ConvertedWay> convertedWays;
     16    private Map<Way, BitSet> wayRoutes = new HashMap<Way, BitSet>();
     17    private Collection<ConvertedWay> convertedWays;
    1818
    19         public void addWay(Way way, RouteDefinition route) {
     19    public void addWay(Way way, RouteDefinition route) {
    2020
    21                 if (way.getNodesCount() >= 2) {
    22                         BitSet routes = wayRoutes.get(way);
    23                         if (routes == null) {
    24                                 routes = new BitSet();
    25                                 wayRoutes.put(way, routes);
    26                         }
    27                         routes.set(route.getIndex());
    28                 }
     21        if (way.getNodesCount() >= 2) {
     22            BitSet routes = wayRoutes.get(way);
     23            if (routes == null) {
     24                routes = new BitSet();
     25                wayRoutes.put(way, routes);
     26            }
     27            routes.set(route.getIndex());
     28        }
    2929
    30         }
     30    }
    3131
    32         public Collection<ConvertedWay> getConvertedWays() {
    33                 if (convertedWays == null) {
    34                         Map<WayEnd, ConvertedWay> ways = new HashMap<WayEnd, ConvertedWay>();
     32    public Collection<ConvertedWay> getConvertedWays() {
     33        if (convertedWays == null) {
     34            Map<WayEnd, ConvertedWay> ways = new HashMap<WayEnd, ConvertedWay>();
    3535
    36                         for (Entry<Way, BitSet> wayEntry:wayRoutes.entrySet()) {
    37                                 ConvertedWay way = new ConvertedWay(wayEntry.getValue(), wayEntry.getKey());
     36            for (Entry<Way, BitSet> wayEntry:wayRoutes.entrySet()) {
     37                ConvertedWay way = new ConvertedWay(wayEntry.getValue(), wayEntry.getKey());
    3838
    39                                 ConvertedWay wayBefore = ways.get(way.getStart());
    40                                 ConvertedWay wayAfter = ways.get(way.getStop());
     39                ConvertedWay wayBefore = ways.get(way.getStart());
     40                ConvertedWay wayAfter = ways.get(way.getStop());
    4141
    42                                 if (wayBefore != null) {
    43                                         removeWay(ways, wayBefore);
    44                                         way.connect(wayBefore);
    45                                 }
     42                if (wayBefore != null) {
     43                    removeWay(ways, wayBefore);
     44                    way.connect(wayBefore);
     45                }
    4646
    47                                 if (wayAfter != null) {
    48                                         removeWay(ways, wayAfter);
    49                                         way.connect(wayAfter);
    50                                 }
     47                if (wayAfter != null) {
     48                    removeWay(ways, wayAfter);
     49                    way.connect(wayAfter);
     50                }
    5151
    52                                 ways.put(way.getStart(), way);
    53                                 ways.put(way.getStop(), way);
    54                         }
     52                ways.put(way.getStart(), way);
     53                ways.put(way.getStop(), way);
     54            }
    5555
    56                         Set<ConvertedWay> uniqueWays = new HashSet<ConvertedWay>();
    57                         uniqueWays.addAll(ways.values());
    58                         convertedWays = uniqueWays;
    59                 }
    60                 return convertedWays;
    61         }
     56            Set<ConvertedWay> uniqueWays = new HashSet<ConvertedWay>();
     57            uniqueWays.addAll(ways.values());
     58            convertedWays = uniqueWays;
     59        }
     60        return convertedWays;
     61    }
    6262
    63         private void removeWay(Map<WayEnd, ConvertedWay> map, ConvertedWay wayInMap) {
    64                 map.remove(wayInMap.getStart());
    65                 map.remove(wayInMap.getStop());
    66         }
     63    private void removeWay(Map<WayEnd, ConvertedWay> map, ConvertedWay wayInMap) {
     64        map.remove(wayInMap.getStart());
     65        map.remove(wayInMap.getStop());
     66    }
    6767
    68         public void clear() {
    69                 convertedWays = null;
    70                 wayRoutes.clear();
    71         }
     68    public void clear() {
     69        convertedWays = null;
     70        wayRoutes.clear();
     71    }
    7272
    7373}
  • applications/editors/josm/plugins/routes/src/org/openstreetmap/josm/plugins/routes/RelationEditMode.java

    r22046 r23189  
    2121
    2222public class RelationEditMode extends MapMode {
    23         private static final long serialVersionUID = -7767329767438266289L;
     23    private static final long serialVersionUID = -7767329767438266289L;
    2424
    25         private Way highlightedWay;
     25    private Way highlightedWay;
    2626
    27         public RelationEditMode(MapFrame mapFrame) {
    28                 super(tr("Edit relation"), "node/autonode", tr("Edit relations"),
    29                                 Shortcut.registerShortcut("mapmode:editRelation", tr("Mode: {0}", tr("Edit relation")), KeyEvent.VK_H, Shortcut.GROUP_EDIT),
    30                                 mapFrame, Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
    31         }
     27    public RelationEditMode(MapFrame mapFrame) {
     28        super(tr("Edit relation"), "node/autonode", tr("Edit relations"),
     29                Shortcut.registerShortcut("mapmode:editRelation", tr("Mode: {0}", tr("Edit relation")), KeyEvent.VK_H, Shortcut.GROUP_EDIT),
     30                mapFrame, Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
     31    }
    3232
    33         @Override
    34         public void enterMode() {
    35                 super.enterMode();
    36                 Main.map.mapView.addMouseListener(this);
    37                 Main.map.mapView.addMouseMotionListener(this);
    38         }
     33    @Override
     34    public void enterMode() {
     35        super.enterMode();
     36        Main.map.mapView.addMouseListener(this);
     37        Main.map.mapView.addMouseMotionListener(this);
     38    }
    3939
    40         @Override
    41         public void exitMode() {
    42                 super.exitMode();
    43                 Main.map.mapView.removeMouseListener(this);
    44                 Main.map.mapView.removeMouseMotionListener(this);
    45         }
     40    @Override
     41    public void exitMode() {
     42        super.exitMode();
     43        Main.map.mapView.removeMouseListener(this);
     44        Main.map.mapView.removeMouseMotionListener(this);
     45    }
    4646
    47         @Override
    48         public void mouseMoved(MouseEvent e) {
    49                 Way nearestWay = Main.map.mapView.getNearestWay(e.getPoint(), OsmPrimitive.isUsablePredicate);
    50                 if (nearestWay != highlightedWay) {
    51                         if (highlightedWay != null) {
    52                                 highlightedWay.setHighlighted(false);
    53                         }
    54                         if (nearestWay != null) {
    55                                 nearestWay.setHighlighted(true);
    56                         }
    57                         highlightedWay = nearestWay;
    58                         Main.map.mapView.repaint();
    59                 }
    60         }
     47    @Override
     48    public void mouseMoved(MouseEvent e) {
     49        Way nearestWay = Main.map.mapView.getNearestWay(e.getPoint(), OsmPrimitive.isUsablePredicate);
     50        if (nearestWay != highlightedWay) {
     51            if (highlightedWay != null) {
     52                highlightedWay.setHighlighted(false);
     53            }
     54            if (nearestWay != null) {
     55                nearestWay.setHighlighted(true);
     56            }
     57            highlightedWay = nearestWay;
     58            Main.map.mapView.repaint();
     59        }
     60    }
    6161
    62         @Override
    63         public void mouseClicked(MouseEvent e) {
    64                 if (Main.main.getCurrentDataSet() == null)
    65                         return;
     62    @Override
     63    public void mouseClicked(MouseEvent e) {
     64        if (Main.main.getCurrentDataSet() == null)
     65            return;
    6666
    67                 Way way = Main.map.mapView.getNearestWay(e.getPoint(), OsmPrimitive.isUsablePredicate);
    68                 Collection<Relation> selectedRelations = Main.main.getCurrentDataSet().getSelectedRelations();
     67        Way way = Main.map.mapView.getNearestWay(e.getPoint(), OsmPrimitive.isUsablePredicate);
     68        Collection<Relation> selectedRelations = Main.main.getCurrentDataSet().getSelectedRelations();
    6969
    70                 if (way != null) {
     70        if (way != null) {
    7171
    72                         if (selectedRelations.isEmpty()) {
    73                                 JOptionPane.showMessageDialog(Main.parent, tr("No relation is selected"));
    74                         }
     72            if (selectedRelations.isEmpty()) {
     73                JOptionPane.showMessageDialog(Main.parent, tr("No relation is selected"));
     74            }
    7575
    76                         for (OsmPrimitive rel:selectedRelations) {
    77                                 Relation r = (Relation)rel;
    78                                 RelationMember foundMember = null;
    79                                 for (RelationMember member:r.getMembers()) {
    80                                         if (member.getMember() == way) {
    81                                                 foundMember = member;
    82                                                 break;
    83                                         }
    84                                 }
     76            for (OsmPrimitive rel:selectedRelations) {
     77                Relation r = (Relation)rel;
     78                RelationMember foundMember = null;
     79                for (RelationMember member:r.getMembers()) {
     80                    if (member.getMember() == way) {
     81                        foundMember = member;
     82                        break;
     83                    }
     84                }
    8585
    86                                 if (foundMember != null) {
    87                                         Main.main.undoRedo.add(new RemoveRelationMemberCommand(r, new RelationMember("", way)));
    88                                 } else {
    89                                         Relation newRelation = new Relation(r);
    90                                         newRelation.addMember(new RelationMember("", way));
    91                                         Main.main.undoRedo.add(new ChangeCommand(r, newRelation));
    92                                 }
    93                         }
    94                 }
    95         }
     86                if (foundMember != null) {
     87                    Main.main.undoRedo.add(new RemoveRelationMemberCommand(r, new RelationMember("", way)));
     88                } else {
     89                    Relation newRelation = new Relation(r);
     90                    newRelation.addMember(new RelationMember("", way));
     91                    Main.main.undoRedo.add(new ChangeCommand(r, newRelation));
     92                }
     93            }
     94        }
     95    }
    9696
    9797
  • applications/editors/josm/plugins/routes/src/org/openstreetmap/josm/plugins/routes/RouteDefinition.java

    r19338 r23189  
    1010public class RouteDefinition {
    1111
    12         private final Color color;
    13         private final String matchString;
    14         private Match match;
    15         private final int index;
     12    private final Color color;
     13    private final String matchString;
     14    private Match match;
     15    private final int index;
    1616
    17         public RouteDefinition(int index, Color color, String expression) {
    18                 this.color = color;
    19                 this.matchString = expression;
    20                 this.index = index;
    21                 try {
    22                         match = SearchCompiler.compile(expression, false, false);
    23                 } catch (ParseError e) {
    24                         match = new SearchCompiler.Never();
    25                         e.printStackTrace();
    26                 }
    27         }
     17    public RouteDefinition(int index, Color color, String expression) {
     18        this.color = color;
     19        this.matchString = expression;
     20        this.index = index;
     21        try {
     22            match = SearchCompiler.compile(expression, false, false);
     23        } catch (ParseError e) {
     24            match = new SearchCompiler.Never();
     25            e.printStackTrace();
     26        }
     27    }
    2828
    29         public boolean matches(OsmPrimitive primitive) {
    30                 return match.match(primitive);
    31         }
     29    public boolean matches(OsmPrimitive primitive) {
     30        return match.match(primitive);
     31    }
    3232
    33         public Color getColor() {
    34                 return color;
    35         }
     33    public Color getColor() {
     34        return color;
     35    }
    3636
    37         public int getIndex() {
    38                 return index;
    39         }
     37    public int getIndex() {
     38        return index;
     39    }
    4040
    41         @Override
    42         public String toString() {
    43                 return color.toString() + " " + matchString;
    44         }
     41    @Override
     42    public String toString() {
     43        return color.toString() + " " + matchString;
     44    }
    4545
    4646}
  • applications/editors/josm/plugins/routes/src/org/openstreetmap/josm/plugins/routes/RouteLayer.java

    r22549 r23189  
    3333public class RouteLayer extends Layer implements DataSetListenerAdapter.Listener {
    3434
    35         private final PathPainter pathPainter;
    36         private final PathBuilder pathBuilder = new PathBuilder();
    37         private final List<RouteDefinition> routes = new ArrayList<RouteDefinition>();
    38         private volatile boolean datasetChanged = true;
     35    private final PathPainter pathPainter;
     36    private final PathBuilder pathBuilder = new PathBuilder();
     37    private final List<RouteDefinition> routes = new ArrayList<RouteDefinition>();
     38    private volatile boolean datasetChanged = true;
    3939
    40         public RouteLayer(RoutesXMLLayer xmlLayer) {
    41                 super(xmlLayer.getName());
     40    public RouteLayer(RoutesXMLLayer xmlLayer) {
     41        super(xmlLayer.getName());
    4242
    43                 int index = 0;
    44                 for (RoutesXMLRoute route:xmlLayer.getRoute()) {
    45                         if (route.isEnabled()) {
    46                                 Color color = ColorHelper.html2color(route.getColor());
    47                                 if (color == null) {
    48                                         color = Color.RED;
    49                                         System.err.printf("Routes plugin - unable to convert color (%s)\n", route.getColor());
    50                                 }
    51                                 routes.add(new RouteDefinition(index++, color, route.getPattern()));
    52                         }
    53                 }
     43        int index = 0;
     44        for (RoutesXMLRoute route:xmlLayer.getRoute()) {
     45            if (route.isEnabled()) {
     46                Color color = ColorHelper.html2color(route.getColor());
     47                if (color == null) {
     48                    color = Color.RED;
     49                    System.err.printf("Routes plugin - unable to convert color (%s)\n", route.getColor());
     50                }
     51                routes.add(new RouteDefinition(index++, color, route.getPattern()));
     52            }
     53        }
    5454
    55                 if ("wide".equals(Main.pref.get("routes.painter"))) {
    56                         pathPainter = new WideLinePainter(this);
    57                 } else {
    58                         pathPainter = new NarrowLinePainter(this);
    59                 }
     55        if ("wide".equals(Main.pref.get("routes.painter"))) {
     56            pathPainter = new WideLinePainter(this);
     57        } else {
     58            pathPainter = new NarrowLinePainter(this);
     59        }
    6060
    61                 DatasetEventManager.getInstance().addDatasetListener(new DataSetListenerAdapter(this), FireMode.IMMEDIATELY);
    62         }
     61        DatasetEventManager.getInstance().addDatasetListener(new DataSetListenerAdapter(this), FireMode.IMMEDIATELY);
     62    }
    6363
    64         @Override
    65         public Icon getIcon() {
    66                 return ImageProvider.get("layer", "osmdata_small");
    67         }
     64    @Override
     65    public Icon getIcon() {
     66        return ImageProvider.get("layer", "osmdata_small");
     67    }
    6868
    69         @Override
    70         public Object getInfoComponent() {
    71                 return null;
    72         }
     69    @Override
     70    public Object getInfoComponent() {
     71        return null;
     72    }
    7373
    74         @Override
    75         public Action[] getMenuEntries() {
    76                 return new Action[0];
    77         }
     74    @Override
     75    public Action[] getMenuEntries() {
     76        return new Action[0];
     77    }
    7878
    79         @Override
    80         public String getToolTipText() {
    81                 return "Hiking routes";
    82         }
     79    @Override
     80    public String getToolTipText() {
     81        return "Hiking routes";
     82    }
    8383
    84         @Override
    85         public boolean isMergable(Layer other) {
    86                 return false;
    87         }
     84    @Override
     85    public boolean isMergable(Layer other) {
     86        return false;
     87    }
    8888
    89         @Override
    90         public void mergeFrom(Layer from) {
    91                 // Merging is not supported
    92         }
     89    @Override
     90    public void mergeFrom(Layer from) {
     91        // Merging is not supported
     92    }
    9393
    94         private void addRelation(Relation relation, RouteDefinition route) {
    95                 for (RelationMember member:relation.getMembers()) {
    96                         if (member.getMember() instanceof Way) {
    97                                 Way way = (Way)member.getMember();
    98                                 pathBuilder.addWay(way, route);
    99                         }
    100                 }
    101         }
     94    private void addRelation(Relation relation, RouteDefinition route) {
     95        for (RelationMember member:relation.getMembers()) {
     96            if (member.getMember() instanceof Way) {
     97                Way way = (Way)member.getMember();
     98                pathBuilder.addWay(way, route);
     99            }
     100        }
     101    }
    102102
    103         @Override
    104         public void paint(Graphics2D g, MapView mv, Bounds bounds) {
     103    @Override
     104    public void paint(Graphics2D g, MapView mv, Bounds bounds) {
    105105
    106                 DataSet dataset = Main.main.getCurrentDataSet();
     106        DataSet dataset = Main.main.getCurrentDataSet();
    107107
    108                 if (dataset == null) {
    109                         return;
    110                 }
     108        if (dataset == null) {
     109            return;
     110        }
    111111
    112                 if (datasetChanged) {
    113                         datasetChanged = false;
    114                         pathBuilder.clear();
     112        if (datasetChanged) {
     113            datasetChanged = false;
     114            pathBuilder.clear();
    115115
    116                         for (Relation relation:dataset.getRelations()) {
    117                                 for (RouteDefinition route:routes) {
    118                                         if (route.matches(relation)) {
    119                                                 addRelation(relation, route);
    120                                         }
    121                                 }
    122                         }
     116            for (Relation relation:dataset.getRelations()) {
     117                for (RouteDefinition route:routes) {
     118                    if (route.matches(relation)) {
     119                        addRelation(relation, route);
     120                    }
     121                }
     122            }
    123123
    124                         for (Way way:dataset.getWays()) {
    125                                 for (RouteDefinition route:routes) {
    126                                         if (route.matches(way)) {
    127                                                 pathBuilder.addWay(way, route);
    128                                         }
    129                                 }
    130                         }
    131                 }
     124            for (Way way:dataset.getWays()) {
     125                for (RouteDefinition route:routes) {
     126                    if (route.matches(way)) {
     127                        pathBuilder.addWay(way, route);
     128                    }
     129                }
     130            }
     131        }
    132132
    133                 Stroke stroke = g.getStroke();
    134                 Color color   = g.getColor();
    135                 for (ConvertedWay way:pathBuilder.getConvertedWays()) {
    136                         pathPainter.drawWay(way, mv, g);
    137                 }
    138                 g.setStroke(stroke);
    139                 g.setColor(color);
     133        Stroke stroke = g.getStroke();
     134        Color color   = g.getColor();
     135        for (ConvertedWay way:pathBuilder.getConvertedWays()) {
     136            pathPainter.drawWay(way, mv, g);
     137        }
     138        g.setStroke(stroke);
     139        g.setColor(color);
    140140
    141         }
     141    }
    142142
    143         @Override
    144         public void visitBoundingBox(BoundingXYVisitor v) {
     143    @Override
     144    public void visitBoundingBox(BoundingXYVisitor v) {
    145145
    146         }
     146    }
    147147
    148         public List<RouteDefinition> getRoutes() {
    149                 return routes;
    150         }
     148    public List<RouteDefinition> getRoutes() {
     149        return routes;
     150    }
    151151
    152         public void processDatasetEvent(AbstractDatasetChangedEvent event) {
    153                 datasetChanged = true;
    154         }
     152    public void processDatasetEvent(AbstractDatasetChangedEvent event) {
     153        datasetChanged = true;
     154    }
    155155
    156156}
  • applications/editors/josm/plugins/routes/src/org/openstreetmap/josm/plugins/routes/RoutesPlugin.java

    r19473 r23189  
    2626
    2727public class RoutesPlugin extends Plugin implements LayerChangeListener {
    28        
     28
    2929    private final List<RouteLayer> routeLayers = new ArrayList<RouteLayer>();
    3030    private boolean isShown;
    31    
     31
    3232    public RoutesPlugin(PluginInformation info) {
    33         super(info);
    34         MapView.addLayerChangeListener(this);
    35        
     33        super(info);
     34        MapView.addLayerChangeListener(this);
     35
    3636        File routesFile = new File(getPluginDir() + File.separator + "routes.xml");
    3737        if (!routesFile.exists()) {
    3838            System.out.println("File with route definitions doesn't exist, using default");
    39            
     39
    4040            try {
    4141                routesFile.getParentFile().mkdir();
    4242                OutputStream outputStream = new FileOutputStream(routesFile);
    4343                InputStream inputStream = Routes.class.getResourceAsStream("routes.xml");
    44                  
    45                 byte[] b = new byte[512]; 
    46                 int read; 
    47                 while ((read = inputStream.read(b)) != -1) { 
     44
     45                byte[] b = new byte[512];
     46                int read;
     47                while ((read = inputStream.read(b)) != -1) {
    4848                    outputStream.write(b, 0, read);
    4949                }
    50                
    51                 outputStream.close();               
     50
     51                outputStream.close();
    5252                inputStream.close();
    53                    
     53
    5454            } catch (IOException e) {
    5555                e.printStackTrace();
    5656            }
    5757        }
    58        
     58
    5959        try {
    6060            JAXBContext context = JAXBContext.newInstance(
     
    6464                new FileInputStream(getPluginDir() + File.separator + "routes.xml"));
    6565            for (RoutesXMLLayer layer:routes.getLayer()) {
    66                 if (layer.isEnabled()) {
    67                         routeLayers.add(new RouteLayer(layer));
    68                 }
     66                if (layer.isEnabled()) {
     67                    routeLayers.add(new RouteLayer(layer));
     68                }
    6969            }
    7070        } catch (Exception e) {
    7171            e.printStackTrace();
    72         } 
     72        }
    7373
    7474        //new RelationEditMode(Main.map);
     
    7777
    7878    public void activeLayerChange(Layer oldLayer, Layer newLayer) {
    79         // TODO Auto-generated method stub 
     79        // TODO Auto-generated method stub
    8080    }
    81    
     81
    8282    private void checkLayers() {
    8383        if (Main.map != null && Main.map.mapView != null) {
     
    9191                                    Main.main.addLayer(routeLayer);
    9292                                }
    93                             }                           
     93                            }
    9494                        });
    9595                    }
    9696                    return;
    97                 } 
     97                }
    9898            }
    9999            if (isShown) {
     
    104104                            Main.main.removeLayer(routeLayer);
    105105                        }
    106                     }                   
     106                    }
    107107                });
    108108            }
  • applications/editors/josm/plugins/routes/src/org/openstreetmap/josm/plugins/routes/paint/AbstractLinePainter.java

    r22590 r23189  
    1717public abstract class AbstractLinePainter implements PathPainter {
    1818
    19         // Following two method copied from http://blog.persistent.info/2004/03/java-lineline-intersections.html
    20         protected boolean getLineLineIntersection(Line2D.Double l1,
    21                         Line2D.Double l2,
    22                         Point intersection)
    23         {
    24                 double  x1 = l1.getX1(), y1 = l1.getY1(),
    25                 x2 = l1.getX2(), y2 = l1.getY2(),
    26                 x3 = l2.getX1(), y3 = l2.getY1(),
    27                 x4 = l2.getX2(), y4 = l2.getY2();
    28                 double dx1 = x2 - x1;
    29                 double dx2 = x4 - x3;
    30                 double dy1 = y2 - y1;
    31                 double dy2 = y4 - y3;
     19    // Following two method copied from http://blog.persistent.info/2004/03/java-lineline-intersections.html
     20    protected boolean getLineLineIntersection(Line2D.Double l1,
     21            Line2D.Double l2,
     22            Point intersection)
     23    {
     24        double  x1 = l1.getX1(), y1 = l1.getY1(),
     25        x2 = l1.getX2(), y2 = l1.getY2(),
     26        x3 = l2.getX1(), y3 = l2.getY1(),
     27        x4 = l2.getX2(), y4 = l2.getY2();
     28        double dx1 = x2 - x1;
     29        double dx2 = x4 - x3;
     30        double dy1 = y2 - y1;
     31        double dy2 = y4 - y3;
    3232
    33                 double ua = (dx2 * (y1 - y3) - dy2 * (x1 - x3)) / (dy2 * dx1 - dx2 * dy1);
     33        double ua = (dx2 * (y1 - y3) - dy2 * (x1 - x3)) / (dy2 * dx1 - dx2 * dy1);
    3434
    35                 if (Math.abs(dy2 * dx1 - dx2 * dy1) < 0.0001) {
    36                         intersection.x = (int)l1.x2;
    37                         intersection.y = (int)l1.y2;
    38                         return false;
    39                 } else {
    40                         intersection.x = (int)(x1 + ua * (x2 - x1));
    41                         intersection.y = (int)(y1 + ua * (y2 - y1));
    42                 }
     35        if (Math.abs(dy2 * dx1 - dx2 * dy1) < 0.0001) {
     36            intersection.x = (int)l1.x2;
     37            intersection.y = (int)l1.y2;
     38            return false;
     39        } else {
     40            intersection.x = (int)(x1 + ua * (x2 - x1));
     41            intersection.y = (int)(y1 + ua * (y2 - y1));
     42        }
    4343
    44                 return true;
    45         }
     44        return true;
     45    }
    4646
    47         protected double det(double a, double b, double c, double d)
    48         {
    49                 return a * d - b * c;
    50         }
     47    protected double det(double a, double b, double c, double d)
     48    {
     49        return a * d - b * c;
     50    }
    5151
    52         protected Point shiftPoint(Point2D p1, Point2D p2, double shift) {
    53                 double dx = p2.getX() - p1.getX();
    54                 double dy = p2.getY() - p1.getY();
     52    protected Point shiftPoint(Point2D p1, Point2D p2, double shift) {
     53        double dx = p2.getX() - p1.getX();
     54        double dy = p2.getY() - p1.getY();
    5555
    56                 // Perpendicular vector
    57                 double ndx = -dy;
    58                 double ndy = dx;
     56        // Perpendicular vector
     57        double ndx = -dy;
     58        double ndy = dx;
    5959
    60                 // Normalize
    61                 double length = Math.sqrt(ndx * ndx + ndy * ndy);
    62                 ndx = ndx / length;
    63                 ndy = ndy / length;
     60        // Normalize
     61        double length = Math.sqrt(ndx * ndx + ndy * ndy);
     62        ndx = ndx / length;
     63        ndy = ndy / length;
    6464
    65                 return new Point((int)(p1.getX() + shift * ndx), (int)(p1.getY() + shift * ndy));
    66         }
     65        return new Point((int)(p1.getX() + shift * ndx), (int)(p1.getY() + shift * ndy));
     66    }
    6767
    68         protected Line2D.Double shiftLine(Point2D p1, Point2D p2, double shift) {
    69                 double dx = p2.getX() - p1.getX();
    70                 double dy = p2.getY() - p1.getY();
     68    protected Line2D.Double shiftLine(Point2D p1, Point2D p2, double shift) {
     69        double dx = p2.getX() - p1.getX();
     70        double dy = p2.getY() - p1.getY();
    7171
    72                 Point2D point1 = shiftPoint(p1, p2, shift);
    73                 Point2D point2 = new Point2D.Double(point1.getX() + dx, point1.getY() + dy);
     72        Point2D point1 = shiftPoint(p1, p2, shift);
     73        Point2D point2 = new Point2D.Double(point1.getX() + dx, point1.getY() + dy);
    7474
    75                 return new Line2D.Double(
    76                                 point1, point2);
    77         }
     75        return new Line2D.Double(
     76                point1, point2);
     77    }
    7878
    79         protected GeneralPath getPath(Graphics2D g, MapView mapView, List<Node> nodes, double shift) {
     79    protected GeneralPath getPath(Graphics2D g, MapView mapView, List<Node> nodes, double shift) {
    8080
    81                 GeneralPath path = new GeneralPath();
     81        GeneralPath path = new GeneralPath();
    8282
    83                 if (nodes.size() < 2) {
    84                         return path;
    85                 }
     83        if (nodes.size() < 2) {
     84            return path;
     85        }
    8686
    87                 Point p1 = null;
    88                 Point p2 = null;
    89                 Point p3 = null;
    90                 Point lastPoint = null;
     87        Point p1 = null;
     88        Point p2 = null;
     89        Point p3 = null;
     90        Point lastPoint = null;
    9191
    92                 for (Node n: nodes) {
    93                         Point p = mapView.getPoint(n);
     92        for (Node n: nodes) {
     93            Point p = mapView.getPoint(n);
    9494
    95                         if (!p.equals(p3)) {
    96                                 p1 = p2;
    97                                 p2 = p3;
    98                                 p3 = p;
    99                         } else {
    100                                 continue;
    101                         }
     95            if (!p.equals(p3)) {
     96                p1 = p2;
     97                p2 = p3;
     98                p3 = p;
     99            } else {
     100                continue;
     101            }
    102102
    103                         p = null;
    104                         if (p2 != null) {
    105                                 if (p1 == null) {
    106                                         p = shiftPoint(p2, p3, shift);
    107                                 } else {
    108                                         Line2D.Double line1 = shiftLine(p1, p2, shift);
    109                                         Line2D.Double line2 = shiftLine(p2, p3, shift);
     103            p = null;
     104            if (p2 != null) {
     105                if (p1 == null) {
     106                    p = shiftPoint(p2, p3, shift);
     107                } else {
     108                    Line2D.Double line1 = shiftLine(p1, p2, shift);
     109                    Line2D.Double line2 = shiftLine(p2, p3, shift);
    110110
    111                                         /*path.moveTo((float)line1.x1, (float)line1.y1);
    112                                         path.lineTo((float)line1.x2, (float)line1.y2);
    113                                         path.moveTo((float)line2.x1, (float)line2.y1);
    114                                         path.lineTo((float)line2.x2, (float)line2.y2);*/
     111                    /*path.moveTo((float)line1.x1, (float)line1.y1);
     112                    path.lineTo((float)line1.x2, (float)line1.y2);
     113                    path.moveTo((float)line2.x1, (float)line2.y1);
     114                    path.lineTo((float)line2.x2, (float)line2.y2);*/
    115115
    116                                         p = new Point();
    117                                         if (!getLineLineIntersection(line1, line2, p)) {
    118                                                 p = null;
    119                                         } else {
    120                                                 int dx = p.x - p2.x;
    121                                                 int dy = p.y - p2.y;
    122                                                 int distance = (int)Math.sqrt(dx * dx + dy * dy);
    123                                                 if (distance > 10) {
    124                                                         p.x = p2.x + dx / (distance / 10);
    125                                                         p.y = p2.y + dy / (distance / 10);
    126                                                 }
    127                                         }
    128                                 }
    129                         }
     116                    p = new Point();
     117                    if (!getLineLineIntersection(line1, line2, p)) {
     118                        p = null;
     119                    } else {
     120                        int dx = p.x - p2.x;
     121                        int dy = p.y - p2.y;
     122                        int distance = (int)Math.sqrt(dx * dx + dy * dy);
     123                        if (distance > 10) {
     124                            p.x = p2.x + dx / (distance / 10);
     125                            p.y = p2.y + dy / (distance / 10);
     126                        }
     127                    }
     128                }
     129            }
    130130
    131                         if (p != null && lastPoint != null) {
    132                                 drawSegment(g, mapView, path, lastPoint, p);
    133                         }
    134                         if (p != null) {
    135                                 lastPoint = p;
    136                         }
    137                 }
     131            if (p != null && lastPoint != null) {
     132                drawSegment(g, mapView, path, lastPoint, p);
     133            }
     134            if (p != null) {
     135                lastPoint = p;
     136            }
     137        }
    138138
    139                 if (p2 != null && p3 != null && lastPoint != null) {
    140                         p3 = shiftPoint(p3, p2, -shift);
    141                         drawSegment(g, mapView, path, lastPoint, p3);
    142                 }
     139        if (p2 != null && p3 != null && lastPoint != null) {
     140            p3 = shiftPoint(p3, p2, -shift);
     141            drawSegment(g, mapView, path, lastPoint, p3);
     142        }
    143143
    144                 return path;
    145         }
     144        return path;
     145    }
    146146
    147         private void drawSegment(Graphics2D g, NavigatableComponent nc, GeneralPath path, Point p1, Point p2) {
    148                 boolean drawIt = false;
    149                 if (Main.isOpenjdk) {
    150                         /**
    151                         * Work around openjdk bug. It leads to drawing artefacts when zooming in a lot. (#4289, #4424)
    152                         * (It looks like int overflow when clipping.) We do custom clipping.
    153                         */
    154                         Rectangle bounds = g.getClipBounds();
    155                         bounds.grow(100, 100);                  // avoid arrow heads at the border
    156                         LineClip clip = new LineClip();
    157                         drawIt = clip.cohenSutherland(p1.x, p1.y, p2.x, p2.y, bounds.x, bounds.y, bounds.x+bounds.width, bounds.y+bounds.height);
    158                         if (drawIt) {
    159                                 p1 = clip.getP1();
    160                                 p2 = clip.getP2();
    161                         }
    162                 } else {
    163                         drawIt = isSegmentVisible(nc, p1, p2);
    164                 }
    165                 if (drawIt) {
    166                         /* draw segment line */
    167                         path.moveTo(p1.x, p1.y);
    168                         path.lineTo(p2.x, p2.y);
    169                 }
    170         }
     147    private void drawSegment(Graphics2D g, NavigatableComponent nc, GeneralPath path, Point p1, Point p2) {
     148        boolean drawIt = false;
     149        if (Main.isOpenjdk) {
     150            /**
     151            * Work around openjdk bug. It leads to drawing artefacts when zooming in a lot. (#4289, #4424)
     152            * (It looks like int overflow when clipping.) We do custom clipping.
     153            */
     154            Rectangle bounds = g.getClipBounds();
     155            bounds.grow(100, 100);                  // avoid arrow heads at the border
     156            LineClip clip = new LineClip();
     157            drawIt = clip.cohenSutherland(p1.x, p1.y, p2.x, p2.y, bounds.x, bounds.y, bounds.x+bounds.width, bounds.y+bounds.height);
     158            if (drawIt) {
     159                p1 = clip.getP1();
     160                p2 = clip.getP2();
     161            }
     162        } else {
     163            drawIt = isSegmentVisible(nc, p1, p2);
     164        }
     165        if (drawIt) {
     166            /* draw segment line */
     167            path.moveTo(p1.x, p1.y);
     168            path.lineTo(p2.x, p2.y);
     169        }
     170    }
    171171
    172         private boolean isSegmentVisible(NavigatableComponent nc, Point p1, Point p2) {
    173                 if ((p1.x < 0) && (p2.x < 0)) return false;
    174                 if ((p1.y < 0) && (p2.y < 0)) return false;
    175                 if ((p1.x > nc.getWidth()) && (p2.x > nc.getWidth())) return false;
    176                 if ((p1.y > nc.getHeight()) && (p2.y > nc.getHeight())) return false;
    177                 return true;
    178         }
     172    private boolean isSegmentVisible(NavigatableComponent nc, Point p1, Point p2) {
     173        if ((p1.x < 0) && (p2.x < 0)) return false;
     174        if ((p1.y < 0) && (p2.y < 0)) return false;
     175        if ((p1.x > nc.getWidth()) && (p2.x > nc.getWidth())) return false;
     176        if ((p1.y > nc.getHeight()) && (p2.y > nc.getHeight())) return false;
     177        return true;
     178    }
    179179
    180180
  • applications/editors/josm/plugins/routes/src/org/openstreetmap/josm/plugins/routes/paint/NarrowLinePainter.java

    r21174 r23189  
    1414public class NarrowLinePainter extends AbstractLinePainter {
    1515
    16         private static final float LINE_WIDTH = 5;
    17         private final RouteLayer layer;
     16    private static final float LINE_WIDTH = 5;
     17    private final RouteLayer layer;
    1818
    19         public NarrowLinePainter(RouteLayer layer) {
    20                 this.layer = layer;
    21         }
     19    public NarrowLinePainter(RouteLayer layer) {
     20        this.layer = layer;
     21    }
    2222
    23         public void drawWay(ConvertedWay way, MapView mapView, Graphics2D g) {
    24                 List<Node> nodes = way.getNodes();
    25                 BitSet routes = way.getRoutes();
     23    public void drawWay(ConvertedWay way, MapView mapView, Graphics2D g) {
     24        List<Node> nodes = way.getNodes();
     25        BitSet routes = way.getRoutes();
    2626
    27                 if (nodes.size() < 2) {
    28                         return;
    29                 }
     27        if (nodes.size() < 2) {
     28            return;
     29        }
    3030
    31                 //double totalWidth = LINE_WIDTH + (colors.size() - 1) * 4;
    32                 //double width = totalWidth / colors.size();
    33                 //double shift = -totalWidth / 2 + width / 2;
    34                 double width = LINE_WIDTH;
    35                 double shift = - (LINE_WIDTH * routes.cardinality()) / 2 + width / 2;
     31        //double totalWidth = LINE_WIDTH + (colors.size() - 1) * 4;
     32        //double width = totalWidth / colors.size();
     33        //double shift = -totalWidth / 2 + width / 2;
     34        double width = LINE_WIDTH;
     35        double shift = - (LINE_WIDTH * routes.cardinality()) / 2 + width / 2;
    3636
    37                 for (int k=0; k<routes.length(); k++) {
     37        for (int k=0; k<routes.length(); k++) {
    3838
    39                         if (!routes.get(k)) {
    40                                 continue;
    41                         }
     39            if (!routes.get(k)) {
     40                continue;
     41            }
    4242
    43                         RouteDefinition route = layer.getRoutes().get(k);
     43            RouteDefinition route = layer.getRoutes().get(k);
    4444
    45                         g.setColor(route.getColor());
    46                         g.setStroke(new BasicStroke((float) width));
     45            g.setColor(route.getColor());
     46            g.setStroke(new BasicStroke((float) width));
    4747
    48                         g.draw(getPath(g, mapView, nodes, shift));
     48            g.draw(getPath(g, mapView, nodes, shift));
    4949
    50                         shift += width + 2;
    51                 }
    52         }
     50            shift += width + 2;
     51        }
     52    }
    5353
    5454}
  • applications/editors/josm/plugins/routes/src/org/openstreetmap/josm/plugins/routes/paint/PathPainter.java

    r16428 r23189  
    77
    88public interface PathPainter {
    9        
    10         public void drawWay(ConvertedWay way, MapView mapView, Graphics2D g);
     9
     10    public void drawWay(ConvertedWay way, MapView mapView, Graphics2D g);
    1111
    1212}
  • applications/editors/josm/plugins/routes/src/org/openstreetmap/josm/plugins/routes/paint/WideLinePainter.java

    r21174 r23189  
    1515public class WideLinePainter extends AbstractLinePainter {
    1616
    17         private static final float LINE_WIDTH = 10;
    18         private final RouteLayer layer;
     17    private static final float LINE_WIDTH = 10;
     18    private final RouteLayer layer;
    1919
    20         public WideLinePainter(RouteLayer layer) {
    21                 this.layer = layer;
    22         }
     20    public WideLinePainter(RouteLayer layer) {
     21        this.layer = layer;
     22    }
    2323
    24         public void drawWay(ConvertedWay way, MapView mapView, Graphics2D g) {
    25                 List<Node> nodes = way.getNodes();
    26                 BitSet routes = way.getRoutes();
     24    public void drawWay(ConvertedWay way, MapView mapView, Graphics2D g) {
     25        List<Node> nodes = way.getNodes();
     26        BitSet routes = way.getRoutes();
    2727
    28                 if (nodes.size() < 2) {
    29                         return;
    30                 }
     28        if (nodes.size() < 2) {
     29            return;
     30        }
    3131
    32                 double totalWidth = LINE_WIDTH + (routes.size() - 1) * 4;
    33                 double width = totalWidth / routes.cardinality();
    34                 double shift = -totalWidth / 2 + width / 2;
     32        double totalWidth = LINE_WIDTH + (routes.size() - 1) * 4;
     33        double width = totalWidth / routes.cardinality();
     34        double shift = -totalWidth / 2 + width / 2;
    3535
    36                 for (int k=0; k<routes.length(); k++) {
     36        for (int k=0; k<routes.length(); k++) {
    3737
    38                         if (!routes.get(k)) {
    39                                 continue;
    40                         }
     38            if (!routes.get(k)) {
     39                continue;
     40            }
    4141
    42                         RouteDefinition route = layer.getRoutes().get(k);
     42            RouteDefinition route = layer.getRoutes().get(k);
    4343
    44                         Color color = route.getColor();
    45                         g.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), 100));
    46                         g.setStroke(new BasicStroke((float) width));
     44            Color color = route.getColor();
     45            g.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), 100));
     46            g.setStroke(new BasicStroke((float) width));
    4747
    48                         g.draw(getPath(g, mapView, nodes, shift));
     48            g.draw(getPath(g, mapView, nodes, shift));
    4949
    50                         shift += width;
    51                 }
    52         }
     50            shift += width;
     51        }
     52    }
    5353
    5454}
  • applications/editors/josm/plugins/routes/src/org/openstreetmap/josm/plugins/routes/xml/ObjectFactory.java

    r16593 r23189  
    11//
    2 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 in JDK 6 
    3 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
    4 // Any modifications to this file will be lost upon recompilation of the source schema. 
    5 // Generated on: 2009.07.19 at 03:50:48 odp. CEST 
     2// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 in JDK 6
     3// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
     4// Any modifications to this file will be lost upon recompilation of the source schema.
     5// Generated on: 2009.07.19 at 03:50:48 odp. CEST
    66//
    77
     
    1313
    1414/**
    15  * This object contains factory methods for each 
    16  * Java content interface and Java element interface 
    17  * generated in the org.openstreetmap.josm.plugins.routes.xml package. 
    18  * <p>An ObjectFactory allows you to programatically 
    19  * construct new instances of the Java representation 
    20  * for XML content. The Java representation of XML 
    21  * content can consist of schema derived interfaces 
    22  * and classes representing the binding of schema 
    23  * type definitions, element declarations and model 
    24  * groups.  Factory methods for each of these are 
     15 * This object contains factory methods for each
     16 * Java content interface and Java element interface
     17 * generated in the org.openstreetmap.josm.plugins.routes.xml package.
     18 * <p>An ObjectFactory allows you to programatically
     19 * construct new instances of the Java representation
     20 * for XML content. The Java representation of XML
     21 * content can consist of schema derived interfaces
     22 * and classes representing the binding of schema
     23 * type definitions, element declarations and model
     24 * groups.  Factory methods for each of these are
    2525 * provided in this class.
    26  * 
     26 *
    2727 */
    2828@XmlRegistry
     
    3232    /**
    3333     * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: org.openstreetmap.josm.plugins.routes.xml
    34      * 
     34     *
    3535     */
    3636    public ObjectFactory() {
     
    3939    /**
    4040     * Create an instance of {@link RoutesXMLRoute }
    41      * 
     41     *
    4242     */
    4343    public RoutesXMLRoute createRoutesXMLRoute() {
     
    4747    /**
    4848     * Create an instance of {@link RoutesXMLLayer }
    49      * 
     49     *
    5050     */
    5151    public RoutesXMLLayer createRoutesXMLLayer() {
     
    5555    /**
    5656     * Create an instance of {@link Routes }
    57      * 
     57     *
    5858     */
    5959    public Routes createRoutes() {
  • applications/editors/josm/plugins/routes/src/org/openstreetmap/josm/plugins/routes/xml/Routes.java

    r16593 r23189  
    11//
    2 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 in JDK 6 
    3 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
    4 // Any modifications to this file will be lost upon recompilation of the source schema. 
    5 // Generated on: 2009.07.19 at 03:50:48 odp. CEST 
     2// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 in JDK 6
     3// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
     4// Any modifications to this file will be lost upon recompilation of the source schema.
     5// Generated on: 2009.07.19 at 03:50:48 odp. CEST
    66//
    77
     
    1919/**
    2020 * <p>Java class for anonymous complex type.
    21  * 
     21 *
    2222 * <p>The following schema fragment specifies the expected content contained within this class.
    23  * 
     23 *
    2424 * <pre>
    2525 * &lt;complexType>
     
    3333 * &lt;/complexType>
    3434 * </pre>
    35  * 
    36  * 
     35 *
     36 *
    3737 */
    3838@XmlAccessorType(XmlAccessType.FIELD)
     
    4747    /**
    4848     * Gets the value of the layer property.
    49      * 
     49     *
    5050     * <p>
    5151     * This accessor method returns a reference to the live list,
     
    5353     * returned list will be present inside the JAXB object.
    5454     * This is why there is not a <CODE>set</CODE> method for the layer property.
    55      * 
     55     *
    5656     * <p>
    5757     * For example, to add a new item, do as follows:
     
    5959     *    getLayer().add(newItem);
    6060     * </pre>
    61      * 
    62      * 
     61     *
     62     *
    6363     * <p>
    6464     * Objects of the following type(s) are allowed in the list
    6565     * {@link RoutesXMLLayer }
    66      * 
    67      * 
     66     *
     67     *
    6868     */
    6969    public List<RoutesXMLLayer> getLayer() {
  • applications/editors/josm/plugins/routes/src/org/openstreetmap/josm/plugins/routes/xml/RoutesXMLLayer.java

    r16593 r23189  
    11//
    2 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 in JDK 6 
    3 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
    4 // Any modifications to this file will be lost upon recompilation of the source schema. 
    5 // Generated on: 2009.07.19 at 03:50:48 odp. CEST 
     2// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 in JDK 6
     3// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
     4// Any modifications to this file will be lost upon recompilation of the source schema.
     5// Generated on: 2009.07.19 at 03:50:48 odp. CEST
    66//
    77
     
    1919/**
    2020 * <p>Java class for layer complex type.
    21  * 
     21 *
    2222 * <p>The following schema fragment specifies the expected content contained within this class.
    23  * 
     23 *
    2424 * <pre>
    2525 * &lt;complexType name="layer">
     
    3535 * &lt;/complexType>
    3636 * </pre>
    37  * 
    38  * 
     37 *
     38 *
    3939 */
    4040@XmlAccessorType(XmlAccessType.FIELD)
     
    5252    /**
    5353     * Gets the value of the route property.
    54      * 
     54     *
    5555     * <p>
    5656     * This accessor method returns a reference to the live list,
     
    5858     * returned list will be present inside the JAXB object.
    5959     * This is why there is not a <CODE>set</CODE> method for the route property.
    60      * 
     60     *
    6161     * <p>
    6262     * For example, to add a new item, do as follows:
     
    6464     *    getRoute().add(newItem);
    6565     * </pre>
    66      * 
    67      * 
     66     *
     67     *
    6868     * <p>
    6969     * Objects of the following type(s) are allowed in the list
    7070     * {@link RoutesXMLRoute }
    71      * 
    72      * 
     71     *
     72     *
    7373     */
    7474    public List<RoutesXMLRoute> getRoute() {
     
    8181    /**
    8282     * Gets the value of the name property.
    83      * 
     83     *
    8484     * @return
    8585     *     possible object is
    8686     *     {@link String }
    87      *     
     87     *
    8888     */
    8989    public String getName() {
     
    9393    /**
    9494     * Sets the value of the name property.
    95      * 
     95     *
    9696     * @param value
    9797     *     allowed object is
    9898     *     {@link String }
    99      *     
     99     *
    100100     */
    101101    public void setName(String value) {
     
    105105    /**
    106106     * Gets the value of the enabled property.
    107      * 
     107     *
    108108     * @return
    109109     *     possible object is
    110110     *     {@link Boolean }
    111      *     
     111     *
    112112     */
    113113    public boolean isEnabled() {
     
    121121    /**
    122122     * Sets the value of the enabled property.
    123      * 
     123     *
    124124     * @param value
    125125     *     allowed object is
    126126     *     {@link Boolean }
    127      *     
     127     *
    128128     */
    129129    public void setEnabled(Boolean value) {
  • applications/editors/josm/plugins/routes/src/org/openstreetmap/josm/plugins/routes/xml/RoutesXMLRoute.java

    r16593 r23189  
    11//
    2 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 in JDK 6 
    3 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
    4 // Any modifications to this file will be lost upon recompilation of the source schema. 
    5 // Generated on: 2009.07.19 at 03:50:48 odp. CEST 
     2// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 in JDK 6
     3// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
     4// Any modifications to this file will be lost upon recompilation of the source schema.
     5// Generated on: 2009.07.19 at 03:50:48 odp. CEST
    66//
    77
     
    1818/**
    1919 * <p>Java class for route complex type.
    20  * 
     20 *
    2121 * <p>The following schema fragment specifies the expected content contained within this class.
    22  * 
     22 *
    2323 * <pre>
    2424 * &lt;complexType name="route">
     
    3434 * &lt;/complexType>
    3535 * </pre>
    36  * 
    37  * 
     36 *
     37 *
    3838 */
    3939@XmlAccessorType(XmlAccessType.FIELD)
     
    5252    /**
    5353     * Gets the value of the pattern property.
    54      * 
     54     *
    5555     * @return
    5656     *     possible object is
    5757     *     {@link String }
    58      *     
     58     *
    5959     */
    6060    public String getPattern() {
     
    6464    /**
    6565     * Sets the value of the pattern property.
    66      * 
     66     *
    6767     * @param value
    6868     *     allowed object is
    6969     *     {@link String }
    70      *     
     70     *
    7171     */
    7272    public void setPattern(String value) {
     
    7676    /**
    7777     * Gets the value of the color property.
    78      * 
     78     *
    7979     * @return
    8080     *     possible object is
    8181     *     {@link String }
    82      *     
     82     *
    8383     */
    8484    public String getColor() {
     
    8888    /**
    8989     * Sets the value of the color property.
    90      * 
     90     *
    9191     * @param value
    9292     *     allowed object is
    9393     *     {@link String }
    94      *     
     94     *
    9595     */
    9696    public void setColor(String value) {
     
    100100    /**
    101101     * Gets the value of the enabled property.
    102      * 
     102     *
    103103     * @return
    104104     *     possible object is
    105105     *     {@link Boolean }
    106      *     
     106     *
    107107     */
    108108    public boolean isEnabled() {
     
    116116    /**
    117117     * Sets the value of the enabled property.
    118      * 
     118     *
    119119     * @param value
    120120     *     allowed object is
    121121     *     {@link Boolean }
    122      *     
     122     *
    123123     */
    124124    public void setEnabled(Boolean value) {
  • applications/editors/josm/plugins/routes/src/org/openstreetmap/josm/plugins/routes/xml/package-info.java

    r16593 r23189  
    11//
    2 // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 in JDK 6 
    3 // See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
    4 // Any modifications to this file will be lost upon recompilation of the source schema. 
    5 // Generated on: 2009.07.19 at 03:50:48 odp. CEST 
     2// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 in JDK 6
     3// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
     4// Any modifications to this file will be lost upon recompilation of the source schema.
     5// Generated on: 2009.07.19 at 03:50:48 odp. CEST
    66//
    77
  • applications/editors/josm/plugins/routing/src/com/innovant/josm/jrt/core/EdgeIterator.java

    r15707 r23189  
    44
    55    public boolean hasNext();
    6    
     6
    77    public RoutingEdge next();
    88
  • applications/editors/josm/plugins/routing/src/com/innovant/josm/jrt/core/RoutingEdge.java

    r15707 r23189  
    88
    99      public LatLon toLatLon();
    10      
     10
    1111      public Object fromV();
    1212
     
    1414
    1515      public double getLength();
    16      
     16
    1717      public void setLength(double length);
    18      
     18
    1919      public double getSpeed();
    2020
    2121      public void setSpeed(double speed);
    22      
     22
    2323      public boolean isOneway();
    24      
     24
    2525      public void setOneway(boolean isOneway);
    2626
  • applications/editors/josm/plugins/routing/src/com/innovant/josm/jrt/core/RoutingGraphDelegator.java

    r15707 r23189  
    11/**
    2  * 
     2 *
    33 */
    44package com.innovant.josm.jrt.core;
     
    2323     */
    2424    static Logger logger = Logger.getLogger(RoutingGraphDelegator.class);
    25    
     25
    2626    /**
    2727     *
    2828     */
    2929    private RouteType routeType;
    30    
     30
    3131    public RoutingGraphDelegator(Graph<Node, OsmEdge> arg0) {
    3232        super(arg0);
    3333    }
    34    
     34
    3535
    3636    public RouteType getRouteType() {
     
    4444
    4545    /**
    46      * 
     46     *
    4747     */
    4848    private static final long serialVersionUID = 1L;
     
    5151    public double getEdgeWeight(OsmEdge edge) {
    5252        double weight=Double.MAX_VALUE;
    53        
     53
    5454        if (routeType==RouteType.SHORTEST) weight=edge.getLength();
    5555        if (routeType==RouteType.FASTEST) weight=edge.getLength() / edge.getSpeed();
  • applications/editors/josm/plugins/routing/src/com/innovant/josm/jrt/osm/OsmEdge.java

    r16290 r23189  
    9494    return length;
    9595  }
    96  
     96
    9797  public void setLength(double length) {
    9898    this.length = length;
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/LaunchAction.java

    r20079 r23189  
    2121public class LaunchAction extends JosmAction implements SelectionChangedListener {
    2222
    23         public LaunchAction()  {
    24                 super(
    25                                 tr("Edit tags"),
    26                                 null, //TODO: set "tag-editor" and add /images/tag-editor.png to distrib
    27                                 tr("Launches the tag editor dialog"),
    28                                 Shortcut.registerShortcut(
    29                                                 "edit:launchtageditor",
    30                                                 tr("Launches the tag editor dialog"),
    31                                                 KeyEvent.VK_T,
    32                                                 Shortcut.GROUP_EDIT),
    33                                                 true
    34                 );
     23    public LaunchAction()  {
     24        super(
     25                tr("Edit tags"),
     26                null, //TODO: set "tag-editor" and add /images/tag-editor.png to distrib
     27                tr("Launches the tag editor dialog"),
     28                Shortcut.registerShortcut(
     29                        "edit:launchtageditor",
     30                        tr("Launches the tag editor dialog"),
     31                        KeyEvent.VK_T,
     32                        Shortcut.GROUP_EDIT),
     33                        true
     34        );
    3535
    36                 DataSet.selListeners.add(this);
    37                 setEnabled(false);
    38         }
     36        DataSet.selListeners.add(this);
     37        setEnabled(false);
     38    }
    3939
    40         /**
    41         * launch the editor
    42         */
    43         protected void launchEditor() {
    44                 if (!isEnabled())
    45                         return;
    46                 TagEditorDialog dialog = TagEditorDialog.getInstance();
    47                 dialog.startEditSession();
    48                 dialog.setVisible(true);
    49         }
     40    /**
     41    * launch the editor
     42    */
     43    protected void launchEditor() {
     44        if (!isEnabled())
     45            return;
     46        TagEditorDialog dialog = TagEditorDialog.getInstance();
     47        dialog.startEditSession();
     48        dialog.setVisible(true);
     49    }
    5050
    51         public void actionPerformed(ActionEvent e) {
    52                 launchEditor();
    53         }
     51    public void actionPerformed(ActionEvent e) {
     52        launchEditor();
     53    }
    5454
    55         public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
    56                 setEnabled(newSelection != null && newSelection.size() >0);
    57         }
     55    public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
     56        setEnabled(newSelection != null && newSelection.size() >0);
     57    }
    5858}
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/TagEditorDialog.java

    r21024 r23189  
    5050@SuppressWarnings("serial")
    5151public class TagEditorDialog extends JDialog {
    52         static private final Logger logger = Logger.getLogger(TagEditorDialog.class.getName());
    53 
    54         /** the unique instance */
    55         static private  TagEditorDialog instance = null;
    56 
    57         /**
    58         * Access to the singleton instance
    59         *
    60         * @return the singleton instance of the dialog
    61         */
    62         static public TagEditorDialog getInstance() {
    63                 if (instance == null) {
    64                         instance = new TagEditorDialog();
    65                 }
    66                 return instance;
    67         }
    68 
    69         /** default preferred size */
    70         static public final Dimension PREFERRED_SIZE = new Dimension(700, 500);
    71 
    72         /** the properties table */
    73         private TagEditor tagEditor = null;
    74 
    75         /**  the auto completion list viewer */
    76         private AutoCompletionListViewer aclViewer = null;
    77 
    78         /** the cache of auto completion values used by the tag editor */
    79         private AutoCompletionManager autocomplete = null;
    80 
    81         private OKAction okAction = null;
    82         private CancelAction cancelAction = null;
    83 
    84         /**
    85         * @return the tag editor model
    86         */
    87         public TagEditorModel getModel() {
    88                 return tagEditor.getModel();
    89         }
    90 
    91         protected JPanel buildButtonRow() {
    92                 JPanel pnl = new JPanel(new FlowLayout(FlowLayout.CENTER));
    93                
    94                 // the ok button
    95                 //
    96                 pnl.add(new JButton(okAction = new OKAction()));
    97                 getModel().addPropertyChangeListener(okAction);
    98 
    99                 // the cancel button
    100                 //
    101                 pnl.add(new JButton(cancelAction  = new CancelAction()));
    102                 return pnl;
    103         }
    104 
    105         protected JPanel buildTagGridPanel() {
    106                 // create tag editor and inject an instance of the tag
    107                 // editor model
    108                 //
    109                 tagEditor = new TagEditor();
    110                
    111                 // create the auto completion list viewer and connect it
    112                 // to the tag editor
    113                 //
    114                 AutoCompletionList autoCompletionList = new AutoCompletionList();
    115                 aclViewer = new AutoCompletionListViewer(autoCompletionList);
    116                 tagEditor.setAutoCompletionList(autoCompletionList);
    117                 aclViewer.addAutoCompletionListListener(tagEditor);
    118                 tagEditor.addComponentNotStoppingCellEditing(aclViewer);
    119 
    120                 JPanel pnlTagGrid = new JPanel();
    121                 pnlTagGrid.setLayout(new BorderLayout());
    122                
    123                
    124                 pnlTagGrid.add(tagEditor, BorderLayout.CENTER);
    125                 pnlTagGrid.add(aclViewer, BorderLayout.EAST);
    126                 pnlTagGrid.setBorder(BorderFactory.createEmptyBorder(5, 0,0,0));
    127                
    128                 JSplitPane splitPane = new JSplitPane(
    129                                 JSplitPane.HORIZONTAL_SPLIT,
    130                                 tagEditor,
    131                                 aclViewer
    132                 );
    133                 splitPane.setOneTouchExpandable(false);
    134                 splitPane.setDividerLocation(600);             
    135                 pnlTagGrid.add(splitPane, BorderLayout.CENTER);
    136                 return pnlTagGrid;
    137         }
    138                
    139         /**
    140         * build the GUI
    141         */
    142         protected void build() {
    143                 getContentPane().setLayout(new BorderLayout());
    144 
    145                 // basic UI prpoperties
    146                 //
    147                 setModal(true);
    148                 setSize(PREFERRED_SIZE);
    149                 setTitle(tr("JOSM Tag Editor Plugin"));
    150                
    151                 JPanel pnlTagGrid = buildTagGridPanel();
    152 
    153                 // create the preset selector
    154                 //
    155                 TabularPresetSelector presetSelector = new TabularPresetSelector();
    156                 presetSelector.addPresetSelectorListener(
    157                                 new IPresetSelectorListener() {
    158                                         public void itemSelected(Item item) {
    159                                                 tagEditor.stopEditing();
    160                                                 tagEditor.getModel().applyPreset(item);
    161                                                 tagEditor.requestFocusInTopLeftCell();
    162                                         }
    163                                 }
    164                 );
    165 
    166                 JPanel pnlPresetSelector = new JPanel();
    167                 pnlPresetSelector.setLayout(new BorderLayout());
    168                 pnlPresetSelector.add(presetSelector,BorderLayout.CENTER);
    169                 pnlPresetSelector.setBorder(BorderFactory.createEmptyBorder(0,0,5,0     ));
    170 
    171                 // create the tag selector
    172                 //
    173                 TabularTagSelector tagSelector = new TabularTagSelector();
    174                 tagSelector.addTagSelectorListener(
    175                                 new ITagSelectorListener() {
    176                                         public void itemSelected(KeyValuePair pair) {
    177                                                 tagEditor.stopEditing();
    178                                                 tagEditor.getModel().applyKeyValuePair(pair);
    179                                                 tagEditor.requestFocusInTopLeftCell();
    180                                         }
    181                                 }
    182                 );
    183                 JPanel pnlTagSelector = new JPanel();
    184                 pnlTagSelector.setLayout(new BorderLayout());
    185                 pnlTagSelector.add(tagSelector,BorderLayout.CENTER);
    186                 pnlTagSelector.setBorder(BorderFactory.createEmptyBorder(0,0,5,0        ));
    187 
    188                 // create the tabbed pane
    189                 //
    190                 JTabbedPane tabbedPane = new JTabbedPane();
    191                 tabbedPane.add(pnlPresetSelector, tr("Presets"));
    192                 tabbedPane.add(pnlTagSelector, tr("Tags"));
    193 
    194                
    195                 // create split pane
    196                 //
    197                 JSplitPane splitPane = new JSplitPane(
    198                                 JSplitPane.VERTICAL_SPLIT,
    199                                 tabbedPane,
    200                                 pnlTagGrid
    201                 );
    202                 splitPane.setOneTouchExpandable(true);
    203                 splitPane.setDividerLocation(200);
    204 
    205                 Dimension minimumSize = new Dimension(100, 50);
    206                 presetSelector.setMinimumSize(minimumSize);
    207                 pnlTagGrid.setMinimumSize(minimumSize);
    208 
    209                 getContentPane().add(splitPane,BorderLayout.CENTER);
    210 
    211                 getContentPane().add(buildButtonRow(), BorderLayout.SOUTH);
    212 
    213 
    214                 addWindowListener(
    215                                 new WindowAdapter() {
    216                                         @Override public void windowActivated(WindowEvent e) {
    217                                                 SwingUtilities.invokeLater(new Runnable(){
    218                                                         public void run()
    219                                                         {
    220                                                                 getModel().ensureOneTag();
    221                                                                 tagEditor.clearSelection();
    222                                                                 tagEditor.requestFocusInTopLeftCell();
    223                                                         }
    224                                                 });
    225                                         }
    226                                 }
    227                 );
    228 
    229                 // makes sure that 'Ctrl-Enter' in the properties table
    230                 // and in the aclViewer is handled by okAction
    231                 //
    232                 getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put((KeyStroke)cancelAction.getValue(Action.ACCELERATOR_KEY), okAction.getValue(AbstractAction.NAME));
    233                 getRootPane().getActionMap().put(cancelAction.getValue(Action.NAME), cancelAction);
    234 
    235                 getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put((KeyStroke)okAction.getValue(Action.ACCELERATOR_KEY), okAction.getValue(AbstractAction.NAME));
    236                 getRootPane().getActionMap().put(okAction.getValue(Action.NAME), okAction);
    237 
    238 
    239                 // make sure the OK action is also enabled in sub components. I registered
    240                 // the action in the input and action maps of the dialogs root pane and I expected
    241                 // it to get triggered regardless of what subcomponent had focus, but it didn't.
    242                 //
    243                 aclViewer.installKeyAction(okAction);
    244                 aclViewer.installKeyAction(cancelAction);
    245                 presetSelector.installKeyAction(okAction);
    246                 presetSelector.installKeyAction(cancelAction);
    247         }
    248 
    249         /**
    250         * constructor
    251         */
    252         protected TagEditorDialog() {
    253                 build();
    254         }
     52    static private final Logger logger = Logger.getLogger(TagEditorDialog.class.getName());
     53
     54    /** the unique instance */
     55    static private  TagEditorDialog instance = null;
     56
     57    /**
     58    * Access to the singleton instance
     59    *
     60    * @return the singleton instance of the dialog
     61    */
     62    static public TagEditorDialog getInstance() {
     63        if (instance == null) {
     64            instance = new TagEditorDialog();
     65        }
     66        return instance;
     67    }
     68
     69    /** default preferred size */
     70    static public final Dimension PREFERRED_SIZE = new Dimension(700, 500);
     71
     72    /** the properties table */
     73    private TagEditor tagEditor = null;
     74
     75    /**  the auto completion list viewer */
     76    private AutoCompletionListViewer aclViewer = null;
     77
     78    /** the cache of auto completion values used by the tag editor */
     79    private AutoCompletionManager autocomplete = null;
     80
     81    private OKAction okAction = null;
     82    private CancelAction cancelAction = null;
     83
     84    /**
     85    * @return the tag editor model
     86    */
     87    public TagEditorModel getModel() {
     88        return tagEditor.getModel();
     89    }
     90
     91    protected JPanel buildButtonRow() {
     92        JPanel pnl = new JPanel(new FlowLayout(FlowLayout.CENTER));
     93       
     94        // the ok button
     95        //
     96        pnl.add(new JButton(okAction = new OKAction()));
     97        getModel().addPropertyChangeListener(okAction);
     98
     99        // the cancel button
     100        //
     101        pnl.add(new JButton(cancelAction  = new CancelAction()));
     102        return pnl;
     103    }
     104
     105    protected JPanel buildTagGridPanel() {
     106        // create tag editor and inject an instance of the tag
     107        // editor model
     108        //
     109        tagEditor = new TagEditor();
     110       
     111        // create the auto completion list viewer and connect it
     112        // to the tag editor
     113        //
     114        AutoCompletionList autoCompletionList = new AutoCompletionList();
     115        aclViewer = new AutoCompletionListViewer(autoCompletionList);
     116        tagEditor.setAutoCompletionList(autoCompletionList);
     117        aclViewer.addAutoCompletionListListener(tagEditor);
     118        tagEditor.addComponentNotStoppingCellEditing(aclViewer);
     119
     120        JPanel pnlTagGrid = new JPanel();
     121        pnlTagGrid.setLayout(new BorderLayout());
     122       
     123       
     124        pnlTagGrid.add(tagEditor, BorderLayout.CENTER);
     125        pnlTagGrid.add(aclViewer, BorderLayout.EAST);
     126        pnlTagGrid.setBorder(BorderFactory.createEmptyBorder(5, 0,0,0));
     127       
     128        JSplitPane splitPane = new JSplitPane(
     129                JSplitPane.HORIZONTAL_SPLIT,
     130                tagEditor,
     131                aclViewer
     132        );
     133        splitPane.setOneTouchExpandable(false);
     134        splitPane.setDividerLocation(600);     
     135        pnlTagGrid.add(splitPane, BorderLayout.CENTER);
     136        return pnlTagGrid;
     137    }
     138       
     139    /**
     140    * build the GUI
     141    */
     142    protected void build() {
     143        getContentPane().setLayout(new BorderLayout());
     144
     145        // basic UI prpoperties
     146        //
     147        setModal(true);
     148        setSize(PREFERRED_SIZE);
     149        setTitle(tr("JOSM Tag Editor Plugin"));
     150       
     151        JPanel pnlTagGrid = buildTagGridPanel();
     152
     153        // create the preset selector
     154        //
     155        TabularPresetSelector presetSelector = new TabularPresetSelector();
     156        presetSelector.addPresetSelectorListener(
     157                new IPresetSelectorListener() {
     158                    public void itemSelected(Item item) {
     159                        tagEditor.stopEditing();
     160                        tagEditor.getModel().applyPreset(item);
     161                        tagEditor.requestFocusInTopLeftCell();
     162                    }
     163                }
     164        );
     165
     166        JPanel pnlPresetSelector = new JPanel();
     167        pnlPresetSelector.setLayout(new BorderLayout());
     168        pnlPresetSelector.add(presetSelector,BorderLayout.CENTER);
     169        pnlPresetSelector.setBorder(BorderFactory.createEmptyBorder(0,0,5,0 ));
     170
     171        // create the tag selector
     172        //
     173        TabularTagSelector tagSelector = new TabularTagSelector();
     174        tagSelector.addTagSelectorListener(
     175                new ITagSelectorListener() {
     176                    public void itemSelected(KeyValuePair pair) {
     177                        tagEditor.stopEditing();
     178                        tagEditor.getModel().applyKeyValuePair(pair);
     179                        tagEditor.requestFocusInTopLeftCell();
     180                    }
     181                }
     182        );
     183        JPanel pnlTagSelector = new JPanel();
     184        pnlTagSelector.setLayout(new BorderLayout());
     185        pnlTagSelector.add(tagSelector,BorderLayout.CENTER);
     186        pnlTagSelector.setBorder(BorderFactory.createEmptyBorder(0,0,5,0    ));
     187
     188        // create the tabbed pane
     189        //
     190        JTabbedPane tabbedPane = new JTabbedPane();
     191        tabbedPane.add(pnlPresetSelector, tr("Presets"));
     192        tabbedPane.add(pnlTagSelector, tr("Tags"));
     193
     194       
     195        // create split pane
     196        //
     197        JSplitPane splitPane = new JSplitPane(
     198                JSplitPane.VERTICAL_SPLIT,
     199                tabbedPane,
     200                pnlTagGrid
     201        );
     202        splitPane.setOneTouchExpandable(true);
     203        splitPane.setDividerLocation(200);
     204
     205        Dimension minimumSize = new Dimension(100, 50);
     206        presetSelector.setMinimumSize(minimumSize);
     207        pnlTagGrid.setMinimumSize(minimumSize);
     208
     209        getContentPane().add(splitPane,BorderLayout.CENTER);
     210
     211        getContentPane().add(buildButtonRow(), BorderLayout.SOUTH);
     212
     213
     214        addWindowListener(
     215                new WindowAdapter() {
     216                    @Override public void windowActivated(WindowEvent e) {
     217                        SwingUtilities.invokeLater(new Runnable(){
     218                            public void run()
     219                            {
     220                                getModel().ensureOneTag();
     221                                tagEditor.clearSelection();
     222                                tagEditor.requestFocusInTopLeftCell();
     223                            }
     224                        });
     225                    }
     226                }
     227        );
     228
     229        // makes sure that 'Ctrl-Enter' in the properties table
     230        // and in the aclViewer is handled by okAction
     231        //
     232        getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put((KeyStroke)cancelAction.getValue(Action.ACCELERATOR_KEY), okAction.getValue(AbstractAction.NAME));
     233        getRootPane().getActionMap().put(cancelAction.getValue(Action.NAME), cancelAction);
     234
     235        getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put((KeyStroke)okAction.getValue(Action.ACCELERATOR_KEY), okAction.getValue(AbstractAction.NAME));
     236        getRootPane().getActionMap().put(okAction.getValue(Action.NAME), okAction);
     237
     238
     239        // make sure the OK action is also enabled in sub components. I registered
     240        // the action in the input and action maps of the dialogs root pane and I expected
     241        // it to get triggered regardless of what subcomponent had focus, but it didn't.
     242        //
     243        aclViewer.installKeyAction(okAction);
     244        aclViewer.installKeyAction(cancelAction);
     245        presetSelector.installKeyAction(okAction);
     246        presetSelector.installKeyAction(cancelAction);
     247    }
     248
     249    /**
     250    * constructor
     251    */
     252    protected TagEditorDialog() {
     253        build();
     254    }
    255255
    256256    @Override
     
    270270    }
    271271
    272         /**
    273         * start an editing session. This method should be called before the dialog
    274         * is shown on the screen, i.e. before {@link Dialog#setVisible(boolean)} is
    275         * called.
    276         */
    277         public void startEditSession() {
    278                 tagEditor.getModel().clearAppliedPresets();
    279                 tagEditor.getModel().initFromJOSMSelection();
    280                 autocomplete = Main.main.getEditLayer().data.getAutoCompletionManager();
    281                 tagEditor.setAutoCompletionManager(autocomplete);
    282                 getModel().ensureOneTag();
    283         }
    284 
    285         class CancelAction extends AbstractAction {
    286                 public CancelAction() {
    287                         putValue(NAME, tr("Cancel"));
    288                         putValue(SMALL_ICON, ImageProvider.get("cancel"));
    289                         putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE,0));
    290                         putValue(SHORT_DESCRIPTION, tr("Abort tag editing and close dialog"));
    291                 }
    292 
    293                 public void actionPerformed(ActionEvent arg0) {
    294                         setVisible(false);
    295                 }
    296         }
    297 
    298         class OKAction extends AbstractAction implements PropertyChangeListener {
    299 
    300                 public OKAction() {
    301                         putValue(NAME, tr("OK"));
    302                         putValue(SMALL_ICON, ImageProvider.get("ok"));
    303                         putValue(SHORT_DESCRIPTION, tr("Apply edited tags and close dialog"));
    304                         putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke("ctrl ENTER"));
    305                 }
    306 
    307                 public void actionPerformed(ActionEvent e) {
    308                         run();
    309                 }
    310 
    311                 public void run() {
    312                         tagEditor.stopEditing();
    313                         setVisible(false);
    314                         tagEditor.getModel().updateJOSMSelection();
    315                         DataSet ds = Main.main.getCurrentDataSet();
    316                         ds.fireSelectionChanged();
    317                         Main.parent.repaint(); // repaint all - drawing could have been changed
    318                 }
    319 
    320                 public void propertyChange(PropertyChangeEvent evt) {
    321                         if (! evt.getPropertyName().equals(TagEditorModel.PROP_DIRTY))
    322                                 return;
    323                         if (! evt.getNewValue().getClass().equals(Boolean.class))
    324                                 return;
    325                         boolean dirty = (Boolean)evt.getNewValue();
    326                         setEnabled(dirty);
    327                 }
    328         }
     272    /**
     273    * start an editing session. This method should be called before the dialog
     274    * is shown on the screen, i.e. before {@link Dialog#setVisible(boolean)} is
     275    * called.
     276    */
     277    public void startEditSession() {
     278        tagEditor.getModel().clearAppliedPresets();
     279        tagEditor.getModel().initFromJOSMSelection();
     280        autocomplete = Main.main.getEditLayer().data.getAutoCompletionManager();
     281        tagEditor.setAutoCompletionManager(autocomplete);
     282        getModel().ensureOneTag();
     283    }
     284
     285    class CancelAction extends AbstractAction {
     286        public CancelAction() {
     287            putValue(NAME, tr("Cancel"));
     288            putValue(SMALL_ICON, ImageProvider.get("cancel"));
     289            putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE,0));
     290            putValue(SHORT_DESCRIPTION, tr("Abort tag editing and close dialog"));
     291        }
     292
     293        public void actionPerformed(ActionEvent arg0) {
     294            setVisible(false);
     295        }
     296    }
     297
     298    class OKAction extends AbstractAction implements PropertyChangeListener {
     299
     300        public OKAction() {
     301            putValue(NAME, tr("OK"));
     302            putValue(SMALL_ICON, ImageProvider.get("ok"));
     303            putValue(SHORT_DESCRIPTION, tr("Apply edited tags and close dialog"));
     304            putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke("ctrl ENTER"));
     305        }
     306
     307        public void actionPerformed(ActionEvent e) {
     308            run();
     309        }
     310
     311        public void run() {
     312            tagEditor.stopEditing();
     313            setVisible(false);
     314            tagEditor.getModel().updateJOSMSelection();
     315            DataSet ds = Main.main.getCurrentDataSet();
     316            ds.fireSelectionChanged();
     317            Main.parent.repaint(); // repaint all - drawing could have been changed
     318        }
     319
     320        public void propertyChange(PropertyChangeEvent evt) {
     321            if (! evt.getPropertyName().equals(TagEditorModel.PROP_DIRTY))
     322                return;
     323            if (! evt.getNewValue().getClass().equals(Boolean.class))
     324                return;
     325            boolean dirty = (Boolean)evt.getNewValue();
     326            setEnabled(dirty);
     327        }
     328    }
    329329}
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/TagEditorPlugin.java

    r20079 r23189  
    77
    88public class TagEditorPlugin extends Plugin {
    9         LaunchAction action;
    10        
    11         /**
    12         * constructor
    13         */
    14         public TagEditorPlugin(PluginInformation info) {
    15                 super(info);
    16                 action = new LaunchAction();
    17                 MainMenu.add(Main.main.menu.editMenu, action);
    18         }
     9    LaunchAction action;
     10   
     11    /**
     12    * constructor
     13    */
     14    public TagEditorPlugin(PluginInformation info) {
     15        super(info);
     16        action = new LaunchAction();
     17        MainMenu.add(Main.main.menu.editMenu, action);
     18    }
    1919}
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/ac/AutoCompletionContext.java

    r20058 r23189  
    55public class AutoCompletionContext {
    66
    7         private boolean selectionIncludesNodes = false;
    8         private boolean selectionIncludesWays = false;
    9         private boolean selectionIncludesRelations = false;
    10         private boolean selectionEmpty = false;
     7    private boolean selectionIncludesNodes = false;
     8    private boolean selectionIncludesWays = false;
     9    private boolean selectionIncludesRelations = false;
     10    private boolean selectionEmpty = false;
    1111
    12         public AutoCompletionContext(){
    13         }
     12    public AutoCompletionContext(){
     13    }
    1414
    15         public void initFromJOSMSelection() {
    16                 selectionIncludesNodes = ! Main.main.getCurrentDataSet().getSelectedNodes().isEmpty();
    17                 selectionIncludesWays = !Main.main.getCurrentDataSet().getSelectedWays().isEmpty();
    18                 selectionIncludesRelations = !Main.main.getCurrentDataSet().getSelectedRelations().isEmpty();
    19                 selectionEmpty = (Main.main.getCurrentDataSet().getSelected().size() == 0);
    20         }
     15    public void initFromJOSMSelection() {
     16        selectionIncludesNodes = ! Main.main.getCurrentDataSet().getSelectedNodes().isEmpty();
     17        selectionIncludesWays = !Main.main.getCurrentDataSet().getSelectedWays().isEmpty();
     18        selectionIncludesRelations = !Main.main.getCurrentDataSet().getSelectedRelations().isEmpty();
     19        selectionEmpty = (Main.main.getCurrentDataSet().getSelected().size() == 0);
     20    }
    2121
    22         public boolean isSelectionEmpty() {
    23                 return selectionEmpty;
    24         }
     22    public boolean isSelectionEmpty() {
     23        return selectionEmpty;
     24    }
    2525
    26         public boolean isSelectionIncludesNodes() {
    27                 return selectionIncludesNodes;
    28         }
     26    public boolean isSelectionIncludesNodes() {
     27        return selectionIncludesNodes;
     28    }
    2929
    30         public void setSelectionIncludesNodes(boolean selectionIncludesNodes) {
    31                 this.selectionIncludesNodes = selectionIncludesNodes;
    32         }
     30    public void setSelectionIncludesNodes(boolean selectionIncludesNodes) {
     31        this.selectionIncludesNodes = selectionIncludesNodes;
     32    }
    3333
    34         public boolean isSelectionIncludesWays() {
    35                 return selectionIncludesWays;
    36         }
     34    public boolean isSelectionIncludesWays() {
     35        return selectionIncludesWays;
     36    }
    3737
    38         public void setSelectionIncludesWays(boolean selectionIncludesWays) {
    39                 this.selectionIncludesWays = selectionIncludesWays;
    40         }
     38    public void setSelectionIncludesWays(boolean selectionIncludesWays) {
     39        this.selectionIncludesWays = selectionIncludesWays;
     40    }
    4141
    42         public boolean isSelectionIncludesRelations() {
    43                 return selectionIncludesRelations;
    44         }
     42    public boolean isSelectionIncludesRelations() {
     43        return selectionIncludesRelations;
     44    }
    4545
    46         public void setSelectionIncludesRelations(boolean selectionIncludesRelations) {
    47                 this.selectionIncludesRelations = selectionIncludesRelations;
    48         }
     46    public void setSelectionIncludesRelations(boolean selectionIncludesRelations) {
     47        this.selectionIncludesRelations = selectionIncludesRelations;
     48    }
    4949}
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/ac/AutoCompletionListRenderer.java

    r20058 r23189  
    2121public class AutoCompletionListRenderer extends JLabel implements TableCellRenderer {
    2222
    23         static public final String RES_OSM_ICON = "/resources/osm.gif";
    24         static public final String RES_SELECTION_ICON = "/resources/selection.gif";
     23    static public final String RES_OSM_ICON = "/resources/osm.gif";
     24    static public final String RES_SELECTION_ICON = "/resources/selection.gif";
    2525
    26         /** the icon used to decorate items of priority
    27         *  {@link AutoCompletionItemPritority#IS_IN_STANDARD}
    28         */
    29         private Icon iconStandard;
     26    /** the icon used to decorate items of priority
     27    *  {@link AutoCompletionItemPritority#IS_IN_STANDARD}
     28    */
     29    private Icon iconStandard;
    3030
    31         /** the icon used to decorate items of priority
    32         *  {@link AutoCompletionItemPritority#IS_IN_SELECTION}
    33         */
    34         private Icon iconSelection;
     31    /** the icon used to decorate items of priority
     32    *  {@link AutoCompletionItemPritority#IS_IN_SELECTION}
     33    */
     34    private Icon iconSelection;
    3535
    36         /**
    37         * constructor
    38         */
    39         public AutoCompletionListRenderer() {
    40                 setOpaque(true);
    41                 loadIcons();
    42         }
     36    /**
     37    * constructor
     38    */
     39    public AutoCompletionListRenderer() {
     40        setOpaque(true);
     41        loadIcons();
     42    }
    4343
    44         /**
    45         * loads the icons
    46         */
    47         protected void loadIcons() {
    48                 URL imgURL = getClass().getResource(RES_OSM_ICON);
    49                 if (imgURL != null) {
    50                         iconStandard = new ImageIcon(imgURL);
    51                 } else {
    52                         System.err.println("Could not load icon: " + RES_OSM_ICON);
    53                         iconStandard = null;
    54                 }
     44    /**
     45    * loads the icons
     46    */
     47    protected void loadIcons() {
     48        URL imgURL = getClass().getResource(RES_OSM_ICON);
     49        if (imgURL != null) {
     50            iconStandard = new ImageIcon(imgURL);
     51        } else {
     52            System.err.println("Could not load icon: " + RES_OSM_ICON);
     53            iconStandard = null;
     54        }
    5555
    56                 imgURL = getClass().getResource(RES_SELECTION_ICON);
    57                 if (imgURL != null) {
    58                         iconSelection = new ImageIcon(imgURL);
    59                 } else {
    60                         System.err.println("Could not load icon: " + RES_SELECTION_ICON);
    61                         iconSelection = null;
    62                 }
    63         }
     56        imgURL = getClass().getResource(RES_SELECTION_ICON);
     57        if (imgURL != null) {
     58            iconSelection = new ImageIcon(imgURL);
     59        } else {
     60            System.err.println("Could not load icon: " + RES_SELECTION_ICON);
     61            iconSelection = null;
     62        }
     63    }
    6464
    65         /**
    66         * prepares the renderer for rendering a specific icon
    67         *
    68         * @param item the item to be rendered
    69         */
    70         protected void prepareRendererIcon(AutoCompletionListItem item) {
    71                 if (item.getPriority().equals(AutoCompletionItemPritority.IS_IN_STANDARD)) {
    72                         if (iconStandard != null) {
    73                                 setIcon(iconStandard);
    74                         }
    75                 } else if (item.getPriority().equals(AutoCompletionItemPritority.IS_IN_SELECTION)) {
    76                         if (iconSelection != null) {
    77                                 setIcon(iconSelection);
    78                         }
    79                 }
    80         }
     65    /**
     66    * prepares the renderer for rendering a specific icon
     67    *
     68    * @param item the item to be rendered
     69    */
     70    protected void prepareRendererIcon(AutoCompletionListItem item) {
     71        if (item.getPriority().equals(AutoCompletionItemPritority.IS_IN_STANDARD)) {
     72            if (iconStandard != null) {
     73                setIcon(iconStandard);
     74            }
     75        } else if (item.getPriority().equals(AutoCompletionItemPritority.IS_IN_SELECTION)) {
     76            if (iconSelection != null) {
     77                setIcon(iconSelection);
     78            }
     79        }
     80    }
    8181
    82         /**
    83         * resets the renderer
    84         */
    85         protected void resetRenderer() {
    86                 setIcon(null);
    87                 setText("");
    88                 setFont(UIManager.getFont("Table.font"));
    89                 setOpaque(true);
    90                 setBackground(UIManager.getColor("Table.background"));
    91                 setForeground(UIManager.getColor("Table.foreground"));
    92         }
     82    /**
     83    * resets the renderer
     84    */
     85    protected void resetRenderer() {
     86        setIcon(null);
     87        setText("");
     88        setFont(UIManager.getFont("Table.font"));
     89        setOpaque(true);
     90        setBackground(UIManager.getColor("Table.background"));
     91        setForeground(UIManager.getColor("Table.foreground"));
     92    }
    9393
    94         /**
    95         * prepares background and text colors for a selected item
    96         */
    97         protected void renderSelected() {
    98                 setBackground(UIManager.getColor("Table.selectionBackground"));
    99                 setForeground(UIManager.getColor("Table.selectionForeground"));
    100         }
     94    /**
     95    * prepares background and text colors for a selected item
     96    */
     97    protected void renderSelected() {
     98        setBackground(UIManager.getColor("Table.selectionBackground"));
     99        setForeground(UIManager.getColor("Table.selectionForeground"));
     100    }
    101101
    102         public Component getTableCellRendererComponent(JTable table, Object value,
    103                         boolean isSelected, boolean hasFocus, int row, int column) {
     102    public Component getTableCellRendererComponent(JTable table, Object value,
     103            boolean isSelected, boolean hasFocus, int row, int column) {
    104104
    105                 resetRenderer();
    106                 // set icon and text
    107                 //
    108                 if (value instanceof AutoCompletionListItem) {
    109                         AutoCompletionListItem item = (AutoCompletionListItem)value;
    110                         prepareRendererIcon(item);
    111                         setText(item.getValue());
    112                         setToolTipText(item.getValue());
    113                 } else if (value != null) {
    114                         setText(value.toString());
    115                         setToolTipText(value.toString());
    116                 } else {
    117                         setText(tr("unknown"));
    118                         setFont(getFont().deriveFont(Font.ITALIC));
    119                 }
     105        resetRenderer();
     106        // set icon and text
     107        //
     108        if (value instanceof AutoCompletionListItem) {
     109            AutoCompletionListItem item = (AutoCompletionListItem)value;
     110            prepareRendererIcon(item);
     111            setText(item.getValue());
     112            setToolTipText(item.getValue());
     113        } else if (value != null) {
     114            setText(value.toString());
     115            setToolTipText(value.toString());
     116        } else {
     117            setText(tr("unknown"));
     118            setFont(getFont().deriveFont(Font.ITALIC));
     119        }
    120120
    121                 // prepare background and foreground for a selected item
    122                 //
    123                 if (isSelected) {
    124                         renderSelected();
    125                 }
    126                 return this;
    127         }
     121        // prepare background and foreground for a selected item
     122        //
     123        if (isSelected) {
     124            renderSelected();
     125        }
     126        return this;
     127    }
    128128}
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/ac/AutoCompletionListViewer.java

    r20058 r23189  
    2222
    2323public class AutoCompletionListViewer extends JPanel {
    24        
    25         static private Logger logger = Logger.getLogger(AutoCompletionListViewer.class.getName());
     24   
     25    static private Logger logger = Logger.getLogger(AutoCompletionListViewer.class.getName());
    2626
    27         /** the table showing the auto completion list entries */
    28         private JTable table = null;
    29        
    30         /** the auto completion list to be displayed */
    31         private AutoCompletionList autoCompletionList = null;
    32        
    33         /** the listeners */
    34         private ArrayList<IAutoCompletionListListener> listener = null;
    35        
    36         /**
    37         * creates the GUI
    38         */
    39         protected void createGUI() {
    40                 setBackground(Color.WHITE);
    41                 setLayout(new BorderLayout());
    42        
    43                 table = new JTable();
    44                
    45                 // the table model
    46                 //
    47                 if (autoCompletionList == null) {
    48                         //logger.info("setting model to default model");
    49                         table.setModel(new DefaultTableModel());
    50                 } else {
    51                         //logger.info("setting model to " + autoCompletionList);
    52                         table.setModel(autoCompletionList);
    53                 }
    54                
    55                 // no table header required
    56                 table.setTableHeader(null);
    57                
    58                 // set cell renderer
    59                 //
    60                 table.setDefaultRenderer(Object.class, new AutoCompletionListRenderer());
    61                
    62                 // embed in a scroll pane
    63                 JScrollPane p  = new JScrollPane(table);
    64                 p.setBackground(Color.WHITE);
    65                 add(p, BorderLayout.CENTER);
    66                
    67                 // only single selection allowed
    68                 //
    69                 table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    70                
    71                 // fire item change event on double click
    72                 //
    73                 table.addMouseListener(
    74                                 new MouseAdapter() {
    75                                         @Override
    76                                         public void mouseClicked(MouseEvent e) {
    77                                                 if (e.getClickCount() == 2) {
    78                                                         int row = table.getSelectedRow();
    79                                                         String item = autoCompletionList.getFilteredItem(row).getValue();
    80                                                         fireAutoCompletionListItemSelected(item);
    81                                                 }
    82                                         }                                       
    83                                 }
    84                 );
    85         }
    86        
    87         /**
    88         * constructor
    89         *
    90         * @param list the auto completion list to be rendered. If null, the list is empty.
    91        
    92         */
    93         public AutoCompletionListViewer(AutoCompletionList list) {             
    94                 this.autoCompletionList = list;
    95                 createGUI();
    96                 listener = new ArrayList<IAutoCompletionListListener>();
    97         }
    98        
    99         /**
    100         * constructor
    101         */
    102         public AutoCompletionListViewer() {
    103                 this.autoCompletionList = null;
    104                 createGUI();
    105                 listener = new ArrayList<IAutoCompletionListListener>();
    106         }
     27    /** the table showing the auto completion list entries */
     28    private JTable table = null;
     29   
     30    /** the auto completion list to be displayed */
     31    private AutoCompletionList autoCompletionList = null;
     32   
     33    /** the listeners */
     34    private ArrayList<IAutoCompletionListListener> listener = null;
     35   
     36    /**
     37    * creates the GUI
     38    */
     39    protected void createGUI() {
     40        setBackground(Color.WHITE);
     41        setLayout(new BorderLayout());
     42   
     43        table = new JTable();
     44       
     45        // the table model
     46        //
     47        if (autoCompletionList == null) {
     48            //logger.info("setting model to default model");
     49            table.setModel(new DefaultTableModel());
     50        } else {
     51            //logger.info("setting model to " + autoCompletionList);
     52            table.setModel(autoCompletionList);
     53        }
     54       
     55        // no table header required
     56        table.setTableHeader(null);
     57       
     58        // set cell renderer
     59        //
     60        table.setDefaultRenderer(Object.class, new AutoCompletionListRenderer());
     61       
     62        // embed in a scroll pane
     63        JScrollPane p  = new JScrollPane(table);
     64        p.setBackground(Color.WHITE);
     65        add(p, BorderLayout.CENTER);
     66       
     67        // only single selection allowed
     68        //
     69        table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
     70       
     71        // fire item change event on double click
     72        //
     73        table.addMouseListener(
     74                new MouseAdapter() {
     75                    @Override
     76                    public void mouseClicked(MouseEvent e) {
     77                        if (e.getClickCount() == 2) {
     78                            int row = table.getSelectedRow();
     79                            String item = autoCompletionList.getFilteredItem(row).getValue();
     80                            fireAutoCompletionListItemSelected(item);
     81                        }
     82                    }                   
     83                }
     84        );
     85    }
     86   
     87    /**
     88    * constructor
     89    *
     90    * @param list the auto completion list to be rendered. If null, the list is empty.
     91   
     92    */
     93    public AutoCompletionListViewer(AutoCompletionList list) {     
     94        this.autoCompletionList = list;
     95        createGUI();
     96        listener = new ArrayList<IAutoCompletionListListener>();
     97    }
     98   
     99    /**
     100    * constructor
     101    */
     102    public AutoCompletionListViewer() {
     103        this.autoCompletionList = null;
     104        createGUI();
     105        listener = new ArrayList<IAutoCompletionListListener>();
     106    }
    107107
    108         /**
    109         *
    110         */
    111         @Override public Dimension getMaximumSize() {      
    112             Dimension d = super.getMaximumSize();
    113             d.width = 100;
    114             return d;
     108    /**
     109    *
     110    */
     111    @Override public Dimension getMaximumSize() {      
     112        Dimension d = super.getMaximumSize();
     113        d.width = 100;
     114        return d;
    115115    }
    116        
    117         /**
    118         *
    119         */
    120         @Override public Dimension getPreferredSize() {    
    121             Dimension d = super.getMaximumSize();
    122             d.width = 150;
    123             return d;
     116   
     117    /**
     118    *
     119    */
     120    @Override public Dimension getPreferredSize() {    
     121        Dimension d = super.getMaximumSize();
     122        d.width = 150;
     123        return d;
    124124    }
    125125
    126126
    127         /**
    128         * replies the auto completion list this viewer renders
    129         *
    130         * @return the auto completion list; may be null
    131         */
    132         public AutoCompletionList getAutoCompletionList() {
    133         return autoCompletionList;
     127    /**
     128    * replies the auto completion list this viewer renders
     129    *
     130    * @return the auto completion list; may be null
     131    */
     132    public AutoCompletionList getAutoCompletionList() {
     133        return autoCompletionList;
    134134    }
    135135
    136136
    137         /**
    138         * sets the auto completion list this viewer renders
    139         *
    140         * @param autoCompletionList  the auto completion list; may be null
    141         */
    142         public void setAutoCompletionList(AutoCompletionList autoCompletionList) {
    143         this.autoCompletionList = autoCompletionList;
    144         if (autoCompletionList == null) {
    145                 table.setModel(new DefaultTableModel());
    146         } else {
    147                 table.setModel(autoCompletionList);
    148         }
     137    /**
     138    * sets the auto completion list this viewer renders
     139    *
     140    * @param autoCompletionList  the auto completion list; may be null
     141    */
     142    public void setAutoCompletionList(AutoCompletionList autoCompletionList) {
     143        this.autoCompletionList = autoCompletionList;
     144        if (autoCompletionList == null) {
     145            table.setModel(new DefaultTableModel());
     146        } else {
     147            table.setModel(autoCompletionList);
     148        }
    149149    }
    150        
    151         /**
    152         * add an {@link IAutoCompletionListListener}
    153         *
    154         * @param listener  the listener
    155         */
    156         public void addAutoCompletionListListener(IAutoCompletionListListener listener) {
    157                 if (listener != null && !this.listener.contains(listener)) {
    158                         synchronized(this.listener) {
    159                                 this.listener.add(listener);
    160                         }
    161                 }
    162         }
    163        
    164         /**
    165         * removes a {@link IAutoCompletionListListener}
    166         *
    167         * @param listener the listener
    168         */
    169         public void removeAutoCompletionListListener(IAutoCompletionListListener listener) {
    170                 if (listener != null && this.listener.contains(listener)) {
    171                         synchronized(this.listener) {
    172                                 this.listener.remove(listener);
    173                         }
    174                 }
    175         }
    176        
    177         /**
    178         * notifies listeners about a selected item in the auto completion list 
    179         */
    180         protected void fireAutoCompletionListItemSelected(String item) {
    181                 synchronized(this.listener) {
    182                         for (IAutoCompletionListListener target: listener) {
    183                                 target.autoCompletionItemSelected(item);
    184                         }                       
    185                 }
    186         }       
    187        
    188         public void installKeyAction(Action a) {
    189                 getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put((KeyStroke)a.getValue(AbstractAction.ACCELERATOR_KEY), a.getValue(AbstractAction.NAME));
    190                 getActionMap().put(a.getValue(AbstractAction.NAME), a);
     150   
     151    /**
     152    * add an {@link IAutoCompletionListListener}
     153    *
     154    * @param listener  the listener
     155    */
     156    public void addAutoCompletionListListener(IAutoCompletionListListener listener) {
     157        if (listener != null && !this.listener.contains(listener)) {
     158            synchronized(this.listener) {
     159                this.listener.add(listener);
     160            }
     161        }
     162    }
     163   
     164    /**
     165    * removes a {@link IAutoCompletionListListener}
     166    *
     167    * @param listener the listener
     168    */
     169    public void removeAutoCompletionListListener(IAutoCompletionListListener listener) {
     170        if (listener != null && this.listener.contains(listener)) {
     171            synchronized(this.listener) {
     172                this.listener.remove(listener);
     173            }
     174        }
     175    }
     176   
     177    /**
     178    * notifies listeners about a selected item in the auto completion list 
     179    */
     180    protected void fireAutoCompletionListItemSelected(String item) {
     181        synchronized(this.listener) {
     182            for (IAutoCompletionListListener target: listener) {
     183                target.autoCompletionItemSelected(item);
     184            }           
     185        }
     186    }   
     187   
     188    public void installKeyAction(Action a) {
     189        getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put((KeyStroke)a.getValue(AbstractAction.ACCELERATOR_KEY), a.getValue(AbstractAction.NAME));
     190        getActionMap().put(a.getValue(AbstractAction.NAME), a);
    191191
    192         }
     192    }
    193193}
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/ac/IAutoCompletionListListener.java

    r14324 r23189  
    22
    33public interface IAutoCompletionListListener {
    4         public void autoCompletionItemSelected(String item);
     4    public void autoCompletionItemSelected(String item);
    55}
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/PresetItemListCellRenderer.java

    r20058 r23189  
    1414
    1515public class PresetItemListCellRenderer extends JLabel implements ListCellRenderer {
    16         private static final Logger logger = Logger.getLogger(PresetItemListCellRenderer.class.getName());
     16    private static final Logger logger = Logger.getLogger(PresetItemListCellRenderer.class.getName());
    1717
    18         public Component getListCellRendererComponent(JList list, Object value,
    19                         int index, boolean isSelected, boolean cellHasFocus) {
     18    public Component getListCellRendererComponent(JList list, Object value,
     19            int index, boolean isSelected, boolean cellHasFocus) {
    2020
    21                 Item item = (Item)value;
    22                 if (item == null) {
    23                         setText(tr("(none)"));
    24                         setIcon(null);
    25                 } else {
    26                         if (isSelected) {
    27                                 setBackground(UIManager.getColor("Table.selectionBackground"));
    28                                 setForeground(UIManager.getColor("Table.selectionForeground"));
    29                         } else {
    30                                 setBackground(UIManager.getColor("Table.background"));
    31                                 setForeground(UIManager.getColor("Table.foreground"));
    32                         }
    33                         setIcon(item.getIcon());
    34                         StringBuilder sb = new StringBuilder();
    35                         sb.append(item.getParent().getName())
    36                         .append("/")
    37                         .append(item.getName());
    38                         setText(sb.toString());
    39                         setOpaque(true);
    40                         setFont(UIManager.getFont("Table.font"));
    41                 }
    42                 return this;
    43         }
     21        Item item = (Item)value;
     22        if (item == null) {
     23            setText(tr("(none)"));
     24            setIcon(null);
     25        } else {
     26            if (isSelected) {
     27                setBackground(UIManager.getColor("Table.selectionBackground"));
     28                setForeground(UIManager.getColor("Table.selectionForeground"));
     29            } else {
     30                setBackground(UIManager.getColor("Table.background"));
     31                setForeground(UIManager.getColor("Table.foreground"));
     32            }
     33            setIcon(item.getIcon());
     34            StringBuilder sb = new StringBuilder();
     35            sb.append(item.getParent().getName())
     36            .append("/")
     37            .append(item.getName());
     38            setText(sb.toString());
     39            setOpaque(true);
     40            setFont(UIManager.getFont("Table.font"));
     41        }
     42        return this;
     43    }
    4444}
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/PresetManager.java

    r20058 r23189  
    1919public class PresetManager extends JPanel {
    2020
    21         static private final Logger logger = Logger.getLogger(PresetManager.class.getName());
     21    static private final Logger logger = Logger.getLogger(PresetManager.class.getName());
    2222
    23         private JComboBox presets;
    24         private JButton btnRemove;
    25         private JButton btnHighlight;
    26         private TagEditorModel model = null;
     23    private JComboBox presets;
     24    private JButton btnRemove;
     25    private JButton btnHighlight;
     26    private TagEditorModel model = null;
    2727
    28         protected void build() {
    29                 setLayout(new FlowLayout(FlowLayout.LEFT));
     28    protected void build() {
     29        setLayout(new FlowLayout(FlowLayout.LEFT));
    3030
    31                 // create the combobox to display the list of applied presets
    32                 //
    33                 presets = new JComboBox() {
    34                         @Override
    35                         public Dimension getPreferredSize() {
    36                                 Dimension d = super.getPreferredSize();
    37                                 d.width = 200;
    38                                 return d;
    39                         }
    40                 };
     31        // create the combobox to display the list of applied presets
     32        //
     33        presets = new JComboBox() {
     34            @Override
     35            public Dimension getPreferredSize() {
     36                Dimension d = super.getPreferredSize();
     37                d.width = 200;
     38                return d;
     39            }
     40        };
    4141
    42                 presets.addItemListener(
    43                                 new ItemListener(){
    44                                         public void itemStateChanged(ItemEvent e) {
    45                                                 syncWidgetStates();
    46                                         }
    47                                 }
    48                 );
     42        presets.addItemListener(
     43                new ItemListener(){
     44                    public void itemStateChanged(ItemEvent e) {
     45                        syncWidgetStates();
     46                    }
     47                }
     48        );
    4949
    50                 presets.setRenderer(new PresetItemListCellRenderer());
    51                 add(presets);
     50        presets.setRenderer(new PresetItemListCellRenderer());
     51        add(presets);
    5252
    53                 btnHighlight = new JButton(tr("Highlight"));
    54                 btnHighlight.addActionListener(
    55                                 new ActionListener()  {
    56                                         public void actionPerformed(ActionEvent arg0) {
    57                                                 highlightCurrentPreset();
    58                                         }
    59                                 }
    60                 );
     53        btnHighlight = new JButton(tr("Highlight"));
     54        btnHighlight.addActionListener(
     55                new ActionListener()  {
     56                    public void actionPerformed(ActionEvent arg0) {
     57                        highlightCurrentPreset();
     58                    }
     59                }
     60        );
    6161
    62                 add(btnHighlight);
     62        add(btnHighlight);
    6363
    64                 btnRemove = new JButton(tr("Remove"));
    65                 btnRemove.addActionListener(
    66                                 new ActionListener()  {
    67                                         public void actionPerformed(ActionEvent arg0) {
    68                                                 removeCurrentPreset();
    69                                         }
    70                                 }
    71                 );
     64        btnRemove = new JButton(tr("Remove"));
     65        btnRemove.addActionListener(
     66                new ActionListener()  {
     67                    public void actionPerformed(ActionEvent arg0) {
     68                        removeCurrentPreset();
     69                    }
     70                }
     71        );
    7272
    73                 add(btnRemove);
    74                 syncWidgetStates();
    75         }
     73        add(btnRemove);
     74        syncWidgetStates();
     75    }
    7676
    77         protected void syncWidgetStates() {
    78                 btnRemove.setEnabled(presets.getSelectedItem() != null);
    79                 btnHighlight.setEnabled(presets.getSelectedItem() != null);
    80         }
     77    protected void syncWidgetStates() {
     78        btnRemove.setEnabled(presets.getSelectedItem() != null);
     79        btnHighlight.setEnabled(presets.getSelectedItem() != null);
     80    }
    8181
    82         protected void removeCurrentPreset() {
    83                 Item item= (Item)presets.getSelectedItem();
    84                 if (item != null && model !=null) {
    85                         model.removeAppliedPreset(item);
    86                 }
    87         }
     82    protected void removeCurrentPreset() {
     83        Item item= (Item)presets.getSelectedItem();
     84        if (item != null && model !=null) {
     85            model.removeAppliedPreset(item);
     86        }
     87    }
    8888
    89         protected void highlightCurrentPreset() {
    90                 model.highlightCurrentPreset();
    91         }
     89    protected void highlightCurrentPreset() {
     90        model.highlightCurrentPreset();
     91    }
    9292
    93         public PresetManager() {
    94                 build();
    95         }
     93    public PresetManager() {
     94        build();
     95    }
    9696
    97         public void setModel(TagEditorModel model) {
    98                 presets.setModel(model.getAppliedPresetsModel());
    99                 this.model = model;
    100         }
     97    public void setModel(TagEditorModel model) {
     98        presets.setModel(model.getAppliedPresetsModel());
     99        this.model = model;
     100    }
    101101}
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/TableCellRenderer.java

    r20197 r23189  
    2626 */
    2727public class TableCellRenderer extends JLabel implements javax.swing.table.TableCellRenderer  {
    28        
    29         private static Logger logger = Logger.getLogger(TableCellRenderer.class.getName());
    30         public static final Color BG_COLOR_HIGHLIGHTED = new Color(255,255,204);
    31                
    32         private Font fontStandard = null;
    33         private Font fontItalic = null;
    34        
    35         public TableCellRenderer() {
    36                 fontStandard = getFont();
    37                 fontItalic = fontStandard.deriveFont(Font.ITALIC);
    38                 setOpaque(true);
    39                 setBorder(new EmptyBorder(5,5,5,5));
    40         }
    41        
    42         /**
    43         * renders the name of a tag in the second column of
    44         * the table
    45         *
    46         * @param tag  the tag
    47         */
    48         protected void renderTagName(TagModel tag) {
    49                 setText(tag.getName());
    50         }
    51        
    52         /**
    53         * renders the value of a a tag in the third column of
    54         * the table
    55         *
    56         * @param tag  the  tag
    57         */
    58         protected void renderTagValue(TagModel tag) {
    59                 if (tag.getValueCount() == 0) {
    60                         setText("");
    61                 } else if (tag.getValueCount() == 1) {
    62                         setText(tag.getValues().get(0));
    63                 } else if (tag.getValueCount() >  1) {
    64                         setText(tr("multiple"));
    65                         setFont(fontItalic);
    66                 }
    67         }
    68        
    69         /**
    70         * resets the renderer
    71         */
    72         protected void resetRenderer() {
    73                 setText("");
    74                 setIcon(null);
    75                 setFont(fontStandard);
    76         }
    77        
    78         protected TagEditorModel getModel(JTable table) {
    79                 return (TagEditorModel)table.getModel();
    80         }
    81        
    82         protected boolean belongsToSelectedPreset(TagModel tagModel, TagEditorModel model) {
    83                
    84                 // current tag is empty or consists of whitespace only => can't belong to
    85                 // a selected preset
    86                 //
    87                 if (tagModel.getName().trim().equals("") && tagModel.getValue().equals("")) {
    88                         return false;
    89                 }
    90                
    91                 // no current preset selected?
    92                 //
    93                 Item item = (Item)model.getAppliedPresetsModel().getSelectedItem();
    94                 if (item == null) {
    95                         return false;
    96                 }
    97                
    98                 for(Tag tag: item.getTags()) {
    99                         if (tag.getValue() == null) {
    100                                 if (tagModel.getName().equals(tag.getKey())) {
    101                                         return true;
    102                                 }
    103                         } else {
    104                                 if (tagModel.getName().equals(tag.getKey())
    105                                         && tagModel.getValue().equals(tag.getValue())) {
    106                                         return true;
    107                                 }
    108                         }
    109                 }               
    110                 return false;
    111         }
    112        
    113         /**
    114         * renders the background color. The default color is white. It is
    115         * set to {@see TableCellRenderer#BG_COLOR_HIGHLIGHTED} if this cell
    116         * displays the tag which is suggested by the currently selected
    117         * preset.
    118         *
    119         * @param tagModel the tag model
    120         * @param model the tag editor model
    121         */
    122         protected void renderColor(TagModel tagModel, TagEditorModel model, boolean isSelected) {
    123                 if (isSelected){
    124                         setBackground(UIManager.getColor("Table.selectionBackground"));
    125                         setForeground(UIManager.getColor("Table.selectionForeground"));
    126                 } else {
    127                         setBackground(UIManager.getColor("Table.background"));
    128                         setForeground(UIManager.getColor("Table.foreground"));
    129                 }               
    130                 if (belongsToSelectedPreset(tagModel, model)) {
    131                         setBackground(BG_COLOR_HIGHLIGHTED);
    132                 }
    133         }
    134        
    135         /**
    136         * replies the cell renderer component for a specific cell
    137         *
    138         * @param table  the table
    139         * @param value the value to be rendered
    140         * @param isSelected  true, if the value is selected
    141         * @param hasFocus true, if the cell has focus
    142         * @param rowIndex the row index
    143         * @param vColIndex the column index
    144         *
    145         * @return the renderer component
    146         */
    147         public Component getTableCellRendererComponent(JTable table, Object value,
     28   
     29    private static Logger logger = Logger.getLogger(TableCellRenderer.class.getName());
     30    public static final Color BG_COLOR_HIGHLIGHTED = new Color(255,255,204);
     31       
     32    private Font fontStandard = null;
     33    private Font fontItalic = null;
     34   
     35    public TableCellRenderer() {
     36        fontStandard = getFont();
     37        fontItalic = fontStandard.deriveFont(Font.ITALIC);
     38        setOpaque(true);
     39        setBorder(new EmptyBorder(5,5,5,5));
     40    }
     41   
     42    /**
     43    * renders the name of a tag in the second column of
     44    * the table
     45    *
     46    * @param tag  the tag
     47    */
     48    protected void renderTagName(TagModel tag) {
     49        setText(tag.getName());
     50    }
     51   
     52    /**
     53    * renders the value of a a tag in the third column of
     54    * the table
     55    *
     56    * @param tag  the  tag
     57    */
     58    protected void renderTagValue(TagModel tag) {
     59        if (tag.getValueCount() == 0) {
     60            setText("");
     61        } else if (tag.getValueCount() == 1) {
     62            setText(tag.getValues().get(0));
     63        } else if (tag.getValueCount() >  1) {
     64            setText(tr("multiple"));
     65            setFont(fontItalic);
     66        }
     67    }
     68   
     69    /**
     70    * resets the renderer
     71    */
     72    protected void resetRenderer() {
     73        setText("");
     74        setIcon(null);
     75        setFont(fontStandard);
     76    }
     77   
     78    protected TagEditorModel getModel(JTable table) {
     79        return (TagEditorModel)table.getModel();
     80    }
     81   
     82    protected boolean belongsToSelectedPreset(TagModel tagModel, TagEditorModel model) {
     83       
     84        // current tag is empty or consists of whitespace only => can't belong to
     85        // a selected preset
     86        //
     87        if (tagModel.getName().trim().equals("") && tagModel.getValue().equals("")) {
     88            return false;
     89        }
     90       
     91        // no current preset selected?
     92        //
     93        Item item = (Item)model.getAppliedPresetsModel().getSelectedItem();
     94        if (item == null) {
     95            return false;
     96        }
     97       
     98        for(Tag tag: item.getTags()) {
     99            if (tag.getValue() == null) {
     100                if (tagModel.getName().equals(tag.getKey())) {
     101                    return true;
     102                }
     103            } else {
     104                if (tagModel.getName().equals(tag.getKey())
     105                    && tagModel.getValue().equals(tag.getValue())) {
     106                    return true;
     107                }
     108            }
     109        }       
     110        return false;
     111    }
     112   
     113    /**
     114    * renders the background color. The default color is white. It is
     115    * set to {@see TableCellRenderer#BG_COLOR_HIGHLIGHTED} if this cell
     116    * displays the tag which is suggested by the currently selected
     117    * preset.
     118    *
     119    * @param tagModel the tag model
     120    * @param model the tag editor model
     121    */
     122    protected void renderColor(TagModel tagModel, TagEditorModel model, boolean isSelected) {
     123        if (isSelected){
     124            setBackground(UIManager.getColor("Table.selectionBackground"));
     125            setForeground(UIManager.getColor("Table.selectionForeground"));
     126        } else {
     127            setBackground(UIManager.getColor("Table.background"));
     128            setForeground(UIManager.getColor("Table.foreground"));
     129        }       
     130        if (belongsToSelectedPreset(tagModel, model)) {
     131            setBackground(BG_COLOR_HIGHLIGHTED);
     132        }
     133    }
     134   
     135    /**
     136    * replies the cell renderer component for a specific cell
     137    *
     138    * @param table  the table
     139    * @param value the value to be rendered
     140    * @param isSelected  true, if the value is selected
     141    * @param hasFocus true, if the cell has focus
     142    * @param rowIndex the row index
     143    * @param vColIndex the column index
     144    *
     145    * @return the renderer component
     146    */
     147    public Component getTableCellRendererComponent(JTable table, Object value,
    148148            boolean isSelected, boolean hasFocus, int rowIndex, int vColIndex) {
    149                
    150                 resetRenderer();
    151                 TagModel tagModel  = (TagModel)value;
    152                 switch(vColIndex) {
    153                         case 0: renderTagName(tagModel); break;
    154                         case 1: renderTagValue(tagModel); break;
    155                 }
    156                 renderColor(tagModel, (TagEditorModel)table.getModel(),isSelected);
    157                 if (hasFocus && isSelected) {
    158                         if (table.getSelectedColumnCount() == 1 && table.getSelectedRowCount() == 1) {
    159                                 if (table.getEditorComponent() != null) {
    160                                         table.getEditorComponent().requestFocusInWindow();
    161                                 }
    162                         }
    163                 }
    164                 return this;
    165         }
     149       
     150        resetRenderer();
     151        TagModel tagModel  = (TagModel)value;
     152        switch(vColIndex) {
     153            case 0: renderTagName(tagModel); break;
     154            case 1: renderTagValue(tagModel); break;
     155        }
     156        renderColor(tagModel, (TagEditorModel)table.getModel(),isSelected);
     157        if (hasFocus && isSelected) {
     158            if (table.getSelectedColumnCount() == 1 && table.getSelectedRowCount() == 1) {
     159                if (table.getEditorComponent() != null) {
     160                    table.getEditorComponent().requestFocusInWindow();
     161                }
     162            }
     163        }
     164        return this;
     165    }
    166166}
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/TagEditor.java

    r21024 r23189  
    5656public class TagEditor extends JPanel implements IAutoCompletionListListener {
    5757
    58         private static final Logger logger = Logger.getLogger(TagEditor.class.getName());
    59 
    60         private TagEditorModel tagEditorModel;
    61         private TagTable tblTagEditor;
    62         private PresetManager presetManager;
    63        
    64         /**
     58    private static final Logger logger = Logger.getLogger(TagEditor.class.getName());
     59
     60    private TagEditorModel tagEditorModel;
     61    private TagTable tblTagEditor;
     62    private PresetManager presetManager;
     63   
     64    /**
    6565     * builds the panel with the button row
    6666     *
     
    8585   
    8686    public void addComponentNotStoppingCellEditing(Component c) {
    87         tblTagEditor.addComponentNotStoppingCellEditing(c);
     87        tblTagEditor.addComponentNotStoppingCellEditing(c);
    8888    }
    8989   
     
    9494        JPanel pnl = new JPanel(new GridBagLayout());
    9595
    96                 DefaultListSelectionModel rowSelectionModel = new DefaultListSelectionModel();
    97                 DefaultListSelectionModel colSelectionModel = new DefaultListSelectionModel();
    98                
    99                 tagEditorModel = new TagEditorModel(rowSelectionModel,colSelectionModel);
    100                
    101                 // build the scrollable table for editing tag names and tag values
    102                 //
    103                 tblTagEditor = new TagTable(tagEditorModel);
    104                 tblTagEditor.setTagCellEditor(new TagSpecificationAwareTagCellEditor());
    105                 TableCellRenderer renderer = new TableCellRenderer();
    106                 tblTagEditor.getColumnModel().getColumn(0).setCellRenderer(renderer);
    107                 tblTagEditor.getColumnModel().getColumn(1).setCellRenderer(renderer);
    108 
    109                 final JScrollPane scrollPane = new JScrollPane(tblTagEditor);
    110                 JPanel pnlTagTable = new JPanel(new BorderLayout());
    111                 pnlTagTable.add(scrollPane, BorderLayout.CENTER);
     96        DefaultListSelectionModel rowSelectionModel = new DefaultListSelectionModel();
     97        DefaultListSelectionModel colSelectionModel = new DefaultListSelectionModel();
     98       
     99        tagEditorModel = new TagEditorModel(rowSelectionModel,colSelectionModel);
     100       
     101        // build the scrollable table for editing tag names and tag values
     102        //
     103        tblTagEditor = new TagTable(tagEditorModel);
     104        tblTagEditor.setTagCellEditor(new TagSpecificationAwareTagCellEditor());
     105        TableCellRenderer renderer = new TableCellRenderer();
     106        tblTagEditor.getColumnModel().getColumn(0).setCellRenderer(renderer);
     107        tblTagEditor.getColumnModel().getColumn(1).setCellRenderer(renderer);
     108
     109        final JScrollPane scrollPane = new JScrollPane(tblTagEditor);
     110        JPanel pnlTagTable = new JPanel(new BorderLayout());
     111        pnlTagTable.add(scrollPane, BorderLayout.CENTER);
    112112
    113113        GridBagConstraints gc = new GridBagConstraints();
     
    133133    }
    134134   
    135         /**
    136         * builds the GUI
    137         *
    138         */
    139         protected void build() {
    140                 setLayout(new BorderLayout());
    141                
    142                 add(buildTagEditorPanel(), BorderLayout.CENTER);
    143 
    144                 // build the preset manager which shows a list of applied presets
    145                 //
    146                 presetManager = new PresetManager();
    147                 presetManager.setModel(tagEditorModel);
    148                 add(presetManager, BorderLayout.NORTH);
    149         }
    150 
    151         /**
    152         * constructor
    153         */
    154         public TagEditor() {
    155                 build();
    156         }
    157 
    158         /**
    159         * replies the tag editor model
    160         * @return the tag editor model
    161         */
    162         public TagEditorModel getTagEditorModel() {
    163                 return tagEditorModel;
    164         }
    165        
    166         public void clearSelection() {
    167                 tblTagEditor.getSelectionModel().clearSelection();
    168         }
    169 
    170         public void stopEditing() {
    171                 TableCellEditor editor = tblTagEditor.getCellEditor();
    172                 if (editor != null) {
    173                         editor.stopCellEditing();
    174                 }
    175         }
    176        
    177         public void setAutoCompletionList(AutoCompletionList autoCompletionList) {
    178                 tblTagEditor.setAutoCompletionList(autoCompletionList);
    179         }
    180 
    181         public void setAutoCompletionManager(AutoCompletionManager autocomplete) {
    182                 tblTagEditor.setAutoCompletionManager(autocomplete);
    183         }
    184 
    185         public void autoCompletionItemSelected(String item) {
    186                 logger.info("autocompletion item selected ...");
    187                 TagSpecificationAwareTagCellEditor editor = (TagSpecificationAwareTagCellEditor)tblTagEditor.getCellEditor();
    188                 if (editor != null) {
    189                         editor.autoCompletionItemSelected(item);
    190                 }
    191         }
    192 
    193         public void requestFocusInTopLeftCell() {
    194                 tblTagEditor.requestFocusInCell(0,0);
    195         }
    196        
    197         public TagEditorModel getModel() {
    198                 return tagEditorModel;
    199         }
     135    /**
     136    * builds the GUI
     137    *
     138    */
     139    protected void build() {
     140        setLayout(new BorderLayout());
     141       
     142        add(buildTagEditorPanel(), BorderLayout.CENTER);
     143
     144        // build the preset manager which shows a list of applied presets
     145        //
     146        presetManager = new PresetManager();
     147        presetManager.setModel(tagEditorModel);
     148        add(presetManager, BorderLayout.NORTH);
     149    }
     150
     151    /**
     152    * constructor
     153    */
     154    public TagEditor() {
     155        build();
     156    }
     157
     158    /**
     159    * replies the tag editor model
     160    * @return the tag editor model
     161    */
     162    public TagEditorModel getTagEditorModel() {
     163        return tagEditorModel;
     164    }
     165   
     166    public void clearSelection() {
     167        tblTagEditor.getSelectionModel().clearSelection();
     168    }
     169
     170    public void stopEditing() {
     171        TableCellEditor editor = tblTagEditor.getCellEditor();
     172        if (editor != null) {
     173            editor.stopCellEditing();
     174        }
     175    }
     176   
     177    public void setAutoCompletionList(AutoCompletionList autoCompletionList) {
     178        tblTagEditor.setAutoCompletionList(autoCompletionList);
     179    }
     180
     181    public void setAutoCompletionManager(AutoCompletionManager autocomplete) {
     182        tblTagEditor.setAutoCompletionManager(autocomplete);
     183    }
     184
     185    public void autoCompletionItemSelected(String item) {
     186        logger.info("autocompletion item selected ...");
     187        TagSpecificationAwareTagCellEditor editor = (TagSpecificationAwareTagCellEditor)tblTagEditor.getCellEditor();
     188        if (editor != null) {
     189            editor.autoCompletionItemSelected(item);
     190        }
     191    }
     192
     193    public void requestFocusInTopLeftCell() {
     194        tblTagEditor.requestFocusInCell(0,0);
     195    }
     196   
     197    public TagEditorModel getModel() {
     198        return tagEditorModel;
     199    }
    200200}
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/TagEditorModel.java

    r20058 r23189  
    2525@SuppressWarnings("serial")
    2626public class TagEditorModel extends org.openstreetmap.josm.gui.tagging.TagEditorModel  {
    27         static private final Logger logger = Logger.getLogger(TagEditorModel.class.getName());
    28        
    29         private DefaultComboBoxModel appliedPresets = null;
     27    static private final Logger logger = Logger.getLogger(TagEditorModel.class.getName());
     28   
     29    private DefaultComboBoxModel appliedPresets = null;
    3030
    31         /**
    32         * constructor
    33         */
    34         public TagEditorModel(DefaultListSelectionModel rowSelectionModel, DefaultListSelectionModel colSelectionModel){
    35                 super(rowSelectionModel, colSelectionModel);
    36                 appliedPresets = new DefaultComboBoxModel();
    37         }
     31    /**
     32    * constructor
     33    */
     34    public TagEditorModel(DefaultListSelectionModel rowSelectionModel, DefaultListSelectionModel colSelectionModel){
     35        super(rowSelectionModel, colSelectionModel);
     36        appliedPresets = new DefaultComboBoxModel();
     37    }
    3838
    39         /**
    40         * applies the tags defined for a preset item to the tag model.
    41         *
    42         * Mandatory tags are added to the list of currently edited tags.
    43         * Optional tags are not added.
    44         * The model remembers the currently applied presets.
    45         *
    46         * @param item  the preset item. Must not be null.
    47         * @exception IllegalArgumentException thrown, if item is null
    48         *
    49         */
    50         public void applyPreset(Item item) {
    51                 if (item == null)
    52                         throw new IllegalArgumentException("argument 'item' must not be null");
    53                 // check whether item is already applied
    54                 //
    55                 for(int i=0; i < appliedPresets.getSize(); i++) {
    56                         if (appliedPresets.getElementAt(i).equals(item))
    57                                 // abort - preset already applied
    58                                 return;
    59                 }
     39    /**
     40    * applies the tags defined for a preset item to the tag model.
     41    *
     42    * Mandatory tags are added to the list of currently edited tags.
     43    * Optional tags are not added.
     44    * The model remembers the currently applied presets.
     45    *
     46    * @param item  the preset item. Must not be null.
     47    * @exception IllegalArgumentException thrown, if item is null
     48    *
     49    */
     50    public void applyPreset(Item item) {
     51        if (item == null)
     52            throw new IllegalArgumentException("argument 'item' must not be null");
     53        // check whether item is already applied
     54        //
     55        for(int i=0; i < appliedPresets.getSize(); i++) {
     56            if (appliedPresets.getElementAt(i).equals(item))
     57                // abort - preset already applied
     58                return;
     59        }
    6060
    61                 // apply the tags proposed by the preset
    62                 //
    63                 for(Tag tag : item.getTags()) {
    64                         if (!tag.isOptional()) {
    65                                 if (!includesTag(tag.getKey())) {
    66                                         TagModel tagModel = new TagModel(tag.getKey(),tag.getValue());
    67                                         prepend(tagModel);
    68                                 } else {
    69                                         TagModel tagModel = get(tag.getKey());
    70                                         // only overwrite an existing value if the preset
    71                                         // proposes a value. I.e. don't overwrite
    72                                         // existing values for tag 'name' with an empty string
    73                                         //
    74                                         if (tag.getValue() != null) {
    75                                                 tagModel.setValue(tag.getValue());
    76                                         }
    77                                 }
    78                         }
    79                 }
     61        // apply the tags proposed by the preset
     62        //
     63        for(Tag tag : item.getTags()) {
     64            if (!tag.isOptional()) {
     65                if (!includesTag(tag.getKey())) {
     66                    TagModel tagModel = new TagModel(tag.getKey(),tag.getValue());
     67                    prepend(tagModel);
     68                } else {
     69                    TagModel tagModel = get(tag.getKey());
     70                    // only overwrite an existing value if the preset
     71                    // proposes a value. I.e. don't overwrite
     72                    // existing values for tag 'name' with an empty string
     73                    //
     74                    if (tag.getValue() != null) {
     75                        tagModel.setValue(tag.getValue());
     76                    }
     77                }
     78            }
     79        }
    8080
    81                 // remember the preset and make it the current preset
    82                 //
    83                 appliedPresets.addElement(item);
    84                 appliedPresets.setSelectedItem(item);
    85                 fireTableDataChanged();
    86         }
     81        // remember the preset and make it the current preset
     82        //
     83        appliedPresets.addElement(item);
     84        appliedPresets.setSelectedItem(item);
     85        fireTableDataChanged();
     86    }
    8787
    8888
    89         /**
    90         * applies a tag given by a {@see KeyValuePair} to the model
    91         *
    92         * @param pair the key value pair
    93         */
    94         public void applyKeyValuePair(KeyValuePair pair) {
    95                 TagModel tagModel = get(pair.getKey());
    96                 if (tagModel == null) {
    97                         tagModel = new TagModel(pair.getKey(), pair.getValue());
    98                         prepend(tagModel);
    99                 } else {
    100                         tagModel.setValue(pair.getValue());
    101                 }
    102                 fireTableDataChanged();
    103         }
     89    /**
     90    * applies a tag given by a {@see KeyValuePair} to the model
     91    *
     92    * @param pair the key value pair
     93    */
     94    public void applyKeyValuePair(KeyValuePair pair) {
     95        TagModel tagModel = get(pair.getKey());
     96        if (tagModel == null) {
     97            tagModel = new TagModel(pair.getKey(), pair.getValue());
     98            prepend(tagModel);
     99        } else {
     100            tagModel.setValue(pair.getValue());
     101        }
     102        fireTableDataChanged();
     103    }
    104104
    105105
    106         public DefaultComboBoxModel getAppliedPresetsModel() {
    107                 return appliedPresets;
    108         }
     106    public DefaultComboBoxModel getAppliedPresetsModel() {
     107        return appliedPresets;
     108    }
    109109
    110         public void removeAppliedPreset(Item item) {
    111                 if (item == null)
    112                         return;
    113                 for (Tag tag: item.getTags()) {
    114                         if (tag.getValue() != null) {
    115                                 // preset tag with explicit key and explicit value. Remove tag model
    116                                 // from the current model if both the key and the value match
    117                                 //
    118                                 TagModel tagModel = get(tag.getKey());
    119                                 if (tagModel !=null && tag.getValue().equals(tagModel.getValue())) {
    120                                         tags.remove(tagModel);
    121                                         setDirty(true);
    122                                 }
    123                         } else {
    124                                 // preset tag with required key. No explicit value given. Remove tag
    125                                 // model with the respective key
    126                                 //
    127                                 TagModel tagModel = get(tag.getKey());
    128                                 if (tagModel != null) {
    129                                         tags.remove(tagModel);
    130                                         setDirty(true);
    131                                 }
    132                         }
    133                 }
    134                 appliedPresets.removeElement(item);
    135                 fireTableDataChanged();
    136         }
     110    public void removeAppliedPreset(Item item) {
     111        if (item == null)
     112            return;
     113        for (Tag tag: item.getTags()) {
     114            if (tag.getValue() != null) {
     115                // preset tag with explicit key and explicit value. Remove tag model
     116                // from the current model if both the key and the value match
     117                //
     118                TagModel tagModel = get(tag.getKey());
     119                if (tagModel !=null && tag.getValue().equals(tagModel.getValue())) {
     120                    tags.remove(tagModel);
     121                    setDirty(true);
     122                }
     123            } else {
     124                // preset tag with required key. No explicit value given. Remove tag
     125                // model with the respective key
     126                //
     127                TagModel tagModel = get(tag.getKey());
     128                if (tagModel != null) {
     129                    tags.remove(tagModel);
     130                    setDirty(true);
     131                }
     132            }
     133        }
     134        appliedPresets.removeElement(item);
     135        fireTableDataChanged();
     136    }
    137137
    138         public void clearAppliedPresets() {
    139                 appliedPresets.removeAllElements();
    140                 fireTableDataChanged();
    141         }
     138    public void clearAppliedPresets() {
     139        appliedPresets.removeAllElements();
     140        fireTableDataChanged();
     141    }
    142142
    143         public void highlightCurrentPreset() {
    144                 fireTableDataChanged();
    145         }
    146        
    147         /**
    148         * updates the tags of the primitives in the current selection with the
    149         * values in the current tag model
    150         *
    151         */
    152         public void updateJOSMSelection() {
    153                 ArrayList<Command> commands = new ArrayList<Command>();
    154                 Collection<OsmPrimitive> selection = Main.main.getCurrentDataSet().getSelected();
    155                 if (selection == null)
    156                         return;
    157                 for (TagModel tag : tags) {
    158                         Command command = createUpdateTagCommand(selection,tag);
    159                         if (command != null) {
    160                                 commands.add(command);
    161                         }
    162                 }
    163                 Command deleteCommand = createDeleteTagsCommand(selection);
    164                 if (deleteCommand != null) {
    165                         commands.add(deleteCommand);
    166                 }
     143    public void highlightCurrentPreset() {
     144        fireTableDataChanged();
     145    }
     146   
     147    /**
     148    * updates the tags of the primitives in the current selection with the
     149    * values in the current tag model
     150    *
     151    */
     152    public void updateJOSMSelection() {
     153        ArrayList<Command> commands = new ArrayList<Command>();
     154        Collection<OsmPrimitive> selection = Main.main.getCurrentDataSet().getSelected();
     155        if (selection == null)
     156            return;
     157        for (TagModel tag : tags) {
     158            Command command = createUpdateTagCommand(selection,tag);
     159            if (command != null) {
     160                commands.add(command);
     161            }
     162        }
     163        Command deleteCommand = createDeleteTagsCommand(selection);
     164        if (deleteCommand != null) {
     165            commands.add(deleteCommand);
     166        }
    167167
    168                 SequenceCommand command = new SequenceCommand(
    169                                 trn("Updating properties of up to {0} object", "Updating properties of up to {0} objects", selection.size(), selection.size()),
    170                                 commands
    171                 );
     168        SequenceCommand command = new SequenceCommand(
     169                trn("Updating properties of up to {0} object", "Updating properties of up to {0} objects", selection.size(), selection.size()),
     170                commands
     171        );
    172172
    173                 // executes the commands and adds them to the undo/redo chains
    174                 Main.main.undoRedo.add(command);
    175         }
    176        
    177         /**
    178         * initializes the model with the tags in the current JOSM selection
    179         */
    180         public void initFromJOSMSelection() {
    181                 Collection<OsmPrimitive> selection = Main.main.getCurrentDataSet().getSelected();
    182                 clear();
    183                 for (OsmPrimitive element : selection) {
    184                         for (String key : element.keySet()) {
    185                                 String value = element.get(key);
    186                                 add(key,value);
    187                         }
    188                 }
    189                 sort();
    190                 setDirty(false);
    191         }
     173        // executes the commands and adds them to the undo/redo chains
     174        Main.main.undoRedo.add(command);
     175    }
     176   
     177    /**
     178    * initializes the model with the tags in the current JOSM selection
     179    */
     180    public void initFromJOSMSelection() {
     181        Collection<OsmPrimitive> selection = Main.main.getCurrentDataSet().getSelected();
     182        clear();
     183        for (OsmPrimitive element : selection) {
     184            for (String key : element.keySet()) {
     185                String value = element.get(key);
     186                add(key,value);
     187            }
     188        }
     189        sort();
     190        setDirty(false);
     191    }
    192192}
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/TagSpecificationAwareTagCellEditor.java

    r21024 r23189  
    1212
    1313public class TagSpecificationAwareTagCellEditor extends TagCellEditor {
    14         private static final Logger logger = Logger.getLogger(TagCellEditor.class.getName());
     14    private static final Logger logger = Logger.getLogger(TagCellEditor.class.getName());
    1515
    16         /**
    17         * initializes  the auto completion list when the table cell editor starts
    18         * to edit the key of a tag. In this case the auto completion list is
    19         * initialized with the set of standard key values and the set of current key
    20         * values from the the current JOSM data set. Keys already present in the
    21         * current tag model are removed from the auto completion list.
    22         *
    23         * @param model  the tag editor model
    24         * @param currentTag  the current tag
    25         */
    26         protected void initAutoCompletionListForKeys(TagEditorModel model, TagModel currentTag) {               
    27                 if (getAutoCompletionList() == null) {
    28                         logger.warning("autoCompletionList is null. Make sure an instance of AutoCompletionList is injected into TableCellEditor.");
    29                         return;
    30                 }
     16    /**
     17    * initializes  the auto completion list when the table cell editor starts
     18    * to edit the key of a tag. In this case the auto completion list is
     19    * initialized with the set of standard key values and the set of current key
     20    * values from the the current JOSM data set. Keys already present in the
     21    * current tag model are removed from the auto completion list.
     22    *
     23    * @param model  the tag editor model
     24    * @param currentTag  the current tag
     25    */
     26    protected void initAutoCompletionListForKeys(TagEditorModel model, TagModel currentTag) {       
     27        if (getAutoCompletionList() == null) {
     28            logger.warning("autoCompletionList is null. Make sure an instance of AutoCompletionList is injected into TableCellEditor.");
     29            return;
     30        }
    3131
    32                 autoCompletionList.clear();
     32        autoCompletionList.clear();
    3333
    34                 // add the list of standard keys
    35                 //
    36                 try {
    37                         //autoCompletionList.add(TagSpecifications.getInstance().getKeysForAutoCompletion(context));
    38                 } catch(Exception e) {
    39                         logger.log(Level.WARNING, "failed to initialize auto completion list with standard keys.", e);
    40                 }
     34        // add the list of standard keys
     35        //
     36        try {
     37            //autoCompletionList.add(TagSpecifications.getInstance().getKeysForAutoCompletion(context));
     38        } catch(Exception e) {
     39            logger.log(Level.WARNING, "failed to initialize auto completion list with standard keys.", e);
     40        }
    4141
    42                 // add the list of keys in the current data set
    43                 //
    44                 autocomplete.populateWithKeys(autoCompletionList);
    45                 AutoCompletionContext context = new AutoCompletionContext();
    46                 try {
    47                         context.initFromJOSMSelection();
    48                         autoCompletionList.add(TagSpecifications.getInstance().getKeysForAutoCompletion(context));
    49                 } catch(Exception e) {
    50                         System.out.println("Warning: failed to initialize auto completion list with tag specification keys. Exception was: " + e.toString());
    51                         e.printStackTrace();
    52                 }
     42        // add the list of keys in the current data set
     43        //
     44        autocomplete.populateWithKeys(autoCompletionList);
     45        AutoCompletionContext context = new AutoCompletionContext();
     46        try {
     47            context.initFromJOSMSelection();
     48            autoCompletionList.add(TagSpecifications.getInstance().getKeysForAutoCompletion(context));
     49        } catch(Exception e) {
     50            System.out.println("Warning: failed to initialize auto completion list with tag specification keys. Exception was: " + e.toString());
     51            e.printStackTrace();
     52        }
    5353
    54                 // remove the keys already present in the current tag model
    55                 //
    56                 for (String key : model.getKeys()) {
    57                         if (! key.equals(currentTag.getName())) {
    58                                 autoCompletionList.remove(key);
    59                         }
    60                 }
    61                 autoCompletionList.fireTableDataChanged();
    62         }
     54        // remove the keys already present in the current tag model
     55        //
     56        for (String key : model.getKeys()) {
     57            if (! key.equals(currentTag.getName())) {
     58                autoCompletionList.remove(key);
     59            }
     60        }
     61        autoCompletionList.fireTableDataChanged();
     62    }
    6363
    64         /**
    65         * initializes the auto completion list when the cell editor starts to edit
    66         * a tag value. In this case the auto completion list is initialized with the
    67         * set of standard values for a given key and the set of values present in the
    68         * current data set for the given key.
    69         *
    70         * @param forKey the key
    71         */
    72         protected void initAutoCompletionListForValues(String forKey) {
     64    /**
     65    * initializes the auto completion list when the cell editor starts to edit
     66    * a tag value. In this case the auto completion list is initialized with the
     67    * set of standard values for a given key and the set of values present in the
     68    * current data set for the given key.
     69    *
     70    * @param forKey the key
     71    */
     72    protected void initAutoCompletionListForValues(String forKey) {
    7373
    74                 if (autoCompletionList == null) {
    75                         logger.warning("autoCompletionList is null. Make sure an instance of AutoCompletionList is injected into TableCellEditor.");
    76                         return;
    77                 }
    78                 autoCompletionList.clear();
    79                 autocomplete.populateWithTagValues(autoCompletionList, forKey);
    80                
    81                 AutoCompletionContext context = new AutoCompletionContext();
    82                 try {
    83                         context.initFromJOSMSelection();
    84                         autoCompletionList.add(TagSpecifications.getInstance().getLabelsForAutoCompletion(forKey, context));
    85                 } catch(Exception e) {
    86                         System.out.println("Warning: failed to initialize auto completion list with tag specification values. Exception was: " + e.toString());
    87                         e.printStackTrace();
    88                 }
     74        if (autoCompletionList == null) {
     75            logger.warning("autoCompletionList is null. Make sure an instance of AutoCompletionList is injected into TableCellEditor.");
     76            return;
     77        }
     78        autoCompletionList.clear();
     79        autocomplete.populateWithTagValues(autoCompletionList, forKey);
     80       
     81        AutoCompletionContext context = new AutoCompletionContext();
     82        try {
     83            context.initFromJOSMSelection();
     84            autoCompletionList.add(TagSpecifications.getInstance().getLabelsForAutoCompletion(forKey, context));
     85        } catch(Exception e) {
     86            System.out.println("Warning: failed to initialize auto completion list with tag specification values. Exception was: " + e.toString());
     87            e.printStackTrace();
     88        }
    8989
    90                 //  add the list of possible values for a key from the current selection
    91                 //
    92                 if (currentTag.getValueCount() > 1) {
    93                         for (String value : currentTag.getValues()) {
    94                                 //logger.info("adding ac item " + value + " with priority IN_SELECTION");;
    95                                 autoCompletionList.add(
    96                                                 new AutoCompletionListItem(value, AutoCompletionItemPritority.IS_IN_SELECTION)
    97                                 );
    98                         }
    99                 }
    100         }
     90        //  add the list of possible values for a key from the current selection
     91        //
     92        if (currentTag.getValueCount() > 1) {
     93            for (String value : currentTag.getValues()) {
     94                //logger.info("adding ac item " + value + " with priority IN_SELECTION");;
     95                autoCompletionList.add(
     96                        new AutoCompletionListItem(value, AutoCompletionItemPritority.IS_IN_SELECTION)
     97                );
     98            }
     99        }
     100    }
    101101}
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/AbstractNameIconProvider.java

    r20058 r23189  
    1212
    1313public abstract class AbstractNameIconProvider implements INameIconProvider {
    14        
    15         protected String name;
    16         protected String iconName;
    17         protected ImageIcon icon;
    18         protected File zipIconArchive;
    19        
    20         public String getName() {
    21                 return name;
    22         }
     14   
     15    protected String name;
     16    protected String iconName;
     17    protected ImageIcon icon;
     18    protected File zipIconArchive;
     19   
     20    public String getName() {
     21        return name;
     22    }
    2323
    24         public void setName(String name) {
    25                 this.name = name;
    26         }
     24    public void setName(String name) {
     25        this.name = name;
     26    }
    2727
    28         public String getIconName() {
    29                 return iconName;
    30         }
     28    public String getIconName() {
     29        return iconName;
     30    }
    3131
    32         public void setIconName(String iconName, File zipIconArchive) {
    33                 this.iconName = iconName;
    34         }
    35        
    36         public Icon getIcon() {
    37                 if (icon == null) {
    38                         Collection<String> s = Main.pref.getCollection("taggingpreset.icon.sources", null);
    39                 icon = ImageProvider.getIfAvailable(s, "presets", null, getIconName(), zipIconArchive);
    40                 if (icon == null) return null;
    41                 Image i = icon.getImage().getScaledInstance(16, 16, Image.SCALE_DEFAULT);
    42                         icon = new ImageIcon(i);
    43                 }
    44                 return icon;
    45         }
     32    public void setIconName(String iconName, File zipIconArchive) {
     33        this.iconName = iconName;
     34    }
     35   
     36    public Icon getIcon() {
     37        if (icon == null) {
     38            Collection<String> s = Main.pref.getCollection("taggingpreset.icon.sources", null);
     39            icon = ImageProvider.getIfAvailable(s, "presets", null, getIconName(), zipIconArchive);
     40            if (icon == null) return null;
     41            Image i = icon.getImage().getScaledInstance(16, 16, Image.SCALE_DEFAULT);
     42            icon = new ImageIcon(i);
     43        }
     44        return icon;
     45    }
    4646}
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/Group.java

    r20058 r23189  
    1010 */
    1111public class Group extends AbstractNameIconProvider {
    12        
    13         static final private Logger logger = Logger.getLogger(Group.class.getName());
    14        
    15         private List<Item> items = null;
    16        
    17         public Group() {
    18                 items = new ArrayList<Item>();
    19         }
    20        
    21         public Group(String name) {
    22                 this();
    23                 setName(name);
    24         }
    25        
    26         public void addItem(Item item) {
    27                 item.setParent(this);
    28                 items.add(item);
    29         }
    30        
    31         public void removeItem(Item item) {
    32                 items.remove(item);
    33         }
    34        
    35         public List<Item> getItems() {
    36                 return items;
    37         }
     12   
     13    static final private Logger logger = Logger.getLogger(Group.class.getName());
     14   
     15    private List<Item> items = null;
     16   
     17    public Group() {
     18        items = new ArrayList<Item>();
     19    }
     20   
     21    public Group(String name) {
     22        this();
     23        setName(name);
     24    }
     25   
     26    public void addItem(Item item) {
     27        item.setParent(this);
     28        items.add(item);
     29    }
     30   
     31    public void removeItem(Item item) {
     32        items.remove(item);
     33    }
     34   
     35    public List<Item> getItems() {
     36        return items;
     37    }
    3838}
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/INameIconProvider.java

    r20058 r23189  
    44
    55public interface INameIconProvider {
    6         public String getName();
    7         public Icon  getIcon();
     6    public String getName();
     7    public Icon  getIcon();
    88}
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/Item.java

    r20058 r23189  
    77public class Item  extends AbstractNameIconProvider {
    88
    9         private final static Logger logger = Logger.getLogger(Item.class.getName());
     9    private final static Logger logger = Logger.getLogger(Item.class.getName());
    1010
    11         private String label;
    12         private List<Tag> tags;
    13         private Group parent;
     11    private String label;
     12    private List<Tag> tags;
     13    private Group parent;
    1414
    15         public Item() {
    16                 tags = new ArrayList<Tag>();
    17         }
     15    public Item() {
     16        tags = new ArrayList<Tag>();
     17    }
    1818
    19         public Group getParent() {
    20                 return parent;
    21         }
     19    public Group getParent() {
     20        return parent;
     21    }
    2222
    23         public void setParent(Group parent) {
    24                 this.parent = parent;
    25         }
     23    public void setParent(Group parent) {
     24        this.parent = parent;
     25    }
    2626
    27         public String getLabel() {
    28                 return label;
    29         }
     27    public String getLabel() {
     28        return label;
     29    }
    3030
    31         public void setLabel(String label) {
    32                 this.label = label;
    33         }
     31    public void setLabel(String label) {
     32        this.label = label;
     33    }
    3434
    35         public Item(String name) {
    36                 setName(name);
    37         }
     35    public Item(String name) {
     36        setName(name);
     37    }
    3838
    39         public void addTag(Tag tag) {
    40                 tags.add(tag);
    41         }
     39    public void addTag(Tag tag) {
     40        tags.add(tag);
     41    }
    4242
    43         public List<Tag> getTags() {
    44                 return tags;
    45         }
     43    public List<Tag> getTags() {
     44        return tags;
     45    }
    4646
    47         @Override
    48         public String toString() {
    49                 StringBuilder builder  = new StringBuilder();
    50                 builder.append("[")
    51                 .append(getClass().getName())
    52                 .append(":")
    53                 .append("name=")
    54                 .append(name)
    55                 .append("]");
     47    @Override
     48    public String toString() {
     49        StringBuilder builder  = new StringBuilder();
     50        builder.append("[")
     51        .append(getClass().getName())
     52        .append(":")
     53        .append("name=")
     54        .append(name)
     55        .append("]");
    5656
    57                 return builder.toString();
    58         }
     57        return builder.toString();
     58    }
    5959}
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/Presets.java

    r20058 r23189  
    2525
    2626public class Presets {
    27         private static Logger logger = Logger.getLogger(Presets.class.getName());
     27    private static Logger logger = Logger.getLogger(Presets.class.getName());
    2828
    29         private static Presets presets = null;
     29    private static Presets presets = null;
    3030
    31         static public void initPresets() {
     31    static public void initPresets() {
    3232
    33                 presets = new Presets();
    34                 LinkedList<String> sources = new LinkedList<String>();
     33        presets = new Presets();
     34        LinkedList<String> sources = new LinkedList<String>();
    3535
    36                 // code copied from org.openstreetmap.josm.gui.tagging.TaggingPreset
    37                 // and slightly modified
    38                 //
    39                 if (Main.pref.getBoolean("taggingpreset.enable-defaults", true)) {
    40                         sources.add("resource://data/defaultpresets.xml");
    41                 }
    42                 sources.addAll(Main.pref.getCollection("taggingpreset.sources",
    43                                 new LinkedList<String>()));
     36        // code copied from org.openstreetmap.josm.gui.tagging.TaggingPreset
     37        // and slightly modified
     38        //
     39        if (Main.pref.getBoolean("taggingpreset.enable-defaults", true)) {
     40            sources.add("resource://data/defaultpresets.xml");
     41        }
     42        sources.addAll(Main.pref.getCollection("taggingpreset.sources",
     43                new LinkedList<String>()));
    4444
    45                 File zipIconArchive = null;
    46                 for (String source : sources) {
    47                         try {
    48                                 MirroredInputStream s = new MirroredInputStream(source);
     45        File zipIconArchive = null;
     46        for (String source : sources) {
     47            try {
     48                MirroredInputStream s = new MirroredInputStream(source);
    4949                InputStream zip = s.getZipEntry("xml","preset");
    5050                if(zip != null) {
    51                         zipIconArchive = s.getFile();
     51                    zipIconArchive = s.getFile();
    5252                }
    53                                 InputStreamReader r;
    54                                 try {
    55                                         r = new InputStreamReader(s, "UTF-8");
    56                                 } catch (UnsupportedEncodingException e) {
    57                                         r = new InputStreamReader(s);
    58                                 }
    59                                 presets = loadPresets(r, presets, zipIconArchive);
    60                         } catch (PresetIOException e) {
    61                                 logger
    62                                                 .log(Level.SEVERE, tr(
    63                                                                 "Could not read tagging preset source: {0}",
    64                                                                 source), e);
    65                                 JOptionPane.showMessageDialog(Main.parent, tr(
    66                                                 "Could not read tagging preset source: {0}", source),
    67                                                 tr("Error"), JOptionPane.ERROR_MESSAGE);
    68                         } catch (IOException e) {
    69                                 e.printStackTrace();
    70                                 JOptionPane.showMessageDialog(Main.parent, tr(
    71                                                 "Could not read tagging preset source: {0}", source),
    72                                                 tr("Error"), JOptionPane.ERROR_MESSAGE);
    73                         }
    74                 }
    75         }
     53                InputStreamReader r;
     54                try {
     55                    r = new InputStreamReader(s, "UTF-8");
     56                } catch (UnsupportedEncodingException e) {
     57                    r = new InputStreamReader(s);
     58                }
     59                presets = loadPresets(r, presets, zipIconArchive);
     60            } catch (PresetIOException e) {
     61                logger
     62                        .log(Level.SEVERE, tr(
     63                                "Could not read tagging preset source: {0}",
     64                                source), e);
     65                JOptionPane.showMessageDialog(Main.parent, tr(
     66                        "Could not read tagging preset source: {0}", source),
     67                        tr("Error"), JOptionPane.ERROR_MESSAGE);
     68            } catch (IOException e) {
     69                e.printStackTrace();
     70                JOptionPane.showMessageDialog(Main.parent, tr(
     71                        "Could not read tagging preset source: {0}", source),
     72                        tr("Error"), JOptionPane.ERROR_MESSAGE);
     73            }
     74        }
     75    }
    7676
    77         static public Presets loadPresets(URL from) throws PresetIOException {
    78                 try {
    79                         URLConnection con = from.openConnection();
    80                         con.connect();
    81                         Reader reader = new InputStreamReader(con.getInputStream());
    82                         return loadPresets(reader, null, null);
    83                 } catch (Exception e) {
    84                         logger.log(Level.SEVERE,
    85                                         "exception caught while loading preset file", e);
    86                         throw new PresetIOException(e);
    87                 }
    88         }
     77    static public Presets loadPresets(URL from) throws PresetIOException {
     78        try {
     79            URLConnection con = from.openConnection();
     80            con.connect();
     81            Reader reader = new InputStreamReader(con.getInputStream());
     82            return loadPresets(reader, null, null);
     83        } catch (Exception e) {
     84            logger.log(Level.SEVERE,
     85                    "exception caught while loading preset file", e);
     86            throw new PresetIOException(e);
     87        }
     88    }
    8989
    90         static public Presets loadPresets(Reader reader, Presets p, File zipIconArchive) throws PresetIOException {
    91                 try {
    92                         Parser parser = new Parser();
    93                         parser.setReader(reader);
    94                         parser.setPresets(p);
    95                         parser.parse();
    96                         return parser.getPresets();
    97                 } catch (Exception e) {
    98                         logger.log(Level.SEVERE, "exception caught while loading presets",e);
    99                         throw new PresetIOException(e);
    100                 }
    101         }
     90    static public Presets loadPresets(Reader reader, Presets p, File zipIconArchive) throws PresetIOException {
     91        try {
     92            Parser parser = new Parser();
     93            parser.setReader(reader);
     94            parser.setPresets(p);
     95            parser.parse();
     96            return parser.getPresets();
     97        } catch (Exception e) {
     98            logger.log(Level.SEVERE, "exception caught while loading presets",e);
     99            throw new PresetIOException(e);
     100        }
     101    }
    102102
    103         static public Presets getPresets() {
    104                 if (presets == null) {
    105                         initPresets();
    106                 }
    107                 return presets;
    108         }
     103    static public Presets getPresets() {
     104        if (presets == null) {
     105            initPresets();
     106        }
     107        return presets;
     108    }
    109109
    110         private List<Group> groups;
     110    private List<Group> groups;
    111111
    112         public Presets() {
    113                 groups = new ArrayList<Group>();
    114         }
     112    public Presets() {
     113        groups = new ArrayList<Group>();
     114    }
    115115
    116         public void addGroup(Group group) {
    117                 groups.add(group);
    118         }
     116    public void addGroup(Group group) {
     117        groups.add(group);
     118    }
    119119
    120         public void removeGroup(Group group) {
    121                 groups.remove(group);
    122         }
     120    public void removeGroup(Group group) {
     121        groups.remove(group);
     122    }
    123123
    124         public List<Group> getGroups() {
    125                 return groups;
    126         }
     124    public List<Group> getGroups() {
     125        return groups;
     126    }
    127127}
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/Tag.java

    r20058 r23189  
    22
    33public class Tag {
    4         private String key;
    5         private String value;
    6         private String displayName;
    7         private boolean optional = false;
    8        
    9         public Tag() {         
    10         }
     4    private String key;
     5    private String value;
     6    private String displayName;
     7    private boolean optional = false;
     8   
     9    public Tag() {     
     10    }
    1111
    12         public String getKey() {
    13                 return key;
    14         }
     12    public String getKey() {
     13        return key;
     14    }
    1515
    16         public void setKey(String key) {
    17                 this.key = key;
    18         }
     16    public void setKey(String key) {
     17        this.key = key;
     18    }
    1919
    20         public String getValue() {
    21                 return value;
    22         }
     20    public String getValue() {
     21        return value;
     22    }
    2323
    24         public void setValue(String value) {
    25                 this.value = value;
    26         }
     24    public void setValue(String value) {
     25        this.value = value;
     26    }
    2727
    28         public String getDisplayName() {
    29                 return displayName;
    30         }
     28    public String getDisplayName() {
     29        return displayName;
     30    }
    3131
    32         public void setDisplayName(String displayName) {
    33                 this.displayName = displayName;
    34         }
     32    public void setDisplayName(String displayName) {
     33        this.displayName = displayName;
     34    }
    3535
    36         public boolean isOptional() {
    37                 return optional;
    38         }
     36    public boolean isOptional() {
     37        return optional;
     38    }
    3939
    40         public void setOptional(boolean optional) {
    41                 this.optional = optional;
    42         }
     40    public void setOptional(boolean optional) {
     41        this.optional = optional;
     42    }
    4343}
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/io/Parser.java

    r20058 r23189  
    2222
    2323public class Parser {
    24        
    25         static final private Logger logger = Logger.getLogger(Parser.class.getName());
    26        
     24   
     25    static final private Logger logger = Logger.getLogger(Parser.class.getName());
     26   
    2727    private Presets presets = null;
    28         private Reader reader;
    29         private Stack<Group> currentGroup;
    30         private Item currentItem;
    31         private boolean inOptionalKeys = false;
    32         private XMLReader parser;
    33         private File zipIconArchive;
    34 
    35         public Parser() {
    36                 currentGroup = new Stack<Group>();
    37                 currentItem = null;
    38         }
    39        
    40         public Parser(Reader reader) {         
    41                 this();
    42                 if (reader == null) {
    43                         throw new IllegalArgumentException("reader must not be null");
    44                 }
    45                 this.reader = reader;
    46         }
    47        
    48         public void setReader(Reader reader) {
    49                 this.reader = reader;
    50         }
    51        
    52         public Reader getReader() {
    53                 return reader;
    54         }
    55        
    56         public void setZipIconArchive(File zipIconArchive) {
    57                 this.zipIconArchive = zipIconArchive;
    58         }
    59        
    60         public Presets getPresets() {
    61                 return presets;
    62         }
    63 
    64         public void setPresets(Presets presets) {
    65                 this.presets = presets;
    66         }
    67 
    68         protected void init() throws PresetIOException {
    69                 try {
    70                         parser = XMLReaderFactory.createXMLReader();
    71                         Handler handler = new Handler();
    72                         parser.setContentHandler(handler);
    73                         parser.setErrorHandler(handler);
    74                         parser.setFeature( "http://xml.org/sax/features/validation", false);
    75                         parser.setFeature("http://xml.org/sax/features/namespaces", false);
    76                         parser.setFeature("http://xml.org/sax/features/namespace-prefixes", false);
    77                 } catch(SAXException e) {
    78                         logger.log(Level.SEVERE, "exception while creating SAX parser", e);
    79                         throw new PresetIOException("exception while creating SAX parser",e);                   
    80                 }
    81         }
    82 
    83         /**
    84         * parses the presets given by the input source in {@see #getReader()}.
    85         * Creates a new set of presets if {@see #getPresets()} is null, otherwise
    86         * parses the presets into the set of presets given by {@see #getPresets()}.
    87         *
    88         * Call {@see #getPresets()} to retrieve the parsed presets after parsing.
    89         *
    90         * @throws IllegalStateException thrown, if {@see #getReader()} is null. Set a properly initialized reader first.
    91         * @throws PresetIOException if an exception is detected during parsing
    92         */
    93         public void parse()  throws PresetIOException {
    94                 if (getReader() == null) {
    95                         throw new IllegalStateException("reader is null. set reader first.");
    96                 }
    97                 if (getPresets() == null) {
    98                         logger.warning("presets is null. Creating a new set of presets");
    99                         setPresets(new Presets());
    100                 }
    101                 parse(getReader());
    102                 return;
    103         }
    104        
    105         /**
    106         * parses the presets given by the input source in {@see #getReader()}.
    107         * Creates a new set of presets if {@see #getPresets()} is null, otherwise
    108         * parses the presets into the set of presets given by {@see #getPresets()}.
    109         *
    110         * Call {@see #getPresets()} to retrieve the parsed presets after parsing.
    111         *
    112         * @param reader  a properly initialized reader
    113         * @throws PresetIOException if an exception is detected during parsing
    114         */
    115         public void parse(Reader reader) throws PresetIOException {
    116                 init();
    117                 if (getPresets() == null) {
    118                         logger.warning("presets is null. Creating a new set of presets");
    119                         setPresets(new Presets());
    120                 }
    121                 try {
    122                         parser.parse(new InputSource(reader));
    123                 } catch(Exception e) {
    124                         logger.log(Level.SEVERE, "exception while parsing preset file", e);
    125                         throw new PresetIOException(e);
    126                 }
    127                 // "release" XML parser
    128                 parser = null;         
    129         }
    130        
    131         protected String translatedAttributeValue(String attrValue) {
    132                 if (attrValue == null) {
    133                         return null;
    134                 } else {
    135                         return tr(attrValue);
    136                 }
    137         }
    138        
    139         protected void onStartGroup(String name, String iconName) {
    140                 Group g = new Group();
    141                 g.setName(translatedAttributeValue(name));
    142                 g.setIconName(iconName, zipIconArchive);
    143                 currentGroup.push(g);
    144         }
    145        
    146         protected void onEndGroup() {
    147                 Group g = currentGroup.pop();
    148                 presets.addGroup(g);
    149         }
    150        
    151         protected void onStartItem(String name, String iconName) {
    152                 currentItem = new Item();
    153                 currentItem.setName(translatedAttributeValue(name));
    154                 currentItem.setIconName(iconName, zipIconArchive);
    155         }
    156        
    157         protected void onEndItem() {
    158                 if (currentGroup == null) {
    159                         logger.log(Level.SEVERE, "illegal state. no current group defined");
    160                         throw new IllegalStateException("illegal state. no current group defined");
    161                 }
    162                 currentGroup.peek().addItem(currentItem);
    163                 currentItem = null;
    164         }
    165        
    166         protected void onStartOptionalKeys() {
    167                 this.inOptionalKeys = true;
    168         }
    169        
    170         protected void onEndOptionalKeys() {
    171                 this.inOptionalKeys = false;
    172         }
    173        
    174         protected void onTag(String key, String value, String displayName){
    175                 Tag tag = new Tag();
    176                 tag.setKey(key);
    177                 tag.setValue(value);
    178                 tag.setDisplayName(translatedAttributeValue(displayName));
    179                 tag.setOptional(inOptionalKeys);
    180                
    181                 if (currentItem == null) {
    182                         logger.log(Level.SEVERE, "illegal state. no current item defined");
    183                         throw new IllegalStateException("illegal state. no current item defined");                     
    184                 }
    185                 currentItem.addTag(tag);       
    186         }
    187        
    188         protected void onLabel(String label) {
    189                 if (currentItem == null) {
    190                         logger.log(Level.SEVERE, "illegal state. no current item defined");
    191                         throw new IllegalStateException("illegal state. no current item defined");                                             
    192                 }
    193                 currentItem.setLabel(label);
    194         }
    195        
    196         /**
    197         * The SAX handler for reading XML files with tag specifications
    198         *
    199         *
    200         */
    201         class Handler extends DefaultHandler {
    202                
    203                 @Override
    204                 public void endDocument() throws SAXException {
    205                         logger.log(Level.FINE,"END");
    206                 }
    207 
    208                 @Override
    209                 public void error(SAXParseException e) throws SAXException {
    210                         logger.log(Level.SEVERE, "XML parsing error", e);
    211                 }
    212 
    213                 @Override
    214                 public void fatalError(SAXParseException e) throws SAXException {
    215                         logger.log(Level.SEVERE, "XML parsing error", e);
    216                 }
    217 
    218                 @Override
    219                 public void startDocument() throws SAXException {
    220                         logger.log(Level.FINE,"START");
    221                 }
    222 
    223                 protected String getAttribute(Attributes attributes, String qName) {
    224                         for (int i =0; i < attributes.getLength();i++) {
    225                                 if (attributes.getQName(i).equals(qName)) {
    226                                         return attributes.getValue(i);
    227                                 }
    228                         }
    229                         return null;
    230                 }
    231                
    232                 @Override
    233                 public void startElement(String namespaceURI, String localName, String qName,
    234                                 Attributes atts) throws SAXException {
    235                         if ("group".equals(qName)) {
    236                                 onStartGroup(getAttribute(atts, "name"), getAttribute(atts, "icon"));
    237                         } else if ("item".equals(qName)) {
    238                                 onStartItem(getAttribute(atts, "name"), getAttribute(atts, "icon"));
    239                         } else if ("label".equals(qName)) {
    240                                 onLabel(getAttribute(atts, "text"));
    241                         } else if ("optional".equals(qName)) {
    242                                 onStartOptionalKeys();
    243                         } else if ("key".equals(qName) || "text".equals(qName) || "combo".equals(qName)
    244                                            || "check".equals(qName)) {
    245                                 onTag(getAttribute(atts, "key"), getAttribute(atts, "value"), getAttribute(atts, "text"));
    246                         }                       
    247                 }
    248                
    249                 @Override
    250                 public void endElement(String namespaceURI, String localName, String qName)
    251                                 throws SAXException {
    252                         if ("group".equals(qName)) {
    253                                 onEndGroup();
    254                         } else if ("item".equals(qName)) {
    255                                 onEndItem();
    256                         } else if ("label".equals(qName)) {
    257                                 // do nothing
    258                         } else if ("optional".equals(qName)) {
    259                                 onEndOptionalKeys();
    260                         }                       
    261                 }
    262 
    263                 /* (non-Javadoc)
    264                 * @see org.xml.sax.helpers.DefaultHandler#warning(org.xml.sax.SAXParseException)
    265                 */
    266                 @Override
    267                 public void warning(SAXParseException e) throws SAXException {
    268                         // TODO Auto-generated method stub
    269                         logger.log(Level.WARNING, "XML parsing warning", e);
    270                 }
    271         }
     28    private Reader reader;
     29    private Stack<Group> currentGroup;
     30    private Item currentItem;
     31    private boolean inOptionalKeys = false;
     32    private XMLReader parser;
     33    private File zipIconArchive;
     34
     35    public Parser() {
     36        currentGroup = new Stack<Group>();
     37        currentItem = null;
     38    }
     39   
     40    public Parser(Reader reader) {     
     41        this();
     42        if (reader == null) {
     43            throw new IllegalArgumentException("reader must not be null");
     44        }
     45        this.reader = reader;
     46    }
     47   
     48    public void setReader(Reader reader) {
     49        this.reader = reader;
     50    }
     51   
     52    public Reader getReader() {
     53        return reader;
     54    }
     55   
     56    public void setZipIconArchive(File zipIconArchive) {
     57        this.zipIconArchive = zipIconArchive;
     58    }
     59   
     60    public Presets getPresets() {
     61        return presets;
     62    }
     63
     64    public void setPresets(Presets presets) {
     65        this.presets = presets;
     66    }
     67
     68    protected void init() throws PresetIOException {
     69        try {
     70            parser = XMLReaderFactory.createXMLReader();
     71            Handler handler = new Handler();
     72            parser.setContentHandler(handler);
     73            parser.setErrorHandler(handler);
     74            parser.setFeature( "http://xml.org/sax/features/validation", false);
     75            parser.setFeature("http://xml.org/sax/features/namespaces", false);
     76            parser.setFeature("http://xml.org/sax/features/namespace-prefixes", false);
     77        } catch(SAXException e) {
     78            logger.log(Level.SEVERE, "exception while creating SAX parser", e);
     79            throw new PresetIOException("exception while creating SAX parser",e);           
     80        }
     81    }
     82
     83    /**
     84    * parses the presets given by the input source in {@see #getReader()}.
     85    * Creates a new set of presets if {@see #getPresets()} is null, otherwise
     86    * parses the presets into the set of presets given by {@see #getPresets()}.
     87    *
     88    * Call {@see #getPresets()} to retrieve the parsed presets after parsing.
     89    *
     90    * @throws IllegalStateException thrown, if {@see #getReader()} is null. Set a properly initialized reader first.
     91    * @throws PresetIOException if an exception is detected during parsing
     92    */
     93    public void parse()  throws PresetIOException {
     94        if (getReader() == null) {
     95            throw new IllegalStateException("reader is null. set reader first.");
     96        }
     97        if (getPresets() == null) {
     98            logger.warning("presets is null. Creating a new set of presets");
     99            setPresets(new Presets());
     100        }
     101        parse(getReader());
     102        return;
     103    }
     104   
     105    /**
     106    * parses the presets given by the input source in {@see #getReader()}.
     107    * Creates a new set of presets if {@see #getPresets()} is null, otherwise
     108    * parses the presets into the set of presets given by {@see #getPresets()}.
     109    *
     110    * Call {@see #getPresets()} to retrieve the parsed presets after parsing.
     111    *
     112    * @param reader  a properly initialized reader
     113    * @throws PresetIOException if an exception is detected during parsing
     114    */
     115    public void parse(Reader reader) throws PresetIOException {
     116        init();
     117        if (getPresets() == null) {
     118            logger.warning("presets is null. Creating a new set of presets");
     119            setPresets(new Presets());
     120        }
     121        try {
     122            parser.parse(new InputSource(reader));
     123        } catch(Exception e) {
     124            logger.log(Level.SEVERE, "exception while parsing preset file", e);
     125            throw new PresetIOException(e);
     126        }
     127        // "release" XML parser
     128        parser = null;     
     129    }
     130   
     131    protected String translatedAttributeValue(String attrValue) {
     132        if (attrValue == null) {
     133            return null;
     134        } else {
     135            return tr(attrValue);
     136        }
     137    }
     138   
     139    protected void onStartGroup(String name, String iconName) {
     140        Group g = new Group();
     141        g.setName(translatedAttributeValue(name));
     142        g.setIconName(iconName, zipIconArchive);
     143        currentGroup.push(g);
     144    }
     145   
     146    protected void onEndGroup() {
     147        Group g = currentGroup.pop();
     148        presets.addGroup(g);
     149    }
     150   
     151    protected void onStartItem(String name, String iconName) {
     152        currentItem = new Item();
     153        currentItem.setName(translatedAttributeValue(name));
     154        currentItem.setIconName(iconName, zipIconArchive);
     155    }
     156   
     157    protected void onEndItem() {
     158        if (currentGroup == null) {
     159            logger.log(Level.SEVERE, "illegal state. no current group defined");
     160            throw new IllegalStateException("illegal state. no current group defined");
     161        }
     162        currentGroup.peek().addItem(currentItem);
     163        currentItem = null;
     164    }
     165   
     166    protected void onStartOptionalKeys() {
     167        this.inOptionalKeys = true;
     168    }
     169   
     170    protected void onEndOptionalKeys() {
     171        this.inOptionalKeys = false;
     172    }
     173   
     174    protected void onTag(String key, String value, String displayName){
     175        Tag tag = new Tag();
     176        tag.setKey(key);
     177        tag.setValue(value);
     178        tag.setDisplayName(translatedAttributeValue(displayName));
     179        tag.setOptional(inOptionalKeys);
     180       
     181        if (currentItem == null) {
     182            logger.log(Level.SEVERE, "illegal state. no current item defined");
     183            throw new IllegalStateException("illegal state. no current item defined");         
     184        }
     185        currentItem.addTag(tag);   
     186    }
     187   
     188    protected void onLabel(String label) {
     189        if (currentItem == null) {
     190            logger.log(Level.SEVERE, "illegal state. no current item defined");
     191            throw new IllegalStateException("illegal state. no current item defined");                     
     192        }
     193        currentItem.setLabel(label);
     194    }
     195   
     196    /**
     197    * The SAX handler for reading XML files with tag specifications
     198    *
     199    *
     200    */
     201    class Handler extends DefaultHandler {
     202       
     203        @Override
     204        public void endDocument() throws SAXException {
     205            logger.log(Level.FINE,"END");
     206        }
     207
     208        @Override
     209        public void error(SAXParseException e) throws SAXException {
     210            logger.log(Level.SEVERE, "XML parsing error", e);
     211        }
     212
     213        @Override
     214        public void fatalError(SAXParseException e) throws SAXException {
     215            logger.log(Level.SEVERE, "XML parsing error", e);
     216        }
     217
     218        @Override
     219        public void startDocument() throws SAXException {
     220            logger.log(Level.FINE,"START");
     221        }
     222
     223        protected String getAttribute(Attributes attributes, String qName) {
     224            for (int i =0; i < attributes.getLength();i++) {
     225                if (attributes.getQName(i).equals(qName)) {
     226                    return attributes.getValue(i);
     227                }
     228            }
     229            return null;
     230        }
     231       
     232        @Override
     233        public void startElement(String namespaceURI, String localName, String qName,
     234                Attributes atts) throws SAXException {
     235            if ("group".equals(qName)) {
     236                onStartGroup(getAttribute(atts, "name"), getAttribute(atts, "icon"));
     237            } else if ("item".equals(qName)) {
     238                onStartItem(getAttribute(atts, "name"), getAttribute(atts, "icon"));
     239            } else if ("label".equals(qName)) {
     240                onLabel(getAttribute(atts, "text"));
     241            } else if ("optional".equals(qName)) {
     242                onStartOptionalKeys();
     243            } else if ("key".equals(qName) || "text".equals(qName) || "combo".equals(qName)
     244                       || "check".equals(qName)) {
     245                onTag(getAttribute(atts, "key"), getAttribute(atts, "value"), getAttribute(atts, "text"));
     246            }           
     247        }
     248       
     249        @Override
     250        public void endElement(String namespaceURI, String localName, String qName)
     251                throws SAXException {
     252            if ("group".equals(qName)) {
     253                onEndGroup();
     254            } else if ("item".equals(qName)) {
     255                onEndItem();
     256            } else if ("label".equals(qName)) {
     257                // do nothing
     258            } else if ("optional".equals(qName)) {
     259                onEndOptionalKeys();
     260            }           
     261        }
     262
     263        /* (non-Javadoc)
     264        * @see org.xml.sax.helpers.DefaultHandler#warning(org.xml.sax.SAXParseException)
     265        */
     266        @Override
     267        public void warning(SAXParseException e) throws SAXException {
     268            // TODO Auto-generated method stub
     269            logger.log(Level.WARNING, "XML parsing warning", e);
     270        }
     271    }
    272272}
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/io/PresetIOException.java

    r20058 r23189  
    33public class PresetIOException extends Exception {
    44
    5         public PresetIOException() {
    6                 super();
    7                 // TODO Auto-generated constructor stub
    8         }
     5    public PresetIOException() {
     6        super();
     7        // TODO Auto-generated constructor stub
     8    }
    99
    10         public PresetIOException(String arg0, Throwable arg1) {
    11                 super(arg0, arg1);
    12                 // TODO Auto-generated constructor stub
    13         }
     10    public PresetIOException(String arg0, Throwable arg1) {
     11        super(arg0, arg1);
     12        // TODO Auto-generated constructor stub
     13    }
    1414
    15         public PresetIOException(String arg0) {
    16                 super(arg0);
    17                 // TODO Auto-generated constructor stub
    18         }
     15    public PresetIOException(String arg0) {
     16        super(arg0);
     17        // TODO Auto-generated constructor stub
     18    }
    1919
    20         public PresetIOException(Throwable arg0) {
    21                 super(arg0);
    22                 // TODO Auto-generated constructor stub
    23         }
     20    public PresetIOException(Throwable arg0) {
     21        super(arg0);
     22        // TODO Auto-generated constructor stub
     23    }
    2424}
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/ui/IPresetSelectorListener.java

    r14328 r23189  
    55public interface IPresetSelectorListener {
    66
    7         public void itemSelected(Item item);
     7    public void itemSelected(Item item);
    88}
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/ui/NameIconCellRenderer.java

    r15319 r23189  
    1616public class NameIconCellRenderer extends JLabel implements TableCellRenderer {
    1717
    18         private static Logger logger = Logger.getLogger(NameIconCellRenderer.class.getName());
    19         public static final Color BG_COLOR_SELECTED = new Color(143,170,255);
     18    private static Logger logger = Logger.getLogger(NameIconCellRenderer.class.getName());
     19    public static final Color BG_COLOR_SELECTED = new Color(143,170,255);
    2020
    2121
    22         protected void init() {
    23                 setOpaque(true);
    24                 setFont(new Font("SansSerif",Font.PLAIN,10));
    25         }
     22    protected void init() {
     23        setOpaque(true);
     24        setFont(new Font("SansSerif",Font.PLAIN,10));
     25    }
    2626
    27         public NameIconCellRenderer() {
    28                 init();
    29         }
     27    public NameIconCellRenderer() {
     28        init();
     29    }
    3030
    31         public Component getTableCellRendererComponent(JTable table, Object value,
    32                         boolean isSelected, boolean hasFocus, int rowIndex, int colIndex) {
     31    public Component getTableCellRendererComponent(JTable table, Object value,
     32            boolean isSelected, boolean hasFocus, int rowIndex, int colIndex) {
    3333
    34                 if (isSelected) {
    35                         setBackground(BG_COLOR_SELECTED);
    36                 } else  {
    37                         setBackground(Color.WHITE);
    38                 }
    39                 INameIconProvider provider = (INameIconProvider) value;
    40                 setText(provider.getName());
    41                 setIcon(provider.getIcon());
    42                 return this;
    43         }
     34        if (isSelected) {
     35            setBackground(BG_COLOR_SELECTED);
     36        } else  {
     37            setBackground(Color.WHITE);
     38        }
     39        INameIconProvider provider = (INameIconProvider) value;
     40        setText(provider.getName());
     41        setIcon(provider.getIcon());
     42        return this;
     43    }
    4444}
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/ui/PresetsTable.java

    r14328 r23189  
    99public class PresetsTable extends JTable {
    1010
    11         /**
    12         * initialize the table
    13         */
    14         protected void init() {                         
    15                 setAutoResizeMode(JTable.AUTO_RESIZE_OFF);             
    16                 setRowSelectionAllowed(true);
    17                 setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    18                 setRowHeight(18); // icon height (=16) + minimal border
    19                
    20         }
    21        
    22         public PresetsTable(TableModel model, TableColumnModel columnModel) {
    23                 super(model,columnModel);
    24                 init();
    25         }
    26        
    27         /**
    28         * adjusts the width of the columns for the tag name and the tag value
    29         * to the width of the scroll panes viewport.
    30         *
    31         * Note: {@see #getPreferredScrollableViewportSize()} did not work as expected
    32         *
    33         * @param scrollPaneWidth the width of the scroll panes viewport
    34         */
    35         public void adjustColumnWidth(int scrollPaneWidth) {
    36                 TableColumnModel tcm = getColumnModel();
    37                 int width = scrollPaneWidth;
    38                 width = width / 2;
    39                 if (width > 0) {
    40                         tcm.getColumn(0).setMinWidth(width);
    41                         tcm.getColumn(0).setMaxWidth(width);
    42                         tcm.getColumn(1).setMinWidth(width);
    43                         tcm.getColumn(1).setMaxWidth(width);                   
    44                 }
    45         }
     11    /**
     12    * initialize the table
     13    */
     14    protected void init() {             
     15        setAutoResizeMode(JTable.AUTO_RESIZE_OFF);     
     16        setRowSelectionAllowed(true);
     17        setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
     18        setRowHeight(18); // icon height (=16) + minimal border
     19       
     20    }
     21   
     22    public PresetsTable(TableModel model, TableColumnModel columnModel) {
     23        super(model,columnModel);
     24        init();
     25    }
     26   
     27    /**
     28    * adjusts the width of the columns for the tag name and the tag value
     29    * to the width of the scroll panes viewport.
     30    *
     31    * Note: {@see #getPreferredScrollableViewportSize()} did not work as expected
     32    *
     33    * @param scrollPaneWidth the width of the scroll panes viewport
     34    */
     35    public void adjustColumnWidth(int scrollPaneWidth) {
     36        TableColumnModel tcm = getColumnModel();
     37        int width = scrollPaneWidth;
     38        width = width / 2;
     39        if (width > 0) {
     40            tcm.getColumn(0).setMinWidth(width);
     41            tcm.getColumn(0).setMaxWidth(width);
     42            tcm.getColumn(1).setMinWidth(width);
     43            tcm.getColumn(1).setMaxWidth(width);           
     44        }
     45    }
    4646
    4747}
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/ui/PresetsTableColumnModel.java

    r14328 r23189  
    88public class PresetsTableColumnModel extends DefaultTableColumnModel  {
    99
    10         protected void createColumns() {
    11                 TableCellRenderer renderer = new NameIconCellRenderer();
    12                
    13                 TableColumn col = null;
    14                
    15                 // column 0 - Group   
    16                 col = new TableColumn(0);
    17                 col.setHeaderValue(tr("Group"));
    18                 col.setResizable(true);
    19                 col.setCellRenderer(renderer);
    20                 addColumn(col);
    21                
    22                 // column 1 - Item   
    23                 col = new TableColumn(1);
    24                 col.setHeaderValue(tr("Item"));
    25                 col.setResizable(true);
    26                 col.setCellRenderer(renderer);
    27                 addColumn(col);
     10    protected void createColumns() {
     11        TableCellRenderer renderer = new NameIconCellRenderer();
     12       
     13        TableColumn col = null;
     14       
     15        // column 0 - Group   
     16        col = new TableColumn(0);
     17        col.setHeaderValue(tr("Group"));
     18        col.setResizable(true);
     19        col.setCellRenderer(renderer);
     20        addColumn(col);
     21       
     22        // column 1 - Item   
     23        col = new TableColumn(1);
     24        col.setHeaderValue(tr("Item"));
     25        col.setResizable(true);
     26        col.setCellRenderer(renderer);
     27        addColumn(col);
    2828
    29         }
     29    }
    3030
    31         public PresetsTableColumnModel() {
    32                 createColumns();
    33         }
    34        
     31    public PresetsTableColumnModel() {
     32        createColumns();
     33    }
     34   
    3535}
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/ui/PresetsTableModel.java

    r17637 r23189  
    1414public class PresetsTableModel extends AbstractTableModel  {
    1515
    16         private static final Logger logger = Logger.getLogger(PresetsTableModel.class.getName());
     16    private static final Logger logger = Logger.getLogger(PresetsTableModel.class.getName());
    1717
    18         private final ArrayList<TableModelListener> listeners = new ArrayList<TableModelListener>();
    19         private final ArrayList<Item> items = new ArrayList<Item>();
    20         private final ArrayList<Item> visibleItems = new ArrayList<Item>();
    21         private Presets presets = null;
     18    private final ArrayList<TableModelListener> listeners = new ArrayList<TableModelListener>();
     19    private final ArrayList<Item> items = new ArrayList<Item>();
     20    private final ArrayList<Item> visibleItems = new ArrayList<Item>();
     21    private Presets presets = null;
    2222
    23         protected void initModelFromPresets(Presets presets) {
    24                 for(Group group: presets.getGroups()) {
    25                         for(Item item: group.getItems()) {
    26                                 items.add(item);
    27                                 visibleItems.add(item);
    28                         }
    29                 }
    30         }
     23    protected void initModelFromPresets(Presets presets) {
     24        for(Group group: presets.getGroups()) {
     25            for(Item item: group.getItems()) {
     26                items.add(item);
     27                visibleItems.add(item);
     28            }
     29        }
     30    }
    3131
    32         public PresetsTableModel() {
    33         }
     32    public PresetsTableModel() {
     33    }
    3434
    35         public PresetsTableModel(Presets presets) {
    36                 setPresets(presets);
    37         }
     35    public PresetsTableModel(Presets presets) {
     36        setPresets(presets);
     37    }
    3838
    3939
    40         public Presets getPresets() {
    41                 return presets;
    42         }
     40    public Presets getPresets() {
     41        return presets;
     42    }
    4343
    44         public void setPresets(Presets presets) {
    45                 this.presets = presets;
    46                 initModelFromPresets(presets);
    47                 fireTableDataChanged();
    48         }
     44    public void setPresets(Presets presets) {
     45        this.presets = presets;
     46        initModelFromPresets(presets);
     47        fireTableDataChanged();
     48    }
    4949
    50         @Override
    51         public void addTableModelListener(TableModelListener l) {
    52                 synchronized(listeners) {
    53                         if (l == null)
    54                                 return;
    55                         if (!listeners.contains(l)) {
    56                                 listeners.add(l);
    57                         }
    58                 }
    59         }
     50    @Override
     51    public void addTableModelListener(TableModelListener l) {
     52        synchronized(listeners) {
     53            if (l == null)
     54                return;
     55            if (!listeners.contains(l)) {
     56                listeners.add(l);
     57            }
     58        }
     59    }
    6060
    61         @Override
    62         public Class<?> getColumnClass(int columnIndex) {
    63                 return String.class;
    64         }
     61    @Override
     62    public Class<?> getColumnClass(int columnIndex) {
     63        return String.class;
     64    }
    6565
    66         public int getColumnCount() {
    67                 return 2;
    68         }
     66    public int getColumnCount() {
     67        return 2;
     68    }
    6969
    70         public int getRowCount() {
    71                 return visibleItems.size();
    72         }
     70    public int getRowCount() {
     71        return visibleItems.size();
     72    }
    7373
    74         public Object getValueAt(int rowIndex, int columnIndex) {
    75                 Item item = visibleItems.get(rowIndex);
    76                 switch(columnIndex) {
    77                 case 0: return item.getParent();
    78                 case 1: return item;
    79                 default: return "unknown";
     74    public Object getValueAt(int rowIndex, int columnIndex) {
     75        Item item = visibleItems.get(rowIndex);
     76        switch(columnIndex) {
     77        case 0: return item.getParent();
     78        case 1: return item;
     79        default: return "unknown";
    8080
    81                 }
    82         }
     81        }
     82    }
    8383
    84         @Override
    85         public boolean isCellEditable(int rowIndex, int columnIndex) {
    86                 return false;
    87         }
     84    @Override
     85    public boolean isCellEditable(int rowIndex, int columnIndex) {
     86        return false;
     87    }
    8888
    89         @Override
    90         public void removeTableModelListener(TableModelListener l) {
    91                 synchronized (listeners) {
    92                         if (listeners.contains(l)) {
    93                                 listeners.remove(l);
    94                         }
    95                 }
    96         }
     89    @Override
     90    public void removeTableModelListener(TableModelListener l) {
     91        synchronized (listeners) {
     92            if (listeners.contains(l)) {
     93                listeners.remove(l);
     94            }
     95        }
     96    }
    9797
    98         @Override
    99         public void setValueAt(Object value, int rowIndex, int columnIndex) {
    100                 // do nothing. No editing allowed
    101         }
     98    @Override
     99    public void setValueAt(Object value, int rowIndex, int columnIndex) {
     100        // do nothing. No editing allowed
     101    }
    102102
    103         public Item getVisibleItem(int idx) {
    104                 if (idx < 0 || idx >= this.visibleItems.size())
    105                         throw new IndexOutOfBoundsException("index out of bounds. idx=" + idx);
    106                 return visibleItems.get(idx);
    107         }
     103    public Item getVisibleItem(int idx) {
     104        if (idx < 0 || idx >= this.visibleItems.size())
     105            throw new IndexOutOfBoundsException("index out of bounds. idx=" + idx);
     106        return visibleItems.get(idx);
     107    }
    108108
    109         public void filter(String filter) {
    110                 synchronized(this) {
    111                         if (filter == null || filter.trim().equals("")) {
    112                                 visibleItems.clear();
    113                                 for(Item item: items) {
    114                                         visibleItems.add(item);
    115                                 }
    116                         } else {
    117                                 visibleItems.clear();
    118                                 filter = filter.toLowerCase();
    119                                 for(Item item: items) {
    120                                         if (    (item.getName() != null && item.getName().toLowerCase().trim().startsWith(filter))
    121                                                         || (item.getParent().getName() != null && item.getParent().getName().toLowerCase().trim().startsWith(filter))) {
    122                                                 visibleItems.add(item);
    123                                         }
    124                                 }
    125                         }
    126                         fireTableDataChanged();
    127                         fireTableStructureChanged();
    128                 }
    129         }
     109    public void filter(String filter) {
     110        synchronized(this) {
     111            if (filter == null || filter.trim().equals("")) {
     112                visibleItems.clear();
     113                for(Item item: items) {
     114                    visibleItems.add(item);
     115                }
     116            } else {
     117                visibleItems.clear();
     118                filter = filter.toLowerCase();
     119                for(Item item: items) {
     120                    if (    (item.getName() != null && item.getName().toLowerCase().trim().startsWith(filter))
     121                            || (item.getParent().getName() != null && item.getParent().getName().toLowerCase().trim().startsWith(filter))) {
     122                        visibleItems.add(item);
     123                    }
     124                }
     125            }
     126            fireTableDataChanged();
     127            fireTableStructureChanged();
     128        }
     129    }
    130130}
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/preset/ui/TabularPresetSelector.java

    r21024 r23189  
    3737public class TabularPresetSelector extends JPanel {
    3838
    39         private PresetsTable presetsTable = null;
    40         private JTextField   tfFilter = null;
    41         private final ArrayList<IPresetSelectorListener> listeners = new ArrayList<IPresetSelectorListener>();
    42         private JScrollPane scrollPane;
    43         private JButton btnApply;
    44 
    45 
    46         protected JPanel buildFilterPanel() {
    47                 JPanel pnl = new JPanel();
    48                 JLabel lbl = new JLabel(tr("Search: "));
    49                 pnl.setLayout(new FlowLayout(FlowLayout.LEFT));
    50                 tfFilter = new JTextField(20);
    51                 pnl.add(lbl);
    52                 pnl.add(tfFilter,BorderLayout.CENTER);
    53                 JButton btn = new JButton(tr("Filter"));
    54                 pnl.add(btn);
    55                 btn.addActionListener(
    56                                 new ActionListener() {
    57                                         public void actionPerformed(ActionEvent e) {
    58                                                 filter(tfFilter.getText());
    59                                         }
    60 
    61                                 }
    62                 );
    63                 btn = new JButton(tr("Clear"));
    64                 pnl.add(btn);
    65                 btn.addActionListener(
    66                                 new ActionListener() {
    67                                         public void actionPerformed(ActionEvent e) {
    68                                                 tfFilter.setText("");
    69                                                 tfFilter.requestFocus();
    70                                         }
    71                                 }
    72                 );
    73                 return pnl;
    74         }
    75 
    76 
    77 
    78         protected JScrollPane buildPresetGrid() {
    79 
    80                 presetsTable = new PresetsTable(new PresetsTableModel(),new PresetsTableColumnModel());
    81 
    82                 scrollPane = new JScrollPane(presetsTable);
    83 
    84                 scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    85                 scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
    86 
    87                 // this adapters ensures that the width of the tag table columns is adjusted
    88                 // to the width of the scroll pane viewport. Also tried to overwrite
    89                 // getPreferredViewportSize() in JTable, but did not work.
    90                 //
    91                 scrollPane.addComponentListener(
    92                                 new ComponentAdapter() {
    93                                         @Override public void componentResized(ComponentEvent e) {
    94                                                 super.componentResized(e);
    95                                                 Dimension d = scrollPane.getViewport().getExtentSize();
    96                                                 presetsTable.adjustColumnWidth(d.width);
    97                                         }
    98                                 }
    99                 );
    100 
    101                 // add the double click listener
    102                 //
    103                 presetsTable.addMouseListener(new DoubleClickAdapter());
    104 
    105                 // replace Enter action. apply the current preset on enter
    106                 //
    107                 presetsTable.unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0));
    108                 ActionListener enterAction = new ActionListener() {
    109                         public void actionPerformed(ActionEvent e) {
    110                                 int rowNum = presetsTable.getSelectedRow();
    111                                 if (rowNum >= 0) {
    112                                         Item item = getModel().getVisibleItem(rowNum);
    113                                         fireItemSelected(item);
    114                                 }
    115                         }
    116                 };
    117 
    118                 presetsTable.registerKeyboardAction(
    119                                 enterAction,
    120                                 "Enter",
    121                                 KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0),
    122                                 JComponent.WHEN_FOCUSED
    123                 );
    124 
    125                 return scrollPane;
    126         }
    127 
    128         protected JPanel buildControlButtonPanel() {
    129                 JPanel pnl = new JPanel();
    130                 pnl.setLayout(new FlowLayout(FlowLayout.LEFT));
    131                 btnApply = new JButton(tr("Apply"));
    132                 pnl.add(btnApply);
    133                 btnApply.addActionListener(
    134                                 new ActionListener() {
    135                                         public void actionPerformed(ActionEvent arg0) {
    136                                                 int row = presetsTable.getSelectedRow();
    137                                                 if (row >=0) {
    138                                                         Item item = getModel().getVisibleItem(row);
    139                                                         fireItemSelected(item);
    140                                                 }
    141                                         }
    142                                 }
    143                 );
    144                 return pnl;
    145         }
    146 
    147         protected void build() {
    148                 setLayout(new BorderLayout());
    149                 add(buildFilterPanel(), BorderLayout.NORTH);
    150                 add(buildPresetGrid(), BorderLayout.CENTER);
    151                 add(buildControlButtonPanel(), BorderLayout.SOUTH);
    152 
    153                 // wire the text field for filter expressions to the prests
    154                 // table
    155                 //
    156                 tfFilter.getDocument().addDocumentListener(
    157                                 new DocumentListener() {
    158                                         public void changedUpdate(DocumentEvent arg0) {
    159                                                 onUpdate();
    160                                         }
    161 
    162                                         public void insertUpdate(DocumentEvent arg0) {
    163                                                 onUpdate();
    164                                         }
    165 
    166                                         public void removeUpdate(DocumentEvent arg0) {
    167                                                 onUpdate();
    168                                         }
    169 
    170                                         protected void onUpdate() {
    171                                                 filter(tfFilter.getText());
    172                                         }
    173                                 }
    174                 );
    175 
    176                 tfFilter.addActionListener(
    177                                 new ActionListener() {
    178                                         public void actionPerformed(ActionEvent e) {
    179                                                 filter(tfFilter.getText());
    180                                         }
    181                                 }
    182                 );
    183 
    184                 // wire the apply button to the selection model of the preset table
    185                 //
    186                 presetsTable.getSelectionModel().addListSelectionListener(
    187                                 new ListSelectionListener() {
    188                                         public void valueChanged(ListSelectionEvent e) {
    189                                                 btnApply.setEnabled(presetsTable.getSelectedRowCount() != 0);
    190                                         }
    191                                 }
    192                 );
    193 
    194 
    195                 // load the set of presets and bind them to the preset table
    196                 //
    197                 Presets.initPresets();
    198                 bindTo(Presets.getPresets());
    199                 presetsTable.getSelectionModel().clearSelection();
    200                 btnApply.setEnabled(false);
    201 
    202         }
    203 
    204         public void bindTo(Presets presets) {
    205                 PresetsTableModel model = (PresetsTableModel)presetsTable.getModel();
    206                 model.setPresets(presets);
    207         }
    208 
    209         public TabularPresetSelector() {
    210                 build();
    211         }
    212 
    213         public void addPresetSelectorListener(IPresetSelectorListener listener) {
    214                 synchronized(this.listeners) {
    215                         if (listener != null && ! listeners.contains(listener)) {
    216                                 listeners.add(listener);
    217                         }
    218                 }
    219         }
    220 
    221         public void removePresetSelectorListener(IPresetSelectorListener listener) {
    222                 synchronized(this.listeners) {
    223                         if (listener != null) {
    224                                 listeners.remove(listener);
    225                         }
    226                 }
    227         }
    228 
    229         protected void fireItemSelected(Item item) {
    230                 synchronized(this.listeners) {
    231                         for(IPresetSelectorListener listener: listeners) {
    232                                 listener.itemSelected(item);
    233                         }
    234                 }
    235         }
    236 
    237 
    238 
    239 
    240         private class DoubleClickAdapter extends MouseAdapter {
    241                 @Override
    242                 public void mouseClicked(MouseEvent e) {
    243                         if (e.getClickCount() == 2) {
    244                                 int rowNum = presetsTable.rowAtPoint(e.getPoint());
    245                                 Item item = getModel().getVisibleItem(rowNum);
    246                                 fireItemSelected(item);
    247                         }
    248                 }
    249         }
    250 
    251 
    252         public void filter(String filter) {
    253                 presetsTable.getSelectionModel().clearSelection();
    254                 getModel().filter(filter);
    255 
    256                 presetsTable.scrollRectToVisible(presetsTable.getCellRect(0, 0, false));
    257 
    258                 // we change the number of rows by applying a filter condition. Because
    259                 // the table is embedded in a JScrollPane which again may be embedded in
    260                 // other JScrollPanes or JSplitPanes it seems that we have to recalculate
    261                 // the layout and repaint the component tree. Maybe there is a more efficient way
    262                 // to keep the GUI in sync with the number of rows in table. By trial
    263                 // and error I ended up with the following lines.
    264                 //
    265                 Component c = presetsTable;
    266                 while(c != null) {
    267                         c.doLayout();
    268                         c.repaint();
    269                         c = c.getParent();
    270                 }
    271         }
    272 
    273 
    274         protected PresetsTableModel getModel() {
    275                 return (PresetsTableModel)presetsTable.getModel();
    276         }
    277 
    278         public void installKeyAction(Action a) {
    279                 getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put((KeyStroke)a.getValue(AbstractAction.ACCELERATOR_KEY), a.getValue(AbstractAction.NAME));
    280                 getActionMap().put(a.getValue(AbstractAction.NAME), a);
    281 
    282         }
     39    private PresetsTable presetsTable = null;
     40    private JTextField   tfFilter = null;
     41    private final ArrayList<IPresetSelectorListener> listeners = new ArrayList<IPresetSelectorListener>();
     42    private JScrollPane scrollPane;
     43    private JButton btnApply;
     44
     45
     46    protected JPanel buildFilterPanel() {
     47        JPanel pnl = new JPanel();
     48        JLabel lbl = new JLabel(tr("Search: "));
     49        pnl.setLayout(new FlowLayout(FlowLayout.LEFT));
     50        tfFilter = new JTextField(20);
     51        pnl.add(lbl);
     52        pnl.add(tfFilter,BorderLayout.CENTER);
     53        JButton btn = new JButton(tr("Filter"));
     54        pnl.add(btn);
     55        btn.addActionListener(
     56                new ActionListener() {
     57                    public void actionPerformed(ActionEvent e) {
     58                        filter(tfFilter.getText());
     59                    }
     60
     61                }
     62        );
     63        btn = new JButton(tr("Clear"));
     64        pnl.add(btn);
     65        btn.addActionListener(
     66                new ActionListener() {
     67                    public void actionPerformed(ActionEvent e) {
     68                        tfFilter.setText("");
     69                        tfFilter.requestFocus();
     70                    }
     71                }
     72        );
     73        return pnl;
     74    }
     75
     76
     77
     78    protected JScrollPane buildPresetGrid() {
     79
     80        presetsTable = new PresetsTable(new PresetsTableModel(),new PresetsTableColumnModel());
     81
     82        scrollPane = new JScrollPane(presetsTable);
     83
     84        scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
     85        scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
     86
     87        // this adapters ensures that the width of the tag table columns is adjusted
     88        // to the width of the scroll pane viewport. Also tried to overwrite
     89        // getPreferredViewportSize() in JTable, but did not work.
     90        //
     91        scrollPane.addComponentListener(
     92                new ComponentAdapter() {
     93                    @Override public void componentResized(ComponentEvent e) {
     94                        super.componentResized(e);
     95                        Dimension d = scrollPane.getViewport().getExtentSize();
     96                        presetsTable.adjustColumnWidth(d.width);
     97                    }
     98                }
     99        );
     100
     101        // add the double click listener
     102        //
     103        presetsTable.addMouseListener(new DoubleClickAdapter());
     104
     105        // replace Enter action. apply the current preset on enter
     106        //
     107        presetsTable.unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0));
     108        ActionListener enterAction = new ActionListener() {
     109            public void actionPerformed(ActionEvent e) {
     110                int rowNum = presetsTable.getSelectedRow();
     111                if (rowNum >= 0) {
     112                    Item item = getModel().getVisibleItem(rowNum);
     113                    fireItemSelected(item);
     114                }
     115            }
     116        };
     117
     118        presetsTable.registerKeyboardAction(
     119                enterAction,
     120                "Enter",
     121                KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0),
     122                JComponent.WHEN_FOCUSED
     123        );
     124
     125        return scrollPane;
     126    }
     127
     128    protected JPanel buildControlButtonPanel() {
     129        JPanel pnl = new JPanel();
     130        pnl.setLayout(new FlowLayout(FlowLayout.LEFT));
     131        btnApply = new JButton(tr("Apply"));
     132        pnl.add(btnApply);
     133        btnApply.addActionListener(
     134                new ActionListener() {
     135                    public void actionPerformed(ActionEvent arg0) {
     136                        int row = presetsTable.getSelectedRow();
     137                        if (row >=0) {
     138                            Item item = getModel().getVisibleItem(row);
     139                            fireItemSelected(item);
     140                        }
     141                    }
     142                }
     143        );
     144        return pnl;
     145    }
     146
     147    protected void build() {
     148        setLayout(new BorderLayout());
     149        add(buildFilterPanel(), BorderLayout.NORTH);
     150        add(buildPresetGrid(), BorderLayout.CENTER);
     151        add(buildControlButtonPanel(), BorderLayout.SOUTH);
     152
     153        // wire the text field for filter expressions to the prests
     154        // table
     155        //
     156        tfFilter.getDocument().addDocumentListener(
     157                new DocumentListener() {
     158                    public void changedUpdate(DocumentEvent arg0) {
     159                        onUpdate();
     160                    }
     161
     162                    public void insertUpdate(DocumentEvent arg0) {
     163                        onUpdate();
     164                    }
     165
     166                    public void removeUpdate(DocumentEvent arg0) {
     167                        onUpdate();
     168                    }
     169
     170                    protected void onUpdate() {
     171                        filter(tfFilter.getText());
     172                    }
     173                }
     174        );
     175
     176        tfFilter.addActionListener(
     177                new ActionListener() {
     178                    public void actionPerformed(ActionEvent e) {
     179                        filter(tfFilter.getText());
     180                    }
     181                }
     182        );
     183
     184        // wire the apply button to the selection model of the preset table
     185        //
     186        presetsTable.getSelectionModel().addListSelectionListener(
     187                new ListSelectionListener() {
     188                    public void valueChanged(ListSelectionEvent e) {
     189                        btnApply.setEnabled(presetsTable.getSelectedRowCount() != 0);
     190                    }
     191                }
     192        );
     193
     194
     195        // load the set of presets and bind them to the preset table
     196        //
     197        Presets.initPresets();
     198        bindTo(Presets.getPresets());
     199        presetsTable.getSelectionModel().clearSelection();
     200        btnApply.setEnabled(false);
     201
     202    }
     203
     204    public void bindTo(Presets presets) {
     205        PresetsTableModel model = (PresetsTableModel)presetsTable.getModel();
     206        model.setPresets(presets);
     207    }
     208
     209    public TabularPresetSelector() {
     210        build();
     211    }
     212
     213    public void addPresetSelectorListener(IPresetSelectorListener listener) {
     214        synchronized(this.listeners) {
     215            if (listener != null && ! listeners.contains(listener)) {
     216                listeners.add(listener);
     217            }
     218        }
     219    }
     220
     221    public void removePresetSelectorListener(IPresetSelectorListener listener) {
     222        synchronized(this.listeners) {
     223            if (listener != null) {
     224                listeners.remove(listener);
     225            }
     226        }
     227    }
     228
     229    protected void fireItemSelected(Item item) {
     230        synchronized(this.listeners) {
     231            for(IPresetSelectorListener listener: listeners) {
     232                listener.itemSelected(item);
     233            }
     234        }
     235    }
     236
     237
     238
     239
     240    private class DoubleClickAdapter extends MouseAdapter {
     241        @Override
     242        public void mouseClicked(MouseEvent e) {
     243            if (e.getClickCount() == 2) {
     244                int rowNum = presetsTable.rowAtPoint(e.getPoint());
     245                Item item = getModel().getVisibleItem(rowNum);
     246                fireItemSelected(item);
     247            }
     248        }
     249    }
     250
     251
     252    public void filter(String filter) {
     253        presetsTable.getSelectionModel().clearSelection();
     254        getModel().filter(filter);
     255
     256        presetsTable.scrollRectToVisible(presetsTable.getCellRect(0, 0, false));
     257
     258        // we change the number of rows by applying a filter condition. Because
     259        // the table is embedded in a JScrollPane which again may be embedded in
     260        // other JScrollPanes or JSplitPanes it seems that we have to recalculate
     261        // the layout and repaint the component tree. Maybe there is a more efficient way
     262        // to keep the GUI in sync with the number of rows in table. By trial
     263        // and error I ended up with the following lines.
     264        //
     265        Component c = presetsTable;
     266        while(c != null) {
     267            c.doLayout();
     268            c.repaint();
     269            c = c.getParent();
     270        }
     271    }
     272
     273
     274    protected PresetsTableModel getModel() {
     275        return (PresetsTableModel)presetsTable.getModel();
     276    }
     277
     278    public void installKeyAction(Action a) {
     279        getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put((KeyStroke)a.getValue(AbstractAction.ACCELERATOR_KEY), a.getValue(AbstractAction.NAME));
     280        getActionMap().put(a.getValue(AbstractAction.NAME), a);
     281
     282    }
    283283
    284284}
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/tagspec/KeyValuePair.java

    r14329 r23189  
    22
    33public class KeyValuePair {
    4         private String key = new String("");
    5         private String value = new String("");
    6        
    7         public KeyValuePair() {}
    8        
    9         public KeyValuePair(String key, String value) {
    10                 setKey(key);
    11                 setValue(value);
    12         }
     4    private String key = new String("");
     5    private String value = new String("");
     6   
     7    public KeyValuePair() {}
     8   
     9    public KeyValuePair(String key, String value) {
     10        setKey(key);
     11        setValue(value);
     12    }
    1313
    14        
    15         public String getKey() {
    16                 return key;
    17         }
     14   
     15    public String getKey() {
     16        return key;
     17    }
    1818
    19         public void setKey(String key) {
    20                 this.key = key == null? ""  :key;
    21         }
     19    public void setKey(String key) {
     20        this.key = key == null? ""  :key;
     21    }
    2222
    23         public String getValue() {
    24                 return value;
    25         }
     23    public String getValue() {
     24        return value;
     25    }
    2626
    27         public void setValue(String value) {
    28                 this.value = value == null ? "" : value;
    29         }
     27    public void setValue(String value) {
     28        this.value = value == null ? "" : value;
     29    }
    3030
    31         @Override
    32         public int hashCode() {
    33                 final int prime = 31;
    34                 int result = 1;
    35                 result = prime * result + ((key == null) ? 0 : key.hashCode());
    36                 result = prime * result + ((value == null) ? 0 : value.hashCode());
    37                 return result;
    38         }
     31    @Override
     32    public int hashCode() {
     33        final int prime = 31;
     34        int result = 1;
     35        result = prime * result + ((key == null) ? 0 : key.hashCode());
     36        result = prime * result + ((value == null) ? 0 : value.hashCode());
     37        return result;
     38    }
    3939
    40         @Override
    41         public boolean equals(Object obj) {
    42                 if (this == obj)
    43                         return true;
    44                 if (obj == null)
    45                         return false;
    46                 if (getClass() != obj.getClass())
    47                         return false;
    48                 KeyValuePair other = (KeyValuePair) obj;
    49                 if (key == null) {
    50                         if (other.key != null)
    51                                 return false;
    52                 } else if (!key.equals(other.key))
    53                         return false;
    54                 if (value == null) {
    55                         if (other.value != null)
    56                                 return false;
    57                 } else if (!value.equals(other.value))
    58                         return false;
    59                 return true;
    60         }
     40    @Override
     41    public boolean equals(Object obj) {
     42        if (this == obj)
     43            return true;
     44        if (obj == null)
     45            return false;
     46        if (getClass() != obj.getClass())
     47            return false;
     48        KeyValuePair other = (KeyValuePair) obj;
     49        if (key == null) {
     50            if (other.key != null)
     51                return false;
     52        } else if (!key.equals(other.key))
     53            return false;
     54        if (value == null) {
     55            if (other.value != null)
     56                return false;
     57        } else if (!value.equals(other.value))
     58            return false;
     59        return true;
     60    }
    6161
    6262}
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/tagspec/LableSpecification.java

    r14329 r23189  
    55public class LableSpecification {
    66
    7         /** the key of the tag */
    8         private String value;
    9                
    10        
    11         private boolean applicableToNode = true;
    12         private boolean applicableToWay = true;
    13         private boolean applicableToRelation = true;
    14        
    15         /**
    16         * constructor
    17         */
    18         public LableSpecification() {
    19         }
     7    /** the key of the tag */
     8    private String value;
     9       
     10   
     11    private boolean applicableToNode = true;
     12    private boolean applicableToWay = true;
     13    private boolean applicableToRelation = true;
     14   
     15    /**
     16    * constructor
     17    */
     18    public LableSpecification() {
     19    }
    2020
    21         public boolean isApplicable(AutoCompletionContext context) {
    22                 boolean ret = false;
    23                 if (context.isSelectionEmpty()) {
    24                         ret = true;
    25                 } else {
    26                         ret = ret || (applicableToNode && context.isSelectionIncludesNodes());
    27                         ret = ret || (applicableToWay && context.isSelectionIncludesWays());
    28                         ret = ret || (applicableToRelation && context.isSelectionIncludesRelations());
    29                 }
    30                 return ret;
    31         }
     21    public boolean isApplicable(AutoCompletionContext context) {
     22        boolean ret = false;
     23        if (context.isSelectionEmpty()) {
     24            ret = true;
     25        } else {
     26            ret = ret || (applicableToNode && context.isSelectionIncludesNodes());
     27            ret = ret || (applicableToWay && context.isSelectionIncludesWays());
     28            ret = ret || (applicableToRelation && context.isSelectionIncludesRelations());
     29        }
     30        return ret;
     31    }
    3232
    33         /* --------------------------------------------------------------------------- */
    34         /* setters/getters                                                             */
    35         /* --------------------------------------------------------------------------- */
     33    /* --------------------------------------------------------------------------- */
     34    /* setters/getters                                                             */
     35    /* --------------------------------------------------------------------------- */
    3636
    37         public String getValue() {
    38                 return value;
    39         }
     37    public String getValue() {
     38        return value;
     39    }
    4040
    41         public void setValue(String value) {
    42                 this.value = value;
    43         }
     41    public void setValue(String value) {
     42        this.value = value;
     43    }
    4444
    45         public boolean isApplicableToNode() {
    46                 return applicableToNode;
    47         }
     45    public boolean isApplicableToNode() {
     46        return applicableToNode;
     47    }
    4848
    49         public void setApplicableToNode(boolean applicableToNode) {
    50                 this.applicableToNode = applicableToNode;
    51         }
     49    public void setApplicableToNode(boolean applicableToNode) {
     50        this.applicableToNode = applicableToNode;
     51    }
    5252
    53         public boolean isApplicableToWay() {
    54                 return applicableToWay;
    55         }
     53    public boolean isApplicableToWay() {
     54        return applicableToWay;
     55    }
    5656
    57         public void setApplicableToWay(boolean applicableToWay) {
    58                 this.applicableToWay = applicableToWay;
    59         }
     57    public void setApplicableToWay(boolean applicableToWay) {
     58        this.applicableToWay = applicableToWay;
     59    }
    6060
    61         public boolean isApplicableToRelation() {
    62                 return applicableToRelation;
    63         }
     61    public boolean isApplicableToRelation() {
     62        return applicableToRelation;
     63    }
    6464
    65         public void setApplicableToRelation(boolean applicableToRelation) {
    66                 this.applicableToRelation = applicableToRelation;
    67         }
    68        
     65    public void setApplicableToRelation(boolean applicableToRelation) {
     66        this.applicableToRelation = applicableToRelation;
     67    }
     68   
    6969
    70        
    71        
     70   
     71   
    7272}
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/tagspec/TagSpecification.java

    r20058 r23189  
    1010 * elements:
    1111 * <ul>
    12  *       <li>the <strong>key</strong> the of the tag</li>
     12 *   <li>the <strong>key</strong> the of the tag</li>
    1313 *   <li>the <strong>type</strong> of the tag</li>
    1414 *   <li>whether the tag is applicable to a node, a way or a relation</li>
     
    1919public class TagSpecification {
    2020
    21         /** the key of the tag */
    22         private String key;
     21    /** the key of the tag */
     22    private String key;
    2323
    24         /** the type of the tag */
    25         private String type;
     24    /** the type of the tag */
     25    private String type;
    2626
    27         /** the type of the tag */
     27    /** the type of the tag */
    2828
    29         private boolean applicableToNode = true;
    30         private boolean applicableToWay = true;
    31         private boolean applicableToRelation = true;
     29    private boolean applicableToNode = true;
     30    private boolean applicableToWay = true;
     31    private boolean applicableToRelation = true;
    3232
    33         private ArrayList<LableSpecification> lables = null;
     33    private ArrayList<LableSpecification> lables = null;
    3434
    3535
    36         /**
    37         * constructor
    38         */
    39         public TagSpecification() {
    40                 lables = new ArrayList<LableSpecification>();
    41         }
     36    /**
     37    * constructor
     38    */
     39    public TagSpecification() {
     40        lables = new ArrayList<LableSpecification>();
     41    }
    4242
    43         @Override
    44         public String toString() {
    45                 StringBuilder builder = new StringBuilder();
    46                 builder.append("<TagSpecification ");
    47                 builder.append("key=\"").append(key).append("\"").append(", ");
    48                 builder.append("type=\"").append(type).append("\"").append(", ");
    49                 builder.append("applicable-to-node=\"").append(applicableToNode).append("\"").append(", ");
    50                 builder.append("applicable-to-way=\"").append(applicableToWay).append("\"").append(", ");
    51                 builder.append("applicable-to-relation=\"").append(applicableToRelation).append("\"");
    52                 builder.append(" />");
    53                 return builder.toString();
    54         }
     43    @Override
     44    public String toString() {
     45        StringBuilder builder = new StringBuilder();
     46        builder.append("<TagSpecification ");
     47        builder.append("key=\"").append(key).append("\"").append(", ");
     48        builder.append("type=\"").append(type).append("\"").append(", ");
     49        builder.append("applicable-to-node=\"").append(applicableToNode).append("\"").append(", ");
     50        builder.append("applicable-to-way=\"").append(applicableToWay).append("\"").append(", ");
     51        builder.append("applicable-to-relation=\"").append(applicableToRelation).append("\"");
     52        builder.append(" />");
     53        return builder.toString();
     54    }
    5555
    56         /**
    57         * @return th e list of predefined labels for this tag; an empty list if no
    58         *   labels are defined
    59         */
    60         public List<LableSpecification> getLables() {
    61                 return lables;
    62         }
     56    /**
     57    * @return th e list of predefined labels for this tag; an empty list if no
     58    *   labels are defined
     59    */
     60    public List<LableSpecification> getLables() {
     61        return lables;
     62    }
    6363
    64         /**
    65         * sets the list of lables for this tag specification
    66         *
    67         * @param lables  the list of lables; must not be null
    68         * @exception IllegalArgumentException thrown, if lables is null
    69         */
    70         public void setLables(List<LableSpecification> lables) throws IllegalArgumentException {
    71                 if (lables == null)
    72                         throw new IllegalArgumentException("argument 'lables' must not be null");
    73                 this.lables.clear();
    74                 for (LableSpecification l : lables) {
    75                         this.lables.add(l);
    76                 }
    77         }
     64    /**
     65    * sets the list of lables for this tag specification
     66    *
     67    * @param lables  the list of lables; must not be null
     68    * @exception IllegalArgumentException thrown, if lables is null
     69    */
     70    public void setLables(List<LableSpecification> lables) throws IllegalArgumentException {
     71        if (lables == null)
     72            throw new IllegalArgumentException("argument 'lables' must not be null");
     73        this.lables.clear();
     74        for (LableSpecification l : lables) {
     75            this.lables.add(l);
     76        }
     77    }
    7878
    79         /**
    80         * Adds a label to the list of label for this tag specification. The label
    81         * is only added if i
    82         *
    83         * @param lable the lalbe to add; must not be null
    84         * @exception IllegalArgumentException thrown, if lable is null
    85         */
    86         public void addLable(LableSpecification lable) throws IllegalArgumentException  {
    87                 if (lable == null)
    88                         throw new IllegalArgumentException("argument 'lable' must not be null");
    89                 if (!this.lables.contains(lable)) {
    90                         this.lables.add(lable);
    91                 }
    92         }
     79    /**
     80    * Adds a label to the list of label for this tag specification. The label
     81    * is only added if i
     82    *
     83    * @param lable the lalbe to add; must not be null
     84    * @exception IllegalArgumentException thrown, if lable is null
     85    */
     86    public void addLable(LableSpecification lable) throws IllegalArgumentException  {
     87        if (lable == null)
     88            throw new IllegalArgumentException("argument 'lable' must not be null");
     89        if (!this.lables.contains(lable)) {
     90            this.lables.add(lable);
     91        }
     92    }
    9393
    94         public boolean isApplicable(AutoCompletionContext context) {
    95                 boolean ret = false;
    96                 if (context.isSelectionEmpty()) {
    97                         ret = true;
    98                 } else {
    99                         ret = ret || (applicableToNode && context.isSelectionIncludesNodes());
    100                         ret = ret || (applicableToWay && context.isSelectionIncludesWays());
    101                         ret = ret || (applicableToRelation && context.isSelectionIncludesRelations());
    102                 }
    103                 return ret;
    104         }
     94    public boolean isApplicable(AutoCompletionContext context) {
     95        boolean ret = false;
     96        if (context.isSelectionEmpty()) {
     97            ret = true;
     98        } else {
     99            ret = ret || (applicableToNode && context.isSelectionIncludesNodes());
     100            ret = ret || (applicableToWay && context.isSelectionIncludesWays());
     101            ret = ret || (applicableToRelation && context.isSelectionIncludesRelations());
     102        }
     103        return ret;
     104    }
    105105
    106         /* --------------------------------------------------------------------------- */
    107         /* setters/getters                                                             */
    108         /* --------------------------------------------------------------------------- */
    109         public String getKey() {
    110                 return key;
    111         }
    112         public void setKey(String key) {
    113                 this.key = key;
    114         }
    115         public String getType() {
    116                 return type;
    117         }
    118         public void setType(String type) {
    119                 this.type = type;
    120         }
    121         public boolean isApplicableToNode() {
    122                 return applicableToNode;
    123         }
    124         public void setApplicableToNode(boolean applicableToNode) {
    125                 this.applicableToNode = applicableToNode;
    126         }
    127         public boolean isApplicableToWay() {
    128                 return applicableToWay;
    129         }
    130         public void setApplicableToWay(boolean applicableToWay) {
    131                 this.applicableToWay = applicableToWay;
    132         }
    133         public boolean isApplicableToRelation() {
    134                 return applicableToRelation;
    135         }
    136         public void setApplicableToRelation(boolean applicableToRelation) {
    137                 this.applicableToRelation = applicableToRelation;
    138         }
     106    /* --------------------------------------------------------------------------- */
     107    /* setters/getters                                                             */
     108    /* --------------------------------------------------------------------------- */
     109    public String getKey() {
     110        return key;
     111    }
     112    public void setKey(String key) {
     113        this.key = key;
     114    }
     115    public String getType() {
     116        return type;
     117    }
     118    public void setType(String type) {
     119        this.type = type;
     120    }
     121    public boolean isApplicableToNode() {
     122        return applicableToNode;
     123    }
     124    public void setApplicableToNode(boolean applicableToNode) {
     125        this.applicableToNode = applicableToNode;
     126    }
     127    public boolean isApplicableToWay() {
     128        return applicableToWay;
     129    }
     130    public void setApplicableToWay(boolean applicableToWay) {
     131        this.applicableToWay = applicableToWay;
     132    }
     133    public boolean isApplicableToRelation() {
     134        return applicableToRelation;
     135    }
     136    public void setApplicableToRelation(boolean applicableToRelation) {
     137        this.applicableToRelation = applicableToRelation;
     138    }
    139139}
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/tagspec/TagSpecifications.java

    r20058 r23189  
    3535public class TagSpecifications {
    3636
    37         final static public String ATTR_KEY = "key";
    38         final static public String ATTR_TYPE = "type";
    39         final static public String ATTR_FOR_NODE = "for-node";
    40         final static public String ATTR_FOR_WAY = "for-way";
    41         final static public String ATTR_FOR_RELATION = "for-relation";
    42         final static public String ATTR_VALUE = "value";
    43 
    44         final static public String ELEM_ROOT = "osm-tag-definitions";
    45         final static public String ELEM_TAG = "tag";
    46         final static public String ELEM_LABEL = "label";
    47 
    48         final static public String DTD = "osm-tag-definitions.dtd";
    49 
    50 
    51         /** the default name of the resource file with the  tag specifications */
    52         static public final String RES_NAME_TAG_SPECIFICATIONS = "/resources/osm-tag-definitions.xml";
    53 
    54         /** the logger object */
    55         private static Logger logger = Logger.getLogger(TagSpecification.class.getName());
    56 
    57         /** list of tag specifications managed list */
    58         private ArrayList<TagSpecification> tagSpecifications = null;
    59 
    60         private static TagSpecifications instance = null;
    61 
    62         /**
    63         * loads the the tag specifications from the resource file given by
    64         * {@link #RES_NAME_TAG_SPECIFICATIONS}.
    65         *
    66         * @return the list of {@link TagSpecification}s
    67         * @throws Exception thrown, if an exception occurs
    68         */
    69         static public void loadFromResources() throws Exception  {
    70                 InputStream in = TagSpecifications.class.getResourceAsStream(RES_NAME_TAG_SPECIFICATIONS);
    71                 if (in == null) {
    72                         logger.log(Level.SEVERE, "failed to create input stream for resource '" + RES_NAME_TAG_SPECIFICATIONS + "'");
    73                 }
    74                 BufferedReader reader = new BufferedReader(new InputStreamReader(in));
    75                 TagSpecifications spec = new TagSpecifications();
    76                 spec.load(reader);
    77                 reader.close();
    78                 instance = spec;
    79 
    80         }
    81 
    82         static public TagSpecifications getInstance() throws Exception {
    83                 if (instance == null) {
    84                         loadFromResources();
    85                 }
    86                 return instance;
    87         }
    88 
    89         /**
    90         * constructor
    91         */
    92         public TagSpecifications() {
    93                 tagSpecifications = new ArrayList<TagSpecification>();
    94         }
    95 
    96 
    97         /**
    98         * loads the tag specifications from a specific reader
    99         *
    100         * @param in  the reader to read from
    101         * @throws Exception thrown, if an exception occurs
    102         */
    103         public void load(Reader in) throws Exception {
    104                 XMLReader parser;
    105 
    106                 try {
    107                         parser = XMLReaderFactory.createXMLReader();
    108                         Handler handler = new Handler();
    109                         parser.setContentHandler(handler);
    110                         parser.setErrorHandler(handler);
    111                         parser.setEntityResolver(new ResourceEntityResolver());
    112                         parser.setFeature( "http://xml.org/sax/features/validation", true);
    113                         parser.setFeature("http://xml.org/sax/features/namespaces", true);
    114                         parser.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
    115                         parser.parse(new InputSource(in));
    116 
    117                 } catch (Exception e) {
    118                         logger.log(Level.SEVERE, "failed to load tag specificatoin file", e);
    119                         throw e;
    120                 } finally {
    121                         parser = null;
    122                 }
    123         }
    124 
    125         public List<AutoCompletionListItem> getKeysForAutoCompletion(AutoCompletionContext context) {
    126                 ArrayList<AutoCompletionListItem> keys = new ArrayList<AutoCompletionListItem>();
    127                 for (TagSpecification spec : tagSpecifications) {
    128                         if (!spec.isApplicable(context)) {
    129                                 continue;
    130                         }
    131                         AutoCompletionListItem item = new AutoCompletionListItem();
    132                         item.setValue(spec.getKey());
    133                         item.setPriority(AutoCompletionItemPritority.IS_IN_STANDARD);
    134                         keys.add(item);
    135                 }
    136                 return keys;
    137         }
    138 
    139         public List<AutoCompletionListItem> getLabelsForAutoCompletion(String forKey, AutoCompletionContext context) {
    140                 ArrayList<AutoCompletionListItem> items = new ArrayList<AutoCompletionListItem>();
    141                 for (TagSpecification spec : tagSpecifications) {
    142                         if (spec.getKey().equals(forKey)) {
    143                                 List<LableSpecification> lables = spec.getLables();
    144                                 for (LableSpecification l : lables) {
    145                                         if (!l.isApplicable(context)) {
    146                                                 continue;
    147                                         }
    148                                         AutoCompletionListItem item = new AutoCompletionListItem();
    149                                         item.setValue(l.getValue());
    150                                         item.setPriority(AutoCompletionItemPritority.IS_IN_STANDARD);
    151                                         items.add(item);
    152                                 }
    153                         }
    154                 }
    155                 return items;
    156         }
    157        
    158         /**
    159         * replies a list of {@see KeyValuePair}s for all {@see TagSpecification}s and
    160         * {@see LableSpecification}s.
    161         *
    162         * @return the list
    163         */
    164         public ArrayList<KeyValuePair> asList() {
    165                 ArrayList<KeyValuePair> entries = new ArrayList<KeyValuePair>();
    166 
    167                 for (TagSpecification s : tagSpecifications) {
    168                         for (LableSpecification l : s.getLables()) {
    169                                 entries.add(new KeyValuePair(s.getKey(), l.getValue()));
    170                         }
    171                 }
    172                 return entries;
    173         }
    174 
    175 
    176 
    177         /**
    178         * The SAX handler for reading XML files with tag specifications
    179         *
    180         * @author gubaer
    181         *
    182         */
    183         class Handler extends DefaultHandler {
    184 
    185                 /**  the current tag specification. Not null, while parsing the content
    186                 * between &lt;tag&gt; ... &lt;/tag&gt;
    187                 */
    188                 private TagSpecification currentTagSpecification  = null;
    189 
    190 
    191                 @Override
    192                 public void endDocument() throws SAXException {
    193                         logger.log(Level.FINE,"END");
    194                 }
    195 
    196 
    197 
    198                 @Override
    199                 public void error(SAXParseException e) throws SAXException {
    200                         logger.log(Level.SEVERE, "XML parsing error", e);
    201                 }
    202 
    203                 @Override
    204                 public void fatalError(SAXParseException e) throws SAXException {
    205                         logger.log(Level.SEVERE, "XML parsing error", e);
    206                 }
    207 
    208                 @Override
    209                 public void startDocument() throws SAXException {
    210                         logger.log(Level.FINE,"START");
    211                 }
    212 
    213 
    214                 /**
    215                 * parses a string value consisting of 'yes' or 'no' (exactly, case
    216                 * sensitive)
    217                 *
    218                 * @param value the string value
    219                 * @return true, if value is <code>yes</code>; false, if value is <code>no</code>
    220                 * @throws SAXException thrown, if value is neither <code>yes</code> nor <code>no</code>
    221                 */
    222                 protected boolean parseYesNo(String value) throws SAXException {
    223                         if ("yes".equals(value))
    224                                 return true;
    225                         else if ("no".equals(value))
    226                                 return false;
    227                         else
    228                                 throw new SAXException("expected 'yes' or 'no' as attribute value, got '" + value + "'");
    229                 }
    230 
    231                 /**
    232                 * handles a start element with name <code>osm-tag-definitions</code>
    233                 *
    234                 * @param atts  the XML attributes
    235                 * @throws SAXException
    236                 */
    237                 protected void startElementOsmTagDefinitions(Attributes atts) throws SAXException {
    238                         tagSpecifications = new ArrayList<TagSpecification>();
    239                 }
    240 
    241                 /**
    242                 * handles an end element with name <code>osm-tag-specifications</code>
    243                 *
    244                 * @throws SAXException
    245                 */
    246                 protected void endElementOsmTagDefinitions() throws SAXException {
    247                         // do nothing
    248                 }
    249 
    250                 /**
    251                 * handles a start element with name <code>tag</code>
    252                 *
    253                 * @param atts the XML attributes of the element
    254                 * @throws SAXException
    255                 */
    256                 protected void startElementTag(Attributes atts) throws SAXException {
    257                         currentTagSpecification = new TagSpecification();
    258                         for (int i=0; i< atts.getLength(); i++) {
    259                                 String name = atts.getQName(i);
    260                                 String value = atts.getValue(i);
    261 
    262                                 if (ATTR_KEY.equals(name)) {
    263                                         currentTagSpecification.setKey(value);
    264                                 } else if (ATTR_TYPE.equals(name)) {
    265                                         currentTagSpecification.setType(value);
    266                                 } else if (ATTR_FOR_NODE.equals(name)) {
    267                                         currentTagSpecification.setApplicableToNode(parseYesNo(value));
    268                                 } else if (ATTR_FOR_WAY.equals(name)) {
    269                                         currentTagSpecification.setApplicableToWay(parseYesNo(value));
    270                                 } else if (ATTR_FOR_RELATION.equals(name)) {
    271                                         currentTagSpecification.setApplicableToRelation(parseYesNo(value));
    272                                 } else
    273                                         throw new SAXException("unknown attribut '" + name + "' on element 'tag'");
    274                         }
    275                 }
    276 
    277 
    278                 /**
    279                 * handles an end element with name <code>tag</code>
    280                 * @throws SAXException
    281                 */
    282                 protected void endElementTag() throws SAXException {
    283                         tagSpecifications.add(currentTagSpecification);
    284                         currentTagSpecification = null;
    285 
    286                 }
    287 
    288                 /**
    289                 * handles a start element with name <code>label</code>
    290                 *
    291                 * @param atts the XML attributes
    292                 * @throws SAXException
    293                 */
    294                 protected void startElementLabel(Attributes atts) throws SAXException {
    295                         LableSpecification ls = new LableSpecification();
    296                         for (int i=0; i< atts.getLength(); i++) {
    297                                 String name = atts.getQName(i);
    298                                 String value = atts.getValue(i);
    299 
    300                                 if (ATTR_VALUE.equals(name)) {
    301                                         ls.setValue(value);
    302                                 } else if (ATTR_FOR_NODE.equals(name)) {
    303                                         ls.setApplicableToNode(parseYesNo(value));
    304                                 } else if (ATTR_FOR_WAY.equals(name)) {
    305                                         ls.setApplicableToWay(parseYesNo(value));
    306                                 } else if (ATTR_FOR_RELATION.equals(name)) {
    307                                         ls.setApplicableToRelation(parseYesNo(value));
    308                                 } else
    309                                         throw new SAXException("unknown attribut '" + name + "' on element 'lable'");
    310                         }
    311                         currentTagSpecification.addLable(ls);
    312                 }
    313 
    314                 /**
    315                 * handles an end element with name <code>label</code>
    316                 *
    317                 * @throws SAXException
    318                 */
    319                 protected void endElementLabel() throws SAXException {
    320                         // do nothing
    321                 }
    322 
    323                 @Override
    324                 public void startElement(String namespaceURI, String localName, String qName,
    325                                 Attributes atts) throws SAXException {
    326                         if (ELEM_ROOT.equals(qName)) {
    327                                 startElementOsmTagDefinitions(atts);
    328                         } else if (ELEM_TAG.equals(qName)) {
    329                                 startElementTag(atts);
    330                         } else if (ELEM_LABEL.equals(qName)) {
    331                                 startElementLabel(atts);
    332                         } else
    333                                 throw new SAXException("unknown element '" + qName + "'");
    334                 }
    335 
    336                 @Override
    337                 public void endElement(String namespaceURI, String localName, String qName)
    338                 throws SAXException {
    339                         if (ELEM_ROOT.equals(qName)) {
    340                                 endElementOsmTagDefinitions();
    341                         } else if (ELEM_TAG.equals(qName)) {
    342                                 endElementTag();
    343                         } else if (ELEM_LABEL.equals(qName)) {
    344                                 endElementLabel();
    345                         } else
    346                                 throw new SAXException("unknown element '" + qName + "'");
    347                 }
    348 
    349                 @Override
    350                 public void warning(SAXParseException e) throws SAXException {
    351                         // TODO Auto-generated method stub
    352                         logger.log(Level.WARNING, "XML parsing warning", e);
    353                 }
    354         }
    355 
    356         /**
    357         *
    358         *
    359         */
    360         class ResourceEntityResolver implements EntityResolver {
    361 
    362                 public InputSource resolveEntity(String publicId, String systemId)
    363                 throws SAXException, IOException {
    364                         if (systemId != null && systemId.endsWith(DTD))
    365                                 return new InputSource(
    366                                                 TagSpecifications.class.getResourceAsStream(DTD)
    367                                 );
    368                         else
    369                                 throw new SAXException("couldn't load external DTD '" + systemId + "'");
    370                 }
    371 
    372         }
    373 
    374         static public void main(String args[]) throws Exception{
    375                 TagSpecifications.loadFromResources();
    376         }
     37    final static public String ATTR_KEY = "key";
     38    final static public String ATTR_TYPE = "type";
     39    final static public String ATTR_FOR_NODE = "for-node";
     40    final static public String ATTR_FOR_WAY = "for-way";
     41    final static public String ATTR_FOR_RELATION = "for-relation";
     42    final static public String ATTR_VALUE = "value";
     43
     44    final static public String ELEM_ROOT = "osm-tag-definitions";
     45    final static public String ELEM_TAG = "tag";
     46    final static public String ELEM_LABEL = "label";
     47
     48    final static public String DTD = "osm-tag-definitions.dtd";
     49
     50
     51    /** the default name of the resource file with the  tag specifications */
     52    static public final String RES_NAME_TAG_SPECIFICATIONS = "/resources/osm-tag-definitions.xml";
     53
     54    /** the logger object */
     55    private static Logger logger = Logger.getLogger(TagSpecification.class.getName());
     56
     57    /** list of tag specifications managed list */
     58    private ArrayList<TagSpecification> tagSpecifications = null;
     59
     60    private static TagSpecifications instance = null;
     61
     62    /**
     63    * loads the the tag specifications from the resource file given by
     64    * {@link #RES_NAME_TAG_SPECIFICATIONS}.
     65    *
     66    * @return the list of {@link TagSpecification}s
     67    * @throws Exception thrown, if an exception occurs
     68    */
     69    static public void loadFromResources() throws Exception  {
     70        InputStream in = TagSpecifications.class.getResourceAsStream(RES_NAME_TAG_SPECIFICATIONS);
     71        if (in == null) {
     72            logger.log(Level.SEVERE, "failed to create input stream for resource '" + RES_NAME_TAG_SPECIFICATIONS + "'");
     73        }
     74        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
     75        TagSpecifications spec = new TagSpecifications();
     76        spec.load(reader);
     77        reader.close();
     78        instance = spec;
     79
     80    }
     81
     82    static public TagSpecifications getInstance() throws Exception {
     83        if (instance == null) {
     84            loadFromResources();
     85        }
     86        return instance;
     87    }
     88
     89    /**
     90    * constructor
     91    */
     92    public TagSpecifications() {
     93        tagSpecifications = new ArrayList<TagSpecification>();
     94    }
     95
     96
     97    /**
     98    * loads the tag specifications from a specific reader
     99    *
     100    * @param in  the reader to read from
     101    * @throws Exception thrown, if an exception occurs
     102    */
     103    public void load(Reader in) throws Exception {
     104        XMLReader parser;
     105
     106        try {
     107            parser = XMLReaderFactory.createXMLReader();
     108            Handler handler = new Handler();
     109            parser.setContentHandler(handler);
     110            parser.setErrorHandler(handler);
     111            parser.setEntityResolver(new ResourceEntityResolver());
     112            parser.setFeature( "http://xml.org/sax/features/validation", true);
     113            parser.setFeature("http://xml.org/sax/features/namespaces", true);
     114            parser.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
     115            parser.parse(new InputSource(in));
     116
     117        } catch (Exception e) {
     118            logger.log(Level.SEVERE, "failed to load tag specificatoin file", e);
     119            throw e;
     120        } finally {
     121            parser = null;
     122        }
     123    }
     124
     125    public List<AutoCompletionListItem> getKeysForAutoCompletion(AutoCompletionContext context) {
     126        ArrayList<AutoCompletionListItem> keys = new ArrayList<AutoCompletionListItem>();
     127        for (TagSpecification spec : tagSpecifications) {
     128            if (!spec.isApplicable(context)) {
     129                continue;
     130            }
     131            AutoCompletionListItem item = new AutoCompletionListItem();
     132            item.setValue(spec.getKey());
     133            item.setPriority(AutoCompletionItemPritority.IS_IN_STANDARD);
     134            keys.add(item);
     135        }
     136        return keys;
     137    }
     138
     139    public List<AutoCompletionListItem> getLabelsForAutoCompletion(String forKey, AutoCompletionContext context) {
     140        ArrayList<AutoCompletionListItem> items = new ArrayList<AutoCompletionListItem>();
     141        for (TagSpecification spec : tagSpecifications) {
     142            if (spec.getKey().equals(forKey)) {
     143                List<LableSpecification> lables = spec.getLables();
     144                for (LableSpecification l : lables) {
     145                    if (!l.isApplicable(context)) {
     146                        continue;
     147                    }
     148                    AutoCompletionListItem item = new AutoCompletionListItem();
     149                    item.setValue(l.getValue());
     150                    item.setPriority(AutoCompletionItemPritority.IS_IN_STANDARD);
     151                    items.add(item);
     152                }
     153            }
     154        }
     155        return items;
     156    }
     157   
     158    /**
     159    * replies a list of {@see KeyValuePair}s for all {@see TagSpecification}s and
     160    * {@see LableSpecification}s.
     161    *
     162    * @return the list
     163    */
     164    public ArrayList<KeyValuePair> asList() {
     165        ArrayList<KeyValuePair> entries = new ArrayList<KeyValuePair>();
     166
     167        for (TagSpecification s : tagSpecifications) {
     168            for (LableSpecification l : s.getLables()) {
     169                entries.add(new KeyValuePair(s.getKey(), l.getValue()));
     170            }
     171        }
     172        return entries;
     173    }
     174
     175
     176
     177    /**
     178    * The SAX handler for reading XML files with tag specifications
     179    *
     180    * @author gubaer
     181    *
     182    */
     183    class Handler extends DefaultHandler {
     184
     185        /**  the current tag specification. Not null, while parsing the content
     186        * between &lt;tag&gt; ... &lt;/tag&gt;
     187        */
     188        private TagSpecification currentTagSpecification  = null;
     189
     190
     191        @Override
     192        public void endDocument() throws SAXException {
     193            logger.log(Level.FINE,"END");
     194        }
     195
     196
     197
     198        @Override
     199        public void error(SAXParseException e) throws SAXException {
     200            logger.log(Level.SEVERE, "XML parsing error", e);
     201        }
     202
     203        @Override
     204        public void fatalError(SAXParseException e) throws SAXException {
     205            logger.log(Level.SEVERE, "XML parsing error", e);
     206        }
     207
     208        @Override
     209        public void startDocument() throws SAXException {
     210            logger.log(Level.FINE,"START");
     211        }
     212
     213
     214        /**
     215        * parses a string value consisting of 'yes' or 'no' (exactly, case
     216        * sensitive)
     217        *
     218        * @param value the string value
     219        * @return true, if value is <code>yes</code>; false, if value is <code>no</code>
     220        * @throws SAXException thrown, if value is neither <code>yes</code> nor <code>no</code>
     221        */
     222        protected boolean parseYesNo(String value) throws SAXException {
     223            if ("yes".equals(value))
     224                return true;
     225            else if ("no".equals(value))
     226                return false;
     227            else
     228                throw new SAXException("expected 'yes' or 'no' as attribute value, got '" + value + "'");
     229        }
     230
     231        /**
     232        * handles a start element with name <code>osm-tag-definitions</code>
     233        *
     234        * @param atts  the XML attributes
     235        * @throws SAXException
     236        */
     237        protected void startElementOsmTagDefinitions(Attributes atts) throws SAXException {
     238            tagSpecifications = new ArrayList<TagSpecification>();
     239        }
     240
     241        /**
     242        * handles an end element with name <code>osm-tag-specifications</code>
     243        *
     244        * @throws SAXException
     245        */
     246        protected void endElementOsmTagDefinitions() throws SAXException {
     247            // do nothing
     248        }
     249
     250        /**
     251        * handles a start element with name <code>tag</code>
     252        *
     253        * @param atts the XML attributes of the element
     254        * @throws SAXException
     255        */
     256        protected void startElementTag(Attributes atts) throws SAXException {
     257            currentTagSpecification = new TagSpecification();
     258            for (int i=0; i< atts.getLength(); i++) {
     259                String name = atts.getQName(i);
     260                String value = atts.getValue(i);
     261
     262                if (ATTR_KEY.equals(name)) {
     263                    currentTagSpecification.setKey(value);
     264                } else if (ATTR_TYPE.equals(name)) {
     265                    currentTagSpecification.setType(value);
     266                } else if (ATTR_FOR_NODE.equals(name)) {
     267                    currentTagSpecification.setApplicableToNode(parseYesNo(value));
     268                } else if (ATTR_FOR_WAY.equals(name)) {
     269                    currentTagSpecification.setApplicableToWay(parseYesNo(value));
     270                } else if (ATTR_FOR_RELATION.equals(name)) {
     271                    currentTagSpecification.setApplicableToRelation(parseYesNo(value));
     272                } else
     273                    throw new SAXException("unknown attribut '" + name + "' on element 'tag'");
     274            }
     275        }
     276
     277
     278        /**
     279        * handles an end element with name <code>tag</code>
     280        * @throws SAXException
     281        */
     282        protected void endElementTag() throws SAXException {
     283            tagSpecifications.add(currentTagSpecification);
     284            currentTagSpecification = null;
     285
     286        }
     287
     288        /**
     289        * handles a start element with name <code>label</code>
     290        *
     291        * @param atts the XML attributes
     292        * @throws SAXException
     293        */
     294        protected void startElementLabel(Attributes atts) throws SAXException {
     295            LableSpecification ls = new LableSpecification();
     296            for (int i=0; i< atts.getLength(); i++) {
     297                String name = atts.getQName(i);
     298                String value = atts.getValue(i);
     299
     300                if (ATTR_VALUE.equals(name)) {
     301                    ls.setValue(value);
     302                } else if (ATTR_FOR_NODE.equals(name)) {
     303                    ls.setApplicableToNode(parseYesNo(value));
     304                } else if (ATTR_FOR_WAY.equals(name)) {
     305                    ls.setApplicableToWay(parseYesNo(value));
     306                } else if (ATTR_FOR_RELATION.equals(name)) {
     307                    ls.setApplicableToRelation(parseYesNo(value));
     308                } else
     309                    throw new SAXException("unknown attribut '" + name + "' on element 'lable'");
     310            }
     311            currentTagSpecification.addLable(ls);
     312        }
     313
     314        /**
     315        * handles an end element with name <code>label</code>
     316        *
     317        * @throws SAXException
     318        */
     319        protected void endElementLabel() throws SAXException {
     320            // do nothing
     321        }
     322
     323        @Override
     324        public void startElement(String namespaceURI, String localName, String qName,
     325                Attributes atts) throws SAXException {
     326            if (ELEM_ROOT.equals(qName)) {
     327                startElementOsmTagDefinitions(atts);
     328            } else if (ELEM_TAG.equals(qName)) {
     329                startElementTag(atts);
     330            } else if (ELEM_LABEL.equals(qName)) {
     331                startElementLabel(atts);
     332            } else
     333                throw new SAXException("unknown element '" + qName + "'");
     334        }
     335
     336        @Override
     337        public void endElement(String namespaceURI, String localName, String qName)
     338        throws SAXException {
     339            if (ELEM_ROOT.equals(qName)) {
     340                endElementOsmTagDefinitions();
     341            } else if (ELEM_TAG.equals(qName)) {
     342                endElementTag();
     343            } else if (ELEM_LABEL.equals(qName)) {
     344                endElementLabel();
     345            } else
     346                throw new SAXException("unknown element '" + qName + "'");
     347        }
     348
     349        @Override
     350        public void warning(SAXParseException e) throws SAXException {
     351            // TODO Auto-generated method stub
     352            logger.log(Level.WARNING, "XML parsing warning", e);
     353        }
     354    }
     355
     356    /**
     357    *
     358    *
     359    */
     360    class ResourceEntityResolver implements EntityResolver {
     361
     362        public InputSource resolveEntity(String publicId, String systemId)
     363        throws SAXException, IOException {
     364            if (systemId != null && systemId.endsWith(DTD))
     365                return new InputSource(
     366                        TagSpecifications.class.getResourceAsStream(DTD)
     367                );
     368            else
     369                throw new SAXException("couldn't load external DTD '" + systemId + "'");
     370        }
     371
     372    }
     373
     374    static public void main(String args[]) throws Exception{
     375        TagSpecifications.loadFromResources();
     376    }
    377377}
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/tagspec/ui/ITagSelectorListener.java

    r20058 r23189  
    44
    55public interface ITagSelectorListener {
    6         public void itemSelected(KeyValuePair pair);
     6    public void itemSelected(KeyValuePair pair);
    77}
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/tagspec/ui/KeyValueCellRenderer.java

    r20058 r23189  
    1212public class KeyValueCellRenderer extends JLabel implements TableCellRenderer  {
    1313
    14         private static final Logger logger = Logger.getLogger(KeyValueCellRenderer.class.getName());
     14    private static final Logger logger = Logger.getLogger(KeyValueCellRenderer.class.getName());
    1515
    16         protected void init() {
    17                 setFont(new Font("Courier",Font.PLAIN,getFont().getSize()));
    18                 setOpaque(true);
    19         }
     16    protected void init() {
     17        setFont(new Font("Courier",Font.PLAIN,getFont().getSize()));
     18        setOpaque(true);
     19    }
    2020
    21         public KeyValueCellRenderer() {
    22                 init();
    23         }
     21    public KeyValueCellRenderer() {
     22        init();
     23    }
    2424
    25         public Component getTableCellRendererComponent(JTable table, Object value,
    26                         boolean isSelected, boolean hasFocus, int rowIndex, int colIndex) {
     25    public Component getTableCellRendererComponent(JTable table, Object value,
     26            boolean isSelected, boolean hasFocus, int rowIndex, int colIndex) {
    2727
    28                 if (isSelected) {
    29                         setBackground(UIManager.getColor("Table.selectionBackground"));
    30                         setForeground(UIManager.getColor("Table.selectionForeground"));
    31                 } else  {
    32                         setBackground(UIManager.getColor("Table.background"));
    33                         setForeground(UIManager.getColor("Table.foreground"));
    34                 }
    35                 setText((String)value);
    36                 setIcon(null);
    37                 return this;
    38         }
     28        if (isSelected) {
     29            setBackground(UIManager.getColor("Table.selectionBackground"));
     30            setForeground(UIManager.getColor("Table.selectionForeground"));
     31        } else  {
     32            setBackground(UIManager.getColor("Table.background"));
     33            setForeground(UIManager.getColor("Table.foreground"));
     34        }
     35        setText((String)value);
     36        setIcon(null);
     37        return this;
     38    }
    3939}
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/tagspec/ui/TabularTagSelector.java

    r20058 r23189  
    3333public class TabularTagSelector extends JPanel {
    3434
    35         private TagsTable tagsTable;
    36         private JTextField tfFilter;
    37         private JButton btnApply;
    38         private JScrollPane scrollPane;
    39         private final ArrayList<ITagSelectorListener> listeners = new ArrayList<ITagSelectorListener>();
    40 
    41         protected JPanel buildFilterPanel() {
    42                 JPanel pnl = new JPanel();
    43                 JLabel lbl = new JLabel(tr("Search: "));
    44                 pnl.setLayout(new FlowLayout(FlowLayout.LEFT));
    45                 tfFilter = new JTextField(20);
    46                 pnl.add(lbl);
    47                 pnl.add(tfFilter,BorderLayout.CENTER);
    48                 JButton btn = new JButton(tr("Filter"));
    49                 pnl.add(btn);
    50                 btn.addActionListener(
    51                                 new ActionListener() {
    52                                         public void actionPerformed(ActionEvent e) {
    53                                                 filter(tfFilter.getText());
    54                                         }
    55 
    56                                 }
    57                 );
    58                 btn = new JButton(tr("Clear"));
    59                 pnl.add(btn);
    60                 btn.addActionListener(
    61                                 new ActionListener() {
    62                                         public void actionPerformed(ActionEvent e) {
    63                                                 tfFilter.setText("");
    64                                                 tfFilter.requestFocus();
    65                                         }
    66                                 }
    67                 );
    68                 return pnl;
    69         }
    70 
    71         protected JScrollPane buildPresetGrid() {
    72 
    73                 tagsTable = new TagsTable(new TagsTableModel(),new TagsTableColumnModel());
    74                 getModel().initFromTagSpecifications();
    75 
    76                 scrollPane = new JScrollPane(tagsTable);
    77 
    78                 scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    79                 scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
    80 
    81                 // this adapters ensures that the width of the tag table columns is adjusted
    82                 // to the width of the scroll pane viewport. Also tried to overwrite
    83                 // getPreferredViewportSize() in JTable, but did not work.
    84                 //
    85                 scrollPane.addComponentListener(
    86                                 new ComponentAdapter() {
    87                                         @Override public void componentResized(ComponentEvent e) {
    88                                                 super.componentResized(e);
    89                                                 Dimension d = scrollPane.getViewport().getExtentSize();
    90                                                 tagsTable.adjustColumnWidth(d.width);
    91                                         }
    92                                 }
    93                 );
    94 
    95                 // add the double click listener
    96                 //
    97                 tagsTable.addMouseListener(new DoubleClickAdapter());
    98 
    99                 // replace Enter action. apply the current preset on enter
    100                 //
    101                 tagsTable.unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0));
    102                 ActionListener enterAction = new ActionListener() {
    103                         public void actionPerformed(ActionEvent e) {
    104                                 int rowNum = tagsTable.getSelectedRow();
    105                                 if (rowNum >= 0) {
    106                                         KeyValuePair item = getModel().getVisibleItem(rowNum);
    107                                         fireItemSelected(item);
    108                                 }
    109                         }
    110                 };
    111 
    112                 tagsTable.registerKeyboardAction(
    113                                 enterAction,
    114                                 "Enter",
    115                                 KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0),
    116                                 JComponent.WHEN_FOCUSED
    117                 );
    118 
    119                 return scrollPane;
    120         }
    121 
    122         protected JPanel buildControlButtonPanel() {
    123                 JPanel pnl = new JPanel();
    124                 pnl.setLayout(new FlowLayout(FlowLayout.LEFT));
    125                 btnApply = new JButton("Apply");
    126                 pnl.add(btnApply);
    127                 btnApply.addActionListener(
    128                                 new ActionListener() {
    129                                         public void actionPerformed(ActionEvent arg0) {
    130                                                 int row = tagsTable.getSelectedRow();
    131                                                 if (row >=0) {
    132                                                         KeyValuePair item = getModel().getVisibleItem(row);
    133                                                         fireItemSelected(item);
    134                                                 }
    135                                         }
    136                                 }
    137                 );
    138                 return pnl;
    139         }
    140 
    141         protected void build() {
    142                 setLayout(new BorderLayout());
    143                 add(buildFilterPanel(), BorderLayout.NORTH);
    144                 add(buildPresetGrid(), BorderLayout.CENTER);
    145                 add(buildControlButtonPanel(), BorderLayout.SOUTH);
    146 
    147                 // wire the text field for filter expressions to the prests
    148                 // table
    149                 //
    150                 tfFilter.getDocument().addDocumentListener(
    151                                 new DocumentListener() {
    152                                         public void changedUpdate(DocumentEvent arg0) {
    153                                                 onUpdate();
    154                                         }
    155 
    156                                         public void insertUpdate(DocumentEvent arg0) {
    157                                                 onUpdate();
    158                                         }
    159 
    160                                         public void removeUpdate(DocumentEvent arg0) {
    161                                                 onUpdate();
    162                                         }
    163 
    164                                         protected void onUpdate() {
    165                                                 filter(tfFilter.getText());
    166                                         }
    167                                 }
    168                 );
    169 
    170                 tfFilter.addActionListener(
    171                                 new ActionListener() {
    172                                         public void actionPerformed(ActionEvent e) {
    173                                                 filter(tfFilter.getText());
    174                                         }
    175                                 }
    176                 );
    177 
    178                 // wire the apply button to the selection model of the preset table
    179                 //
    180                 tagsTable.getSelectionModel().addListSelectionListener(
    181                                 new ListSelectionListener() {
    182                                         public void valueChanged(ListSelectionEvent e) {
    183                                                 btnApply.setEnabled(tagsTable.getSelectedRowCount() != 0);
    184                                         }
    185                                 }
    186                 );
    187 
    188 
    189                 // load the set of presets and bind them to the preset table
    190                 //
    191                 tagsTable.getSelectionModel().clearSelection();
    192                 btnApply.setEnabled(false);
    193 
    194         }
    195 
    196         public TabularTagSelector() {
    197                 build();
    198         }
    199 
    200 
    201         public void filter(String filter) {
    202                 tagsTable.getSelectionModel().clearSelection();
    203                 getModel().filter(filter);
    204 
    205                 tagsTable.scrollRectToVisible(tagsTable.getCellRect(0, 0, false));
    206 
    207                 // we change the number of rows by applying a filter condition. Because
    208                 // the table is embedded in a JScrollPane which again may be embedded in
    209                 // other JScrollPanes or JSplitPanes it seems that we have to recalculate
    210                 // the layout and repaint the component tree. Maybe there is a more efficient way
    211                 // to keep the GUI in sync with the number of rows in table. By trial
    212                 // and error I ended up with the following lines.
    213                 //
    214                 Component c = tagsTable;
    215                 while(c != null) {
    216                         c.doLayout();
    217                         c.repaint();
    218                         c = c.getParent();
    219                 }
    220         }
    221 
    222         protected TagsTableModel getModel() {
    223                 return (TagsTableModel)tagsTable.getModel();
    224         }
    225 
    226 
    227         public void addTagSelectorListener(ITagSelectorListener listener) {
    228                 synchronized(this.listeners) {
    229                         if (listener != null && ! listeners.contains(listener)) {
    230                                 listeners.add(listener);
    231                         }
    232                 }
    233         }
    234 
    235         public void removeTagSelectorListener(ITagSelectorListener listener) {
    236                 synchronized(this.listeners) {
    237                         if (listener != null) {
    238                                 listeners.remove(listener);
    239                         }
    240                 }
    241         }
    242 
    243         protected void fireItemSelected(KeyValuePair pair) {
    244                 synchronized(this.listeners) {
    245                         for(ITagSelectorListener listener: listeners) {
    246                                 listener.itemSelected(pair);
    247                         }
    248                 }
    249         }
    250 
    251         private class DoubleClickAdapter extends MouseAdapter {
    252                 @Override
    253                 public void mouseClicked(MouseEvent e) {
    254                         if (e.getClickCount() == 2) {
    255                                 int rowNum = tagsTable.rowAtPoint(e.getPoint());
    256                                 KeyValuePair pair = getModel().getVisibleItem(rowNum);
    257                                 fireItemSelected(pair);
    258                         }
    259                 }
    260         }
     35    private TagsTable tagsTable;
     36    private JTextField tfFilter;
     37    private JButton btnApply;
     38    private JScrollPane scrollPane;
     39    private final ArrayList<ITagSelectorListener> listeners = new ArrayList<ITagSelectorListener>();
     40
     41    protected JPanel buildFilterPanel() {
     42        JPanel pnl = new JPanel();
     43        JLabel lbl = new JLabel(tr("Search: "));
     44        pnl.setLayout(new FlowLayout(FlowLayout.LEFT));
     45        tfFilter = new JTextField(20);
     46        pnl.add(lbl);
     47        pnl.add(tfFilter,BorderLayout.CENTER);
     48        JButton btn = new JButton(tr("Filter"));
     49        pnl.add(btn);
     50        btn.addActionListener(
     51                new ActionListener() {
     52                    public void actionPerformed(ActionEvent e) {
     53                        filter(tfFilter.getText());
     54                    }
     55
     56                }
     57        );
     58        btn = new JButton(tr("Clear"));
     59        pnl.add(btn);
     60        btn.addActionListener(
     61                new ActionListener() {
     62                    public void actionPerformed(ActionEvent e) {
     63                        tfFilter.setText("");
     64                        tfFilter.requestFocus();
     65                    }
     66                }
     67        );
     68        return pnl;
     69    }
     70
     71    protected JScrollPane buildPresetGrid() {
     72
     73        tagsTable = new TagsTable(new TagsTableModel(),new TagsTableColumnModel());
     74        getModel().initFromTagSpecifications();
     75
     76        scrollPane = new JScrollPane(tagsTable);
     77
     78        scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
     79        scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
     80
     81        // this adapters ensures that the width of the tag table columns is adjusted
     82        // to the width of the scroll pane viewport. Also tried to overwrite
     83        // getPreferredViewportSize() in JTable, but did not work.
     84        //
     85        scrollPane.addComponentListener(
     86                new ComponentAdapter() {
     87                    @Override public void componentResized(ComponentEvent e) {
     88                        super.componentResized(e);
     89                        Dimension d = scrollPane.getViewport().getExtentSize();
     90                        tagsTable.adjustColumnWidth(d.width);
     91                    }
     92                }
     93        );
     94
     95        // add the double click listener
     96        //
     97        tagsTable.addMouseListener(new DoubleClickAdapter());
     98
     99        // replace Enter action. apply the current preset on enter
     100        //
     101        tagsTable.unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0));
     102        ActionListener enterAction = new ActionListener() {
     103            public void actionPerformed(ActionEvent e) {
     104                int rowNum = tagsTable.getSelectedRow();
     105                if (rowNum >= 0) {
     106                    KeyValuePair item = getModel().getVisibleItem(rowNum);
     107                    fireItemSelected(item);
     108                }
     109            }
     110        };
     111
     112        tagsTable.registerKeyboardAction(
     113                enterAction,
     114                "Enter",
     115                KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0),
     116                JComponent.WHEN_FOCUSED
     117        );
     118
     119        return scrollPane;
     120    }
     121
     122    protected JPanel buildControlButtonPanel() {
     123        JPanel pnl = new JPanel();
     124        pnl.setLayout(new FlowLayout(FlowLayout.LEFT));
     125        btnApply = new JButton("Apply");
     126        pnl.add(btnApply);
     127        btnApply.addActionListener(
     128                new ActionListener() {
     129                    public void actionPerformed(ActionEvent arg0) {
     130                        int row = tagsTable.getSelectedRow();
     131                        if (row >=0) {
     132                            KeyValuePair item = getModel().getVisibleItem(row);
     133                            fireItemSelected(item);
     134                        }
     135                    }
     136                }
     137        );
     138        return pnl;
     139    }
     140
     141    protected void build() {
     142        setLayout(new BorderLayout());
     143        add(buildFilterPanel(), BorderLayout.NORTH);
     144        add(buildPresetGrid(), BorderLayout.CENTER);
     145        add(buildControlButtonPanel(), BorderLayout.SOUTH);
     146
     147        // wire the text field for filter expressions to the prests
     148        // table
     149        //
     150        tfFilter.getDocument().addDocumentListener(
     151                new DocumentListener() {
     152                    public void changedUpdate(DocumentEvent arg0) {
     153                        onUpdate();
     154                    }
     155
     156                    public void insertUpdate(DocumentEvent arg0) {
     157                        onUpdate();
     158                    }
     159
     160                    public void removeUpdate(DocumentEvent arg0) {
     161                        onUpdate();
     162                    }
     163
     164                    protected void onUpdate() {
     165                        filter(tfFilter.getText());
     166                    }
     167                }
     168        );
     169
     170        tfFilter.addActionListener(
     171                new ActionListener() {
     172                    public void actionPerformed(ActionEvent e) {
     173                        filter(tfFilter.getText());
     174                    }
     175                }
     176        );
     177
     178        // wire the apply button to the selection model of the preset table
     179        //
     180        tagsTable.getSelectionModel().addListSelectionListener(
     181                new ListSelectionListener() {
     182                    public void valueChanged(ListSelectionEvent e) {
     183                        btnApply.setEnabled(tagsTable.getSelectedRowCount() != 0);
     184                    }
     185                }
     186        );
     187
     188
     189        // load the set of presets and bind them to the preset table
     190        //
     191        tagsTable.getSelectionModel().clearSelection();
     192        btnApply.setEnabled(false);
     193
     194    }
     195
     196    public TabularTagSelector() {
     197        build();
     198    }
     199
     200
     201    public void filter(String filter) {
     202        tagsTable.getSelectionModel().clearSelection();
     203        getModel().filter(filter);
     204
     205        tagsTable.scrollRectToVisible(tagsTable.getCellRect(0, 0, false));
     206
     207        // we change the number of rows by applying a filter condition. Because
     208        // the table is embedded in a JScrollPane which again may be embedded in
     209        // other JScrollPanes or JSplitPanes it seems that we have to recalculate
     210        // the layout and repaint the component tree. Maybe there is a more efficient way
     211        // to keep the GUI in sync with the number of rows in table. By trial
     212        // and error I ended up with the following lines.
     213        //
     214        Component c = tagsTable;
     215        while(c != null) {
     216            c.doLayout();
     217            c.repaint();
     218            c = c.getParent();
     219        }
     220    }
     221
     222    protected TagsTableModel getModel() {
     223        return (TagsTableModel)tagsTable.getModel();
     224    }
     225
     226
     227    public void addTagSelectorListener(ITagSelectorListener listener) {
     228        synchronized(this.listeners) {
     229            if (listener != null && ! listeners.contains(listener)) {
     230                listeners.add(listener);
     231            }
     232        }
     233    }
     234
     235    public void removeTagSelectorListener(ITagSelectorListener listener) {
     236        synchronized(this.listeners) {
     237            if (listener != null) {
     238                listeners.remove(listener);
     239            }
     240        }
     241    }
     242
     243    protected void fireItemSelected(KeyValuePair pair) {
     244        synchronized(this.listeners) {
     245            for(ITagSelectorListener listener: listeners) {
     246                listener.itemSelected(pair);
     247            }
     248        }
     249    }
     250
     251    private class DoubleClickAdapter extends MouseAdapter {
     252        @Override
     253        public void mouseClicked(MouseEvent e) {
     254            if (e.getClickCount() == 2) {
     255                int rowNum = tagsTable.rowAtPoint(e.getPoint());
     256                KeyValuePair pair = getModel().getVisibleItem(rowNum);
     257                fireItemSelected(pair);
     258            }
     259        }
     260    }
    261261}
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/tagspec/ui/TagsTable.java

    r14330 r23189  
    77
    88public class TagsTable extends JTable {
    9         /**
    10         * initialize the table
    11         */
    12         protected void init() {                         
    13                 setAutoResizeMode(JTable.AUTO_RESIZE_OFF);             
    14                 setRowSelectionAllowed(true);
    15                 setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    16         }
    17        
    18         public TagsTable(TableModel model, TableColumnModel columnModel) {
    19                 super(model,columnModel);
    20                 init();
    21         }
    22        
    23         /**
    24         * adjusts the width of the columns for the tag name and the tag value
    25         * to the width of the scroll panes viewport.
    26         *
    27         * Note: {@see #getPreferredScrollableViewportSize()} did not work as expected
    28         *
    29         * @param scrollPaneWidth the width of the scroll panes viewport
    30         */
    31         public void adjustColumnWidth(int scrollPaneWidth) {
    32                 TableColumnModel tcm = getColumnModel();
    33                 int width = scrollPaneWidth;
    34                 width = width / 2;
    35                 if (width > 0) {
    36                         tcm.getColumn(0).setMinWidth(width);
    37                         tcm.getColumn(0).setMaxWidth(width);
    38                         tcm.getColumn(1).setMinWidth(width);
    39                         tcm.getColumn(1).setMaxWidth(width);                   
    40                 }
    41         }
     9    /**
     10    * initialize the table
     11    */
     12    protected void init() {             
     13        setAutoResizeMode(JTable.AUTO_RESIZE_OFF);     
     14        setRowSelectionAllowed(true);
     15        setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
     16    }
     17   
     18    public TagsTable(TableModel model, TableColumnModel columnModel) {
     19        super(model,columnModel);
     20        init();
     21    }
     22   
     23    /**
     24    * adjusts the width of the columns for the tag name and the tag value
     25    * to the width of the scroll panes viewport.
     26    *
     27    * Note: {@see #getPreferredScrollableViewportSize()} did not work as expected
     28    *
     29    * @param scrollPaneWidth the width of the scroll panes viewport
     30    */
     31    public void adjustColumnWidth(int scrollPaneWidth) {
     32        TableColumnModel tcm = getColumnModel();
     33        int width = scrollPaneWidth;
     34        width = width / 2;
     35        if (width > 0) {
     36            tcm.getColumn(0).setMinWidth(width);
     37            tcm.getColumn(0).setMaxWidth(width);
     38            tcm.getColumn(1).setMinWidth(width);
     39            tcm.getColumn(1).setMaxWidth(width);           
     40        }
     41    }
    4242}
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/tagspec/ui/TagsTableColumnModel.java

    r14330 r23189  
    88
    99public class TagsTableColumnModel extends DefaultTableColumnModel {
    10        
    11         protected void createColumns() {
    12                 TableCellRenderer renderer = new KeyValueCellRenderer();
    13                
    14                 TableColumn col = null;
    15                
    16                 // column 0 - Key   
    17                 col = new TableColumn(0);
    18                 col.setHeaderValue(tr("Key"));
    19                 col.setResizable(true);
    20                 col.setCellRenderer(renderer);
    21                 addColumn(col);
    22                
    23                 // column 1 - Value   
    24                 col = new TableColumn(1);
    25                 col.setHeaderValue(tr("Value"));
    26                 col.setResizable(true);
    27                 col.setCellRenderer(renderer);
    28                 addColumn(col);
    29         }
     10   
     11    protected void createColumns() {
     12        TableCellRenderer renderer = new KeyValueCellRenderer();
     13       
     14        TableColumn col = null;
     15       
     16        // column 0 - Key   
     17        col = new TableColumn(0);
     18        col.setHeaderValue(tr("Key"));
     19        col.setResizable(true);
     20        col.setCellRenderer(renderer);
     21        addColumn(col);
     22       
     23        // column 1 - Value   
     24        col = new TableColumn(1);
     25        col.setHeaderValue(tr("Value"));
     26        col.setResizable(true);
     27        col.setCellRenderer(renderer);
     28        addColumn(col);
     29    }
    3030
    31         public TagsTableColumnModel() {
    32                 createColumns();
    33         }
     31    public TagsTableColumnModel() {
     32        createColumns();
     33    }
    3434}
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/tagspec/ui/TagsTableModel.java

    r20058 r23189  
    1515public class TagsTableModel extends AbstractTableModel {
    1616
    17         static private Logger logger = Logger.getLogger(TagsTableModel.class.getName());
     17    static private Logger logger = Logger.getLogger(TagsTableModel.class.getName());
    1818
    19         private ArrayList<KeyValuePair> items = null;
    20         private ArrayList<KeyValuePair> visibleItems = null;
     19    private ArrayList<KeyValuePair> items = null;
     20    private ArrayList<KeyValuePair> visibleItems = null;
    2121
    22         public TagsTableModel() {
    23                 items = new ArrayList<KeyValuePair>();
    24                 visibleItems = new ArrayList<KeyValuePair>();
    25         }
     22    public TagsTableModel() {
     23        items = new ArrayList<KeyValuePair>();
     24        visibleItems = new ArrayList<KeyValuePair>();
     25    }
    2626
    27         protected void sort() {
    28                 Collections.sort(
    29                                 items,
    30                                 new Comparator<KeyValuePair>() {
    31                                         public int compare(KeyValuePair self,
    32                                                         KeyValuePair other) {
    33                                                 int ret =self.getKey().compareToIgnoreCase(other.getKey());
     27    protected void sort() {
     28        Collections.sort(
     29                items,
     30                new Comparator<KeyValuePair>() {
     31                    public int compare(KeyValuePair self,
     32                            KeyValuePair other) {
     33                        int ret =self.getKey().compareToIgnoreCase(other.getKey());
    3434
    35                                                 if (ret == 0)
    36                                                         return self.getValue().compareToIgnoreCase(other.getValue());
    37                                                 else
    38                                                         return ret;
    39                                         }
    40                                 }
    41                 );
    42         }
     35                        if (ret == 0)
     36                            return self.getValue().compareToIgnoreCase(other.getValue());
     37                        else
     38                            return ret;
     39                    }
     40                }
     41        );
     42    }
    4343
    44         protected void clear() {
    45                 items.clear();
    46                 visibleItems.clear();
    47         }
     44    protected void clear() {
     45        items.clear();
     46        visibleItems.clear();
     47    }
    4848
    49         public void initFromTagSpecifications() {
    50                 clear();
    51                 TagSpecifications spec;
     49    public void initFromTagSpecifications() {
     50        clear();
     51        TagSpecifications spec;
    5252
    53                 try {
    54                         spec = TagSpecifications.getInstance();
    55                 } catch(Exception e) {
    56                         logger.log(Level.SEVERE, "failed to init TagTableModel. Exception:" + e);
    57                         return;
    58                 }
     53        try {
     54            spec = TagSpecifications.getInstance();
     55        } catch(Exception e) {
     56            logger.log(Level.SEVERE, "failed to init TagTableModel. Exception:" + e);
     57            return;
     58        }
    5959
    60                 items = spec.asList();
    61                 sort();
    62                 for(KeyValuePair item : items) {
    63                         visibleItems.add(item);
    64                 }
    65         }
     60        items = spec.asList();
     61        sort();
     62        for(KeyValuePair item : items) {
     63            visibleItems.add(item);
     64        }
     65    }
    6666
    67         public int getColumnCount() {
    68                 return 2;
    69         }
     67    public int getColumnCount() {
     68        return 2;
     69    }
    7070
    71         public int getRowCount() {
    72                 return visibleItems.size();
    73         }
     71    public int getRowCount() {
     72        return visibleItems.size();
     73    }
    7474
    75         public Object getValueAt(int row, int col) {
    76                 KeyValuePair pair = visibleItems.get(row);
    77                 switch(col) {
    78                 case 0: return pair.getKey();
    79                 case 1: return pair.getValue();
    80                 default:
    81                         /* should not happen */
    82                         throw new IllegalArgumentException(tr("unexpected column number {0}",col));
    83                 }
    84         }
     75    public Object getValueAt(int row, int col) {
     76        KeyValuePair pair = visibleItems.get(row);
     77        switch(col) {
     78        case 0: return pair.getKey();
     79        case 1: return pair.getValue();
     80        default:
     81            /* should not happen */
     82            throw new IllegalArgumentException(tr("unexpected column number {0}",col));
     83        }
     84    }
    8585
    86         public void filter(String filter) {
    87                 synchronized(this) {
    88                         if (filter == null || filter.trim().equals("")) {
    89                                 visibleItems.clear();
    90                                 for(KeyValuePair pair: items) {
    91                                         visibleItems.add(pair);
    92                                 }
    93                         } else {
    94                                 visibleItems.clear();
    95                                 filter = filter.toLowerCase();
    96                                 for(KeyValuePair pair: items) {
    97                                         if (pair.getKey().toLowerCase().trim().startsWith(filter)
    98                                                         ||  pair.getValue().toLowerCase().trim().startsWith(filter)) {
    99                                                 visibleItems.add(pair);
    100                                         }
    101                                 }
    102                         }
    103                         fireTableDataChanged();
    104                         fireTableStructureChanged();
    105                 }
    106         }
     86    public void filter(String filter) {
     87        synchronized(this) {
     88            if (filter == null || filter.trim().equals("")) {
     89                visibleItems.clear();
     90                for(KeyValuePair pair: items) {
     91                    visibleItems.add(pair);
     92                }
     93            } else {
     94                visibleItems.clear();
     95                filter = filter.toLowerCase();
     96                for(KeyValuePair pair: items) {
     97                    if (pair.getKey().toLowerCase().trim().startsWith(filter)
     98                            ||  pair.getValue().toLowerCase().trim().startsWith(filter)) {
     99                        visibleItems.add(pair);
     100                    }
     101                }
     102            }
     103            fireTableDataChanged();
     104            fireTableStructureChanged();
     105        }
     106    }
    107107
    108         @Override
    109         public boolean isCellEditable(int rowIndex, int columnIndex) {
    110                 return false;
    111         }
     108    @Override
     109    public boolean isCellEditable(int rowIndex, int columnIndex) {
     110        return false;
     111    }
    112112
    113         public KeyValuePair getVisibleItem(int row) {
    114                 if (row < 0 || row >= visibleItems.size())
    115                         throw new IndexOutOfBoundsException("row is out of bound: row=" + row);
    116                 return visibleItems.get(row);
    117         }
     113    public KeyValuePair getVisibleItem(int row) {
     114        if (row < 0 || row >= visibleItems.size())
     115            throw new IndexOutOfBoundsException("row is out of bound: row=" + row);
     116        return visibleItems.get(row);
     117    }
    118118}
  • applications/editors/josm/plugins/tagging-preset-tester/src/org/openstreetmap/josm/plugins/taggingpresettester/TaggingPresetTester.java

    r21797 r23189  
    5555        panel.repaint();
    5656    }
    57    
     57
    5858    public TaggingPresetTester(String[] args) {
    5959        super(tr("Tagging Preset Tester"));
  • applications/editors/josm/plugins/undelete/src/org/openstreetmap/josm/plugins/undelete/Undelete.java

    r22291 r23189  
    5050
    5151    public Undelete(PluginInformation info) {
    52         super(info);
     52        super(info);
    5353        Undelete = MainMenu.add(Main.main.menu.fileMenu, new UndeleteAction());
    5454
    5555    }
    56    
    57    
     56
     57
    5858    private class UndeleteAction extends JosmAction {
    5959        /**
    60                  *
    61                 */
    62                 private static final long serialVersionUID = 1L;
    63                 public UndeleteAction() {
     60         *
     61        */
     62        private static final long serialVersionUID = 1L;
     63        public UndeleteAction() {
    6464        super(tr("Undelete object..."), "undelete", tr("Undelete object by id"), Shortcut.registerShortcut("tools:undelete", tr("File: {0}", tr("Undelete object...")),
    6565        KeyEvent.VK_U, Shortcut.GROUP_EDIT, KeyEvent.SHIFT_DOWN_MASK|KeyEvent.ALT_DOWN_MASK), true);
     
    117117        undelete(layer.isSelected(), cbType.getType(), ids, 0);
    118118      }
    119     }     
    120          
     119    }
     120
    121121    /**
    122122     * Download the given primitive.
     
    128128            Main.main.addLayer(tmpLayer);
    129129        }
    130        
     130
    131131        final DataSet datas = tmpLayer.data;
    132132        final OsmDataLayer layer=tmpLayer;
    133        
     133
    134134        HistoryLoadTask task  = new HistoryLoadTask();
    135135        for (long id: ids)
     
    138138        }
    139139
    140        
    141        
     140
     141
    142142        Main.worker.execute(task);
    143        
     143
    144144        Runnable r = new Runnable() {
    145145            public void run() {
     
    149149
    150150                History h = HistoryDataSet.getInstance().getHistory(id, type);
    151                
     151
    152152                OsmPrimitive primitive;
    153153                HistoryOsmPrimitive hPrimitive1=h.getLatest();
    154154                HistoryOsmPrimitive hPrimitive2;
    155                
     155
    156156                boolean visible=hPrimitive1.isVisible();
    157                
     157
    158158                if (visible)
    159159                {
    160160                  // If the object is not deleted we get the real object
    161161                  DownloadPrimitiveTask download=new DownloadPrimitiveTask(new SimplePrimitiveId(id, type), layer);
    162                   System.out.println(tr("Will get {0}", id));                 
     162                  System.out.println(tr("Will get {0}", id));
    163163                  download.run();
    164                  
    165                  
    166                   System.out.println(tr("Looking for {0}", id));                 
     164
     165
     166                  System.out.println(tr("Looking for {0}", id));
    167167                  primitive=datas.getPrimitiveById(id, type);
    168168                  System.out.println(tr("Found {0}", primitive.getId()));
     
    178178                    // We get all info from the latest version
    179179                    hPrimitive2=hPrimitive1;
    180                    
     180
    181181                    Node node = new Node(id, (int) hPrimitive1.getVersion());
    182182
    183183                    HistoryNode hNode = (HistoryNode) hPrimitive1;
    184184                    node.setCoor(hNode.getCoords());
    185                    
     185
    186186                    primitive=node;
    187187                    if (parent>0)
     
    196196                    hPrimitive2 = h.getByVersion(h.getNumVersions()-1);
    197197
    198                    
    199                    
     198
     199
    200200                    Way way = new Way(id, (int) hPrimitive1.getVersion());
    201                    
     201
    202202                    HistoryWay hWay = (HistoryWay) hPrimitive2;
    203203                    //System.out.println(tr("Primitive {0} version {1}: {2} nodes", hPrimitive2.getId(), hPrimitive2.getVersion(), hWay.getNumNodes()));
    204204                    List<Long> nodeIds = hWay.getNodes();
    205205                    undelete(false, OsmPrimitiveType.NODE, nodeIds, id);
    206                    
     206
    207207                    primitive=way;
    208                    
     208
    209209                  }
    210210                  else
    211                   { 
     211                  {
    212212                      primitive=new Node();
    213213                      hPrimitive1=h.getLatest();
     
    216216
    217217                  User user = User.createOsmUser(hPrimitive1.getUid(), hPrimitive1.getUser());
    218                  
     218
    219219                  primitive.setUser(user);
    220                  
     220
    221221                  primitive.setKeys(hPrimitive2.getTags());
    222                  
     222
    223223                  primitive.put("history", "retrieved using undelete JOSM plugin");
    224                  
     224
    225225                  primitive.setModified(true);
    226                  
    227                   datas.addPrimitive(primitive);               
     226
     227                  datas.addPrimitive(primitive);
    228228                }
    229                  
     229
    230230
    231231                //HistoryBrowserDialogManager.getInstance().show(h);
     
    234234              {
    235235                Way parentWay=(Way)datas.getPrimitiveById(parent, OsmPrimitiveType.WAY);
    236                
     236
    237237                parentWay.setNodes(nodes);
    238238              }
     
    240240        };
    241241        Main.worker.submit(r);
    242        
     242
    243243        //if (downloadReferrers) {
    244244        //    Main.worker.submit(new DownloadReferrersTask(layer, id, type));
    245245        //}
    246     }     
     246    }
    247247}
  • applications/editors/josm/plugins/wayselector/src/org/openstreetmap/josm/plugins/wayselector/WaySelectorPlugin.java

    r20482 r23189  
    5050
    5151        public void actionPerformed(ActionEvent ev) {
    52             DataSet ds = Main.main.getCurrentDataSet();
    53             WaySelection ws = new WaySelection(ds.getSelectedWays());
    54             ws.extend(ds);
     52        DataSet ds = Main.main.getCurrentDataSet();
     53        WaySelection ws = new WaySelection(ds.getSelectedWays());
     54        ws.extend(ds);
    5555        }
    5656
Note: See TracChangeset for help on using the changeset viewer.