LCOV - code coverage report
Current view: top level - src/dfrouter - RODFNet.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 329 490 67.1 %
Date: 2024-09-16 15:39:55 Functions: 24 30 80.0 %

          Line data    Source code
       1             : /****************************************************************************/
       2             : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3             : // Copyright (C) 2001-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    RODFNet.cpp
      15             : /// @author  Daniel Krajzewicz
      16             : /// @author  Eric Nicolay
      17             : /// @author  Jakob Erdmann
      18             : /// @author  Michael Behrisch
      19             : /// @date    Thu, 16.03.2006
      20             : ///
      21             : // A DFROUTER-network
      22             : /****************************************************************************/
      23             : #include <config.h>
      24             : 
      25             : #include <cassert>
      26             : #include <iostream>
      27             : #include <map>
      28             : #include <queue>
      29             : #include <vector>
      30             : #include <iterator>
      31             : #include "RODFNet.h"
      32             : #include "RODFDetector.h"
      33             : #include "RODFRouteDesc.h"
      34             : #include "RODFDetectorFlow.h"
      35             : #include "RODFEdge.h"
      36             : #include <cmath>
      37             : #include <utils/common/MsgHandler.h>
      38             : #include <utils/common/ToString.h>
      39             : #include <utils/common/UtilExceptions.h>
      40             : #include <utils/geom/GeomHelper.h>
      41             : 
      42             : 
      43             : // ===========================================================================
      44             : // method definitions
      45             : // ===========================================================================
      46         714 : RODFNet::RODFNet(bool amInHighwayMode) :
      47         714 :     RONet(), myAmInHighwayMode(amInHighwayMode),
      48         714 :     mySourceNumber(0), mySinkNumber(0), myInBetweenNumber(0), myInvalidNumber(0),
      49         714 :     myMaxSpeedFactorPKW(1),
      50         714 :     myMaxSpeedFactorLKW(1),
      51         714 :     myAvgSpeedFactorPKW(1),
      52         714 :     myAvgSpeedFactorLKW(1) {
      53         714 :     myDisallowedEdges = OptionsCont::getOptions().getStringVector("disallowed-edges");
      54         714 :     myAllowedVClass = getVehicleClassID(OptionsCont::getOptions().getString("vclass"));
      55         714 :     myKeepTurnarounds = OptionsCont::getOptions().getBool("keep-turnarounds");
      56         714 : }
      57             : 
      58             : 
      59        1428 : RODFNet::~RODFNet() {
      60        2142 : }
      61             : 
      62             : 
      63             : bool
      64        7028 : RODFNet::isAllowed(const ROEdge* const edge) const {
      65        6298 :     return (!edge->isInternal() && !edge->isWalkingArea() && !edge->isCrossing() &&
      66       13326 :             (edge->getPermissions() & myAllowedVClass) == myAllowedVClass &&
      67        6296 :             find(myDisallowedEdges.begin(), myDisallowedEdges.end(), edge->getID()) == myDisallowedEdges.end());
      68             : 
      69             : }
      70             : 
      71             : 
      72             : void
      73         244 : RODFNet::buildApproachList() {
      74        3885 :     for (const auto& rit : getEdgeMap()) {
      75        3641 :         ROEdge* const ce = rit.second;
      76        3641 :         if (!isAllowed(ce)) {
      77         746 :             continue;
      78             :         }
      79        6282 :         for (ROEdge* const help : ce->getSuccessors()) {
      80        3387 :             if (!isAllowed(help)) {
      81             :                 // blocked edges will not be used
      82          22 :                 continue;
      83             :             }
      84        3365 :             if (!myKeepTurnarounds && help->getToJunction() == ce->getFromJunction()) {
      85             :                 // do not use turnarounds
      86          98 :                 continue;
      87             :             }
      88             :             // add the connection help->ce to myApproachingEdges
      89        3267 :             myApproachingEdges[help].push_back(ce);
      90             :             // add the connection ce->help to myApproachingEdges
      91        3267 :             myApproachedEdges[ce].push_back(help);
      92             :         }
      93             :     }
      94         244 : }
      95             : 
      96             : 
      97             : void
      98         420 : RODFNet::buildDetectorEdgeDependencies(RODFDetectorCon& detcont) const {
      99         420 :     myDetectorsOnEdges.clear();
     100         420 :     myDetectorEdges.clear();
     101         420 :     const std::vector<RODFDetector*>& dets = detcont.getDetectors();
     102        3476 :     for (std::vector<RODFDetector*>::const_iterator i = dets.begin(); i != dets.end(); ++i) {
     103        3056 :         ROEdge* e = getDetectorEdge(**i);
     104        3056 :         myDetectorsOnEdges[e].push_back((*i)->getID());
     105        3056 :         myDetectorEdges[(*i)->getID()] = e;
     106             :     }
     107         420 : }
     108             : 
     109             : 
     110             : void
     111         208 : RODFNet::computeTypes(RODFDetectorCon& detcont,
     112             :                       bool sourcesStrict) const {
     113         416 :     PROGRESS_BEGIN_MESSAGE(TL("Computing detector types"));
     114         208 :     const std::vector< RODFDetector*>& dets = detcont.getDetectors();
     115             :     // build needed information. first
     116         208 :     buildDetectorEdgeDependencies(detcont);
     117             :     // compute detector types then
     118        1664 :     for (std::vector< RODFDetector*>::const_iterator i = dets.begin(); i != dets.end(); ++i) {
     119        1456 :         if (isSource(**i, detcont, sourcesStrict)) {
     120         363 :             (*i)->setType(SOURCE_DETECTOR);
     121         363 :             mySourceNumber++;
     122             :         }
     123        1456 :         if (isDestination(**i, detcont)) {
     124         280 :             (*i)->setType(SINK_DETECTOR);
     125         280 :             mySinkNumber++;
     126             :         }
     127        1456 :         if ((*i)->getType() == TYPE_NOT_DEFINED) {
     128         843 :             (*i)->setType(BETWEEN_DETECTOR);
     129         843 :             myInBetweenNumber++;
     130             :         }
     131             :     }
     132             :     // recheck sources
     133        1664 :     for (std::vector< RODFDetector*>::const_iterator i = dets.begin(); i != dets.end(); ++i) {
     134        1456 :         if ((*i)->getType() == SOURCE_DETECTOR && isFalseSource(**i, detcont)) {
     135          18 :             (*i)->setType(DISCARDED_DETECTOR);
     136          18 :             myInvalidNumber++;
     137          18 :             mySourceNumber--;
     138             :         }
     139             :     }
     140             :     // print results
     141         208 :     PROGRESS_DONE_MESSAGE();
     142         208 :     WRITE_MESSAGE(TL("Computed detector types:"));
     143         416 :     WRITE_MESSAGEF(TL(" % source detectors"), toString(mySourceNumber));
     144         416 :     WRITE_MESSAGEF(TL(" % sink detectors"), toString(mySinkNumber));
     145         416 :     WRITE_MESSAGEF(TL(" % in-between detectors"), toString(myInBetweenNumber));
     146         416 :     WRITE_MESSAGEF(TL(" % invalid detectors"), toString(myInvalidNumber));
     147         208 : }
     148             : 
     149             : 
     150             : bool
     151        2999 : RODFNet::hasInBetweenDetectorsOnly(ROEdge* edge,
     152             :                                    const RODFDetectorCon& detectors) const {
     153             :     assert(myDetectorsOnEdges.find(edge) != myDetectorsOnEdges.end());
     154             :     const std::vector<std::string>& detIDs = myDetectorsOnEdges.find(edge)->second;
     155             :     std::vector<std::string>::const_iterator i;
     156        5259 :     for (i = detIDs.begin(); i != detIDs.end(); ++i) {
     157        3684 :         const RODFDetector& det = detectors.getDetector(*i);
     158        3684 :         if (det.getType() != BETWEEN_DETECTOR) {
     159             :             return false;
     160             :         }
     161             :     }
     162             :     return true;
     163             : }
     164             : 
     165             : 
     166             : bool
     167        1424 : RODFNet::hasSourceDetector(ROEdge* edge,
     168             :                            const RODFDetectorCon& detectors) const {
     169             :     assert(myDetectorsOnEdges.find(edge) != myDetectorsOnEdges.end());
     170             :     const std::vector<std::string>& detIDs = myDetectorsOnEdges.find(edge)->second;
     171             :     std::vector<std::string>::const_iterator i;
     172        3064 :     for (i = detIDs.begin(); i != detIDs.end(); ++i) {
     173        1674 :         const RODFDetector& det = detectors.getDetector(*i);
     174        1674 :         if (det.getType() == SOURCE_DETECTOR) {
     175             :             return true;
     176             :         }
     177             :     }
     178             :     return false;
     179             : }
     180             : 
     181             : 
     182             : 
     183             : void
     184        1320 : RODFNet::computeRoutesFor(ROEdge* edge, RODFRouteDesc& base, int /*no*/,
     185             :                           bool keepUnfoundEnds,
     186             :                           bool keepShortestOnly,
     187             :                           ROEdgeVector& /*visited*/,
     188             :                           const RODFDetector& det, RODFRouteCont& into,
     189             :                           const RODFDetectorCon& detectors,
     190             :                           int maxFollowingLength,
     191             :                           ROEdgeVector& seen) const {
     192             :     std::vector<RODFRouteDesc> unfoundEnds;
     193             :     std::priority_queue<RODFRouteDesc, std::vector<RODFRouteDesc>, DFRouteDescByTimeComperator> toSolve;
     194             :     std::map<ROEdge*, ROEdgeVector > dets2Follow;
     195        1320 :     dets2Follow[edge] = ROEdgeVector();
     196        1320 :     base.passedNo = 0;
     197        1320 :     double minDist = OptionsCont::getOptions().getFloat("min-route-length");
     198        1320 :     toSolve.push(base);
     199        6992 :     while (!toSolve.empty()) {
     200        5672 :         RODFRouteDesc current = toSolve.top();
     201        5672 :         toSolve.pop();
     202        5672 :         ROEdge* last = *(current.edges2Pass.end() - 1);
     203        5672 :         if (hasDetector(last)) {
     204        4539 :             if (dets2Follow.find(last) == dets2Follow.end()) {
     205        6028 :                 dets2Follow[last] = ROEdgeVector();
     206             :             }
     207        5125 :             for (ROEdgeVector::reverse_iterator i = current.edges2Pass.rbegin() + 1; i != current.edges2Pass.rend(); ++i) {
     208        3805 :                 if (hasDetector(*i)) {
     209        3219 :                     dets2Follow[*i].push_back(last);
     210             :                     break;
     211             :                 }
     212             :             }
     213             :         }
     214             : 
     215             :         // do not process an edge twice
     216        5672 :         if (find(seen.begin(), seen.end(), last) != seen.end() && keepShortestOnly) {
     217         116 :             continue;
     218             :         }
     219        5556 :         seen.push_back(last);
     220             :         // end if the edge has no further connections
     221        5556 :         if (!hasApproached(last)) {
     222             :             // ok, no further connections to follow
     223         671 :             current.factor = 1.;
     224         671 :             double cdist = current.edges2Pass[0]->getFromJunction()->getPosition().distanceTo(current.edges2Pass.back()->getToJunction()->getPosition());
     225         671 :             if (minDist < cdist) {
     226         667 :                 into.addRouteDesc(current);
     227             :             }
     228         671 :             continue;
     229         671 :         }
     230             :         // check for passing detectors:
     231             :         //  if the current last edge is not the one the detector is placed on ...
     232             :         bool addNextNoFurther = false;
     233        4885 :         if (last != getDetectorEdge(det)) {
     234             :             // ... if there is a detector ...
     235        3667 :             if (hasDetector(last)) {
     236        2999 :                 if (!hasInBetweenDetectorsOnly(last, detectors)) {
     237             :                     // ... and it's not an in-between-detector
     238             :                     // -> let's add this edge and the following, but not any further
     239             :                     addNextNoFurther = true;
     240        1424 :                     current.lastDetectorEdge = last;
     241        1424 :                     current.duration2Last = (SUMOTime) current.duration_2;
     242        1424 :                     current.distance2Last = current.distance;
     243        1424 :                     current.endDetectorEdge = last;
     244        1424 :                     if (hasSourceDetector(last, detectors)) {
     245             : ///!!!                        //toDiscard.push_back(current);
     246             :                     }
     247        1424 :                     current.factor = 1.;
     248        1424 :                     double cdist = current.edges2Pass[0]->getFromJunction()->getPosition().distanceTo(current.edges2Pass.back()->getToJunction()->getPosition());
     249        1424 :                     if (minDist < cdist) {
     250        1420 :                         into.addRouteDesc(current);
     251             :                     }
     252        1424 :                     continue;
     253        1424 :                 } else {
     254             :                     // ... if it's an in-between-detector
     255             :                     // -> mark the current route as to be continued
     256        1575 :                     current.passedNo = 0;
     257        1575 :                     current.duration2Last = (SUMOTime) current.duration_2;
     258        1575 :                     current.distance2Last = current.distance;
     259        1575 :                     current.lastDetectorEdge = last;
     260             :                 }
     261             :             }
     262             :         }
     263             :         // check for highway off-ramps
     264        3461 :         if (myAmInHighwayMode) {
     265             :             // if it's beside the highway...
     266           0 :             if (last->getSpeedLimit() < 19.4 && last != getDetectorEdge(det)) {
     267             :                 // ... and has more than one following edge
     268           0 :                 if (myApproachedEdges.find(last)->second.size() > 1) {
     269             :                     // -> let's add this edge and the following, but not any further
     270             :                     addNextNoFurther = true;
     271             :                 }
     272             : 
     273             :             }
     274             :         }
     275             :         // check for missing end connections
     276             :         if (!addNextNoFurther) {
     277             :             // ... if this one would be processed, but already too many edge
     278             :             //  without a detector occurred
     279        3461 :             if (current.passedNo > maxFollowingLength) {
     280             :                 // mark not to process any further
     281           0 :                 WRITE_WARNINGF(TL("Could not close route for '%'"), det.getID());
     282           0 :                 unfoundEnds.push_back(current);
     283           0 :                 current.factor = 1.;
     284           0 :                 double cdist = current.edges2Pass[0]->getFromJunction()->getPosition().distanceTo(current.edges2Pass.back()->getToJunction()->getPosition());
     285           0 :                 if (minDist < cdist) {
     286           0 :                     into.addRouteDesc(current);
     287             :                 }
     288           0 :                 continue;
     289           0 :             }
     290             :         }
     291             :         // ... else: loop over the next edges
     292             :         const ROEdgeVector& appr  = myApproachedEdges.find(last)->second;
     293             :         bool hadOne = false;
     294        7906 :         for (int i = 0; i < (int)appr.size(); i++) {
     295        4445 :             if (find(current.edges2Pass.begin(), current.edges2Pass.end(), appr[i]) != current.edges2Pass.end()) {
     296             :                 // do not append an edge twice (do not build loops)
     297          93 :                 continue;
     298             :             }
     299        4352 :             RODFRouteDesc t(current);
     300        4352 :             t.duration_2 += (appr[i]->getLength() / appr[i]->getSpeedLimit()); //!!!
     301        4352 :             t.distance += appr[i]->getLength();
     302        4352 :             t.edges2Pass.push_back(appr[i]);
     303        4352 :             if (!addNextNoFurther) {
     304        4352 :                 t.passedNo++;
     305        4352 :                 toSolve.push(t);
     306             :             } else {
     307           0 :                 if (!hadOne) {
     308           0 :                     t.factor = (double) 1. / (double) appr.size();
     309           0 :                     double cdist = current.edges2Pass[0]->getFromJunction()->getPosition().distanceTo(current.edges2Pass.back()->getToJunction()->getPosition());
     310           0 :                     if (minDist < cdist) {
     311           0 :                         into.addRouteDesc(t);
     312             :                     }
     313             :                     hadOne = true;
     314             :                 }
     315             :             }
     316        4352 :         }
     317        5672 :     }
     318             :     //
     319        1320 :     if (!keepUnfoundEnds) {
     320             :         std::vector<RODFRouteDesc>::iterator i;
     321             :         ConstROEdgeVector lastDetEdges;
     322        1320 :         for (i = unfoundEnds.begin(); i != unfoundEnds.end(); ++i) {
     323           0 :             if (find(lastDetEdges.begin(), lastDetEdges.end(), (*i).lastDetectorEdge) == lastDetEdges.end()) {
     324           0 :                 lastDetEdges.push_back((*i).lastDetectorEdge);
     325             :             } else {
     326           0 :                 bool ok = into.removeRouteDesc(*i);
     327             :                 assert(ok);
     328             :                 UNUSED_PARAMETER(ok); // only used for assertion
     329             :             }
     330             :         }
     331             :     } else {
     332             :         // !!! patch the factors
     333             :     }
     334        1320 :     while (!toSolve.empty()) {
     335             : //        RODFRouteDesc d = toSolve.top();
     336           0 :         toSolve.pop();
     337             : //        delete d;
     338             :     }
     339        1320 : }
     340             : 
     341             : 
     342             : void
     343         212 : RODFNet::buildRoutes(RODFDetectorCon& detcont, bool keepUnfoundEnds, bool includeInBetween,
     344             :                      bool keepShortestOnly, int maxFollowingLength) const {
     345             :     // build needed information first
     346         212 :     buildDetectorEdgeDependencies(detcont);
     347             :     // then build the routes
     348             :     std::map<ROEdge*, RODFRouteCont* > doneEdges;
     349         212 :     const std::vector< RODFDetector*>& dets = detcont.getDetectors();
     350        1812 :     for (std::vector< RODFDetector*>::const_iterator i = dets.begin(); i != dets.end(); ++i) {
     351        1600 :         ROEdge* e = getDetectorEdge(**i);
     352        1600 :         if (doneEdges.find(e) != doneEdges.end()) {
     353             :             // use previously build routes
     354         280 :             (*i)->addRoutes(new RODFRouteCont(*doneEdges[e]));
     355         280 :             continue;
     356             :         }
     357             :         ROEdgeVector seen;
     358        1320 :         RODFRouteCont* routes = new RODFRouteCont();
     359        1320 :         doneEdges[e] = routes;
     360             :         RODFRouteDesc rd;
     361        1320 :         rd.edges2Pass.push_back(e);
     362        1320 :         rd.duration_2 = (e->getLength() / e->getSpeedLimit()); //!!!;
     363        1320 :         rd.endDetectorEdge = nullptr;
     364        1320 :         rd.lastDetectorEdge = nullptr;
     365        1320 :         rd.distance = e->getLength();
     366        1320 :         rd.distance2Last = 0;
     367        1320 :         rd.duration2Last = 0;
     368             : 
     369        1320 :         rd.overallProb = 0;
     370             : 
     371             :         ROEdgeVector visited;
     372        1320 :         visited.push_back(e);
     373        1320 :         computeRoutesFor(e, rd, 0, keepUnfoundEnds, keepShortestOnly,
     374             :                          visited, **i, *routes, detcont, maxFollowingLength, seen);
     375             :         //!!!routes->removeIllegal(illegals);
     376        1320 :         (*i)->addRoutes(routes);
     377             : 
     378             :         // add routes to in-between detectors if wished
     379        1320 :         if (includeInBetween) {
     380             :             // go through the routes
     381             :             const std::vector<RODFRouteDesc>& r = routes->get();
     382          12 :             for (std::vector<RODFRouteDesc>::const_iterator j = r.begin(); j != r.end(); ++j) {
     383             :                 const RODFRouteDesc& mrd = *j;
     384           6 :                 double duration = mrd.duration_2;
     385           6 :                 double distance = mrd.distance;
     386             :                 // go through each route's edges
     387             :                 ROEdgeVector::const_iterator routeend = mrd.edges2Pass.end();
     388          18 :                 for (ROEdgeVector::const_iterator k = mrd.edges2Pass.begin(); k != routeend; ++k) {
     389             :                     // check whether any detectors lies on the current edge
     390          12 :                     if (myDetectorsOnEdges.find(*k) == myDetectorsOnEdges.end()) {
     391           0 :                         duration -= (*k)->getLength() / (*k)->getSpeedLimit();
     392           0 :                         distance -= (*k)->getLength();
     393           0 :                         continue;
     394             :                     }
     395             :                     // go through the detectors
     396          24 :                     for (const std::string& l : myDetectorsOnEdges.find(*k)->second) {
     397          12 :                         const RODFDetector& m = detcont.getDetector(l);
     398          12 :                         if (m.getType() == BETWEEN_DETECTOR) {
     399             :                             RODFRouteDesc nrd;
     400             :                             copy(k, routeend, back_inserter(nrd.edges2Pass));
     401           4 :                             nrd.duration_2 = duration;//!!!;
     402           4 :                             nrd.endDetectorEdge = mrd.endDetectorEdge;
     403           4 :                             nrd.lastDetectorEdge = mrd.lastDetectorEdge;
     404           4 :                             nrd.distance = distance;
     405           4 :                             nrd.distance2Last = mrd.distance2Last;
     406           4 :                             nrd.duration2Last = mrd.duration2Last;
     407           4 :                             nrd.overallProb = mrd.overallProb;
     408           4 :                             nrd.factor = mrd.factor;
     409           4 :                             ((RODFDetector&) m).addRoute(nrd);
     410           4 :                         }
     411             :                     }
     412          12 :                     duration -= (*k)->getLength() / (*k)->getSpeedLimit();
     413          12 :                     distance -= (*k)->getLength();
     414             :                 }
     415             :             }
     416             :         }
     417             : 
     418        1320 :     }
     419         212 : }
     420             : 
     421             : 
     422             : void
     423           0 : RODFNet::revalidateFlows(const RODFDetector* detector,
     424             :                          RODFDetectorFlows& flows,
     425             :                          SUMOTime startTime, SUMOTime endTime,
     426             :                          SUMOTime stepOffset) {
     427             :     {
     428           0 :         if (flows.knows(detector->getID())) {
     429           0 :             const std::vector<FlowDef>& detFlows = flows.getFlowDefs(detector->getID());
     430           0 :             for (std::vector<FlowDef>::const_iterator j = detFlows.begin(); j != detFlows.end(); ++j) {
     431           0 :                 if ((*j).qPKW > 0 || (*j).qLKW > 0) {
     432             :                     return;
     433             :                 }
     434             :             }
     435             :         }
     436             :     }
     437             :     // ok, there is no information for the whole time;
     438             :     //  lets find preceding detectors and rebuild the flows if possible
     439           0 :     WRITE_WARNINGF(TL("Detector '%' has no flows.\n Trying to rebuild."), detector->getID());
     440             :     // go back and collect flows
     441             :     ROEdgeVector previous;
     442             :     {
     443             :         std::vector<IterationEdge> missing;
     444             :         IterationEdge ie;
     445           0 :         ie.depth = 0;
     446           0 :         ie.edge = getDetectorEdge(*detector);
     447           0 :         missing.push_back(ie);
     448             :         bool maxDepthReached = false;
     449           0 :         while (!missing.empty() && !maxDepthReached) {
     450           0 :             IterationEdge last = missing.back();
     451             :             missing.pop_back();
     452           0 :             ROEdgeVector approaching = myApproachingEdges[last.edge];
     453           0 :             for (ROEdgeVector::const_iterator j = approaching.begin(); j != approaching.end(); ++j) {
     454           0 :                 if (hasDetector(*j)) {
     455           0 :                     previous.push_back(*j);
     456             :                 } else {
     457           0 :                     ie.depth = last.depth + 1;
     458           0 :                     ie.edge = *j;
     459           0 :                     missing.push_back(ie);
     460           0 :                     if (ie.depth > 5) {
     461             :                         maxDepthReached = true;
     462             :                     }
     463             :                 }
     464             :             }
     465             :         }
     466           0 :         if (maxDepthReached) {
     467           0 :             WRITE_WARNING(TL(" Could not build list of previous flows."));
     468             :         }
     469             :     }
     470             :     // Edges with previous detectors are now in "previous";
     471             :     //  compute following
     472             :     ROEdgeVector latter;
     473             :     {
     474             :         std::vector<IterationEdge> missing;
     475           0 :         for (ROEdgeVector::const_iterator k = previous.begin(); k != previous.end(); ++k) {
     476             :             IterationEdge ie;
     477           0 :             ie.depth = 0;
     478           0 :             ie.edge = *k;
     479           0 :             missing.push_back(ie);
     480             :         }
     481             :         bool maxDepthReached = false;
     482           0 :         while (!missing.empty() && !maxDepthReached) {
     483           0 :             IterationEdge last = missing.back();
     484             :             missing.pop_back();
     485           0 :             ROEdgeVector approached = myApproachedEdges[last.edge];
     486           0 :             for (ROEdgeVector::const_iterator j = approached.begin(); j != approached.end(); ++j) {
     487           0 :                 if (*j == getDetectorEdge(*detector)) {
     488           0 :                     continue;
     489             :                 }
     490           0 :                 if (hasDetector(*j)) {
     491           0 :                     latter.push_back(*j);
     492             :                 } else {
     493             :                     IterationEdge ie;
     494           0 :                     ie.depth = last.depth + 1;
     495           0 :                     ie.edge = *j;
     496           0 :                     missing.push_back(ie);
     497           0 :                     if (ie.depth > 5) {
     498             :                         maxDepthReached = true;
     499             :                     }
     500             :                 }
     501             :             }
     502             :         }
     503           0 :         if (maxDepthReached) {
     504           0 :             WRITE_WARNING(TL(" Could not build list of latter flows."));
     505             :             return;
     506             :         }
     507             :     }
     508             :     // Edges with latter detectors are now in "latter";
     509             : 
     510             :     // lets not validate them by now - surely this should be done
     511             :     // for each time step: collect incoming flows; collect outgoing;
     512             :     std::vector<FlowDef> mflows;
     513             :     int index = 0;
     514           0 :     for (SUMOTime t = startTime; t < endTime; t += stepOffset, index++) {
     515             :         // collect incoming
     516             :         FlowDef inFlow;
     517             :         inFlow.qLKW = 0;
     518             :         inFlow.qPKW = 0;
     519             :         inFlow.vLKW = 0;
     520             :         inFlow.vPKW = 0;
     521             :         // !! time difference is missing
     522           0 :         for (const ROEdge* const e : previous) {
     523           0 :             const std::vector<FlowDef>& eflows = static_cast<const RODFEdge*>(e)->getFlows();
     524           0 :             if (eflows.size() != 0) {
     525           0 :                 const FlowDef& srcFD = eflows[index];
     526           0 :                 inFlow.qLKW += srcFD.qLKW;
     527           0 :                 inFlow.qPKW += srcFD.qPKW;
     528           0 :                 inFlow.vLKW += srcFD.vLKW;
     529           0 :                 inFlow.vPKW += srcFD.vPKW;
     530             :             }
     531             :         }
     532           0 :         inFlow.vLKW /= (double) previous.size();
     533           0 :         inFlow.vPKW /= (double) previous.size();
     534             :         // collect outgoing
     535             :         FlowDef outFlow;
     536             :         outFlow.qLKW = 0;
     537             :         outFlow.qPKW = 0;
     538             :         outFlow.vLKW = 0;
     539             :         outFlow.vPKW = 0;
     540             :         // !! time difference is missing
     541           0 :         for (const ROEdge* const e : latter) {
     542           0 :             const std::vector<FlowDef>& eflows = static_cast<const RODFEdge*>(e)->getFlows();
     543           0 :             if (eflows.size() != 0) {
     544           0 :                 const FlowDef& srcFD = eflows[index];
     545           0 :                 outFlow.qLKW += srcFD.qLKW;
     546           0 :                 outFlow.qPKW += srcFD.qPKW;
     547           0 :                 outFlow.vLKW += srcFD.vLKW;
     548           0 :                 outFlow.vPKW += srcFD.vPKW;
     549             :             }
     550             :         }
     551           0 :         outFlow.vLKW /= (double) latter.size();
     552           0 :         outFlow.vPKW /= (double) latter.size();
     553             :         //
     554             :         FlowDef mFlow;
     555           0 :         mFlow.qLKW = inFlow.qLKW - outFlow.qLKW;
     556           0 :         mFlow.qPKW = inFlow.qPKW - outFlow.qPKW;
     557           0 :         mFlow.vLKW = (inFlow.vLKW + outFlow.vLKW) / (double) 2.;
     558           0 :         mFlow.vPKW = (inFlow.vPKW + outFlow.vPKW) / (double) 2.;
     559           0 :         mflows.push_back(mFlow);
     560             :     }
     561           0 :     static_cast<RODFEdge*>(getDetectorEdge(*detector))->setFlows(mflows);
     562           0 :     flows.setFlows(detector->getID(), mflows);
     563             : }
     564             : 
     565             : 
     566             : void
     567           0 : RODFNet::revalidateFlows(const RODFDetectorCon& detectors,
     568             :                          RODFDetectorFlows& flows,
     569             :                          SUMOTime startTime, SUMOTime endTime,
     570             :                          SUMOTime stepOffset) {
     571           0 :     const std::vector<RODFDetector*>& dets = detectors.getDetectors();
     572           0 :     for (std::vector<RODFDetector*>::const_iterator i = dets.begin(); i != dets.end(); ++i) {
     573             :         // check whether there is at least one entry with a flow larger than zero
     574           0 :         revalidateFlows(*i, flows, startTime, endTime, stepOffset);
     575             :     }
     576           0 : }
     577             : 
     578             : 
     579             : 
     580             : void
     581           7 : RODFNet::removeEmptyDetectors(RODFDetectorCon& detectors,
     582             :                               RODFDetectorFlows& flows) {
     583           7 :     const std::vector<RODFDetector*>& dets = detectors.getDetectors();
     584         106 :     for (std::vector<RODFDetector*>::const_iterator i = dets.begin(); i != dets.end();) {
     585             :         bool remove = true;
     586             :         // check whether there is at least one entry with a flow larger than zero
     587          99 :         if (flows.knows((*i)->getID())) {
     588             :             remove = false;
     589             :         }
     590             :         if (remove) {
     591          14 :             WRITE_MESSAGEF(TL("Removed detector '%' because no flows for him exist."), (*i)->getID());
     592           7 :             flows.removeFlow((*i)->getID());
     593           7 :             detectors.removeDetector((*i)->getID());
     594             :             i = dets.begin();
     595             :         } else {
     596             :             i++;
     597             :         }
     598             :     }
     599           7 : }
     600             : 
     601             : 
     602             : 
     603             : void
     604           7 : RODFNet::reportEmptyDetectors(RODFDetectorCon& detectors,
     605             :                               RODFDetectorFlows& flows) {
     606           7 :     const std::vector<RODFDetector*>& dets = detectors.getDetectors();
     607          70 :     for (std::vector<RODFDetector*>::const_iterator i = dets.begin(); i != dets.end(); ++i) {
     608             :         bool remove = true;
     609             :         // check whether there is at least one entry with a flow larger than zero
     610          63 :         if (flows.knows((*i)->getID())) {
     611             :             remove = false;
     612             :         }
     613             :         if (remove) {
     614          14 :             WRITE_MESSAGEF(TL("Detector '%' has no flow."), (*i)->getID());
     615             :         }
     616             :     }
     617           7 : }
     618             : 
     619             : 
     620             : 
     621             : ROEdge*
     622       28409 : RODFNet::getDetectorEdge(const RODFDetector& det) const {
     623       56818 :     const std::string edgeName = SUMOXMLDefinitions::getEdgeIDFromLane(det.getLaneID());
     624             :     ROEdge* ret = getEdge(edgeName);
     625       28409 :     if (ret == nullptr) {
     626           0 :         throw ProcessError("Edge '" + edgeName + "' used by detector '" + det.getID() + "' is not known.");
     627             :     }
     628       28409 :     return ret;
     629             : }
     630             : 
     631             : 
     632             : bool
     633        3539 : RODFNet::hasApproaching(ROEdge* edge) const {
     634             :     return myApproachingEdges.find(edge) != myApproachingEdges.end()
     635        6275 :            && myApproachingEdges.find(edge)->second.size() != 0;
     636             : }
     637             : 
     638             : 
     639             : bool
     640        8459 : RODFNet::hasApproached(ROEdge* edge) const {
     641             :     return myApproachedEdges.find(edge) != myApproachedEdges.end()
     642       15845 :            && myApproachedEdges.find(edge)->second.size() != 0;
     643             : }
     644             : 
     645             : 
     646             : bool
     647     1472858 : RODFNet::hasDetector(ROEdge* edge) const {
     648             :     return myDetectorsOnEdges.find(edge) != myDetectorsOnEdges.end()
     649     1472858 :            && myDetectorsOnEdges.find(edge)->second.size() != 0;
     650             : }
     651             : 
     652             : 
     653             : const std::vector<std::string>&
     654           0 : RODFNet::getDetectorList(ROEdge* edge) const {
     655           0 :     return myDetectorsOnEdges.find(edge)->second;
     656             : }
     657             : 
     658             : 
     659             : double
     660           0 : RODFNet::getAbsPos(const RODFDetector& det) const {
     661        1680 :     if (det.getPos() >= 0) {
     662             :         return det.getPos();
     663             :     }
     664        1236 :     return getDetectorEdge(det)->getLength() + det.getPos();
     665             : }
     666             : 
     667             : bool
     668        1456 : RODFNet::isSource(const RODFDetector& det, const RODFDetectorCon& detectors,
     669             :                   bool strict) const {
     670             :     ROEdgeVector seen;
     671        2912 :     return isSource(det, getDetectorEdge(det), seen, detectors, strict);
     672             : }
     673             : 
     674             : bool
     675         333 : RODFNet::isFalseSource(const RODFDetector& det, const RODFDetectorCon& detectors) const {
     676             :     ROEdgeVector seen;
     677         666 :     return isFalseSource(det, getDetectorEdge(det), seen, detectors);
     678             : }
     679             : 
     680             : bool
     681        1456 : RODFNet::isDestination(const RODFDetector& det, const RODFDetectorCon& detectors) const {
     682             :     ROEdgeVector seen;
     683        1456 :     return isDestination(det, getDetectorEdge(det), seen, detectors);
     684             : }
     685             : 
     686             : 
     687             : bool
     688        3589 : RODFNet::isSource(const RODFDetector& det, ROEdge* edge,
     689             :                   ROEdgeVector& seen,
     690             :                   const RODFDetectorCon& detectors,
     691             :                   bool strict) const {
     692        3589 :     if (seen.size() == 1000) { // !!!
     693           0 :         WRITE_WARNINGF(TL("Quitting checking for being a source for detector '%' due to seen edge limit."), det.getID());
     694           0 :         return false;
     695             :     }
     696        3589 :     if (edge == getDetectorEdge(det)) {
     697             :         // maybe there is another detector at the same edge
     698             :         //  get the list of this/these detector(s)
     699             :         const std::vector<std::string>& detsOnEdge = myDetectorsOnEdges.find(edge)->second;
     700        3386 :         for (std::vector<std::string>::const_iterator i = detsOnEdge.begin(); i != detsOnEdge.end(); ++i) {
     701        1980 :             if ((*i) == det.getID()) {
     702        1440 :                 continue;
     703             :             }
     704         540 :             const RODFDetector& sec = detectors.getDetector(*i);
     705         540 :             if (getAbsPos(sec) < getAbsPos(det)) {
     706             :                 // ok, there is another detector on the same edge and it is
     707             :                 //  before this one -> no source
     708             :                 return false;
     709             :             }
     710             :         }
     711             :     }
     712             :     // it's a source if no edges are approaching the edge
     713        3539 :     if (!hasApproaching(edge)) {
     714         803 :         if (edge != getDetectorEdge(det)) {
     715         587 :             if (hasDetector(edge)) {
     716             :                 return false;
     717             :             }
     718             :         }
     719         378 :         return true;
     720             :     }
     721        2736 :     if (edge != getDetectorEdge(det)) {
     722             :         // ok, we are at one of the edges in front
     723        1546 :         if (myAmInHighwayMode) {
     724           0 :             if (edge->getSpeedLimit() >= 19.4) {
     725           0 :                 if (hasDetector(edge)) {
     726             :                     // we are still on the highway and there is another detector
     727             :                     return false;
     728             :                 }
     729             :                 // the next is a hack for the A100 scenario...
     730             :                 //  We have to look into further edges herein edges
     731             :                 const ROEdgeVector& appr = myApproachingEdges.find(edge)->second;
     732             :                 int noFalse = 0;
     733             :                 int noSkipped = 0;
     734           0 :                 for (int i = 0; i < (int)appr.size(); i++) {
     735           0 :                     if (hasDetector(appr[i])) {
     736           0 :                         noFalse++;
     737             :                     }
     738             :                 }
     739           0 :                 if (noFalse + noSkipped == (int)appr.size()) {
     740             :                     return false;
     741             :                 }
     742             :             }
     743             :         }
     744             :     }
     745             : 
     746        2736 :     if (myAmInHighwayMode) {
     747           0 :         if (edge->getSpeedLimit() < 19.4 && edge != getDetectorEdge(det)) {
     748             :             // we have left the highway already
     749             :             //  -> the detector will be a highway source
     750           0 :             if (!hasDetector(edge)) {
     751             :                 return true;
     752             :             }
     753             :         }
     754             :     }
     755             :     if (myDetectorsOnEdges.find(edge) != myDetectorsOnEdges.end()
     756        2736 :             &&
     757        2274 :             myDetectorEdges.find(det.getID())->second != edge) {
     758             :         return false;
     759             :     }
     760             : 
     761             :     // let's check the edges in front
     762             :     const ROEdgeVector& appr = myApproachingEdges.find(edge)->second;
     763             :     int numOk = 0;
     764             :     int numFalse = 0;
     765             :     int numSkipped = 0;
     766        1652 :     seen.push_back(edge);
     767        3896 :     for (int i = 0; i < (int)appr.size(); i++) {
     768        2244 :         bool had = std::find(seen.begin(), seen.end(), appr[i]) != seen.end();
     769        2244 :         if (!had) {
     770        2133 :             if (isSource(det, appr[i], seen, detectors, strict)) {
     771         346 :                 numOk++;
     772             :             } else {
     773        1787 :                 numFalse++;
     774             :             }
     775             :         } else {
     776         111 :             numSkipped++;
     777             :         }
     778             :     }
     779        1652 :     if (strict) {
     780           0 :         return numOk + numSkipped == (int)appr.size();
     781             :     }
     782        1652 :     return numFalse + numSkipped != (int)appr.size();
     783             : }
     784             : 
     785             : 
     786             : bool
     787        2953 : RODFNet::isDestination(const RODFDetector& det, ROEdge* edge, ROEdgeVector& seen,
     788             :                        const RODFDetectorCon& detectors) const {
     789        2953 :     if (seen.size() == 1000) { // !!!
     790           0 :         WRITE_WARNINGF(TL("Quitting checking for being a destination for detector '%' due to seen edge limit."), det.getID());
     791           0 :         return false;
     792             :     }
     793        2953 :     if (edge == getDetectorEdge(det)) {
     794             :         // maybe there is another detector at the same edge
     795             :         //  get the list of this/these detector(s)
     796             :         const std::vector<std::string>& detsOnEdge = myDetectorsOnEdges.find(edge)->second;
     797        3350 :         for (std::vector<std::string>::const_iterator i = detsOnEdge.begin(); i != detsOnEdge.end(); ++i) {
     798        1944 :             if ((*i) == det.getID()) {
     799        1422 :                 continue;
     800             :             }
     801         522 :             const RODFDetector& sec = detectors.getDetector(*i);
     802         522 :             if (getAbsPos(sec) > getAbsPos(det)) {
     803             :                 // ok, there is another detector on the same edge and it is
     804             :                 //  after this one -> no destination
     805             :                 return false;
     806             :             }
     807             :         }
     808             :     }
     809        2903 :     if (!hasApproached(edge)) {
     810         402 :         if (edge != getDetectorEdge(det)) {
     811         305 :             if (hasDetector(edge)) {
     812             :                 return false;
     813             :             }
     814             :         }
     815         309 :         return true;
     816             :     }
     817        2501 :     if (edge != getDetectorEdge(det)) {
     818             :         // ok, we are at one of the edges coming behind
     819        1192 :         if (myAmInHighwayMode) {
     820           0 :             if (edge->getSpeedLimit() >= 19.4) {
     821           0 :                 if (hasDetector(edge)) {
     822             :                     // we are still on the highway and there is another detector
     823             :                     return false;
     824             :                 }
     825             :             }
     826             :         }
     827             :     }
     828             : 
     829        2501 :     if (myAmInHighwayMode) {
     830           0 :         if (edge->getSpeedLimit() < 19.4 && edge != getDetectorEdge(det)) {
     831           0 :             if (hasDetector(edge)) {
     832             :                 return true;
     833             :             }
     834           0 :             if (myApproachedEdges.find(edge)->second.size() > 1) {
     835             :                 return true;
     836             :             }
     837             : 
     838             :         }
     839             :     }
     840             : 
     841             :     if (myDetectorsOnEdges.find(edge) != myDetectorsOnEdges.end()
     842        2501 :             &&
     843        2342 :             myDetectorEdges.find(det.getID())->second != edge) {
     844             :         return false;
     845             :     }
     846             :     const ROEdgeVector& appr  = myApproachedEdges.find(edge)->second;
     847             :     bool isall = true;
     848        1468 :     seen.push_back(edge);
     849        2966 :     for (int i = 0; i < (int)appr.size() && isall; i++) {
     850        1498 :         bool had = std::find(seen.begin(), seen.end(), appr[i]) != seen.end();
     851        1498 :         if (!had) {
     852        1497 :             if (!isDestination(det, appr[i], seen, detectors)) {
     853             :                 isall = false;
     854             :             }
     855             :         }
     856             :     }
     857             :     return isall;
     858             : }
     859             : 
     860             : bool
     861        1403 : RODFNet::isFalseSource(const RODFDetector& det, ROEdge* edge, ROEdgeVector& seen,
     862             :                        const RODFDetectorCon& detectors) const {
     863        1403 :     if (seen.size() == 1000) { // !!!
     864           0 :         WRITE_WARNINGF(TL("Quitting checking for being a false source for detector '%' due to seen edge limit."), det.getID());
     865           0 :         return false;
     866             :     }
     867        1403 :     seen.push_back(edge);
     868        1403 :     if (edge != getDetectorEdge(det)) {
     869             :         // ok, we are at one of the edges coming behind
     870        1070 :         if (hasDetector(edge)) {
     871             :             const std::vector<std::string>& dets = myDetectorsOnEdges.find(edge)->second;
     872         646 :             for (std::vector<std::string>::const_iterator i = dets.begin(); i != dets.end(); ++i) {
     873         646 :                 if (detectors.getDetector(*i).getType() == SINK_DETECTOR) {
     874             :                     return false;
     875             :                 }
     876         448 :                 if (detectors.getDetector(*i).getType() == BETWEEN_DETECTOR) {
     877             :                     return false;
     878             :                 }
     879          18 :                 if (detectors.getDetector(*i).getType() == SOURCE_DETECTOR) {
     880             :                     return true;
     881             :                 }
     882             :             }
     883             :         } else {
     884         424 :             if (myAmInHighwayMode && edge->getSpeedLimit() < 19.) {
     885             :                 return false;
     886             :             }
     887             :         }
     888             :     }
     889             : 
     890         757 :     if (myApproachedEdges.find(edge) == myApproachedEdges.end()) {
     891             :         return false;
     892             :     }
     893             : 
     894             :     const ROEdgeVector& appr  = myApproachedEdges.find(edge)->second;
     895             :     bool isall = false;
     896        1871 :     for (int i = 0; i < (int)appr.size() && !isall; i++) {
     897             :         //printf("checking %s->\n", appr[i].c_str());
     898        1162 :         bool had = std::find(seen.begin(), seen.end(), appr[i]) != seen.end();
     899        1162 :         if (!had) {
     900        1070 :             if (isFalseSource(det, appr[i], seen, detectors)) {
     901             :                 isall = true;
     902             :             }
     903             :         }
     904             :     }
     905             :     return isall;
     906             : }
     907             : 
     908             : 
     909             : void
     910         104 : RODFNet::buildEdgeFlowMap(const RODFDetectorFlows& flows,
     911             :                           const RODFDetectorCon& detectors,
     912             :                           SUMOTime startTime, SUMOTime endTime,
     913             :                           SUMOTime stepOffset) {
     914             :     std::map<ROEdge*, std::vector<std::string>, idComp>::iterator i;
     915             :     double speedFactorSumPKW = 0;
     916             :     double speedFactorSumLKW = 0;
     917             :     double speedFactorCountPKW = 0;
     918             :     double speedFactorCountLKW = 0;
     919        1006 :     for (i = myDetectorsOnEdges.begin(); i != myDetectorsOnEdges.end(); ++i) {
     920         902 :         ROEdge* into = (*i).first;
     921         902 :         const double maxSpeedPKW = into->getVClassMaxSpeed(SVC_PASSENGER);
     922         902 :         const double maxSpeedLKW = into->getVClassMaxSpeed(SVC_TRUCK);
     923             : 
     924             :         const std::vector<std::string>& dets = (*i).second;
     925             :         std::map<double, std::vector<std::string> > cliques;
     926             :         std::vector<std::string>* maxClique = nullptr;
     927        1955 :         for (std::vector<std::string>::const_iterator j = dets.begin(); j != dets.end(); ++j) {
     928        1053 :             if (!flows.knows(*j)) {
     929         154 :                 continue;
     930             :             }
     931         899 :             const RODFDetector& det = detectors.getDetector(*j);
     932             :             bool found = false;
     933         981 :             for (std::map<double, std::vector<std::string> >::iterator k = cliques.begin(); !found && k != cliques.end(); ++k) {
     934          82 :                 if (fabs((*k).first - det.getPos()) < 1) {
     935          82 :                     (*k).second.push_back(*j);
     936          82 :                     if ((*k).second.size() > maxClique->size()) {
     937             :                         maxClique = &(*k).second;
     938             :                     }
     939             :                     found = true;
     940             :                 }
     941             :             }
     942         899 :             if (!found) {
     943         817 :                 cliques[det.getPos()].push_back(*j);
     944         817 :                 maxClique = &cliques[det.getPos()];
     945             :             }
     946             :         }
     947         902 :         if (maxClique == nullptr) {
     948             :             continue;
     949             :         }
     950             :         std::vector<FlowDef> mflows; // !!! reserve
     951      310610 :         for (SUMOTime t = startTime; t < endTime; t += stepOffset) {
     952             :             FlowDef fd;
     953      309793 :             fd.qPKW = 0;
     954      309793 :             fd.qLKW = 0;
     955      309793 :             fd.vLKW = 0;
     956      309793 :             fd.vPKW = 0;
     957      309793 :             fd.fLKW = 0;
     958      309793 :             fd.isLKW = 0;
     959      309793 :             mflows.push_back(fd);
     960             :         }
     961        1716 :         for (std::vector<std::string>::iterator l = maxClique->begin(); l != maxClique->end(); ++l) {
     962             :             bool didWarn = false;
     963         899 :             const std::vector<FlowDef>& dflows = flows.getFlowDefs(*l);
     964             :             int index = 0;
     965      402872 :             for (SUMOTime t = startTime; t < endTime; t += stepOffset, index++) {
     966      401973 :                 const FlowDef& srcFD = dflows[index];
     967             :                 FlowDef& fd = mflows[index];
     968      401973 :                 fd.qPKW += srcFD.qPKW;
     969      401973 :                 fd.qLKW += srcFD.qLKW;
     970      401973 :                 fd.vLKW += srcFD.vLKW / (double) maxClique->size();
     971      401973 :                 fd.vPKW += srcFD.vPKW / (double) maxClique->size();
     972      401973 :                 fd.fLKW += srcFD.fLKW / (double) maxClique->size();
     973      401973 :                 fd.isLKW += srcFD.isLKW / (double) maxClique->size();
     974      401973 :                 const double speedFactorPKW = srcFD.vPKW / 3.6 / maxSpeedPKW;
     975      401973 :                 const double speedFactorLKW = srcFD.vLKW / 3.6 / maxSpeedLKW;
     976      401973 :                 myMaxSpeedFactorPKW = MAX2(myMaxSpeedFactorPKW, speedFactorPKW);
     977      401973 :                 myMaxSpeedFactorLKW = MAX2(myMaxSpeedFactorLKW, speedFactorLKW);
     978      401973 :                 speedFactorCountPKW += srcFD.qPKW;
     979      401973 :                 speedFactorCountLKW += srcFD.qLKW;
     980      401973 :                 speedFactorSumPKW += srcFD.qPKW * speedFactorPKW;
     981      401973 :                 speedFactorSumLKW += srcFD.qLKW * speedFactorLKW;
     982      401973 :                 if (!didWarn && srcFD.vPKW > 0 && srcFD.vPKW < 255 && srcFD.vPKW / 3.6 > into->getSpeedLimit()) {
     983        1506 :                     WRITE_MESSAGE("Detected PKW speed (" + toString(srcFD.vPKW / 3.6, 3) + ") higher than allowed speed (" + toString(into->getSpeedLimit(), 3) + ") at '" + (*l) + "' on edge '" + into->getID() + "'.");
     984             :                     didWarn = true;
     985             :                 }
     986      401220 :                 if (!didWarn && srcFD.vLKW > 0 && srcFD.vLKW < 255 && srcFD.vLKW / 3.6 > into->getSpeedLimit()) {
     987          16 :                     WRITE_MESSAGE("Detected LKW speed (" + toString(srcFD.vLKW / 3.6, 3) + ") higher than allowed speed (" + toString(into->getSpeedLimit(), 3) + ") at '" + (*l) + "' on edge '" + into->getID() + "'.");
     988             :                     didWarn = true;
     989             :                 }
     990             :             }
     991             :         }
     992         817 :         static_cast<RODFEdge*>(into)->setFlows(mflows);
     993             :     }
     994             :     // @note: this assumes that the speedFactors are independent of location and time
     995         104 :     if (speedFactorCountPKW > 0) {
     996          99 :         myAvgSpeedFactorPKW = speedFactorSumPKW / speedFactorCountPKW;
     997         198 :         WRITE_MESSAGEF(TL("Average speedFactor for PKW is % maximum speedFactor is %."), toString(myAvgSpeedFactorPKW), toString(myMaxSpeedFactorPKW));
     998             :     }
     999         104 :     if (speedFactorCountLKW > 0) {
    1000          25 :         myAvgSpeedFactorLKW = speedFactorSumLKW / speedFactorCountLKW;
    1001          50 :         WRITE_MESSAGEF(TL("Average speedFactor for LKW is % maximum speedFactor is %."), toString(myAvgSpeedFactorLKW), toString(myMaxSpeedFactorLKW));
    1002             :     }
    1003             : 
    1004         104 : }
    1005             : 
    1006             : 
    1007             : void
    1008           0 : RODFNet::buildDetectorDependencies(RODFDetectorCon& detectors) {
    1009             :     // !!! this will not work when several detectors are lying on the same edge on different positions
    1010             : 
    1011             : 
    1012           0 :     buildDetectorEdgeDependencies(detectors);
    1013             :     // for each detector, compute the lists of predecessor and following detectors
    1014             :     std::map<std::string, ROEdge*>::const_iterator i;
    1015           0 :     for (i = myDetectorEdges.begin(); i != myDetectorEdges.end(); ++i) {
    1016           0 :         const RODFDetector& det = detectors.getDetector((*i).first);
    1017           0 :         if (!det.hasRoutes()) {
    1018           0 :             continue;
    1019             :         }
    1020             :         // mark current detectors
    1021             :         std::vector<RODFDetector*> last;
    1022             :         {
    1023           0 :             const std::vector<std::string>& detNames = myDetectorsOnEdges.find((*i).second)->second;
    1024           0 :             for (std::vector<std::string>::const_iterator j = detNames.begin(); j != detNames.end(); ++j) {
    1025           0 :                 last.push_back(&detectors.getModifiableDetector(*j));
    1026             :             }
    1027             :         }
    1028             :         // iterate over the current detector's routes
    1029           0 :         const std::vector<RODFRouteDesc>& routes = det.getRouteVector();
    1030           0 :         for (std::vector<RODFRouteDesc>::const_iterator j = routes.begin(); j != routes.end(); ++j) {
    1031             :             const ROEdgeVector& edges2Pass = (*j).edges2Pass;
    1032           0 :             for (ROEdgeVector::const_iterator k = edges2Pass.begin() + 1; k != edges2Pass.end(); ++k) {
    1033           0 :                 if (myDetectorsOnEdges.find(*k) != myDetectorsOnEdges.end()) {
    1034             :                     const std::vector<std::string>& detNames = myDetectorsOnEdges.find(*k)->second;
    1035             :                     // ok, consecutive detector found
    1036           0 :                     for (std::vector<RODFDetector*>::iterator l = last.begin(); l != last.end(); ++l) {
    1037             :                         // mark as follower of current
    1038           0 :                         for (std::vector<std::string>::const_iterator m = detNames.begin(); m != detNames.end(); ++m) {
    1039           0 :                             detectors.getModifiableDetector(*m).addPriorDetector(*l);
    1040           0 :                             (*l)->addFollowingDetector(&detectors.getDetector(*m));
    1041             :                         }
    1042             :                     }
    1043             :                     last.clear();
    1044           0 :                     for (std::vector<std::string>::const_iterator m = detNames.begin(); m != detNames.end(); ++m) {
    1045           0 :                         last.push_back(&detectors.getModifiableDetector(*m));
    1046             :                     }
    1047             :                 }
    1048             :             }
    1049             :         }
    1050             :     }
    1051           0 : }
    1052             : 
    1053             : 
    1054             : void
    1055           0 : RODFNet::mesoJoin(RODFDetectorCon& detectors, RODFDetectorFlows& flows) {
    1056           0 :     buildDetectorEdgeDependencies(detectors);
    1057             :     std::map<ROEdge*, std::vector<std::string>, idComp>::iterator i;
    1058           0 :     for (i = myDetectorsOnEdges.begin(); i != myDetectorsOnEdges.end(); ++i) {
    1059             :         const std::vector<std::string>& dets = (*i).second;
    1060             :         std::map<double, std::vector<std::string> > cliques;
    1061             :         // compute detector cliques
    1062           0 :         for (std::vector<std::string>::const_iterator j = dets.begin(); j != dets.end(); ++j) {
    1063           0 :             const RODFDetector& det = detectors.getDetector(*j);
    1064             :             bool found = false;
    1065           0 :             for (std::map<double, std::vector<std::string> >::iterator k = cliques.begin(); !found && k != cliques.end(); ++k) {
    1066           0 :                 if (fabs((*k).first - det.getPos()) < 10.) {
    1067           0 :                     (*k).second.push_back(*j);
    1068             :                     found = true;
    1069             :                 }
    1070             :             }
    1071           0 :             if (!found) {
    1072           0 :                 cliques[det.getPos()] = std::vector<std::string>();
    1073           0 :                 cliques[det.getPos()].push_back(*j);
    1074             :             }
    1075             :         }
    1076             :         // join detector cliques
    1077           0 :         for (std::map<double, std::vector<std::string> >::iterator m = cliques.begin(); m != cliques.end(); ++m) {
    1078           0 :             std::vector<std::string> clique = (*m).second;
    1079             :             // do not join if only one
    1080           0 :             if (clique.size() == 1) {
    1081             :                 continue;
    1082             :             }
    1083             :             std::string nid;
    1084           0 :             for (std::vector<std::string>::iterator n = clique.begin(); n != clique.end(); ++n) {
    1085           0 :                 std::cout << *n << " ";
    1086           0 :                 if (n != clique.begin()) {
    1087           0 :                     nid = nid + "_";
    1088             :                 }
    1089           0 :                 nid = nid + *n;
    1090             :             }
    1091             :             std::cout << ":" << nid << std::endl;
    1092           0 :             flows.mesoJoin(nid, (*m).second);
    1093           0 :             detectors.mesoJoin(nid, (*m).second);
    1094           0 :         }
    1095             :     }
    1096           0 : }
    1097             : 
    1098             : 
    1099             : /****************************************************************************/

Generated by: LCOV version 1.14