Changeset 2421 in josm for trunk/src/org/openstreetmap/josm/gui/dialogs/relation/RelationNodeMap.java
- Timestamp:
- 2009-11-09T17:02:00+01:00 (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/gui/dialogs/relation/RelationNodeMap.java
-
Property svn:eol-style
set to
native
r2365 r2421 1 // License: GPL. For details, see LICENSE file. 1 2 package org.openstreetmap.josm.gui.dialogs.relation; 2 3 3 4 import java.util.ArrayList; 5 import java.util.Iterator; 6 import java.util.List; 7 import java.util.Map; 8 import java.util.TreeMap; 4 9 import java.util.TreeSet; 5 10 … … 8 13 import org.openstreetmap.josm.data.osm.Way; 9 14 15 import static org.openstreetmap.josm.gui.dialogs.relation.WayConnectionType.Direction.*; 16 10 17 /** 11 * A mapping from Node positions to elements in a Relation (currently Nodes and Ways only) 18 * Auxiliary class for relation sorting. 19 * 20 * Constructs two mappings: One that maps each way to its nodes and the inverse mapping that 21 * maps each node to all ways that have this node. 22 * After construction both maps are consistent, but later on objects that are no longer needed 23 * are removed from the value sets. 24 * However the corresponding keys are not deleted even if they map to an empty set. 25 * Note that normal ways have 2 nodes (beginning and end) but roundabouts can have less or more 26 * (that are shared by other members). 12 27 * 13 28 * @author Christiaan Welvaart <cjw@time4t.net> 14 * 29 * 15 30 */ 16 31 public class RelationNodeMap { 32 /* 33 * read only list of all relation members 34 */ 35 private final List<RelationMember> members; 36 /* 37 * the maps. (Need TreeMap for efficiency.) 38 */ 39 private TreeMap<Node, TreeSet<Integer>> nodesMap; 40 private TreeMap<Integer, TreeSet<Node>> waysMap; 41 /* 42 * Used to keep track of what members are done. 43 */ 44 private TreeSet<Integer> remaining; 45 17 46 /** 18 * For each way endpoint, list all ways that share this node47 * All members that are incomplete or not a way 19 48 */ 20 private java.util.HashMap<Node, TreeSet<Integer>> points; 21 /** 22 * Singleton nodes 23 */ 24 private java.util.HashMap<Node, Integer> nodes; 25 private java.util.Vector<Integer> remaining; 26 /** 27 * read only list 28 */ 29 private final ArrayList<RelationMember> members; 49 private List<Integer> notSortable = new ArrayList<Integer>(); 30 50 31 51 RelationNodeMap(ArrayList<RelationMember> members) { 32 int i;52 this.members = members; 33 53 34 this.members = members; 35 points = new java.util.HashMap<Node, TreeSet<Integer>>(); 36 nodes = new java.util.HashMap<Node, Integer>(); 37 remaining = new java.util.Vector<Integer>(); 54 nodesMap = new TreeMap<Node, TreeSet<Integer>>(); 55 waysMap = new TreeMap<Integer, TreeSet<Node>>(); 38 56 39 for (i = 0; i < members.size(); ++i) {57 for (int i = 0; i < members.size(); ++i) { 40 58 RelationMember m = members.get(i); 41 if (m.getMember().incomplete )59 if (m.getMember().incomplete || !m.isWay()) 42 60 { 43 remaining.add(Integer.valueOf(i));61 notSortable.add(i); 44 62 } 45 else 46 { 47 add(i, m); 48 } 49 } 50 } 51 52 Integer find(Node node, int current) { 53 Integer result = null; 54 55 try { 56 result = nodes.get(node); 57 if (result == null) { 58 result = points.get(node).first(); 59 if (members.get(current).getMember() == members.get(result).getMember()) { 60 result = points.get(node).last(); 61 } 62 } 63 } catch (NullPointerException f) { 64 } catch (java.util.NoSuchElementException e) { 65 } 66 67 return result; 68 } 69 70 void add(int n, RelationMember m) { 71 if (m.isWay()) { 72 Way w = m.getWay(); 73 if (w.lastNode() == w.firstNode()) 74 { 75 nodes.put(w.firstNode(), n); 76 } 77 else 78 { 79 if (!points.containsKey(w.firstNode())) { 80 points.put(w.firstNode(), new TreeSet<Integer>()); 81 } 82 points.get(w.firstNode()).add(n); 83 84 if (!points.containsKey(w.lastNode())) { 85 points.put(w.lastNode(), new TreeSet<Integer>()); 86 } 87 points.get(w.lastNode()).add(n); 88 } 89 } else if (m.isNode()) { 90 Node node = m.getNode(); 91 nodes.put(node, n); 92 } else { 93 remaining.add(n); 94 } 95 } 96 97 boolean remove(int n, RelationMember a) { 98 boolean result; 99 if (a.isWay()) { 100 Way w = a.getWay(); 101 if (w.firstNode() == w.lastNode()) 102 { 103 result = (nodes.remove(w.firstNode()) != null); 104 } 105 else 106 { 107 result = points.get(w.firstNode()).remove(n); 108 result &= points.get(w.lastNode()).remove(n); 109 } 110 } else { 111 result = (nodes.remove(a.getMember()) != null); 112 } 113 return result; 114 } 115 116 // no node-mapped entries left 117 boolean isEmpty() { 118 return points.isEmpty() && nodes.isEmpty(); 119 } 120 121 java.util.Vector<Integer> getRemaining() { 122 return remaining; 123 } 124 125 Integer pop() { 126 Node node = null; 127 Integer result = null; 128 129 if (!nodes.isEmpty()) { 130 node = nodes.keySet().iterator().next(); 131 result = nodes.get(node); 132 nodes.remove(node); 133 } else if (!points.isEmpty()) { 134 for (TreeSet<Integer> set : points.values()) { 135 if (!set.isEmpty()) { 136 result = set.first(); 137 Way w = members.get(result).getWay(); 138 points.get(w.firstNode()).remove(result); 139 points.get(w.lastNode()).remove(result); 140 break; 63 else { 64 Way w = m.getWay(); 65 if (MemberTableModel.roundaboutType(w) != NONE) { 66 for (Node nd : w.getNodes()) { 67 addPair(nd, i); 68 } 69 } else { 70 addPair(w.firstNode(), i); 71 addPair(w.lastNode(), i); 141 72 } 142 73 } 143 74 } 144 75 145 return result; 76 remaining = new TreeSet<Integer>(); 77 for (Integer k : waysMap.keySet()) { 78 remaining.add(k); 79 } 80 81 /* 82 * Clean up the maps, i.e. remove nodes from roundabouts and dead ends that 83 * cannot be used in future. (only for performance) 84 */ 85 Iterator<Map.Entry<Node,TreeSet<Integer>>> it = nodesMap.entrySet().iterator(); 86 while (it.hasNext()) { 87 Map.Entry<Node,TreeSet<Integer>> nodeLinks = it.next(); 88 89 if (nodeLinks.getValue().size() < 2) { 90 // System.err.println("DELETE: "+nodeLinks.getKey()+" "+nodeLinks.getValue()); 91 if (nodeLinks.getValue().size() != 1) throw new AssertionError(); 92 93 Integer d_way = nodeLinks.getValue().iterator().next(); 94 TreeSet<Node> d_way_nodes = waysMap.get(d_way); 95 d_way_nodes.remove(nodeLinks.getKey()); 96 97 it.remove(); 98 continue; 99 } 100 // System.err.println(nodeLinks.getKey()+" "+nodeLinks.getValue()); 101 102 } 103 // System.err.println(""); 104 // System.err.println(remaining); 105 // System.err.println(""); 106 // System.err.println(nodesMap); 107 // System.err.println(""); 108 // System.err.println(waysMap); 109 110 } 111 112 private void addPair(Node n, int i) { 113 TreeSet<Integer> ts = nodesMap.get(n); 114 if (ts == null) { 115 ts = new TreeSet<Integer>(); 116 nodesMap.put(n, ts); 117 } 118 ts.add(i); 119 120 TreeSet<Node> ts2 = waysMap.get(i); 121 if (ts2 == null) { 122 ts2 = new TreeSet<Node>(); 123 waysMap.put(i, ts2); 124 } 125 ts2.add(n); 126 } 127 128 /** 129 * Return a relation member that is linked to the 130 * member 'i', but has not been popped jet. 131 * Return null if there is no such member left. 132 */ 133 public Integer popAdjacent(Integer i) { 134 // System.err.print("Adjacent["+i+"]:"); 135 TreeSet<Node> nodes = waysMap.get(i); 136 // System.err.print(nodes); 137 for (Node n : nodes) { 138 // System.err.print(" {"+n.getId()+"} "); 139 TreeSet<Integer> adj = nodesMap.get(n); 140 if (!adj.isEmpty()) { 141 Integer j = adj.iterator().next(); 142 done(j); 143 waysMap.get(j).remove(n); 144 // System.err.println(j); 145 return j; 146 } 147 } 148 return null; 149 } 150 151 /** 152 * Returns some remaining member or null if 153 * every sortable member has been processed. 154 */ 155 public Integer pop() { 156 if (remaining.isEmpty()) return null; 157 Integer i = remaining.iterator().next(); 158 done(i); 159 return i; 160 } 161 162 /** 163 * This relation member has been processed. 164 * Remove references in the nodesMap. 165 */ 166 private void done(Integer i) { 167 remaining.remove(i); 168 TreeSet<Node> nodes = waysMap.get(i); 169 for (Node n : nodes) { 170 boolean result = nodesMap.get(n).remove(i); 171 if (!result) throw new AssertionError(); 172 } 173 } 174 175 public List<Integer> getNotSortableMembers() { 176 return notSortable; 146 177 } 147 178 } -
Property svn:eol-style
set to
Note:
See TracChangeset
for help on using the changeset viewer.