Changeset 805 in josm


Ignore:
Timestamp:
2008-08-18T01:27:58+02:00 (16 years ago)
Author:
stoecker
Message:

Added virtual nodes in select mode. Closes #595.

Location:
trunk/src/org/openstreetmap/josm
Files:
1 deleted
7 edited

Legend:

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

    r655 r805  
    1111import java.awt.event.MouseEvent;
    1212import java.util.Collection;
     13import java.util.Collections;
    1314import java.util.LinkedList;
    1415
     
    1718import org.openstreetmap.josm.Main;
    1819import org.openstreetmap.josm.actions.MergeNodesAction;
     20import org.openstreetmap.josm.command.AddCommand;
    1921import org.openstreetmap.josm.command.Command;
     22import org.openstreetmap.josm.command.ChangeCommand;
    2023import org.openstreetmap.josm.command.MoveCommand;
    2124import org.openstreetmap.josm.command.RotateCommand;
     25import org.openstreetmap.josm.command.SequenceCommand;
    2226import org.openstreetmap.josm.data.coor.EastNorth;
    2327import org.openstreetmap.josm.data.osm.Node;
    2428import org.openstreetmap.josm.data.osm.OsmPrimitive;
     29import org.openstreetmap.josm.data.osm.Way;
     30import org.openstreetmap.josm.data.osm.WaySegment;
    2531import org.openstreetmap.josm.data.osm.visitor.AllNodesVisitor;
    2632import org.openstreetmap.josm.gui.MapFrame;
     33import org.openstreetmap.josm.gui.MapView;
    2734import org.openstreetmap.josm.gui.SelectionManager;
    2835import org.openstreetmap.josm.gui.SelectionManager.SelectionEnded;
     
    108115                Main.map.mapView.addMouseListener(this);
    109116                Main.map.mapView.addMouseMotionListener(this);
     117                Main.map.mapView.enableVirtualNodes(Main.pref.getInteger("mappaint.node.virtual-size", 4) != 0);
    110118        }
    111119
     
    115123                Main.map.mapView.removeMouseListener(this);
    116124                Main.map.mapView.removeMouseMotionListener(this);
     125                Main.map.mapView.enableVirtualNodes(false);
    117126        }
    118127
     
    195204        }
    196205
     206        private Collection<OsmPrimitive> getNearestCollectionVirtual(Point p) {
     207                MapView c = Main.map.mapView;
     208                OsmPrimitive osm = c.getNearestNode(p);
     209                if (osm == null)
     210                {
     211                        WaySegment nearestWaySeg = c.getNearestWaySegment(p);
     212                        if(nearestWaySeg != null)
     213                        {
     214                                osm = nearestWaySeg.way;
     215                                if(Main.pref.getInteger("mappaint.node.virtual-size", 4) > 0)
     216                                {
     217                                        Way w = (Way)osm;
     218                                        Point p1 = c.getPoint(w.nodes.get(nearestWaySeg.lowerIndex).eastNorth);
     219                                        Point p2 = c.getPoint(w.nodes.get(nearestWaySeg.lowerIndex+1).eastNorth);
     220                                        int xd = p2.x-p1.x; if(xd < 0) xd = -xd;
     221                                        int yd = p2.y-p1.y; if(yd < 0) yd = -yd;
     222                                        if(xd+yd > Main.pref.getInteger("mappaint.node.virtual-space", 50))
     223                                        {
     224                                                Point pc = new Point((p1.x+p2.x)/2, (p1.y+p2.y)/2);
     225                                                if(p.distanceSq(pc) < Main.map.mapView.snapDistance)
     226                                                {
     227                                                        Collection<Command> cmds = new LinkedList<Command>();
     228                                                        Node n = new Node(Main.map.mapView.getLatLon(pc.x, pc.y));
     229                                                        cmds.add(new AddCommand(n));
     230
     231                                                        Way wnew = new Way(w);
     232                                                        wnew.nodes.add(nearestWaySeg.lowerIndex+1, n);
     233                                                        cmds.add(new ChangeCommand(w, wnew));
     234                                                        Main.main.undoRedo.add(new SequenceCommand(tr("Add a new node to an existing way"), cmds));
     235                                                        osm = n;
     236                                                }
     237                                        }
     238                                }
     239                        }
     240                }
     241                if (osm == null)
     242                        return Collections.emptySet();
     243                return Collections.singleton(osm);
     244        }
     245
    197246        /**
    198247         * Look, whether any object is selected. If not, select the nearest node.
     
    216265                initialMoveThresholdExceeded = false;
    217266
    218                 Collection<OsmPrimitive> osmColl =
    219                         Main.map.mapView.getNearestCollection(e.getPoint());
     267                Collection<OsmPrimitive> osmColl = getNearestCollectionVirtual(e.getPoint());
    220268
    221269                if (ctrl && shift) {
     
    289337
    290338        public void selectPrims(Collection<OsmPrimitive> selectionList, boolean shift, boolean ctrl) {
    291             if (shift && ctrl)
     339                if (shift && ctrl)
    292340                        return; // not allowed together
    293341
     
    305353                Main.ds.setSelected(curSel);
    306354                Main.map.mapView.repaint();
    307     }
     355        }
    308356       
    309357        @Override public String getModeHelpText() {
  • trunk/src/org/openstreetmap/josm/data/osm/visitor/MapPaintVisitor.java

    r804 r805  
    2727import org.openstreetmap.josm.data.osm.Relation;
    2828import org.openstreetmap.josm.data.osm.Way;
     29import org.openstreetmap.josm.data.osm.visitor.SimplePaintVisitor;
    2930import org.openstreetmap.josm.gui.NavigatableComponent;
    3031import org.openstreetmap.josm.gui.mappaint.AreaElemStyle;
     
    3435import org.openstreetmap.josm.gui.mappaint.MapPaintStyles;
    3536
    36 public class MapPaintVisitor implements Visitor {
    37    
    38     protected boolean useRealWidth;
    39     protected boolean zoomLevelDisplay;
    40     protected boolean fillAreas;
    41     protected int fillAlpha;
    42     protected Color untaggedColor;
    43     protected Color textColor;
    44     protected boolean currentDashed = false;
    45     protected int currentWidth = 0;
    46     protected Stroke currentStroke = null;   
    47     protected static final Font orderFont = new Font("Helvetica", Font.PLAIN, 8);
    48    
    49     public boolean inactive;
    50    
    51     /**
    52      * The environment to paint to.
    53      */
    54     protected Graphics g;
    55    
    56     /**
    57      * MapView to get screen coordinates.
    58      */
    59     protected NavigatableComponent nc;
    60    
    61     /**
    62      * Draw subsequent segments of same color as one Path
    63      */
    64     protected Color currentColor = null;
    65     protected GeneralPath currentPath = new GeneralPath();
    66    
    67     protected static final double PHI = Math.toRadians(20);
    68    
    69     /**
    70      * Preferences
    71     */
    72     protected Color inactiveColor;
    73     protected Color selectedColor;
    74     protected Color nodeColor;
    75     protected Color dfltWayColor;
    76     protected Color untaggedWayColor;
    77     protected Color incompleteColor;
    78     protected Color backgroundColor;
    79     protected boolean showDirectionArrow;
    80     protected boolean showRelevantDirectionsOnly;
    81     protected boolean showOrderNumber;
    82    
    83         private boolean fillSelectedNode;
    84 
    85         private boolean fillUnselectedNode;
    86 
    87         private int selectedNodeRadius;
    88 
    89         private int unselectedNodeRadius;
    90        
    91         private int taggedNodeRadius;
    92 
    93         private int selectedNodeSize;
    94 
    95         private int unselectedNodeSize;
    96 
    97         private int defaultSegmentWidth = 2;
    98         private int taggedNodeSize;
    99 
    100     public final static Color darkerblue = new Color(0,0,96);
    101     public final static Color darkblue = new Color(0,0,128);
    102    
    103     protected boolean isZoomOk(ElemStyle e) {
    104         double circum = Main.map.mapView.getScale()*100*Main.proj.scaleFactor()*40041455; // circumference of the earth in meter
    105 
    106         /* show everything if the user wishes so */
    107         if (!zoomLevelDisplay) {
    108             return true;
    109         }
    110 
    111         if (e == null) {
    112             /* the default for things that don't have a rule (show, if scale is smaller than 1500m) */
    113             if (circum < 1500)
    114                 return true;
    115             return false;
    116         }
    117 
    118         // formula to calculate a map scale: natural size / map size = scale
    119         // example: 876000mm (876m as displayed) / 22mm (roughly estimated screen size of legend bar) = 39818
    120         //
    121         // so the exact "correcting value" below depends only on the screen size and resolution
    122         // XXX - do we need a Preference setting for this (if things vary widely)?
    123         /*System.out.println(
    124    "Circum: " + circum +
    125    " max: " + e.getMaxScale() + "(" + e.getMaxScale()/22 + ")" +
    126    " min:" + e.getMinScale() + "(" + e.getMinScale()/22 + ")");*/
    127         if(circum>=e.getMaxScale() / 22 || circum<e.getMinScale() / 22)
    128             return false;
    129         return true;
    130     }
    131 
    132     /**
    133      * Draw a small rectangle.
    134      * White if selected (as always) or red otherwise.
    135      *
    136      * @param n The node to draw.
    137      */
    138     public void visit(Node n) {
    139         ElemStyle nodeStyle = MapPaintStyles.getStyle(n);
    140         if (nodeStyle!=null) {
    141             if (nodeStyle instanceof IconElemStyle) {
    142                 if (isZoomOk(nodeStyle)) {
    143                     drawNode(n, ((IconElemStyle)nodeStyle).getIcon(), ((IconElemStyle)nodeStyle).doAnnotate());
    144                 }
    145             } else {
    146                 // throw some sort of exception
    147             }
    148         } else {
     37public class MapPaintVisitor extends SimplePaintVisitor {
     38        protected boolean useRealWidth;
     39        protected boolean zoomLevelDisplay;
     40        protected boolean fillAreas;
     41        protected int fillAlpha;
     42        protected Color untaggedColor;
     43        protected Color textColor;
     44        protected boolean currentDashed = false;
     45        protected int currentWidth = 0;
     46        protected Stroke currentStroke = null;
     47        protected static final Font orderFont = new Font("Helvetica", Font.PLAIN, 8);
     48
     49        protected boolean isZoomOk(ElemStyle e) {
     50                double circum = Main.map.mapView.getScale()*100*Main.proj.scaleFactor()*40041455; // circumference of the earth in meter
     51
     52                /* show everything if the user wishes so */
     53                if (!zoomLevelDisplay) {
     54                        return true;
     55                }
     56
     57                if (e == null) {
     58                        /* the default for things that don't have a rule (show, if scale is smaller than 1500m) */
     59                        if (circum < 1500)
     60                                return true;
     61                        return false;
     62                }
     63
     64                // formula to calculate a map scale: natural size / map size = scale
     65                // example: 876000mm (876m as displayed) / 22mm (roughly estimated screen size of legend bar) = 39818
     66                //
     67                // so the exact "correcting value" below depends only on the screen size and resolution
     68                // XXX - do we need a Preference setting for this (if things vary widely)?
     69                /*System.out.println(
     70                "Circum: " + circum +
     71                " max: " + e.getMaxScale() + "(" + e.getMaxScale()/22 + ")" +
     72                " min:" + e.getMinScale() + "(" + e.getMinScale()/22 + ")");*/
     73                if(circum>=e.getMaxScale() / 22 || circum<e.getMinScale() / 22)
     74                        return false;
     75                return true;
     76        }
     77
     78        /**
     79         * Draw a small rectangle.
     80         * White if selected (as always) or red otherwise.
     81         *
     82         * @param n The node to draw.
     83         */
     84        public void visit(Node n) {
     85                ElemStyle nodeStyle = MapPaintStyles.getStyle(n);
     86                if (nodeStyle!=null) {
     87                        if (nodeStyle instanceof IconElemStyle) {
     88                                if (isZoomOk(nodeStyle)) {
     89                                        drawNode(n, ((IconElemStyle)nodeStyle).getIcon(), ((IconElemStyle)nodeStyle).doAnnotate());
     90                                }
     91                        } else {
     92                                // throw some sort of exception
     93                        }
     94                } else {
    14995                        if (n.selected)
    15096                                drawNode(n, selectedColor, selectedNodeSize, selectedNodeRadius, fillSelectedNode);
     
    15399                        else
    154100                                drawNode(n, nodeColor, unselectedNodeSize, unselectedNodeRadius, fillUnselectedNode);
    155         }
    156     }
    157 
    158     /**
    159      * Draw a line for all segments, according to tags.
    160      * @param w The way to draw.
    161      */
    162     public void visit(Way w) {
    163         double circum = Main.map.mapView.getScale()*100*Main.proj.scaleFactor()*40041455; // circumference of the earth in meter
    164                 // show direction arrows, if draw.segment.relevant_directions_only is not set, the way is tagged with a direction key
    165                 // (even if the tag is negated as in oneway=false) or the way is selected
    166         boolean showDirection = w.selected ||
    167                                         ((!useRealWidth) && (showDirectionArrow
    168                                                              && (!showRelevantDirectionsOnly || w.hasDirectionKeys)));
    169 
    170         Color colour = untaggedColor;
     101                }
     102        }
     103
     104        /**
     105         * Draw a line for all segments, according to tags.
     106         * @param w The way to draw.
     107         */
     108        public void visit(Way w) {
     109                double circum = Main.map.mapView.getScale()*100*Main.proj.scaleFactor()*40041455; // circumference of the earth in meter
     110                // show direction arrows, if draw.segment.relevant_directions_only is not set, the way is tagged with a direction key
     111                // (even if the tag is negated as in oneway=false) or the way is selected
     112                boolean showDirection = w.selected || ((!useRealWidth) && (showDirectionArrow
     113                 && (!showRelevantDirectionsOnly || w.hasDirectionKeys)));
     114
     115                Color colour = untaggedColor;
    171116                int width = defaultSegmentWidth;
    172         int realWidth = 0; //the real width of the element in meters
    173         boolean dashed = false;
    174         boolean area = false;
    175         ElemStyle wayStyle = MapPaintStyles.getStyle(w);
    176 
    177         if(!isZoomOk(wayStyle)) {
    178             return;
    179         }
    180 
    181         if(wayStyle!=null)
    182         {
    183             if(wayStyle instanceof LineElemStyle)
    184             {
    185                 colour = ((LineElemStyle)wayStyle).colour;
    186                 width = ((LineElemStyle)wayStyle).width;
    187                 realWidth = ((LineElemStyle)wayStyle).realWidth;
    188                 dashed = ((LineElemStyle)wayStyle).dashed;
    189             }
    190             else if (wayStyle instanceof AreaElemStyle)
    191             {
    192                 colour = ((AreaElemStyle)wayStyle).getColour();
    193                 area = true;
    194             }
    195         }
    196 
    197         if (area && fillAreas)
    198             drawWayAsArea(w, colour);
    199         int orderNumber = 0;
    200 
    201         Node lastN = null;
    202         for (Node n : w.nodes) {
    203             if (lastN == null) {
    204                 lastN = n;
    205                 continue;
    206             }
    207             orderNumber++;
    208 
    209             if (area) {
    210                 if(fillAreas)
    211                 {
    212                     // hack to make direction arrows visible against filled background
    213                     if (showDirection)
    214                         drawSeg(lastN, n, w.selected ? selectedColor : untaggedColor, showDirection, width, true);
    215                 }
    216                 else
    217                     drawSeg(lastN, n, w.selected ? selectedColor : colour, showDirection, width, true);
    218             } else {
    219                 if (realWidth > 0 && useRealWidth && !showDirection) {
    220                     int tmpWidth = (int) (100 /  (float) (circum / realWidth));
    221                     if (tmpWidth > width) width = tmpWidth;
    222                 }
    223                 drawSeg(lastN, n, w.selected ? selectedColor : colour, showDirection, width, dashed);
    224             }
    225 
    226             if (showOrderNumber)
    227                 drawOrderNumber(lastN, n, orderNumber);
    228 
    229             lastN = n;
    230         }
    231     }
    232 
    233     public void visit(Relation e) {
    234         // relations are not (yet?) drawn.
    235     }
    236    
    237     // This assumes that all segments are aligned in the same direction!
    238     protected void drawWayAsArea(Way w, Color colour)
    239     {
    240         Polygon polygon = new Polygon();
    241         Point p;
    242         // set the opacity (alpha) level of the filled polygon
    243         Color coloura = new Color( colour.getRed(), colour.getGreen(), colour.getBlue(), fillAlpha);
    244 
    245         for (Node n : w.nodes)
    246         {
    247             p = nc.getPoint(n.eastNorth);
    248             polygon.addPoint(p.x,p.y);
    249         }
    250 
    251         g.setColor( w.selected ?
    252                 selectedColor : coloura);
    253 
    254         g.fillPolygon(polygon);
    255     }
    256 
    257     // NEW
    258     protected void drawNode(Node n, ImageIcon icon, boolean annotate) {
    259         Point p = nc.getPoint(n.eastNorth);
    260         if ((p.x < 0) || (p.y < 0) || (p.x > nc.getWidth()) || (p.y > nc.getHeight())) return;
    261         int w = icon.getIconWidth(), h=icon.getIconHeight();
    262         icon.paintIcon ( Main.map.mapView, g, p.x-w/2, p.y-h/2 );
    263         String name = (n.keys==null) ? null : n.keys.get("name");
    264         if (name!=null && annotate)
    265         {
    266             g.setColor(textColor);
    267             Font defaultFont = g.getFont();
    268             g.setFont (orderFont);
    269             g.drawString (name, p.x+w/2+2, p.y+h/2+2);
    270             g.setFont(defaultFont);
    271         }
    272         if (n.selected)
    273         {
    274             g.setColor (  selectedColor );
    275             g.drawRect (p.x-w/2-2,p.y-w/2-2, w+4, h+4);
    276         }
    277     }
    278 
    279     /**
    280      * Draw a line with the given color.
    281      */
    282     protected void drawSegment(Node n1, Node n2, Color col, boolean showDirection) {
    283         if (useRealWidth && showDirection) showDirection = false;
    284         drawSeg(n1, n2, col, showDirection, 1, false);
    285     }
    286 
    287     private void drawSeg(Node n1, Node n2, Color col, boolean showDirection, int width, boolean dashed) {
    288         if (col != currentColor || width != currentWidth || dashed != currentDashed) {
    289             displaySegments(col, width, dashed);
    290         }
    291         Point p1 = nc.getPoint(n1.eastNorth);
    292         Point p2 = nc.getPoint(n2.eastNorth);
    293 
    294         if (!isSegmentVisible(p1, p2)) {
    295             return;
    296         }
    297         //if (ls.selected)
    298         // col = selectedColor;
    299         //g.setColor(col);
    300         //g.setWidth(width);
    301         //if (dashed)
    302         // g2d.setStroke(new BasicStroke(width,BasicStroke.CAP_BUTT,BasicStroke.JOIN_ROUND,0,new float[] {9},0));
    303         //else
    304         // g2d.setStroke(new BasicStroke(width,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND));
    305 
    306         //g.drawLine(p1.x, p1.y, p2.x, p2.y);
    307         currentPath.moveTo(p1.x, p1.y);
    308         currentPath.lineTo(p2.x, p2.y);
    309 
    310         if (showDirection) {
    311             double t = Math.atan2(p2.y-p1.y, p2.x-p1.x) + Math.PI;
    312             //g.drawLine(p2.x,p2.y, (int)(p2.x + 10*Math.cos(t-PHI)), (int)(p2.y + 10*Math.sin(t-PHI)));
    313             //g.drawLine(p2.x,p2.y, (int)(p2.x + 10*Math.cos(t+PHI)), (int)(p2.y + 10*Math.sin(t+PHI)));
    314             currentPath.lineTo((int)(p2.x + 10*Math.cos(t-PHI)), (int)(p2.y + 10*Math.sin(t-PHI)));
    315             currentPath.moveTo((int)(p2.x + 10*Math.cos(t+PHI)), (int)(p2.y + 10*Math.sin(t+PHI)));
    316             currentPath.lineTo(p2.x, p2.y);
    317         }
    318         //g2d.setStroke(new BasicStroke(1));
    319 
    320     }
    321 
    322     protected void displaySegments() {
    323         displaySegments(null, 0, false);
    324     }
    325 
    326     protected void displaySegments(Color newColor, int newWidth, boolean newDash) {
    327 
    328         if (currentPath != null) {
    329             Graphics2D g2d = (Graphics2D)g;
    330             g2d.setColor(inactive ? inactiveColor : currentColor);
    331             if (currentStroke == null) {
    332                 if (currentDashed)
    333                     g2d.setStroke(new BasicStroke(currentWidth,BasicStroke.CAP_BUTT,BasicStroke.JOIN_ROUND,0,new float[] {9},0));
    334                 else
    335                     g2d.setStroke(new BasicStroke(currentWidth,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND));
    336             }
    337             g2d.draw(currentPath);
    338             g2d.setStroke(new BasicStroke(1));
    339 
    340             currentPath = new GeneralPath();
    341             currentColor = newColor;
    342             currentWidth = newWidth;
    343             currentDashed = newDash;
    344             currentStroke = null;
    345         }
    346     }
    347 
    348     /**
    349      * Draw the node as small rectangle with the given color.
    350      *
    351      * @param n  The node to draw.
    352      * @param color The color of the node.
    353      */
    354     public void drawNode(Node n, Color color, int size, int radius, boolean fill) {
     117                int realWidth = 0; //the real width of the element in meters
     118                boolean dashed = false;
     119                boolean area = false;
     120                ElemStyle wayStyle = MapPaintStyles.getStyle(w);
     121
     122                if(!isZoomOk(wayStyle)) {
     123                        return;
     124                }
     125
     126                if(wayStyle!=null)
     127                {
     128                        if(wayStyle instanceof LineElemStyle)
     129                        {
     130                                colour = ((LineElemStyle)wayStyle).colour;
     131                                width = ((LineElemStyle)wayStyle).width;
     132                                realWidth = ((LineElemStyle)wayStyle).realWidth;
     133                                dashed = ((LineElemStyle)wayStyle).dashed;
     134                        }
     135                        else if (wayStyle instanceof AreaElemStyle)
     136                        {
     137                                colour = ((AreaElemStyle)wayStyle).getColour();
     138                                area = true;
     139                        }
     140                }
     141
     142                if (area && fillAreas)
     143                        drawWayAsArea(w, colour);
     144                int orderNumber = 0;
     145
     146                Node lastN = null;
     147                for (Node n : w.nodes) {
     148                        if (lastN == null) {
     149                                lastN = n;
     150                                continue;
     151                        }
     152                        orderNumber++;
     153
     154                        if (area) {
     155                                if(fillAreas)
     156                                {
     157                                        // hack to make direction arrows visible against filled background
     158                                        if (showDirection)
     159                                                drawSeg(lastN, n, w.selected ? selectedColor : untaggedColor, showDirection, width, true);
     160                                }
     161                                else
     162                                        drawSeg(lastN, n, w.selected ? selectedColor : colour, showDirection, width, true);
     163                        } else {
     164                                if (realWidth > 0 && useRealWidth && !showDirection) {
     165                                        int tmpWidth = (int) (100 /  (float) (circum / realWidth));
     166                                        if (tmpWidth > width) width = tmpWidth;
     167                                }
     168                                drawSeg(lastN, n, w.selected ? selectedColor : colour, showDirection, width, dashed);
     169                        }
     170
     171                        if (showOrderNumber)
     172                                drawOrderNumber(lastN, n, orderNumber);
     173
     174                        lastN = n;
     175                }
     176        }
     177
     178        public void visit(Relation e) {
     179                // relations are not (yet?) drawn.
     180        }
     181
     182        // This assumes that all segments are aligned in the same direction!
     183        protected void drawWayAsArea(Way w, Color colour)
     184        {
     185                Polygon polygon = new Polygon();
     186                Point p;
     187                // set the opacity (alpha) level of the filled polygon
     188                Color coloura = new Color( colour.getRed(), colour.getGreen(), colour.getBlue(), fillAlpha);
     189
     190                for (Node n : w.nodes)
     191                {
     192                        p = nc.getPoint(n.eastNorth);
     193                        polygon.addPoint(p.x,p.y);
     194                }
     195
     196                g.setColor( w.selected ?
     197                                selectedColor : coloura);
     198
     199                g.fillPolygon(polygon);
     200        }
     201
     202        // NEW
     203        protected void drawNode(Node n, ImageIcon icon, boolean annotate) {
     204                Point p = nc.getPoint(n.eastNorth);
     205                if ((p.x < 0) || (p.y < 0) || (p.x > nc.getWidth()) || (p.y > nc.getHeight())) return;
     206                int w = icon.getIconWidth(), h=icon.getIconHeight();
     207                icon.paintIcon ( Main.map.mapView, g, p.x-w/2, p.y-h/2 );
     208                String name = (n.keys==null) ? null : n.keys.get("name");
     209                if (name!=null && annotate)
     210                {
     211                        g.setColor(textColor);
     212                        Font defaultFont = g.getFont();
     213                        g.setFont (orderFont);
     214                        g.drawString (name, p.x+w/2+2, p.y+h/2+2);
     215                        g.setFont(defaultFont);
     216                }
     217                if (n.selected)
     218                {
     219                        g.setColor (  selectedColor );
     220                        g.drawRect (p.x-w/2-2,p.y-w/2-2, w+4, h+4);
     221                }
     222        }
     223
     224        /**
     225         * Draw a line with the given color.
     226         */
     227        protected void drawSegment(Node n1, Node n2, Color col, boolean showDirection) {
     228                if (useRealWidth && showDirection) showDirection = false;
     229                drawSeg(n1, n2, col, showDirection, 1, false);
     230        }
     231
     232        private void drawSeg(Node n1, Node n2, Color col, boolean showDirection, int width, boolean dashed) {
     233                if (col != currentColor || width != currentWidth || dashed != currentDashed) {
     234                        displaySegments(col, width, dashed);
     235                }
     236                Point p1 = nc.getPoint(n1.eastNorth);
     237                Point p2 = nc.getPoint(n2.eastNorth);
     238
     239                if (!isSegmentVisible(p1, p2)) {
     240                        return;
     241                }
     242                drawVirtualNode(p1, p2, col);
     243                currentPath.moveTo(p1.x, p1.y);
     244                currentPath.lineTo(p2.x, p2.y);
     245
     246                if (showDirection) {
     247                        double t = Math.atan2(p2.y-p1.y, p2.x-p1.x) + Math.PI;
     248                        currentPath.lineTo((int)(p2.x + 10*Math.cos(t-PHI)), (int)(p2.y + 10*Math.sin(t-PHI)));
     249                        currentPath.moveTo((int)(p2.x + 10*Math.cos(t+PHI)), (int)(p2.y + 10*Math.sin(t+PHI)));
     250                        currentPath.lineTo(p2.x, p2.y);
     251                }
     252        }
     253
     254        protected void displaySegments() {
     255                displaySegments(null, 0, false);
     256        }
     257
     258        protected void displaySegments(Color newColor, int newWidth, boolean newDash) {
     259
     260                if (currentPath != null) {
     261                        Graphics2D g2d = (Graphics2D)g;
     262                        g2d.setColor(inactive ? inactiveColor : currentColor);
     263                        if (currentStroke == null) {
     264                                if (currentDashed)
     265                                        g2d.setStroke(new BasicStroke(currentWidth,BasicStroke.CAP_BUTT,BasicStroke.JOIN_ROUND,0,new float[] {9},0));
     266                                else
     267                                        g2d.setStroke(new BasicStroke(currentWidth,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND));
     268                        }
     269                        g2d.draw(currentPath);
     270                        g2d.setStroke(new BasicStroke(1));
     271
     272                        currentPath = new GeneralPath();
     273                        currentColor = newColor;
     274                        currentWidth = newWidth;
     275                        currentDashed = newDash;
     276                        currentStroke = null;
     277                }
     278        }
     279
     280        /**
     281         * Draw the node as small rectangle with the given color.
     282         *
     283         * @param n  The node to draw.
     284         * @param color The color of the node.
     285         */
     286        public void drawNode(Node n, Color color, int size, int radius, boolean fill) {
    355287                if (isZoomOk(null) && size > 1) {
    356288                        Point p = nc.getPoint(n.eastNorth);
    357289                        if ((p.x < 0) || (p.y < 0) || (p.x > nc.getWidth())
    358                                 || (p.y > nc.getHeight()))
     290                                        || (p.y > nc.getHeight()))
    359291                                return;
    360292                        g.setColor(color);
     
    367299        }
    368300
    369     // NW 111106 Overridden from SimplePaintVisitor in josm-1.4-nw1
    370     // Shows areas before non-areas
    371     public void visitAll(DataSet data) {
    372         inactiveColor = Main.pref.getColor(marktr("inactive"), Color.DARK_GRAY);
    373         selectedColor = Main.pref.getColor(marktr("selected"), Color.YELLOW);
    374         nodeColor = Main.pref.getColor(marktr("node"), Color.RED);
    375         dfltWayColor = Main.pref.getColor(marktr("way"), darkblue);
    376         incompleteColor = Main.pref.getColor(marktr("incomplete way"), darkerblue);
    377         backgroundColor = Main.pref.getColor(marktr("background"), Color.BLACK);
    378         untaggedColor = Main.pref.getColor(marktr("untagged"),Color.GRAY);
    379         textColor = Main.pref.getColor (marktr("text"), Color.WHITE);
    380         showDirectionArrow = Main.pref.getBoolean("draw.segment.direction");
    381         showRelevantDirectionsOnly = Main.pref.getBoolean("draw.segment.relevant_directions_only");
    382         showOrderNumber = Main.pref.getBoolean("draw.segment.order_number");
    383         useRealWidth = Main.pref.getBoolean("mappaint.useRealWidth",false);
    384         zoomLevelDisplay = Main.pref.getBoolean("mappaint.zoomLevelDisplay",false);
    385         fillAreas = Main.pref.getBoolean("mappaint.fillareas", true);
    386 
    387                 selectedNodeRadius = Main.pref.getInteger("mappaint.node.selected-size",
    388                         5) / 2;
    389                 selectedNodeSize = selectedNodeRadius * 2;
    390 
    391                 unselectedNodeRadius = Main.pref.getInteger(
    392                         "mappaint.node.unselected-size", 3) / 2;
    393                 unselectedNodeSize = unselectedNodeRadius * 2;
    394 
    395                 taggedNodeRadius = Main.pref.getInteger(
    396                                 "mappaint.node.tagged-size", 5) / 2;
    397                 taggedNodeSize = taggedNodeRadius * 2;
    398 
    399                 defaultSegmentWidth = Main.pref.getInteger(
    400                         "mappaint.segment.default-width", 2);
    401 
    402                 fillSelectedNode = Main.pref.getBoolean("mappaint.node.fill-selected",
    403                         true);
    404                 fillUnselectedNode = Main.pref.getBoolean(
    405                         "mappaint.node.fill-unselected", false);
    406 
    407                 ((Graphics2D)g)
    408                         .setRenderingHint(
    409                                 RenderingHints.KEY_ANTIALIASING,
    410                                 Main.pref.getBoolean("mappaint.use-antialiasing", true) ? RenderingHints.VALUE_ANTIALIAS_ON
    411                                         : RenderingHints.VALUE_ANTIALIAS_OFF);
    412 
    413                 fillAlpha = Math.min(255, Math.max(0, Integer.valueOf(Main.pref
    414                         .getInteger("mappaint.fillalpha", 50))));
    415 
    416         Collection<Way> noAreaWays = new LinkedList<Way>();
    417 
    418         for (final OsmPrimitive osm : data.ways)
    419             if (!osm.incomplete && !osm.deleted && MapPaintStyles.isArea(osm))
    420                 osm.visit(this);
    421             else if (!osm.deleted && !osm.incomplete)
    422                 noAreaWays.add((Way)osm);
    423 
    424         for (final OsmPrimitive osm : noAreaWays)
    425             osm.visit(this);
    426 
    427         for (final OsmPrimitive osm : data.nodes)
    428             if (!osm.incomplete && !osm.deleted)
    429                 osm.visit(this);
    430 
    431         for (final OsmPrimitive osm : data.getSelected())
    432             if (!osm.incomplete && !osm.deleted){
    433                 osm.visit(this);
    434             }
    435         displaySegments();
    436     }
    437    
    438     /**
    439      * Draw a number of the order of the two consecutive nodes within the
    440      * parents way
    441      */
    442     protected void drawOrderNumber(Node n1, Node n2, int orderNumber) {
    443         Point p1 = nc.getPoint(n1.eastNorth);
    444         Point p2 = nc.getPoint(n2.eastNorth);
    445         if (!isSegmentVisible(p1, p2)) {
    446             return;
    447         }
    448         int strlen = (""+orderNumber).length();
    449         int x = (p1.x+p2.x)/2 - 4*strlen;
    450         int y = (p1.y+p2.y)/2 + 4;
    451 
    452         Color c = g.getColor();
    453         g.setColor(backgroundColor);
    454         g.fillRect(x-1, y-12, 8*strlen+1, 14);
    455         g.setColor(c);
    456         g.drawString(""+orderNumber, x, y);
    457       }
    458 
    459     private boolean isSegmentVisible(Point p1, Point p2) {
    460         if ((p1.x < 0) && (p2.x < 0)) return false;
    461         if ((p1.y < 0) && (p2.y < 0)) return false;
    462         if ((p1.x > nc.getWidth()) && (p2.x > nc.getWidth())) return false;
    463         if ((p1.y > nc.getHeight()) && (p2.y > nc.getHeight())) return false;
    464         return true;
    465     }
    466    
    467     public void setGraphics(Graphics g) {
    468         this.g = g;
    469     }
    470 
    471     public void setNavigatableComponent(NavigatableComponent nc) {
    472         this.nc = nc;
    473     }
     301        // NW 111106 Overridden from SimplePaintVisitor in josm-1.4-nw1
     302        // Shows areas before non-areas
     303        public void visitAll(DataSet data, Boolean virtual) {
     304                getSettings(virtual);
     305                untaggedColor = Main.pref.getColor(marktr("untagged"),Color.GRAY);
     306                textColor = Main.pref.getColor (marktr("text"), Color.WHITE);
     307                useRealWidth = Main.pref.getBoolean("mappaint.useRealWidth",false);
     308                zoomLevelDisplay = Main.pref.getBoolean("mappaint.zoomLevelDisplay",false);
     309                fillAreas = Main.pref.getBoolean("mappaint.fillareas", true);
     310                fillAlpha = Math.min(255, Math.max(0, Integer.valueOf(Main.pref.getInteger("mappaint.fillalpha", 50))));
     311
     312                Collection<Way> noAreaWays = new LinkedList<Way>();
     313
     314                for (final OsmPrimitive osm : data.ways)
     315                        if (!osm.incomplete && !osm.deleted && MapPaintStyles.isArea(osm))
     316                                osm.visit(this);
     317                        else if (!osm.deleted && !osm.incomplete)
     318                                noAreaWays.add((Way)osm);
     319
     320                for (final OsmPrimitive osm : noAreaWays)
     321                        osm.visit(this);
     322
     323                for (final OsmPrimitive osm : data.nodes)
     324                        if (!osm.incomplete && !osm.deleted)
     325                                osm.visit(this);
     326
     327                for (final OsmPrimitive osm : data.getSelected())
     328                        if (!osm.incomplete && !osm.deleted){
     329                                osm.visit(this);
     330                        }
     331                displaySegments();
     332        }
     333
     334        /**
     335         * Draw a number of the order of the two consecutive nodes within the
     336         * parents way
     337         */
     338        protected void drawOrderNumber(Node n1, Node n2, int orderNumber) {
     339                Point p1 = nc.getPoint(n1.eastNorth);
     340                Point p2 = nc.getPoint(n2.eastNorth);
     341                if (!isSegmentVisible(p1, p2)) {
     342                        return;
     343                }
     344                int strlen = (""+orderNumber).length();
     345                int x = (p1.x+p2.x)/2 - 4*strlen;
     346                int y = (p1.y+p2.y)/2 + 4;
     347
     348                Color c = g.getColor();
     349                g.setColor(backgroundColor);
     350                g.fillRect(x-1, y-12, 8*strlen+1, 14);
     351                g.setColor(c);
     352                g.drawString(""+orderNumber, x, y);
     353        }
    474354}
  • trunk/src/org/openstreetmap/josm/data/osm/visitor/SimplePaintVisitor.java

    r804 r805  
    2727
    2828/**
    29  * A visitor that paints a simple scheme of every primitive it visits to a 
     29 * A visitor that paints a simple scheme of every primitive it visits to a
    3030 * previous set graphic environment.
    31  * 
     31 *
    3232 * @author imi
    3333 */
     
    4747         */
    4848        protected NavigatableComponent nc;
    49        
     49
    5050        public boolean inactive;
    5151
    5252        protected static final double PHI = Math.toRadians(20);
    53        
     53
    5454        /**
    5555         * Preferences
     
    6363        protected Color incompleteColor;
    6464        protected Color backgroundColor;
    65     protected boolean showDirectionArrow;
    66     protected boolean showRelevantDirectionsOnly;
     65        protected boolean showDirectionArrow;
     66        protected boolean showRelevantDirectionsOnly;
    6767        protected boolean showOrderNumber;
    68        
    69         private boolean fillSelectedNode;
    70 
    71         private boolean fillUnselectedNode;
    72 
    73         private int selectedNodeRadius;
    74 
    75         private int unselectedNodeRadius;
    76 
    77         private int selectedNodeSize;
    78 
    79         private int unselectedNodeSize;
    80 
    81         private int defaultSegmentWidth = 2;
     68        protected boolean fillSelectedNode;
     69        protected boolean fillUnselectedNode;
     70        protected int selectedNodeRadius;
     71        protected int unselectedNodeRadius;
     72        protected int selectedNodeSize;
     73        protected int unselectedNodeSize;
     74        protected int defaultSegmentWidth = 2;
     75        protected int virtualNodeSize;
     76        protected int virtualNodeSpace;
     77        protected int taggedNodeRadius;
     78        protected int taggedNodeSize;
    8279
    8380        /**
     
    8885
    8986        Rectangle bbox = new Rectangle();
    90         private int taggedNodeRadius;
    91         private int taggedNodeSize;
    92 
    93         public void visitAll(DataSet data) {
     87
     88        protected void getSettings(Boolean virtual) {
    9489                inactiveColor = Main.pref.getColor(marktr("inactive"), Color.DARK_GRAY);
    9590                selectedColor = Main.pref.getColor(marktr("selected"), Color.WHITE);
     
    10398                showRelevantDirectionsOnly = Main.pref.getBoolean("draw.segment.relevant_directions_only");
    10499                showOrderNumber = Main.pref.getBoolean("draw.segment.order_number");
    105                
    106                 selectedNodeRadius = Main.pref.getInteger("mappaint.node.selected-size",
    107                         5) / 2;
     100                selectedNodeRadius = Main.pref.getInteger("mappaint.node.selected-size", 5) / 2;
    108101                selectedNodeSize = selectedNodeRadius * 2;
    109                 unselectedNodeRadius = Main.pref.getInteger(
    110                         "mappaint.node.unselected-size", 3) / 2;
     102                unselectedNodeRadius = Main.pref.getInteger("mappaint.node.unselected-size", 3) / 2;
    111103                unselectedNodeSize = unselectedNodeRadius * 2;
    112 
    113                 taggedNodeRadius = Main.pref.getInteger(
    114                                 "mappaint.node.tagged-size", 5) / 2;
     104                taggedNodeRadius = Main.pref.getInteger("mappaint.node.tagged-size", 5) / 2;
    115105                taggedNodeSize = taggedNodeRadius * 2;
    116 
    117                 defaultSegmentWidth = Main.pref.getInteger(
    118                         "mappaint.segment.default-width", 2);
    119 
    120                 fillSelectedNode = Main.pref.getBoolean("mappaint.node.fill-selected",
    121                         true);
    122                 fillUnselectedNode = Main.pref.getBoolean(
    123                         "mappaint.node.fill-unselected", false);
     106                defaultSegmentWidth = Main.pref.getInteger("mappaint.segment.default-width", 2);
     107                fillSelectedNode = Main.pref.getBoolean("mappaint.node.fill-selected", true);
     108                fillUnselectedNode = Main.pref.getBoolean("mappaint.node.fill-unselected", false);
     109                virtualNodeSize = virtual ? Main.pref.getInteger("mappaint.node.virtual-size", 4) / 2 : 0;
     110                virtualNodeSpace = Main.pref.getInteger("mappaint.node.virtual-space", 50);
    124111
    125112                ((Graphics2D)g)
    126                         .setRenderingHint(
    127                                 RenderingHints.KEY_ANTIALIASING,
    128                                 Main.pref.getBoolean("mappaint.use-antialiasing", true) ? RenderingHints.VALUE_ANTIALIAS_ON
    129                                         : RenderingHints.VALUE_ANTIALIAS_OFF);
    130 
     113                                .setRenderingHint(
     114                                                RenderingHints.KEY_ANTIALIASING,
     115                                                Main.pref.getBoolean("mappaint.use-antialiasing", true) ? RenderingHints.VALUE_ANTIALIAS_ON
     116                                                                : RenderingHints.VALUE_ANTIALIAS_OFF);
     117        }
     118
     119        public void visitAll(DataSet data, Boolean virtual) {
     120                getSettings(virtual);
    131121                // draw tagged ways first, then untagged ways. takes
    132122                // time to iterate through list twice, OTOH does not
     
    141131                displaySegments(null);
    142132
    143             for (final OsmPrimitive osm : data.ways)
     133                for (final OsmPrimitive osm : data.ways)
    144134                        if (!osm.deleted && !osm.selected && !osm.tagged)
    145135                                osm.visit(this);
    146136                displaySegments(null);
    147            
     137
    148138                for (final OsmPrimitive osm : data.nodes)
    149139                        if (!osm.deleted && !osm.selected)
    150140                                osm.visit(this);
    151        
     141
    152142                for (final OsmPrimitive osm : data.getSelected())
    153143                        if (!osm.deleted)
    154144                                osm.visit(this);
    155145                displaySegments(null);
    156         }
    157 
    158         /**
    159          * Draw a small rectangle. 
     146        }
     147
     148        /**
     149         * Draw a small rectangle.
    160150         * White if selected (as always) or red otherwise.
    161          * 
     151         *
    162152         * @param n The node to draw.
    163153         */
     
    171161                else if(n.tagged)
    172162                        drawNode(n, nodeColor, taggedNodeSize, taggedNodeRadius, fillUnselectedNode);
    173                 else 
     163                else
    174164                        drawNode(n, nodeColor, unselectedNodeSize, unselectedNodeRadius, fillUnselectedNode);
    175165        }
     
    182172                if (w.incomplete) return;
    183173
    184                 // show direction arrows, if draw.segment.relevant_directions_only is not set, the way is tagged with a direction key
    185                 // (even if the tag is negated as in oneway=false) or the way is selected
    186 
    187                 boolean showThisDirectionArrow = w.selected
    188                                                 || (showDirectionArrow
    189                                                     && (!showRelevantDirectionsOnly || w.hasDirectionKeys));
     174                                // show direction arrows, if draw.segment.relevant_directions_only is not set, the way is tagged with a direction key
     175                                // (even if the tag is negated as in oneway=false) or the way is selected
     176
     177                                boolean showThisDirectionArrow = w.selected
     178                                                                                                || (showDirectionArrow
     179                                                                                                        && (!showRelevantDirectionsOnly || w.hasDirectionKeys));
    190180                Color wayColor;
    191                
     181
    192182                if (inactive) {
    193183                        wayColor = inactiveColor;
     
    254244                }
    255245        }
    256        
     246
    257247        /**
    258248         * Draw an number of the order of the two consecutive nodes within the
     
    271261                        g.drawString(""+orderNumber, x, y);
    272262                }
    273     }
     263        }
    274264
    275265        /**
     
    283273                        Point p = nc.getPoint(n.eastNorth);
    284274                        if ((p.x < 0) || (p.y < 0) || (p.x > nc.getWidth())
    285                                 || (p.y > nc.getHeight()))
     275                                        || (p.y > nc.getHeight()))
    286276                                return;
    287277                        g.setColor(color);
     
    294284        }
    295285
     286        protected void drawVirtualNode(Point p1, Point p2, Color col)
     287        {
     288                if(virtualNodeSize > 0)
     289                {
     290                        int xd = p2.x-p1.x; if(xd < 0) xd = -xd;
     291                        int yd = p2.y-p1.y; if(yd < 0) yd = -yd;
     292                        if(xd+yd > virtualNodeSpace)
     293                        {
     294                                int x = (p1.x+p2.x)/2;
     295                                int y = (p1.y+p2.y)/2;
     296                                currentPath.moveTo(x-5, y);
     297                                currentPath.lineTo(x+5, y);
     298                                currentPath.moveTo(x, y-5);
     299                                currentPath.lineTo(x, y+5);
     300                        }
     301                }
     302        }
     303
    296304        /**
    297305         * Draw a line with the given color.
     
    300308
    301309                if (col != currentColor) displaySegments(col);
    302                
     310
    303311                if (isSegmentVisible(p1, p2)) {
     312                        drawVirtualNode(p1, p2, col);
     313
    304314                        currentPath.moveTo(p1.x, p1.y);
    305315                        currentPath.lineTo(p2.x, p2.y);
    306                        
     316
    307317                        if (showDirection) {
    308318                                double t = Math.atan2(p2.y-p1.y, p2.x-p1.x) + Math.PI;
    309319                                currentPath.lineTo((int)(p2.x + 10*Math.cos(t-PHI)), (int)(p2.y + 10*Math.sin(t-PHI)));
    310320                                currentPath.moveTo((int)(p2.x + 10*Math.cos(t+PHI)), (int)(p2.y + 10*Math.sin(t+PHI)));
    311                                 currentPath.lineTo(p2.x, p2.y); 
     321                                currentPath.lineTo(p2.x, p2.y);
    312322                        }
    313323                }
    314324        }
    315        
    316     private boolean isSegmentVisible(Point p1, Point p2) {
    317         if ((p1.x < 0) && (p2.x < 0)) return false;
    318         if ((p1.y < 0) && (p2.y < 0)) return false;
    319         if ((p1.x > nc.getWidth()) && (p2.x > nc.getWidth())) return false;
    320         if ((p1.y > nc.getHeight()) && (p2.y > nc.getHeight())) return false;
    321         return true;
    322     }
    323        
     325
     326        protected boolean isSegmentVisible(Point p1, Point p2) {
     327                if ((p1.x < 0) && (p2.x < 0)) return false;
     328                if ((p1.y < 0) && (p2.y < 0)) return false;
     329                if ((p1.x > nc.getWidth()) && (p2.x > nc.getWidth())) return false;
     330                if ((p1.y > nc.getHeight()) && (p2.y > nc.getHeight())) return false;
     331                return true;
     332        }
     333
    324334        public void setGraphics(Graphics g) {
    325335                this.g = g;
     
    327337
    328338        public void setNavigatableComponent(NavigatableComponent nc) {
    329         this.nc = nc;
    330     }
     339                this.nc = nc;
     340        }
    331341
    332342        protected void displaySegments(Color newColor) {
     
    338348                }
    339349        }
    340        
    341         /**
    342          * Provided for backwards compatibility only.
    343          * FIXME: remove this once not used by plugins any longer.
    344          */
    345         public static Color getPreferencesColor(String name, Color dflt) {
    346                 return Main.pref.getColor(name, dflt);
    347         }
    348350}
  • trunk/src/org/openstreetmap/josm/gui/MapView.java

    r804 r805  
    182182        }
    183183
     184        private Boolean virtualnodes = false;
     185        public void enableVirtualNodes(Boolean state)
     186        {
     187                if(virtualnodes != state)
     188                {
     189                        virtualnodes = state;
     190                        repaint();
     191                }
     192        }
     193        public Boolean useVirtualNodes()
     194        {
     195                return virtualnodes;
     196        }
     197
    184198        /**
    185199         * Moves the layer to the given new position. No event is fired.
  • trunk/src/org/openstreetmap/josm/gui/NavigatableComponent.java

    r794 r805  
    3232public class NavigatableComponent extends JComponent implements Helpful {
    3333
    34 
    3534        public static final EastNorth world = Main.proj.latlon2eastNorth(new LatLon(Projection.MAX_LAT, Projection.MAX_LON));
    36 
     35        public static final int snapDistance = sqr(Main.pref.getInteger("node.snap-distance", 10));
     36
     37        private static int sqr(int a) { return a*a;}
    3738        /**
    3839         * The scale factor in x or y-units per pixel. This means, if scale = 10,
     
    141142                        Point sp = getPoint(n.eastNorth);
    142143                        double dist = p.distanceSq(sp);
    143                         if (minDistanceSq > dist && dist < 100) {
     144                        if (minDistanceSq > dist && dist < snapDistance) {
    144145                                minDistanceSq = p.distanceSq(sp);
    145146                                minPrimitive = n;
     
    180181                                double b = p.distanceSq(A);
    181182                                double perDist = a-(a-b+c)*(a-b+c)/4/c; // perpendicular distance squared
    182                                 if (perDist < 100 && a < c+100 && b < c+100) {
     183                                if (perDist < snapDistance && a < c+snapDistance && b < c+snapDistance) {
    183184                                        List<WaySegment> l;
    184185                                        if (nearest.containsKey(perDist)) {
     
    228229                WaySegment nearestWaySeg = getNearestWaySegment(p);
    229230                return nearestWaySeg == null ? null : nearestWaySeg.way;
    230     }
     231        }
    231232
    232233        /**
     
    240241         * If nothing is found, return <code>null</code>.
    241242         *
    242          * @param p                              The point on screen.
    243          * @return      The primitive that is nearest to the point p.
     243         * @param p The point on screen.
     244         * @return  The primitive that is nearest to the point p.
    244245         */
    245246        public OsmPrimitive getNearest(Point p) {
    246247                OsmPrimitive osm = getNearestNode(p);
    247248                if (osm == null)
     249                {
    248250                        osm = getNearestWay(p);
     251                }
    249252                return osm;
    250253        }
     
    258261                        return Collections.emptySet();
    259262                return Collections.singleton(osm);
    260         }
    261 
    262         @Deprecated
    263         public OsmPrimitive getNearest(Point p, boolean segmentInsteadWay) {
    264                 return getNearest(p);
    265263        }
    266264
     
    290288                                double b = p.distanceSq(A);
    291289                                double perDist = a-(a-b+c)*(a-b+c)/4/c; // perpendicular distance squared
    292                                 if (perDist < 100 && a < c+100 && b < c+100) {
     290                                if (perDist < snapDistance && a < c+snapDistance && b < c+snapDistance) {
    293291                                        nearest.add(w);
    294292                                                break;
     
    299297                for (Node n : Main.ds.nodes) {
    300298                        if (!n.deleted && !n.incomplete
    301                                         && getPoint(n.eastNorth).distanceSq(p) < 100) {
     299                                        && getPoint(n.eastNorth).distanceSq(p) < snapDistance) {
    302300                                nearest.add(n);
    303301                        }
     
    318316                for (Node n : Main.ds.nodes) {
    319317                        if (!n.deleted && !n.incomplete
    320                                         && getPoint(n.eastNorth).distanceSq(p) < 100) {
     318                                        && getPoint(n.eastNorth).distanceSq(p) < snapDistance) {
    321319                                nearest.add(n);
    322320                        }
  • trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java

    r804 r805  
    148148        @Override public void paint(final Graphics g, final MapView mv) {
    149149                boolean inactive = Main.map.mapView.getActiveLayer() != this && Main.pref.getBoolean("draw.data.inactive_color", true);
     150                boolean virtual = !inactive && Main.map.mapView.useVirtualNodes();
    150151                if (Main.pref.getBoolean("draw.data.downloaded_area", true)) {
    151152                        // FIXME this is inefficient; instead a proper polygon has to be built, and instead
     
    169170                        wireframeMapPainter.setNavigatableComponent(mv);
    170171                        wireframeMapPainter.inactive = inactive;
    171                         wireframeMapPainter.visitAll(data);
     172                        wireframeMapPainter.visitAll(data, virtual);
    172173                }
    173174                else
     
    176177                        standardMapPainter.setNavigatableComponent(mv);
    177178                        standardMapPainter.inactive = inactive;
    178                         standardMapPainter.visitAll(data);
     179                        standardMapPainter.visitAll(data, virtual);
    179180                }
    180181                Main.map.conflictDialog.paintConflicts(g, mv);
  • trunk/src/org/openstreetmap/josm/gui/preferences/DrawingPreference.java

    r781 r805  
    2727        private JCheckBox segmentOrderNumber = new JCheckBox(tr("Draw segment order numbers"));
    2828        private JCheckBox sourceBounds = new JCheckBox(tr("Draw boundaries of downloaded data"));
     29        private JCheckBox virtualNodes = new JCheckBox(tr("Draw virtual nodes in select mode"));
    2930        private JCheckBox inactive = new JCheckBox(tr("Draw inactive layers in other color"));
    3031        private JCheckBox useAntialiasing = new JCheckBox(tr("Smooth map graphics (antialiasing)"));
     
    121122                sourceBounds.setSelected(Main.pref.getBoolean("draw.data.downloaded_area", true));
    122123                gui.display.add(sourceBounds, GBC.eop().insets(20,0,0,0));
    123                
     124
     125                // virtual nodes
     126                virtualNodes.setToolTipText(tr("Draw virtual nodes in select mode for easy way modification."));
     127                virtualNodes.setSelected(Main.pref.getInteger("mappaint.node.virtual-size", 4) != 0);
     128                gui.display.add(virtualNodes, GBC.eop().insets(20,0,0,0));
     129
    124130                // background layers in inactive color
    125131                inactive.setToolTipText(tr("Draw the inactive data layers in a different color."));
     
    142148                Main.pref.put("draw.data.inactive_color", inactive.isSelected());
    143149                Main.pref.put("mappaint.use-antialiasing", useAntialiasing.isSelected());
     150                Main.pref.put("mappaint.node.virtual-size", virtualNodes.isSelected() ? "4" : "0");
    144151    }
    145152}
Note: See TracChangeset for help on using the changeset viewer.