Changeset 2394 in josm


Ignore:
Timestamp:
2009-11-06T17:55:07+01:00 (10 years ago)
Author:
bastiK
Message:

Relationdialog: show roundabouts in the 'linked' column

Location:
trunk
Files:
2 added
3 edited
3 moved

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableLinkedCellRenderer.java

    r2365 r2394  
    1212
    1313import org.openstreetmap.josm.tools.ImageProvider;
     14import org.openstreetmap.josm.gui.dialogs.relation.WayConnectionType.Direction;
     15
    1416
    1517public class MemberTableLinkedCellRenderer extends MemberTableCellRenderer {
    1618
    17     final static Image arrowUp = ImageProvider.get("dialogs", "arrowup").getImage();
    18     final static Image arrowDown = ImageProvider.get("dialogs", "arrowdown").getImage();
    19     final static Image corners = ImageProvider.get("dialogs", "roundedcorners").getImage();
     19    final static Image arrowUp = ImageProvider.get("dialogs/relation", "arrowup").getImage();
     20    final static Image arrowDown = ImageProvider.get("dialogs/relation", "arrowdown").getImage();
     21    final static Image corners = ImageProvider.get("dialogs/relation", "roundedcorners").getImage();
     22    final static Image roundabout_right = ImageProvider.get("dialogs/relation", "roundabout_right_tiny").getImage();
     23    final static Image roundabout_left = ImageProvider.get("dialogs/relation", "roundabout_left_tiny").getImage();
    2024    private WayConnectionType value = new WayConnectionType();
    2125
     
    3741        if (value == null || !value.isValid()) {
    3842            return;
    39         }
    40 
    41         Image arrow = null;
    42         switch (value.direction) {
    43             case 1:
    44                 arrow = arrowDown;
    45                 break;
    46             case -1:
    47                 arrow = arrowUp;
    48                 break;
    4943        }
    5044
     
    10094        }
    10195
    102         if ((arrow != null) && (value.linkPrev || value.linkNext)) {
    103             g.drawImage(arrow, xoff-3, (y1 + y2) / 2 - 2, null);
    104         }
    105 
     96        /* vertical lines */
    10697        g.setColor(Color.black);
    10798        g.drawLine(xoff, y1, xoff, y2);
     
    109100            g.drawLine(xoff+xloop, y1, xoff+xloop, y2);
    110101        }
    111        
     102
     103        /* special icons */
     104        Image arrow = null;
     105        switch (value.direction) {
     106            case FORWARD:
     107                arrow = arrowDown;
     108                break;
     109            case BACKWARD:
     110                arrow = arrowUp;
     111                break;
     112        }
     113        if ((arrow != null) && (value.linkPrev || value.linkNext)) {
     114            g.drawImage(arrow, xoff-3, (y1 + y2) / 2 - 2, null);
     115        }
     116        else if (value.direction == Direction.ROUNDABOUT_LEFT) {
     117            g.drawImage(roundabout_left, xoff-6, 1, null);
     118        } else if (value.direction == Direction.ROUNDABOUT_RIGHT) {
     119            g.drawImage(roundabout_right, xoff-6, 1, null);
     120        }       
    112121    }
    113122}
  • trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java

    r2375 r2394  
    2020
    2121import org.openstreetmap.josm.Main;
     22import org.openstreetmap.josm.data.coor.EastNorth;
    2223import org.openstreetmap.josm.data.osm.Node;
    2324import org.openstreetmap.josm.data.osm.OsmPrimitive;
     
    2526import org.openstreetmap.josm.data.osm.RelationMember;
    2627import org.openstreetmap.josm.data.osm.Way;
     28import org.openstreetmap.josm.gui.dialogs.relation.WayConnectionType.Direction;
    2729import org.openstreetmap.josm.gui.layer.OsmDataLayer;
     30
     31import static org.openstreetmap.josm.gui.dialogs.relation.WayConnectionType.Direction.*;
    2832
    2933public class MemberTableModel extends AbstractTableModel implements TableModelListener {
     
    669673    }
    670674
    671 /**
    672  * Determines the direction of way k with reference to the way ref_i.
    673  * The direction of way ref_i is ref_direction.
    674  *
    675  * ref_i is usually the predecessor of k.
    676  *
    677  * direction:
    678  * Let the relation be a route of oneway streets, and someone travels them in the given order.
    679  * Direction is 1 for if it is legel and -1 if it is illegal to do so for the given way.
    680  *
    681  * If the two ways are not properly linked the return value is 0.
    682  **/
    683     private int determineDirection(int ref_i,int ref_direction, int k) {
     675    /**
     676     * Determines the direction of way k with respect to the way ref_i.
     677     * The way ref_i is assumed to have the direction ref_direction and
     678     * to be the predecessor of k.
     679     *
     680     * If both ways are not linked in any way, NONE is returned.
     681     *
     682     * Else the direction is given as follows:
     683     * Let the relation be a route of oneway streets, and someone travels them in the given order.
     684     * Direction is FORWARD for if it is legel and BACKWARD if it is illegal to do so for the given way.
     685     *
     686     **/
     687    private Direction determineDirection(int ref_i,Direction ref_direction, int k) {
    684688        if (ref_i < 0 || k < 0 || ref_i >= members.size() || k >= members.size()) {
    685             return 0;
    686         }
    687         if (ref_direction == 0) {
    688             return 0;
     689            return NONE;
     690        }
     691        if (ref_direction == NONE) {
     692            return NONE;
    689693        }
    690694       
     
    702706       
    703707        if (way_ref == null || way == null) {
    704             return 0;
    705         }
     708            return NONE;
     709        }
     710
     711        /** the list of nodes the way k can dock to */
     712        List<Node> refNodes= new ArrayList<Node>();
    706713       
    707         Node nRef = ref_direction > 0 ? way_ref.lastNode() : way_ref.firstNode();
    708         if (nRef == null) {
    709             return 0;
     714        switch (ref_direction) {
     715            case FORWARD:
     716                refNodes.add(way_ref.lastNode());
     717                break;
     718            case BACKWARD:
     719                refNodes.add(way_ref.firstNode());
     720                break;
     721            case ROUNDABOUT_LEFT:
     722            case ROUNDABOUT_RIGHT:
     723                refNodes = way_ref.getNodes();
     724                break;
     725        }
     726                   
     727        if (refNodes == null) {
     728            return NONE;
    710729        }
    711730       
    712         if (nRef == way.firstNode()) {
    713             return 1;
    714         }
    715         if (nRef == way.lastNode()) {
    716             return -1;
    717         }
    718         return 0;
    719     }
    720 
     731        for (Node n : refNodes) {
     732            if (n == null) continue;
     733            if (roundaboutType(k) != NONE) {
     734                for (Node nn : way.getNodes()) {
     735                    if (n == nn) {
     736                        return roundaboutType(k);
     737                    }
     738                }
     739            } else {
     740                if (n == way.firstNode()) {
     741                    return FORWARD;
     742                }
     743                if (n == way.lastNode()) {
     744                    return BACKWARD;
     745                }
     746            }
     747        }
     748        return NONE;
     749    }
     750
     751    /**
     752     * determine, if the way i is a roundabout and if yes, what type of roundabout
     753     */
     754    private Direction roundaboutType(int i) {
     755        RelationMember m = members.get(i);
     756        if (m == null || !m.isWay()) return NONE;
     757        Way w = m.getWay();
     758        if (w != null &&       
     759                "roundabout".equals(w.get("junction")) &&
     760                w.getNodesCount() < 200 &&
     761                w.getNodesCount() > 2 &&
     762                w.getNode(0) != null &&
     763                w.getNode(1) != null &&
     764                w.getNode(2) != null &&
     765                w.firstNode() == w.lastNode()) {
     766            /** do some simple determinant / cross pruduct test on the first 3 nodes
     767                to see, if the roundabout goes clock wise or ccw */
     768            EastNorth en1 = w.getNode(0).getEastNorth();
     769            EastNorth en2 = w.getNode(1).getEastNorth();
     770            EastNorth en3 = w.getNode(2).getEastNorth();
     771            en1 = en1.sub(en2);
     772            en2 = en2.sub(en3);
     773            return en1.north() * en2.east() - en2.north() * en1.east() > 0 ? ROUNDABOUT_LEFT : ROUNDABOUT_RIGHT;
     774        } else
     775            return NONE;
     776    }
     777   
    721778    private WayConnectionType wayConnection(int i) {
    722779        if (connectionType == null) {
     
    730787    }
    731788
     789    /**
     790     * refresh the cache of member WayConnectionTypes
     791     */
    732792    public void updateLinks() {
    733793        connectionType = null;
     
    761821            boolean linkPrev = (i != firstGroupIdx);
    762822            boolean linkNext;
    763             int dir;
     823            Direction dir;
    764824            if (linkPrev) {
    765825                dir = determineDirection(i-1, con.get(i-1).direction, i);
    766                 linkNext = (determineDirection(i, dir, i+1) != 0);
     826                linkNext = (determineDirection(i, dir, i+1) != NONE);
    767827            }
    768828            else {
    769                 dir = determineDirection(i, +1, i+1) != 0 ? +1 : 0;
    770                 if (dir == 0) {
    771                     dir = determineDirection(i, -1, i+1) != 0 ? -1 : 0;
    772                 }
    773                 linkNext = (dir != 0);
     829                if (roundaboutType(i) != NONE) {
     830                    dir = determineDirection(i, roundaboutType(i), i+1) != NONE ? roundaboutType(i) : NONE;
     831                } else { /** guess the direction and see if it fits with the next member */
     832                    dir = determineDirection(i, FORWARD, i+1) != NONE ? FORWARD : NONE;
     833                    if (dir == NONE) {
     834                        dir = determineDirection(i, BACKWARD, i+1) != NONE ? BACKWARD : NONE;
     835                    }
     836                }
     837                linkNext = (dir != NONE);
     838                if (dir == NONE) {
     839                    if (roundaboutType(i) != NONE) {
     840                        dir = roundaboutType(i);
     841                    }
     842                }
     843                   
    774844            }
    775845
     
    779849                boolean loop;
    780850                if (i == firstGroupIdx) {
    781                     loop = determineDirection(i, 1, i) == 1;
     851                    loop = determineDirection(i, FORWARD, i) == FORWARD;
    782852                } else {
    783853                    loop = determineDirection(i, dir, firstGroupIdx) == con.get(firstGroupIdx).direction;
     
    792862        }
    793863        connectionType = con;
     864//        for (int i=0; i<con.size(); ++i) {
     865//            System.err.println(con.get(i));
     866//        }
    794867    }
    795868}
  • trunk/src/org/openstreetmap/josm/gui/dialogs/relation/WayConnectionType.java

    r2365 r2394  
    33
    44import static org.openstreetmap.josm.tools.I18n.tr;
     5
     6import static org.openstreetmap.josm.gui.dialogs.relation.WayConnectionType.Direction.*;
    57
    68public class WayConnectionType {
     
    1416
    1517    /**
    16      * direction is +1 if the first node of this way is connected to the previous way
     18     * direction is FORWARD if the first node of this way is connected to the previous way
    1719     * and / or the last node of this way is connected to the next way.
    18      * direction is -1 if it is the other way around.
    19      * If this way is neither connected to the previous nor to the next way, then
    20      * direction has the value 0.
     20     * direction is BACKWARD if it is the other way around.
     21     * direction has a ROUNDABOUT value, if it is tagged as such and it is somehow
     22     * connected to the previous / next member.
     23     * If there is no connection to the previous or next member, then
     24     * direction has the value NONE.
    2125     */
    22     public final int direction;
     26    public final Direction direction;
     27   
     28    public enum Direction {
     29        FORWARD, BACKWARD, ROUNDABOUT_LEFT, ROUNDABOUT_RIGHT, NONE;
     30       
     31        public boolean isRoundabout() {
     32            return this == ROUNDABOUT_RIGHT || this == ROUNDABOUT_LEFT;
     33        }   
     34    };
    2335
    2436    /** True, if the element is part of a closed loop of ways. */
    2537    public boolean isLoop;
    2638
    27     public WayConnectionType(boolean linkPrev, boolean linkNext, int direction) {
     39    public boolean isRoundabout = false;
     40   
     41    public WayConnectionType(boolean linkPrev, boolean linkNext, Direction direction) {
    2842        this.linkPrev = linkPrev;
    2943        this.linkNext = linkNext;
     
    3852        this.linkNext = false;
    3953        this.isLoop = false;
    40         this.direction = 0;
     54        this.direction = NONE;
    4155        invalid = true;
    4256    }
Note: See TracChangeset for help on using the changeset viewer.