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

Last change on this file since 6544 was 6544, checked in by simon04, 10 years ago

fix #9473 - Added wayselector plugin to josm core. This plugin was initially written by Marko Mäkelä (Skela).

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