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.DurationUnit;
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(Time.ZERO, Duration.ZERO, new Duration(60.0, DurationUnit.MINUTE),
66 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(final SimulatorInterface<Time, Duration, OTSSimTimeDouble> pSimulator)
154 throws SimRuntimeException
155 {
156
157 this.simulator = (OTSDEVSSimulatorInterface) pSimulator;
158
159 try
160 {
161
162 Map<String, AbstractNWBRoadElement> roadMapNWB = getRoadMapNWB("A58", "NWB_A58", "NWB_wegvakken");
163
164
165 Map<String, AbstractNWBRoadElement> laneMapNWB = getRoadMapNWB("A58", "rijstroken_A58", "NWB_rijstroken");
166
167
168 Map<String, AbstractNWBRoadElement> specialLaneMapNWB =
169 getRoadMapNWB("A58", "mengstroken_A58", "NWB_mengstroken");
170
171 combineNWBMaps(roadMapNWB, laneMapNWB, specialLaneMapNWB);
172 }
173 catch (NetworkException nwe)
174 {
175 nwe.printStackTrace();
176 }
177
178 }
179
180
181
182
183
184
185
186 private void combineNWBMaps(Map<String, AbstractNWBRoadElement> roadMapNWB,
187 Map<String, AbstractNWBRoadElement> laneMapNWB, Map<String, AbstractNWBRoadElement> specialLaneMapNWB)
188 {
189
190
191
192
193 for (AbstractNWBRoadElement laneElement : laneMapNWB.values())
194 {
195 NWBDrivingLane lane = (NWBDrivingLane) laneElement;
196 NWBRoadElement road = (NWBRoadElement) roadMapNWB.get(lane.getRoadId());
197 List<LineString> lineSegmentList = splitRoad(road, lane);
198 }
199 }
200
201
202
203
204
205
206
207 private List<LineString> splitRoad(NWBRoadElement road, NWBDrivingLane segment)
208 {
209 MultiLineString lines = (MultiLineString) road.getMyGeom();
210 LineString line = (LineString) lines.getGeometryN(0);
211 List<LineString> lineSegmentList = new ArrayList<>();
212 ;
213
214
215 lineSegmentList.add(SubstringLine.getSubstring(line, segment.getBeginDistance(), segment.getEndDistance()));
216 if (segment.getBeginDistance() > 0)
217 {
218 lineSegmentList.add(SubstringLine.getSubstring(line, 0, segment.getBeginDistance()));
219 }
220 if (segment.getEndDistance() < road.getEndDistance())
221 {
222 lineSegmentList.add(SubstringLine.getSubstring(line, 0, segment.getBeginDistance()));
223 }
224 return lineSegmentList;
225 }
226
227
228
229
230
231
232
233
234
235 private Map<String, AbstractNWBRoadElement> getRoadMapNWB(String initialDir, String fileName, String shapeIdentifier)
236 throws NetworkException
237 {
238 FileDataStore dataStoreLink = null;
239 try
240 {
241 dataStoreLink = newDatastore(initialDir, fileName);
242 }
243 catch (IOException e)
244 {
245
246 e.printStackTrace();
247 }
248
249 FeatureIterator feautureIterator = getFeatureIterator(dataStoreLink);
250
251 Map<String, AbstractNWBRoadElement> roadMApNWB = getFeatureAttributes(feautureIterator, shapeIdentifier);
252 return roadMApNWB;
253
254 }
255
256
257
258
259
260
261
262 private FileDataStore newDatastore(String initialDir, final String fileName) throws IOException
263 {
264 try
265 {
266 URL url = TestShapeParser.class.getResource("/");
267 File file = new File(url.getFile() + "../../Data/" + initialDir);
268 String fn = file.getCanonicalPath();
269 fn = fn.replace('\\', '/');
270 File iniDir = new File(fn);
271 file = new File(iniDir, fileName + ".shp");
272
273 FileDataStore dataStoreLink = FileDataStoreFinder.getDataStore(file);
274 return dataStoreLink;
275
276 }
277 catch (IOException exception)
278 {
279 exception.printStackTrace();
280 }
281 return null;
282
283 }
284
285
286
287
288
289 private FeatureIterator getFeatureIterator(FileDataStore dataStore)
290 {
291 try
292 {
293 String[] typeNameLink = dataStore.getTypeNames();
294 SimpleFeatureSource sourceLink;
295 sourceLink = dataStore.getFeatureSource(typeNameLink[0]);
296 SimpleFeatureCollection featuresLink = sourceLink.getFeatures();
297 return featuresLink.features();
298
299 }
300 catch (IOException e)
301 {
302
303 e.printStackTrace();
304 }
305 return null;
306 }
307
308
309
310
311
312
313
314 private Map<String, AbstractNWBRoadElement> getFeatureAttributes(final FeatureIterator feautureIterator,
315 String shapeIdentifier) throws NetworkException
316 {
317 Map<String, AbstractNWBRoadElement> roadMap = new HashMap<>();
318 while (feautureIterator.hasNext())
319 {
320 Feature feature = feautureIterator.next();
321
322 if (shapeIdentifier.equals("NWB_wegvakken"))
323 {
324 NWBRoadElement road = getPropertiesNWB(feature);
325 roadMap.put(road.getRoadId(), road);
326 }
327 else if (shapeIdentifier.equals("NWB_rijstroken"))
328 {
329 NWBDrivingLane road = getPropertiesDrivingLanes(feature);
330 roadMap.put(road.getRoadId(), road);
331 }
332 else if (shapeIdentifier.equals("NWB_mengstroken"))
333 {
334 NWBDrivingLane road = getPropertiesSpecialLanes(feature);
335 roadMap.put(road.getRoadId(), road);
336 }
337 }
338 return roadMap;
339 }
340
341
342
343
344
345
346 private NWBRoadElement getPropertiesNWB(final Feature feature) throws NetworkException
347 {
348 Geometry theGeom = (Geometry) feature.getDefaultGeometryProperty().getValue();
349 Coordinate[] coordinates = theGeom.getCoordinates();
350 Property property = feature.getProperty("WVK_ID");
351 String roadId = property.getValue().toString();
352 property = feature.getProperty("JTE_ID_BEG");
353 String junctionIdBegin = property.getValue().toString();
354 property = feature.getProperty("JTE_ID_END");
355 String junctionIdEnd = property.getValue().toString();
356 property = feature.getProperty("ADMRICHTNG");
357 String adminDirection = property.getValue().toString();
358 property = feature.getProperty("RIJRICHTNG");
359 String drivingDirection = property.getValue().toString();
360 property = feature.getProperty("BEGINKM");
361 Double beginKM = parseDouble(property);
362 property = feature.getProperty("EINDKM");
363 Double endKM = parseDouble(property);
364 property = feature.getProperty("BEGAFSTAND");
365 Double beginDistance = parseDouble(property);
366 property = feature.getProperty("ENDAFSTAND");
367 Double endDistance = parseDouble(property);
368
369 OTSNode startNode = new OTSNode(this.network, junctionIdBegin, new OTSPoint3D(coordinates[0]));
370 OTSNode endNode = new OTSNode(this.network, junctionIdEnd, new OTSPoint3D(coordinates[coordinates.length - 1]));
371 return new NWBRoadElement(theGeom, startNode, endNode, roadId, beginDistance, endDistance, junctionIdBegin,
372 junctionIdEnd, adminDirection, drivingDirection, beginKM, endKM);
373 }
374
375
376
377
378
379
380 private NWBDrivingLane getPropertiesDrivingLanes(final Feature feature) throws NetworkException
381 {
382 Geometry theGeom = (Geometry) feature.getDefaultGeometryProperty().getValue();
383 Coordinate[] coordinates = theGeom.getCoordinates();
384
385 Property property = feature.getProperty("WVK_ID");
386 String roadId = property.getValue().toString();
387
388 property = feature.getProperty("KANTCODE");
389 String sideCode = property.getValue().toString();
390
391 property = feature.getProperty("BEGAFSTAND");
392 Double beginDistance = parseDouble(property);
393
394 property = feature.getProperty("ENDAFSTAND");
395 Double endDistance = parseDouble(property);
396
397 property = feature.getProperty("OMSCHR");
398 String laneDescription = property.getValue().toString();
399 String[] lanes = laneDescription.split("->");
400 Integer startNumberOfLanes = Integer.parseInt(lanes[0].trim());
401 Integer endNumberOfLanes = Integer.parseInt(lanes[1].trim());
402
403 String junctionIdBegin = roadId + "_" + beginDistance;
404 String junctionIdEnd = roadId + "_" + endDistance;
405 OTSNode startNode = new OTSNode(this.network, junctionIdBegin, new OTSPoint3D(coordinates[0]));
406 OTSNode endNode = new OTSNode(this.network, junctionIdEnd, new OTSPoint3D(coordinates[coordinates.length - 1]));
407 return new NWBDrivingLane(theGeom, startNode, endNode, roadId, beginDistance, endDistance, startNumberOfLanes,
408 endNumberOfLanes, sideCode);
409 }
410
411
412
413
414
415
416 private NWBDrivingLane getPropertiesSpecialLanes(final Feature feature) throws NetworkException
417 {
418 Geometry theGeom = (Geometry) feature.getDefaultGeometryProperty().getValue();
419 Coordinate[] coordinates = theGeom.getCoordinates();
420
421 Property property = feature.getProperty("WVK_ID");
422 String roadId = property.getValue().toString();
423
424 property = feature.getProperty("KANTCODE");
425 String sideCode = property.getValue().toString();
426
427 property = feature.getProperty("BEGAFSTAND");
428 Double beginDistance = parseDouble(property);
429
430 property = feature.getProperty("ENDAFSTAND");
431 Double endDistance = parseDouble(property);
432
433 property = feature.getProperty("OMSCHR");
434 String laneType = property.getValue().toString();
435
436 property = feature.getProperty("AANT_MSK");
437 String laneDescription = property.getValue().toString();
438 String[] lanes = laneDescription.split("->");
439 Integer startNumberOfLanes = Integer.parseInt(lanes[0].trim().substring(0, 1));
440 Integer endNumberOfLanes = Integer.parseInt(lanes[1].trim().substring(0, 1));
441
442 String junctionIdBegin = roadId + "_" + beginDistance;
443 String junctionIdEnd = roadId + "_" + endDistance;
444 OTSNode startNode = new OTSNode(this.network, junctionIdBegin, new OTSPoint3D(coordinates[0]));
445 OTSNode endNode = new OTSNode(this.network, junctionIdEnd, new OTSPoint3D(coordinates[coordinates.length - 1]));
446 return new NWBDrivingLane(theGeom, startNode, endNode, roadId, beginDistance, endDistance, startNumberOfLanes,
447 endNumberOfLanes, sideCode);
448 }
449
450
451
452
453
454 private Double parseDouble(Property property)
455 {
456 if (property.getValue() != null)
457 {
458 if (property.getValue().toString() != null)
459 {
460 return Double.parseDouble(property.getValue().toString());
461 }
462 }
463 return Double.NaN;
464 }
465
466
467 @Override
468 public SimulatorInterface<Time, Duration, OTSSimTimeDouble> getSimulator()
469 {
470 return this.simulator;
471 }
472
473
474 @Override
475 public OTSNetwork getNetwork()
476 {
477 return this.network;
478 }
479
480
481 @Override
482 public final String toString()
483 {
484 return "TestXMLModel [simulator=" + this.simulator + "]";
485 }
486
487 }
488
489 }