source: josm/trunk/src/org/openstreetmap/josm/actions/SelectNonBranchingWaySequences.java@ 16770

Last change on this file since 16770 was 16438, checked in by simon04, 4 years ago

see #19251 - Java 8: use Stream

  • Property svn:eol-style set to native
File size: 4.4 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.actions;
3
4import java.util.Collection;
5import java.util.LinkedList;
6import java.util.Objects;
7import java.util.Set;
8import java.util.TreeSet;
9
10import org.openstreetmap.josm.data.osm.DataSet;
11import org.openstreetmap.josm.data.osm.Node;
12import org.openstreetmap.josm.data.osm.OsmPrimitive;
13import org.openstreetmap.josm.data.osm.Way;
14
15/**
16 * Auxiliary class for the {@link SelectNonBranchingWaySequencesAction}.
17 *
18 * @author Marko Mäkelä
19 */
20public class SelectNonBranchingWaySequences {
21 /**
22 * outer endpoints of selected ways
23 */
24 private Set<Node> outerNodes;
25 /**
26 * endpoints of selected ways
27 */
28 private Set<Node> nodes;
29
30 /**
31 * Creates a way selection
32 *
33 * @param ways selection a selection of ways
34 */
35 public SelectNonBranchingWaySequences(final Collection<Way> ways) {
36 if (ways.isEmpty()) {
37 // The selection cannot be extended.
38 outerNodes = null;
39 nodes = null;
40 } else {
41 nodes = new TreeSet<>();
42 outerNodes = new TreeSet<>();
43
44 for (Way way : ways) {
45 addNodes(way);
46 }
47 }
48 }
49
50 /**
51 * Add a way endpoint to nodes, outerNodes
52 *
53 * @param node a way endpoint
54 */
55 private void addNodes(Node node) {
56 if (node == null) return;
57 else if (!nodes.add(node))
58 outerNodes.remove(node);
59 else
60 outerNodes.add(node);
61 }
62
63 /**
64 * Add the endpoints of the way to nodes, outerNodes
65 *
66 * @param way a way whose endpoints are added
67 */
68 private void addNodes(Way way) {
69 addNodes(way.firstNode());
70 addNodes(way.lastNode());
71 }
72
73 /**
74 * Find out if the selection can be extended
75 *
76 * @return true if the selection can be extended
77 */
78 public boolean canExtend() {
79 return outerNodes != null && !outerNodes.isEmpty();
80 }
81
82 /**
83 * Finds out if the current selection can be extended.
84 *
85 * @param selection current selection (ways and others)
86 * @param node perimeter node from which to extend the selection
87 * @return a way by which to extend the selection, or null
88 */
89 private static Way findWay(Collection<OsmPrimitive> selection, Node node) {
90 Way foundWay = null;
91
92 for (Way way : node.getParentWays()) {
93 if (way.getNodesCount() < 2 || !way.isFirstLastNode(node)
94 || !way.isSelectable()
95 || selection.contains(way))
96 continue;
97
98 /* A previously unselected way was found that is connected
99 to the node. */
100 if (foundWay != null)
101 /* This is not the only qualifying way. There is a
102 branch at the node, and we cannot extend the selection. */
103 return null;
104
105 /* Remember the first found qualifying way. */
106 foundWay = way;
107 }
108
109 /* Return the only way found, or null if none was found. */
110 return foundWay;
111 }
112
113 /**
114 * Finds out if the current selection can be extended.
115 * <p>
116 * The members outerNodes, nodes must have been initialized.
117 * How to update these members when extending the selection, @see extend().
118 * </p>
119 * @param selection current selection
120 * @return a way by which to extend the selection, or null
121 */
122 private Way findWay(Collection<OsmPrimitive> selection) {
123 return outerNodes.stream()
124 .map(node -> findWay(selection, node))
125 .filter(Objects::nonNull)
126 .findFirst().orElse(null);
127
128 }
129
130 /**
131 * Extend the current selection
132 *
133 * @param data the data set in which to extend the selection
134 */
135 public void extend(DataSet data) {
136 if (!canExtend())
137 return;
138
139 Collection<OsmPrimitive> currentSelection = data.getSelected();
140
141 Way way = findWay(currentSelection);
142
143 if (way == null)
144 return;
145
146 boolean selectionChanged = false;
147 Collection<OsmPrimitive> selection = new LinkedList<>(currentSelection);
148
149 do {
150 if (!selection.add(way))
151 break;
152
153 selectionChanged = true;
154 addNodes(way);
155
156 way = findWay(selection);
157 } while (way != null);
158
159 if (selectionChanged)
160 data.setSelected(selection);
161 }
162}
Note: See TracBrowser for help on using the repository browser.