View Javadoc
1   /**
2    *
3    */
4   package org.opentrafficsim.road.network.factory.vissim;
5   
6   import java.io.File;
7   import java.util.ArrayList;
8   import java.util.Iterator;
9   import java.util.List;
10  import java.util.Map;
11  
12  import javax.xml.bind.JAXBContext;
13  import javax.xml.bind.JAXBException;
14  import javax.xml.bind.Marshaller;
15  
16  import org.djunits.unit.DirectionUnit;
17  import org.djunits.unit.LengthUnit;
18  import org.djunits.unit.SpeedUnit;
19  import org.djunits.value.vdouble.scalar.Length;
20  import org.djunits.value.vdouble.scalar.Speed;
21  import org.opentrafficsim.core.geometry.OTSPoint3D;
22  import org.opentrafficsim.core.gtu.GTUType;
23  import org.opentrafficsim.core.network.NetworkException;
24  import org.opentrafficsim.road.network.factory.vissim.xsd.DEFINITIONS;
25  import org.opentrafficsim.road.network.factory.vissim.xsd.GLOBAL;
26  import org.opentrafficsim.road.network.factory.vissim.xsd.GTU;
27  import org.opentrafficsim.road.network.factory.vissim.xsd.LINK;
28  import org.opentrafficsim.road.network.factory.vissim.xsd.LINK.BEZIER;
29  import org.opentrafficsim.road.network.factory.vissim.xsd.NETWORK;
30  import org.opentrafficsim.road.network.factory.vissim.xsd.NODE;
31  import org.opentrafficsim.road.network.factory.vissim.xsd.ObjectFactory;
32  import org.opentrafficsim.road.network.factory.vissim.xsd.ROADLAYOUT;
33  import org.opentrafficsim.road.network.factory.vissim.xsd.ROADTYPE;
34  import org.opentrafficsim.road.network.lane.Lane;
35  import org.opentrafficsim.road.network.lane.object.LaneBasedObject;
36  import org.opentrafficsim.road.network.lane.object.sensor.SingleSensor;
37  
38  /**
39   * @author NLGUTU
40   */
41  public class XMLNetworkWriter
42  {
43  
44      static void writeToXML(File file, Map<String, LinkTag> linkTags, Map<String, NodeTag> nodeTags, String sinkKillClassName,
45              String sensorClassName, String trafficLightName) throws NetworkException
46      {
47          try
48          {
49  
50              DEFINITIONS definitions = generateDefinitions();
51  
52              generateGtusAndRoadtypes(definitions);
53  
54              List<NODE> nodes = new ArrayList<>();
55              generateNodes(nodes, nodeTags);
56  
57              List<LINK> links = new ArrayList<>();
58              List<ROADLAYOUT> roadLayouts = new ArrayList<>();
59              generateLinks(links, roadLayouts, linkTags, sinkKillClassName, sensorClassName, trafficLightName);
60              definitions.getContent().addAll(roadLayouts);
61  
62              marshall(file, definitions, nodes, links);
63  
64          }
65          catch (JAXBException e)
66          {
67              e.printStackTrace();
68          }
69      }
70  
71      private static DEFINITIONS generateDefinitions()
72      {
73          DEFINITIONS definitions = new DEFINITIONS();
74          generateGTUTypes(definitions);
75          GLOBAL global = new GLOBAL();
76          definitions.getContent().add(global);
77          return definitions;
78      }
79  
80      private static void generateGTUTypes(DEFINITIONS definitions)
81      {
82          List<GTUTYPE> gtuTypes = new ArrayList<>();
83          GTUTYPE gtuType = new GTUTYPE();
84          gtuType.setNAME("CAR");
85          gtuTypes.add(gtuType);
86          definitions.getContent().addAll(gtuTypes);
87      }
88  
89      private static void generateGtusAndRoadtypes(DEFINITIONS definitions)
90      {
91          // definitions.getContent().add(gtuType);
92          List<GTU> gtus = new ArrayList<>();
93          GTU gtu = new GTU();
94          gtu.setNAME("CAR");
95          gtu.setGTUTYPE("CAR");
96          gtu.setMAXSPEED("CONST(" + new Speed(140, SpeedUnit.KM_PER_HOUR).getInUnit(SpeedUnit.KM_PER_HOUR) + ") km/h");
97          gtu.setLENGTH("CONST(" + new Length(4.5, LengthUnit.METER).getInUnit(LengthUnit.METER) + ") m");
98          gtu.setWIDTH("CONST(" + new Length(2.0, LengthUnit.METER).getInUnit(LengthUnit.METER) + ") m");
99          gtus.add(gtu);
100         definitions.getContent().addAll(gtus);
101 
102         // road types
103         List<ROADTYPE> roadTypes = new ArrayList<>();
104         ROADTYPE roadType = new ROADTYPE();
105         roadType.setDEFAULTLANEKEEPING("KEEPLANE");
106         roadType.setDEFAULTOVERTAKING("NONE");
107         roadType.setDEFAULTLANEWIDTH("3.5m");
108         roadType.setNAME("RINGROAD");
109         ROADTYPE.SPEEDLIMIT speedLimit = new ROADTYPE.SPEEDLIMIT();
110         speedLimit.setGTUTYPE(gtu.getGTUTYPE());
111         speedLimit.setLEGALSPEEDLIMIT(new Speed(140, SpeedUnit.KM_PER_HOUR).getInUnit(SpeedUnit.KM_PER_HOUR) + " km/h");
112         roadType.getSPEEDLIMIT().add(speedLimit);
113         roadTypes.add(roadType);
114         definitions.getContent().addAll(roadTypes);
115 
116     }
117 
118     private static void marshall(File file, DEFINITIONS definitions, List<NODE> nodes, List<LINK> links) throws JAXBException
119     {
120         JAXBContext jaxbContext = JAXBContext.newInstance("org.opentrafficsim.road.network.factory.vissim.xsd");
121         Marshaller marshaller = jaxbContext.createMarshaller();
122         ObjectFactory outputFactory = new ObjectFactory();
123         NETWORK networkElement = outputFactory.createNETWORK();
124         networkElement.getDEFINITIONSOrIncludeOrNODE().add(definitions);
125         networkElement.getDEFINITIONSOrIncludeOrNODE().addAll(nodes);
126         networkElement.getDEFINITIONSOrIncludeOrNODE().addAll(links);
127         marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
128         marshaller.marshal(networkElement, System.out);
129         marshaller.marshal(networkElement, file);
130     }
131 
132     private static void generateLinks(List<LINK> links, List<ROADLAYOUT> roadLayouts, Map<String, LinkTag> linkTags,
133             String sinkKillClassName, String sensorClassName, String trafficLightName) throws NetworkException
134     {
135 
136         Iterator<LinkTag> iter = linkTags.values().iterator();
137         while (iter.hasNext())
138         {
139             LinkTag inputLink = iter.next();
140             LINK link = new LINK();
141             // set link the attributes and items
142             link.setNAME(inputLink.name);
143             String layoutName = "rl" + link.getNAME();
144             link.setROADLAYOUTAttribute(layoutName);
145 
146             if (inputLink.arcTag != null)
147             {
148                 LINK.ARC arc = new LINK.ARC();
149                 arc.setANGLE(inputLink.arcTag.angle.getInUnit(DirectionUnit.EAST_DEGREE) + " deg");
150                 arc.setRADIUS("" + inputLink.arcTag.radius.getInUnit(LengthUnit.METER));
151                 arc.setDIRECTION("" + inputLink.arcTag.direction);
152                 link.setARC(arc);
153             }
154 
155             if (inputLink.bezierTag != null)
156             {
157                 LINK.BEZIER bezier = new BEZIER();
158                 link.setBEZIER(bezier);
159             }
160 
161             ROADLAYOUT rla = new ROADLAYOUT();
162             rla.setROADTYPE("RINGROAD");
163             rla.setNAME(layoutName);
164 
165             Iterator<Lane> lanes = inputLink.lanes.values().iterator();
166             while (lanes.hasNext())
167             {
168                 ROADLAYOUT.LANE lane = new ROADLAYOUT.LANE();
169                 Lane inputLane = lanes.next();
170                 lane.setNAME(inputLane.getId());
171                 lane.setWIDTH(inputLane.getBeginWidth().getInUnit(LengthUnit.METER) + "m");
172                 lane.setOFFSET(inputLane.getDesignLineOffsetAtBegin().getInUnit(LengthUnit.METER) + "m");
173                 if (inputLane.getDesignLineOffsetAtBegin().ne(inputLane.getDesignLineOffsetAtEnd()))
174                 {
175                     double differenceOffset = inputLane.getDesignLineOffsetAtEnd().minus(inputLane.getDesignLineOffsetAtBegin())
176                             .getInUnit(LengthUnit.METER);
177                     link.setOFFSETEND("" + differenceOffset + "m");
178                 }
179                 if (inputLink.connector)
180                 {
181                     lane.setCOLOR("BLACK");
182                 }
183                 else
184                 {
185                     lane.setCOLOR("GRAY");
186                 }
187                 lane.setDIRECTION("FORWARD");
188                 ROADLAYOUT.LANE.SPEEDLIMIT speedLimit = new ROADLAYOUT.LANE.SPEEDLIMIT();
189                 try
190                 {
191                     speedLimit.setLEGALSPEEDLIMIT(
192                             inputLane.getSpeedLimit(inputLane.getNetwork().getGtuType(GTUType.DEFAULTS.VEHICLE))
193                                     .getInUnit(SpeedUnit.KM_PER_HOUR) + " km/h");
194                 }
195                 catch (Exception exception)
196                 {
197                     System.err.println(exception.getMessage());
198                     speedLimit.setLEGALSPEEDLIMIT("100.0 km/h");
199                 }
200                 speedLimit.setGTUTYPE("CAR");
201                 lane.getSPEEDLIMIT().add(speedLimit);
202                 rla.getLANEOrNOTRAFFICLANEOrSHOULDER().add(lane);
203                 for (SingleSensor inputSensor : inputLane.getSensors())
204                 {
205                     LINK.SENSOR sensor = new LINK.SENSOR();
206                     sensor.setNAME(inputSensor.getId());
207                     sensor.setLANE(lane.getNAME());
208                     sensor.setPOSITION(
209                             Double.toString(inputSensor.getLongitudinalPosition().getInUnit(LengthUnit.METER)) + " m");
210                     sensor.setTRIGGER(" " + inputSensor.getPositionType());
211                     if (sensor.getNAME().startsWith("SINK@"))
212                     {
213                         sensor.setCLASS(sinkKillClassName);
214                     }
215                     else
216                     {
217                         sensor.setCLASS(sensorClassName);
218                     }
219                     link.getLANEOVERRIDEOrGENERATOROrLISTGENERATOR().add(sensor);
220                 }
221 
222                 for (LaneBasedObject inputSimpleTrafficLight : inputLane.getLaneBasedObjects())
223                 {
224                     LINK.TRAFFICLIGHT simpleTrafficLight = new LINK.TRAFFICLIGHT();
225                     simpleTrafficLight.setNAME(inputSimpleTrafficLight.getId());
226                     simpleTrafficLight.setLANE(lane.getNAME());
227                     simpleTrafficLight.setPOSITION(
228                             Double.toString(inputSimpleTrafficLight.getLongitudinalPosition().getInUnit(LengthUnit.METER))
229                                     + " m");
230                     simpleTrafficLight.setCLASS(trafficLightName);
231                     link.getLANEOVERRIDEOrGENERATOROrLISTGENERATOR().add(simpleTrafficLight);
232                 }
233                 ROADLAYOUT.STRIPE stripe = new ROADLAYOUT.STRIPE();
234                 stripe.setTYPE("DASHED");
235                 stripe.setOFFSET(inputLane.getDesignLineOffsetAtBegin().minus(inputLane.getBeginWidth().divideBy(2.0))
236                         .getInUnit(LengthUnit.METER) + "m");
237                 rla.getLANEOrNOTRAFFICLANEOrSHOULDER().add(stripe);
238 
239             }
240             // link.setROADLAYOUT(rla);
241             roadLayouts.add(rla);
242 
243             if (inputLink.straightTag != null)
244             {
245                 LINK.STRAIGHT straight = new LINK.STRAIGHT();
246                 if (inputLink.straightTag.length != null)
247                 {
248                     straight.setLENGTH(inputLink.straightTag.length.getInUnit(LengthUnit.METER) + " m");
249                 }
250                 link.setSTRAIGHT(straight);
251             }
252 
253             if (inputLink.polyLineTag != null)
254             {
255                 LINK.POLYLINE polyLine = new LINK.POLYLINE();
256                 String coordString = null;
257                 int length = inputLink.polyLineTag.vertices.length;
258                 for (int i = 0; i < length; i++)
259                 {
260                     OTSPoint3D coord = inputLink.polyLineTag.vertices[i];
261                     coordString = "(" + coord.x + "," + coord.y + "," + coord.z + ")";
262                     polyLine.getINTERMEDIATEPOINTS().add(coordString);
263                 }
264                 link.setPOLYLINE(polyLine);
265             }
266 
267             link.setNODESTART(inputLink.nodeStartTag.name);
268             link.setNODEEND(inputLink.nodeEndTag.name);
269             links.add(link);
270         }
271     }
272 
273     private static void generateNodes(List<NODE> nodes, Map<String, NodeTag> nodeTags)
274     {
275         Iterator<NodeTag> iterNode = nodeTags.values().iterator();
276         while (iterNode.hasNext())
277         {
278             NodeTag inputNode = iterNode.next();
279             NODE node = new NODE();
280             node.setNAME(inputNode.name);
281             node.setCOORDINATE(inputNode.coordinate.toString());
282             nodes.add(node);
283         }
284     }
285 
286 }