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