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