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

Relationdialog: show roundabouts in the 'linked' column

File:
1 edited

Legend:

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