Changeset 19062 in josm
- Timestamp:
- 2024-04-27T08:58:28+02:00 (9 months ago)
- Location:
- trunk
- Files:
-
- 8 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/data/osm/NodeGraph.java
r17515 r19062 22 22 23 23 import org.openstreetmap.josm.tools.Pair; 24 import org.openstreetmap.josm.tools.Utils; 24 25 25 26 /** 26 * A directed or undirected graph of nodes. 27 * A directed or undirected graph of nodes. Nodes are connected via edges represented by NodePair instances. 28 * 27 29 * @since 12463 (extracted from CombineWayAction) 28 30 */ … … 33 35 * @param way way 34 36 * @param directed if {@code true} each pair of nodes will occur once, in the way nodes order. 35 * if {@code false} each pair of nodes will occur twice (the pair and its inverse dcopy)37 * if {@code false} each pair of nodes will occur twice (the pair and its inverse copy) 36 38 * @return a list of pair of nodes from the given way 37 39 */ 38 40 public static List<NodePair> buildNodePairs(Way way, boolean directed) { 39 41 List<NodePair> pairs = new ArrayList<>(); 40 for (Pair<Node, Node> pair: way.getNodePairs(false /* don't sort */)) {42 for (Pair<Node, Node> pair : way.getNodePairs(false)) { 41 43 pairs.add(new NodePair(pair)); 42 44 if (!directed) { … … 50 52 * Builds a list of pair of nodes from the given ways. 51 53 * @param ways ways 52 * @param directed if {@code true} each pair of nodes will occur once, in the way nodes order. 53 * if {@code false} each pair of nodes will occur twice (the pair and its inverse dcopy)54 * @param directed if {@code true} each pair of nodes will occur once, in the way nodes order.<br> 55 * if {@code false} each pair of nodes will occur twice (the pair and its inverse copy) 54 56 * @return a list of pair of nodes from the given ways 55 57 */ 56 58 public static List<NodePair> buildNodePairs(List<Way> ways, boolean directed) { 57 59 List<NodePair> pairs = new ArrayList<>(); 58 for (Way w: ways) { 60 for (Way w : ways) { 59 61 pairs.addAll(buildNodePairs(w, directed)); 60 62 } … … 63 65 64 66 /** 65 * Builds a new list of pair nodes without the duplicated pairs (including inverse dcopies).67 * Builds a new list of pair nodes without the duplicated pairs (including inverse copies). 66 68 * @param pairs existing list of pairs 67 69 * @return a new list of pair nodes without the duplicated pairs … … 69 71 public static List<NodePair> eliminateDuplicateNodePairs(List<NodePair> pairs) { 70 72 List<NodePair> cleaned = new ArrayList<>(); 71 for (NodePair p: pairs) { 73 for (NodePair p : pairs) { 72 74 if (!cleaned.contains(p) && !cleaned.contains(p.swap())) { 73 75 cleaned.add(p); … … 77 79 } 78 80 81 /** 82 * Create a directed graph from the given node pairs. 83 * @param pairs Node pairs to build the graph from 84 * @return node graph structure 85 */ 79 86 public static NodeGraph createDirectedGraphFromNodePairs(List<NodePair> pairs) { 80 87 NodeGraph graph = new NodeGraph(); 81 for (NodePair pair: pairs) { 88 for (NodePair pair : pairs) { 82 89 graph.add(pair); 83 90 } … … 85 92 } 86 93 94 /** 95 * Create a directed graph from the given ways. 96 * @param ways ways to build the graph from 97 * @return node graph structure 98 */ 87 99 public static NodeGraph createDirectedGraphFromWays(Collection<Way> ways) { 88 100 NodeGraph graph = new NodeGraph(); 89 for (Way w: ways) { 90 graph.add(buildNodePairs(w, true /* directed */));101 for (Way w : ways) { 102 graph.add(buildNodePairs(w, true)); 91 103 } 92 104 return graph; … … 100 112 public static NodeGraph createUndirectedGraphFromNodeList(List<NodePair> pairs) { 101 113 NodeGraph graph = new NodeGraph(); 102 for (NodePair pair: pairs) { 114 for (NodePair pair : pairs) { 103 115 graph.add(pair); 104 116 graph.add(pair.swap()); … … 109 121 /** 110 122 * Create an undirected graph from the given ways, but prevent reversing of all 111 * non-new ways by fix one direction. 123 * non-new ways by fixing one direction. 112 124 * @param ways Ways to build the graph from 113 125 * @return node graph structure … … 116 128 public static NodeGraph createUndirectedGraphFromNodeWays(Collection<Way> ways) { 117 129 NodeGraph graph = new NodeGraph(); 118 for (Way w: ways) { 119 graph.add(buildNodePairs(w, false /* undirected */));130 for (Way w : ways) { 131 graph.add(buildNodePairs(w, false)); 120 132 } 121 133 return graph; 122 134 } 123 135 136 /** 137 * Create a nearly undirected graph from the given ways, but prevent reversing of all 138 * non-new ways by fixing one direction. 139 * The first new way gives the direction of the graph. 140 * @param ways Ways to build the graph from 141 * @return node graph structure 142 */ 124 143 public static NodeGraph createNearlyUndirectedGraphFromNodeWays(Collection<Way> ways) { 125 144 boolean dir = true; 126 145 NodeGraph graph = new NodeGraph(); 127 for (Way w: ways) { 146 for (Way w : ways) { 128 147 if (!w.isNew()) { 129 148 /* let the first non-new way give the direction (see #5880) */ … … 131 150 dir = false; 132 151 } else { 133 graph.add(buildNodePairs(w, false /* undirected */));152 graph.add(buildNodePairs(w, false)); 134 153 } 135 154 } … … 138 157 139 158 private final Set<NodePair> edges; 140 private int numUndirectedEges; 141 /** counts the number of edges that were added */159 private int numUndirectedEdges; 160 /** The number of edges that were added. */ 142 161 private int addedEdges; 143 162 private final Map<Node, List<NodePair>> successors = new LinkedHashMap<>(); 144 163 private final Map<Node, List<NodePair>> predecessors = new LinkedHashMap<>(); 145 164 165 /** 166 * Constructs a lookup table from the existing edges in the graph to enable efficient querying. 167 * This method creates a map where each node is associated with a list of nodes that are directly connected to it. 168 * 169 * @return A map representing the graph structure, where nodes are keys, and values are their direct successors. 170 * @since xxx 171 */ 172 public Map<Node, List<Node>> createMap() { 173 final Map<Node, List<Node>> result = new HashMap<>(Utils.hashMapInitialCapacity(edges.size())); 174 175 for (NodePair edge : edges) { 176 result.computeIfAbsent(edge.getA(), k -> new ArrayList<>()).add(edge.getB()); 177 } 178 179 return result; 180 } 181 182 /** 183 * See {@link #prepare()} 184 */ 146 185 protected void rememberSuccessor(NodePair pair) { 147 186 List<NodePair> l = successors.computeIfAbsent(pair.getA(), k -> new ArrayList<>()); … … 151 190 } 152 191 192 /** 193 * See {@link #prepare()} 194 */ 153 195 protected void rememberPredecessors(NodePair pair) { 154 196 List<NodePair> l = predecessors.computeIfAbsent(pair.getB(), k -> new ArrayList<>()); … … 158 200 } 159 201 202 /** 203 * Replies true if {@code n} is a terminal node of the graph. Internal variables should be initialized first. 204 * @param n Node to check 205 * @return {@code true} if it is a terminal node 206 * @see #prepare() 207 */ 160 208 protected boolean isTerminalNode(Node n) { 161 209 if (successors.get(n) == null) return false; … … 175 223 predecessors.clear(); 176 224 177 for (NodePair pair: edges) { 225 for (NodePair pair : edges) { 178 226 if (!undirectedEdges.contains(pair) && !undirectedEdges.contains(pair.swap())) { 179 227 undirectedEdges.add(pair); … … 182 230 rememberPredecessors(pair); 183 231 } 184 numUndirectedEges = undirectedEdges.size(); 232 numUndirectedEdges = undirectedEdges.size(); 185 233 } 186 234 … … 203 251 /** 204 252 * Add a list of node pairs. 205 * @param pairs listof node pairs206 */ 207 public void add( Collection<NodePair> pairs) {208 for (NodePair pair: pairs) { 253 * @param pairs collection of node pairs 254 */ 255 public void add(Iterable<NodePair> pairs) { 256 for (NodePair pair : pairs) { 209 257 add(pair); 210 258 } 211 259 } 212 260 261 /** 262 * Return the edges containing the node pairs of the graph. 263 * @return the edges containing the node pairs of the graph 264 */ 265 public Collection<NodePair> getEdges() { 266 return Collections.unmodifiableSet(edges); 267 } 268 269 /** 270 * Return the terminal nodes of the graph. 271 * @return the terminal nodes of the graph 272 */ 213 273 protected Set<Node> getTerminalNodes() { 214 274 return getNodes().stream().filter(this::isTerminalNode).collect(Collectors.toCollection(LinkedHashSet::new)); … … 230 290 } 231 291 232 protected Set<Node> getNodes() { 292 /** 293 * Return the graph's nodes. 294 * @return the graph's nodes 295 */ 296 public Collection<Node> getNodes() { 233 297 Set<Node> nodes = new LinkedHashSet<>(2 * edges.size()); 234 for (NodePair pair: edges) { 298 for (NodePair pair : edges) { 235 299 nodes.add(pair.getA()); 236 300 nodes.add(pair.getB()); … … 240 304 241 305 protected boolean isSpanningWay(Collection<NodePair> way) { 242 return numUndirectedEges == way.size(); 306 return numUndirectedEdges == way.size(); 243 307 } 244 308 … … 249 313 250 314 /** 251 * Tries to find a spanning path starting from node <code>startNode</code>.252 * 315 * Tries to find a spanning path starting from node {@code startNode}. 316 * <p> 253 317 * Traverses the path in depth-first order. 254 318 * … … 260 324 Deque<NodePair> path = new ArrayDeque<>(); 261 325 Set<NodePair> dupCheck = new HashSet<>(); 262 Deque<NodePair> nextPairs = new ArrayDeque<>(); 263 nextPairs.addAll(getOutboundPairs(startNode)); 326 Deque<NodePair> nextPairs = new ArrayDeque<>(getOutboundPairs(startNode)); 264 327 while (!nextPairs.isEmpty()) { 265 328 NodePair cur = nextPairs.removeLast(); … … 281 344 /** 282 345 * Tries to find a path through the graph which visits each edge (i.e. 283 * the segment of a way) exactly once. 284 * < p><b>Note that duplicated edges are removed first!</b>346 * the segment of a way) exactly once.<p> 347 * <b>Note that duplicated edges are removed first!</b> 285 348 * 286 * @return the path; null, if no path was found349 * @return the path; {@code null}, if no path was found 287 350 */ 288 351 public List<Node> buildSpanningPath() { 289 352 prepare(); 290 if (numUndirectedEges > 0 && isConnected()) { 291 // try to find a path from each "terminal node", i.e. from a292 // node which is connected by exactly one undirected edge s(or293 // two directed edges in opposite direction) to the graph. A 353 if (numUndirectedEdges > 0 && isConnected()) { 354 // Try to find a path from each "terminal node", i.e. from a 355 // node which is connected by exactly one undirected edge (or 356 // two directed edges in the opposite direction) to the graph. A 294 357 // graph built up from way segments is likely to include such 295 358 // nodes, unless the edges build one or more closed rings. … … 325 388 /** 326 389 * Find out if the graph is connected. 327 * @return trueif it is connected.390 * @return {@code true} if it is connected 328 391 */ 329 392 private boolean isConnected() { 330 Set<Node> nodes = getNodes();393 Collection<Node> nodes = getNodes(); 331 394 if (nodes.isEmpty()) 332 395 return false; … … 351 414 /** 352 415 * Sort the nodes by number of appearances in the edges. 353 * @return set of nodes which can be start nodes in a spanning way .416 * @return set of nodes which can be start nodes in a spanning way 354 417 */ 355 418 private Set<Node> getMostFrequentVisitedNodesFirst() { 356 419 if (edges.isEmpty()) 357 420 return Collections.emptySet(); 358 // count appearance of nodes in edges 421 // count the appearance of nodes in edges 359 422 Map<Node, Integer> counters = new HashMap<>(); 360 423 for (NodePair pair : edges) { -
trunk/src/org/openstreetmap/josm/data/osm/WaySegment.java
r17897 r19062 3 3 4 4 /** 5 * A segment consisting of 2consecutive nodes out of a way.5 * A segment consisting of two consecutive nodes out of a way. 6 6 */ 7 7 public final class WaySegment extends IWaySegment<Node, Way> { … … 37 37 endIndex--; 38 38 } 39 throw new IllegalArgumentException(" Node pair is notpart ofway!");39 throw new IllegalArgumentException("The node pair is not consecutive part of the way!"); 40 40 } 41 41 -
trunk/src/org/openstreetmap/josm/data/validation/OsmValidator.java
r18649 r19062 45 45 import org.openstreetmap.josm.data.validation.tests.ConnectivityRelations; 46 46 import org.openstreetmap.josm.data.validation.tests.CrossingWays; 47 import org.openstreetmap.josm.data.validation.tests.CycleDetector; 47 48 import org.openstreetmap.josm.data.validation.tests.DirectionNodes; 48 49 import org.openstreetmap.josm.data.validation.tests.DuplicateNode; … … 155 156 SharpAngles.class, // 3800 .. 3899 156 157 ConnectivityRelations.class, // 3900 .. 3999 157 DirectionNodes.class, // 4000 -4099158 DirectionNodes.class, // 4000 .. 4099 158 159 RightAngleBuildingTest.class, // 4100 .. 4199 160 CycleDetector.class, // 4200 .. 4299 159 161 }; 160 162 -
trunk/src/org/openstreetmap/josm/gui/history/HistoryLoadTask.java
r16211 r19062 10 10 import java.util.ArrayList; 11 11 import java.util.Collection; 12 import java.util.Iterator; 12 13 import java.util.LinkedHashSet; 13 14 import java.util.List; … … 16 17 17 18 import org.openstreetmap.josm.data.osm.Changeset; 19 import org.openstreetmap.josm.data.osm.ChangesetCache; 18 20 import org.openstreetmap.josm.data.osm.OsmPrimitive; 19 21 import org.openstreetmap.josm.data.osm.PrimitiveId; … … 230 232 OsmServerChangesetReader changesetReader = new OsmServerChangesetReader(); 231 233 List<Long> changesetIds = new ArrayList<>(ds.getChangesetIds()); 234 Iterator<Long> iter = changesetIds.iterator(); 235 while (iter.hasNext()) { 236 long id = iter.next(); 237 Changeset cs = ChangesetCache.getInstance().get((int) id); 238 if (cs != null && !cs.isOpen()) { 239 ds.putChangeset(cs); 240 iter.remove(); 241 } 242 } 232 243 233 244 // query changesets 100 by 100 (OSM API limit) 234 245 int n = ChangesetQuery.MAX_CHANGESETS_NUMBER; 235 246 for (int i = 0; i < changesetIds.size(); i += n) { 247 List<Changeset> downloadedCS = new ArrayList<>(changesetIds.size()); 236 248 for (Changeset c : changesetReader.queryChangesets( 237 249 new ChangesetQuery().forChangesetIds(changesetIds.subList(i, Math.min(i + n, changesetIds.size()))), 238 250 progressMonitor.createSubTaskMonitor(1, false))) { 239 251 ds.putChangeset(c); 252 downloadedCS.add(c); 240 253 } 254 ChangesetCache.getInstance().update(downloadedCS); 241 255 } 242 256 }
Note:
See TracChangeset
for help on using the changeset viewer.