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