1 package org.opentrafficsim.road.network.factory.shape;
2
3 import java.awt.Dimension;
4 import java.awt.geom.Rectangle2D;
5 import java.io.File;
6 import java.io.IOException;
7 import java.io.Serializable;
8 import java.net.URL;
9 import java.rmi.RemoteException;
10 import java.util.ArrayList;
11 import java.util.LinkedHashMap;
12 import java.util.List;
13 import java.util.Map;
14 import java.util.UUID;
15
16 import javax.naming.NamingException;
17
18 import org.djunits.unit.DurationUnit;
19 import org.djunits.value.vdouble.scalar.Duration;
20 import org.djunits.value.vdouble.scalar.Time;
21 import org.djutils.io.URLResource;
22 import org.djutils.logger.CategoryLogger;
23 import org.geotools.data.FileDataStore;
24 import org.geotools.data.FileDataStoreFinder;
25 import org.geotools.data.shapefile.ShapefileDataStore;
26 import org.geotools.data.shapefile.ShapefileDataStoreFactory;
27 import org.geotools.data.simple.SimpleFeatureCollection;
28 import org.geotools.data.simple.SimpleFeatureSource;
29 import org.geotools.feature.FeatureIterator;
30 import org.locationtech.jts.geom.Coordinate;
31 import org.locationtech.jts.geom.Geometry;
32 import org.locationtech.jts.geom.LineString;
33 import org.locationtech.jts.geom.MultiLineString;
34 import org.opengis.feature.Feature;
35 import org.opengis.feature.Property;
36 import org.opentrafficsim.core.dsol.AbstractOTSModel;
37 import org.opentrafficsim.core.dsol.OTSAnimator;
38 import org.opentrafficsim.core.dsol.OTSReplication;
39 import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
40 import org.opentrafficsim.core.geometry.OTSGeometryException;
41 import org.opentrafficsim.core.geometry.OTSLine3D;
42 import org.opentrafficsim.core.geometry.OTSPoint3D;
43 import org.opentrafficsim.core.network.LinkType;
44 import org.opentrafficsim.core.network.NetworkException;
45 import org.opentrafficsim.core.network.OTSLink;
46 import org.opentrafficsim.core.network.OTSNetwork;
47 import org.opentrafficsim.core.network.OTSNode;
48 import org.opentrafficsim.draw.network.LinkAnimation;
49 import org.opentrafficsim.draw.network.NodeAnimation;
50 import org.opentrafficsim.road.network.OTSRoadNetwork;
51 import org.pmw.tinylog.Level;
52
53 import nl.tudelft.simulation.dsol.SimRuntimeException;
54 import nl.tudelft.simulation.dsol.experiment.ReplicationMode;
55 import nl.tudelft.simulation.dsol.simulators.AnimatorInterface;
56 import nl.tudelft.simulation.dsol.swing.animation.D2.AnimationPanel;
57 import nl.tudelft.simulation.dsol.swing.gui.DSOLApplication;
58 import nl.tudelft.simulation.dsol.swing.gui.DSOLPanel;
59 import nl.tudelft.simulation.language.DSOLException;
60
61
62
63
64 public class TestShapeParser extends DSOLApplication
65 {
66
67 private static final long serialVersionUID = 1L;
68
69
70
71
72
73 public TestShapeParser(final String title, final DSOLPanel panel)
74 {
75 super(title, panel);
76 panel.getConsole().setLogLevel(Level.TRACE);
77 }
78
79
80
81
82
83
84
85
86
87 public static void main(final String[] args) throws SimRuntimeException, NamingException, RemoteException, DSOLException
88 {
89 CategoryLogger.setAllLogLevel(Level.TRACE);
90 OTSAnimator simulator = new OTSAnimator("TestShapeParser");
91 GisNDWImport model = new GisNDWImport(simulator);
92 DSOLPanel panel = new DSOLPanel(model, simulator);
93 AnimationPanel animationPanel =
94 new AnimationPanel(new Rectangle2D.Double(125000, 375000, 40000, 35000), new Dimension(800, 600), simulator);
95 animationPanel.toggleClass(LinkAnimation.Text.class);
96 animationPanel.toggleClass(NodeAnimation.Text.class);
97 panel.getTabbedPane().add("animation", animationPanel);
98 panel.getTabbedPane().setSelectedIndex(1);
99 OTSReplication replication =
100 OTSReplication.create("rep1", Time.ZERO, Duration.ZERO, new Duration(60.0, DurationUnit.MINUTE), model);
101 simulator.initialize(replication, ReplicationMode.TERMINATING);
102 new TestShapeParser("TestShapeParser", panel);
103 }
104
105
106 @Override
107 public final String toString()
108 {
109 return "TestShapeParser []";
110 }
111
112
113
114
115
116
117
118
119
120
121
122
123 static class GisNDWImport extends AbstractOTSModel
124 {
125
126 private static final long serialVersionUID = 20141121L;
127
128
129 private final OTSRoadNetwork network;
130
131
132
133
134
135 GisNDWImport(final OTSSimulatorInterface simulator)
136 {
137 super(simulator);
138 this.network = new OTSRoadNetwork("test network", true, simulator);
139 }
140
141
142 @Override
143 public final void constructModel() throws SimRuntimeException
144 {
145 try
146 {
147
148 Map<String, AbstractNWBRoadElement> roadMapNWB = getRoadMapNWB("/A58", "NWB_A58", "NWB_wegvakken");
149
150
151 Map<String, AbstractNWBRoadElement> laneMapNWB = getRoadMapNWB("/A58", "rijstroken_A58", "NWB_rijstroken");
152
153
154 Map<String, AbstractNWBRoadElement> specialLaneMapNWB =
155 getRoadMapNWB("/A58", "mengstroken_A58", "NWB_mengstroken");
156
157 combineNWBMaps(roadMapNWB, laneMapNWB, specialLaneMapNWB);
158 }
159 catch (NetworkException nwe)
160 {
161 nwe.printStackTrace();
162 }
163
164 }
165
166
167
168
169
170
171
172 private void combineNWBMaps(Map<String, AbstractNWBRoadElement> roadMapNWB,
173 Map<String, AbstractNWBRoadElement> laneMapNWB, Map<String, AbstractNWBRoadElement> specialLaneMapNWB)
174 {
175
176
177
178
179 for (AbstractNWBRoadElement laneElement : laneMapNWB.values())
180 {
181 NWBDrivingLane lane = (NWBDrivingLane) laneElement;
182 NWBRoadElement road = (NWBRoadElement) roadMapNWB.get(lane.getRoadId());
183 if (road != null)
184 {
185 List<LineString> lineSegmentList = splitRoad(road, lane);
186 }
187 else
188 {
189 System.err.println("road for lane " + lane.toString() + " does not exist");
190 }
191 }
192 }
193
194
195
196
197
198
199
200 private List<LineString> splitRoad(NWBRoadElement road, NWBDrivingLane segment)
201 {
202 MultiLineString lines = (MultiLineString) road.getMyGeom();
203 LineString line = (LineString) lines.getGeometryN(0);
204 List<LineString> lineSegmentList = new ArrayList<>();
205
206
207
208 lineSegmentList.add(SubstringLine.getSubstring(line, segment.getBeginDistance(), segment.getEndDistance()));
209 if (segment.getBeginDistance() > 0)
210 {
211 lineSegmentList.add(SubstringLine.getSubstring(line, 0, segment.getBeginDistance()));
212 }
213 if (segment.getEndDistance() < road.getEndDistance())
214 {
215 lineSegmentList.add(SubstringLine.getSubstring(line, 0, segment.getBeginDistance()));
216 }
217 return lineSegmentList;
218 }
219
220
221
222
223
224
225
226
227
228 private Map<String, AbstractNWBRoadElement> getRoadMapNWB(String initialDir, String fileName, String shapeIdentifier)
229 throws NetworkException
230 {
231 FileDataStore dataStoreLink = null;
232 try
233 {
234 dataStoreLink = newDatastore(initialDir, fileName);
235 }
236 catch (IOException e)
237 {
238
239 e.printStackTrace();
240 }
241
242 FeatureIterator feautureIterator = getFeatureIterator(dataStoreLink);
243
244 Map<String, AbstractNWBRoadElement> roadMApNWB = getFeatureAttributes(feautureIterator, shapeIdentifier);
245 return roadMApNWB;
246
247 }
248
249
250
251
252
253
254
255 private FileDataStore newDatastore(String initialDir, final String fileName) throws IOException
256 {
257 try
258 {
259 URL url = URLResource.getResource(initialDir);
260 File iniDir = new File(url.getFile());
261 File file = new File(iniDir, fileName + ".shp");
262 System.out.println(file + " -- exists: " + file.exists());
263
264 ShapefileDataStoreFactory dataStoreFactory = new ShapefileDataStoreFactory();
265 ShapefileDataStore dataStore = (ShapefileDataStore) dataStoreFactory.createDataStore(file.toURI().toURL());
266
267 FileDataStore dataStoreLink = FileDataStoreFinder.getDataStore(file);
268 System.out.println(dataStore);
269 return dataStore;
270
271 }
272 catch (IOException exception)
273 {
274 exception.printStackTrace();
275 }
276 return null;
277
278 }
279
280
281
282
283
284 private FeatureIterator getFeatureIterator(FileDataStore dataStore)
285 {
286 try
287 {
288 String[] typeNameLink = dataStore.getTypeNames();
289 SimpleFeatureSource sourceLink;
290 sourceLink = dataStore.getFeatureSource(typeNameLink[0]);
291 SimpleFeatureCollection featuresLink = sourceLink.getFeatures();
292 return featuresLink.features();
293
294 }
295 catch (IOException e)
296 {
297
298 e.printStackTrace();
299 }
300 return null;
301 }
302
303
304
305
306
307
308
309 private Map<String, AbstractNWBRoadElement> getFeatureAttributes(final FeatureIterator feautureIterator,
310 String shapeIdentifier) throws NetworkException
311 {
312 Map<String, AbstractNWBRoadElement> roadMap = new LinkedHashMap<>();
313 while (feautureIterator.hasNext())
314 {
315 Feature feature = feautureIterator.next();
316
317 if (shapeIdentifier.equals("NWB_wegvakken"))
318 {
319 NWBRoadElement road = getPropertiesNWB(feature);
320 roadMap.put(road.getRoadId(), road);
321 }
322 else if (shapeIdentifier.equals("NWB_rijstroken"))
323 {
324 NWBDrivingLane road = getPropertiesDrivingLanes(feature);
325 roadMap.put(road.getRoadId(), road);
326 }
327 else if (shapeIdentifier.equals("NWB_mengstroken"))
328 {
329 NWBDrivingLane road = getPropertiesSpecialLanes(feature);
330 roadMap.put(road.getRoadId(), road);
331 }
332 }
333 return roadMap;
334 }
335
336
337
338
339
340
341 private NWBRoadElement getPropertiesNWB(final Feature feature) throws NetworkException
342 {
343 Geometry theGeom = (Geometry) feature.getDefaultGeometryProperty().getValue();
344 Coordinate[] coordinates = theGeom.getCoordinates();
345 Property property = feature.getProperty("WVK_ID");
346 String roadId = property.getValue().toString();
347 property = feature.getProperty("JTE_ID_BEG");
348 String junctionIdBegin = property.getValue().toString();
349 property = feature.getProperty("JTE_ID_END");
350 String junctionIdEnd = property.getValue().toString();
351 property = feature.getProperty("ADMRICHTNG");
352 String adminDirection = property.getValue().toString();
353 property = feature.getProperty("RIJRICHTNG");
354 String drivingDirection = property.getValue().toString();
355 property = feature.getProperty("BEGINKM");
356 Double beginKM = parseDouble(property);
357 property = feature.getProperty("EINDKM");
358 Double endKM = parseDouble(property);
359 property = feature.getProperty("BEGAFSTAND");
360 Double beginDistance = parseDouble(property);
361 property = feature.getProperty("ENDAFSTAND");
362 Double endDistance = parseDouble(property);
363
364 OTSNode startNode;
365 if (this.network.containsNode(junctionIdBegin))
366 startNode = (OTSNode) this.network.getNode(junctionIdBegin);
367 else
368 startNode = new OTSNode(this.network, junctionIdBegin, new OTSPoint3D(coordinates[0]));
369 OTSNode endNode;
370 if (this.network.containsNode(junctionIdEnd))
371 endNode = (OTSNode) this.network.getNode(junctionIdEnd);
372 else
373 endNode = new OTSNode(this.network, junctionIdEnd, new OTSPoint3D(coordinates[coordinates.length - 1]));
374 NWBRoadElement road = new NWBRoadElement(theGeom, startNode, endNode, roadId, beginDistance, endDistance,
375 junctionIdBegin, junctionIdEnd, adminDirection, drivingDirection, beginKM, endKM);
376 if (getSimulator() instanceof AnimatorInterface)
377 {
378 try
379 {
380 System.out.println(startNode);
381 new NodeAnimation(startNode, this.simulator);
382 new NodeAnimation(endNode, this.simulator);
383 OTSLink link = new OTSLink(this.network, UUID.randomUUID().toString(), startNode, endNode, network.getLinkType(LinkType.DEFAULTS.ROAD),
384 new OTSLine3D(coordinates));
385 new LinkAnimation(link, this.simulator, 2.0f);
386 }
387 catch (RemoteException | NamingException | OTSGeometryException exception)
388 {
389 exception.printStackTrace();
390 }
391 }
392 return road;
393 }
394
395
396
397
398
399
400 private NWBDrivingLane getPropertiesDrivingLanes(final Feature feature) throws NetworkException
401 {
402 Geometry theGeom = (Geometry) feature.getDefaultGeometryProperty().getValue();
403 Coordinate[] coordinates = theGeom.getCoordinates();
404
405 Property property = feature.getProperty("WVK_ID");
406 String roadId = property.getValue().toString();
407
408 property = feature.getProperty("KANTCODE");
409 String sideCode = property.getValue().toString();
410
411 property = feature.getProperty("BEGAFSTAND");
412 Double beginDistance = parseDouble(property);
413
414 property = feature.getProperty("ENDAFSTAND");
415 Double endDistance = parseDouble(property);
416
417 property = feature.getProperty("OMSCHR");
418 String laneDescription = property.getValue().toString();
419 String[] lanes = laneDescription.split("->");
420 Integer startNumberOfLanes = Integer.parseInt(lanes[0].trim());
421 Integer endNumberOfLanes = Integer.parseInt(lanes[1].trim());
422
423 String junctionIdBegin = roadId + "_" + beginDistance;
424 String junctionIdEnd = roadId + "_" + endDistance;
425
426 OTSNode startNode;
427 if (this.network.containsNode(junctionIdBegin))
428 startNode = (OTSNode) this.network.getNode(junctionIdBegin);
429 else
430 startNode = new OTSNode(this.network, junctionIdBegin, new OTSPoint3D(coordinates[0]));
431 OTSNode endNode;
432 if (this.network.containsNode(junctionIdEnd))
433 endNode = (OTSNode) this.network.getNode(junctionIdEnd);
434 else
435 endNode = new OTSNode(this.network, junctionIdEnd, new OTSPoint3D(coordinates[coordinates.length - 1]));
436 NWBDrivingLane lane = new NWBDrivingLane(theGeom, startNode, endNode, roadId, beginDistance, endDistance,
437 startNumberOfLanes, endNumberOfLanes, sideCode);
438 if (getSimulator() instanceof AnimatorInterface)
439 {
440 try
441 {
442 new NodeAnimation(startNode, this.simulator);
443 new NodeAnimation(endNode, this.simulator);
444 OTSLink link = new OTSLink(this.network, UUID.randomUUID().toString(), startNode, endNode, network.getLinkType(LinkType.DEFAULTS.ROAD),
445 new OTSLine3D(coordinates));
446 new LinkAnimation(link, this.simulator, 1.0f);
447 }
448 catch (RemoteException | NamingException | OTSGeometryException exception)
449 {
450 exception.printStackTrace();
451 }
452 }
453 return lane;
454 }
455
456
457
458
459
460
461 private NWBDrivingLane getPropertiesSpecialLanes(final Feature feature) throws NetworkException
462 {
463 Geometry theGeom = (Geometry) feature.getDefaultGeometryProperty().getValue();
464 Coordinate[] coordinates = theGeom.getCoordinates();
465
466 Property property = feature.getProperty("WVK_ID");
467 String roadId = property.getValue().toString();
468
469 property = feature.getProperty("KANTCODE");
470 String sideCode = property.getValue().toString();
471
472 property = feature.getProperty("BEGAFSTAND");
473 Double beginDistance = parseDouble(property);
474
475 property = feature.getProperty("ENDAFSTAND");
476 Double endDistance = parseDouble(property);
477
478 property = feature.getProperty("OMSCHR");
479 String laneType = property.getValue().toString();
480
481 property = feature.getProperty("AANT_MSK");
482 String laneDescription = property.getValue().toString();
483 String[] lanes = laneDescription.split("->");
484 Integer startNumberOfLanes = Integer.parseInt(lanes[0].trim().substring(0, 1));
485 Integer endNumberOfLanes = Integer.parseInt(lanes[1].trim().substring(0, 1));
486
487 String junctionIdBegin = roadId + "_" + beginDistance;
488 String junctionIdEnd = roadId + "_" + endDistance;
489 OTSNode startNode;
490 if (this.network.containsNode(junctionIdBegin))
491 startNode = (OTSNode) this.network.getNode(junctionIdBegin);
492 else
493 startNode = new OTSNode(this.network, junctionIdBegin, new OTSPoint3D(coordinates[0]));
494 OTSNode endNode;
495 if (this.network.containsNode(junctionIdEnd))
496 endNode = (OTSNode) this.network.getNode(junctionIdEnd);
497 else
498 endNode = new OTSNode(this.network, junctionIdEnd, new OTSPoint3D(coordinates[coordinates.length - 1]));
499 NWBDrivingLane lane = new NWBDrivingLane(theGeom, startNode, endNode, roadId, beginDistance, endDistance,
500 startNumberOfLanes, endNumberOfLanes, sideCode);
501 if (getSimulator() instanceof AnimatorInterface)
502 {
503 try
504 {
505 new NodeAnimation(startNode, this.simulator);
506 new NodeAnimation(endNode, this.simulator);
507 OTSLink link = new OTSLink(this.network, UUID.randomUUID().toString(), startNode, endNode, network.getLinkType(LinkType.DEFAULTS.ROAD),
508 new OTSLine3D(coordinates));
509 new LinkAnimation(link, this.simulator, 1.0f);
510 }
511 catch (RemoteException | NamingException | OTSGeometryException exception)
512 {
513 exception.printStackTrace();
514 }
515 }
516 return lane;
517 }
518
519
520
521
522
523 private Double parseDouble(final Property property)
524 {
525 if (property.getValue() != null)
526 {
527 if (property.getValue().toString() != null)
528 {
529 return Double.parseDouble(property.getValue().toString());
530 }
531 }
532 return Double.NaN;
533 }
534
535
536 @Override
537 public OTSNetwork getNetwork()
538 {
539 return this.network;
540 }
541
542
543 @Override
544 public final String toString()
545 {
546 return "TestXMLModel [simulator=" + this.simulator + "]";
547 }
548
549
550 @Override
551 public Serializable getSourceId()
552 {
553 return "GisNDWImport";
554 }
555
556 }
557
558 }