Changeset 805 in josm


Ignore:
Timestamp:
Aug 18, 2008 1:27:58 AM (5 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.