Changeset 4162 in osm for applications/editors


Ignore:
Timestamp:
2007-08-16T02:39:09+02:00 (17 years ago)
Author:
frsantos
Message:

Include water and coastline in crossing roads test
Fix calculation of the cells that a segment crosses

Location:
applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator
Files:
1 added
4 edited

Legend:

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

    r4093 r4162  
    8383                newFrame.addToggleDialog(validationDialog);
    8484            Main.main.addLayer(new ErrorLayer(tr("Validation errors")));
     85                if( Main.pref.hasKey(PreferenceEditor.PREF_DEBUG + ".grid") )
     86                        Main.main.addLayer(new GridLayer(tr("Grid")));
    8587            Layer.listeners.add(this);
    8688                }
  • applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/PreferenceEditor.java

    r4087 r4162  
    2626        /** The preferences prefix */
    2727        public static final String PREFIX = "validator";
    28        
     28
     29        /** The preferences key for debug preferences */
     30        public static final String PREF_DEBUG = PREFIX + ".debug";
     31
    2932        /** The preferences key for enabled tests */
    3033        public static final String PREF_TESTS = PREFIX + ".tests";
  • applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/tests/CrossingSegments.java

    r3260 r4162  
    1010import org.openstreetmap.josm.plugins.validator.*;
    1111import org.openstreetmap.josm.plugins.validator.util.Bag;
     12import org.openstreetmap.josm.plugins.validator.util.Util;
    1213
    1314/**
     
    5354            return;
    5455       
    55         if( w.get("highway") == null && w.get("waterway") == null && w.get("railway") == null )
     56        String coastline1 = w.get("natural");
     57        boolean isCoastline1 = coastline1 != null && (coastline1.equals("water") || coastline1.equals("coastline"));
     58        String railway1 = w.get("railway");
     59        boolean isSubway1 = railway1 != null && railway1.equals("subway");
     60        if( w.get("highway") == null && w.get("waterway") == null && !isSubway1 && !isCoastline1)
    5661                return;
    5762       
    5863        String layer1 = w.get("layer");
    59         String railway1 = w.get("railway");
    6064        for(Segment s : w.segments)
    6165        {
     
    6367                        continue;
    6468               
    65             ExtendedSegment es1 = new ExtendedSegment(s, layer1, railway1);
     69            ExtendedSegment es1 = new ExtendedSegment(s, layer1, railway1, coastline1);
    6670            List<List<ExtendedSegment>> cellSegments = getSegments(s);
    6771            for( List<ExtendedSegment> segments : cellSegments)
     
    7478                        String layer2 = es2.layer;
    7579                        String railway2 = es2.railway;
    76                         if( (layer1 == null && layer2 == null || layer1 != null && layer1.equals(layer2)) &&
    77                                 !("subway".equals(railway1) && "subway".equals(railway2)) &&   
    78                                 es1.intersects(es2))
    79                         {
    80                             List<OsmPrimitive> primitives = new ArrayList<OsmPrimitive>();
    81                             primitives.add(es1.s);
    82                             primitives.add(es2.s);
    83                             errors.add( new TestError(this, Severity.WARNING, tr("Crossing roads"), primitives) );
    84                         }
     80                        String coastline2 = es2.coastline;
     81                        if( (layer1 != null || layer2 != null) && (layer1 == null || !layer1.equals(layer2)) )
     82                                continue;
     83                       
     84                        if( !es1.intersects(es2) ) continue;
     85                            if( isSubway1 && "subway".equals(railway2)) continue;
     86                           
     87                            boolean isCoastline2 = coastline2 != null && (coastline2.equals("water") || coastline2.equals("coastline"));
     88                        if( isCoastline1 != isCoastline2 ) continue;
     89                       
     90                    List<OsmPrimitive> primitives = new ArrayList<OsmPrimitive>();
     91                    primitives.add(es1.s);
     92                    primitives.add(es2.s);
     93                    errors.add( new TestError(this, Severity.WARNING, tr("Crossing roads"), primitives) );
    8594                    }
    8695                    segments.add(es1);
     
    92101     * Returns all the cells this segment crosses . Each cell contains the list
    93102     * of segments already processed
    94      * <p>
    95      * This method uses the Bresenham algorithm to follow all cells this segment
    96      * crosses, so, in very few cases (when the segment is very long, and
    97      * crosses a cell very close to the corner), it can miss a cell.
    98103     *
    99104     * @param s The segment
     
    103108        {
    104109                List<List<ExtendedSegment>> cells = new ArrayList<List<ExtendedSegment>>();
    105                 long x0 = Math.round(s.from.eastNorth.east() * 1000);
    106                 long x1 = Math.round(s.to.eastNorth.east()   * 1000);
    107         long y0 = Math.round(s.from.eastNorth.north()* 1000);
    108         long y1 = Math.round(s.to.eastNorth.north()  * 1000);
    109        
    110         boolean steep = Math.abs(y1 - y0) > Math.abs(x1 - x0);
    111         long aux;
    112         if( steep )
    113         {
    114             aux = x0; x0 = x1; x1 = aux;
    115             aux = y0; y0 = y1; y1 = aux;
    116         }
    117         if( x0 > x1 )
    118         {
    119             aux = x0; x0 = x1; x1 = aux;
    120             aux = y0; y0 = y1; y1 = aux;
    121         }
    122         long dx  = x1 - x0,
    123              dy  = Math.abs(y1 - y0),
    124              y   = y0,
    125              error = -dx/2,
    126              ystep = y0 < y1 ? 1 : -1;
    127      
    128         for( long x = x0; x <= x1; x++ ) 
    129         {
    130             Point2D p = steep ? new Point2D.Double(y, x) : new Point2D.Double(x, y);
    131             List<ExtendedSegment> segments = cellSegments.get( p );
     110                for( Point2D cell : Util.getSegmentCells(s, 10000) )
     111                {
     112            List<ExtendedSegment> segments = cellSegments.get( cell );
    132113            if( segments == null )
    133114            {
    134115                segments = new ArrayList<ExtendedSegment>();
    135                 cellSegments.put(p, segments);
     116                cellSegments.put(cell, segments);
    136117            }
    137118            cells.add(segments);
    138            
    139             error += dy;
    140             if( error > 0 )
    141             {
    142                 error -= dx;
    143                 y += ystep;
    144             }
    145119        }
    146120       
     
    162136        /** The railway type */
    163137                private String railway;
     138
     139                /** The coastline type */
     140                private String coastline;
    164141       
    165142        /**
     
    168145         * @param layer The layer of the way this segment is in
    169146         * @param railway The railway type of the way this segment is in
     147         * @param coastline The coastlyne typo of the way the segment is in
    170148         */
    171         public ExtendedSegment(Segment s, String layer, String railway)
     149        public ExtendedSegment(Segment s, String layer, String railway, String coastline)
    172150        {
    173151            this.s = s;
    174152            this.layer = layer;
    175153            this.railway = railway;
     154            this.coastline = coastline;
    176155        }
    177156       
  • applications/editors/josm/plugins/validator/src/org/openstreetmap/josm/plugins/validator/util/Util.java

    r4122 r4162  
    261261
    262262        // First, round coordinates
    263         long x0 = Math.round(start.from.eastNorth.east()  * 100000);
    264         long y0 = Math.round(start.from.eastNorth.north() * 100000);
    265         long x1 = Math.round(end.to.eastNorth.east()      * 100000);
    266         long y1 = Math.round(end.to.eastNorth.north()     * 100000);
     263        long x0 = Math.round(start.from.eastNorth.east()  * 10000);
     264        long y0 = Math.round(start.from.eastNorth.north() * 10000);
     265        long x1 = Math.round(end.to.eastNorth.east()      * 10000);
     266        long y1 = Math.round(end.to.eastNorth.north()     * 10000);
    267267
    268268        // Start of the way
     
    292292
    293293        // Then floor coordinates, in case the way is in the border of the cell.
    294         x0 = (long)Math.floor(start.from.eastNorth.east()  * 100000);
    295         y0 = (long)Math.floor(start.from.eastNorth.north() * 100000);
    296         x1 = (long)Math.floor(end.to.eastNorth.east()      * 100000);
    297         y1 = (long)Math.floor(end.to.eastNorth.north()     * 100000);
     294        x0 = (long)Math.floor(start.from.eastNorth.east()  * 10000);
     295        y0 = (long)Math.floor(start.from.eastNorth.north() * 10000);
     296        x1 = (long)Math.floor(end.to.eastNorth.east()      * 10000);
     297        y1 = (long)Math.floor(end.to.eastNorth.north()     * 10000);
    298298
    299299        // Start of the way
     
    327327        return cells;
    328328    }   
     329   
     330    /**
     331         * Returns the coordinates of all cells in a grid that a segment goes through.
     332         *
     333         * @param s The segment
     334         * @param gridDetail The detail of the grid. Bigger values give smaller cells, but a bigger number of them.
     335         * @return A list with the coordinates of all cells
     336         */
     337        public static List<Point2D> getSegmentCells(Segment s, int gridDetail)
     338        {
     339                List<Point2D> cells = new ArrayList<Point2D>();
     340                double x0 = s.from.eastNorth.east() * gridDetail;
     341                double x1 = s.to.eastNorth.east()   * gridDetail;
     342        double y0 = s.from.eastNorth.north()* gridDetail + 1;
     343        double y1 = s.to.eastNorth.north()  * gridDetail + 1;
     344
     345        if( x0 > x1 )
     346        {
     347                // Move to 1st-4th cuadrants
     348            double aux;
     349            aux = x0; x0 = x1; x1 = aux;
     350            aux = y0; y0 = y1; y1 = aux;
     351        }
     352       
     353        double dx  = x1 - x0;
     354        double dy  = y1 - y0;
     355        long stepY = y0 <= y1 ? 1 : -1;
     356        long gridX0 = (long)Math.floor(x0);
     357        long gridX1 = (long)Math.floor(x1);
     358        long gridY0 = (long)Math.floor(y0);
     359        long gridY1 = (long)Math.floor(y1);
     360       
     361        long maxSteps = (gridX1 - gridX0) + Math.abs(gridY1 - gridY0) + 1;
     362                while( (gridX0 <= gridX1 && (gridY0 - gridY1)*stepY <= 0) && maxSteps-- > 0)
     363        {
     364                        cells.add( new Point2D.Double(gridX0, gridY0) );
     365                       
     366                // Is the cross between the segment and next vertical line nearer than the cross with next horizontal line?
     367                // Note: segment line formula: y=dy/dx(x-x1)+y1
     368                        // Note: if dy < 0, must use *bottom* line. If dy > 0, must use upper line
     369                double scanY = dy/dx * (gridX0 + 1 - x1) + y1 + (dy < 0 ? -1 : 0);
     370                double scanX = dx/dy * (gridY0 + (dy < 0 ? 0 : 1)*stepY - y1) + x1;
     371               
     372                double distX = Math.pow(gridX0 + 1 - x0, 2) + Math.pow(scanY - y0, 2);
     373                        double distY = Math.pow(scanX - x0, 2) + Math.pow(gridY0 + stepY - y0, 2);
     374                       
     375                        if( distX < distY)
     376                        gridX0 += 1;
     377                else
     378                        gridY0 += stepY;
     379        }
     380               
     381                return cells;
     382        }   
    329383}
Note: See TracChangeset for help on using the changeset viewer.