LCOV - code coverage report
Current view: top level - src/dfrouter - RODFDetector.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 68.2 % 422 288
Test Date: 2024-12-21 15:45:41 Functions: 63.6 % 44 28

            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         1658 : RODFDetector::RODFDetector(const std::string& id, const std::string& laneID,
      54         1658 :                            double pos, const RODFDetectorType type)
      55         3316 :     : 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         3316 : RODFDetector::~RODFDetector() {
      68         1658 :     delete myRoutes;
      69         4974 : }
      70              : 
      71              : 
      72              : void
      73         1416 : RODFDetector::setType(RODFDetectorType type) {
      74         1416 :     myType = type;
      75         1416 : }
      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           37 :         }
     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         1053 : }
     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         1512 : RODFDetector::addRoutes(RODFRouteCont* routes) {
     251         1512 :     delete myRoutes;
     252         1512 :     myRoutes = routes;
     253         1512 : }
     254              : 
     255              : 
     256              : void
     257            4 : RODFDetector::addRoute(RODFRouteDesc& nrd) {
     258            4 :     if (myRoutes == nullptr) {
     259            2 :         myRoutes = new RODFRouteCont();
     260              :     }
     261            4 :     myRoutes->addRouteDesc(nrd);
     262            4 : }
     263              : 
     264              : 
     265              : bool
     266            0 : RODFDetector::hasRoutes() const {
     267          334 :     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          150 :                     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       102956 :         }
     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          200 : RODFDetectorCon::RODFDetectorCon() {}
     474              : 
     475              : 
     476          200 : RODFDetectorCon::~RODFDetectorCon() {
     477         1851 :     for (std::vector<RODFDetector*>::iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
     478         1651 :         delete *i;
     479              :     }
     480          200 : }
     481              : 
     482              : 
     483              : bool
     484         1658 : RODFDetectorCon::addDetector(RODFDetector* dfd) {
     485         1658 :     if (myDetectorMap.find(dfd->getID()) != myDetectorMap.end()) {
     486              :         return false;
     487              :     }
     488         1658 :     myDetectorMap[dfd->getID()] = dfd;
     489         1658 :     myDetectors.push_back(dfd);
     490         3316 :     const std::string edgeid = SUMOXMLDefinitions::getEdgeIDFromLane(dfd->getLaneID());
     491         1658 :     if (myDetectorEdgeMap.find(edgeid) == myDetectorEdgeMap.end()) {
     492         1351 :         myDetectorEdgeMap[edgeid] = std::vector<RODFDetector*>();
     493              :     }
     494         1658 :     myDetectorEdgeMap[edgeid].push_back(dfd);
     495              :     return true; // !!!
     496              : }
     497              : 
     498              : 
     499              : bool
     500          337 : RODFDetectorCon::detectorsHaveCompleteTypes() const {
     501         1994 :     for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
     502         1821 :         if ((*i)->getType() == TYPE_NOT_DEFINED) {
     503              :             return false;
     504              :         }
     505              :     }
     506              :     return true;
     507              : }
     508              : 
     509              : 
     510              : bool
     511          502 : RODFDetectorCon::detectorsHaveRoutes() const {
     512         2014 :     for (std::vector<RODFDetector*>::const_iterator i = myDetectors.begin(); i != myDetectors.end(); ++i) {
     513         1846 :         if ((*i)->hasRoutes()) {
     514              :             return true;
     515              :         }
     516              :     }
     517              :     return false;
     518              : }
     519              : 
     520              : 
     521              : const std::vector< RODFDetector*>&
     522         1373 : RODFDetectorCon::getDetectors() const {
     523         1373 :     return myDetectors;
     524              : }
     525              : 
     526              : 
     527              : void
     528           18 : RODFDetectorCon::save(const std::string& file) const {
     529           18 :     OutputDevice& out = OutputDevice::getDevice(file);
     530           34 :     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            6 :     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         8399 : RODFDetectorCon::getDetector(const std::string& id) const {
     607         8399 :     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          204 :     out.writeXMLHeader("additional", "additional_file.xsd");
     639              :     // write vType(s)
     640          102 :     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            4 :         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           18 :         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       205884 :         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 2.0-1