Changeset 2365 in josm for trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java
- Timestamp:
- 2009-10-31T21:18:59+01:00 (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java
r2317 r2365 16 16 import javax.swing.ListSelectionModel; 17 17 import javax.swing.table.AbstractTableModel; 18 import javax.swing.event.TableModelListener; 19 import javax.swing.event.TableModelEvent; 18 20 19 21 import org.openstreetmap.josm.Main; … … 25 27 import org.openstreetmap.josm.gui.layer.OsmDataLayer; 26 28 27 public class MemberTableModel extends AbstractTableModel { 28 29 public 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 **/ 29 34 private ArrayList<RelationMember> members; 35 private ArrayList<WayConnectionType> connectionType = null; 36 30 37 private DefaultListSelectionModel listSelectionModel; 31 38 private CopyOnWriteArrayList<IMemberModelListener> listeners; … … 39 46 listeners = new CopyOnWriteArrayList<IMemberModelListener>(); 40 47 this.layer = layer; 48 addTableModelListener(this); 41 49 } 42 50 … … 99 107 public boolean isCellEditable(int rowIndex, int columnIndex) { 100 108 return columnIndex == 0; 101 }102 103 @Override104 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);109 109 } 110 110 … … 661 661 } 662 662 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; 704 711 } 705 712 706 713 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; 729 786 } 730 787 }
Note:
See TracChangeset
for help on using the changeset viewer.