1 package org.opentrafficsim.road.network.factory.vissim;
2
3 import java.io.Serializable;
4 import java.util.ArrayList;
5 import java.util.HashMap;
6 import java.util.Iterator;
7 import java.util.List;
8 import java.util.Map;
9
10 import javax.naming.NamingException;
11
12 import org.djunits.value.vdouble.scalar.Angle;
13 import org.djunits.value.vdouble.scalar.Direction;
14 import org.opentrafficsim.core.geometry.OTSGeometryException;
15 import org.opentrafficsim.core.geometry.OTSLine3D;
16 import org.opentrafficsim.core.geometry.OTSPoint3D;
17 import org.opentrafficsim.core.network.NetworkException;
18 import org.opentrafficsim.core.network.OTSNode;
19 import org.xml.sax.SAXException;
20
21 import com.vividsolutions.jts.geom.Coordinate;
22 import com.vividsolutions.jts.geom.LineString;
23
24 import nl.tudelft.simulation.language.Throw;
25
26
27
28
29
30
31
32
33
34
35 class NodeTag implements Serializable
36 {
37
38 private static final long serialVersionUID = 20150723L;
39
40
41 @SuppressWarnings("checkstyle:visibilitymodifier")
42 String name = null;
43
44
45 @SuppressWarnings("checkstyle:visibilitymodifier")
46 OTSPoint3D coordinate = null;
47
48
49 @SuppressWarnings("checkstyle:visibilitymodifier")
50 Direction angle = null;
51
52
53 @SuppressWarnings("checkstyle:visibilitymodifier")
54 Angle slope = null;
55
56
57 @SuppressWarnings("checkstyle:visibilitymodifier")
58 OTSNode node = null;
59
60
61
62
63
64
65
66
67
68 @SuppressWarnings("checkstyle:needbraces")
69 static void parseNodes(final VissimNetworkLaneParser parser, String fromNode, String toNode, OTSPoint3D[] points)
70 throws SAXException, NetworkException
71 {
72 NodeTag nodeFromTag = new NodeTag();
73 nodeFromTag.name = fromNode;
74 nodeFromTag.coordinate = points[0];
75
76 generateOTSNode(parser, nodeFromTag);
77 parser.getNodeTags().put(nodeFromTag.name, nodeFromTag);
78
79 NodeTag nodeToTag = new NodeTag();
80 nodeToTag.name = toNode;
81 nodeToTag.coordinate = points[points.length - 1];
82
83 generateOTSNode(parser, nodeToTag);
84 parser.getNodeTags().put(nodeToTag.name, nodeToTag);
85 }
86
87
88
89
90
91
92 private static void generateOTSNode(final VissimNetworkLaneParser parser, final NodeTag nodeTag) throws NetworkException
93 {
94 if (nodeTag.coordinate != null && nodeTag.angle != null)
95 {
96
97 try
98 {
99 makeOTSNode(nodeTag, parser);
100 }
101 catch (NamingException exception)
102 {
103 throw new NetworkException(exception);
104 }
105 }
106 }
107
108
109
110
111
112
113
114
115
116 static List<NodeTag> parseNodeList(final String nodeNames, final VissimNetworkLaneParser parser)
117 throws SAXException, NetworkException
118 {
119 List<NodeTag> nodeList = new ArrayList<>();
120 String[] ns = nodeNames.split("\\s");
121 for (String s : ns)
122 {
123 if (!parser.getNodeTags().containsKey(s))
124 {
125 throw new SAXException("Node " + s + " from node list [" + nodeNames + "] was not defined");
126 }
127 nodeList.add(parser.getNodeTags().get(s));
128 }
129 return nodeList;
130
131 }
132
133
134
135
136
137
138
139
140 static OTSNode makeOTSNode(final NodeTag nodeTag, final VissimNetworkLaneParser parser)
141 throws NetworkException, NamingException
142 {
143 Throw.whenNull(nodeTag.angle, "NodeTag: " + nodeTag.name + " angle == null");
144 if (nodeTag.node != null)
145 {
146 nodeTag.node.getNetwork().removeNode(nodeTag.node);
147 }
148 String id = nodeTag.name;
149 Direction angle = nodeTag.angle;
150 Angle slope = nodeTag.slope == null ? Angle.ZERO : nodeTag.slope;
151 OTSNode node = new OTSNode(parser.getNetwork(), id, nodeTag.coordinate, angle, slope);
152 nodeTag.node = node;
153 return node;
154 }
155
156
157
158
159 public static void removeDuplicateNodes(final VissimNetworkLaneParser parser)
160 {
161
162 Map<String, String> replaceNodeMap = new HashMap<>();
163 Iterator<NodeTag> nodeTagValues = parser.getNodeTags().values().iterator();
164
165
166 while (nodeTagValues.hasNext())
167 {
168 NodeTag nodeTag = nodeTagValues.next();
169
170 Iterator<NodeTag> nodeTagValuesCopy = parser.getNodeTags().values().iterator();
171 while (nodeTagValuesCopy.hasNext())
172 {
173 NodeTag nodeTagCopy = nodeTagValuesCopy.next();
174
175 if (nodeTagCopy.coordinate.distance(nodeTag.coordinate).si == 0 && !nodeTagCopy.name.equals(nodeTag.name))
176 {
177
178 if (replaceNodeMap.get(nodeTag.name) == null)
179 {
180 replaceNodeMap.put(nodeTagCopy.name, nodeTag.name);
181 }
182 }
183 }
184 }
185
186
187 Iterator<LinkTag> linkTagValues = parser.getLinkTags().values().iterator();
188 while (linkTagValues.hasNext())
189 {
190 LinkTag linkTag = linkTagValues.next();
191 NodeTag nodeTag = linkTag.nodeEndTag;
192 if (replaceNodeMap.get(nodeTag.name) != null)
193 {
194 linkTag.nodeEndTag = parser.getNodeTags().get(replaceNodeMap.get(nodeTag.name));
195 }
196
197 NodeTag node2Tag = linkTag.nodeStartTag;
198 if (replaceNodeMap.get(node2Tag.name) != null)
199 {
200 linkTag.nodeStartTag = parser.getNodeTags().get(replaceNodeMap.get(node2Tag.name));
201 }
202 }
203
204
205 Iterator<String> nodeTagNames = replaceNodeMap.keySet().iterator();
206 while (nodeTagNames.hasNext())
207 {
208 String nodeTagName = nodeTagNames.next();
209 parser.getNodeTags().remove(nodeTagName);
210 }
211
212 }
213
214
215
216
217 public static void removeRedundantNodeTags(final VissimNetworkLaneParser parser)
218 {
219 Iterator<NodeTag> nodeTagValues;
220 Iterator<LinkTag> linkTagValues;
221 Iterator<LinkTag> connectoTagValues;
222
223 Map<String, NodeTag> removeNodeMap = new HashMap<>();
224 nodeTagValues = parser.getNodeTags().values().iterator();
225 while (nodeTagValues.hasNext())
226 {
227 NodeTag nodeTag = nodeTagValues.next();
228 linkTagValues = parser.getLinkTags().values().iterator();
229 boolean found = false;
230 while (linkTagValues.hasNext())
231 {
232 LinkTag linkTag = linkTagValues.next();
233 if (linkTag.nodeStartTag.name.equals(nodeTag.name) || linkTag.nodeEndTag.name.equals(nodeTag.name))
234 {
235 found = true;
236 }
237 }
238
239
240
241
242
243
244
245 if (!found)
246 {
247 removeNodeMap.put(nodeTag.name, nodeTag);
248 }
249 }
250 for (NodeTag nodeTag : removeNodeMap.values())
251 {
252 parser.getNodeTags().remove(nodeTag.name);
253 }
254 }
255
256
257 @Override
258 public String toString()
259 {
260 return "NodeTag [name=" + this.name + ", coordinate=" + this.coordinate + ", node=" + this.node + "]";
261 }
262
263
264
265
266
267
268
269
270
271 public static NodeTag createNewNodeAtLinkPosition(final LinkTag linkTag, final VissimNetworkLaneParser parser,
272 final Double position) throws OTSGeometryException, NetworkException
273 {
274
275 NodeTag nodeTag = new NodeTag();
276
277 OTSLine3D designLineOTS = LinkTag.createLineString(linkTag);
278 LineString designLine = designLineOTS.getLineString();
279
280 LineString designLineStart = SubstringLine.getSubstring(designLine, 0.0, position);
281 Coordinate[] points = designLineStart.getCoordinates();
282 OTSPoint3D point = new OTSPoint3D(points[points.length - 1]);
283 nodeTag.coordinate = point;
284
285 String nodeName = "" + parser.getUpperNodeNr();
286 parser.setUpperNodeNr(parser.getUpperNodeNr() + 1);
287 nodeTag.name = nodeName;
288
289 generateOTSNode(parser, nodeTag);
290 parser.getNodeTags().put(nodeTag.name, nodeTag);
291 return nodeTag;
292 }
293
294 }