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