1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
10 /// @file    MSXMLRawOut.cpp
11 /// @author  Daniel Krajzewicz
12 /// @author  Jakob Erdmann
13 /// @author  Sascha Krieg
14 /// @author  Bjoern Hendriks
15 /// @author  Michael Behrisch
16 /// @date    Mon, 10.05.2004
17 /// @version $Id$
18 ///
19 // Realises dumping the complete network state
20 /****************************************************************************/
21 
22 
23 // ===========================================================================
24 // included modules
25 // ===========================================================================
26 #include <config.h>
27 
28 #include <utils/geom/GeomHelper.h>
29 #include <microsim/MSEdgeControl.h>
30 #include <microsim/MSEdge.h>
31 #include <microsim/MSLane.h>
32 #include <microsim/MSNet.h>
33 #include <microsim/MSVehicle.h>
34 #include <microsim/pedestrians/MSPModel.h>
35 #include <microsim/lcmodels/MSAbstractLaneChangeModel.h>
36 #include <microsim/MSGlobals.h>
37 #include <microsim/MSContainer.h>
38 #include <utils/iodevices/OutputDevice.h>
39 #include "MSXMLRawOut.h"
40 
41 #include <mesosim/MELoop.h>
42 #include <mesosim/MESegment.h>
43 
44 
45 // ===========================================================================
46 // method definitions
47 // ===========================================================================
48 void
write(OutputDevice & of,const MSEdgeControl & ec,SUMOTime timestep,int precision)49 MSXMLRawOut::write(OutputDevice& of, const MSEdgeControl& ec,
50                    SUMOTime timestep, int precision) {
51     of.openTag("timestep") << " time=\"" << time2string(timestep) << "\"";
52     of.setPrecision(precision);
53     const MSEdgeVector& edges = ec.getEdges();
54     for (MSEdgeVector::const_iterator e = edges.begin(); e != edges.end(); ++e) {
55         writeEdge(of, **e, timestep);
56     }
57     of.setPrecision(gPrecision);
58     of.closeTag();
59 }
60 
61 
62 void
writeEdge(OutputDevice & of,const MSEdge & edge,SUMOTime timestep)63 MSXMLRawOut::writeEdge(OutputDevice& of, const MSEdge& edge, SUMOTime timestep) {
64     //en
65     bool dump = !MSGlobals::gOmitEmptyEdgesOnDump;
66     if (!dump) {
67         if (MSGlobals::gUseMesoSim) {
68             MESegment* seg = MSGlobals::gMesoNet->getSegmentForEdge(edge);
69             while (seg != nullptr) {
70                 if (seg->getCarNumber() != 0) {
71                     dump = true;
72                     break;
73                 }
74                 seg = seg->getNextSegment();
75             }
76         } else {
77             const std::vector<MSLane*>& lanes = edge.getLanes();
78             for (std::vector<MSLane*>::const_iterator lane = lanes.begin(); lane != lanes.end(); ++lane) {
79                 if (((**lane).getVehicleNumber() != 0)) {
80                     dump = true;
81                     break;
82                 }
83             }
84         }
85     }
86     //en
87     const std::vector<MSTransportable*>& persons = edge.getSortedPersons(timestep);
88     const std::vector<MSTransportable*>& containers = edge.getSortedContainers(timestep);
89     if (dump || persons.size() > 0 || containers.size() > 0) {
90         of.openTag("edge") << " id=\"" << edge.getID() << "\"";
91         if (dump) {
92             if (MSGlobals::gUseMesoSim) {
93                 MESegment* seg = MSGlobals::gMesoNet->getSegmentForEdge(edge);
94                 while (seg != nullptr) {
95                     seg->writeVehicles(of);
96                     seg = seg->getNextSegment();
97                 }
98             } else {
99                 const std::vector<MSLane*>& lanes = edge.getLanes();
100                 for (std::vector<MSLane*>::const_iterator lane = lanes.begin(); lane != lanes.end(); ++lane) {
101                     writeLane(of, **lane);
102                 }
103             }
104         }
105         // write persons
106         for (std::vector<MSTransportable*>::const_iterator it_p = persons.begin(); it_p != persons.end(); ++it_p) {
107             writeTransportable(of, *it_p, SUMO_TAG_PERSON);
108         }
109         // write containers
110         for (std::vector<MSTransportable*>::const_iterator it_c = containers.begin(); it_c != containers.end(); ++it_c) {
111             writeTransportable(of, *it_c, SUMO_TAG_CONTAINER);
112         }
113         of.closeTag();
114     }
115 }
116 
117 
118 void
writeLane(OutputDevice & of,const MSLane & lane)119 MSXMLRawOut::writeLane(OutputDevice& of, const MSLane& lane) {
120     of.openTag("lane").writeAttr(SUMO_ATTR_ID, lane.getID());
121     for (const MSBaseVehicle* const veh : lane.getVehiclesSecure()) {
122         writeVehicle(of, *veh);
123     }
124     lane.releaseVehicles();
125     of.closeTag();
126 }
127 
128 
129 void
writeVehicle(OutputDevice & of,const MSBaseVehicle & veh)130 MSXMLRawOut::writeVehicle(OutputDevice& of, const MSBaseVehicle& veh) {
131     if (veh.isOnRoad()) {
132         of.openTag("vehicle");
133         of.writeAttr(SUMO_ATTR_ID, veh.getID());
134         of.writeAttr(SUMO_ATTR_POSITION, veh.getPositionOnLane());
135         of.writeAttr(SUMO_ATTR_SPEED, veh.getSpeed());
136         // TODO: activate action step length output, if required
137         //of.writeAttr(SUMO_ATTR_ACTIONSTEPLENGTH, veh.getActionStepLength());
138         if (!MSGlobals::gUseMesoSim) {
139             const MSVehicle& microVeh = static_cast<const MSVehicle&>(veh);
140             // microsim-specific stuff
141             if (MSAbstractLaneChangeModel::haveLateralDynamics()) {
142                 const double posLat = microVeh.getLateralPositionOnLane();
143                 of.writeAttr(SUMO_ATTR_POSITION_LAT, posLat);
144             }
145             const int personNumber = microVeh.getPersonNumber();
146             if (personNumber > 0) {
147                 of.writeAttr(SUMO_ATTR_PERSON_NUMBER, personNumber);
148             }
149             const int containerNumber = microVeh.getContainerNumber();
150             if (containerNumber > 0) {
151                 of.writeAttr(SUMO_ATTR_CONTAINER_NUMBER, containerNumber);
152             }
153             const std::vector<MSTransportable*>& persons = microVeh.getPersons();
154             for (std::vector<MSTransportable*>::const_iterator it_p = persons.begin(); it_p != persons.end(); ++it_p) {
155                 writeTransportable(of, *it_p, SUMO_TAG_PERSON);
156             }
157             const std::vector<MSTransportable*>& containers = microVeh.getContainers();
158             for (std::vector<MSTransportable*>::const_iterator it_c = containers.begin(); it_c != containers.end(); ++it_c) {
159                 writeTransportable(of, *it_c, SUMO_TAG_CONTAINER);
160             }
161         }
162         of.closeTag();
163     }
164 }
165 
166 
167 void
writeTransportable(OutputDevice & of,const MSTransportable * p,SumoXMLTag tag)168 MSXMLRawOut::writeTransportable(OutputDevice& of, const MSTransportable* p, SumoXMLTag tag) {
169     of.openTag(tag);
170     of.writeAttr(SUMO_ATTR_ID, p->getID());
171     of.writeAttr(SUMO_ATTR_POSITION, p->getEdgePos());
172     of.writeAttr(SUMO_ATTR_ANGLE, GeomHelper::naviDegree(p->getAngle()));
173     of.writeAttr("stage", p->getCurrentStageDescription());
174     of.closeTag();
175 }
176 
177 /****************************************************************************/
178