Changeset 9684 in osm


Ignore:
Timestamp:
2008-08-11T22:26:25+02:00 (16 years ago)
Author:
stoecker
Message:

cleanup a lot, ignore errors is now numeric

Location:
applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator
Files:
16 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/OSMValidatorPlugin.java

    r9269 r9684  
    2323
    2424/**
    25  * 
     25 *
    2626 * A OSM data validator
    27  * 
     27 *
    2828 * @author Francisco R. Santos <frsantos@gmail.com>
    2929 */
    3030public class OSMValidatorPlugin extends Plugin implements LayerChangeListener
    3131{
    32     /** The validate action */
    33     ValidateAction validateAction = new ValidateAction(this);
    34    
    35     /** The validation dialog */
    36     ValidatorDialog validationDialog;
    37    
    38     /** The list of errors per layer*/
    39     Map<Layer, List<TestError>> layerErrors = new HashMap<Layer, List<TestError>>();
     32        /** The validate action */
     33        ValidateAction validateAction = new ValidateAction(this);
     34
     35        /** The validation dialog */
     36        ValidatorDialog validationDialog;
     37
     38        /** The list of errors per layer*/
     39        Map<Layer, List<TestError>> layerErrors = new HashMap<Layer, List<TestError>>();
    4040
    4141        /**
     
    4545        public static Class[] allAvailableTests = new Class[]
    4646        {
    47                 DuplicateNode.class,
    48                 OverlappingWays.class,
    49                 UntaggedNode.class,
    50                 UntaggedWay.class,
    51                 SelfIntersectingWay.class,
    52                 DuplicatedWayNodes.class,
    53                 CrossingWays.class,
    54                 SimilarNamedWays.class,
    55                 NodesWithSameName.class,
    56                 Coastlines.class,
    57                 WronglyOrderedWays.class,
    58                 UnclosedWays.class,
    59                 TagChecker.class,
     47                DuplicateNode.class,       // ID    1 ..   99
     48                OverlappingWays.class,     // ID  101 ..  199
     49                UntaggedNode.class,        // ID  201 ..  299
     50                UntaggedWay.class,         // ID  301 ..  399
     51                SelfIntersectingWay.class, // ID  401 ..  499
     52                DuplicatedWayNodes.class,  // ID  501 ..  599
     53                CrossingWays.class,        // ID  601 ..  699
     54                SimilarNamedWays.class,    // ID  701 ..  799
     55                NodesWithSameName.class,   // ID  801 ..  899
     56                Coastlines.class,          // ID  901 ..  999
     57                WronglyOrderedWays.class,  // ID 1001 .. 1099
     58                UnclosedWays.class,        // ID 1101 .. 1199
     59                TagChecker.class,          // ID 1201 .. 1299
    6060        };
    6161
     
    7070
    7171        @Override
    72         public PreferenceSetting getPreferenceSetting() 
     72        public PreferenceSetting getPreferenceSetting()
    7373        {
    7474                return new PreferenceEditor(this);
     
    7676
    7777        @Override
    78         public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) 
     78        public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame)
    7979        {
    8080                if (newFrame != null)
    8181                {
    82                     validationDialog = new ValidatorDialog(this);
    83                 newFrame.addToggleDialog(validationDialog);
    84             Main.main.addLayer(new ErrorLayer(this));
    85                 if( Main.pref.hasKey(PreferenceEditor.PREF_DEBUG + ".grid") )
    86                         Main.main.addLayer(new GridLayer(tr("Grid")));
    87             Layer.listeners.add(this);
     82                        validationDialog = new ValidatorDialog(this);
     83                        newFrame.addToggleDialog(validationDialog);
     84                        Main.main.addLayer(new ErrorLayer(this));
     85                        if( Main.pref.hasKey(PreferenceEditor.PREF_DEBUG + ".grid") )
     86                                Main.main.addLayer(new GridLayer(tr("Grid")));
     87                        Layer.listeners.add(this);
    8888                }
    8989                else
    90             Layer.listeners.remove(this);
    91        
     90                        Layer.listeners.remove(this);
     91
    9292                LinkedList<UploadHook> hooks = ((UploadAction)Main.main.menu.upload).uploadHooks;
    93                 Iterator<UploadHook> hooksIt = hooks.iterator(); 
     93                Iterator<UploadHook> hooksIt = hooks.iterator();
    9494                while( hooksIt.hasNext() )
    9595                {
     
    161161        }
    162162
    163     /**
    164     * Gets the list of all available test classes
    165      *
    166      * @return An array of the test classes             validationDialog.tree.setErrorList(errors);
    167     */
    168     public static Class[] getAllAvailableTests()
    169     {
    170         return allAvailableTests;
    171     }
    172    
     163        /**
     164        * Gets the list of all available test classes
     165         *
     166         * @return An array of the test classes
     167        */
     168        public static Class[] getAllAvailableTests()
     169        {
     170                return allAvailableTests;
     171        }
     172
    173173        /**
    174174         * Initializes all tests
     
    185185                                        test.getClass().getMethod("initialize", new Class[] { OSMValidatorPlugin.class} ).invoke(null, new Object[] {this});
    186186                                }
    187                         }
    188             catch(InvocationTargetException ite)
    189             {
    190                 ite.getCause().printStackTrace();
    191                 JOptionPane.showMessageDialog(null, tr("Error initializing test {0}:\n {1}", test.getClass().getSimpleName(), ite.getCause().getMessage()));
    192             }
    193             catch(Exception e)
    194             {
    195                 e.printStackTrace();
    196                 JOptionPane.showMessageDialog(null, tr("Error initializing test {0}:\n {1}", test.getClass().getSimpleName(), e));
    197             }
    198                 }
    199         }
    200        
    201         public void activeLayerChange(Layer oldLayer, Layer newLayer)
     187                        }
     188                        catch(InvocationTargetException ite)
     189                        {
     190                                ite.getCause().printStackTrace();
     191                                JOptionPane.showMessageDialog(null, tr("Error initializing test {0}:\n {1}",
     192                                test.getClass().getSimpleName(), ite.getCause().getMessage()));
     193                        }
     194                        catch(Exception e)
     195                        {
     196                                e.printStackTrace();
     197                                JOptionPane.showMessageDialog(null, tr("Error initializing test {0}:\n {1}",
     198                                test.getClass().getSimpleName(), e));
     199                        }
     200                }
     201        }
     202
     203        public void activeLayerChange(Layer oldLayer, Layer newLayer)
    202204        {
    203205                if( newLayer instanceof OsmDataLayer )
    204206                {
    205                 List<TestError> errors = layerErrors.get(newLayer);
    206                 validationDialog.tree.setErrorList(errors);
    207                         Main.map.repaint();             
    208                 }
    209         }
    210 
    211         public void layerAdded(Layer newLayer) 
     207                        List<TestError> errors = layerErrors.get(newLayer);
     208                        validationDialog.tree.setErrorList(errors);
     209                        Main.map.repaint();
     210                }
     211        }
     212
     213        public void layerAdded(Layer newLayer)
    212214        {
    213215                if( newLayer instanceof OsmDataLayer )
     
    217219        }
    218220
    219         public void layerRemoved(Layer oldLayer) 
     221        public void layerRemoved(Layer oldLayer)
    220222        {
    221223                layerErrors.remove(oldLayer);
  • applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/TestError.java

    r9598 r9684  
    3333        private Test tester;
    3434        /** Internal code used by testers to classify errors */
    35         private int internalCode = -1;
     35        private int code;
    3636        /** If this error is selected */
    3737        private boolean selected;
    38        
     38
    3939        /**
    4040         * Constructors
     
    4444         * @param primitive The affected primitive
    4545         * @param primitives The affected primitives
    46          * @param internalCode The internal code
    47          */
    48         public TestError(Test tester, Severity severity, String message, String description,
     46         * @param code The test error reference code
     47         */
     48        public TestError(Test tester, Severity severity, String message, String description, int code,
    4949                        List<? extends OsmPrimitive> primitives, List<?> highlighted) {
    5050                this.tester = tester;
     
    5454                this.primitives = primitives;
    5555                this.highlighted = highlighted;
    56         }
    57         public TestError(Test tester, Severity severity, String message, List<? extends OsmPrimitive> primitives, List<?> highlighted)
    58         {
    59                 this(tester, severity, message, null, primitives, highlighted);
    60         }
    61         public TestError(Test tester, Severity severity, String message, String description, List<? extends OsmPrimitive> primitives)
    62         {
    63                 this(tester, severity, message, description, primitives, primitives);
    64         }
    65         public TestError(Test tester, Severity severity, String message, List<? extends OsmPrimitive> primitives)
    66         {
    67                 this(tester, severity, message, null, primitives, primitives);
    68         }
    69         public TestError(Test tester, Severity severity, String message, OsmPrimitive primitive)
    70         {
    71                 this(tester, severity, message, null, Collections.singletonList(primitive), Collections.singletonList(primitive));
    72         }
    73         public TestError(Test tester, Severity severity, String message, String description, OsmPrimitive primitive)
    74         {
    75                 this(tester, severity, message, description, Collections.singletonList(primitive));
    76         }
    77         public TestError(Test tester, Severity severity, String message, OsmPrimitive primitive, int internalCode)
    78         {
    79                 this(tester, severity, message, null, primitive);
    80                 this.internalCode = internalCode;
    81         }
    82         public TestError(Test tester, Severity severity, String message, String description, OsmPrimitive primitive, int internalCode)
    83         {
    84                 this(tester, severity, message, description, primitive);
    85                 this.internalCode = internalCode;
     56                this.code = code;
     57        }
     58        public TestError(Test tester, Severity severity, String message, int code, List<? extends OsmPrimitive> primitives, List<?> highlighted)
     59        {
     60                this(tester, severity, message, null, code, primitives, highlighted);
     61        }
     62        public TestError(Test tester, Severity severity, String message, String description, int code, List<? extends OsmPrimitive> primitives)
     63        {
     64                this(tester, severity, message, description, code, primitives, primitives);
     65        }
     66        public TestError(Test tester, Severity severity, String message, int code, List<? extends OsmPrimitive> primitives)
     67        {
     68                this(tester, severity, message, null, code, primitives, primitives);
     69        }
     70        public TestError(Test tester, Severity severity, String message, int code, OsmPrimitive primitive)
     71        {
     72                this(tester, severity, message, null, code, Collections.singletonList(primitive), Collections.singletonList(primitive));
     73        }
     74        public TestError(Test tester, Severity severity, String message, String description, int code, OsmPrimitive primitive)
     75        {
     76                this(tester, severity, message, description, code, Collections.singletonList(primitive));
    8677        }
    8778
     
    10899         * @param message The error message
    109100         */
    110         public void setMessage(String message) 
     101        public void setMessage(String message)
    111102        {
    112103                this.message = message;
    113104        }
    114        
    115         /**
    116          * Gets the list of primitives affected by this error 
     105
     106        /**
     107         * Gets the list of primitives affected by this error
    117108         * @return the list of primitives affected by this error
    118109         */
    119         public List<? extends OsmPrimitive> getPrimitives() 
     110        public List<? extends OsmPrimitive> getPrimitives()
    120111        {
    121112                return primitives;
     
    123114
    124115        /**
    125          * Sets the list of primitives affected by this error 
     116         * Sets the list of primitives affected by this error
    126117         * @param primitives the list of primitives affected by this error
    127118         */
    128119
    129         public void setPrimitives(List<OsmPrimitive> primitives) 
     120        public void setPrimitives(List<OsmPrimitive> primitives)
    130121        {
    131122                this.primitives = primitives;
     
    136127         * @return the severity of this error
    137128         */
    138         public Severity getSeverity() 
     129        public Severity getSeverity()
    139130        {
    140131                return severity;
     
    145136         * @param severity the severity of this error
    146137         */
    147         public void setSeverity(Severity severity) 
     138        public void setSeverity(Severity severity)
    148139        {
    149140                this.severity = severity;
     
    156147        {
    157148                Collection<String> strings = new TreeSet<String>();
    158                 String ignorestring = message;
     149                String ignorestring = Integer.toString(code);
    159150                for (OsmPrimitive o : primitives)
    160151                {
     
    195186
    196187        /**
    197          * Gets the internal code
    198          * @return the internal code
    199          */
    200         public int getInternalCode()
    201         {
    202                 return internalCode;
    203         }
    204 
    205         /**
    206          * Sets the internal code
    207          * @param internalCode The internal code
    208          */
    209         public void setInternalCode(int internalCode)
    210         {
    211                 this.internalCode = internalCode;
    212         }
    213        
     188         * Gets the code
     189         * @return the code
     190         */
     191        public int getCode()
     192        {
     193                return code;
     194        }
     195
    214196        /**
    215197         * Returns true if the error can be fixed automatically
     
    255237        }
    256238
    257     /**
    258     * Visitor that highlights the primitives affected by this error
    259     * @author frsantos
    260     */
    261     class PaintVisitor implements Visitor
    262     {
    263         /** The graphics */
    264         private final Graphics g;
    265         /** The MapView */
    266         private final MapView mv;
    267        
    268         /**
    269          * Constructor
    270          * @param g The graphics
    271         * @param mv The Mapview
    272         */
    273         public PaintVisitor(Graphics g, MapView mv)
    274         {
    275             this.g = g;
    276             this.mv = mv;
    277         }
     239        /**
     240        * Visitor that highlights the primitives affected by this error
     241        * @author frsantos
     242        */
     243        class PaintVisitor implements Visitor
     244        {
     245                /** The graphics */
     246                private final Graphics g;
     247                /** The MapView */
     248                private final MapView mv;
     249
     250                /**
     251                 * Constructor
     252                 * @param g The graphics
     253                * @param mv The Mapview
     254                */
     255                public PaintVisitor(Graphics g, MapView mv)
     256                {
     257                        this.g = g;
     258                        this.mv = mv;
     259                }
    278260
    279261                public void visit(OsmPrimitive p) {
    280             if (!p.deleted && !p.incomplete) {
    281                 p.visit(this);
    282                         }
    283                 }
    284 
    285         /**
    286          * Draws a circle around the node
    287         * @param n The node
    288         * @param color The circle color
    289         */
    290         public void drawNode(Node n, Color color)
    291         {
    292             Point p = mv.getPoint(n.eastNorth);
    293             g.setColor(color);
    294             if( selected )
    295             {
    296                 g.fillOval(p.x-5, p.y-5, 10, 10);
    297             }
    298             else
    299                 g.drawOval(p.x-5, p.y-5, 10, 10);
    300         }
    301 
    302         /**
    303         * Draws a line around the segment
    304          *
    305         * @param s The segment
    306         * @param color The color
    307         */
    308         public void drawSegment(Node n1, Node n2, Color color)
    309         {
    310             Point p1 = mv.getPoint(n1.eastNorth);
    311             Point p2 = mv.getPoint(n2.eastNorth);
    312             g.setColor(color);
    313            
    314             double t = Math.atan2(p2.x-p1.x, p2.y-p1.y);
    315             double cosT = Math.cos(t);
    316             double sinT = Math.sin(t);
    317             int deg = (int)Math.toDegrees(t);
    318             if( selected )
    319             {
    320                 int[] x = new int[] {(int)(p1.x + 5*cosT), (int)(p2.x + 5*cosT), (int)(p2.x - 5*cosT), (int)(p1.x - 5*cosT)};
    321                 int[] y = new int[] {(int)(p1.y - 5*sinT), (int)(p2.y - 5*sinT), (int)(p2.y + 5*sinT), (int)(p1.y + 5*sinT)};
    322                 g.fillPolygon(x, y, 4);
    323                 g.fillArc(p1.x-5, p1.y-5, 10, 10, deg, 180 );
    324                 g.fillArc(p2.x-5, p2.y-5, 10, 10, deg, -180);
    325             }
    326             else
    327             {
    328                 g.drawLine((int)(p1.x + 5*cosT), (int)(p1.y - 5*sinT), (int)(p2.x + 5*cosT), (int)(p2.y - 5*sinT));
    329                 g.drawLine((int)(p1.x - 5*cosT), (int)(p1.y + 5*sinT), (int)(p2.x - 5*cosT), (int)(p2.y + 5*sinT));
    330                 g.drawArc(p1.x-5, p1.y-5, 10, 10, deg, 180 );
    331                 g.drawArc(p2.x-5, p2.y-5, 10, 10, deg, -180);
    332             }
    333         }
    334 
    335        
    336         /**
    337          * Draw a small rectangle.
    338         * White if selected (as always) or red otherwise.
    339          *
    340         * @param n The node to draw.
    341         */
    342         public void visit(Node n)
    343         {
    344             if( isNodeVisible(n) )
    345                 drawNode(n, severity.getColor());
    346         }
    347 
    348         public void visit(Way w)
    349         {
     262                        if (!p.deleted && !p.incomplete) {
     263                                p.visit(this);
     264                        }
     265                }
     266
     267                /**
     268                 * Draws a circle around the node
     269                * @param n The node
     270                * @param color The circle color
     271                */
     272                public void drawNode(Node n, Color color)
     273                {
     274                        Point p = mv.getPoint(n.eastNorth);
     275                        g.setColor(color);
     276                        if( selected )
     277                        {
     278                                g.fillOval(p.x-5, p.y-5, 10, 10);
     279                        }
     280                        else
     281                                g.drawOval(p.x-5, p.y-5, 10, 10);
     282                }
     283
     284                /**
     285                * Draws a line around the segment
     286                 *
     287                * @param s The segment
     288                * @param color The color
     289                */
     290                public void drawSegment(Node n1, Node n2, Color color)
     291                {
     292                        Point p1 = mv.getPoint(n1.eastNorth);
     293                        Point p2 = mv.getPoint(n2.eastNorth);
     294                        g.setColor(color);
     295
     296                        double t = Math.atan2(p2.x-p1.x, p2.y-p1.y);
     297                        double cosT = Math.cos(t);
     298                        double sinT = Math.sin(t);
     299                        int deg = (int)Math.toDegrees(t);
     300                        if( selected )
     301                        {
     302                                int[] x = new int[] {(int)(p1.x + 5*cosT), (int)(p2.x + 5*cosT), (int)(p2.x - 5*cosT), (int)(p1.x - 5*cosT)};
     303                                int[] y = new int[] {(int)(p1.y - 5*sinT), (int)(p2.y - 5*sinT), (int)(p2.y + 5*sinT), (int)(p1.y + 5*sinT)};
     304                                g.fillPolygon(x, y, 4);
     305                                g.fillArc(p1.x-5, p1.y-5, 10, 10, deg, 180 );
     306                                g.fillArc(p2.x-5, p2.y-5, 10, 10, deg, -180);
     307                        }
     308                        else
     309                        {
     310                                g.drawLine((int)(p1.x + 5*cosT), (int)(p1.y - 5*sinT), (int)(p2.x + 5*cosT), (int)(p2.y - 5*sinT));
     311                                g.drawLine((int)(p1.x - 5*cosT), (int)(p1.y + 5*sinT), (int)(p2.x - 5*cosT), (int)(p2.y + 5*sinT));
     312                                g.drawArc(p1.x-5, p1.y-5, 10, 10, deg, 180 );
     313                                g.drawArc(p2.x-5, p2.y-5, 10, 10, deg, -180);
     314                        }
     315                }
     316
     317
     318                /**
     319                 * Draw a small rectangle.
     320                * White if selected (as always) or red otherwise.
     321                 *
     322                * @param n The node to draw.
     323                */
     324                public void visit(Node n)
     325                {
     326                        if( isNodeVisible(n) )
     327                                drawNode(n, severity.getColor());
     328                }
     329
     330                public void visit(Way w)
     331                {
    350332                        Node lastN = null;
    351333                        for (Node n : w.nodes) {
     
    354336                                        continue;
    355337                                }
    356                 if (isSegmentVisible(lastN, n))
    357                 {
    358                     drawSegment(lastN, n, severity.getColor());
    359                 }
     338                                if (isSegmentVisible(lastN, n))
     339                                {
     340                                        drawSegment(lastN, n, severity.getColor());
     341                                }
    360342                                lastN = n;
    361343                        }
    362         }
     344                }
    363345
    364346                public void visit(WaySegment ws) {
     
    375357                        /* No idea how to draw a relation. */
    376358                }
    377        
    378         /**
    379         * Checks if the given node is in the visible area.
    380         * @param n The node to check for visibility
    381         * @return true if the node is visible
    382         */
    383         protected boolean isNodeVisible(Node n) {
    384             Point p = mv.getPoint(n.eastNorth);
    385             return !((p.x < 0) || (p.y < 0) || (p.x > mv.getWidth()) || (p.y > mv.getHeight()));
    386         }
    387 
    388         /**
    389         * Checks if the given segment is in the visible area.
    390         * NOTE: This will return true for a small number of non-visible
    391          *      segments.
    392         * @param ls The segment to check
    393         * @return true if the segment is visible
    394         */
    395         protected boolean isSegmentVisible(Node n1, Node n2) {
    396             Point p1 = mv.getPoint(n1.eastNorth);
    397             Point p2 = mv.getPoint(n2.eastNorth);
    398             if ((p1.x < 0) && (p2.x < 0)) return false;
    399             if ((p1.y < 0) && (p2.y < 0)) return false;
    400             if ((p1.x > mv.getWidth()) && (p2.x > mv.getWidth())) return false;
    401             if ((p1.y > mv.getHeight()) && (p2.y > mv.getHeight())) return false;
    402             return true;
    403         }
    404     }
    405 
    406     /**
    407     * Sets the selection flag of this error
    408     * @param selected if this error is selected
    409     */
    410     public void setSelected(boolean selected)
    411     {
    412         this.selected = selected;
    413     }
     359
     360                /**
     361                * Checks if the given node is in the visible area.
     362                * @param n The node to check for visibility
     363                * @return true if the node is visible
     364                */
     365                protected boolean isNodeVisible(Node n) {
     366                        Point p = mv.getPoint(n.eastNorth);
     367                        return !((p.x < 0) || (p.y < 0) || (p.x > mv.getWidth()) || (p.y > mv.getHeight()));
     368                }
     369
     370                /**
     371                * Checks if the given segment is in the visible area.
     372                * NOTE: This will return true for a small number of non-visible
     373                 *              segments.
     374                * @param ls The segment to check
     375                * @return true if the segment is visible
     376                */
     377                protected boolean isSegmentVisible(Node n1, Node n2) {
     378                        Point p1 = mv.getPoint(n1.eastNorth);
     379                        Point p2 = mv.getPoint(n2.eastNorth);
     380                        if ((p1.x < 0) && (p2.x < 0)) return false;
     381                        if ((p1.y < 0) && (p2.y < 0)) return false;
     382                        if ((p1.x > mv.getWidth()) && (p2.x > mv.getWidth())) return false;
     383                        if ((p1.y > mv.getHeight()) && (p2.y > mv.getHeight())) return false;
     384                        return true;
     385                }
     386        }
     387
     388        /**
     389        * Sets the selection flag of this error
     390        * @param selected if this error is selected
     391        */
     392        public void setSelected(boolean selected)
     393        {
     394                this.selected = selected;
     395        }
    414396}
  • applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/Coastlines.java

    r5583 r9684  
    1616/**
    1717 * Check coastlines for errors
    18  * 
     18 *
    1919 * @author frsantos
    2020 */
    21 public class Coastlines extends Test 
     21public class Coastlines extends Test
    2222{
    23     /** All ways, grouped by cells */
    24     Map<Point2D,List<Way>> _cellWays;
    25     /** The already detected errors */
    26     Bag<Way, Way> _errorWays;
     23        protected static int UNORDERED_COASTLINES = 901;
     24
     25        /** All ways, grouped by cells */
     26        Map<Point2D,List<Way>> _cellWays;
     27        /** The already detected errors */
     28        Bag<Way, Way> _errorWays;
    2729
    2830        /**
    2931         * Constructor
    3032         */
    31         public Coastlines() 
     33        public Coastlines()
    3234        {
    3335                super(tr("Coastlines."),
     
    3537        }
    3638
    37     @Override
    38     public void startTest()
    39     {
    40         _cellWays = new HashMap<Point2D,List<Way>>(1000);
    41         _errorWays = new Bag<Way, Way>();
    42     }
     39        @Override
     40        public void startTest()
     41        {
     42                _cellWays = new HashMap<Point2D,List<Way>>(1000);
     43                _errorWays = new Bag<Way, Way>();
     44        }
    4345
    44     @Override
    45     public void endTest()
    46     {
    47         _cellWays = null;
    48         _errorWays = null;
    49     }
    50    
    5146        @Override
    52         public void visit(Way w)
     47        public void endTest()
    5348        {
    54         if( w.deleted || w.incomplete )
    55             return;
    56        
    57         String natural = w.get("natural");
    58         if( natural == null || !natural.equals("coastline") )
    59             return;
    60        
    61         List<List<Way>> cellWays = Util.getWaysInCell(w, _cellWays);
    62         for( List<Way> ways : cellWays)
    63         {
    64             for( Way w2 : ways)
    65             {
    66                 if( _errorWays.contains(w, w2) || _errorWays.contains(w2, w) )
    67                         continue;
    68                
    69                 String natural2 = w.get("natural");
    70                 if( natural2 == null || !natural2.equals("coastline") )
    71                     continue;
    72                
    73                 if( w.nodes.get(0).equals(w2.nodes.get(0)) || w.nodes.get(w.nodes.size() - 1).equals(w2.nodes.get(w2.nodes.size() - 1)))
    74                 {
    75                     List<OsmPrimitive> primitives = new ArrayList<OsmPrimitive>();
    76                     primitives.add(w);
    77                     primitives.add(w2);
    78                     errors.add( new TestError(this, Severity.ERROR, tr("Unordered coastline"), primitives) );
    79                     _errorWays.add(w, w2);
    80                 }
    81             }
    82             ways.add(w);
    83         }
     49                _cellWays = null;
     50                _errorWays = null;
     51        }
     52
     53        @Override
     54        public void visit(Way w)
     55        {
     56                if( w.deleted || w.incomplete )
     57                        return;
     58
     59                String natural = w.get("natural");
     60                if( natural == null || !natural.equals("coastline") )
     61                        return;
     62
     63                List<List<Way>> cellWays = Util.getWaysInCell(w, _cellWays);
     64                for( List<Way> ways : cellWays)
     65                {
     66                        for( Way w2 : ways)
     67                        {
     68                                if( _errorWays.contains(w, w2) || _errorWays.contains(w2, w) )
     69                                        continue;
     70
     71                                String natural2 = w.get("natural");
     72                                if( natural2 == null || !natural2.equals("coastline") )
     73                                        continue;
     74
     75                                if( w.nodes.get(0).equals(w2.nodes.get(0)) || w.nodes.get(w.nodes.size() - 1).equals(w2.nodes.get(w2.nodes.size() - 1)))
     76                                {
     77                                        List<OsmPrimitive> primitives = new ArrayList<OsmPrimitive>();
     78                                        primitives.add(w);
     79                                        primitives.add(w2);
     80                                        errors.add( new TestError(this, Severity.ERROR, tr("Unordered coastline"), UNORDERED_COASTLINES, primitives) );
     81                                        _errorWays.add(w, w2);
     82                                }
     83                        }
     84                        ways.add(w);
     85                }
    8486        }
    8587}
  • applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/CrossingWays.java

    r8692 r9684  
    1414/**
    1515 * Tests if there are segments that crosses in the same layer
    16  * 
     16 *
    1717 * @author frsantos
    1818 */
    19 public class CrossingWays extends Test 
     19public class CrossingWays extends Test
    2020{
     21        protected static int CROSSING_WAYS = 601;
     22
    2123        /** All way segments, grouped by cells */
    2224        Map<Point2D,List<ExtendedSegment>> cellSegments;
     
    2628        Map<List<Way>, List<WaySegment>> ways_seen;
    2729
    28        
     30
    2931        /**
    3032         * Constructor
    3133         */
    32         public CrossingWays() 
     34        public CrossingWays()
    3335        {
    3436                super(tr("Crossing ways."),
     
    3840
    3941        @Override
    40         public void startTest() 
     42        public void startTest()
    4143        {
    4244                cellSegments = new HashMap<Point2D,List<ExtendedSegment>>(1000);
     
    4648
    4749        @Override
    48         public void endTest() 
     50        public void endTest()
    4951        {
    5052                cellSegments = null;
     
    5456
    5557        @Override
    56         public void visit(Way w) 
     58        public void visit(Way w)
    5759        {
    5860                if( w.deleted || w.incomplete )
    5961                        return;
    6062
    61                 String coastline1 = w.get("natural"); 
     63                String coastline1 = w.get("natural");
    6264                boolean isCoastline1 = coastline1 != null && (coastline1.equals("water") || coastline1.equals("coastline"));
    63                 String railway1 = w.get("railway"); 
     65                String railway1 = w.get("railway");
    6466                boolean isSubway1 = railway1 != null && railway1.equals("subway");
    65                 if( w.get("highway") == null && w.get("waterway") == null && (railway1 == null || isSubway1)  && !isCoastline1) 
     67                if( w.get("highway") == null && w.get("waterway") == null && (railway1 == null || isSubway1)  && !isCoastline1)
    6668                        return;
    6769
    68                 String layer1 = w.get("layer");
     70                String layer1 = w.get("layer");
    6971
    7072                int nodesSize = w.nodes.size();
     
    102104                                                highlight.add(es2.ws);
    103105
    104                                                 errors.add(new TestError(this, Severity.WARNING, tr("Crossing ways"),
    105                                                 prims,
    106                                                 highlight));
     106                                                errors.add(new TestError(this, Severity.WARNING,
     107                                                tr("Crossing ways"), CROSSING_WAYS, prims, highlight));
    107108                                                ways_seen.put(prims, highlight);
    108109                                        }
     
    131132                for( Point2D cell : Util.getSegmentCells(n1, n2, 10000) )
    132133                {
    133             List<ExtendedSegment> segments = cellSegments.get( cell );
    134             if( segments == null )
    135             {
    136                 segments = new ArrayList<ExtendedSegment>();
    137                 cellSegments.put(cell, segments);
    138             }
    139             cells.add(segments);
    140         }
    141        
     134                        List<ExtendedSegment> segments = cellSegments.get( cell );
     135                        if( segments == null )
     136                        {
     137                                segments = new ArrayList<ExtendedSegment>();
     138                                cellSegments.put(cell, segments);
     139                        }
     140                        cells.add(segments);
     141                }
     142
    142143                return cells;
    143144        }
    144    
    145     /**
    146     * A way segment with some additional information
    147     * @author frsantos
    148     */
    149     private class ExtendedSegment
    150     {
     145
     146        /**
     147        * A way segment with some additional information
     148        * @author frsantos
     149        */
     150        private class ExtendedSegment
     151        {
    151152                public Node n1, n2;
    152153
    153154                public WaySegment ws;
    154        
    155         /** The layer */
    156         public String layer;
    157        
    158         /** The railway type */
     155
     156                /** The layer */
     157                public String layer;
     158
     159                /** The railway type */
    159160                public String railway;
    160161
    161162                /** The coastline type */
    162163                public String coastline;
    163        
    164         /**
    165         * Constructor
    166         * @param ws The way segment
    167         * @param layer The layer of the way this segment is in
    168         * @param railway The railway type of the way this segment is in
    169         * @param coastline The coastlyne typo of the way the segment is in
    170         */
    171         public ExtendedSegment(WaySegment ws, String layer, String railway, String coastline)
    172         {
    173             this.ws = ws;
     164
     165                /**
     166                * Constructor
     167                * @param ws The way segment
     168                * @param layer The layer of the way this segment is in
     169                * @param railway The railway type of the way this segment is in
     170                * @param coastline The coastlyne typo of the way the segment is in
     171                */
     172                public ExtendedSegment(WaySegment ws, String layer, String railway, String coastline)
     173                {
     174                        this.ws = ws;
    174175                        this.n1 = ws.way.nodes.get(ws.lowerIndex);
    175176                        this.n2 = ws.way.nodes.get(ws.lowerIndex + 1);
    176             this.layer = layer;
    177             this.railway = railway;
    178             this.coastline = coastline;
    179         }
    180        
    181         /**
    182         * Checks whether this segment crosses other segment
    183         * @param s2 The other segment
    184         * @return true if both segements crosses
    185         */
    186         public boolean intersects(ExtendedSegment s2)
    187         {
    188                         if( n1.equals(s2.n1) || n2.equals(s2.n2) || 
    189                         n1.equals(s2.n2)   || n2.equals(s2.n1) )
    190                 {
    191                 return false;
    192                 }
    193            
    194                 return Line2D.linesIntersect(
     177                        this.layer = layer;
     178                        this.railway = railway;
     179                        this.coastline = coastline;
     180                }
     181
     182                /**
     183                * Checks whether this segment crosses other segment
     184                * @param s2 The other segment
     185                * @return true if both segements crosses
     186                */
     187                public boolean intersects(ExtendedSegment s2)
     188                {
     189                        if( n1.equals(s2.n1) || n2.equals(s2.n2) ||
     190                                n1.equals(s2.n2)   || n2.equals(s2.n1) )
     191                        {
     192                                return false;
     193                        }
     194
     195                        return Line2D.linesIntersect(
    195196                                n1.eastNorth.east(), n1.eastNorth.north(),
    196197                                n2.eastNorth.east(), n2.eastNorth.north(),
    197198                                s2.n1.eastNorth.east(), s2.n1.eastNorth.north(),
    198199                                s2.n2.eastNorth.east(), s2.n2.eastNorth.north());
    199         }
    200     }
     200                }
     201        }
    201202}
  • applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/DuplicateNode.java

    r8769 r9684  
    1717/**
    1818 * Tests if there are duplicate nodes
    19  * 
     19 *
    2020 * @author frsantos
    2121 */
    22 public class DuplicateNode extends Test 
     22public class DuplicateNode extends Test
    2323{
     24        protected static int DUPLICATE_NODE = 1;
     25
    2426        /** Bag of all nodes */
    2527        Bag<LatLon, OsmPrimitive> nodes;
    26        
     28
    2729        /**
    2830         * Constructor
    2931         */
    30         public DuplicateNode() 
     32        public DuplicateNode()
    3133        {
    3234                super(tr("Duplicated nodes."),
     
    3638
    3739        @Override
    38         public void startTest() 
     40        public void startTest()
    3941        {
    4042                nodes = new Bag<LatLon, OsmPrimitive>(1000);
     
    4244
    4345        @Override
    44         public void endTest() 
     46        public void endTest()
    4547        {
    4648                for(List<OsmPrimitive> duplicated : nodes.values() )
     
    4850                        if( duplicated.size() > 1)
    4951                        {
    50                                 TestError testError = new TestError(this, Severity.ERROR, tr("Duplicated nodes"), duplicated);
     52                                TestError testError = new TestError(this, Severity.ERROR, tr("Duplicated nodes"), DUPLICATE_NODE, duplicated);
    5153                                errors.add( testError );
    5254                        }
     
    5658
    5759        @Override
    58         public void visit(Node n) 
     60        public void visit(Node n)
    5961        {
    6062                if(!n.deleted && !n.incomplete)
    6163                        nodes.add(n.coor, n);
    6264        }
    63        
    64     /**
    65     * Merge the nodes into one.
    66     * Copied from UtilsPlugin.MergePointsAction
    67     */
     65
     66        /**
     67        * Merge the nodes into one.
     68        * Copied from UtilsPlugin.MergePointsAction
     69        */
    6870        @Override
    6971        public Command fixError(TestError testError)
    7072        {
    71         Collection<? extends OsmPrimitive> sel = testError.getPrimitives();
    72         Collection<OsmPrimitive> nodes = new ArrayList<OsmPrimitive>();
    73        
    74         Node target = null;
    75         for (OsmPrimitive osm : sel)
    76             nodes.add(osm);
    77        
    78         if( nodes.size() < 2 )
    79             return null;
    80        
    81         for ( OsmPrimitive o : nodes )
    82         {
    83             Node n = (Node)o;
    84             if( target == null || target.id == 0 )
    85             {
    86                 target = n;
    87                 continue;
    88             }
    89             if( n.id == 0 )
    90                 continue;
    91             if( n.id < target.id )
    92                 target = n;
    93         }
    94         if( target == null )
    95             return null;
    96        
    97         // target is what we're merging into
    98         // nodes is the list of nodes to be removed
    99         nodes.remove(target);
    100        
    101         // Merge all properties
    102         Node newtarget = new Node(target);
    103         for (final OsmPrimitive o : nodes)
    104         {
    105             Node n = (Node)o;
    106             for ( String key : n.keySet() )
    107             {
    108                 if( newtarget.keySet().contains(key) && !newtarget.get(key).equals(n.get(key)) )
    109                 {
    110                     JOptionPane.showMessageDialog(Main.parent, tr("Nodes have conflicting key: " + key + " ["+newtarget.get(key)+", "+n.get(key)+"]"));
    111                     return null;
    112                 }
    113                 newtarget.put( key, n.get(key) );
    114             }
    115         }       
     73                Collection<? extends OsmPrimitive> sel = testError.getPrimitives();
     74                Collection<OsmPrimitive> nodes = new ArrayList<OsmPrimitive>();
    11675
    117         Collection<Command> cmds = new LinkedList<Command>();
     76                Node target = null;
     77                for (OsmPrimitive osm : sel)
     78                        nodes.add(osm);
     79
     80                if( nodes.size() < 2 )
     81                        return null;
     82
     83                for ( OsmPrimitive o : nodes )
     84                {
     85                        Node n = (Node)o;
     86                        if( target == null || target.id == 0 )
     87                        {
     88                                target = n;
     89                                continue;
     90                        }
     91                        if( n.id == 0 )
     92                                continue;
     93                        if( n.id < target.id )
     94                                target = n;
     95                }
     96                if( target == null )
     97                        return null;
     98
     99                // target is what we're merging into
     100                // nodes is the list of nodes to be removed
     101                nodes.remove(target);
     102
     103                // Merge all properties
     104                Node newtarget = new Node(target);
     105                for (final OsmPrimitive o : nodes)
     106                {
     107                        Node n = (Node)o;
     108                        for ( String key : n.keySet() )
     109                        {
     110                                if( newtarget.keySet().contains(key) && !newtarget.get(key).equals(n.get(key)) )
     111                                {
     112                                        JOptionPane.showMessageDialog(Main.parent, tr("Nodes have conflicting key: {0} [{1}, {2}]",
     113                                        key, newtarget.get(key), n.get(key)));
     114                                        return null;
     115                                }
     116                                newtarget.put( key, n.get(key) );
     117                        }
     118                }
     119
     120                Collection<Command> cmds = new LinkedList<Command>();
    118121
    119122                // Now search the ways for occurences of the nodes we are about to
     
    135138                }
    136139
    137         cmds.add(new DeleteCommand(nodes));
    138         cmds.add(new ChangeCommand(target, newtarget));
    139         return new SequenceCommand(tr("Merge Nodes"), cmds);
     140                cmds.add(new DeleteCommand(nodes));
     141                cmds.add(new ChangeCommand(target, newtarget));
     142                return new SequenceCommand(tr("Merge Nodes"), cmds);
    140143        }
    141        
     144
    142145        @Override
    143146        public boolean isFixable(TestError testError)
    144147        {
    145148                return (testError.getTester() instanceof DuplicateNode);
    146         }       
     149        }
    147150}
  • applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/DuplicatedWayNodes.java

    r6302 r9684  
    11package org.openstreetmap.josm.plugins.validator.tests;
     2
    23import static org.openstreetmap.josm.tools.I18n.tr;
     4
    35import org.openstreetmap.josm.plugins.validator.Test;
    46import org.openstreetmap.josm.plugins.validator.TestError;
     
    1416
    1517public class DuplicatedWayNodes extends Test {
     18        protected static int DUPLICATE_WAY_NODE = 501;
     19
    1620        public DuplicatedWayNodes() {
    1721                super(tr("Duplicated way nodes."),
     
    2933                        }
    3034                        if (lastN == n) {
    31                                 errors.add(new TestError(this, Severity.ERROR, tr("Duplicated way nodes"),
     35                                errors.add(new TestError(this, Severity.ERROR, tr("Duplicated way nodes"), DUPLICATE_WAY_NODE,
    3236                                        Arrays.asList(w), Arrays.asList(n)));
    3337                                break;
  • applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/NodesWithSameName.java

    r6557 r9684  
    1414
    1515public class NodesWithSameName extends Test {
     16        protected static int SAME_NAME = 801;
     17
    1618        private Map<String, List<Node>> namesToNodes;
    1719
    1820        public NodesWithSameName() {
    1921                super(tr("Nodes with same name"),
    20                         tr("Find nodes that have the same name " +
    21                                 "(might be duplicates due to e.g. the OpenGeoDB import)"));
     22                        tr("Find nodes that have the same name (might be duplicates)"));
    2223        }
    2324
     
    4344                        if (nodes.size() > 1) {
    4445                                errors.add(new TestError(this, Severity.WARNING,
    45                                         tr("Nodes with same name"), nodes));
     46                                        tr("Nodes with same name"), SAME_NAME, nodes));
    4647                        }
    4748                }
  • applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/OverlappingWays.java

    r9598 r9684  
    2222 * @author frsantos
    2323 */
    24 public class OverlappingWays extends Test 
     24public class OverlappingWays extends Test
    2525{
    2626        /** Bag of all way segments */
    2727        Bag<Pair<Node,Node>, WaySegment> nodePairs;
    28        
    29         /**
    30          * Constructor
    31          */
    32         public OverlappingWays()
     28
     29        protected static int OVERLAPPING_HIGHWAY = 101;
     30        protected static int OVERLAPPING_RAILWAY = 102;
     31        protected static int OVERLAPPING_WAY = 103;
     32        protected static int OVERLAPPING_HIGHWAY_AREA = 111;
     33        protected static int OVERLAPPING_RAILWAY_AREA = 112;
     34        protected static int OVERLAPPING_WAY_AREA = 113;
     35        protected static int OVERLAPPING_AREA = 120;
     36
     37        /** Constructor */
     38        public OverlappingWays()
    3339        {
    3440                super(tr("Overlapping ways."),
     
    4652
    4753        @Override
    48         public void endTest() 
     54        public void endTest()
    4955        {
    50                 Map<List<Way>, List<WaySegment>> ways_seen =
    51                         new HashMap<List<Way>, List<WaySegment>>(500);
     56                Map<List<Way>, List<WaySegment>> ways_seen = new HashMap<List<Way>, List<WaySegment>>(500);
    5257
    5358                for (List<WaySegment> duplicated : nodePairs.values())
     
    8489                                /* These ways not seen before
    8590                                 * If two or more of the overlapping ways are
    86                                  * highways or railways mark a seperate error
    87                                 */
     91                                 * highways or railways mark a seperate error
     92                                 */
    8893                                if ((highlight = ways_seen.get(current_ways)) == null)
    89                                 {
     94                                {
    9095                                        String errortype;
     96                                        int type;
    9197
    9298                                        if(area > 0)
    9399                                        {
    94100                                                if (ways == 0 || duplicated.size() == area)
     101                                                {
    95102                                                        errortype = tr("Overlapping areas");
     103                                                        type = OVERLAPPING_AREA;
     104                                                }
    96105                                                else if (highway == ways)
     106                                                {
    97107                                                        errortype = tr("Overlapping highways (with area)");
     108                                                        type = OVERLAPPING_HIGHWAY_AREA;
     109                                                }
    98110                                                else if (railway == ways)
     111                                                {
    99112                                                        errortype = tr("Overlapping railways (with area)");
     113                                                        type = OVERLAPPING_RAILWAY_AREA;
     114                                                }
    100115                                                else
     116                                                {
    101117                                                        errortype = tr("Overlapping ways (with area)");
     118                                                        type = OVERLAPPING_WAY_AREA;
     119                                                }
    102120                                        }
    103121                                        else if (highway == ways)
     122                                        {
    104123                                                errortype = tr("Overlapping highways");
     124                                                type = OVERLAPPING_HIGHWAY;
     125                                        }
    105126                                        else if (railway == ways)
     127                                        {
    106128                                                errortype = tr("Overlapping railways");
     129                                                type = OVERLAPPING_RAILWAY;
     130                                        }
    107131                                        else
     132                                        {
    108133                                                errortype = tr("Overlapping ways");
     134                                                type = OVERLAPPING_WAY;
     135                                        }
    109136
    110                                         errors.add(new TestError(this, Severity.OTHER, tr(errortype), prims, duplicated));
     137                                        errors.add(new TestError(this, Severity.OTHER, tr(errortype), type, prims, duplicated));
    111138                                        ways_seen.put(current_ways, duplicated);
    112139                                }
     
    122149
    123150        @Override
    124         public void visit(Way w) 
     151        public void visit(Way w)
    125152        {
    126153                Node lastN = null;
  • applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/SelfIntersectingWay.java

    r6302 r9684  
    1616 */
    1717public class SelfIntersectingWay extends Test {
     18        protected static int SELF_INTERSECT = 401;
     19
    1820        public SelfIntersectingWay() {
    1921                super(tr("Self-intersecting ways"),
     
    2931                        if (nodes.contains(n)) {
    3032                                errors.add(new TestError(this,
    31                                         Severity.WARNING, tr("Self-intersecting ways"),
     33                                        Severity.WARNING, tr("Self-intersecting ways"), SELF_INTERSECT,
    3234                                        Arrays.asList(w), Arrays.asList(n)));
    3335                                break;
     
    3638                        }
    3739                }
    38         }               
     40        }
    3941}
  • applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/SimilarNamedWays.java

    r5583 r9684  
    1313import org.openstreetmap.josm.plugins.validator.util.Bag;
    1414import org.openstreetmap.josm.plugins.validator.util.Util;
     15
    1516/**
    1617 * Checks for similar named ways, symptom of a possible typo. It uses the
    1718 * Levenshtein distance to check for similarity
    18  * 
     19 *
    1920 * @author frsantos
    2021 */
    21 public class SimilarNamedWays extends Test 
     22public class SimilarNamedWays extends Test
    2223{
    23     /** All ways, grouped by cells */
    24     Map<Point2D,List<Way>> cellWays;
    25     /** The already detected errors */
    26     Bag<Way, Way> errorWays;
    27    
    28     /**
     24        protected static int SIMILAR_NAMED = 701;
     25
     26        /** All ways, grouped by cells */
     27        Map<Point2D,List<Way>> cellWays;
     28        /** The already detected errors */
     29        Bag<Way, Way> errorWays;
     30
     31        /**
    2932         * Constructor
    3033         */
    31         public SimilarNamedWays() 
     34        public SimilarNamedWays()
    3235        {
    3336                super(tr("Similar named ways."),
     
    3538        }
    3639
    37     @Override
    38     public void startTest()
    39     {
    40         cellWays = new HashMap<Point2D,List<Way>>(1000);
    41         errorWays = new Bag<Way, Way>();
    42     }
     40        @Override
     41        public void startTest()
     42        {
     43                cellWays = new HashMap<Point2D,List<Way>>(1000);
     44                errorWays = new Bag<Way, Way>();
     45        }
    4346
    44     @Override
    45     public void endTest()
    46     {
    47         cellWays = null;
    48         errorWays = null;
    49     }
    50    
    5147        @Override
    52         public void visit(Way w)
     48        public void endTest()
    5349        {
    54         if( w.deleted || w.incomplete )
    55             return;
    56        
    57         String name = w.get("name");
    58         if( name == null || name.length() < 6 )
    59             return;
    60        
    61         List<List<Way>> theCellWays = Util.getWaysInCell(w, cellWays);
    62         for( List<Way> ways : theCellWays)
    63         {
    64             for( Way w2 : ways)
    65             {
    66                 if( errorWays.contains(w, w2) || errorWays.contains(w2, w) )
    67                         continue;
    68                
    69                 String name2 = w2.get("name");
    70                 if( name2 == null || name2.length() < 6 )
    71                     continue;
    72                
    73                 int levenshteinDistance = getLevenshteinDistance(name, name2);
    74                 if( 0 < levenshteinDistance && levenshteinDistance <= 2 )
    75                 {
    76                     List<OsmPrimitive> primitives = new ArrayList<OsmPrimitive>();
    77                     primitives.add(w);
    78                     primitives.add(w2);
    79                     errors.add( new TestError(this, Severity.WARNING, tr("Similar named ways"), primitives) );
    80                     errorWays.add(w, w2);
    81                 }
    82             }
    83             ways.add(w);
    84         }
     50                cellWays = null;
     51                errorWays = null;
    8552        }
    86    
    87     /**
    88      * Compute Levenshtein distance
    89      *
    90      * @param s First word
    91      * @param t Second word
    92      * @return The distance between words
    93      */
    94     public int getLevenshteinDistance(String s, String t)
    95     {
    96         int d[][]; // matrix
    97         int n; // length of s
    98         int m; // length of t
    99         int i; // iterates through s
    100         int j; // iterates through t
    101         char s_i; // ith character of s
    102         char t_j; // jth character of t
    103         int cost; // cost
    10453
    105         // Step 1
     54        @Override
     55        public void visit(Way w)
     56        {
     57                if( w.deleted || w.incomplete )
     58                        return;
    10659
    107         n = s.length();
    108         m = t.length();
    109         if (n == 0) return m;
    110         if (m == 0) return n;
    111         d = new int[n + 1][m + 1];
     60                String name = w.get("name");
     61                if( name == null || name.length() < 6 )
     62                        return;
    11263
    113         // Step 2
    114         for (i = 0; i <= n; i++) d[i][0] = i;
    115         for (j = 0; j <= m; j++) d[0][j] = j;
     64                List<List<Way>> theCellWays = Util.getWaysInCell(w, cellWays);
     65                for( List<Way> ways : theCellWays)
     66                {
     67                        for( Way w2 : ways)
     68                        {
     69                                if( errorWays.contains(w, w2) || errorWays.contains(w2, w) )
     70                                        continue;
    11671
    117         // Step 3
    118         for (i = 1; i <= n; i++)
    119         {
    120             s_i = s.charAt(i - 1);
     72                                String name2 = w2.get("name");
     73                                if( name2 == null || name2.length() < 6 )
     74                                        continue;
    12175
    122             // Step 4
    123             for (j = 1; j <= m; j++)
    124             {
    125                 t_j = t.charAt(j - 1);
     76                                int levenshteinDistance = getLevenshteinDistance(name, name2);
     77                                if( 0 < levenshteinDistance && levenshteinDistance <= 2 )
     78                                {
     79                                        List<OsmPrimitive> primitives = new ArrayList<OsmPrimitive>();
     80                                        primitives.add(w);
     81                                        primitives.add(w2);
     82                                        errors.add( new TestError(this, Severity.WARNING, tr("Similar named ways"), SIMILAR_NAMED, primitives) );
     83                                        errorWays.add(w, w2);
     84                                }
     85                        }
     86                        ways.add(w);
     87                }
     88        }
    12689
    127                 // Step 5
    128                 if (s_i == t_j)
    129                 {
    130                     cost = 0;
    131                 }
    132                 else
    133                 {
    134                     cost = 1;
    135                 }
     90        /**
     91         * Compute Levenshtein distance
     92         *
     93         * @param s First word
     94         * @param t Second word
     95         * @return The distance between words
     96         */
     97        public int getLevenshteinDistance(String s, String t)
     98        {
     99                int d[][]; // matrix
     100                int n; // length of s
     101                int m; // length of t
     102                int i; // iterates through s
     103                int j; // iterates through t
     104                char s_i; // ith character of s
     105                char t_j; // jth character of t
     106                int cost; // cost
    136107
    137                 // Step 6
    138                 d[i][j] = Minimum(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost);
    139             }
    140         }
     108                // Step 1
    141109
    142         // Step 7
    143         return d[n][m];
     110                n = s.length();
     111                m = t.length();
     112                if (n == 0) return m;
     113                if (m == 0) return n;
     114                d = new int[n + 1][m + 1];
    144115
    145     }
     116                // Step 2
     117                for (i = 0; i <= n; i++) d[i][0] = i;
     118                for (j = 0; j <= m; j++) d[0][j] = j;
    146119
    147     /**
    148      * Get minimum of three values
    149      * @param a First value
    150      * @param b Second value
    151      * @param c Third value
    152      * @return The minimum of the tre values
    153      */
    154     private static int Minimum(int a, int b, int c)
    155     {
    156         int mi = a;
    157         if (b < mi)
    158         {
    159             mi = b;
    160         }
    161         if (c < mi)
    162         {
    163             mi = c;
    164         }
    165         return mi;
    166     }
     120                // Step 3
     121                for (i = 1; i <= n; i++)
     122                {
     123                        s_i = s.charAt(i - 1);
     124
     125                        // Step 4
     126                        for (j = 1; j <= m; j++)
     127                        {
     128                                t_j = t.charAt(j - 1);
     129
     130                                // Step 5
     131                                if (s_i == t_j)
     132                                {
     133                                        cost = 0;
     134                                }
     135                                else
     136                                {
     137                                        cost = 1;
     138                                }
     139
     140                                // Step 6
     141                                d[i][j] = Minimum(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost);
     142                        }
     143                }
     144
     145                // Step 7
     146                return d[n][m];
     147        }
     148
     149        /**
     150         * Get minimum of three values
     151         * @param a First value
     152         * @param b Second value
     153         * @param c Third value
     154         * @return The minimum of the tre values
     155         */
     156        private static int Minimum(int a, int b, int c)
     157        {
     158                int mi = a;
     159                if (b < mi)
     160                {
     161                        mi = b;
     162                }
     163                if (c < mi)
     164                {
     165                        mi = c;
     166                }
     167                return mi;
     168        }
    167169}
  • applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/TagChecker.java

    r9598 r9684  
    112112        protected JButton deleteSrcButton;
    113113
    114         protected static int EMPTY_VALUES = 0;
    115         protected static int INVALID_KEY = 1;
    116         protected static int INVALID_VALUE = 2;
    117         protected static int FIXME = 3;
    118         protected static int INVALID_SPACE = 3;
    119         protected static int TAG_CHECK = 4;
     114        protected static int EMPTY_VALUES      = 1200;
     115        protected static int INVALID_KEY       = 1201;
     116        protected static int INVALID_VALUE     = 1202;
     117        protected static int FIXME             = 1203;
     118        protected static int INVALID_SPACE     = 1204;
     119        protected static int INVALID_KEY_SPACE = 1205;
     120        protected static int TAG_CHECK         = 1206;
    120121
    121122        /** List of sources for spellcheck data */
     
    165166                                sources = SPELL_FILE + ";" + sources;
    166167                }
    167                
     168
    168169                StringTokenizer st = new StringTokenizer(sources, ";");
    169170                StringBuilder errorSources = new StringBuilder();
     
    224225                        throw new IOException( tr("Could not download data file(s):\n{0}", errorSources) );
    225226        }
    226        
     227
    227228        /**
    228229         * Reads the presets data.
     
    245246                readPresetFromPreferences();
    246247        }
    247        
    248        
     248
     249
    249250        @Override
    250251        public void visit(Node n)
     
    275276                                if(d.match(p))
    276277                                {
    277                                         errors.add( new TestError(this, Severity.WARNING, tr("Illegal tag/value combinations"), p, TAG_CHECK) );
     278                                        errors.add( new TestError(this, Severity.WARNING, tr("Illegal tag/value combinations"),
     279                                        tr(d.description()), TAG_CHECK, p) );
    278280                                        withErrors.add(p, "TC");
    279281                                        break;
     
    289291                        if( checkValues && (value==null || value.trim().length() == 0) && !withErrors.contains(p, "EV"))
    290292                        {
    291                                 errors.add( new TestError(this, Severity.WARNING, tr("Tags with empty values"), tr("Key ''{0}'' invalid.", key), p, EMPTY_VALUES) );
     293                                errors.add( new TestError(this, Severity.WARNING, tr("Tags with empty values"),
     294                                tr("Key ''{0}'' invalid.", key), EMPTY_VALUES, p) );
    292295                                withErrors.add(p, "EV");
    293296                        }
    294297                        if( checkKeys && spellCheckKeyData.containsKey(key) && !withErrors.contains(p, "IPK"))
    295298                        {
    296                                 errors.add( new TestError(this, Severity.WARNING, tr("Invalid property key"), tr("Key ''{0}'' invalid.", key), p, INVALID_KEY) );
     299                                errors.add( new TestError(this, Severity.WARNING, tr("Invalid property key"),
     300                                tr("Key ''{0}'' invalid.", key), INVALID_KEY, p) );
    297301                                withErrors.add(p, "IPK");
    298302                        }
    299303                        if( checkKeys && key.indexOf(" ") >= 0 && !withErrors.contains(p, "IPK"))
    300304                        {
    301                                 errors.add( new TestError(this, Severity.WARNING, tr("Invalid white space in property key"), tr("Key ''{0}'' invalid.", key), p, INVALID_KEY) );
     305                                errors.add( new TestError(this, Severity.WARNING, tr("Invalid white space in property key"),
     306                                tr("Key ''{0}'' invalid.", key), INVALID_KEY_SPACE, p) );
    302307                                withErrors.add(p, "IPK");
    303308                        }
    304309                        if( checkValues && value != null && (value.startsWith(" ") || value.endsWith(" ")) && !withErrors.contains(p, "SPACE"))
    305310                        {
    306                                 errors.add( new TestError(this, Severity.OTHER, tr("Property values start or end with white space"), tr("Key ''{0}'' invalid.", key), p, INVALID_SPACE) );
     311                                errors.add( new TestError(this, Severity.OTHER, tr("Property values start or end with white space"),
     312                                tr("Key ''{0}'' invalid.", key), INVALID_SPACE, p) );
    307313                                withErrors.add(p, "SPACE");
    308314                        }
     
    312318                                if( values != null && !values.contains(prop.getValue()) && !withErrors.contains(p, "UPV"))
    313319                                {
    314                                         errors.add( new TestError(this, Severity.OTHER, tr("Unknown property values"), tr("Key ''{0}'' invalid.", key), p, INVALID_VALUE) );
     320                                        errors.add( new TestError(this, Severity.OTHER, tr("Unknown property values"),
     321                                        tr("Key ''{0}'' invalid.", key), INVALID_VALUE, p) );
    315322                                        withErrors.add(p, "UPV");
    316323                                }
     
    321328                                && !withErrors.contains(p, "FIXME"))
    322329                                {
    323                                         errors.add( new TestError(this, Severity.OTHER, tr("FIXMES"), p, FIXME) );
     330                                        errors.add( new TestError(this, Severity.OTHER, tr("FIXMES"), FIXME, p) );
    324331                                        withErrors.add(p, "FIXME");
    325332                                }
     
    346353                        in = new BufferedReader(new InputStreamReader(inStream));
    347354                }
    348                
     355
    349356                XmlObjectParser parser = new XmlObjectParser();
    350357                parser.mapOnStart("item", TaggingPreset.class);
     
    355362                parser.map("key", TaggingPreset.Key.class);
    356363                parser.start(in);
    357                
     364
    358365                while(parser.hasNext())
    359366                {
     
    378385                        InputStream in = null;
    379386                        String source = st.nextToken();
    380                         try 
     387                        try
    381388                        {
    382389                                if (source.startsWith("http") || source.startsWith("ftp") || source.startsWith("file"))
     
    388395                                readPresets(in);
    389396                                in.close();
    390                         } 
     397                        }
    391398                        catch (IOException e)
    392399                        {
    393400                                // Error already reported by JOSM
    394                         } 
     401                        }
    395402                        catch (SAXException e)
    396403                        {
     
    426433                        super.visit(selection);
    427434        }
    428        
     435
    429436        @Override
    430437        public void addGui(JPanel testPanel)
     
    575582        {
    576583                enabled = prefCheckKeys.isSelected() || prefCheckValues.isSelected() || prefCheckComplex.isSelected() || prefCheckFixmes.isSelected();
    577                 testBeforeUpload = prefCheckKeysBeforeUpload.isSelected() || prefCheckValuesBeforeUpload.isSelected() || prefCheckFixmesBeforeUpload.isSelected() || prefCheckComplexBeforeUpload.isSelected();
     584                testBeforeUpload = prefCheckKeysBeforeUpload.isSelected() || prefCheckValuesBeforeUpload.isSelected()
     585                || prefCheckFixmesBeforeUpload.isSelected() || prefCheckComplexBeforeUpload.isSelected();
    578586
    579587                Main.pref.put(PREF_CHECK_VALUES, prefCheckValues.isSelected());
     
    620628                                else if(value.startsWith(" ") || value.endsWith(" "))
    621629                                        commands.add( new ChangePropertyCommand(Collections.singleton(primitives.get(i)), key, value.trim()) );
     630                                else if(key.startsWith(" ") || key.endsWith(" "))
     631                                {
     632                                        commands.add( new ChangePropertyKeyCommand(Collections.singleton(primitives.get(i)), key, key.trim()) );
     633                                }
    622634                                else
    623635                                {
     
    642654                if( testError.getTester() instanceof TagChecker)
    643655                {
    644                         int code = testError.getInternalCode();
    645                         return code == INVALID_KEY || code == EMPTY_VALUES || code == INVALID_SPACE;
     656                        int code = testError.getCode();
     657                        return code == INVALID_KEY || code == EMPTY_VALUES || code == INVALID_SPACE || code == INVALID_KEY_SPACE;
    646658                }
    647659
     
    652664                public String getData(String data)
    653665                {
    654 System.out.println(data);
    655666                        return "not implemented yet";
    656667                }
     
    659670                        return false;
    660671                }
     672                public String description()
     673                {
     674                        return "not implemented yet";
     675                }
    661676        }
    662677}
  • applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/UnclosedWays.java

    r9598 r9684  
    1818 * @author stoecker
    1919 */
    20 public class UnclosedWays extends Test  {
     20public class UnclosedWays extends Test  {
    2121        /** The already detected errors */
    2222        Bag<Way, Way> _errorWays;
     
    4242                _errorWays = null;
    4343        }
    44        
     44
    4545        @Override
    4646        public void visit(Way w)
     
    4848                boolean force = false; /* force even if end-to-end distance is long */
    4949                String type = null, test;
    50                
     50                int mode = 0;
     51
    5152                if( w.deleted || w.incomplete )
    5253                        return;
    53                
     54
    5455                test = w.get("natural");
    5556                if(test != null)
     
    5859                                force = true;
    5960                        type = tr("natural type {0}", tr(test));
     61                        mode = 1101;
    6062                }
    6163                test = w.get("landuse");
     
    6466                        force = true;
    6567                        type = tr("landuse type {0}", tr(test));
     68                        mode = 1102;
    6669                }
    6770                test = w.get("amenities");
     
    7073                        force = true;
    7174                        type = tr("amenities type {0}", tr(test));
     75                        mode = 1103;
    7276                }
    7377                test = w.get("sport");
     
    7680                        force = true;
    7781                        type = tr("sport type {0}", tr(test));
     82                        mode = 1104;
    7883                }
    7984                test = w.get("tourism");
     
    8287                        force = true;
    8388                        type = tr("tourism type {0}", tr(test));
     89                        mode = 1105;
    8490                }
    8591                test = w.get("shop");
     
    8894                        force = true;
    8995                        type = tr("shop type {0}", tr(test));
     96                        mode = 1106;
    9097                }
    9198                test = w.get("leisure");
     
    94101                        force = true;
    95102                        type = tr("leisure type {0}", tr(test));
     103                        mode = 1107;
    96104                }
    97105                test = w.get("waterway");
     
    100108                        force = true;
    101109                        type = tr("waterway type {0}", tr(test));
     110                        mode = 1108;
    102111                }
    103                 /*test = w.get("junction");
    104                 if(test != null && test.equals("roundabout"))
    105                 {
    106                         force = true;
    107                         type = tr("junction type {0}", tr(test));
    108                 }*/
    109112                test = w.get("building");
    110113                if (test != null && ("true".equalsIgnoreCase(test) || "yes".equalsIgnoreCase(test) || "1".equals(test)))
     
    112115                        force = true;
    113116                        type = tr("building");
     117                        mode = 1120;
    114118                }
    115119                test = w.get("area");
     
    118122                        force = true;
    119123                        type = tr("area");
     124                        mode = 1130;
    120125                }
    121126
     
    129134                                List<OsmPrimitive> primitives = new ArrayList<OsmPrimitive>();
    130135                                primitives.add(w);
    131                                 errors.add(new TestError(this, Severity.WARNING, tr("Unclosed way"), type, primitives));
     136                                errors.add(new TestError(this, Severity.WARNING, tr("Unclosed way"), type, mode, primitives));
    132137                                _errorWays.add(w,w);
    133138                        }
  • applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/UntaggedNode.java

    r5609 r9684  
    1313import org.openstreetmap.josm.plugins.validator.Severity;
    1414import org.openstreetmap.josm.plugins.validator.Test;
     15import org.openstreetmap.josm.plugins.validator.util.Util;
    1516import org.openstreetmap.josm.plugins.validator.TestError;
     17
    1618/**
    1719 * Checks for untagged nodes that are in no way
    18  * 
     20 *
    1921 * @author frsantos
    2022 */
    21 public class UntaggedNode extends Test 
     23public class UntaggedNode extends Test
    2224{
    23         /** Tags allowed in a node */
    24         public static String[] allowedTags = new String[] { "created_by" };
    25        
     25        protected static int UNTAGGED_NODE = 201;
     26
    2627        /** Bag of all nodes */
    2728        Set<Node> emptyNodes;
    28        
     29
    2930        /**
    3031         * Constructor
    3132         */
    32         public UntaggedNode() 
     33        public UntaggedNode()
    3334        {
    3435                super(tr("Untagged nodes."),
     
    3738
    3839        @Override
    39         public void startTest() 
     40        public void startTest()
    4041        {
    4142                emptyNodes = new HashSet<Node>(100);
    4243        }
    43        
     44
    4445        @Override
    45     public void visit(Collection<OsmPrimitive> selection)
    46     {
     46        public void visit(Collection<OsmPrimitive> selection)
     47        {
    4748                // If there is a partial selection, it may be false positives if a
    4849                // node is selected, but not the container way. So, in this
     
    6465                        }
    6566                }
    66     }
    67    
     67        }
     68
    6869        @Override
    69         public void visit(Node n) 
     70        public void visit(Node n)
    7071        {
    71                 if (n.incomplete || n.deleted) return;
     72                if(!n.incomplete && !n.deleted && Util.countDataTags(n) == 0)
     73                        emptyNodes.add(n);
     74        }
    7275
    73                 int numTags = 0;
    74                 Map<String, String> tags = n.keys;
    75                 if( tags != null )
    76                 {
    77                         numTags = tags.size();
    78                         for( String tag : allowedTags)
    79                                 if( tags.containsKey(tag) ) numTags--;
    80                 }
    81                
    82                 if( numTags == 0 )
    83                 {
    84                         emptyNodes.add(n);
    85                 }
    86         }
    87        
    8876        @Override
    89         public void visit(Way w) 
     77        public void visit(Way w)
    9078        {
    9179                for (Node n : w.nodes) {
     
    9381                }
    9482        }
    95        
     83
    9684        @Override
    97         public void endTest() 
     85        public void endTest()
    9886        {
    9987                for(Node node : emptyNodes)
    10088                {
    101                         errors.add( new TestError(this, Severity.OTHER, tr("Untagged and unconnected nodes"), node) );
     89                        errors.add( new TestError(this, Severity.OTHER, tr("Untagged and unconnected nodes"), UNTAGGED_NODE, node) );
    10290                }
    10391                emptyNodes = null;
    10492        }
    105        
     93
    10694        @Override
    10795        public Command fixError(TestError testError)
     
    10997                return new DeleteCommand(testError.getPrimitives());
    11098        }
    111        
     99
    112100        @Override
    113101        public boolean isFixable(TestError testError)
    114102        {
    115103                return (testError.getTester() instanceof UntaggedNode);
    116         }               
     104        }
    117105}
  • applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/UntaggedWay.java

    r5609 r9684  
    1313import org.openstreetmap.josm.plugins.validator.Test;
    1414import org.openstreetmap.josm.plugins.validator.TestError;
     15import org.openstreetmap.josm.plugins.validator.util.Util;
     16
    1517/**
    1618 * Checks for untagged ways
    17  * 
     19 *
    1820 * @author frsantos
    1921 */
    20 public class UntaggedWay extends Test 
     22public class UntaggedWay extends Test
    2123{
    2224        /** Empty way error */
    23         protected static final int EMPTY_WAY    = 0;
     25        protected static final int EMPTY_WAY    = 301;
    2426        /** Untagged way error */
    25         protected static final int UNTAGGED_WAY = 1;
     27        protected static final int UNTAGGED_WAY = 302;
    2628        /** Unnamed way error */
    27         protected static final int UNNAMED_WAY  = 2;
     29        protected static final int UNNAMED_WAY  = 303;
    2830        /** One node way error */
    29         protected static final int ONE_NODE_WAY = 3;
     31        protected static final int ONE_NODE_WAY = 304;
    3032
    31     /** Tags allowed in a way */
    32     public static final String[] ALLOWED_TAGS = new String[] { "created_by", "converted_by" };
     33        /** Ways that must have a name */
     34        public static final Set<String> NAMED_WAYS = new HashSet<String>();
     35        static
     36        {
     37                NAMED_WAYS.add( "motorway" );
     38                NAMED_WAYS.add( "trunk" );
     39                NAMED_WAYS.add( "primary" );
     40                NAMED_WAYS.add( "secondary" );
     41                NAMED_WAYS.add( "tertiary" );
     42                NAMED_WAYS.add( "residential" );
     43                NAMED_WAYS.add( "pedestrian" ); ;
     44        }
    3345
    34     /** Ways that must have a name */
    35     public static final Set<String> NAMED_WAYS = new HashSet<String>();
    36     static
    37     {
    38         NAMED_WAYS.add( "motorway" );
    39         NAMED_WAYS.add( "trunk" );
    40         NAMED_WAYS.add( "primary" );
    41         NAMED_WAYS.add( "secondary" );
    42         NAMED_WAYS.add( "tertiary" );
    43         NAMED_WAYS.add( "residential" );
    44         NAMED_WAYS.add( "pedestrian" ); ;
    45     }
    46    
    47     /**
     46        /**
    4847         * Constructor
    4948         */
    50         public UntaggedWay() 
     49        public UntaggedWay()
    5150        {
    5251                super(tr("Untagged, empty, and one node ways."),
     
    5554
    5655        @Override
    57         public void visit(Way w) 
     56        public void visit(Way w)
    5857        {
    5958                if (w.deleted || w.incomplete) return;
    6059
    61                 int numTags = 0;
    6260                Map<String, String> tags = w.keys;
    6361                if( tags != null )
    6462                {
    65                         numTags = tags.size();
    66                         for( String tag : ALLOWED_TAGS)
    67                                 if( tags.containsKey(tag) ) numTags--;
    68            
    69             String highway = tags.get("highway");
    70             if( numTags != 0 && highway != null && NAMED_WAYS.contains(highway))
    71             {
    72                 if( !tags.containsKey("name") && !tags.containsKey("ref") )
    73                 {
    74                     boolean hasName = false;
    75                     for( String key : w.keySet())
    76                     {
    77                         hasName = key.startsWith("name:") || key.endsWith("_name") || key.endsWith("_ref");
    78                         if( hasName )
    79                             break;
    80                     }
    81                    
    82                     if( !hasName)
    83                         errors.add( new TestError(this, Severity.WARNING, tr("Unnamed ways"), w, UNNAMED_WAY ) );
    84                 }
    85             }
     63                        String highway = tags.get("highway");
     64                        if(highway != null && NAMED_WAYS.contains(highway))
     65                        {
     66                                if( !tags.containsKey("name") && !tags.containsKey("ref") )
     67                                {
     68                                        boolean hasName = false;
     69                                        for( String key : w.keySet())
     70                                        {
     71                                                hasName = key.startsWith("name:") || key.endsWith("_name") || key.endsWith("_ref");
     72                                                if( hasName )
     73                                                        break;
     74                                        }
     75
     76                                        if( !hasName)
     77                                                errors.add( new TestError(this, Severity.WARNING, tr("Unnamed ways"), UNNAMED_WAY, w) );
     78                                }
     79                        }
    8680                }
    87                
    88         if( numTags == 0 )
    89         {
    90             errors.add( new TestError(this, Severity.WARNING, tr("Untagged ways"), w, UNTAGGED_WAY) );
    91         }
    92        
    93         if( w.nodes.size() == 0 )
    94         {
    95             errors.add( new TestError(this, Severity.ERROR, tr("Empty ways"), w, EMPTY_WAY) );
    96         }
    97        
    98         if( w.nodes.size() == 1 )
    99         {
    100             errors.add( new TestError(this, Severity.ERROR, tr("One node ways"), w, ONE_NODE_WAY) );
    101         }
    102        
    103         }               
    104        
     81
     82                if(Util.countDataTags(w) == 0)
     83                {
     84                        errors.add( new TestError(this, Severity.WARNING, tr("Untagged ways"), UNTAGGED_WAY, w) );
     85                }
     86
     87                if( w.nodes.size() == 0 )
     88                {
     89                        errors.add( new TestError(this, Severity.ERROR, tr("Empty ways"), EMPTY_WAY, w) );
     90                }
     91                else if( w.nodes.size() == 1 )
     92                {
     93                        errors.add( new TestError(this, Severity.ERROR, tr("One node ways"), ONE_NODE_WAY, w) );
     94                }
     95
     96        }
     97
    10598        @Override
    10699        public boolean isFixable(TestError testError)
     
    108101                if( testError.getTester() instanceof UntaggedWay )
    109102                {
    110                         return testError.getInternalCode() == EMPTY_WAY
    111                                 || testError.getInternalCode() == ONE_NODE_WAY;
     103                        return testError.getCode() == EMPTY_WAY
     104                                || testError.getCode() == ONE_NODE_WAY;
    112105                }
    113                
     106
    114107                return false;
    115108        }
    116        
     109
    117110        @Override
    118111        public Command fixError(TestError testError)
  • applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/WronglyOrderedWays.java

    r8904 r9684  
    2020 */
    2121public class WronglyOrderedWays extends Test  {
     22        protected static int WRONGLY_ORDERED_COAST = 1001;
     23        protected static int WRONGLY_ORDERED_WATER = 1002;
     24        protected static int WRONGLY_ORDERED_LAND  = 1003;
     25
    2226        /** The already detected errors */
    2327        Bag<Way, Way> _errorWays;
     
    4347                _errorWays = null;
    4448        }
    45        
     49
    4650        @Override
    4751        public void visit(Way w)
    4852        {
    4953                String errortype = "";
    50                
     54                int type;
     55
    5156                if( w.deleted || w.incomplete )
    5257                        return;
    53                
     58
    5459                String natural = w.get("natural");
    5560                if( natural == null)
    5661                        return;
    57                
     62
    5863                if( natural.equals("coastline") )
     64                {
    5965                        errortype = tr("Reversed coastline: land not on left side");
     66                        type= WRONGLY_ORDERED_COAST;
     67                }
    6068                else if(natural.equals("water") )
     69                {
    6170                        errortype = tr("Reversed water: land not on left side");
     71                        type= WRONGLY_ORDERED_WATER;
     72                }
    6273                else if( natural.equals("land") )
     74                {
    6375                        errortype = tr("Reversed land: land not on left side");
     76                        type= WRONGLY_ORDERED_LAND;
     77                }
    6478                else
    6579                        return;
     
    90104                                List<OsmPrimitive> primitives = new ArrayList<OsmPrimitive>();
    91105                                primitives.add(w);
    92                                 errors.add( new TestError(this, Severity.WARNING, errortype, primitives) );
     106                                errors.add( new TestError(this, Severity.WARNING, errortype, type, primitives) );
    93107                                _errorWays.add(w,w);
    94108                        }
  • applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/util/Util.java

    r9561 r9684  
    1515import org.openstreetmap.josm.Main;
    1616import org.openstreetmap.josm.data.osm.Way;
     17import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1718import org.openstreetmap.josm.data.osm.Node;
    1819import org.openstreetmap.josm.plugins.*;
     
    2223/**
    2324 * Utility class
    24  * 
     25 *
    2526 * @author frsantos
    2627 */
    27 public class Util 
     28public class Util
    2829{
    29         /**
     30        /** Tags without informational contents */
     31        private static final String[] noDataTags = new String[] { "created_by", "converted_by", "source" };
     32        public static int countDataTags(OsmPrimitive osm)
     33        {
     34                int numTags = 0;
     35                Map<String, String> tags = osm.keys;
     36                if(tags != null)
     37                {
     38                        numTags = tags.size();
     39                        for(String tag : noDataTags)
     40                                if(tags.containsKey(tag))
     41                                        --numTags;
     42                }
     43                return numTags;
     44        }
     45
     46        /**
    3047         * Returns the plugin's directory of the plugin
    31          * 
     48         *
    3249         * @return The directory of the plugin
    3350         */
     
    4259         */
    4360        public static Version getVersion()
    44     {
    45         PluginInformation info = PluginInformation.getLoaded("validator");
    46         if( info == null )
    47             return null;
     61        {
     62                PluginInformation info = PluginInformation.getLoaded("validator");
     63                if( info == null )
     64                        return null;
    4865
    4966                return new Version(info.version, info.attr.get("Plugin-Date"));
    50     }
    51 
    52     /**
    53     * Utility class for displaying versions
    54      *
    55     * @author frsantos
    56     */
    57     public static class Version
    58     {
    59         /** The revision */
    60         public String revision;
    61         /** The build time */
    62         public String time;
    63        
    64         /**
    65         * Constructor
    66         * @param revision
    67         * @param time
    68         */
    69         public Version(String revision, String time)
    70         {
     67        }
     68
     69        /**
     70        * Utility class for displaying versions
     71         *
     72        * @author frsantos
     73        */
     74        public static class Version
     75        {
     76                /** The revision */
     77                public String revision;
     78                /** The build time */
     79                public String time;
     80
     81                /**
     82                * Constructor
     83                * @param revision
     84                * @param time
     85                */
     86                public Version(String revision, String time)
     87                {
    7188                        this.revision = revision;
    7289                        this.time = time;
    7390                }
    74     }
    75    
    76    
    77     /**
    78     * Loads a text file in a String
    79      *
    80     * @param resource The URL of the file
    81     * @return A String with the file contents
    82     * @throws IOException when error reading the file
    83     */
    84     public static String loadFile(URL resource) throws IOException
    85     {
    86         BufferedReader in = null;
    87                 try 
     91        }
     92
     93
     94        /**
     95        * Loads a text file in a String
     96         *
     97        * @param resource The URL of the file
     98        * @return A String with the file contents
     99        * @throws IOException when error reading the file
     100        */
     101        public static String loadFile(URL resource) throws IOException
     102        {
     103                BufferedReader in = null;
     104                try
    88105                {
    89106                        in = new BufferedReader(new InputStreamReader(resource.openStream()));
    90107                        StringBuilder sb = new StringBuilder();
    91                         for (String line = in.readLine(); line != null; line = in.readLine()) 
     108                        for (String line = in.readLine(); line != null; line = in.readLine())
    92109                        {
    93110                                sb.append(line);
     
    107124                        }
    108125                }
    109     }
    110    
    111     /**
    112     * Mirrors a file to a local file.
    113     * <p>
    114     * The file mirrored is only downloaded if it has been more than one day since last download
    115      *
    116     * @param url The URL of the remote file
    117     * @param destDir The destionation dir of the mirrored file
    118      * @param maxTime The time interval, in seconds, to check if the file changed. If less than 0, it defaults to 1 week
    119     * @return The local file
    120     */
    121     public static File mirror(URL url, String destDir, long maxTime)
    122     {
    123         if( url.getProtocol().equals("file") )
    124             return new File(url.toString() ) ;
    125        
    126         String localPath = Main.pref.get( PreferenceEditor.PREFIX + ".mirror." + url);
    127         File oldFile = null;
    128         if( localPath != null && localPath.length() > 0)
    129         {
    130             StringTokenizer st = new StringTokenizer(localPath, ";");
    131             long checkDate = Long.parseLong(st.nextToken());
    132             localPath = st.nextToken();
    133             oldFile = new File(localPath);
    134             maxTime = (maxTime <= 0) ? 7 * 24 * 60 * 60 * 1000 : maxTime * 1000;
    135             if( System.currentTimeMillis() - checkDate < maxTime )
    136             {
    137                 if( oldFile.exists() )
    138                     return oldFile;
    139             }
    140         }
    141 
    142         File destDirFile = new File(destDir);
    143         if( !destDirFile.exists() )
    144             destDirFile.mkdirs();
    145 
    146         localPath = destDir + System.currentTimeMillis() + "-" + new File(url.getPath()).getName();
    147         BufferedOutputStream bos = null;
    148         BufferedInputStream bis = null;
    149         try
    150         {
    151             URLConnection conn = url.openConnection();
    152             conn.setConnectTimeout(5000);
    153             bis = new BufferedInputStream(conn.getInputStream());
    154             bos = new BufferedOutputStream( new FileOutputStream(localPath) );
    155             byte[] buffer = new byte[4096];
    156             int length;
    157             while( (length = bis.read( buffer )) > -1 )
    158             {
    159                 bos.write( buffer, 0, length );
    160             }
    161         }
    162         catch(IOException ioe)
    163         {
    164             if( oldFile != null )
    165                 return oldFile;
    166             else
    167                 return null;
    168         }
    169         finally
    170         {
    171             if( bis != null )
    172             {
    173                 try {
    174                     bis.close();
    175                 } catch (IOException e) {
    176                     e.printStackTrace();
    177                 }
    178             }
    179             if( bos != null )
    180             {
    181                 try {
    182                     bos.close();
    183                 } catch (IOException e) {
    184                     e.printStackTrace();
    185                 }
    186             }
    187         }
    188        
    189         Main.pref.put( PreferenceEditor.PREFIX + ".mirror." + url, System.currentTimeMillis() + ";" + localPath);
    190        
    191         if( oldFile != null )
    192             oldFile.delete();
    193 
    194         return new File(localPath);
    195     }
    196    
    197     /**
    198     * Returns the start and end cells of a way.
    199     * @param w The way
    200     * @param cellWays The map with all cells
    201     * @return A list with all the cells the way starts or ends
    202     */
    203     public static List<List<Way>> getWaysInCell(Way w, Map<Point2D,List<Way>> cellWays)
    204     {
     126        }
     127
     128        /**
     129        * Mirrors a file to a local file.
     130        * <p>
     131        * The file mirrored is only downloaded if it has been more than one day since last download
     132         *
     133        * @param url The URL of the remote file
     134        * @param destDir The destionation dir of the mirrored file
     135         * @param maxTime The time interval, in seconds, to check if the file changed. If less than 0, it defaults to 1 week
     136        * @return The local file
     137        */
     138        public static File mirror(URL url, String destDir, long maxTime)
     139        {
     140                if( url.getProtocol().equals("file") )
     141                        return new File(url.toString() ) ;
     142
     143                String localPath = Main.pref.get( PreferenceEditor.PREFIX + ".mirror." + url);
     144                File oldFile = null;
     145                if( localPath != null && localPath.length() > 0)
     146                {
     147                        StringTokenizer st = new StringTokenizer(localPath, ";");
     148                        long checkDate = Long.parseLong(st.nextToken());
     149                        localPath = st.nextToken();
     150                        oldFile = new File(localPath);
     151                        maxTime = (maxTime <= 0) ? 7 * 24 * 60 * 60 * 1000 : maxTime * 1000;
     152                        if( System.currentTimeMillis() - checkDate < maxTime )
     153                        {
     154                                if( oldFile.exists() )
     155                                        return oldFile;
     156                        }
     157                }
     158
     159                File destDirFile = new File(destDir);
     160                if( !destDirFile.exists() )
     161                        destDirFile.mkdirs();
     162
     163                localPath = destDir + System.currentTimeMillis() + "-" + new File(url.getPath()).getName();
     164                BufferedOutputStream bos = null;
     165                BufferedInputStream bis = null;
     166                try
     167                {
     168                        URLConnection conn = url.openConnection();
     169                        conn.setConnectTimeout(5000);
     170                        bis = new BufferedInputStream(conn.getInputStream());
     171                        bos = new BufferedOutputStream( new FileOutputStream(localPath) );
     172                        byte[] buffer = new byte[4096];
     173                        int length;
     174                        while( (length = bis.read( buffer )) > -1 )
     175                        {
     176                                bos.write( buffer, 0, length );
     177                        }
     178                }
     179                catch(IOException ioe)
     180                {
     181                        if( oldFile != null )
     182                                return oldFile;
     183                        else
     184                                return null;
     185                }
     186                finally
     187                {
     188                        if( bis != null )
     189                        {
     190                                try {
     191                                        bis.close();
     192                                } catch (IOException e) {
     193                                        e.printStackTrace();
     194                                }
     195                        }
     196                        if( bos != null )
     197                        {
     198                                try {
     199                                        bos.close();
     200                                } catch (IOException e) {
     201                                        e.printStackTrace();
     202                                }
     203                        }
     204                }
     205
     206                Main.pref.put( PreferenceEditor.PREFIX + ".mirror." + url, System.currentTimeMillis() + ";" + localPath);
     207
     208                if( oldFile != null )
     209                        oldFile.delete();
     210
     211                return new File(localPath);
     212        }
     213
     214        /**
     215        * Returns the start and end cells of a way.
     216        * @param w The way
     217        * @param cellWays The map with all cells
     218        * @return A list with all the cells the way starts or ends
     219        */
     220        public static List<List<Way>> getWaysInCell(Way w, Map<Point2D,List<Way>> cellWays)
     221        {
    205222                if (w.nodes.size() == 0)
    206             return Collections.emptyList();
     223                        return Collections.emptyList();
    207224
    208225                Node n1 = w.nodes.get(0);
    209226                Node n2 = w.nodes.get(w.nodes.size() - 1);
    210        
    211         List<List<Way>> cells = new ArrayList<List<Way>>(2);
    212         Set<Point2D> cellNodes = new HashSet<Point2D>();
    213         Point2D cell;
    214 
    215         // First, round coordinates
    216         long x0 = Math.round(n1.eastNorth.east()  * 10000);
    217         long y0 = Math.round(n1.eastNorth.north() * 10000);
    218         long x1 = Math.round(n2.eastNorth.east()  * 10000);
    219         long y1 = Math.round(n2.eastNorth.north() * 10000);
    220 
    221         // Start of the way
    222         cell = new Point2D.Double(x0, y0);
    223         cellNodes.add(cell);
    224         List<Way> ways = cellWays.get( cell );
    225         if( ways == null )
    226         {
    227             ways = new ArrayList<Way>();
    228             cellWays.put(cell, ways);
    229         }
    230         cells.add(ways);
    231        
    232         // End of the way
    233         cell = new Point2D.Double(x1, y1);
    234         if( !cellNodes.contains(cell) )
    235         {
    236             cellNodes.add(cell);
    237             ways = cellWays.get( cell );
    238             if( ways == null )
    239             {
    240                 ways = new ArrayList<Way>();
    241                 cellWays.put(cell, ways);
    242             }
    243             cells.add(ways);
    244         }
    245 
    246         // Then floor coordinates, in case the way is in the border of the cell.
    247         x0 = (long)Math.floor(n1.eastNorth.east()  * 10000);
    248         y0 = (long)Math.floor(n1.eastNorth.north() * 10000);
    249         x1 = (long)Math.floor(n2.eastNorth.east()  * 10000);
    250         y1 = (long)Math.floor(n2.eastNorth.north() * 10000);
    251 
    252         // Start of the way
    253         cell = new Point2D.Double(x0, y0);
    254         if( !cellNodes.contains(cell) )
    255         {
    256             cellNodes.add(cell);
    257             ways = cellWays.get( cell );
    258             if( ways == null )
    259             {
    260                 ways = new ArrayList<Way>();
    261                 cellWays.put(cell, ways);
    262             }
    263             cells.add(ways);
    264         }
    265        
    266         // End of the way
    267         cell = new Point2D.Double(x1, y1);
    268         if( !cellNodes.contains(cell) )
    269         {
    270             cellNodes.add(cell);
    271             ways = cellWays.get( cell );
    272             if( ways == null )
    273             {
    274                 ways = new ArrayList<Way>();
    275                 cellWays.put(cell, ways);
    276             }
    277             cells.add(ways);
    278         }
    279 
    280         return cells;
    281     }   
    282    
    283     /**
     227
     228                List<List<Way>> cells = new ArrayList<List<Way>>(2);
     229                Set<Point2D> cellNodes = new HashSet<Point2D>();
     230                Point2D cell;
     231
     232                // First, round coordinates
     233                long x0 = Math.round(n1.eastNorth.east()  * 10000);
     234                long y0 = Math.round(n1.eastNorth.north() * 10000);
     235                long x1 = Math.round(n2.eastNorth.east()  * 10000);
     236                long y1 = Math.round(n2.eastNorth.north() * 10000);
     237
     238                // Start of the way
     239                cell = new Point2D.Double(x0, y0);
     240                cellNodes.add(cell);
     241                List<Way> ways = cellWays.get( cell );
     242                if( ways == null )
     243                {
     244                        ways = new ArrayList<Way>();
     245                        cellWays.put(cell, ways);
     246                }
     247                cells.add(ways);
     248
     249                // End of the way
     250                cell = new Point2D.Double(x1, y1);
     251                if( !cellNodes.contains(cell) )
     252                {
     253                        cellNodes.add(cell);
     254                        ways = cellWays.get( cell );
     255                        if( ways == null )
     256                        {
     257                                ways = new ArrayList<Way>();
     258                                cellWays.put(cell, ways);
     259                        }
     260                        cells.add(ways);
     261                }
     262
     263                // Then floor coordinates, in case the way is in the border of the cell.
     264                x0 = (long)Math.floor(n1.eastNorth.east()  * 10000);
     265                y0 = (long)Math.floor(n1.eastNorth.north() * 10000);
     266                x1 = (long)Math.floor(n2.eastNorth.east()  * 10000);
     267                y1 = (long)Math.floor(n2.eastNorth.north() * 10000);
     268
     269                // Start of the way
     270                cell = new Point2D.Double(x0, y0);
     271                if( !cellNodes.contains(cell) )
     272                {
     273                        cellNodes.add(cell);
     274                        ways = cellWays.get( cell );
     275                        if( ways == null )
     276                        {
     277                                ways = new ArrayList<Way>();
     278                                cellWays.put(cell, ways);
     279                        }
     280                        cells.add(ways);
     281                }
     282
     283                // End of the way
     284                cell = new Point2D.Double(x1, y1);
     285                if( !cellNodes.contains(cell) )
     286                {
     287                        cellNodes.add(cell);
     288                        ways = cellWays.get( cell );
     289                        if( ways == null )
     290                        {
     291                                ways = new ArrayList<Way>();
     292                                cellWays.put(cell, ways);
     293                        }
     294                        cells.add(ways);
     295                }
     296
     297                return cells;
     298        }
     299
     300        /**
    284301         * Returns the coordinates of all cells in a grid that a line between 2
    285302         * nodes intersects with.
    286          * 
     303         *
    287304         * @param n1 The first node.
    288305         * @param n2 The second node.
     
    291308         * @return A list with the coordinates of all cells
    292309         */
    293         public static List<Point2D> getSegmentCells(Node n1, Node n2, int gridDetail) 
     310        public static List<Point2D> getSegmentCells(Node n1, Node n2, int gridDetail)
    294311        {
    295312                List<Point2D> cells = new ArrayList<Point2D>();
    296313                double x0 = n1.eastNorth.east() * gridDetail;
    297314                double x1 = n2.eastNorth.east() * gridDetail;
    298         double y0 = n1.eastNorth.north() * gridDetail + 1;
    299         double y1 = n2.eastNorth.north() * gridDetail + 1;
    300 
    301         if( x0 > x1 )
    302         {
    303                 // Move to 1st-4th cuadrants
    304             double aux;
    305             aux = x0; x0 = x1; x1 = aux;
    306             aux = y0; y0 = y1; y1 = aux;
    307         }
    308        
    309         double dx  = x1 - x0;
    310         double dy  = y1 - y0;
    311         long stepY = y0 <= y1 ? 1 : -1;
    312         long gridX0 = (long)Math.floor(x0);
    313         long gridX1 = (long)Math.floor(x1);
    314         long gridY0 = (long)Math.floor(y0);
    315         long gridY1 = (long)Math.floor(y1);
    316        
    317         long maxSteps = (gridX1 - gridX0) + Math.abs(gridY1 - gridY0) + 1;
     315                double y0 = n1.eastNorth.north() * gridDetail + 1;
     316                double y1 = n2.eastNorth.north() * gridDetail + 1;
     317
     318                if( x0 > x1 )
     319                {
     320                        // Move to 1st-4th cuadrants
     321                        double aux;
     322                        aux = x0; x0 = x1; x1 = aux;
     323                        aux = y0; y0 = y1; y1 = aux;
     324                }
     325
     326                double dx  = x1 - x0;
     327                double dy  = y1 - y0;
     328                long stepY = y0 <= y1 ? 1 : -1;
     329                long gridX0 = (long)Math.floor(x0);
     330                long gridX1 = (long)Math.floor(x1);
     331                long gridY0 = (long)Math.floor(y0);
     332                long gridY1 = (long)Math.floor(y1);
     333
     334                long maxSteps = (gridX1 - gridX0) + Math.abs(gridY1 - gridY0) + 1;
    318335                while( (gridX0 <= gridX1 && (gridY0 - gridY1)*stepY <= 0) && maxSteps-- > 0)
    319         {
     336                {
    320337                        cells.add( new Point2D.Double(gridX0, gridY0) );
    321                        
    322                 // Is the cross between the segment and next vertical line nearer than the cross with next horizontal line?
    323                 // Note: segment line formula: y=dy/dx(x-x1)+y1
    324                         // Note: if dy < 0, must use *bottom* line. If dy > 0, must use upper line 
    325                 double scanY = dy/dx * (gridX0 + 1 - x1) + y1 + (dy < 0 ? -1 : 0);
    326                 double scanX = dx/dy * (gridY0 + (dy < 0 ? 0 : 1)*stepY - y1) + x1;
    327                
    328                 double distX = Math.pow(gridX0 + 1 - x0, 2) + Math.pow(scanY - y0, 2);
     338
     339                        // Is the cross between the segment and next vertical line nearer than the cross with next horizontal line?
     340                        // Note: segment line formula: y=dy/dx(x-x1)+y1
     341                        // Note: if dy < 0, must use *bottom* line. If dy > 0, must use upper line
     342                        double scanY = dy/dx * (gridX0 + 1 - x1) + y1 + (dy < 0 ? -1 : 0);
     343                        double scanX = dx/dy * (gridY0 + (dy < 0 ? 0 : 1)*stepY - y1) + x1;
     344
     345                        double distX = Math.pow(gridX0 + 1 - x0, 2) + Math.pow(scanY - y0, 2);
    329346                        double distY = Math.pow(scanX - x0, 2) + Math.pow(gridY0 + stepY - y0, 2);
    330                        
     347
    331348                        if( distX < distY)
    332                         gridX0 += 1;
    333                 else
    334                         gridY0 += stepY;
    335         }
    336                
     349                                gridX0 += 1;
     350                        else
     351                                gridY0 += stepY;
     352                }
     353
    337354                return cells;
    338         }   
     355        }
    339356}
Note: See TracChangeset for help on using the changeset viewer.