Ignore:
Timestamp:
2009-10-31T21:18:59+01:00 (14 years ago)
Author:
Gubaer
Message:

applied #3771: patch by bastiK: add nicer symbols for relation member connectedness

File:
1 edited

Legend:

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

    r2317 r2365  
    1616import javax.swing.ListSelectionModel;
    1717import javax.swing.table.AbstractTableModel;
     18import javax.swing.event.TableModelListener;
     19import javax.swing.event.TableModelEvent;
    1820
    1921import org.openstreetmap.josm.Main;
     
    2527import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    2628
    27 public class MemberTableModel extends AbstractTableModel {
    28 
     29public class MemberTableModel extends AbstractTableModel implements TableModelListener {
     30
     31    /**
     32     * data of the table model: The list of members and the cached WayConnectionType of each member.
     33     **/
    2934    private ArrayList<RelationMember> members;
     35    private ArrayList<WayConnectionType> connectionType = null;
     36   
    3037    private DefaultListSelectionModel listSelectionModel;
    3138    private CopyOnWriteArrayList<IMemberModelListener> listeners;
     
    3946        listeners = new CopyOnWriteArrayList<IMemberModelListener>();
    4047        this.layer = layer;
     48        addTableModelListener(this);
    4149    }
    4250
     
    99107    public boolean isCellEditable(int rowIndex, int columnIndex) {
    100108        return columnIndex == 0;
    101     }
    102 
    103     @Override
    104     public void setValueAt(Object value, int rowIndex, int columnIndex) {
    105         RelationMember member = members.get(rowIndex);
    106         RelationMember newMember = new RelationMember(value.toString(), member.getMember());
    107         members.remove(rowIndex);
    108         members.add(rowIndex, newMember);
    109109    }
    110110
     
    661661    }
    662662
    663     // simple version of code that was removed from GenericReleationEditor
    664     // no recursion and no forward/backward support
    665     // TODO: add back the number of linked elements
    666     // Returns +1 if member i and (i+1) are ways and could be combined without changing
    667     // the direction of one of them. If they are linked "head to head" or "tail to tail"
    668     // -1 is returned.
    669     // In all other cases the result is null.
    670     private Integer linked(int i) {
    671         // this method is aimed at finding out whether the
    672         // relation member is "linked" with the next, i.e. whether
    673         // (if both are ways) these ways are connected.
    674 
    675         Integer link = null;
    676         RelationMember m1 = members.get(i);
    677         RelationMember m2 = members.get((i + 1) % members.size());
    678         Way way1 = null;
    679         Way way2 = null;
    680 
    681         if (m1.isWay()) {
    682             way1 = m1.getWay();
    683         }
    684         if (m2.isWay()) {
    685             way2 = m2.getWay();
    686         }
    687         if ((way1 != null) && (way2 != null)) {
    688             Node way1first = way1.firstNode();
    689             Node way1last = way1.lastNode();
    690             Node way2first = way2.firstNode();
    691             Node way2last = way2.lastNode();
    692             if (way1first != null && way2first != null && (way1first == way2first)) {
    693                 link = -1;
    694             } else if (way1first != null && way2last != null && (way1first == way2last)) {
    695                 link = 1;
    696             } else if (way1last != null && way2first != null && (way1last == way2first)) {
    697                 link = 1;
    698             } else if (way1last != null && way2last != null && (way1last == way2last)) {
    699                 link = -1;
    700             }
    701         }
    702 
    703         return link;
     663/**
     664 * Determines the direction of way k with reference to the way ref_i.
     665 * The direction of way ref_i is ref_direction.
     666 *
     667 * ref_i is usually the predecessor of k.
     668 *
     669 * direction:
     670 * Let the relation be a route of oneway streets, and someone travels them in the given order.
     671 * Direction is 1 for if it is legel and -1 if it is illegal to do so for the given way.
     672 *
     673 * If the two ways are not properly linked the return value is 0.
     674 **/
     675    private int determineDirection(int ref_i,int ref_direction, int k) {
     676        if (ref_i < 0 || k < 0 || ref_i >= members.size() || k >= members.size()) {
     677            return 0;
     678        }
     679        if (ref_direction == 0) {
     680            return 0;
     681        }
     682       
     683        RelationMember m_ref = members.get(ref_i);
     684        RelationMember m = members.get(k);
     685        Way way_ref = null;
     686        Way way = null;
     687
     688        if (m_ref.isWay()) {
     689            way_ref = m_ref.getWay();
     690        }
     691        if (m.isWay()) {
     692            way = m.getWay();
     693        }
     694       
     695        if (way_ref == null || way == null) {
     696            return 0;
     697        }
     698       
     699        Node nRef = ref_direction > 0 ? way_ref.lastNode() : way_ref.firstNode();
     700        if (nRef == null) {
     701            return 0;
     702        }
     703       
     704        if (nRef == way.firstNode()) {
     705            return 1;
     706        }
     707        if (nRef == way.lastNode()) {
     708            return -1;
     709        }
     710        return 0;
    704711    }
    705712
    706713    private WayConnectionType wayConnection(int i) {
    707         RelationMember m = members.get(i);
    708         if (! m.isWay())
    709             return new WayConnectionType();
    710         Way w = m.getWay();
    711         if (w == null || w.incomplete)
    712             return new WayConnectionType();
    713 
    714         int ip = (i - 1 + members.size()) % members.size();
    715         Integer link_p = linked(ip);
    716         Integer link_n = linked(i);
    717         Integer dir = 1;
    718         // FIXME: It is somewhat stupid to loop here, but
    719         // there shouldn't be a performance problem in practice.
    720         for (int k = i - 1; k >= 0; --k) {
    721             Integer link = linked(k);
    722             if (link != null) {
    723                 dir *= link;
    724             } else {
    725                 break;
    726             }
    727         }
    728         return new WayConnectionType(link_p != null, link_n != null, dir);
     714        if (connectionType == null) {
     715            updateLinks();
     716        }
     717        return connectionType.get(i);
     718    }
     719
     720    public void tableChanged(TableModelEvent e) {
     721        connectionType = null;
     722    }
     723
     724    public void updateLinks() {
     725        connectionType = null;
     726        ArrayList<WayConnectionType> con = new ArrayList<WayConnectionType>();
     727
     728        for (int i=0; i<members.size(); ++i) con.add(null);
     729
     730        int firstGroupIdx=0;
     731        boolean resetFirstGoupIdx=false;
     732
     733        for (int i=0; i<members.size(); ++i) {
     734            if (resetFirstGoupIdx) {
     735                firstGroupIdx = i;
     736                resetFirstGoupIdx = false;
     737            }
     738
     739            RelationMember m = members.get(i);
     740            if (! m.isWay()) {
     741                con.set(i, new WayConnectionType());
     742                resetFirstGoupIdx = true;
     743                continue;
     744            }
     745
     746            Way w = m.getWay();
     747            if (w == null || w.incomplete) {
     748                con.set(i, new WayConnectionType());
     749                resetFirstGoupIdx = true;
     750                continue;
     751            }
     752
     753            boolean linkPrev = (i != firstGroupIdx);
     754            boolean linkNext;
     755            int dir;
     756            if (linkPrev) {
     757                dir = determineDirection(i-1, con.get(i-1).direction, i);
     758                linkNext = (determineDirection(i, dir, i+1) != 0);
     759            }
     760            else {
     761                dir = determineDirection(i, +1, i+1) != 0 ? +1 : 0;
     762                if (dir == 0) {
     763                    dir = determineDirection(i, -1, i+1) != 0 ? -1 : 0;
     764                }
     765                linkNext = (dir != 0);
     766            }
     767
     768            con.set(i, new WayConnectionType(linkPrev, linkNext, dir));
     769
     770            if (! linkNext) {
     771                boolean loop;
     772                if (i == firstGroupIdx) {
     773                    loop = determineDirection(i, 1, i) == 1;
     774                } else {
     775                    loop = determineDirection(i, dir, firstGroupIdx) == con.get(firstGroupIdx).direction;
     776                }
     777                if (loop) {
     778                    for (int j=firstGroupIdx; j <= i; ++j) {
     779                        con.get(j).isLoop = true;
     780                    }
     781                }
     782                resetFirstGoupIdx = true;
     783            }
     784        }
     785        connectionType = con;
    729786    }
    730787}
Note: See TracChangeset for help on using the changeset viewer.