LCOV - code coverage report
Current view: top level - src/microsim/output - MSMeanData_Net.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 76.6 % 274 210
Test Date: 2026-09-20 15:45:03 Functions: 88.9 % 18 16

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2004-2026 German Aerospace Center (DLR) and others.
       4              : // This program and the accompanying materials are made available under the
       5              : // terms of the Eclipse Public License 2.0 which is available at
       6              : // https://www.eclipse.org/legal/epl-2.0/
       7              : // This Source Code may also be made available under the following Secondary
       8              : // Licenses when the conditions for such availability set forth in the Eclipse
       9              : // Public License 2.0 are satisfied: GNU General Public License, version 2
      10              : // or later which is available at
      11              : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
      12              : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
      13              : /****************************************************************************/
      14              : /// @file    MSMeanData_Net.cpp
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Michael Behrisch
      17              : /// @author  Jakob Erdmann
      18              : /// @date    Mon, 10.05.2004
      19              : ///
      20              : // Network state mean data collector for edges/lanes
      21              : /****************************************************************************/
      22              : #include <config.h>
      23              : 
      24              : #ifdef HAVE_FOX
      25              : #include <utils/common/ScopedLocker.h>
      26              : #endif
      27              : #include <utils/common/SUMOTime.h>
      28              : #include <utils/common/ToString.h>
      29              : #include <utils/iodevices/OutputDevice.h>
      30              : #include <microsim/MSEdgeControl.h>
      31              : #include <microsim/MSEdge.h>
      32              : #include <microsim/MSLane.h>
      33              : #include <microsim/MSVehicle.h>
      34              : #include <microsim/MSGlobals.h>
      35              : #include <mesosim/MELoop.h>
      36              : #include <mesosim/MESegment.h>
      37              : #include "MSMeanData_Net.h"
      38              : 
      39              : 
      40              : // ===========================================================================
      41              : // debug constants
      42              : // ===========================================================================
      43              : //#define DEBUG_OCCUPANCY
      44              : //#define DEBUG_OCCUPANCY2
      45              : //#define DEBUG_NOTIFY_ENTER
      46              : //#define DEBUG_COND (veh.getLane()->getID() == "")
      47              : //#define DEBUG_COND (false)
      48              : //#define DEBUG_COND2 (veh.getEdge()->getID() == "")
      49              : 
      50              : 
      51              : // ===========================================================================
      52              : // method definitions
      53              : // ===========================================================================
      54              : // ---------------------------------------------------------------------------
      55              : // MSMeanData_Net::MSLaneMeanDataValues - methods
      56              : // ---------------------------------------------------------------------------
      57      8328777 : MSMeanData_Net::MSLaneMeanDataValues::MSLaneMeanDataValues(MSLane* const lane,
      58              :         const double length,
      59              :         const bool doAdd,
      60      8328777 :         const MSMeanData_Net* parent)
      61              :     : MSMeanData::MeanDataValues(lane, length, doAdd, parent),
      62      8328777 :       nVehDeparted(0), nVehArrived(0), nVehEntered(0), nVehLeft(0),
      63      8328777 :       nVehVaporized(0), nVehTeleported(0), waitSeconds(0), timeLoss(0),
      64      8328777 :       nVehLaneChangeFrom(0), nVehLaneChangeTo(0),
      65      8328777 :       frontSampleSeconds(0), frontTravelledDistance(0),
      66      8328777 :       vehLengthSum(0), occupationSum(0),
      67      8328777 :       minimalVehicleLength(INVALID_DOUBLE),
      68      8328777 :       myParent(parent) {}
      69              : 
      70              : 
      71     16654209 : MSMeanData_Net::MSLaneMeanDataValues::~MSLaneMeanDataValues() {
      72     16654209 : }
      73              : 
      74              : 
      75              : void
      76     16953750 : MSMeanData_Net::MSLaneMeanDataValues::reset(bool) {
      77     16953750 :     nVehDeparted = 0;
      78     16953750 :     nVehArrived = 0;
      79     16953750 :     nVehEntered = 0;
      80     16953750 :     nVehLeft = 0;
      81     16953750 :     nVehVaporized = 0;
      82     16953750 :     nVehTeleported = 0;
      83     16953750 :     nVehLaneChangeFrom = 0;
      84     16953750 :     nVehLaneChangeTo = 0;
      85     16953750 :     sampleSeconds = 0.;
      86     16953750 :     travelledDistance = 0;
      87     16953750 :     waitSeconds = 0;
      88     16953750 :     timeLoss = 0;
      89     16953750 :     frontSampleSeconds = 0;
      90     16953750 :     frontTravelledDistance = 0;
      91     16953750 :     vehLengthSum = 0;
      92     16953750 :     occupationSum = 0;
      93     16953750 :     minimalVehicleLength = INVALID_DOUBLE;
      94     16953750 :     resetTime = SIMSTEP;
      95     16953750 : }
      96              : 
      97              : 
      98              : void
      99      8661150 : MSMeanData_Net::MSLaneMeanDataValues::addTo(MSMeanData::MeanDataValues& val) const {
     100              :     MSLaneMeanDataValues& v = (MSLaneMeanDataValues&) val;
     101      8661150 :     v.nVehDeparted += nVehDeparted;
     102      8661150 :     v.nVehArrived += nVehArrived;
     103      8661150 :     v.nVehEntered += nVehEntered;
     104      8661150 :     v.nVehLeft += nVehLeft;
     105      8661150 :     v.nVehVaporized += nVehVaporized;
     106      8661150 :     v.nVehTeleported += nVehTeleported;
     107      8661150 :     v.nVehLaneChangeFrom += nVehLaneChangeFrom;
     108      8661150 :     v.nVehLaneChangeTo += nVehLaneChangeTo;
     109      8661150 :     v.sampleSeconds += sampleSeconds;
     110      8661150 :     v.travelledDistance += travelledDistance;
     111      8661150 :     v.waitSeconds += waitSeconds;
     112      8661150 :     v.timeLoss += timeLoss;
     113      8661150 :     v.frontSampleSeconds += frontSampleSeconds;
     114      8661150 :     v.frontTravelledDistance += frontTravelledDistance;
     115      8661150 :     v.vehLengthSum += vehLengthSum;
     116      8661150 :     v.occupationSum += occupationSum;
     117      8661150 :     if (v.minimalVehicleLength == INVALID_DOUBLE) {
     118      8569091 :         v.minimalVehicleLength = minimalVehicleLength;
     119              :     } else {
     120       178028 :         v.minimalVehicleLength = MIN2(minimalVehicleLength, v.minimalVehicleLength);
     121              :     }
     122      8661150 :     if (mySubData != nullptr) {
     123          280 :         mySubData->addTo(*val.getSubData());
     124              :     }
     125      8661150 : }
     126              : 
     127              : 
     128              : void
     129    416949670 : MSMeanData_Net::MSLaneMeanDataValues::notifyMoveInternal(
     130              :     const SUMOTrafficObject& veh, const double frontOnLane,
     131              :     const double timeOnLane, const double /* meanSpeedFrontOnLane */,
     132              :     const double meanSpeedVehicleOnLane,
     133              :     const double travelledDistanceFrontOnLane,
     134              :     const double travelledDistanceVehicleOnLane,
     135              :     const double meanLengthOnLane) {
     136              : #ifdef DEBUG_OCCUPANCY
     137              :     if (DEBUG_COND2) {
     138              :         std::cout << SIMTIME << "\n  MSMeanData_Net::MSLaneMeanDataValues::notifyMoveInternal()\n"
     139              :                   << "  veh '" << veh.getID() << "' on edge '" << veh.getEdge()->getID() << "'"
     140              :                   << ", timeOnLane=" << timeOnLane
     141              :                   << ", meanSpeedVehicleOnLane=" << meanSpeedVehicleOnLane
     142              :                   << ",\ntravelledDistanceFrontOnLane=" << travelledDistanceFrontOnLane
     143              :                   << ", travelledDistanceVehicleOnLane=" << travelledDistanceVehicleOnLane
     144              :                   << ", meanLengthOnLane=" << meanLengthOnLane
     145              :                   << std::endl;
     146              :     }
     147              : #endif
     148    416949670 :     if (myParent != nullptr && !myParent->vehicleApplies(veh)) {
     149              :         return;
     150              :     }
     151    416907350 :     sampleSeconds += timeOnLane;
     152    416907350 :     travelledDistance += travelledDistanceVehicleOnLane;
     153    416907350 :     vehLengthSum += veh.getVehicleType().getLength() * timeOnLane;
     154    416907350 :     if (MSGlobals::gUseMesoSim) {
     155              :         // For the mesosim case no information on whether the vehicle was occupying
     156              :         // the lane with its whole length is available. We assume the whole length
     157              :         // Therefore this increment is taken out with more information on the vehicle movement.
     158     10341512 :         occupationSum += veh.getVehicleType().getLength() * timeOnLane;
     159              :     } else {
     160              :         // for the microsim case more elaborate calculation of the average length on the lane,
     161              :         // is taken out in notifyMove(), refs #153
     162    406565838 :         occupationSum += meanLengthOnLane * TS;
     163              :     }
     164    416907350 :     if (!veh.isStopped()) {
     165    400859960 :         if (myParent != nullptr && (meanSpeedVehicleOnLane < myParent->myHaltSpeed
     166    340253907 :                                     || (myParent->myHaltSpeedRel > 0 && meanSpeedVehicleOnLane / veh.getCurrentEdge()->getSpeedLimit(veh.getVClass()) < myParent->myHaltSpeedRel))) {
     167     60549319 :             waitSeconds += timeOnLane;
     168    340310641 :         } else if (MSGlobals::gUseMesoSim) {
     169     10284991 :             waitSeconds += STEPS2TIME(veh.getWaitingTime());
     170              :         }
     171    400859960 :         const double vmax = veh.getLane() == nullptr ? veh.getEdge()->getVehicleMaxSpeed(&veh) : veh.getLane()->getVehicleMaxSpeed(&veh);
     172    400859960 :         if (vmax > 0) {
     173    799932825 :             timeLoss += timeOnLane * MAX2(0.0, vmax - meanSpeedVehicleOnLane) / vmax;
     174              :         }
     175              :     }
     176    416907350 :     frontSampleSeconds += frontOnLane;
     177    416907350 :     frontTravelledDistance += travelledDistanceFrontOnLane;
     178    416907350 :     if (minimalVehicleLength == INVALID_DOUBLE) {
     179       698743 :         minimalVehicleLength = veh.getVehicleType().getLengthWithGap();
     180              :     } else {
     181    830983047 :         minimalVehicleLength = MIN2(minimalVehicleLength, veh.getVehicleType().getLengthWithGap());
     182              :     }
     183              : #ifdef DEBUG_OCCUPANCY2
     184              :     // refs #3265
     185              :     std::cout << SIMTIME << "ID: " << getDescription() << " minVehicleLength=" << minimalVehicleLength << std::endl;
     186              : #endif
     187              : }
     188              : 
     189              : 
     190              : bool
     191     27502088 : MSMeanData_Net::MSLaneMeanDataValues::notifyLeave(SUMOTrafficObject& veh, double /*lastPos*/, MSMoveReminder::Notification reason, const MSLane* /* enteredLane */) {
     192     27502088 :     if ((myParent == nullptr || myParent->vehicleApplies(veh)) && (
     193     18380870 :                 getLane() == nullptr || !veh.isVehicle() || getLane() == static_cast<MSVehicle&>(veh).getLane())) {
     194              : #ifdef HAVE_FOX
     195     23087203 :         ScopedLocker<> lock(myNotificationMutex, MSGlobals::gNumSimThreads > 1);
     196              : #endif
     197     23087203 :         if (MSGlobals::gUseMesoSim) {
     198      9121059 :             removeFromVehicleUpdateValues(veh);
     199              :         }
     200     23087203 :         if (reason == MSMoveReminder::NOTIFICATION_ARRIVED) {
     201      3000818 :             ++nVehArrived;
     202     20086385 :         } else if (reason == MSMoveReminder::NOTIFICATION_LANE_CHANGE) {
     203       132119 :             ++nVehLaneChangeFrom;
     204     19954266 :         } else if (myParent == nullptr || reason != MSMoveReminder::NOTIFICATION_SEGMENT) {
     205     12080606 :             ++nVehLeft;
     206     12080606 :             if (reason == MSMoveReminder::NOTIFICATION_TELEPORT || reason == MSMoveReminder::NOTIFICATION_TELEPORT_ARRIVED) {
     207         6860 :                 ++nVehTeleported;
     208     12073746 :             } else if (reason >= MSMoveReminder::NOTIFICATION_VAPORIZED_CALIBRATOR) {
     209        70303 :                 ++nVehVaporized;
     210              :             }
     211              :         }
     212              :     }
     213     27502088 :     if (MSGlobals::gUseMesoSim || !veh.isVehicle()) {
     214              :         // only microsim vehicles keep the reminder until their back has fully left the edge/lane
     215      9134181 :         return false;
     216              :     }
     217     18367907 :     return reason == MSMoveReminder::NOTIFICATION_JUNCTION;
     218              : }
     219              : 
     220              : 
     221              : bool
     222     24112450 : MSMeanData_Net::MSLaneMeanDataValues::notifyEnter(SUMOTrafficObject& veh, MSMoveReminder::Notification reason, const MSLane* enteredLane) {
     223              : #ifdef DEBUG_NOTIFY_ENTER
     224              :     std::cout << "\n" << SIMTIME << " MSMeanData_Net::MSLaneMeanDataValues: veh '" << veh.getID() << "' enters lane '" << enteredLane->getID() << "'" << std::endl;
     225              : #else
     226              :     UNUSED_PARAMETER(enteredLane);
     227              : #endif
     228     24112450 :     if (myParent == nullptr || myParent->vehicleApplies(veh)) {
     229     23196380 :         if (getLane() == nullptr || !veh.isVehicle() || getLane() == static_cast<MSVehicle&>(veh).getLane()) {
     230              : #ifdef HAVE_FOX
     231     23187540 :             ScopedLocker<> lock(myNotificationMutex, MSGlobals::gNumSimThreads > 1);
     232              : #endif
     233     23187540 :             if (reason == MSMoveReminder::NOTIFICATION_DEPARTED) {
     234      3178211 :                 ++nVehDeparted;
     235     20009329 :             } else if (reason == MSMoveReminder::NOTIFICATION_LANE_CHANGE) {
     236       131779 :                 ++nVehLaneChangeTo;
     237     19877550 :             } else if (myParent == nullptr || reason != MSMoveReminder::NOTIFICATION_SEGMENT) {
     238     12034065 :                 ++nVehEntered;
     239              :             }
     240              :         }
     241     23196380 :         return true;
     242              :     }
     243              :     return false;
     244              : }
     245              : 
     246              : 
     247              : bool
     248     22488293 : MSMeanData_Net::MSLaneMeanDataValues::isEmpty() const {
     249     21827159 :     return sampleSeconds == 0 && nVehDeparted == 0 && nVehArrived == 0 && nVehEntered == 0
     250     44315004 :            && nVehLeft == 0 && nVehVaporized == 0 && nVehTeleported == 0 && nVehLaneChangeFrom == 0 && nVehLaneChangeTo == 0;
     251              : }
     252              : 
     253              : double
     254       965538 : MSMeanData_Net::MSLaneMeanDataValues::getOccupancy(SUMOTime period, int numLanes) const {
     255       965538 :     return occupationSum / STEPS2TIME(period) / myLaneLength / (double)numLanes * 100.;
     256              : }
     257              : 
     258              : void
     259       965416 : MSMeanData_Net::MSLaneMeanDataValues::write(OutputDevice& dev, const SumoXMLAttrMask& attributeMask, const SUMOTime period,
     260              :         const int numLanes, const double speedLimit, const double defaultTravelTime, const int numVehicles) const {
     261              : 
     262       965416 :     double density = frontSampleSeconds / STEPS2TIME(period) * 1000. / myLaneLength;
     263       965416 :     double overlapDensity = sampleSeconds / STEPS2TIME(period) * 1000. / myLaneLength;
     264       965416 :     if (MSGlobals::gLateralResolution < 0) {
     265              :         // avoid exceeding upper bound
     266       911371 :         density = MIN2(density, 1000 * (double)numLanes / MAX2(minimalVehicleLength, NUMERICAL_EPS));
     267       909763 :         overlapDensity = MIN2(overlapDensity, 1000 * (double)numLanes / MAX2(minimalVehicleLength, NUMERICAL_EPS));
     268              :     }
     269       965416 :     const double laneDensity = density / (double)numLanes;
     270       965416 :     const double occupancy = getOccupancy(period, numLanes);
     271              : #ifdef DEBUG_OCCUPANCY2
     272              :     // tests #3264
     273              :     if (occupancy > 100) {
     274              :         std::cout << SIMTIME << " Encountered bad occupancy: " << occupancy
     275              :                   << ", myLaneLength=" << myLaneLength << ", period=" << STEPS2TIME(period) << ", occupationSum=" << occupationSum
     276              :                   << std::endl;
     277              :     }
     278              :     // refs #3265
     279              :     std::cout << SIMTIME << "ID: " << getDescription() << " minVehicleLength=" << minimalVehicleLength
     280              :               << "\ndensity=" << density << "\n";
     281              : #endif
     282              : 
     283       965416 :     if (myParent == nullptr) {
     284        10065 :         const double speed = sampleSeconds == 0 ? 0. : travelledDistance / sampleSeconds;
     285        10065 :         const double frontSpeed = frontSampleSeconds == 0 ? 0. : frontTravelledDistance / frontSampleSeconds;
     286        10065 :         dev.writeOptionalAttr(SUMO_ATTR_DENSITY, density, attributeMask, sampleSeconds == 0);
     287        10065 :         dev.writeOptionalAttr(SUMO_ATTR_LANEDENSITY, laneDensity, attributeMask, sampleSeconds == 0);
     288        10065 :         dev.writeOptionalAttr(SUMO_ATTR_OCCUPANCY, occupancy, attributeMask, sampleSeconds == 0);
     289        10065 :         dev.writeOptionalAttr(SUMO_ATTR_WAITINGTIME, waitSeconds, attributeMask, sampleSeconds == 0);
     290        10065 :         dev.writeOptionalAttr(SUMO_ATTR_TIMELOSS, timeLoss, attributeMask, sampleSeconds == 0);
     291        10065 :         dev.writeOptionalAttr(SUMO_ATTR_SPEED, speed, attributeMask, sampleSeconds == 0);
     292        10065 :         dev.writeOptionalAttr(SUMO_ATTR_SPEEDREL, speedLimit == 0. || sampleSeconds == 0 ? 0. : travelledDistance / sampleSeconds / speedLimit,
     293        10065 :                               attributeMask, sampleSeconds == 0);
     294        10065 :         dev.writeOptionalAttr(SUMO_ATTR_DEPARTED, nVehDeparted, attributeMask);
     295        10065 :         dev.writeOptionalAttr(SUMO_ATTR_ARRIVED, nVehArrived, attributeMask);
     296        10065 :         dev.writeOptionalAttr(SUMO_ATTR_ENTERED, nVehEntered, attributeMask);
     297        10065 :         dev.writeOptionalAttr(SUMO_ATTR_LEFT, nVehLeft, attributeMask);
     298        10065 :         dev.writeOptionalAttr(SUMO_ATTR_VAPORIZED, nVehVaporized, attributeMask, nVehVaporized == 0);
     299        10065 :         dev.writeOptionalAttr(SUMO_ATTR_TELEPORTED, nVehTeleported, attributeMask, nVehTeleported == 0);
     300        10065 :         dev.writeOptionalAttr(SUMO_ATTR_FLOW, density * frontSpeed * 3.6, attributeMask, frontSampleSeconds == 0);
     301        10065 :         dev.writeOptionalAttr(SUMO_ATTR_DISTANCE, frontTravelledDistance, attributeMask);
     302        20130 :         dev.closeTag();
     303              :         return;
     304              :     }
     305       955351 :     const bool haveSamples = sampleSeconds > myParent->myMinSamples;
     306       955351 :     const bool haveFrontSamples = frontSampleSeconds > myParent->myMinSamples;
     307       955351 :     const bool haveSamplesOrDefault = haveSamples || defaultTravelTime >= 0.;
     308              :     bool haveTravelTime = haveSamplesOrDefault;
     309       955351 :     double traveltime = myParent->myMaxTravelTime;
     310       955351 :     if (haveSamples) {
     311       623115 :         if (numVehicles > 0) {
     312          244 :             traveltime = sampleSeconds / numVehicles;
     313              :         } else {
     314              :             traveltime = myParent->myMaxTravelTime;
     315       622871 :             if (frontTravelledDistance > NUMERICAL_EPS) {
     316       851201 :                 traveltime = MIN2(traveltime, myLaneLength * frontSampleSeconds / frontTravelledDistance);
     317       197129 :             } else if (defaultTravelTime >= 0.) {
     318            0 :                 traveltime = defaultTravelTime;
     319              :             } else {
     320              :                 haveTravelTime = false;
     321              :             }
     322              :         }
     323       332236 :     } else if (defaultTravelTime >= 0.) {
     324         2638 :         traveltime = defaultTravelTime;
     325              :     }
     326       955351 :     dev.writeOptionalAttr(SUMO_ATTR_TRAVELTIME, traveltime, attributeMask, !haveTravelTime);
     327       955351 :     double overlapTraveltime = myParent->myMaxTravelTime;
     328       955351 :     if (travelledDistance > 0.) {
     329              :         // one vehicle has to drive lane length + vehicle length before it has left the lane
     330              :         // thus we need to scale with an extended length, approximated by lane length + average vehicle length
     331       856735 :         overlapTraveltime = MIN2(overlapTraveltime, (myLaneLength + vehLengthSum / sampleSeconds) * sampleSeconds / travelledDistance);
     332              :     }
     333       955351 :     dev.writeOptionalAttr(SUMO_ATTR_OVERLAPTRAVELTIME, overlapTraveltime, attributeMask, !haveSamples || numVehicles > 0);
     334       955351 :     dev.writeOptionalAttr(SUMO_ATTR_DENSITY, density, attributeMask, !haveSamples || numVehicles > 0);
     335       955351 :     dev.writeOptionalAttr(SUMO_ATTR_OVERLAPDENSITY, overlapDensity, attributeMask, sampleSeconds == 0);
     336       955351 :     dev.writeOptionalAttr(SUMO_ATTR_LANEDENSITY, laneDensity, attributeMask, !haveSamples || numVehicles > 0);
     337       955351 :     dev.writeOptionalAttr(SUMO_ATTR_OCCUPANCY, occupancy, attributeMask, !haveSamples || numVehicles > 0);
     338       955351 :     dev.writeOptionalAttr(SUMO_ATTR_WAITINGTIME, waitSeconds, attributeMask, !haveSamples);
     339       955351 :     dev.writeOptionalAttr(SUMO_ATTR_TIMELOSS, timeLoss, attributeMask, !haveSamples);
     340       955351 :     double speed = 0.;
     341              :     double frontSpeed = 0.;
     342       955351 :     if (haveSamples) {
     343       623115 :         speed = travelledDistance / sampleSeconds;
     344       332236 :     } else if (defaultTravelTime > 0.) {
     345         2638 :         speed = myLaneLength / defaultTravelTime;
     346              :     }
     347       955351 :     if (haveFrontSamples) {
     348       582442 :         frontSpeed = frontTravelledDistance / frontSampleSeconds;
     349       372909 :     } else if (defaultTravelTime > 0.) {
     350         2638 :         frontSpeed = myLaneLength / defaultTravelTime;
     351              :     }
     352       955351 :     dev.writeOptionalAttr(SUMO_ATTR_SPEED, speed, attributeMask, !haveSamplesOrDefault);
     353       955351 :     dev.writeOptionalAttr(SUMO_ATTR_SPEEDREL, speedLimit == 0. ? 0. : speed / speedLimit, attributeMask, !haveSamplesOrDefault);
     354       955351 :     dev.writeOptionalAttr(SUMO_ATTR_DEPARTED, nVehDeparted, attributeMask);
     355       955351 :     dev.writeOptionalAttr(SUMO_ATTR_ARRIVED, nVehArrived, attributeMask);
     356       955351 :     dev.writeOptionalAttr(SUMO_ATTR_ENTERED, nVehEntered, attributeMask);
     357       955351 :     dev.writeOptionalAttr(SUMO_ATTR_LEFT, nVehLeft, attributeMask);
     358       955351 :     dev.writeOptionalAttr(SUMO_ATTR_LANECHANGEDFROM, nVehLaneChangeFrom, attributeMask);
     359       955351 :     dev.writeOptionalAttr(SUMO_ATTR_LANECHANGEDTO, nVehLaneChangeTo, attributeMask);
     360       955351 :     dev.writeOptionalAttr(SUMO_ATTR_VAPORIZED, nVehVaporized, attributeMask, nVehVaporized == 0);
     361       955351 :     dev.writeOptionalAttr(SUMO_ATTR_TELEPORTED, nVehTeleported, attributeMask, nVehTeleported == 0);
     362       955351 :     dev.writeOptionalAttr(SUMO_ATTR_FLOW, density * frontSpeed * 3.6, attributeMask, !haveSamples || numVehicles == 0);
     363       955351 :     dev.writeOptionalAttr(SUMO_ATTR_DISTANCE, frontTravelledDistance, attributeMask);
     364              : }
     365              : 
     366              : 
     367              : double
     368            0 : MSMeanData_Net::MSLaneMeanDataValues::getAttributeValue(SumoXMLAttr a,
     369              :         const SUMOTime period, const double numLanes, const double speedLimit) const {
     370              :     /// @todo: remove redundancy in derived values (density, laneDensity)
     371            0 :     switch (a) {
     372            0 :         case SUMO_ATTR_DENSITY:
     373            0 :             return MIN2(frontSampleSeconds / STEPS2TIME(period) * (double) 1000 / myLaneLength,
     374            0 :                         1000. * numLanes / MAX2(minimalVehicleLength, NUMERICAL_EPS));
     375            0 :         case SUMO_ATTR_LANEDENSITY: {
     376            0 :             const double density = MIN2(frontSampleSeconds / STEPS2TIME(period) * (double) 1000 / myLaneLength,
     377            0 :                                         1000. * numLanes / MAX2(minimalVehicleLength, NUMERICAL_EPS));
     378            0 :             return density / numLanes;
     379              :         }
     380            0 :         case SUMO_ATTR_OVERLAPDENSITY: {
     381            0 :             const double overlapDensity = MIN2(sampleSeconds / STEPS2TIME(period) * (double) 1000 / myLaneLength,
     382            0 :                                                1000. * numLanes / MAX2(minimalVehicleLength, NUMERICAL_EPS));
     383            0 :             return overlapDensity / numLanes;
     384              :         }
     385            0 :         case SUMO_ATTR_OCCUPANCY:
     386            0 :             return occupationSum / STEPS2TIME(period) / myLaneLength / numLanes * (double) 1000;
     387            0 :         case SUMO_ATTR_WAITINGTIME:
     388            0 :             return waitSeconds;
     389            0 :         case SUMO_ATTR_TIMELOSS:
     390            0 :             return timeLoss;
     391            0 :         case SUMO_ATTR_SPEED:
     392            0 :             return travelledDistance / sampleSeconds;
     393            0 :         case SUMO_ATTR_SPEEDREL:
     394            0 :             return speedLimit == 0. ? 0. : travelledDistance / sampleSeconds / speedLimit;
     395            0 :         case SUMO_ATTR_DEPARTED:
     396            0 :             return nVehDeparted;
     397            0 :         case SUMO_ATTR_ARRIVED:
     398            0 :             return nVehArrived;
     399            0 :         case SUMO_ATTR_ENTERED:
     400            0 :             return nVehEntered;
     401            0 :         case SUMO_ATTR_LEFT:
     402            0 :             return nVehLeft;
     403            0 :         case SUMO_ATTR_VAPORIZED:
     404            0 :             return nVehVaporized;
     405            0 :         case SUMO_ATTR_TELEPORTED:
     406            0 :             return nVehTeleported;
     407            0 :         case SUMO_ATTR_FLOW: {
     408            0 :             const double density = MIN2(frontSampleSeconds / STEPS2TIME(period) * (double) 1000 / myLaneLength,
     409            0 :                                         1000. * numLanes / MAX2(minimalVehicleLength, NUMERICAL_EPS));
     410            0 :             const double speed = frontTravelledDistance / frontSampleSeconds;
     411            0 :             return density * speed * 3.6;
     412              :         }
     413            0 :         case SUMO_ATTR_DISTANCE:
     414            0 :             return frontTravelledDistance;
     415              :         default:
     416              :             return 0;
     417              :     }
     418              : }
     419              : 
     420              : 
     421              : // ---------------------------------------------------------------------------
     422              : // MSMeanData_Net - methods
     423              : // ---------------------------------------------------------------------------
     424        22943 : MSMeanData_Net::MSMeanData_Net(const std::string& id,
     425              :                                const SUMOTime dumpBegin,
     426              :                                const SUMOTime dumpEnd, const bool useLanes,
     427              :                                const std::string& excludeEmpty,
     428              :                                const bool withInternal,
     429              :                                const bool trackVehicles,
     430              :                                const int detectPersons,
     431              :                                const double maxTravelTime,
     432              :                                const double minSamples,
     433              :                                const double haltSpeed,
     434              :                                const double haltSpeedRel,
     435              :                                const std::string& vTypes,
     436              :                                const std::string& writeAttributes,
     437              :                                const std::vector<MSEdge*>& edges,
     438        22943 :                                AggregateType aggregate) :
     439              :     MSMeanData(id, dumpBegin, dumpEnd, useLanes, excludeEmpty,
     440              :                withInternal, trackVehicles, detectPersons, maxTravelTime, minSamples, vTypes, writeAttributes, edges, aggregate),
     441        22943 :     myHaltSpeed(haltSpeed),
     442        22943 :     myHaltSpeedRel(haltSpeedRel)
     443        22943 : { }
     444              : 
     445              : 
     446        44867 : MSMeanData_Net::~MSMeanData_Net() {}
     447              : 
     448              : 
     449              : MSMeanData::MeanDataValues*
     450      8326499 : MSMeanData_Net::createValues(MSLane* const lane, const double length, const bool doAdd) const {
     451      8326499 :     return new MSLaneMeanDataValues(lane, length, doAdd, this);
     452              : }
     453              : 
     454              : 
     455              : std::vector<std::string>
     456            0 : MSMeanData_Net::getAttributeNames() const {
     457              :     std::vector<std::string> result;
     458            0 :     result.push_back(toString(SUMO_ATTR_DENSITY));
     459            0 :     result.push_back(toString(SUMO_ATTR_LANEDENSITY));
     460            0 :     result.push_back(toString(SUMO_ATTR_OVERLAPDENSITY));
     461            0 :     result.push_back(toString(SUMO_ATTR_OCCUPANCY));
     462            0 :     result.push_back(toString(SUMO_ATTR_WAITINGTIME));
     463            0 :     result.push_back(toString(SUMO_ATTR_TIMELOSS));
     464            0 :     result.push_back(toString(SUMO_ATTR_SPEED));
     465            0 :     result.push_back(toString(SUMO_ATTR_SPEEDREL));
     466            0 :     result.push_back(toString(SUMO_ATTR_DEPARTED));
     467            0 :     result.push_back(toString(SUMO_ATTR_ARRIVED));
     468            0 :     result.push_back(toString(SUMO_ATTR_ENTERED));
     469            0 :     result.push_back(toString(SUMO_ATTR_LEFT));
     470            0 :     result.push_back(toString(SUMO_ATTR_LANECHANGEDFROM));
     471            0 :     result.push_back(toString(SUMO_ATTR_LANECHANGEDTO));
     472            0 :     result.push_back(toString(SUMO_ATTR_VAPORIZED));
     473            0 :     result.push_back(toString(SUMO_ATTR_TELEPORTED));
     474            0 :     result.push_back(toString(SUMO_ATTR_FLOW));
     475            0 :     result.push_back(toString(SUMO_ATTR_DISTANCE));
     476            0 :     return result;
     477            0 : }
     478              : 
     479              : 
     480              : bool
     481           95 : MSMeanData_Net::supports(const SumoXMLAttrMask& attributeMask) {
     482              :     return
     483           95 :         attributeMask.test(SUMO_ATTR_DENSITY) ||
     484           95 :         attributeMask.test(SUMO_ATTR_LANEDENSITY) ||
     485           95 :         attributeMask.test(SUMO_ATTR_OVERLAPDENSITY) ||
     486           95 :         attributeMask.test(SUMO_ATTR_OCCUPANCY) ||
     487           95 :         attributeMask.test(SUMO_ATTR_WAITINGTIME) ||
     488           95 :         attributeMask.test(SUMO_ATTR_TIMELOSS) ||
     489           71 :         attributeMask.test(SUMO_ATTR_SPEED) ||
     490           71 :         attributeMask.test(SUMO_ATTR_SPEEDREL) ||
     491           71 :         attributeMask.test(SUMO_ATTR_DEPARTED) ||
     492           42 :         attributeMask.test(SUMO_ATTR_ARRIVED) ||
     493           42 :         attributeMask.test(SUMO_ATTR_ENTERED) ||
     494           24 :         attributeMask.test(SUMO_ATTR_LEFT) ||
     495           10 :         attributeMask.test(SUMO_ATTR_LANECHANGEDFROM) ||
     496           10 :         attributeMask.test(SUMO_ATTR_LANECHANGEDTO) ||
     497           10 :         attributeMask.test(SUMO_ATTR_VAPORIZED) ||
     498           10 :         attributeMask.test(SUMO_ATTR_TELEPORTED) ||
     499          105 :         attributeMask.test(SUMO_ATTR_FLOW) ||
     500           95 :         attributeMask.test(SUMO_ATTR_DISTANCE);
     501              : }
     502              : 
     503              : 
     504              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1