LCOV - code coverage report
Current view: top level - src/dfrouter - RODFDetector.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 285 419 68.0 %
Date: 2024-09-16 15:39:55 Functions: 28 44 63.6 %

          Line data    Source code
       1             : /****************************************************************************/
       2             : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3             : // Copyright (C) 2006-2024 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    RODFDetector.cpp
      15             : /// @author  Daniel Krajzewicz
      16             : /// @author  Eric Nicolay
      17             : /// @author  Jakob Erdmann
      18             : /// @author  Sascha Krieg
      19             : /// @author  Michael Behrisch
      20             : /// @author  Laura Bieker
      21             : /// @author  Melanie Knocke
      22             : /// @date    Thu, 16.03.2006
      23             : ///
      24             : // Class representing a detector within the DFROUTER
      25             : /****************************************************************************/
      26             : #include <config.h>
      27             : 
      28             : #include <cassert>
      29             : #include "RODFDetector.h"
      30             : #include <utils/common/FileHelpers.h>
      31             : #include <utils/common/MsgHandler.h>
      32             : #include <utils/common/UtilExceptions.h>
      33             : #include <utils/common/ToString.h>
      34             : #include <router/ROEdge.h>
      35             : #include "RODFEdge.h"
      36             : #include "RODFRouteDesc.h"
      37             : #include "RODFRouteCont.h"
      38             : #include "RODFDetectorFlow.h"
      39             : #include <utils/vehicle/SUMOVTypeParameter.h>
      40             : #include <utils/distribution/RandomDistributor.h>
      41             : #include <utils/common/StdDefs.h>
      42             : #include <utils/common/StringUtils.h>
      43             : #include <utils/geom/GeomHelper.h>
      44             : #include "RODFNet.h"
      45             : #include <utils/iodevices/OutputDevice.h>
      46             : #include <utils/common/StringUtils.h>
      47             : #include <utils/options/OptionsCont.h>
      48             : 
      49             : 
      50             : // ===========================================================================
      51             : // method definitions
      52             : // ===========================================================================
      53        1746 : RODFDetector::RODFDetector(const std::string& id, const std::string& laneID,
      54        1746 :                            double pos, const RODFDetectorType type)
      55        3492 :     : Named(id), myLaneID(laneID), myPosition(pos), myType(type), myRoutes(nullptr) {}
      56             : 
      57             : 
      58           0 : RODFDetector::RODFDetector(const std::string& id, const RODFDetector& f)
      59           0 :     : Named(id), myLaneID(f.myLaneID), myPosition(f.myPosition),
      60           0 :       myType(f.myType), myRoutes(nullptr) {
      61           0 :     if (f.myRoutes != nullptr) {
      62           0 :         myRoutes = new RODFRouteCont(*(f.myRoutes));
      63             :     }
      64           0 : }
      65             : 
      66             : 
      67        3492 : RODFDetector::~RODFDetector() {
      68        1746 :     delete myRoutes;
      69        3492 : }
      70             : 
      71             : 
      72             : void
      73        1504 : RODFDetector::setType(RODFDetectorType type) {
      74        1504 :     myType = type;
      75        1504 : }
      76             : 
      77             : 
      78             : double
      79           0 : RODFDetector::computeDistanceFactor(const RODFRouteDesc& rd) const {
      80           0 :     double distance = rd.edges2Pass[0]->getFromJunction()->getPosition().distanceTo(rd.edges2Pass.back()->getToJunction()->getPosition());
      81             :     double length = 0;
      82           0 :     for (ROEdgeVector::const_iterator i = rd.edges2Pass.begin(); i != rd.edges2Pass.end(); ++i) {
      83           0 :         length += (*i)->getLength();
      84             :     }
      85           0 :     return (distance / length);
      86             : }
      87             : 
      88             : 
      89             : void
      90        1053 : RODFDetector::computeSplitProbabilities(const RODFNet* net, const RODFDetectorCon& detectors,
      91             :                                         const RODFDetectorFlows& flows,
      92             :                                         SUMOTime startTime, SUMOTime endTime, SUMOTime stepOffset) {
      93        1053 :     if (myRoutes == nullptr) {
      94           0 :         return;
      95             :     }
      96             :     // compute edges to determine split probabilities
      97             :     const std::vector<RODFRouteDesc>& routes = myRoutes->get();
      98             :     std::vector<RODFEdge*> nextDetEdges;
      99             :     std::set<ROEdge*> preSplitEdges;
     100        3029 :     for (std::vector<RODFRouteDesc>::const_iterator i = routes.begin(); i != routes.end(); ++i) {
     101             :         const RODFRouteDesc& rd = *i;
     102             :         bool hadSplit = false;
     103        6023 :         for (ROEdgeVector::const_iterator j = rd.edges2Pass.begin(); j != rd.edges2Pass.end(); ++j) {
     104        5171 :             if (hadSplit && net->hasDetector(*j)) {
     105        1124 :                 if (find(nextDetEdges.begin(), nextDetEdges.end(), *j) == nextDetEdges.end()) {
     106         731 :                     nextDetEdges.push_back(static_cast<RODFEdge*>(*j));
     107             :                 }
     108        1124 :                 myRoute2Edge[rd.routename] = static_cast<RODFEdge*>(*j);
     109        1124 :                 break;
     110             :             }
     111        4047 :             if (!hadSplit) {
     112             :                 preSplitEdges.insert(*j);
     113             :             }
     114        4047 :             if ((*j)->getNumSuccessors() > 1) {
     115             :                 hadSplit = true;
     116             :             }
     117             :         }
     118             :     }
     119             :     std::map<ROEdge*, double> inFlows;
     120        2106 :     if (OptionsCont::getOptions().getBool("respect-concurrent-inflows")) {
     121          66 :         for (std::vector<RODFEdge*>::const_iterator i = nextDetEdges.begin(); i != nextDetEdges.end(); ++i) {
     122             :             std::set<ROEdge*> seen(preSplitEdges);
     123             :             ROEdgeVector pending;
     124          37 :             pending.push_back(*i);
     125          37 :             seen.insert(*i);
     126          80 :             while (!pending.empty()) {
     127          43 :                 ROEdge* e = pending.back();
     128             :                 pending.pop_back();
     129         118 :                 for (ROEdgeVector::const_iterator it = e->getPredecessors().begin(); it != e->getPredecessors().end(); it++) {
     130          75 :                     ROEdge* e2 = *it;
     131          75 :                     if (e2->getNumSuccessors() == 1 && seen.count(e2) == 0) {
     132           8 :                         if (net->hasDetector(e2)) {
     133           2 :                             inFlows[*i] += detectors.getAggFlowFor(e2, 0, 0, flows);
     134             :                         } else {
     135           6 :                             pending.push_back(e2);
     136             :                         }
     137             :                         seen.insert(e2);
     138             :                     }
     139             :                 }
     140             :             }
     141             :         }
     142             :     }
     143             :     // compute the probabilities to use a certain direction
     144             :     int index = 0;
     145      614713 :     for (SUMOTime time = startTime; time < endTime; time += stepOffset, ++index) {
     146     1227320 :         mySplitProbabilities.push_back(std::map<RODFEdge*, double>());
     147             :         double overallProb = 0;
     148             :         // retrieve the probabilities
     149     1228027 :         for (std::vector<RODFEdge*>::const_iterator i = nextDetEdges.begin(); i != nextDetEdges.end(); ++i) {
     150      614367 :             double flow = detectors.getAggFlowFor(*i, time, 60, flows) - inFlows[*i];
     151      614367 :             overallProb += flow;
     152      614367 :             mySplitProbabilities[index][*i] = flow;
     153             :         }
     154             :         // norm probabilities
     155      613660 :         if (overallProb > 0) {
     156      507517 :             for (std::vector<RODFEdge*>::const_iterator i = nextDetEdges.begin(); i != nextDetEdges.end(); ++i) {
     157      316287 :                 mySplitProbabilities[index][*i] = mySplitProbabilities[index][*i] / overallProb;
     158             :             }
     159             :         }
     160             :     }
     161             : }
     162             : 
     163             : 
     164             : void
     165         155 : RODFDetector::buildDestinationDistribution(const RODFDetectorCon& detectors,
     166             :         SUMOTime startTime, SUMOTime endTime, SUMOTime stepOffset,
     167             :         const RODFNet& net,
     168             :         std::map<SUMOTime, RandomDistributor<int>* >& into) const {
     169         155 :     if (myRoutes == nullptr) {
     170           0 :         if (myType != DISCARDED_DETECTOR && myType != BETWEEN_DETECTOR) {
     171           0 :             WRITE_ERRORF(TL("Missing routes for detector '%'."), myID);
     172             :         }
     173           0 :         return;
     174             :     }
     175             :     std::vector<RODFRouteDesc>& descs = myRoutes->get();
     176             :     // iterate through time (in output interval steps)
     177      103097 :     for (SUMOTime time = startTime; time < endTime; time += stepOffset) {
     178      102942 :         into[time] = new RandomDistributor<int>();
     179             :         std::map<ROEdge*, double> flowMap;
     180             :         // iterate through the routes
     181             :         int index = 0;
     182      541174 :         for (std::vector<RODFRouteDesc>::iterator ri = descs.begin(); ri != descs.end(); ++ri, index++) {
     183             :             double prob = 1.;
     184     1894068 :             for (ROEdgeVector::iterator j = (*ri).edges2Pass.begin(); j != (*ri).edges2Pass.end() && prob > 0;) {
     185     1455836 :                 if (!net.hasDetector(*j)) {
     186             :                     ++j;
     187      202700 :                     continue;
     188             :                 }
     189     1253136 :                 const RODFDetector& det = detectors.getAnyDetectorForEdge(static_cast<RODFEdge*>(*j));
     190             :                 const std::vector<std::map<RODFEdge*, double> >& probs = det.getSplitProbabilities();
     191     1253136 :                 if (probs.size() == 0) {
     192             :                     prob = 0;
     193             :                     ++j;
     194           0 :                     continue;
     195             :                 }
     196     1253136 :                 const std::map<RODFEdge*, double>& tprobs = probs[(int)((time - startTime) / stepOffset)];
     197     1253136 :                 RODFEdge* splitEdge = nullptr;
     198     1921181 :                 for (std::map<RODFEdge*, double>::const_iterator k = tprobs.begin(); k != tprobs.end(); ++k) {
     199     1406464 :                     if (find(j, (*ri).edges2Pass.end(), (*k).first) != (*ri).edges2Pass.end()) {
     200      738419 :                         prob *= (*k).second;
     201      738419 :                         splitEdge = (*k).first;
     202      738419 :                         break;
     203             :                     }
     204             :                 }
     205     1253136 :                 if (splitEdge != nullptr) {
     206      738419 :                     j = std::find(j, (*ri).edges2Pass.end(), splitEdge);
     207             :                 } else {
     208             :                     ++j;
     209             :                 }
     210             :             }
     211      438232 :             into[time]->add(index, prob);
     212      438232 :             (*ri).overallProb = prob;
     213             :         }
     214             :     }
     215             : }
     216             : 
     217             : 
     218             : const std::vector<RODFRouteDesc>&
     219           0 : RODFDetector::getRouteVector() const {
     220           0 :     return myRoutes->get();
     221             : }
     222             : 
     223             : 
     224             : void
     225           0 : RODFDetector::addPriorDetector(const RODFDetector* det) {
     226             :     myPriorDetectors.insert(det);
     227           0 : }
     228             : 
     229             : 
     230             : void
     231           0 : RODFDetector::addFollowingDetector(const RODFDetector* det) {
     232             :     myFollowingDetectors.insert(det);
     233           0 : }
     234             : 
     235             : 
     236             : const std::set<const RODFDetector*>&
     237           0 : RODFDetector::getPriorDetectors() const {
     238           0 :     return myPriorDetectors;
     239             : }
     240             : 
     241             : 
     242             : const std::set<const RODFDetector*>&
     243           0 : RODFDetector::getFollowerDetectors() const {
     244           0 :     return myFollowingDetectors;
     245             : }
     246             : 
     247             : 
     248             : 
     249             : void
     250        1600 : RODFDetector::addRoutes(RODFRouteCont* routes) {
     251        1600 :     delete myRoutes;
     252        1600 :     myRoutes = routes;
     253        1600 : }
     254             : 
     255             : 
     256             : void
     257           4 : RODFDetector::addRoute(RODFRouteDesc& nrd) {
     258           4 :     if (myRoutes == nullptr) {
     259           4 :         myRoutes = new RODFRouteCont();
     260             :     }
     261           4 :     myRoutes->addRouteDesc(nrd);
     262           4 : }
     263             : 
     264             : 
     265             : bool
     266           0 : RODFDetector::hasRoutes() const {
     267         422 :     return myRoutes != nullptr && myRoutes->get().size() != 0;
     268             : }
     269             : 
     270             : 
     271             : bool
     272         200 : RODFDetector::writeEmitterDefinition(const std::string& file,
     273             :                                      const std::map<SUMOTime, RandomDistributor<int>* >& dists,
     274             :                                      const RODFDetectorFlows& flows,
     275             :                                      SUMOTime startTime, SUMOTime endTime,
     276             :                                      SUMOTime stepOffset,
     277             :                                      bool includeUnusedRoutes,
     278             :                                      double scale,
     279             :                                      bool insertionsOnly,
     280             :                                      double defaultSpeed) const {
     281         200 :     OutputDevice& out = OutputDevice::getDevice(file);
     282         200 :     OptionsCont& oc = OptionsCont::getOptions();
     283         200 :     if (getType() != SOURCE_DETECTOR) {
     284           0 :         out.writeXMLHeader("additional", "additional_file.xsd");
     285             :     }
     286             :     // routes
     287         200 :     if (myRoutes != nullptr && myRoutes->get().size() != 0) {
     288             :         const std::vector<RODFRouteDesc>& routes = myRoutes->get();
     289         400 :         out.openTag(SUMO_TAG_ROUTE_DISTRIBUTION).writeAttr(SUMO_ATTR_ID, myID);
     290             :         bool isEmptyDist = true;
     291         954 :         for (std::vector<RODFRouteDesc>::const_iterator i = routes.begin(); i != routes.end(); ++i) {
     292         754 :             if ((*i).overallProb > 0) {
     293             :                 isEmptyDist = false;
     294             :             }
     295             :         }
     296         954 :         for (std::vector<RODFRouteDesc>::const_iterator i = routes.begin(); i != routes.end(); ++i) {
     297         754 :             if (isEmptyDist) {
     298         756 :                 out.openTag(SUMO_TAG_ROUTE).writeAttr(SUMO_ATTR_REFID, (*i).routename).writeAttr(SUMO_ATTR_PROB, 1.0).closeTag();
     299         565 :             } else if ((*i).overallProb > 0 || includeUnusedRoutes) {
     300        2256 :                 out.openTag(SUMO_TAG_ROUTE).writeAttr(SUMO_ATTR_REFID, (*i).routename).writeAttr(SUMO_ATTR_PROB, (*i).overallProb).closeTag();
     301             :             }
     302             :         }
     303         200 :         out.closeTag(); // routeDistribution
     304             :     } else {
     305           0 :         WRITE_ERRORF(TL("Detector '%' has no routes!?"), getID());
     306           0 :         return false;
     307             :     }
     308             :     // insertions
     309         200 :     int vehicleIndex = 0;
     310         200 :     if (insertionsOnly || flows.knows(myID)) {
     311             :         // get the flows for this detector
     312         169 :         const std::vector<FlowDef>& mflows = flows.getFlowDefs(myID);
     313             :         // go through the simulation seconds
     314             :         int index = 0;
     315      103125 :         for (SUMOTime time = startTime; time < endTime; time += stepOffset, index++) {
     316             :             // get own (departure flow)
     317             :             assert(index < (int)mflows.size());
     318      102956 :             const FlowDef& srcFD = mflows[index];  // !!! check stepOffset
     319             :             // get flows at end
     320      205898 :             RandomDistributor<int>* destDist = dists.find(time) != dists.end() ? dists.find(time)->second : 0;
     321             :             // go through the cars
     322      102956 :             const int numCars = (int)((srcFD.qPKW + srcFD.qLKW) * scale);
     323             : 
     324             : 
     325             :             std::vector<SUMOTime> departures;
     326      205912 :             if (oc.getBool("randomize-flows")) {
     327          11 :                 for (int i = 0; i < numCars; ++i) {
     328          10 :                     departures.push_back(time + RandHelper::rand(stepOffset));
     329             :                 }
     330           1 :                 std::sort(departures.begin(), departures.end());
     331             :             } else {
     332      114766 :                 for (int i = 0; i < numCars; ++i) {
     333       11811 :                     departures.push_back(time + (stepOffset * i / numCars));
     334             :                 }
     335             :             }
     336             : 
     337      114777 :             for (int car = 0; car < numCars; ++car) {
     338             :                 // get the vehicle parameter
     339       11821 :                 double v = -1;
     340             :                 std::string vtype;
     341             :                 int destIndex = -1;
     342       11821 :                 if (destDist != nullptr) {
     343       11371 :                     if (destDist->getOverallProb() > 0) {
     344       11371 :                         destIndex = destDist->get();
     345           0 :                     } else if (myRoutes->get().size() > 0) {
     346             :                         // equal probabilities. see writeEmitterDefinition()
     347           0 :                         destIndex = RandHelper::rand((int)myRoutes->get().size());
     348             :                     }
     349             :                 }
     350       11821 :                 if (srcFD.isLKW >= 1) {
     351          80 :                     srcFD.isLKW = srcFD.isLKW - 1.;
     352          80 :                     v = srcFD.vLKW;
     353             :                     vtype = "LKW";
     354             :                 } else {
     355       11741 :                     v = srcFD.vPKW;
     356             :                     vtype = "PKW";
     357             :                 }
     358             :                 // compute insertion speed
     359       11821 :                 if (v <= 0 || v > 250) {
     360        1208 :                     v = defaultSpeed;
     361             :                 } else {
     362       10613 :                     v /= 3.6;
     363             :                 }
     364             :                 // compute the departure time
     365       11821 :                 const SUMOTime ctime = departures[car];
     366             : 
     367             :                 // write
     368       11821 :                 out.openTag(SUMO_TAG_VEHICLE);
     369       23642 :                 out.writeAttr(SUMO_ATTR_ID, myID + "." + toString(vehicleIndex));
     370       23642 :                 if (oc.getBool("vtype")) {
     371             :                     out.writeAttr(SUMO_ATTR_TYPE, vtype);
     372             :                 }
     373       11821 :                 out.writeAttr(SUMO_ATTR_DEPART, time2string(ctime));
     374       23642 :                 if (oc.isSet("departlane")) {
     375          60 :                     out.writeNonEmptyAttr(SUMO_ATTR_DEPARTLANE, oc.getString("departlane"));
     376             :                 } else {
     377       23582 :                     out.writeAttr(SUMO_ATTR_DEPARTLANE, SUMOXMLDefinitions::getIndexFromLane(myLaneID));
     378             :                 }
     379       23642 :                 if (oc.isSet("departpos")) {
     380         150 :                     std::string posDesc = oc.getString("departpos");
     381         300 :                     if (posDesc.substr(0, 8) == "detector") {
     382          90 :                         double position = myPosition;
     383          90 :                         if (posDesc.length() > 8) {
     384          60 :                             if (posDesc[8] == '+') {
     385          30 :                                 position += StringUtils::toDouble(posDesc.substr(9));
     386          30 :                             } else if (posDesc[8] == '-') {
     387          30 :                                 position -= StringUtils::toDouble(posDesc.substr(9));
     388             :                             } else {
     389           0 :                                 throw NumberFormatException("");
     390             :                             }
     391             :                         }
     392             :                         out.writeAttr(SUMO_ATTR_DEPARTPOS, position);
     393             :                     } else {
     394          60 :                         out.writeNonEmptyAttr(SUMO_ATTR_DEPARTPOS, posDesc);
     395             :                     }
     396             :                 } else {
     397       11671 :                     out.writeAttr(SUMO_ATTR_DEPARTPOS, myPosition);
     398             :                 }
     399       23642 :                 if (oc.isSet("departspeed")) {
     400          60 :                     out.writeNonEmptyAttr(SUMO_ATTR_DEPARTSPEED, oc.getString("departspeed"));
     401             :                 } else {
     402             :                     out.writeAttr(SUMO_ATTR_DEPARTSPEED, v);
     403             :                 }
     404       23642 :                 if (oc.isSet("arrivallane")) {
     405          60 :                     out.writeNonEmptyAttr(SUMO_ATTR_ARRIVALLANE, oc.getString("arrivallane"));
     406             :                 }
     407       23642 :                 if (oc.isSet("arrivalpos")) {
     408          60 :                     out.writeNonEmptyAttr(SUMO_ATTR_ARRIVALPOS, oc.getString("arrivalpos"));
     409             :                 }
     410       23642 :                 if (oc.isSet("arrivalspeed")) {
     411          60 :                     out.writeNonEmptyAttr(SUMO_ATTR_ARRIVALSPEED, oc.getString("arrivalspeed"));
     412             :                 }
     413       11821 :                 if (destIndex >= 0) {
     414       11371 :                     out.writeAttr(SUMO_ATTR_ROUTE, myRoutes->get()[destIndex].routename);
     415             :                 } else {
     416             :                     out.writeAttr(SUMO_ATTR_ROUTE, myID);
     417             :                 }
     418       11821 :                 out.closeTag();
     419       11821 :                 srcFD.isLKW += srcFD.fLKW;
     420       11821 :                 vehicleIndex++;
     421             :             }
     422             :         }
     423             :     }
     424         200 :     if (getType() != SOURCE_DETECTOR) {
     425           0 :         out.close();
     426             :     }
     427             :     return true;
     428             : }
     429             : 
     430             : 
     431             : bool
     432         215 : RODFDetector::writeRoutes(std::vector<std::string>& saved,
     433             :                           OutputDevice& out) {
     434         215 :     if (myRoutes != nullptr) {
     435         430 :         return myRoutes->save(saved, "", out);
     436             :     }
     437             :     return false;
     438             : }
     439             : 
     440             : 
     441             : void
     442           0 : RODFDetector::writeSingleSpeedTrigger(const std::string& file,
     443             :                                       const RODFDetectorFlows& flows,
     444             :                                       SUMOTime startTime, SUMOTime endTime,
     445             :                                       SUMOTime stepOffset, double defaultSpeed) {
     446           0 :     OutputDevice& out = OutputDevice::getDevice(file);
     447           0 :     out.writeXMLHeader("additional", "additional_file.xsd");
     448           0 :     const std::vector<FlowDef>& mflows = flows.getFlowDefs(myID);
     449             :     int index = 0;
     450           0 :     for (SUMOTime t = startTime; t < endTime; t += stepOffset, index++) {
     451             :         assert(index < (int)mflows.size());
     452           0 :         const FlowDef& srcFD = mflows[index];
     453           0 :         double speed = MAX2(srcFD.vLKW, srcFD.vPKW);
     454           0 :         if (speed <= 0 || speed > 250) {
     455           0 :             speed = defaultSpeed;
     456             :         } else {
     457           0 :             speed = (double)(speed / 3.6);
     458             :         }
     459           0 :         out.openTag(SUMO_TAG_STEP).writeAttr(SUMO_ATTR_TIME, time2string(t)).writeAttr(SUMO_ATTR_SPEED, speed).closeTag();
     460             :     }
     461           0 :     out.close();
     462           0 : }
     463             : 
     464             : 
     465             : 
     466             : 
     467             : 
     468             : 
     469             : 
     470             : 
     471             : 
     472             : 
     473         244 : RODFDetectorCon::RODFDetectorCon() {}
     474             : 
     475             : 
     476         244 : RODFDetectorCon::~RODFDetectorCon() {
     477        1983 :     for (std::vector<RODFDetector*>::iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
     478        1739 :         delete *i;
     479             :     }
     480         244 : }
     481             : 
     482             : 
     483             : bool
     484        1746 : RODFDetectorCon::addDetector(RODFDetector* dfd) {
     485        1746 :     if (myDetectorMap.find(dfd->getID()) != myDetectorMap.end()) {
     486             :         return false;
     487             :     }
     488        1746 :     myDetectorMap[dfd->getID()] = dfd;
     489        1746 :     myDetectors.push_back(dfd);
     490        3492 :     const std::string edgeid = SUMOXMLDefinitions::getEdgeIDFromLane(dfd->getLaneID());
     491        1746 :     if (myDetectorEdgeMap.find(edgeid) == myDetectorEdgeMap.end()) {
     492        2878 :         myDetectorEdgeMap[edgeid] = std::vector<RODFDetector*>();
     493             :     }
     494        1746 :     myDetectorEdgeMap[edgeid].push_back(dfd);
     495             :     return true; // !!!
     496             : }
     497             : 
     498             : 
     499             : bool
     500         425 : RODFDetectorCon::detectorsHaveCompleteTypes() const {
     501        2170 :     for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
     502        1953 :         if ((*i)->getType() == TYPE_NOT_DEFINED) {
     503             :             return false;
     504             :         }
     505             :     }
     506             :     return true;
     507             : }
     508             : 
     509             : 
     510             : bool
     511         634 : RODFDetectorCon::detectorsHaveRoutes() const {
     512        2234 :     for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
     513        2022 :         if ((*i)->hasRoutes()) {
     514             :             return true;
     515             :         }
     516             :     }
     517             :     return false;
     518             : }
     519             : 
     520             : 
     521             : const std::vector< RODFDetector*>&
     522        1725 : RODFDetectorCon::getDetectors() const {
     523        1725 :     return myDetectors;
     524             : }
     525             : 
     526             : 
     527             : void
     528          18 : RODFDetectorCon::save(const std::string& file) const {
     529          18 :     OutputDevice& out = OutputDevice::getDevice(file);
     530          51 :     out.writeXMLHeader("detectors", "detectors_file.xsd");
     531         199 :     for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
     532         728 :         out.openTag(SUMO_TAG_DETECTOR_DEFINITION).writeAttr(SUMO_ATTR_ID, StringUtils::escapeXML((*i)->getID())).writeAttr(SUMO_ATTR_LANE, (*i)->getLaneID()).writeAttr(SUMO_ATTR_POSITION, (*i)->getPos());
     533         182 :         switch ((*i)->getType()) {
     534             :             case BETWEEN_DETECTOR:
     535             :                 out.writeAttr(SUMO_ATTR_TYPE, "between");
     536             :                 break;
     537             :             case SOURCE_DETECTOR:
     538             :                 out.writeAttr(SUMO_ATTR_TYPE, "source");
     539             :                 break;
     540             :             case SINK_DETECTOR:
     541             :                 out.writeAttr(SUMO_ATTR_TYPE, "sink");
     542             :                 break;
     543             :             case DISCARDED_DETECTOR:
     544             :                 out.writeAttr(SUMO_ATTR_TYPE, "discarded");
     545             :                 break;
     546           0 :             default:
     547           0 :                 throw 1;
     548             :         }
     549         364 :         out.closeTag();
     550             :     }
     551          17 :     out.close();
     552          17 : }
     553             : 
     554             : 
     555             : void
     556           4 : RODFDetectorCon::saveAsPOIs(const std::string& file) const {
     557           4 :     OutputDevice& out = OutputDevice::getDevice(file);
     558           9 :     out.writeXMLHeader("additional", "additional_file.xsd");
     559          98 :     for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
     560          95 :         out.openTag(SUMO_TAG_POI).writeAttr(SUMO_ATTR_ID, StringUtils::escapeXML((*i)->getID()));
     561          95 :         switch ((*i)->getType()) {
     562             :             case BETWEEN_DETECTOR:
     563             :                 out.writeAttr(SUMO_ATTR_TYPE, "between_detector_position").writeAttr(SUMO_ATTR_COLOR, RGBColor::BLUE);
     564             :                 break;
     565             :             case SOURCE_DETECTOR:
     566             :                 out.writeAttr(SUMO_ATTR_TYPE, "source_detector_position").writeAttr(SUMO_ATTR_COLOR, RGBColor::GREEN);
     567             :                 break;
     568             :             case SINK_DETECTOR:
     569             :                 out.writeAttr(SUMO_ATTR_TYPE, "sink_detector_position").writeAttr(SUMO_ATTR_COLOR, RGBColor::RED);
     570             :                 break;
     571             :             case DISCARDED_DETECTOR:
     572           2 :                 out.writeAttr(SUMO_ATTR_TYPE, "discarded_detector_position").writeAttr(SUMO_ATTR_COLOR, RGBColor(51, 51, 51, 255));
     573           2 :                 break;
     574           0 :             default:
     575           0 :                 throw 1;
     576             :         }
     577         380 :         out.writeAttr(SUMO_ATTR_LANE, (*i)->getLaneID()).writeAttr(SUMO_ATTR_POSITION, (*i)->getPos()).closeTag();
     578             :     }
     579           3 :     out.close();
     580           3 : }
     581             : 
     582             : 
     583             : void
     584         109 : RODFDetectorCon::saveRoutes(const std::string& file) const {
     585         109 :     OutputDevice& out = OutputDevice::getDevice(file);
     586         216 :     out.writeXMLHeader("routes", "routes_file.xsd");
     587             :     std::vector<std::string> saved;
     588             :     // write for source detectors
     589             :     bool lastWasSaved = true;
     590        1231 :     for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
     591        1123 :         if ((*i)->getType() != SOURCE_DETECTOR) {
     592             :             // do not build routes for other than sources
     593         908 :             continue;
     594             :         }
     595         215 :         if (lastWasSaved) {
     596         178 :             out << "\n";
     597             :         }
     598         215 :         lastWasSaved = (*i)->writeRoutes(saved, out);
     599             :     }
     600         108 :     out << "\n";
     601         108 :     out.close();
     602         108 : }
     603             : 
     604             : 
     605             : const RODFDetector&
     606        8443 : RODFDetectorCon::getDetector(const std::string& id) const {
     607        8443 :     return *(myDetectorMap.find(id)->second);
     608             : }
     609             : 
     610             : 
     611             : RODFDetector&
     612           0 : RODFDetectorCon::getModifiableDetector(const std::string& id) const {
     613           0 :     return *(myDetectorMap.find(id)->second);
     614             : }
     615             : 
     616             : 
     617             : bool
     618        9568 : RODFDetectorCon::knows(const std::string& id) const {
     619        9568 :     return myDetectorMap.find(id) != myDetectorMap.end();
     620             : }
     621             : 
     622             : 
     623             : void
     624         104 : RODFDetectorCon::writeEmitters(const std::string& file,
     625             :                                const RODFDetectorFlows& flows,
     626             :                                SUMOTime startTime, SUMOTime endTime,
     627             :                                SUMOTime stepOffset, const RODFNet& net,
     628             :                                bool writeCalibrators,
     629             :                                bool includeUnusedRoutes,
     630             :                                double scale,
     631             :                                bool insertionsOnly) {
     632             :     // compute turn probabilities at detector
     633        1157 :     for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
     634        1053 :         (*i)->computeSplitProbabilities(&net, *this, flows, startTime, endTime, stepOffset);
     635             :     }
     636             :     //
     637         104 :     OutputDevice& out = OutputDevice::getDevice(file);
     638         306 :     out.writeXMLHeader("additional", "additional_file.xsd");
     639             :     // write vType(s)
     640         204 :     const bool separateVTypeOutput = OptionsCont::getOptions().getString("vtype-output") != "";
     641         104 :     OutputDevice& vTypeOut = separateVTypeOutput ? OutputDevice::getDevice(OptionsCont::getOptions().getString("vtype-output")) : out;
     642         102 :     if (separateVTypeOutput) {
     643           6 :         vTypeOut.writeXMLHeader("additional", "additional_file.xsd");
     644             :     }
     645         102 :     const bool forceDev = !OptionsCont::getOptions().isDefault("speeddev");
     646         102 :     const double speedDev = OptionsCont::getOptions().getFloat("speeddev");
     647         204 :     if (OptionsCont::getOptions().getBool("vtype")) {
     648             :         // write separate types
     649           4 :         SUMOVTypeParameter pkwType = SUMOVTypeParameter("PKW", SVC_PASSENGER);
     650           4 :         setSpeedFactorAndDev(pkwType, net.getMaxSpeedFactorPKW(), net.getAvgSpeedFactorPKW(), speedDev, forceDev);
     651           4 :         pkwType.parametersSet |= VTYPEPARS_VEHICLECLASS_SET;
     652           4 :         pkwType.write(vTypeOut);
     653           8 :         SUMOVTypeParameter lkwType = SUMOVTypeParameter("LKW", SVC_TRUCK);
     654           4 :         setSpeedFactorAndDev(lkwType, net.getMaxSpeedFactorLKW(), net.getAvgSpeedFactorLKW(), speedDev, forceDev);
     655           4 :         lkwType.parametersSet |= VTYPEPARS_VEHICLECLASS_SET;
     656           4 :         lkwType.write(vTypeOut);
     657           4 :     } else {
     658             :         // patch default type
     659          98 :         SUMOVTypeParameter type = SUMOVTypeParameter(DEFAULT_VTYPE_ID, SVC_PASSENGER);
     660         101 :         setSpeedFactorAndDev(type, MAX2(net.getMaxSpeedFactorPKW(), net.getMaxSpeedFactorLKW()), net.getAvgSpeedFactorPKW(), speedDev, forceDev);
     661          98 :         if (type.parametersSet != 0) {
     662          95 :             type.write(vTypeOut);
     663             :         }
     664          98 :     }
     665             : 
     666             : 
     667        1137 :     for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
     668        1035 :         RODFDetector* det = *i;
     669             :         // get file name for values (emitter/calibrator definition)
     670        1035 :         std::string escapedID = StringUtils::escapeXML(det->getID());
     671             :         std::string defFileName;
     672        1035 :         if (det->getType() == SOURCE_DETECTOR) {
     673             :             defFileName = file;
     674         835 :         } else if (writeCalibrators && det->getType() == BETWEEN_DETECTOR) {
     675           0 :             defFileName = FileHelpers::getFilePath(file) + "calibrator_" + escapedID + ".def.xml";
     676             :         } else {
     677        1670 :             defFileName = FileHelpers::getFilePath(file) + "other_" + escapedID + ".def.xml";
     678         835 :             continue;
     679             :         }
     680             :         // try to write the definition
     681         400 :         double defaultSpeed = net.getEdge(det->getEdgeID())->getSpeedLimit();
     682             :         //  ... compute routes' distribution over time
     683             :         std::map<SUMOTime, RandomDistributor<int>* > dists;
     684         200 :         if (!insertionsOnly && flows.knows(det->getID())) {
     685         155 :             det->buildDestinationDistribution(*this, startTime, endTime, stepOffset, net, dists);
     686             :         }
     687             :         //  ... write the definition
     688         200 :         if (!det->writeEmitterDefinition(defFileName, dists, flows, startTime, endTime, stepOffset, includeUnusedRoutes, scale, insertionsOnly, defaultSpeed)) {
     689             :             // skip if something failed... (!!!)
     690             :             continue;
     691             :         }
     692             :         //  ... clear temporary values
     693         200 :         clearDists(dists);
     694             :         // write the declaration into the file
     695         200 :         if (writeCalibrators && det->getType() == BETWEEN_DETECTOR) {
     696           0 :             out.openTag(SUMO_TAG_CALIBRATOR).writeAttr(SUMO_ATTR_ID, "calibrator_" + escapedID).writeAttr(SUMO_ATTR_POSITION, det->getPos());
     697           0 :             out.writeAttr(SUMO_ATTR_LANE, det->getLaneID()).writeAttr(SUMO_ATTR_FRIENDLY_POS, true).writeAttr(SUMO_ATTR_FILE, defFileName).closeTag();
     698             :         }
     699             :     }
     700         102 :     out.close();
     701         102 :     if (separateVTypeOutput) {
     702           2 :         vTypeOut.close();
     703             :     }
     704         102 : }
     705             : 
     706             : void
     707         106 : RODFDetectorCon::setSpeedFactorAndDev(SUMOVTypeParameter& type, double maxFactor, double avgFactor, double dev, bool forceDev) {
     708         106 :     if (avgFactor > 1) {
     709             :         // systematically low speeds can easily be caused by traffic
     710             :         // conditions. Whereas elevated speeds probably reflect speeding
     711          93 :         type.speedFactor.getParameter()[0] = avgFactor;
     712          93 :         type.parametersSet |= VTYPEPARS_SPEEDFACTOR_SET;
     713             :     }
     714         106 :     if (forceDev || (maxFactor > 1 && maxFactor > type.speedFactor.getParameter()[0] + NUMERICAL_EPS)) {
     715             :         // setting a non-zero speed deviation causes the simulation to recompute
     716             :         // individual speedFactors to match departSpeed (MSEdge::insertVehicle())
     717           8 :         type.speedFactor.getParameter()[1] = dev;
     718           8 :         type.parametersSet |= VTYPEPARS_SPEEDFACTOR_SET;
     719             :     } else {
     720          98 :         type.speedFactor.getParameter()[1] = -1; // do not write speedDev, only simple speedFactor
     721             :     }
     722         106 : }
     723             : 
     724             : 
     725             : void
     726           0 : RODFDetectorCon::writeEmitterPOIs(const std::string& file,
     727             :                                   const RODFDetectorFlows& flows) {
     728           0 :     OutputDevice& out = OutputDevice::getDevice(file);
     729           0 :     out.writeXMLHeader("additional", "additional_file.xsd");
     730           0 :     for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
     731           0 :         RODFDetector* det = *i;
     732           0 :         double flow = flows.getFlowSumSecure(det->getID());
     733           0 :         const unsigned char col = static_cast<unsigned char>(128 * flow / flows.getMaxDetectorFlow() + 128);
     734           0 :         out.openTag(SUMO_TAG_POI).writeAttr(SUMO_ATTR_ID, StringUtils::escapeXML((*i)->getID()) + ":" + toString(flow));
     735           0 :         switch ((*i)->getType()) {
     736             :             case BETWEEN_DETECTOR:
     737           0 :                 out.writeAttr(SUMO_ATTR_TYPE, "between_detector_position").writeAttr(SUMO_ATTR_COLOR, RGBColor(0, 0, col, 255));
     738           0 :                 break;
     739             :             case SOURCE_DETECTOR:
     740           0 :                 out.writeAttr(SUMO_ATTR_TYPE, "source_detector_position").writeAttr(SUMO_ATTR_COLOR, RGBColor(0, col, 0, 255));
     741           0 :                 break;
     742             :             case SINK_DETECTOR:
     743           0 :                 out.writeAttr(SUMO_ATTR_TYPE, "sink_detector_position").writeAttr(SUMO_ATTR_COLOR, RGBColor(col, 0, 0, 255));
     744           0 :                 break;
     745             :             case DISCARDED_DETECTOR:
     746           0 :                 out.writeAttr(SUMO_ATTR_TYPE, "discarded_detector_position").writeAttr(SUMO_ATTR_COLOR, RGBColor(51, 51, 51, 255));
     747           0 :                 break;
     748           0 :             default:
     749           0 :                 throw 1;
     750             :         }
     751           0 :         out.writeAttr(SUMO_ATTR_LANE, (*i)->getLaneID()).writeAttr(SUMO_ATTR_POSITION, (*i)->getPos()).closeTag();
     752             :     }
     753           0 :     out.close();
     754           0 : }
     755             : 
     756             : 
     757             : int
     758      614369 : RODFDetectorCon::getAggFlowFor(const ROEdge* edge, SUMOTime time, SUMOTime period,
     759             :                                const RODFDetectorFlows&) const {
     760             :     UNUSED_PARAMETER(period);
     761             :     UNUSED_PARAMETER(time);
     762      614369 :     if (edge == nullptr) {
     763             :         return 0;
     764             :     }
     765             : //    double stepOffset = 60; // !!!
     766             : //    double startTime = 0; // !!!
     767             : //    cout << edge->getID() << endl;
     768             :     assert(myDetectorEdgeMap.find(edge->getID()) != myDetectorEdgeMap.end());
     769      614369 :     const std::vector<FlowDef>& flows = static_cast<const RODFEdge*>(edge)->getFlows();
     770             :     double agg = 0;
     771   439320800 :     for (std::vector<FlowDef>::const_iterator i = flows.begin(); i != flows.end(); ++i) {
     772             :         const FlowDef& srcFD = *i;
     773   438706431 :         if (srcFD.qLKW >= 0) {
     774   438706431 :             agg += srcFD.qLKW;
     775             :         }
     776   438706431 :         if (srcFD.qPKW >= 0) {
     777   438706431 :             agg += srcFD.qPKW;
     778             :         }
     779             :     }
     780      614369 :     return (int) agg;
     781             :     /* !!! make this time variable
     782             :     if (flows.size()!=0) {
     783             :         double agg = 0;
     784             :         int beginIndex = (int)((time/stepOffset) - startTime);  // !!! falsch!!!
     785             :         for (SUMOTime t=0; t<period&&beginIndex<flows.size(); t+=(SUMOTime) stepOffset) {
     786             :             const FlowDef &srcFD = flows[beginIndex++];
     787             :             if (srcFD.qLKW>=0) {
     788             :                 agg += srcFD.qLKW;
     789             :             }
     790             :             if (srcFD.qPKW>=0) {
     791             :                 agg += srcFD.qPKW;
     792             :             }
     793             :         }
     794             :         return (int) agg;
     795             :     }
     796             :     */
     797             : //    return -1;
     798             : }
     799             : 
     800             : 
     801             : void
     802           0 : RODFDetectorCon::writeSpeedTrigger(const RODFNet* const net,
     803             :                                    const std::string& file,
     804             :                                    const RODFDetectorFlows& flows,
     805             :                                    SUMOTime startTime, SUMOTime endTime,
     806             :                                    SUMOTime stepOffset) {
     807           0 :     OutputDevice& out = OutputDevice::getDevice(file);
     808           0 :     out.writeXMLHeader("additional", "additional_file.xsd");
     809           0 :     for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
     810           0 :         RODFDetector* det = *i;
     811             :         // write the declaration into the file
     812           0 :         if (det->getType() == SINK_DETECTOR && flows.knows(det->getID())) {
     813           0 :             std::string filename = FileHelpers::getFilePath(file) + "vss_" + det->getID() + ".def.xml";
     814           0 :             out.openTag(SUMO_TAG_VSS).writeAttr(SUMO_ATTR_ID, StringUtils::escapeXML(det->getID())).writeAttr(SUMO_ATTR_LANES, det->getLaneID()).writeAttr(SUMO_ATTR_FILE, filename).closeTag();
     815           0 :             double defaultSpeed = net != nullptr ? net->getEdge(det->getEdgeID())->getSpeedLimit() : (double) 200.;
     816           0 :             det->writeSingleSpeedTrigger(filename, flows, startTime, endTime, stepOffset, defaultSpeed);
     817             :         }
     818             :     }
     819           0 :     out.close();
     820           0 : }
     821             : 
     822             : 
     823             : void
     824           0 : RODFDetectorCon::writeEndRerouterDetectors(const std::string& file) {
     825           0 :     OutputDevice& out = OutputDevice::getDevice(file);
     826           0 :     out.writeXMLHeader("additional", "additional_file.xsd");
     827           0 :     for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
     828           0 :         RODFDetector* det = *i;
     829             :         // write the declaration into the file
     830           0 :         if (det->getType() == SINK_DETECTOR) {
     831           0 :             out.openTag(SUMO_TAG_REROUTER).writeAttr(SUMO_ATTR_ID, "endrerouter_" + StringUtils::escapeXML(det->getID())).writeAttr(SUMO_ATTR_EDGES, det->getLaneID());
     832           0 :             out.writeAttr(SUMO_ATTR_POSITION, 0.).writeAttr(SUMO_ATTR_FILE, "endrerouter_" + det->getID() + ".def.xml").closeTag();
     833             :         }
     834             :     }
     835           0 :     out.close();
     836           0 : }
     837             : 
     838             : 
     839             : void
     840           0 : RODFDetectorCon::writeValidationDetectors(const std::string& file,
     841             :         bool includeSources,
     842             :         bool singleFile, bool friendly) {
     843           0 :     OutputDevice& out = OutputDevice::getDevice(file);
     844           0 :     out.writeXMLHeader("additional", "additional_file.xsd");
     845           0 :     for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
     846           0 :         RODFDetector* det = *i;
     847             :         // write the declaration into the file
     848           0 :         if (det->getType() != SOURCE_DETECTOR || includeSources) {
     849           0 :             double pos = det->getPos();
     850           0 :             if (det->getType() == SOURCE_DETECTOR) {
     851           0 :                 pos += 1;
     852             :             }
     853           0 :             out.openTag(SUMO_TAG_E1DETECTOR).writeAttr(SUMO_ATTR_ID, "validation_" + StringUtils::escapeXML(det->getID())).writeAttr(SUMO_ATTR_LANE, det->getLaneID());
     854           0 :             out.writeAttr(SUMO_ATTR_POSITION, pos).writeAttr(SUMO_ATTR_PERIOD, 60);
     855           0 :             if (friendly) {
     856           0 :                 out.writeAttr(SUMO_ATTR_FRIENDLY_POS, true);
     857             :             }
     858           0 :             if (!singleFile) {
     859           0 :                 out.writeAttr(SUMO_ATTR_FILE, "validation_det_" + StringUtils::escapeXML(det->getID()) + ".xml");
     860             :             } else {
     861             :                 out.writeAttr(SUMO_ATTR_FILE, "validation_dets.xml");
     862             :             }
     863           0 :             out.closeTag();
     864             :         }
     865             :     }
     866           0 :     out.close();
     867           0 : }
     868             : 
     869             : 
     870             : void
     871           7 : RODFDetectorCon::removeDetector(const std::string& id) {
     872             :     //
     873             :     std::map<std::string, RODFDetector*>::iterator ri1 = myDetectorMap.find(id);
     874           7 :     RODFDetector* oldDet = (*ri1).second;
     875             :     myDetectorMap.erase(ri1);
     876             :     //
     877             :     std::vector<RODFDetector*>::iterator ri2 =
     878           7 :         std::find(myDetectors.begin(), myDetectors.end(), oldDet);
     879           7 :     myDetectors.erase(ri2);
     880             :     //
     881             :     bool found = false;
     882          16 :     for (std::map<std::string, std::vector<RODFDetector*> >::iterator rr3 = myDetectorEdgeMap.begin(); !found && rr3 != myDetectorEdgeMap.end(); ++rr3) {
     883           9 :         std::vector<RODFDetector*>& dets = (*rr3).second;
     884          11 :         for (std::vector<RODFDetector*>::iterator ri3 = dets.begin(); !found && ri3 != dets.end();) {
     885           9 :             if (*ri3 == oldDet) {
     886             :                 found = true;
     887             :                 ri3 = dets.erase(ri3);
     888             :             } else {
     889             :                 ++ri3;
     890             :             }
     891             :         }
     892             :     }
     893           7 :     delete oldDet;
     894           7 : }
     895             : 
     896             : 
     897             : void
     898           0 : RODFDetectorCon::guessEmptyFlows(RODFDetectorFlows& flows) {
     899             :     // routes must be built (we have ensured this in main)
     900             :     // detector followers/prior must be build (we have ensured this in main)
     901             :     //
     902           0 :     for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
     903           0 :         RODFDetector* det = *i;
     904             :         const std::set<const RODFDetector*>& prior = det->getPriorDetectors();
     905             :         const std::set<const RODFDetector*>& follower = det->getFollowerDetectors();
     906             :         int noFollowerWithRoutes = 0;
     907             :         int noPriorWithRoutes = 0;
     908             :         // count occurrences of detectors with/without routes
     909             :         std::set<const RODFDetector*>::const_iterator j;
     910           0 :         for (j = prior.begin(); j != prior.end(); ++j) {
     911           0 :             if (flows.knows((*j)->getID())) {
     912             :                 ++noPriorWithRoutes;
     913             :             }
     914             :         }
     915           0 :         for (j = follower.begin(); j != follower.end(); ++j) {
     916           0 :             if (flows.knows((*j)->getID())) {
     917             :                 ++noFollowerWithRoutes;
     918             :             }
     919             :         }
     920             : 
     921             :         // do not process detectors which have no routes
     922           0 :         if (!flows.knows(det->getID())) {
     923             :             continue;
     924             :         }
     925             : 
     926             :         // plain case: all of the prior detectors have routes
     927             :         if (noPriorWithRoutes == (int)prior.size()) {
     928             :             // the number of vehicles is the sum of all vehicles on prior
     929             :             continue;
     930             :         }
     931             : 
     932             :         // plain case: all of the follower detectors have routes
     933             :         if (noFollowerWithRoutes == (int)follower.size()) {
     934             :             // the number of vehicles is the sum of all vehicles on follower
     935             :             continue;
     936             :         }
     937             : 
     938             :     }
     939           0 : }
     940             : 
     941             : 
     942             : const RODFDetector&
     943     1253136 : RODFDetectorCon::getAnyDetectorForEdge(const RODFEdge* const edge) const {
     944    16739389 :     for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
     945    16739389 :         if ((*i)->getEdgeID() == edge->getID()) {
     946     1253136 :             return **i;
     947             :         }
     948             :     }
     949           0 :     throw 1;
     950             : }
     951             : 
     952             : 
     953             : void
     954         200 : RODFDetectorCon::clearDists(std::map<SUMOTime, RandomDistributor<int>* >& dists) const {
     955      103142 :     for (std::map<SUMOTime, RandomDistributor<int>* >::iterator i = dists.begin(); i != dists.end(); ++i) {
     956      102942 :         delete (*i).second;
     957             :     }
     958         200 : }
     959             : 
     960             : 
     961             : void
     962           0 : RODFDetectorCon::mesoJoin(const std::string& nid,
     963             :                           const std::vector<std::string>& oldids) {
     964             :     // build the new detector
     965             :     const RODFDetector& first = getDetector(*(oldids.begin()));
     966           0 :     RODFDetector* newDet = new RODFDetector(nid, first);
     967           0 :     addDetector(newDet);
     968             :     // delete previous
     969           0 :     for (std::vector<std::string>::const_iterator i = oldids.begin(); i != oldids.end(); ++i) {
     970           0 :         removeDetector(*i);
     971             :     }
     972           0 : }
     973             : 
     974             : 
     975             : std::string
     976    16739589 : RODFDetector::getEdgeID() const {
     977    33479178 :     return SUMOXMLDefinitions::getEdgeIDFromLane(myLaneID);
     978             : }
     979             : 
     980             : /****************************************************************************/

Generated by: LCOV version 1.14