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