1 package org.opentrafficsim.road.network.factory.shape;
2
3 import java.awt.geom.Rectangle2D;
4 import java.io.File;
5 import java.io.IOException;
6 import java.net.URL;
7 import java.util.ArrayList;
8 import java.util.HashMap;
9 import java.util.List;
10 import java.util.Map;
11
12 import javax.naming.NamingException;
13 import javax.swing.JPanel;
14 import javax.swing.SwingUtilities;
15
16 import nl.tudelft.simulation.dsol.SimRuntimeException;
17 import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
18
19 import org.djunits.unit.TimeUnit;
20 import org.djunits.value.vdouble.scalar.Duration;
21 import org.djunits.value.vdouble.scalar.Time;
22 import org.geotools.data.FileDataStore;
23 import org.geotools.data.FileDataStoreFinder;
24 import org.geotools.data.simple.SimpleFeatureCollection;
25 import org.geotools.data.simple.SimpleFeatureSource;
26 import org.geotools.feature.FeatureIterator;
27 import org.opengis.feature.Feature;
28 import org.opengis.feature.Property;
29 import org.opentrafficsim.base.modelproperties.PropertyException;
30 import org.opentrafficsim.core.dsol.OTSDEVSSimulatorInterface;
31 import org.opentrafficsim.core.dsol.OTSModelInterface;
32 import org.opentrafficsim.core.dsol.OTSSimTimeDouble;
33 import org.opentrafficsim.core.geometry.OTSPoint3D;
34 import org.opentrafficsim.core.gtu.animation.GTUColorer;
35 import org.opentrafficsim.core.network.Network;
36 import org.opentrafficsim.core.network.NetworkException;
37 import org.opentrafficsim.core.network.OTSNetwork;
38 import org.opentrafficsim.core.network.OTSNode;
39 import org.opentrafficsim.simulationengine.AbstractWrappableAnimation;
40 import org.opentrafficsim.simulationengine.OTSSimulationException;
41 import org.opentrafficsim.simulationengine.SimpleSimulatorInterface;
42
43 import com.vividsolutions.jts.geom.Coordinate;
44 import com.vividsolutions.jts.geom.Geometry;
45 import com.vividsolutions.jts.geom.LineString;
46 import com.vividsolutions.jts.geom.MultiLineString;
47
48 public class TestShapeParser extends AbstractWrappableAnimation
49 {
50
51
52
53
54
55
56 public static void main(final String[] args) throws SimRuntimeException
57 {
58 SwingUtilities.invokeLater(new Runnable()
59 {
60 @Override
61 public void run()
62 {
63 try
64 {
65 TestShapeParser xmlModel = new TestShapeParser();
66
67 xmlModel.buildAnimator(new Time(0.0, TimeUnit.SECOND), new Duration(0.0, TimeUnit.SECOND),
68 new Duration(60.0, TimeUnit.MINUTE), new ArrayList<org.opentrafficsim.base.modelproperties.Property<?>>(), null, true);
69 }
70 catch (SimRuntimeException | NamingException | OTSSimulationException | PropertyException exception)
71 {
72 exception.printStackTrace();
73 }
74 }
75 });
76 }
77
78
79 @Override
80 public final String shortName()
81 {
82 return "TestXMLModel";
83 }
84
85
86 @Override
87 public final String description()
88 {
89 return "TestXMLModel";
90 }
91
92
93 @Override
94 public final void stopTimersThreads()
95 {
96 super.stopTimersThreads();
97 }
98
99
100 @Override
101 protected final JPanel makeCharts(final SimpleSimulatorInterface simulator)
102 {
103 return null;
104 }
105
106
107 @Override
108 protected final OTSModelInterface makeModel(final GTUColorer colorer)
109 {
110 return new GisNDWImport();
111 }
112
113
114 @Override
115 protected final java.awt.geom.Rectangle2D.Double makeAnimationRectangle()
116 {
117 return new Rectangle2D.Double(-1000, -1000, 2000, 2000);
118 }
119
120
121 @Override
122 public final String toString()
123 {
124 return "TestGISParser []";
125 }
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142 class GisNDWImport implements OTSModelInterface
143 {
144
145 private static final long serialVersionUID = 20141121L;
146
147
148 private OTSDEVSSimulatorInterface simulator;
149
150
151 private final Network network = new OTSNetwork("test network");
152
153
154 @Override
155 public final void constructModel(
156 final SimulatorInterface<Time, Duration, OTSSimTimeDouble> pSimulator)
157 throws SimRuntimeException
158 {
159
160 this.simulator = (OTSDEVSSimulatorInterface) pSimulator;
161
162 try
163 {
164
165 Map<String, AbstractNWBRoadElement> roadMapNWB = getRoadMapNWB("A58", "NWB_A58", "NWB_wegvakken");
166
167
168 Map<String, AbstractNWBRoadElement> laneMapNWB = getRoadMapNWB("A58", "rijstroken_A58", "NWB_rijstroken");
169
170
171 Map<String, AbstractNWBRoadElement> specialLaneMapNWB =
172 getRoadMapNWB("A58", "mengstroken_A58", "NWB_mengstroken");
173
174 combineNWBMaps(roadMapNWB, laneMapNWB, specialLaneMapNWB);
175 }
176 catch (NetworkException nwe)
177 {
178 nwe.printStackTrace();
179 }
180
181 }
182
183
184
185
186
187
188
189 private void combineNWBMaps(Map<String, AbstractNWBRoadElement> roadMapNWB,
190 Map<String, AbstractNWBRoadElement> laneMapNWB, Map<String, AbstractNWBRoadElement> specialLaneMapNWB)
191 {
192
193
194
195
196 for (AbstractNWBRoadElement laneElement : laneMapNWB.values())
197 {
198 NWBDrivingLane lane = (NWBDrivingLane) laneElement;
199 NWBRoadElement road = (NWBRoadElement) roadMapNWB.get(lane.getRoadId());
200 List<LineString> lineSegmentList = splitRoad(road, lane);
201 }
202 }
203
204
205
206
207
208
209
210 private List<LineString> splitRoad(NWBRoadElement road, NWBDrivingLane segment)
211 {
212 MultiLineString lines = (MultiLineString) road.getMyGeom();
213 LineString line = (LineString) lines.getGeometryN(0);
214 List<LineString> lineSegmentList = new ArrayList<>();
215 ;
216
217
218 lineSegmentList.add(SubstringLine.getSubstring(line, segment.getBeginDistance(), segment.getEndDistance()));
219 if (segment.getBeginDistance() > 0)
220 {
221 lineSegmentList.add(SubstringLine.getSubstring(line, 0, segment.getBeginDistance()));
222 }
223 if (segment.getEndDistance() < road.getEndDistance())
224 {
225 lineSegmentList.add(SubstringLine.getSubstring(line, 0, segment.getBeginDistance()));
226 }
227 return lineSegmentList;
228 }
229
230
231
232
233
234
235
236
237
238 private Map<String, AbstractNWBRoadElement> getRoadMapNWB(String initialDir, String fileName, String shapeIdentifier)
239 throws NetworkException
240 {
241 FileDataStore dataStoreLink = null;
242 try
243 {
244 dataStoreLink = newDatastore(initialDir, fileName);
245 }
246 catch (IOException e)
247 {
248
249 e.printStackTrace();
250 }
251
252 FeatureIterator feautureIterator = getFeatureIterator(dataStoreLink);
253
254 Map<String, AbstractNWBRoadElement> roadMApNWB = getFeatureAttributes(feautureIterator, shapeIdentifier);
255 return roadMApNWB;
256
257 }
258
259
260
261
262
263
264
265 private FileDataStore newDatastore(String initialDir, final String fileName) throws IOException
266 {
267 try
268 {
269 URL url = TestShapeParser.class.getResource("/");
270 File file = new File(url.getFile() + "../../Data/" + initialDir);
271 String fn = file.getCanonicalPath();
272 fn = fn.replace('\\', '/');
273 File iniDir = new File(fn);
274 file = new File(iniDir, fileName + ".shp");
275
276 FileDataStore dataStoreLink = FileDataStoreFinder.getDataStore(file);
277 return dataStoreLink;
278
279 }
280 catch (IOException exception)
281 {
282 exception.printStackTrace();
283 }
284 return null;
285
286 }
287
288
289
290
291
292 private FeatureIterator getFeatureIterator(FileDataStore dataStore)
293 {
294 try
295 {
296 String[] typeNameLink = dataStore.getTypeNames();
297 SimpleFeatureSource sourceLink;
298 sourceLink = dataStore.getFeatureSource(typeNameLink[0]);
299 SimpleFeatureCollection featuresLink = sourceLink.getFeatures();
300 return featuresLink.features();
301
302 }
303 catch (IOException e)
304 {
305
306 e.printStackTrace();
307 }
308 return null;
309 }
310
311
312
313
314
315
316
317 private Map<String, AbstractNWBRoadElement> getFeatureAttributes(final FeatureIterator feautureIterator,
318 String shapeIdentifier) throws NetworkException
319 {
320 Map<String, AbstractNWBRoadElement> roadMap = new HashMap<>();
321 while (feautureIterator.hasNext())
322 {
323 Feature feature = feautureIterator.next();
324
325 if (shapeIdentifier.equals("NWB_wegvakken"))
326 {
327 NWBRoadElement road = getPropertiesNWB(feature);
328 roadMap.put(road.getRoadId(), road);
329 }
330 else if (shapeIdentifier.equals("NWB_rijstroken"))
331 {
332 NWBDrivingLane road = getPropertiesDrivingLanes(feature);
333 roadMap.put(road.getRoadId(), road);
334 }
335 else if (shapeIdentifier.equals("NWB_mengstroken"))
336 {
337 NWBDrivingLane road = getPropertiesSpecialLanes(feature);
338 roadMap.put(road.getRoadId(), road);
339 }
340 }
341 return roadMap;
342 }
343
344
345
346
347
348
349 private NWBRoadElement getPropertiesNWB(final Feature feature) throws NetworkException
350 {
351 Geometry theGeom = (Geometry) feature.getDefaultGeometryProperty().getValue();
352 Coordinate[] coordinates = theGeom.getCoordinates();
353 Property property = feature.getProperty("WVK_ID");
354 String roadId = property.getValue().toString();
355 property = feature.getProperty("JTE_ID_BEG");
356 String junctionIdBegin = property.getValue().toString();
357 property = feature.getProperty("JTE_ID_END");
358 String junctionIdEnd = property.getValue().toString();
359 property = feature.getProperty("ADMRICHTNG");
360 String adminDirection = property.getValue().toString();
361 property = feature.getProperty("RIJRICHTNG");
362 String drivingDirection = property.getValue().toString();
363 property = feature.getProperty("BEGINKM");
364 Double beginKM = parseDouble(property);
365 property = feature.getProperty("EINDKM");
366 Double endKM = parseDouble(property);
367 property = feature.getProperty("BEGAFSTAND");
368 Double beginDistance = parseDouble(property);
369 property = feature.getProperty("ENDAFSTAND");
370 Double endDistance = parseDouble(property);
371
372 OTSNode startNode = new OTSNode(this.network, junctionIdBegin, new OTSPoint3D(coordinates[0]));
373 OTSNode endNode = new OTSNode(this.network, junctionIdEnd, new OTSPoint3D(coordinates[coordinates.length - 1]));
374 return new NWBRoadElement(theGeom, startNode, endNode, roadId, beginDistance, endDistance, junctionIdBegin,
375 junctionIdEnd, adminDirection, drivingDirection, beginKM, endKM);
376 }
377
378
379
380
381
382
383 private NWBDrivingLane getPropertiesDrivingLanes(final Feature feature) throws NetworkException
384 {
385 Geometry theGeom = (Geometry) feature.getDefaultGeometryProperty().getValue();
386 Coordinate[] coordinates = theGeom.getCoordinates();
387
388 Property property = feature.getProperty("WVK_ID");
389 String roadId = property.getValue().toString();
390
391 property = feature.getProperty("KANTCODE");
392 String sideCode = property.getValue().toString();
393
394 property = feature.getProperty("BEGAFSTAND");
395 Double beginDistance = parseDouble(property);
396
397 property = feature.getProperty("ENDAFSTAND");
398 Double endDistance = parseDouble(property);
399
400 property = feature.getProperty("OMSCHR");
401 String laneDescription = property.getValue().toString();
402 String[] lanes = laneDescription.split("->");
403 Integer startNumberOfLanes = Integer.parseInt(lanes[0].trim());
404 Integer endNumberOfLanes = Integer.parseInt(lanes[1].trim());
405
406 String junctionIdBegin = roadId + "_" + beginDistance;
407 String junctionIdEnd = roadId + "_" + endDistance;
408 OTSNode startNode = new OTSNode(this.network, junctionIdBegin, new OTSPoint3D(coordinates[0]));
409 OTSNode endNode = new OTSNode(this.network, junctionIdEnd, new OTSPoint3D(coordinates[coordinates.length - 1]));
410 return new NWBDrivingLane(theGeom, startNode, endNode, roadId, beginDistance, endDistance, startNumberOfLanes,
411 endNumberOfLanes, sideCode);
412 }
413
414
415
416
417
418
419 private NWBDrivingLane getPropertiesSpecialLanes(final Feature feature) throws NetworkException
420 {
421 Geometry theGeom = (Geometry) feature.getDefaultGeometryProperty().getValue();
422 Coordinate[] coordinates = theGeom.getCoordinates();
423
424 Property property = feature.getProperty("WVK_ID");
425 String roadId = property.getValue().toString();
426
427 property = feature.getProperty("KANTCODE");
428 String sideCode = property.getValue().toString();
429
430 property = feature.getProperty("BEGAFSTAND");
431 Double beginDistance = parseDouble(property);
432
433 property = feature.getProperty("ENDAFSTAND");
434 Double endDistance = parseDouble(property);
435
436 property = feature.getProperty("OMSCHR");
437 String laneType = property.getValue().toString();
438
439 property = feature.getProperty("AANT_MSK");
440 String laneDescription = property.getValue().toString();
441 String[] lanes = laneDescription.split("->");
442 Integer startNumberOfLanes = Integer.parseInt(lanes[0].trim().substring(0, 1));
443 Integer endNumberOfLanes = Integer.parseInt(lanes[1].trim().substring(0, 1));
444
445 String junctionIdBegin = roadId + "_" + beginDistance;
446 String junctionIdEnd = roadId + "_" + endDistance;
447 OTSNode startNode = new OTSNode(this.network, junctionIdBegin, new OTSPoint3D(coordinates[0]));
448 OTSNode endNode = new OTSNode(this.network, junctionIdEnd, new OTSPoint3D(coordinates[coordinates.length - 1]));
449 return new NWBDrivingLane(theGeom, startNode, endNode, roadId, beginDistance, endDistance, startNumberOfLanes,
450 endNumberOfLanes, sideCode);
451 }
452
453
454
455
456
457 private Double parseDouble(Property property)
458 {
459 if (property.getValue() != null)
460 {
461 if (property.getValue().toString() != null)
462 {
463 return Double.parseDouble(property.getValue().toString());
464 }
465 }
466 return Double.NaN;
467 }
468
469
470 @Override
471 public SimulatorInterface<Time, Duration, OTSSimTimeDouble> getSimulator()
472
473 {
474 return this.simulator;
475 }
476
477
478 @Override
479 public final String toString()
480 {
481 return "TestXMLModel [simulator=" + this.simulator + "]";
482 }
483
484 }
485
486 }