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