Changeset 2890 in josm


Ignore:
Timestamp:
2010-01-24T17:55:56+01:00 (10 years 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 edited

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            }
Note: See TracChangeset for help on using the changeset viewer.