LCOV - code coverage report
Current view: top level - src/dfrouter - RODFNet.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 66.2 % 494 327
Test Date: 2024-12-21 15:45:41 Functions: 80.0 % 30 24

            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          436 : RODFNet::RODFNet(bool amInHighwayMode) :
      47          436 :     RONet(), myAmInHighwayMode(amInHighwayMode),
      48          436 :     mySourceNumber(0), mySinkNumber(0), myInBetweenNumber(0), myInvalidNumber(0),
      49          436 :     myMaxSpeedFactorPKW(1),
      50          436 :     myMaxSpeedFactorLKW(1),
      51          436 :     myAvgSpeedFactorPKW(1),
      52          436 :     myAvgSpeedFactorLKW(1) {
      53          436 :     myDisallowedEdges = OptionsCont::getOptions().getStringVector("disallowed-edges");
      54          436 :     myAllowedVClass = getVehicleClassID(OptionsCont::getOptions().getString("vclass"));
      55          436 :     myKeepTurnarounds = OptionsCont::getOptions().getBool("keep-turnarounds");
      56          436 : }
      57              : 
      58              : 
      59          872 : RODFNet::~RODFNet() {
      60         1308 : }
      61              : 
      62              : 
      63              : bool
      64         6896 : RODFNet::isAllowed(const ROEdge* const edge) const {
      65         6166 :     return (!edge->isInternal() && !edge->isWalkingArea() && !edge->isCrossing() &&
      66         6166 :             (edge->getPermissions() & myAllowedVClass) == myAllowedVClass &&
      67         6164 :             find(myDisallowedEdges.begin(), myDisallowedEdges.end(), edge->getID()) == myDisallowedEdges.end());
      68              : 
      69              : }
      70              : 
      71              : 
      72              : void
      73          200 : RODFNet::buildApproachList() {
      74         3753 :     for (const auto& rit : getEdgeMap()) {
      75         3553 :         ROEdge* const ce = rit.second;
      76         3553 :         if (!isAllowed(ce)) {
      77          746 :             continue;
      78              :         }
      79         6150 :         for (ROEdge* const help : ce->getSuccessors()) {
      80         3343 :             if (!isAllowed(help)) {
      81              :                 // blocked edges will not be used
      82           22 :                 continue;
      83              :             }
      84         3321 :             if (!myKeepTurnarounds && help->getToJunction() == ce->getFromJunction()) {
      85              :                 // do not use turnarounds
      86           98 :                 continue;
      87              :             }
      88              :             // add the connection help->ce to myApproachingEdges
      89         3223 :             myApproachingEdges[help].push_back(ce);
      90              :             // add the connection ce->help to myApproachingEdges
      91         3223 :             myApproachedEdges[ce].push_back(help);
      92              :         }
      93              :     }
      94          200 : }
      95              : 
      96              : 
      97              : void
      98          332 : RODFNet::buildDetectorEdgeDependencies(RODFDetectorCon& detcont) const {
      99              :     myDetectorsOnEdges.clear();
     100              :     myDetectorEdges.clear();
     101          332 :     const std::vector<RODFDetector*>& dets = detcont.getDetectors();
     102         3212 :     for (std::vector<RODFDetector*>::const_iterator i = dets.begin(); i != dets.end(); ++i) {
     103         2880 :         ROEdge* e = getDetectorEdge(**i);
     104         2880 :         myDetectorsOnEdges[e].push_back((*i)->getID());
     105         2880 :         myDetectorEdges[(*i)->getID()] = e;
     106              :     }
     107          332 : }
     108              : 
     109              : 
     110              : void
     111          164 : RODFNet::computeTypes(RODFDetectorCon& detcont,
     112              :                       bool sourcesStrict) const {
     113          328 :     PROGRESS_BEGIN_MESSAGE(TL("Computing detector types"));
     114          164 :     const std::vector< RODFDetector*>& dets = detcont.getDetectors();
     115              :     // build needed information. first
     116          164 :     buildDetectorEdgeDependencies(detcont);
     117              :     // compute detector types then
     118         1532 :     for (std::vector< RODFDetector*>::const_iterator i = dets.begin(); i != dets.end(); ++i) {
     119         1368 :         if (isSource(**i, detcont, sourcesStrict)) {
     120          319 :             (*i)->setType(SOURCE_DETECTOR);
     121          319 :             mySourceNumber++;
     122              :         }
     123         1368 :         if (isDestination(**i, detcont)) {
     124          236 :             (*i)->setType(SINK_DETECTOR);
     125          236 :             mySinkNumber++;
     126              :         }
     127         1368 :         if ((*i)->getType() == TYPE_NOT_DEFINED) {
     128          843 :             (*i)->setType(BETWEEN_DETECTOR);
     129          843 :             myInBetweenNumber++;
     130              :         }
     131              :     }
     132              :     // recheck sources
     133         1532 :     for (std::vector< RODFDetector*>::const_iterator i = dets.begin(); i != dets.end(); ++i) {
     134         1368 :         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          164 :     PROGRESS_DONE_MESSAGE();
     142          164 :     WRITE_MESSAGE(TL("Computed detector types:"));
     143          328 :     WRITE_MESSAGEF(TL(" % source detectors"), toString(mySourceNumber));
     144          328 :     WRITE_MESSAGEF(TL(" % sink detectors"), toString(mySinkNumber));
     145          328 :     WRITE_MESSAGEF(TL(" % in-between detectors"), toString(myInBetweenNumber));
     146          328 :     WRITE_MESSAGEF(TL(" % invalid detectors"), toString(myInvalidNumber));
     147          164 : }
     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         1232 : 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         1232 :     dets2Follow[edge] = ROEdgeVector();
     196         1232 :     base.passedNo = 0;
     197         1232 :     double minDist = OptionsCont::getOptions().getFloat("min-route-length");
     198         1232 :     toSolve.push(base);
     199         6772 :     while (!toSolve.empty()) {
     200         5540 :         RODFRouteDesc current = toSolve.top();
     201         5540 :         toSolve.pop();
     202         5540 :         ROEdge* last = *(current.edges2Pass.end() - 1);
     203         5540 :         if (hasDetector(last)) {
     204         4407 :             if (dets2Follow.find(last) == dets2Follow.end()) {
     205         2970 :                 dets2Follow[last] = ROEdgeVector();
     206              :             }
     207         4993 :             for (ROEdgeVector::reverse_iterator i = current.edges2Pass.rbegin() + 1; i != current.edges2Pass.rend(); ++i) {
     208         3761 :                 if (hasDetector(*i)) {
     209         3175 :                     dets2Follow[*i].push_back(last);
     210              :                     break;
     211              :                 }
     212              :             }
     213              :         }
     214              : 
     215              :         // do not process an edge twice
     216         5540 :         if (find(seen.begin(), seen.end(), last) != seen.end() && keepShortestOnly) {
     217          116 :             continue;
     218              :         }
     219         5424 :         seen.push_back(last);
     220              :         // end if the edge has no further connections
     221         5424 :         if (!hasApproached(last)) {
     222              :             // ok, no further connections to follow
     223          583 :             current.factor = 1.;
     224          583 :             double cdist = current.edges2Pass[0]->getFromJunction()->getPosition().distanceTo(current.edges2Pass.back()->getToJunction()->getPosition());
     225          583 :             if (minDist < cdist) {
     226          579 :                 into.addRouteDesc(current);
     227              :             }
     228          583 :             continue;
     229          583 :         }
     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         4841 :         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         3417 :         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         3417 :             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         7818 :         for (int i = 0; i < (int)appr.size(); i++) {
     295         4401 :             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         4308 :             RODFRouteDesc t(current);
     300         4308 :             t.duration_2 += (appr[i]->getLength() / appr[i]->getSpeedLimit()); //!!!
     301         4308 :             t.distance += appr[i]->getLength();
     302         4308 :             t.edges2Pass.push_back(appr[i]);
     303         4308 :             if (!addNextNoFurther) {
     304         4308 :                 t.passedNo++;
     305         4308 :                 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              :         }
     317              :     }
     318              :     //
     319         1232 :     if (!keepUnfoundEnds) {
     320              :         std::vector<RODFRouteDesc>::iterator i;
     321              :         ConstROEdgeVector lastDetEdges;
     322         1232 :         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         1232 :     } else {
     332              :         // !!! patch the factors
     333              :     }
     334         1232 :     while (!toSolve.empty()) {
     335              : //        RODFRouteDesc d = toSolve.top();
     336            0 :         toSolve.pop();
     337              : //        delete d;
     338              :     }
     339         1232 : }
     340              : 
     341              : 
     342              : void
     343          168 : RODFNet::buildRoutes(RODFDetectorCon& detcont, bool keepUnfoundEnds, bool includeInBetween,
     344              :                      bool keepShortestOnly, int maxFollowingLength) const {
     345              :     // build needed information first
     346          168 :     buildDetectorEdgeDependencies(detcont);
     347              :     // then build the routes
     348              :     std::map<ROEdge*, RODFRouteCont* > doneEdges;
     349          168 :     const std::vector< RODFDetector*>& dets = detcont.getDetectors();
     350         1680 :     for (std::vector< RODFDetector*>::const_iterator i = dets.begin(); i != dets.end(); ++i) {
     351         1512 :         ROEdge* e = getDetectorEdge(**i);
     352         1512 :         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         1232 :         RODFRouteCont* routes = new RODFRouteCont();
     359         1232 :         doneEdges[e] = routes;
     360              :         RODFRouteDesc rd;
     361         1232 :         rd.edges2Pass.push_back(e);
     362         1232 :         rd.duration_2 = (e->getLength() / e->getSpeedLimit()); //!!!;
     363         1232 :         rd.endDetectorEdge = nullptr;
     364         1232 :         rd.lastDetectorEdge = nullptr;
     365         1232 :         rd.distance = e->getLength();
     366         1232 :         rd.distance2Last = 0;
     367         1232 :         rd.duration2Last = 0;
     368              : 
     369         1232 :         rd.overallProb = 0;
     370              : 
     371              :         ROEdgeVector visited;
     372         1232 :         visited.push_back(e);
     373         1232 :         computeRoutesFor(e, rd, 0, keepUnfoundEnds, keepShortestOnly,
     374              :                          visited, **i, *routes, detcont, maxFollowingLength, seen);
     375              :         //!!!routes->removeIllegal(illegals);
     376         1232 :         (*i)->addRoutes(routes);
     377              : 
     378              :         // add routes to in-between detectors if wished
     379         1232 :         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              :                         }
     411              :                     }
     412           12 :                     duration -= (*k)->getLength() / (*k)->getSpeedLimit();
     413           12 :                     distance -= (*k)->getLength();
     414              :                 }
     415              :             }
     416              :         }
     417              : 
     418         2464 :     }
     419          168 : }
     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            0 :         }
     466            0 :         if (maxDepthReached) {
     467            0 :             WRITE_WARNING(TL(" Could not build list of previous flows."));
     468              :         }
     469            0 :     }
     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            0 :         }
     503            0 :         if (maxDepthReached) {
     504            0 :             WRITE_WARNING(TL(" Could not build list of latter flows."));
     505              :             return;
     506              :         }
     507            0 :     }
     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            0 : }
     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           21 :             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           21 :             WRITE_MESSAGEF(TL("Detector '%' has no flow."), (*i)->getID());
     615              :         }
     616              :     }
     617            7 : }
     618              : 
     619              : 
     620              : 
     621              : ROEdge*
     622        27265 : RODFNet::getDetectorEdge(const RODFDetector& det) const {
     623        54530 :     const std::string edgeName = SUMOXMLDefinitions::getEdgeIDFromLane(det.getLaneID());
     624              :     ROEdge* ret = getEdge(edgeName);
     625        27265 :     if (ret == nullptr) {
     626            0 :         throw ProcessError("Edge '" + edgeName + "' used by detector '" + det.getID() + "' is not known.");
     627              :     }
     628        27265 :     return ret;
     629              : }
     630              : 
     631              : 
     632              : bool
     633         3407 : RODFNet::hasApproaching(ROEdge* edge) const {
     634              :     return myApproachingEdges.find(edge) != myApproachingEdges.end()
     635         6099 :            && myApproachingEdges.find(edge)->second.size() != 0;
     636              : }
     637              : 
     638              : 
     639              : bool
     640         8195 : RODFNet::hasApproached(ROEdge* edge) const {
     641              :     return myApproachedEdges.find(edge) != myApproachedEdges.end()
     642        15493 :            && myApproachedEdges.find(edge)->second.size() != 0;
     643              : }
     644              : 
     645              : 
     646              : bool
     647      1472550 : RODFNet::hasDetector(ROEdge* edge) const {
     648              :     return myDetectorsOnEdges.find(edge) != myDetectorsOnEdges.end()
     649      1472550 :            && 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         1368 : RODFNet::isSource(const RODFDetector& det, const RODFDetectorCon& detectors,
     669              :                   bool strict) const {
     670              :     ROEdgeVector seen;
     671         2736 :     return isSource(det, getDetectorEdge(det), seen, detectors, strict);
     672         1368 : }
     673              : 
     674              : bool
     675          289 : RODFNet::isFalseSource(const RODFDetector& det, const RODFDetectorCon& detectors) const {
     676              :     ROEdgeVector seen;
     677          578 :     return isFalseSource(det, getDetectorEdge(det), seen, detectors);
     678          289 : }
     679              : 
     680              : bool
     681         1368 : RODFNet::isDestination(const RODFDetector& det, const RODFDetectorCon& detectors) const {
     682              :     ROEdgeVector seen;
     683         2736 :     return isDestination(det, getDetectorEdge(det), seen, detectors);
     684         1368 : }
     685              : 
     686              : 
     687              : bool
     688         3457 : RODFNet::isSource(const RODFDetector& det, ROEdge* edge,
     689              :                   ROEdgeVector& seen,
     690              :                   const RODFDetectorCon& detectors,
     691              :                   bool strict) const {
     692         3457 :     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         3457 :     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         3210 :         for (std::vector<std::string>::const_iterator i = detsOnEdge.begin(); i != detsOnEdge.end(); ++i) {
     701         1892 :             if ((*i) == det.getID()) {
     702         1352 :                 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         3407 :     if (!hasApproaching(edge)) {
     714          715 :         if (edge != getDetectorEdge(det)) {
     715          543 :             if (hasDetector(edge)) {
     716              :                 return false;
     717              :             }
     718              :         }
     719              :         return true;
     720              :     }
     721         2692 :     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         2692 :     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         2692 :             &&
     757         2230 :             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         1608 :     seen.push_back(edge);
     767         3808 :     for (int i = 0; i < (int)appr.size(); i++) {
     768         2200 :         bool had = std::find(seen.begin(), seen.end(), appr[i]) != seen.end();
     769         2200 :         if (!had) {
     770         2089 :             if (isSource(det, appr[i], seen, detectors, strict)) {
     771          346 :                 numOk++;
     772              :             } else {
     773         1743 :                 numFalse++;
     774              :             }
     775              :         } else {
     776          111 :             numSkipped++;
     777              :         }
     778              :     }
     779         1608 :     if (strict) {
     780            0 :         return numOk + numSkipped == (int)appr.size();
     781              :     }
     782         1608 :     return numFalse + numSkipped != (int)appr.size();
     783              : }
     784              : 
     785              : 
     786              : bool
     787         2821 : RODFNet::isDestination(const RODFDetector& det, ROEdge* edge, ROEdgeVector& seen,
     788              :                        const RODFDetectorCon& detectors) const {
     789         2821 :     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         2821 :     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         3174 :         for (std::vector<std::string>::const_iterator i = detsOnEdge.begin(); i != detsOnEdge.end(); ++i) {
     798         1856 :             if ((*i) == det.getID()) {
     799         1334 :                 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         2771 :     if (!hasApproached(edge)) {
     810          314 :         if (edge != getDetectorEdge(det)) {
     811          261 :             if (hasDetector(edge)) {
     812              :                 return false;
     813              :             }
     814              :         }
     815              :         return true;
     816              :     }
     817         2457 :     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         2457 :     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         2457 :             &&
     843         2298 :             myDetectorEdges.find(det.getID())->second != edge) {
     844              :         return false;
     845              :     }
     846              :     const ROEdgeVector& appr  = myApproachedEdges.find(edge)->second;
     847              :     bool isall = true;
     848         1424 :     seen.push_back(edge);
     849         2878 :     for (int i = 0; i < (int)appr.size() && isall; i++) {
     850         1454 :         bool had = std::find(seen.begin(), seen.end(), appr[i]) != seen.end();
     851         1454 :         if (!had) {
     852         1453 :             if (!isDestination(det, appr[i], seen, detectors)) {
     853              :                 isall = false;
     854              :             }
     855              :         }
     856              :     }
     857              :     return isall;
     858              : }
     859              : 
     860              : bool
     861         1315 : RODFNet::isFalseSource(const RODFDetector& det, ROEdge* edge, ROEdgeVector& seen,
     862              :                        const RODFDetectorCon& detectors) const {
     863         1315 :     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         1315 :     seen.push_back(edge);
     868         1315 :     if (edge != getDetectorEdge(det)) {
     869              :         // ok, we are at one of the edges coming behind
     870         1026 :         if (hasDetector(edge)) {
     871              :             const std::vector<std::string>& dets = myDetectorsOnEdges.find(edge)->second;
     872          602 :             for (std::vector<std::string>::const_iterator i = dets.begin(); i != dets.end(); ++i) {
     873          602 :                 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          713 :     if (myApproachedEdges.find(edge) == myApproachedEdges.end()) {
     891              :         return false;
     892              :     }
     893              : 
     894              :     const ROEdgeVector& appr  = myApproachedEdges.find(edge)->second;
     895              :     bool isall = false;
     896         1783 :     for (int i = 0; i < (int)appr.size() && !isall; i++) {
     897              :         //printf("checking %s->\n", appr[i].c_str());
     898         1118 :         bool had = std::find(seen.begin(), seen.end(), appr[i]) != seen.end();
     899         1118 :         if (!had) {
     900         1026 :             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          899 :             for (auto& k : cliques) {
     934           82 :                 if (fabs(k.first - det.getPos()) < 1) {
     935           82 :                     k.second.push_back(*j);
     936           82 :                     if (maxClique == nullptr || k.second.size() > maxClique->size()) {
     937              :                         maxClique = &k.second;
     938              :                     }
     939              :                     found = true;
     940              :                     break;
     941              :                 }
     942              :             }
     943          899 :             if (!found) {
     944          817 :                 cliques[det.getPos()].push_back(*j);
     945          817 :                 maxClique = &cliques[det.getPos()];
     946              :             }
     947              :         }
     948          902 :         if (maxClique == nullptr) {
     949              :             continue;
     950              :         }
     951              :         std::vector<FlowDef> mflows; // !!! reserve
     952       310610 :         for (SUMOTime t = startTime; t < endTime; t += stepOffset) {
     953              :             FlowDef fd;
     954       309793 :             fd.qPKW = 0;
     955       309793 :             fd.qLKW = 0;
     956       309793 :             fd.vLKW = 0;
     957       309793 :             fd.vPKW = 0;
     958       309793 :             fd.fLKW = 0;
     959       309793 :             fd.isLKW = 0;
     960       309793 :             mflows.push_back(fd);
     961              :         }
     962         1716 :         for (std::vector<std::string>::iterator l = maxClique->begin(); l != maxClique->end(); ++l) {
     963              :             bool didWarn = false;
     964          899 :             const std::vector<FlowDef>& dflows = flows.getFlowDefs(*l);
     965              :             int index = 0;
     966       402872 :             for (SUMOTime t = startTime; t < endTime; t += stepOffset, index++) {
     967       401973 :                 const FlowDef& srcFD = dflows[index];
     968              :                 FlowDef& fd = mflows[index];
     969       401973 :                 fd.qPKW += srcFD.qPKW;
     970       401973 :                 fd.qLKW += srcFD.qLKW;
     971       401973 :                 fd.vLKW += srcFD.vLKW / (double) maxClique->size();
     972       401973 :                 fd.vPKW += srcFD.vPKW / (double) maxClique->size();
     973       401973 :                 fd.fLKW += srcFD.fLKW / (double) maxClique->size();
     974       401973 :                 fd.isLKW += srcFD.isLKW / (double) maxClique->size();
     975       401973 :                 const double speedFactorPKW = srcFD.vPKW / 3.6 / maxSpeedPKW;
     976       401973 :                 const double speedFactorLKW = srcFD.vLKW / 3.6 / maxSpeedLKW;
     977       401973 :                 myMaxSpeedFactorPKW = MAX2(myMaxSpeedFactorPKW, speedFactorPKW);
     978       401973 :                 myMaxSpeedFactorLKW = MAX2(myMaxSpeedFactorLKW, speedFactorLKW);
     979       401973 :                 speedFactorCountPKW += srcFD.qPKW;
     980       401973 :                 speedFactorCountLKW += srcFD.qLKW;
     981       401973 :                 speedFactorSumPKW += srcFD.qPKW * speedFactorPKW;
     982       401973 :                 speedFactorSumLKW += srcFD.qLKW * speedFactorLKW;
     983       401973 :                 if (!didWarn && srcFD.vPKW > 0 && srcFD.vPKW < 255 && srcFD.vPKW / 3.6 > into->getSpeedLimit()) {
     984         3012 :                     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() + "'.");
     985              :                     didWarn = true;
     986              :                 }
     987       401220 :                 if (!didWarn && srcFD.vLKW > 0 && srcFD.vLKW < 255 && srcFD.vLKW / 3.6 > into->getSpeedLimit()) {
     988           32 :                     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() + "'.");
     989              :                     didWarn = true;
     990              :                 }
     991              :             }
     992              :         }
     993          817 :         static_cast<RODFEdge*>(into)->setFlows(mflows);
     994          817 :     }
     995              :     // @note: this assumes that the speedFactors are independent of location and time
     996          104 :     if (speedFactorCountPKW > 0) {
     997           99 :         myAvgSpeedFactorPKW = speedFactorSumPKW / speedFactorCountPKW;
     998          198 :         WRITE_MESSAGEF(TL("Average speedFactor for PKW is % maximum speedFactor is %."), toString(myAvgSpeedFactorPKW), toString(myMaxSpeedFactorPKW));
     999              :     }
    1000          104 :     if (speedFactorCountLKW > 0) {
    1001           25 :         myAvgSpeedFactorLKW = speedFactorSumLKW / speedFactorCountLKW;
    1002           50 :         WRITE_MESSAGEF(TL("Average speedFactor for LKW is % maximum speedFactor is %."), toString(myAvgSpeedFactorLKW), toString(myMaxSpeedFactorLKW));
    1003              :     }
    1004              : 
    1005          104 : }
    1006              : 
    1007              : 
    1008              : void
    1009            0 : RODFNet::buildDetectorDependencies(RODFDetectorCon& detectors) {
    1010              :     // !!! this will not work when several detectors are lying on the same edge on different positions
    1011              : 
    1012              : 
    1013            0 :     buildDetectorEdgeDependencies(detectors);
    1014              :     // for each detector, compute the lists of predecessor and following detectors
    1015              :     std::map<std::string, ROEdge*>::const_iterator i;
    1016            0 :     for (i = myDetectorEdges.begin(); i != myDetectorEdges.end(); ++i) {
    1017            0 :         const RODFDetector& det = detectors.getDetector((*i).first);
    1018            0 :         if (!det.hasRoutes()) {
    1019            0 :             continue;
    1020              :         }
    1021              :         // mark current detectors
    1022              :         std::vector<RODFDetector*> last;
    1023              :         {
    1024            0 :             const std::vector<std::string>& detNames = myDetectorsOnEdges.find((*i).second)->second;
    1025            0 :             for (std::vector<std::string>::const_iterator j = detNames.begin(); j != detNames.end(); ++j) {
    1026            0 :                 last.push_back(&detectors.getModifiableDetector(*j));
    1027              :             }
    1028              :         }
    1029              :         // iterate over the current detector's routes
    1030            0 :         const std::vector<RODFRouteDesc>& routes = det.getRouteVector();
    1031            0 :         for (std::vector<RODFRouteDesc>::const_iterator j = routes.begin(); j != routes.end(); ++j) {
    1032              :             const ROEdgeVector& edges2Pass = (*j).edges2Pass;
    1033            0 :             for (ROEdgeVector::const_iterator k = edges2Pass.begin() + 1; k != edges2Pass.end(); ++k) {
    1034            0 :                 if (myDetectorsOnEdges.find(*k) != myDetectorsOnEdges.end()) {
    1035              :                     const std::vector<std::string>& detNames = myDetectorsOnEdges.find(*k)->second;
    1036              :                     // ok, consecutive detector found
    1037            0 :                     for (std::vector<RODFDetector*>::iterator l = last.begin(); l != last.end(); ++l) {
    1038              :                         // mark as follower of current
    1039            0 :                         for (std::vector<std::string>::const_iterator m = detNames.begin(); m != detNames.end(); ++m) {
    1040            0 :                             detectors.getModifiableDetector(*m).addPriorDetector(*l);
    1041            0 :                             (*l)->addFollowingDetector(&detectors.getDetector(*m));
    1042              :                         }
    1043              :                     }
    1044              :                     last.clear();
    1045            0 :                     for (std::vector<std::string>::const_iterator m = detNames.begin(); m != detNames.end(); ++m) {
    1046            0 :                         last.push_back(&detectors.getModifiableDetector(*m));
    1047              :                     }
    1048              :                 }
    1049              :             }
    1050              :         }
    1051            0 :     }
    1052            0 : }
    1053              : 
    1054              : 
    1055              : void
    1056            0 : RODFNet::mesoJoin(RODFDetectorCon& detectors, RODFDetectorFlows& flows) {
    1057            0 :     buildDetectorEdgeDependencies(detectors);
    1058              :     std::map<ROEdge*, std::vector<std::string>, idComp>::iterator i;
    1059            0 :     for (i = myDetectorsOnEdges.begin(); i != myDetectorsOnEdges.end(); ++i) {
    1060              :         const std::vector<std::string>& dets = (*i).second;
    1061              :         std::map<double, std::vector<std::string> > cliques;
    1062              :         // compute detector cliques
    1063            0 :         for (std::vector<std::string>::const_iterator j = dets.begin(); j != dets.end(); ++j) {
    1064            0 :             const RODFDetector& det = detectors.getDetector(*j);
    1065              :             bool found = false;
    1066            0 :             for (std::map<double, std::vector<std::string> >::iterator k = cliques.begin(); !found && k != cliques.end(); ++k) {
    1067            0 :                 if (fabs((*k).first - det.getPos()) < 10.) {
    1068            0 :                     (*k).second.push_back(*j);
    1069              :                     found = true;
    1070              :                 }
    1071              :             }
    1072            0 :             if (!found) {
    1073            0 :                 cliques[det.getPos()] = std::vector<std::string>();
    1074            0 :                 cliques[det.getPos()].push_back(*j);
    1075              :             }
    1076              :         }
    1077              :         // join detector cliques
    1078            0 :         for (std::map<double, std::vector<std::string> >::iterator m = cliques.begin(); m != cliques.end(); ++m) {
    1079            0 :             std::vector<std::string> clique = (*m).second;
    1080              :             // do not join if only one
    1081            0 :             if (clique.size() == 1) {
    1082              :                 continue;
    1083              :             }
    1084              :             std::string nid;
    1085            0 :             for (std::vector<std::string>::iterator n = clique.begin(); n != clique.end(); ++n) {
    1086            0 :                 std::cout << *n << " ";
    1087            0 :                 if (n != clique.begin()) {
    1088            0 :                     nid = nid + "_";
    1089              :                 }
    1090            0 :                 nid = nid + *n;
    1091              :             }
    1092              :             std::cout << ":" << nid << std::endl;
    1093            0 :             flows.mesoJoin(nid, (*m).second);
    1094            0 :             detectors.mesoJoin(nid, (*m).second);
    1095            0 :         }
    1096              :     }
    1097            0 : }
    1098              : 
    1099              : 
    1100              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1