Changeset 2890

Show
Ignore:
Timestamp:
24.01.2010 17:55:56 (6 months ago)
Author:
bastiK
Message:

Reverse Arrows for 'oneway=-1' and similar (see #2387).
More efficient calculation of arrow geometry.
Test file for Arrow direction added.

Location:
trunk
Files:
1 added
3 modified

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java

    r2883 r2890  
    108108    private static final int FLAG_HAS_DIRECTIONS = 1 << 5; 
    109109    private static final int FLAG_TAGGED = 1 << 6; 
     110    private static final int FLAG_DIRECTION_REVERSED = 1 << 7; 
    110111 
    111112    /** 
     
    532533 
    533534    private static volatile Match directionKeys = null; 
     535    private static volatile Match reversedDirectionKeys = null; 
    534536 
    535537    /** 
     
    538540     * Initialized by checkDirectionTagged() 
    539541     */ 
    540     public static void initDirectionKeys() { 
    541         if(directionKeys == null) { 
    542  
    543             // Legacy support - convert list of keys to search pattern 
    544             if (Main.pref.isCollection("tags.direction", false)) { 
    545                 System.out.println("Collection of keys in tags.direction is no longer supported, value will converted to search pattern"); 
    546                 Collection<String> keys = Main.pref.getCollection("tags.direction", null); 
    547                 StringBuilder builder = new StringBuilder(); 
    548                 for (String key:keys) { 
    549                     builder.append(key); 
    550                     builder.append("=* | "); 
    551                 } 
    552                 builder.delete(builder.length() - 3, builder.length()); 
    553                 Main.pref.put("tags.direction", builder.toString()); 
    554             } 
    555  
    556             String defaultValue = "oneway? | incline=* | incline_steep=* | aerialway=* | waterway=stream | waterway=river | waterway=canal | waterway=drain | \"piste:type\"=downhill | \"piste:type\"=sled | man_made=\"piste:halfpipe\" "; 
     542    static { 
     543        // Legacy support - convert list of keys to search pattern 
     544        if (Main.pref.isCollection("tags.direction", false)) { 
     545            System.out.println("Collection of keys in tags.direction is no longer supported, value will converted to search pattern"); 
     546            Collection<String> keys = Main.pref.getCollection("tags.direction", null); 
     547            StringBuilder builder = new StringBuilder(); 
     548            for (String key:keys) { 
     549                builder.append(key); 
     550                builder.append("=* | "); 
     551            } 
     552            builder.delete(builder.length() - 3, builder.length()); 
     553            Main.pref.put("tags.direction", builder.toString()); 
     554        } 
     555 
     556        String reversedDirectionDefault = "oneway=\"-1\" | incline=down | incline=\"-*\""; 
     557        String directionDefault = "oneway? | incline=* | aerialway=* | waterway=stream | waterway=river | waterway=canal | waterway=drain | waterway=rapids | \"piste:type\"=downhill | \"piste:type\"=sled | man_made=\"piste:halfpipe\" "; 
     558 
     559        try { 
     560            reversedDirectionKeys = SearchCompiler.compile(Main.pref.get("tags.reversed_direction", reversedDirectionDefault), false, false); 
     561        } catch (ParseError e) { 
     562            System.err.println("Unable to compile pattern for tags.reversed_direction, trying default pattern: " + e.getMessage()); 
     563 
    557564            try { 
    558                 directionKeys = SearchCompiler.compile(Main.pref.get("tags.direction", defaultValue), false, false); 
    559             } catch (ParseError e) { 
    560                 System.err.println("Unable to compile pattern for tags.direction, trying default pattern: " + e.getMessage()); 
    561  
    562                 try { 
    563                     directionKeys = SearchCompiler.compile(defaultValue, false, false); 
    564                 } catch (ParseError e2) { 
    565                     throw new AssertionError("Unable to compile default pattern for direction keys: " + e2.getMessage()); 
    566                 } 
     565                reversedDirectionKeys = SearchCompiler.compile(reversedDirectionDefault, false, false); 
     566            } catch (ParseError e2) { 
     567                throw new AssertionError("Unable to compile default pattern for direction keys: " + e2.getMessage()); 
     568            } 
     569        } 
     570        try { 
     571            directionKeys = SearchCompiler.compile(Main.pref.get("tags.direction", directionDefault), false, false); 
     572        } catch (ParseError e) { 
     573            System.err.println("Unable to compile pattern for tags.direction, trying default pattern: " + e.getMessage()); 
     574 
     575            try { 
     576                directionKeys = SearchCompiler.compile(directionDefault, false, false); 
     577            } catch (ParseError e2) { 
     578                throw new AssertionError("Unable to compile default pattern for direction keys: " + e2.getMessage()); 
    567579            } 
    568580        } 
     
    576588     * direction dependent. 
    577589     */ 
     590    @Deprecated 
    578591    public static Collection<String> getDirectionKeys() { 
    579592        return Main.pref.getCollection("tags.direction", 
     
    863876    private void keysChangedImpl(Map<String, String> originalKeys) { 
    864877        clearCached(); 
    865         updateHasDirectionKeys(); 
     878        updateDirectionFlags(); 
    866879        updateTagged(); 
    867880        if (dataSet != null) { 
     
    11261139    } 
    11271140 
    1128     private void updateHasDirectionKeys() { 
    1129         initDirectionKeys(); 
     1141    private void updateDirectionFlags() { 
     1142        boolean hasDirections = false; 
     1143        boolean directionReversed = false; 
     1144        if (reversedDirectionKeys.match(this)) { 
     1145            hasDirections = true; 
     1146            directionReversed = true; 
     1147        } 
    11301148        if (directionKeys.match(this)) { 
     1149            hasDirections = true; 
     1150        } 
     1151 
     1152        if (directionReversed) { 
     1153            flags |= FLAG_DIRECTION_REVERSED; 
     1154        } else { 
     1155            flags &= ~FLAG_DIRECTION_REVERSED; 
     1156        } 
     1157        if (hasDirections) { 
    11311158            flags |= FLAG_HAS_DIRECTIONS; 
    11321159        } else { 
     
    11421169    } 
    11431170 
     1171    public boolean reversedDirection() { 
     1172        return (flags & FLAG_DIRECTION_REVERSED) != 0; 
     1173    } 
    11441174    /** 
    11451175     * Replies the name of this primitive. The default implementation replies the value 
     
    12221252 
    12231253    protected String getFlagsAsString() { 
    1224  
    12251254        StringBuilder builder = new StringBuilder(); 
    12261255 
     
    12401269            builder.append("f"); 
    12411270        } 
    1242  
    1243         if (isDeleted()) { 
     1271        if (isDisabled()) { 
    12441272            builder.append("d"); 
    12451273        } 
    1246  
     1274        if (isTagged()) { 
     1275            builder.append("T"); 
     1276        } 
     1277        if (hasDirectionKeys()) { 
     1278            if (reversedDirection()) { 
     1279                builder.append("<"); 
     1280            } else { 
     1281                builder.append(">"); 
     1282            } 
     1283        } 
    12471284        return builder.toString(); 
    12481285    } 
  • trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPainter.java

    r2801 r2890  
    2727 
    2828public class MapPainter { 
    29     private static final double PHI = Math.toRadians(20); 
    30  
    3129    private final Graphics2D g; 
    3230    private final NavigatableComponent nc; 
     
    8179 
    8280    public void drawWay(Way way, Color color, int width, float dashed[], Color dashedColor, boolean showDirection, 
    83             boolean showHeadArrowOnly) { 
     81            boolean reversedDirection, boolean showHeadArrowOnly) { 
    8482 
    8583        GeneralPath path = new GeneralPath(); 
     
    9189            Point p = nc.getPoint(n); 
    9290            if(lastPoint != null) { 
    93                 drawSegment(path, lastPoint, p, (showHeadArrowOnly ? !it.hasNext() : showDirection)); 
     91                drawSegment(path, lastPoint, p, showHeadArrowOnly ? !it.hasNext() : showDirection, reversedDirection); 
    9492            } 
    9593            lastPoint = p; 
     
    128126    } 
    129127 
    130     private void drawSegment(GeneralPath path, Point p1, Point p2, boolean showDirection) { 
     128    private static final double PHI = Math.toRadians(20); 
     129    private static final double cosPHI = Math.cos(PHI); 
     130    private static final double sinPHI = Math.sin(PHI); 
     131 
     132    private void drawSegment(GeneralPath path, Point p1, Point p2, boolean showDirection, boolean reversedDirection) { 
    131133        if (isSegmentVisible(p1, p2)) { 
     134 
     135            /* draw segment line */ 
    132136            path.moveTo(p1.x, p1.y); 
    133137            path.lineTo(p2.x, p2.y); 
    134138 
     139            /* draw arrow */ 
    135140            if (showDirection) { 
    136                 double t = Math.atan2(p2.y-p1.y, p2.x-p1.x) + Math.PI; 
    137                 path.lineTo((int)(p2.x + 10*Math.cos(t-PHI)), (int)(p2.y + 10*Math.sin(t-PHI))); 
    138                 path.moveTo((int)(p2.x + 10*Math.cos(t+PHI)), (int)(p2.y + 10*Math.sin(t+PHI))); 
    139                 path.lineTo(p2.x, p2.y); 
     141                Point q1 = p1; 
     142                Point q2 = p2; 
     143                if (reversedDirection) { 
     144                    q1 = p2; 
     145                    q2 = p1; 
     146                    path.moveTo(q2.x, q2.y); 
     147                } 
     148                final double l =  10. / q1.distance(q2); 
     149 
     150                final double sx = l * (q1.x - q2.x); 
     151                final double sy = l * (q1.y - q2.y); 
     152 
     153                path.lineTo (q2.x + (int) Math.round(cosPHI * sx - sinPHI * sy), q2.y + (int) Math.round(sinPHI * sx + cosPHI * sy)); 
     154                path.moveTo (q2.x + (int) Math.round(cosPHI * sx + sinPHI * sy), q2.y + (int) Math.round(- sinPHI * sx + cosPHI * sy)); 
     155                path.lineTo(q2.x, q2.y); 
    140156            } 
    141157        } 
  • trunk/src/org/openstreetmap/josm/gui/mappaint/LineElemStyle.java

    r2675 r2890  
    146146        boolean showDirection = selected || ((!paintSettings.isUseRealWidth()) && (paintSettings.isShowDirectionArrow() 
    147147                && (!paintSettings.isShowRelevantDirectionsOnly() || w.hasDirectionKeys()))); 
     148        boolean reversedDirection = w.reversedDirection(); 
    148149        /* head only takes over control if the option is true, 
    149150        the direction should be shown at all and not only because it's selected */ 
     
    189190                if(!s.over) { 
    190191                    painter.drawWay(w, s.color != null && selected ? myColor: s.color, s.getWidth(myWidth), 
    191                             s.getDashed(), s.dashedColor, false, false); 
     192                            s.getDashed(), s.dashedColor, false, false, false); 
    192193                } 
    193194            } 
     
    195196 
    196197        /* draw the way */ 
    197         painter.drawWay(w, myColor, myWidth, dashed, dashedColor, showDirection, showOnlyHeadArrowOnly); 
     198        painter.drawWay(w, myColor, myWidth, dashed, dashedColor, showDirection, selected ? false : reversedDirection, showOnlyHeadArrowOnly); 
    198199 
    199200        /* draw overlays above the way */ 
     
    202203                if(s.over) { 
    203204                    painter.drawWay(w, s.color != null && selected ? myColor : s.color, s.getWidth(myWidth), 
    204                             s.getDashed(), s.dashedColor, false, false); 
     205                            s.getDashed(), s.dashedColor, false, false, false); 
    205206                } 
    206207            }