1 package org.opentrafficsim.road.network.factory.osm;
2
3 import java.util.ArrayList;
4 import java.util.List;
5 import java.util.Objects;
6
7 import org.opentrafficsim.road.network.factory.osm.events.WarningEvent;
8 import org.opentrafficsim.road.network.factory.osm.events.WarningListener;
9
10
11
12
13
14
15
16
17
18
19
20 public class OSMLink
21 {
22
23 private final String id;
24
25
26 private final OSMNode start;
27
28
29 private final OSMNode end;
30
31
32 private List<OSMNode> intermediateNodes;
33
34
35 private final double length;
36
37
38 private List<OSMTag> tags;
39
40
41 private byte lanes;
42
43
44 private byte forwardLanes;
45
46
47 private boolean oneway;
48
49
50
51
52
53
54
55
56
57 public OSMLink(final OSMNode fromNode, final OSMNode toNode, final List<OSMTag> tags, final double length,
58 final WarningListener warningListener)
59 {
60 if (fromNode == toNode)
61 {
62 throw new Error("Start and end of link are the same Node: " + fromNode);
63 }
64 String name = "";
65 for (OSMTag tag : tags)
66 {
67 if (tag.getKey().equals("name"))
68 {
69 name = ": " + tag.getValue();
70 }
71 }
72 this.id = Objects.toString(fromNode.getId()) + Objects.toString(toNode.getId()) + name;
73 this.start = fromNode;
74 this.end = toNode;
75 this.length = length;
76 this.lanes = 1;
77 this.forwardLanes = 1;
78 boolean forwardDefined = false;
79
80 List<OSMTag> linkTags = new ArrayList<OSMTag>(tags);
81 for (OSMTag tag : tags)
82 {
83 if (tag.getKey().equals("oneway") && tag.getValue().equals("yes"))
84 {
85 this.setOneway(true);
86 linkTags.remove(tag);
87 this.forwardLanes = this.lanes;
88 }
89 if (tag.getKey().equals("highway") && tag.getValue().equals("motorway_link"))
90 {
91 this.setOneway(true);
92 this.lanes = 1;
93 this.forwardLanes = this.lanes;
94 }
95 if (tag.getKey().equals("highway") && tag.getValue().equals("motorway"))
96 {
97 this.setOneway(true);
98 this.forwardLanes = this.lanes;
99 }
100 if (tag.getKey().equals("highway")
101 && (tag.getValue().equals("cycleway") || tag.getValue().equals("footway")
102 || tag.getValue().equals("pedestrian") || tag.getValue().equals("steps")))
103 {
104 this.lanes = 1;
105 }
106 }
107
108 for (OSMTag tag2 : new ArrayList<OSMTag>(linkTags))
109 {
110 if (tag2.getKey().equals("lanes"))
111 {
112 if (isByte(tag2.getValue()))
113 {
114 this.lanes = Byte.parseByte(tag2.getValue());
115 linkTags.remove(tag2);
116 if (this.oneway)
117 {
118 this.forwardLanes = this.lanes;
119 forwardDefined = true;
120 }
121 }
122 else
123 {
124 String warning = "Illegal value for the tag 'lanes' at link " + this.id;
125 warningListener.warning(new WarningEvent(this, warning));
126 }
127 }
128 if (tag2.getKey().equals("lanes:forward"))
129 {
130 if (isByte(tag2.getValue()))
131 {
132 this.forwardLanes = Byte.parseByte(tag2.getValue());
133 linkTags.remove(tag2);
134 forwardDefined = true;
135 }
136 else
137 {
138 String warning = "Illegal value for the tag 'lanes:forward' at link " + this.id;
139 warningListener.warning(new WarningEvent(this, warning));
140 }
141 }
142 }
143 this.tags = linkTags;
144 if (!forwardDefined && this.lanes > 1)
145 {
146 this.forwardLanes = (byte) (this.lanes / 2);
147 String warning = "No forward lanes defined at link " + this.id;
148 warningListener.warning(new WarningEvent(this, warning));
149 }
150 this.intermediateNodes = new ArrayList<OSMNode>();
151 }
152
153
154
155
156
157
158
159
160
161
162 public OSMLink(final OSMNode startNode, final OSMNode endNode, final List<OSMTag> tags, final double length,
163 final byte lanes, final byte flanes)
164 {
165 if (startNode == endNode)
166 {
167 throw new Error("start and end of link are the same Node: " + startNode);
168 }
169 this.id = Objects.toString(startNode.getId()) + Objects.toString(endNode.getId());
170 this.start = startNode;
171 this.end = endNode;
172 this.tags = tags;
173 this.length = length;
174 this.lanes = lanes;
175 this.forwardLanes = flanes;
176 this.intermediateNodes = new ArrayList<OSMNode>();
177 }
178
179
180
181
182 public final String getId()
183 {
184 return this.id;
185 }
186
187
188
189
190 public final OSMNode getStart()
191 {
192 return this.start;
193 }
194
195
196
197
198 public final OSMNode getEnd()
199 {
200 return this.end;
201 }
202
203
204
205
206
207
208 public final List<OSMTag> getTags()
209 {
210 return new ArrayList<OSMTag>(this.tags);
211 }
212
213
214
215
216
217 public final boolean isOneway()
218 {
219 return this.oneway;
220 }
221
222
223
224
225
226 public final void setOneway(final boolean isOneWay)
227 {
228 this.oneway = isOneWay;
229 }
230
231
232
233
234
235 public final byte getLanes()
236 {
237 return this.lanes;
238 }
239
240
241
242
243
244
245 public final byte getForwardLanes()
246 {
247 return this.forwardLanes;
248 }
249
250
251
252
253
254 public final void addTag(final OSMTag tag)
255 {
256 this.tags.add(tag);
257 }
258
259
260
261
262
263 public final double getLength()
264 {
265 return this.length;
266 }
267
268
269
270
271
272 public final List<OSMNode> getSplineList()
273 {
274 return this.intermediateNodes;
275 }
276
277
278
279
280
281 public final void addSpline(final OSMNode shapeNode)
282 {
283 this.intermediateNodes.add(shapeNode);
284 }
285
286
287
288
289
290
291 public final boolean hasTag(final String key)
292 {
293 for (OSMTag t : this.tags)
294 {
295 if (t.getKey().equals(key))
296 {
297 return true;
298 }
299 }
300 return false;
301 }
302
303
304
305
306
307
308 private boolean isByte(final String s)
309 {
310 try
311 {
312 Byte.parseByte(s);
313 }
314 catch (NumberFormatException e)
315 {
316 return false;
317 }
318 return true;
319 }
320
321
322 public final String toString()
323 {
324 return String.format("Link %s from %d to %d", getId(), getStart().getId(), getEnd().getId());
325 }
326
327
328
329
330
331
332 public final boolean containsAllTags(final List<OSMTag> tagsToCheck)
333 {
334 return this.tags.containsAll(tagsToCheck);
335 }
336
337 }