- Timestamp:
- 2009-10-31T21:18:59+01:00 (15 years ago)
- Location:
- trunk/src/org/openstreetmap/josm/gui/dialogs/relation
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableLinkedCellRenderer.java
r2311 r2365 17 17 final static Image arrowUp = ImageProvider.get("dialogs", "arrowup").getImage(); 18 18 final static Image arrowDown = ImageProvider.get("dialogs", "arrowdown").getImage(); 19 final static Image corners = ImageProvider.get("dialogs", "roundedcorners").getImage(); 19 20 private WayConnectionType value = new WayConnectionType(); 20 21 … … 34 35 public void paintComponent(Graphics g) { 35 36 super.paintComponent(g); 36 if (value == null || value.invalid) {37 if (value == null || !value.isValid()) { 37 38 return; 38 39 } 39 40 40 Image image= null;41 Image arrow = null; 41 42 switch (value.direction) { 42 43 case 1: 43 image= arrowDown;44 arrow = arrowDown; 44 45 break; 45 46 case -1: 46 image= arrowUp;47 arrow = arrowUp; 47 48 break; 48 49 } 49 50 50 51 int ymax=this.getSize().height - 1; 52 int xloop = 8; 51 53 int xoff = this.getSize().width / 2; 54 if (value.isLoop) { 55 xoff -= xloop / 2 - 1; 56 } 52 57 int w = 2; 53 58 int p = 2 + w + 1; … … 55 60 int y2 = 0; 56 61 57 if (image != null && (value.connectedToPrevious || value.connectedToNext)) { 58 g.drawImage(image, xoff-3, ymax / 2 - 2, null); 62 63 if (value.linkPrev) { 64 g.setColor(Color.black); 65 g.fillRect(xoff - 1, 0, 3, 1); 66 y1 = 0; 67 } else { 68 if (value.isLoop) { 69 g.setColor(Color.black); 70 y1 = 5; 71 g.drawImage(corners,xoff,y1-3,xoff+3,y1, 0,0,3,3, new Color(0,0,0,0), null); 72 g.drawImage(corners,xoff+xloop-2,y1-3,xoff+xloop+1,y1, 2,0,5,3, new Color(0,0,0,0), null); 73 g.drawLine(xoff+3,y1-3,xoff+xloop-3,y1-3); 74 } 75 else { 76 g.setColor(Color.red); 77 g.drawRect(xoff-1, p - 1 - w, w, w); 78 y1 = p; 79 } 59 80 } 60 81 61 if (value. connectedToPrevious) {82 if (value.linkNext) { 62 83 g.setColor(Color.black); 63 g.fillRect(xoff - 2, 0, 5, 2);64 y 1 = 0;84 g.fillRect(xoff - 1, ymax, 3, 1); 85 y2 = ymax; 65 86 } else { 66 g.setColor(Color.red); 67 g.drawRect(xoff-1, p - 1 - w, w, w); 68 y1 = p; 87 if (value.isLoop) { 88 g.setColor(Color.black); 89 y2 = ymax - 5; 90 g.fillRect(xoff-1, y2+2, 3, 3); 91 g.drawLine(xoff, y2, xoff, y2+2); 92 g.drawImage(corners,xoff+xloop-2,y2+1,xoff+xloop+1,y2+4, 2,2,5,5, new Color(0,0,0,0), null); 93 g.drawLine(xoff+3-1,y2+3,xoff+xloop-3,y2+3); 94 } 95 else { 96 g.setColor(Color.red); 97 g.drawRect(xoff-1, ymax - p + 1, w, w); 98 y2 = ymax - p; 99 } 69 100 } 70 101 71 if (value.connectedToNext) { 72 g.setColor(Color.black); 73 g.fillRect(xoff - 2, ymax - 1, 5, 2); 74 y2 = ymax; 75 } else { 76 g.setColor(Color.red); 77 g.drawRect(xoff-1, ymax - p + 1, w, w); 78 y2 = ymax - p; 102 if ((arrow != null) && (value.linkPrev || value.linkNext)) { 103 g.drawImage(arrow, xoff-3, (y1 + y2) / 2 - 2, null); 79 104 } 105 80 106 g.setColor(Color.black); 81 107 g.drawLine(xoff, y1, xoff, y2); 108 if (value.isLoop) { 109 g.drawLine(xoff+xloop, y1, xoff+xloop, y2); 110 } 111 82 112 } 83 113 } -
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 } -
trunk/src/org/openstreetmap/josm/gui/dialogs/relation/RelationNodeMap.java
r1938 r2365 2 2 3 3 import java.util.ArrayList; 4 import java.util.TreeSet; 4 5 5 6 import org.openstreetmap.josm.data.osm.Node; … … 14 15 */ 15 16 public class RelationNodeMap { 16 private java.util.HashMap<Node, java.util.TreeSet<Integer>> points; 17 /** 18 * For each way endpoint, list all ways that share this node 19 */ 20 private java.util.HashMap<Node, TreeSet<Integer>> points; 21 /** 22 * Singleton nodes 23 */ 17 24 private java.util.HashMap<Node, Integer> nodes; 18 25 private java.util.Vector<Integer> remaining; 19 private ArrayList<RelationMember> members; 26 /** 27 * read only list 28 */ 29 private final ArrayList<RelationMember> members; 20 30 21 31 RelationNodeMap(ArrayList<RelationMember> members) { … … 23 33 24 34 this.members = members; 25 points = new java.util.HashMap<Node, java.util.TreeSet<Integer>>();35 points = new java.util.HashMap<Node, TreeSet<Integer>>(); 26 36 nodes = new java.util.HashMap<Node, Integer>(); 27 37 remaining = new java.util.Vector<Integer>(); … … 63 73 if (w.lastNode() == w.firstNode()) 64 74 { 65 nodes.put(w.firstNode(), Integer.valueOf(n));75 nodes.put(w.firstNode(), n); 66 76 } 67 77 else 68 78 { 69 79 if (!points.containsKey(w.firstNode())) { 70 points.put(w.firstNode(), new java.util.TreeSet<Integer>());80 points.put(w.firstNode(), new TreeSet<Integer>()); 71 81 } 72 points.get(w.firstNode()).add( Integer.valueOf(n));82 points.get(w.firstNode()).add(n); 73 83 74 84 if (!points.containsKey(w.lastNode())) { 75 points.put(w.lastNode(), new java.util.TreeSet<Integer>());85 points.put(w.lastNode(), new TreeSet<Integer>()); 76 86 } 77 points.get(w.lastNode()).add( Integer.valueOf(n));87 points.get(w.lastNode()).add(n); 78 88 } 79 89 } else if (m.isNode()) { 80 90 Node node = m.getNode(); 81 nodes.put(node, Integer.valueOf(n));91 nodes.put(node, n); 82 92 } else { 83 remaining.add( Integer.valueOf(n));93 remaining.add(n); 84 94 } 85 95 } … … 104 114 } 105 115 106 void move(int from, int to) {107 if (from != to) {108 RelationMember b = members.get(from);109 RelationMember a = members.get(to);110 111 remove(to, b);112 add(to, a);113 }114 }115 116 116 // no node-mapped entries left 117 117 boolean isEmpty() { … … 132 132 nodes.remove(node); 133 133 } else if (!points.isEmpty()) { 134 for ( java.util.TreeSet<Integer> set : points.values()) {134 for (TreeSet<Integer> set : points.values()) { 135 135 if (!set.isEmpty()) { 136 136 result = set.first(); -
trunk/src/org/openstreetmap/josm/gui/dialogs/relation/WayConnectionType.java
r2311 r2365 6 6 public class WayConnectionType { 7 7 8 public final boolean connectedToPrevious; 9 public final boolean connectedToNext; 10 /** Is 1 if way has the same direction as the first way in the set of connected ways. Else it is (-1) */ 8 /** True, if the corresponding primitive is not a way or the way is incomplete */ 9 private final boolean invalid; 10 11 /** True, if linked to the previous / next member. */ 12 public final boolean linkPrev; 13 public final boolean linkNext; 14 15 /** 16 * direction is +1 if the first node of this way is connected to the previous way 17 * 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. 21 */ 11 22 public final int direction; 12 /** The WayConnectionType is invalid, if the corresponding primitive is not a way or the way is incomplete */13 public final boolean invalid;14 23 15 public WayConnectionType(boolean connectedToPrevious, boolean connectedToNext, int direction) { 16 this.connectedToPrevious = connectedToPrevious; 17 this.connectedToNext = connectedToNext; 24 /** True, if the element is part of a closed loop of ways. */ 25 public boolean isLoop; 26 27 public WayConnectionType(boolean linkPrev, boolean linkNext, int direction) { 28 this.linkPrev = linkPrev; 29 this.linkNext = linkNext; 30 this.isLoop = false; 18 31 this.direction = direction; 19 32 invalid = false; 20 33 } 21 34 35 /** construct invalid instance */ 22 36 public WayConnectionType() { 23 connectedToPrevious = false; 24 connectedToNext = false; 25 direction = 1; 37 this.linkPrev = false; 38 this.linkNext = false; 39 this.isLoop = false; 40 this.direction = 0; 26 41 invalid = true; 27 42 } 43 44 public boolean isValid() { 45 return !invalid; 46 } 28 47 29 //@Override30 //public String toString() {31 // return ... 32 //}48 @Override 49 public String toString() { 50 return "[P "+linkPrev+" ;N "+linkNext+" ;D "+direction+" ;L "+isLoop+"]"; 51 } 33 52 34 53 public String getToolTip() { 35 if ( invalid) {54 if (!isValid()) { 36 55 return ""; 37 56 } 38 else if ( connectedToPrevious && connectedToNext) {57 else if (linkPrev && linkNext) { 39 58 return tr("way is connected"); 40 59 } 41 else if ( connectedToPrevious) {60 else if (linkPrev) { 42 61 return tr("way is connected to previous relation member"); 43 62 } 44 else if ( connectedToNext) {63 else if (linkNext) { 45 64 return tr("way is connected to next relation member"); 46 65 } 47 66 else { 48 67 return tr("way is not connected to previous or next relation member"); 49 } 68 }//FIXME: isLoop & direction 50 69 } 51 70 }
Note:
See TracChangeset
for help on using the changeset viewer.