source: josm/trunk/src/org/openstreetmap/josm/data/osm/Way.java@ 1946

Last change on this file since 1946 was 1946, checked in by Gubaer, 15 years ago

applied #3235: patch by Daeron: Visitor implementation doesn't belong to Way

  • Property svn:eol-style set to native
File size: 7.3 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.data.osm;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5import static org.openstreetmap.josm.tools.I18n.trn;
6
7import java.util.ArrayList;
8import java.util.Arrays;
9import java.util.Collection;
10import java.util.HashSet;
11import java.util.List;
12
13import org.openstreetmap.josm.data.osm.visitor.Visitor;
14import org.openstreetmap.josm.tools.CopyList;
15import org.openstreetmap.josm.tools.Pair;
16
17/**
18 * One full way, consisting of a list of way nodes.
19 *
20 * @author imi
21 */
22public final class Way extends OsmPrimitive {
23
24 /**
25 * All way nodes in this way
26 *
27 * @deprecated This public field will become private or protected in the future.
28 * Use the new public API instead.
29 */
30 @Deprecated
31 public final List<Node> nodes = new ArrayList<Node>();
32
33 /**
34 *
35 * You can modify returned list but changes will not be propagated back
36 * to the Way. Use {@link #setNodes(List)} to update this way
37 * @return Nodes composing the way
38 * @since 1862
39 */
40 public List<Node> getNodes() {
41 return new CopyList<Node>(nodes.toArray(new Node[nodes.size()]));
42 }
43
44 /**
45 * @param nodes New way nodes. Can be null, in that case all way nodes are removed
46 * @since 1862
47 */
48 public void setNodes(List<Node> nodes) {
49 this.nodes.clear();
50 if (nodes != null) {
51 this.nodes.addAll(nodes);
52 }
53 clearCached();
54 }
55
56 /**
57 * Replies the number of nodes in this ways.
58 *
59 * @return the number of nodes in this ways.
60 * @since 1862
61 */
62 public int getNodesCount() {
63 return nodes.size();
64 }
65
66 /**
67 * Replies the node at position <code>index</code>.
68 *
69 * @param index the position
70 * @return the node at position <code>index</code>
71 * @exception IndexOutOfBoundsException thrown if <code>index</code> < 0
72 * or <code>index</code> >= {@see #getNodesCount()}
73 * @since 1862
74 */
75 public Node getNode(int index) {
76 return nodes.get(index);
77 }
78
79 /**
80 * Replies true if this way contains the node <code>node</code>, false
81 * otherwise. Replies false if <code>node</code> is null.
82 *
83 * @param node the node. May be null.
84 * @return true if this way contains the node <code>node</code>, false
85 * otherwise
86 * @since 1909
87 */
88 public boolean containsNode(Node node) {
89 if (node == null) return false;
90 return nodes.contains(node);
91 }
92
93 /* mappaint data */
94 public boolean isMappaintArea = false;
95 public Integer mappaintDrawnAreaCode = 0;
96 /* end of mappaint data */
97 @Override protected void clearCached() {
98 super.clearCached();
99 isMappaintArea = false;
100 mappaintDrawnAreaCode = 0;
101 }
102
103 public ArrayList<Pair<Node,Node>> getNodePairs(boolean sort) {
104 ArrayList<Pair<Node,Node>> chunkSet = new ArrayList<Pair<Node,Node>>();
105 if (incomplete) return chunkSet;
106 Node lastN = null;
107 for (Node n : this.nodes) {
108 if (lastN == null) {
109 lastN = n;
110 continue;
111 }
112 Pair<Node,Node> np = new Pair<Node,Node>(lastN, n);
113 if (sort) {
114 Pair.sort(np);
115 }
116 chunkSet.add(np);
117 lastN = n;
118 }
119 return chunkSet;
120 }
121
122
123 @Override public void visit(Visitor visitor) {
124 visitor.visit(this);
125 }
126
127 /**
128 * Create an identical clone of the argument (including the id).
129 *
130 * @param original the original way. Must not be null.
131 */
132 public Way(Way original) {
133 cloneFrom(original);
134 }
135
136 /**
137 * Create an empty way without id. Use this only if you set meaningful
138 * values yourself.
139 */
140 public Way() {
141 }
142
143 /**
144 * Create an incomplete Way with a given id.
145 *
146 * @param id the id. id > 0 required.
147 */
148 public Way(long id) {
149 // FIXME: shouldn't we check for id > 0?
150 //
151 this.id = id;
152 incomplete = true;
153 }
154
155 @Override public void cloneFrom(OsmPrimitive osm) {
156 super.cloneFrom(osm);
157 nodes.clear();
158 nodes.addAll(((Way)osm).nodes);
159 }
160
161 @Override public String toString() {
162 if (incomplete) return "{Way id="+id+" version="+version+" (incomplete)}";
163 return "{Way id="+id+" version="+version+" nodes="+Arrays.toString(nodes.toArray())+"}";
164 }
165
166 @Override
167 public boolean hasEqualSemanticAttributes(OsmPrimitive other) {
168 if (other == null || ! (other instanceof Way) )
169 return false;
170 if (! super.hasEqualSemanticAttributes(other))
171 return false;
172 Way w = (Way)other;
173 return nodes.equals(w.nodes);
174 }
175
176 public int compareTo(OsmPrimitive o) {
177 if (o instanceof Relation)
178 return 1;
179 return o instanceof Way ? Long.valueOf(id).compareTo(o.id) : -1;
180 }
181
182 @Override
183 public String getName() {
184 String name;
185 if (incomplete) {
186 name = tr("incomplete");
187 } else {
188 name = get("name");
189 if (name == null) {
190 name = get("ref");
191 }
192 if (name == null) {
193 name =
194 (get("highway") != null) ? tr("highway") :
195 (get("railway") != null) ? tr("railway") :
196 (get("waterway") != null) ? tr("waterway") :
197 (get("landuse") != null) ? tr("landuse") : "";
198 }
199
200 int nodesNo = new HashSet<Node>(nodes).size();
201 String nodes = trn("{0} node", "{0} nodes", nodesNo, nodesNo);
202 name += (name.length() > 0) ? " ("+nodes+")" : nodes;
203 if(errors != null) {
204 name = "*"+name;
205 }
206 }
207 return name;
208 }
209
210 public void removeNode(Node n) {
211 if (incomplete) return;
212 boolean closed = (lastNode() == n && firstNode() == n);
213 int i;
214 while ((i = nodes.indexOf(n)) >= 0) {
215 nodes.remove(i);
216 }
217 i = nodes.size();
218 if (closed && i > 2) {
219 addNode(firstNode());
220 } else if (i >= 2 && i <= 3 && nodes.get(0) == nodes.get(i-1)) {
221 nodes.remove(i-1);
222 }
223 }
224
225 public void removeNodes(Collection<? extends OsmPrimitive> selection) {
226 if (incomplete) return;
227 for(OsmPrimitive p : selection) {
228 if (p instanceof Node) {
229 removeNode((Node)p);
230 }
231 }
232 }
233
234 public void addNode(Node n) {
235 if (incomplete) return;
236 clearCached();
237 nodes.add(n);
238 }
239
240 public void addNode(int offs, Node n) {
241 if (incomplete) return;
242 clearCached();
243 nodes.add(offs, n);
244 }
245
246 public boolean isClosed() {
247 if (incomplete) return false;
248 return nodes.size() >= 3 && lastNode() == firstNode();
249 }
250
251 public Node lastNode() {
252 if (incomplete || nodes.size() == 0) return null;
253 return nodes.get(nodes.size()-1);
254 }
255
256 public Node firstNode() {
257 if (incomplete || nodes.size() == 0) return null;
258 return nodes.get(0);
259 }
260
261 public boolean isFirstLastNode(Node n) {
262 if (incomplete || nodes.size() == 0) return false;
263 return n == firstNode() || n == lastNode();
264 }
265}
Note: See TracBrowser for help on using the repository browser.