LCOV - code coverage report
Current view: top level - src/netload - NLDetectorBuilder.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 88.9 % 208 185
Test Date: 2024-11-23 15:47:30 Functions: 96.3 % 27 26

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2002-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    NLDetectorBuilder.cpp
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Laura Bieker
      17              : /// @author  Clemens Honomichl
      18              : /// @author  Michael Behrisch
      19              : /// @author  Christian Roessel
      20              : /// @author  Jakob Erdmann
      21              : /// @date    Mon, 15 Apr 2002
      22              : ///
      23              : // Builds detectors for microsim
      24              : /****************************************************************************/
      25              : #include <config.h>
      26              : 
      27              : #include <string>
      28              : #include <iostream>
      29              : #include <microsim/MSNet.h>
      30              : #include <microsim/MSLane.h>
      31              : #include <microsim/MSEdge.h>
      32              : #include <microsim/output/MSInductLoop.h>
      33              : #include <microsim/output/MSE2Collector.h>
      34              : // #include <microsim/output/MSMultiLaneE2Collector.h>
      35              : #include <microsim/output/MSVTypeProbe.h>
      36              : #include <microsim/output/MSRouteProbe.h>
      37              : #include <microsim/output/MSMeanData_Net.h>
      38              : #include <microsim/output/MSMeanData_Emissions.h>
      39              : #include <microsim/output/MSMeanData_Harmonoise.h>
      40              : #include <microsim/output/MSMeanData_Amitran.h>
      41              : #include <microsim/output/MSInstantInductLoop.h>
      42              : #include <microsim/MSGlobals.h>
      43              : #include <microsim/actions/Command_SaveTLCoupledDet.h>
      44              : #include <microsim/actions/Command_SaveTLCoupledLaneDet.h>
      45              : #include <utils/common/UtilExceptions.h>
      46              : #include <utils/common/FileHelpers.h>
      47              : #include <utils/common/StringUtils.h>
      48              : #include <utils/common/StringTokenizer.h>
      49              : #include <utils/common/StringUtils.h>
      50              : #include "NLDetectorBuilder.h"
      51              : #include <microsim/output/MSDetectorControl.h>
      52              : 
      53              : #include <mesosim/MEInductLoop.h>
      54              : #include <mesosim/MELoop.h>
      55              : #include <mesosim/MESegment.h>
      56              : 
      57              : 
      58              : // ===========================================================================
      59              : // method definitions
      60              : // ===========================================================================
      61              : /* -------------------------------------------------------------------------
      62              :  * NLDetectorBuilder::E3DetectorDefinition-methods
      63              :  * ----------------------------------------------------------------------- */
      64         1369 : NLDetectorBuilder::E3DetectorDefinition::E3DetectorDefinition(const std::string& id,
      65              :         const std::string& device, double haltingSpeedThreshold,
      66              :         SUMOTime haltingTimeThreshold, SUMOTime splInterval,
      67              :         const std::string name, const std::string& vTypes,
      68              :         const std::string& nextEdges,
      69         1369 :         int detectPersons, bool openEntry, bool expectArrival) :
      70         1369 :     myID(id), myDevice(device),
      71         1369 :     myHaltingSpeedThreshold(haltingSpeedThreshold),
      72         1369 :     myHaltingTimeThreshold(haltingTimeThreshold),
      73         1369 :     mySampleInterval(splInterval),
      74         1369 :     myName(name),
      75         1369 :     myVehicleTypes(vTypes),
      76         1369 :     myNextEdges(nextEdges),
      77         1369 :     myDetectPersons(detectPersons),
      78         1369 :     myOpenEntry(openEntry),
      79         1369 :     myExpectArrival(expectArrival) {
      80         1369 : }
      81              : 
      82              : 
      83         2738 : NLDetectorBuilder::E3DetectorDefinition::~E3DetectorDefinition() {}
      84              : 
      85              : 
      86              : /* -------------------------------------------------------------------------
      87              :  * NLDetectorBuilder-methods
      88              :  * ----------------------------------------------------------------------- */
      89        43044 : NLDetectorBuilder::NLDetectorBuilder(MSNet& net)
      90        43044 :     : myNet(net), myE3Definition(nullptr) {}
      91              : 
      92              : 
      93        43044 : NLDetectorBuilder::~NLDetectorBuilder() {
      94        43044 :     delete myE3Definition;
      95        43044 : }
      96              : 
      97              : 
      98              : Parameterised*
      99        20986 : NLDetectorBuilder::buildInductLoop(const std::string& id,
     100              :                                    const std::string& lane, double pos, double length, SUMOTime splInterval,
     101              :                                    const std::string& device, bool friendlyPos,
     102              :                                    const std::string name,
     103              :                                    const std::string& vTypes,
     104              :                                    const std::string& nextEdges,
     105              :                                    int detectPersons) {
     106        20986 :     checkSampleInterval(splInterval, SUMO_TAG_E1DETECTOR, id);
     107              :     // get and check the lane
     108        20980 :     MSLane* clane = getLaneChecking(lane, SUMO_TAG_E1DETECTOR, id);
     109              :     // get and check the position
     110        20961 :     pos = getPositionChecking(pos, clane, friendlyPos, SUMO_TAG_E1DETECTOR, id);
     111        20955 :     if (length < 0) {
     112            0 :         throw InvalidArgument("The length of " + toString(SUMO_TAG_E1DETECTOR) + " '" + id + "' cannot be negative");
     113        20955 :     } else if (length > 0 && pos + length > clane->getLength()) {
     114            6 :         if (friendlyPos) {
     115              :             length = MIN2(length, clane->getLength());
     116            6 :             pos = clane->getLength() - length;
     117              :         } else {
     118            0 :             throw InvalidArgument("The length of " + toString(SUMO_TAG_E1DETECTOR) + " '" + id + "' puts it beyond the lane's '" + clane->getID() + "' end.");
     119              :         }
     120              :     }
     121              :     // build the loop
     122        20955 :     MSDetectorFileOutput* loop = createInductLoop(id, clane, pos, length, name, vTypes, nextEdges, detectPersons, true);
     123              :     // add the file output
     124        20949 :     myNet.getDetectorControl().add(SUMO_TAG_INDUCTION_LOOP, loop, device, splInterval);
     125        20943 :     return loop;
     126              : }
     127              : 
     128              : 
     129              : Parameterised*
     130          855 : NLDetectorBuilder::buildInstantInductLoop(const std::string& id,
     131              :         const std::string& lane, double pos,
     132              :         const std::string& device, bool friendlyPos,
     133              :         const std::string name,
     134              :         const std::string& vTypes,
     135              :         const std::string& nextEdges) {
     136              :     // get and check the lane
     137          855 :     MSLane* clane = getLaneChecking(lane, SUMO_TAG_INSTANT_INDUCTION_LOOP, id);
     138              :     // get and check the position
     139          851 :     pos = getPositionChecking(pos, clane, friendlyPos, SUMO_TAG_INSTANT_INDUCTION_LOOP, id);
     140              :     // build the loop
     141          847 :     MSDetectorFileOutput* loop = createInstantInductLoop(id, clane, pos, device, name, vTypes, nextEdges);
     142              :     // add the file output
     143          843 :     myNet.getDetectorControl().add(SUMO_TAG_INSTANT_INDUCTION_LOOP, loop);
     144          843 :     return loop;
     145              : }
     146              : 
     147              : 
     148              : Parameterised*
     149         3021 : NLDetectorBuilder::buildE2Detector(const std::string& id, MSLane* lane, double pos, double endPos, double length,
     150              :                                    const std::string& device, SUMOTime frequency,
     151              :                                    SUMOTime haltingTimeThreshold, double haltingSpeedThreshold, double jamDistThreshold,
     152              :                                    const std::string name, const std::string& vTypes,
     153              :                                    const std::string& nextEdges,
     154              :                                    int detectPersons, bool friendlyPos, bool showDetector,
     155              :                                    MSTLLogicControl::TLSLogicVariants* tlls, MSLane* toLane) {
     156              : 
     157              :     bool tlsGiven = tlls != nullptr;
     158              :     bool toLaneGiven = toLane != nullptr;
     159              :     bool posGiven = pos != std::numeric_limits<double>::max();
     160              :     bool endPosGiven = endPos != std::numeric_limits<double>::max();
     161              : 
     162              :     assert(posGiven || endPosGiven);
     163              : 
     164              :     // Check positioning
     165         3021 :     if (posGiven) {
     166         2449 :         if (pos >= lane->getLength() || (pos < 0 && -pos > lane->getLength())) {
     167            7 :             std::stringstream ss;
     168              :             ss << "The given position (=" << pos << ") for detector '" << id
     169              :                << "' does not lie on the given lane '" << lane->getID()
     170              :                << "' with length " << lane->getLength();
     171            7 :             if (friendlyPos) {
     172            3 :                 double newPos = pos > 0 ? lane->getLength() - POSITION_EPS : 0.;
     173              :                 ss << " (adjusting to new position " << newPos;
     174            3 :                 WRITE_WARNING(ss.str());
     175              :                 pos = newPos;
     176              :             } else {
     177            4 :                 ss << " (0 <= pos < lane->getLength() is required)";
     178            8 :                 throw InvalidArgument(ss.str());
     179              :             }
     180            7 :         }
     181              :     }
     182         3017 :     if (endPosGiven) {
     183          594 :         if (endPos > lane->getLength() || (endPos <= 0 && -endPos >= lane->getLength())) {
     184            0 :             std::stringstream ss;
     185              :             ss << "The given end position (=" << endPos << ") for detector '" << id
     186              :                << "' does not lie on the given lane '" << lane->getID()
     187              :                << "' with length " << lane->getLength();
     188            0 :             if (friendlyPos) {
     189            0 :                 double newEndPos = endPos > 0 ? lane->getLength() : POSITION_EPS;
     190              :                 ss << " (adjusting to new position " << newEndPos;
     191            0 :                 WRITE_WARNING(ss.str());
     192              :                 pos = newEndPos;
     193              :             } else {
     194            0 :                 ss << " (0 <= pos < lane->getLength() is required)";
     195            0 :                 throw InvalidArgument(ss.str());
     196              :             }
     197            0 :         }
     198              :     }
     199              : 
     200              :     MSE2Collector* det = nullptr;
     201         3017 :     if (tlsGiven) {
     202              :         // Detector connected to TLS
     203          554 :         det =  createE2Detector(id, DU_USER_DEFINED, lane, pos, endPos, length, haltingTimeThreshold, haltingSpeedThreshold, jamDistThreshold, name, vTypes, nextEdges, detectPersons, showDetector);
     204          554 :         myNet.getDetectorControl().add(SUMO_TAG_LANE_AREA_DETECTOR, det);
     205              :         // add the file output (XXX: Where's the corresponding delete?)
     206          554 :         if (toLaneGiven) {
     207              :             // Detector also associated to specific link
     208              :             const MSLane* const lastLane = det->getLastLane();
     209            8 :             const MSLink* const link = lastLane->getLinkTo(toLane);
     210            8 :             if (link == nullptr) {
     211              :                 throw InvalidArgument(
     212            0 :                     "The detector '" + id + "' cannot be build as no connection between lanes '"
     213            0 :                     + lastLane->getID() + "' and '" + toLane->getID() + "' exists.");
     214              :             }
     215            8 :             new Command_SaveTLCoupledLaneDet(*tlls, det, myNet.getCurrentTimeStep(), OutputDevice::getDevice(device), link);
     216              :         } else {
     217              :             // detector for tls but without specific link
     218          546 :             new Command_SaveTLCoupledDet(*tlls, det, myNet.getCurrentTimeStep(), OutputDevice::getDevice(device));
     219              :         }
     220              :     } else {
     221              :         // User specified detector for xml-output
     222         2463 :         checkSampleInterval(frequency, SUMO_TAG_E2DETECTOR, id);
     223         2459 :         det = createE2Detector(id, DU_USER_DEFINED, lane, pos, endPos, length, haltingTimeThreshold, haltingSpeedThreshold, jamDistThreshold, name, vTypes, nextEdges, detectPersons, showDetector);
     224         2459 :         myNet.getDetectorControl().add(SUMO_TAG_LANE_AREA_DETECTOR, det, device, frequency);
     225              :     }
     226         3009 :     return det;
     227              : }
     228              : 
     229              : 
     230              : Parameterised*
     231          244 : NLDetectorBuilder::buildE2Detector(const std::string& id, std::vector<MSLane*> lanes, double pos, double endPos,
     232              :                                    const std::string& device, SUMOTime frequency,
     233              :                                    SUMOTime haltingTimeThreshold, double haltingSpeedThreshold, double jamDistThreshold,
     234              :                                    const std::string name, const std::string& vTypes,
     235              :                                    const std::string& nextEdges,
     236              :                                    int detectPersons, bool friendlyPos, bool showDetector,
     237              :                                    MSTLLogicControl::TLSLogicVariants* tlls, MSLane* toLane) {
     238              : 
     239              :     bool tlsGiven = tlls != nullptr;
     240              :     bool toLaneGiven = toLane != nullptr;
     241              :     assert(pos != std::numeric_limits<double>::max());
     242              :     assert(endPos != std::numeric_limits<double>::max());
     243              :     assert(lanes.size() != 0);
     244              : 
     245          244 :     const MSLane* const firstLane = lanes[0];
     246          244 :     const MSLane* const lastLane = lanes.back();
     247              : 
     248              :     // Check positioning
     249          244 :     if (pos >= firstLane->getLength() || (pos < 0 && -pos > firstLane->getLength())) {
     250            1 :         std::stringstream ss;
     251              :         ss << "The given position (=" << pos << ") for detector '" << id
     252              :            << "' does not lie on the given lane '" << firstLane->getID()
     253              :            << "' with length " << firstLane->getLength();
     254            1 :         if (friendlyPos) {
     255            1 :             double newPos = pos > 0 ? firstLane->getLength() - POSITION_EPS : 0.;
     256              :             ss << " (adjusting to new position " << newPos;
     257            1 :             WRITE_WARNING(ss.str());
     258              :             pos = newPos;
     259              :         } else {
     260            0 :             ss << " (0 <= pos < lane->getLength() is required)";
     261            0 :             throw InvalidArgument(ss.str());
     262              :         }
     263            1 :     }
     264          244 :     if (endPos > lastLane->getLength() || (endPos <= 0 && -endPos >= lastLane->getLength())) {
     265            1 :         std::stringstream ss;
     266              :         ss << "The given end position (=" << endPos << ") for detector '" << id
     267              :            << "' does not lie on the given lane '" << lastLane->getID()
     268              :            << "' with length " << lastLane->getLength();
     269            1 :         if (friendlyPos) {
     270            1 :             double newEndPos = endPos > 0 ? lastLane->getLength() : POSITION_EPS;
     271              :             ss << " (adjusting to new position " << newEndPos;
     272            1 :             WRITE_WARNING(ss.str());
     273              :             pos = newEndPos;
     274              :         } else {
     275            0 :             ss << " (0 <= pos < lane->getLength() is required)";
     276            0 :             throw InvalidArgument(ss.str());
     277              :         }
     278            1 :     }
     279              : 
     280              :     MSE2Collector* det = nullptr;
     281          244 :     if (tlsGiven) {
     282              :         // Detector connected to TLS
     283            5 :         det = createE2Detector(id, DU_USER_DEFINED, lanes, pos, endPos, haltingTimeThreshold, haltingSpeedThreshold, jamDistThreshold, name, vTypes, nextEdges, detectPersons, showDetector);
     284            5 :         myNet.getDetectorControl().add(SUMO_TAG_LANE_AREA_DETECTOR, det);
     285              :         // add the file output (XXX: Where's the corresponding delete?)
     286            5 :         if (toLaneGiven) {
     287              :             // Detector also associated to specific link
     288              :             const MSLane* const lastDetLane = det->getLastLane();
     289            0 :             const MSLink* const link = lastDetLane->getLinkTo(toLane);
     290            0 :             if (link == nullptr) {
     291              :                 throw InvalidArgument(
     292            0 :                     "The detector '" + id + "' cannot be build as no connection between lanes '"
     293            0 :                     + lastDetLane->getID() + "' and '" + toLane->getID() + "' exists.");
     294              :             }
     295            0 :             new Command_SaveTLCoupledLaneDet(*tlls, det, myNet.getCurrentTimeStep(), OutputDevice::getDevice(device), link);
     296              :         } else {
     297              :             // detector for tls but without specific link
     298            5 :             new Command_SaveTLCoupledDet(*tlls, det, myNet.getCurrentTimeStep(), OutputDevice::getDevice(device));
     299              :         }
     300              :     } else {
     301              :         // User specified detector for xml-output
     302          239 :         checkSampleInterval(frequency, SUMO_TAG_E2DETECTOR, id);
     303              : 
     304          245 :         det = createE2Detector(id, DU_USER_DEFINED, lanes, pos, endPos, haltingTimeThreshold, haltingSpeedThreshold, jamDistThreshold, name, vTypes, nextEdges, detectPersons, showDetector);
     305          233 :         myNet.getDetectorControl().add(SUMO_TAG_LANE_AREA_DETECTOR, det, device, frequency);
     306              :     }
     307          238 :     return det;
     308              : }
     309              : 
     310              : 
     311              : 
     312              : Parameterised*
     313         1373 : NLDetectorBuilder::beginE3Detector(const std::string& id,
     314              :                                    const std::string& device, SUMOTime splInterval,
     315              :                                    double haltingSpeedThreshold,
     316              :                                    SUMOTime haltingTimeThreshold,
     317              :                                    const std::string name,
     318              :                                    const std::string& vTypes,
     319              :                                    const std::string& nextEdges,
     320              :                                    int detectPersons, bool openEntry, bool expectArrival) {
     321         1373 :     checkSampleInterval(splInterval, SUMO_TAG_E3DETECTOR, id);
     322         2738 :     myE3Definition = new E3DetectorDefinition(id, device, haltingSpeedThreshold, haltingTimeThreshold, splInterval, name, vTypes, nextEdges, detectPersons, openEntry, expectArrival);
     323         1369 :     return myE3Definition;
     324              : }
     325              : 
     326              : 
     327              : void
     328         1691 : NLDetectorBuilder::addE3Entry(const std::string& lane,
     329              :                               double pos, bool friendlyPos) {
     330         1691 :     if (myE3Definition == nullptr) {
     331              :         return;
     332              :     }
     333         1663 :     MSLane* clane = getLaneChecking(lane, SUMO_TAG_E3DETECTOR, myE3Definition->myID);
     334              :     // get and check the position
     335         1659 :     pos = getPositionChecking(pos, clane, friendlyPos, SUMO_TAG_DET_ENTRY, myE3Definition->myID);
     336              :     // build and save the entry
     337         1655 :     myE3Definition->myEntries.push_back(MSCrossSection(clane, pos));
     338              : }
     339              : 
     340              : 
     341              : void
     342         1655 : NLDetectorBuilder::addE3Exit(const std::string& lane,
     343              :                              double pos, bool friendlyPos) {
     344         1655 :     if (myE3Definition == nullptr) {
     345              :         return;
     346              :     }
     347         1627 :     MSLane* clane = getLaneChecking(lane, SUMO_TAG_E3DETECTOR, myE3Definition->myID);
     348              :     // get and check the position
     349         1623 :     pos = getPositionChecking(pos, clane, friendlyPos, SUMO_TAG_DET_EXIT, myE3Definition->myID);
     350              :     // build and save the exit
     351         1619 :     myE3Definition->myExits.push_back(MSCrossSection(clane, pos));
     352              : }
     353              : 
     354              : 
     355              : std::string
     356        10158 : NLDetectorBuilder::getCurrentE3ID() const {
     357        10158 :     if (myE3Definition == nullptr) {
     358          168 :         return "<unknown>";
     359              :     }
     360              :     return myE3Definition->myID;
     361              : }
     362              : 
     363              : 
     364              : void
     365         1397 : NLDetectorBuilder::endE3Detector() {
     366         1397 :     if (myE3Definition == nullptr) {
     367              :         return;
     368              :     }
     369              :     // If E3 own entry or exit detectors
     370         1369 :     if (myE3Definition->myEntries.size() > 0 || myE3Definition->myExits.size() > 0) {
     371              :         // create E3 detector
     372         4083 :         MSDetectorFileOutput* det = createE3Detector(myE3Definition->myID,
     373         1361 :                                     myE3Definition->myEntries, myE3Definition->myExits,
     374         1361 :                                     myE3Definition->myHaltingSpeedThreshold, myE3Definition->myHaltingTimeThreshold,
     375              :                                     myE3Definition->myName,
     376         1361 :                                     myE3Definition->myVehicleTypes,
     377         1361 :                                     myE3Definition->myNextEdges,
     378              :                                     myE3Definition->myDetectPersons,
     379         1361 :                                     myE3Definition->myOpenEntry,
     380         1361 :                                     myE3Definition->myExpectArrival);
     381         1361 :         det->updateParameters(myE3Definition->getParametersMap());
     382              :         // add to net
     383         1361 :         myNet.getDetectorControl().add(SUMO_TAG_ENTRY_EXIT_DETECTOR, det, myE3Definition->myDevice, myE3Definition->mySampleInterval);
     384              :     } else {
     385           40 :         WRITE_WARNING(toString(SUMO_TAG_E3DETECTOR) + " with id = '" + myE3Definition->myID + "' will not be created because is empty (no " + toString(SUMO_TAG_DET_ENTRY) + " or " + toString(SUMO_TAG_DET_EXIT) + " was defined)")
     386              :     }
     387              :     // clean up
     388         1361 :     delete myE3Definition;
     389         1361 :     myE3Definition = nullptr;
     390              : }
     391              : 
     392              : 
     393              : void
     394          108 : NLDetectorBuilder::buildVTypeProbe(const std::string& id,
     395              :                                    const std::string& vtype, SUMOTime frequency,
     396              :                                    const std::string& device) {
     397          108 :     checkSampleInterval(frequency, SUMO_TAG_VTYPEPROBE, id);
     398           96 :     new MSVTypeProbe(id, vtype, OutputDevice::getDevice(device), frequency);
     399           90 : }
     400              : 
     401              : 
     402              : void
     403          458 : NLDetectorBuilder::buildRouteProbe(const std::string& id, const std::string& edge,
     404              :                                    SUMOTime frequency, SUMOTime begin,
     405              :                                    const std::string& device,
     406              :                                    const std::string& vTypes) {
     407          458 :     checkSampleInterval(frequency, SUMO_TAG_ROUTEPROBE, id);
     408          458 :     MSEdge* e = getEdgeChecking(edge, SUMO_TAG_ROUTEPROBE, id);
     409         1374 :     MSRouteProbe* probe = new MSRouteProbe(id, e, id + "_" + toString(begin), id + "_" + toString(begin - frequency), vTypes);
     410              :     // add the file output
     411          458 :     myNet.getDetectorControl().add(SUMO_TAG_ROUTEPROBE, probe, device, frequency, begin);
     412          458 : }
     413              : 
     414              : 
     415              : MSDetectorFileOutput*
     416        23346 : NLDetectorBuilder::createInductLoop(const std::string& id,
     417              :                                     MSLane* lane, double pos,
     418              :                                     double length,
     419              :                                     const std::string name,
     420              :                                     const std::string& vTypes,
     421              :                                     const std::string& nextEdges,
     422              :                                     int detectPersons,
     423              :                                     bool /*show*/) {
     424        23346 :     if (MSGlobals::gUseMesoSim) {
     425          567 :         return new MEInductLoop(id, MSGlobals::gMesoNet->getSegmentForEdge(lane->getEdge(), pos), pos, name, vTypes, nextEdges, detectPersons);
     426              :     }
     427        46317 :     return new MSInductLoop(id, lane, pos, length, name, vTypes, nextEdges, detectPersons, false);
     428              : }
     429              : 
     430              : 
     431              : MSDetectorFileOutput*
     432          725 : NLDetectorBuilder::createInstantInductLoop(const std::string& id,
     433              :         MSLane* lane, double pos, const std::string& od,
     434              :         const std::string name, const std::string& vTypes,
     435              :         const std::string& nextEdges) {
     436         1453 :     return new MSInstantInductLoop(id, OutputDevice::getDevice(od), lane, pos, name, vTypes, nextEdges);
     437              : }
     438              : 
     439              : 
     440              : MSE2Collector*
     441         5017 : NLDetectorBuilder::createE2Detector(const std::string& id,
     442              :                                     DetectorUsage usage, MSLane* lane, double pos, double endPos, double length,
     443              :                                     SUMOTime haltingTimeThreshold, double haltingSpeedThreshold, double jamDistThreshold,
     444              :                                     const std::string name, const std::string& vTypes,
     445              :                                     const std::string& nextEdges,
     446              :                                     int detectPersons, bool /* showDetector */) {
     447        15051 :     return new MSE2Collector(id, usage, lane, pos, endPos, length, haltingTimeThreshold, haltingSpeedThreshold, jamDistThreshold, name, vTypes, nextEdges, detectPersons);
     448              : }
     449              : 
     450              : MSE2Collector*
     451          238 : NLDetectorBuilder::createE2Detector(const std::string& id,
     452              :                                     DetectorUsage usage, std::vector<MSLane*> lanes, double pos, double endPos,
     453              :                                     SUMOTime haltingTimeThreshold, double haltingSpeedThreshold, double jamDistThreshold,
     454              :                                     const std::string name, const std::string& vTypes,
     455              :                                     const std::string& nextEdges,
     456              :                                     int detectPersons, bool /* showDetector */) {
     457          486 :     return new MSE2Collector(id, usage, lanes, pos, endPos, haltingTimeThreshold, haltingSpeedThreshold, jamDistThreshold, name, vTypes, nextEdges, detectPersons);
     458              : }
     459              : 
     460              : MSDetectorFileOutput*
     461         1196 : NLDetectorBuilder::createE3Detector(const std::string& id,
     462              :                                     const CrossSectionVector& entries,
     463              :                                     const CrossSectionVector& exits,
     464              :                                     double haltingSpeedThreshold,
     465              :                                     SUMOTime haltingTimeThreshold,
     466              :                                     const std::string name, const std::string& vTypes,
     467              :                                     const std::string& nextEdges,
     468              :                                     int detectPersons,
     469              :                                     bool openEntry,
     470              :                                     bool expectArrival) {
     471         3588 :     return new MSE3Collector(id, entries, exits, haltingSpeedThreshold, haltingTimeThreshold, name, vTypes, nextEdges, detectPersons, openEntry, expectArrival);
     472              : }
     473              : 
     474              : 
     475              : double
     476        25094 : NLDetectorBuilder::getPositionChecking(double pos, MSLane* lane, bool friendlyPos,
     477              :                                        SumoXMLTag tag,
     478              :                                        const std::string& detid) {
     479              :     // check whether it is given from the end
     480        25094 :     if (pos < 0) {
     481         2193 :         pos += lane->getLength();
     482              :     }
     483              :     // check whether it is on the lane
     484        25094 :     if (pos > lane->getLength()) {
     485          540 :         if (friendlyPos) {
     486              :             pos = lane->getLength();
     487              :         } else {
     488           36 :             throw InvalidArgument("The position of " + toString(tag) + " '" + detid + "' lies beyond the lane's '" + lane->getID() + "' end.");
     489              :         }
     490              :     }
     491        25076 :     if (pos < 0) {
     492          178 :         if (friendlyPos) {
     493              :             pos = 0.;
     494              :         } else {
     495            0 :             throw InvalidArgument("The position of " + toString(tag) + "  '" + detid + "' lies before the lane's '" + lane->getID() + "' begin.");
     496              :         }
     497              :     }
     498        25076 :     return pos;
     499              : }
     500              : 
     501              : 
     502              : void
     503         4351 : NLDetectorBuilder::createEdgeLaneMeanData(const std::string& id, SUMOTime frequency,
     504              :         SUMOTime begin, SUMOTime end, const std::string& type,
     505              :         const bool useLanes, const bool withEmpty, const bool printDefaults,
     506              :         const bool withInternal, const bool trackVehicles, const int detectPersons,
     507              :         const double maxTravelTime, const double minSamples,
     508              :         const double haltSpeed, const std::string& vTypes,
     509              :         const std::string& writeAttributes,
     510              :         std::vector<MSEdge*> edges,
     511              :         bool aggregate,
     512              :         const std::string& device) {
     513         4351 :     if (begin < 0) {
     514           72 :         throw InvalidArgument("Negative begin time for meandata dump '" + id + "'.");
     515              :     }
     516         4315 :     if (end < 0) {
     517              :         end = SUMOTime_MAX;
     518              :     }
     519         4315 :     if (end <= begin) {
     520           72 :         throw InvalidArgument("End before or at begin for meandata dump '" + id + "'.");
     521              :     }
     522         8558 :     checkStepLengthMultiple(begin, " for meandata dump '" + id + "'");
     523              :     MSMeanData* det = nullptr;
     524         4279 :     if (type == "" || type == "performance" || type == "traffic") {
     525              :         det = new MSMeanData_Net(id, begin, end, useLanes, withEmpty,
     526         2974 :                                  printDefaults, withInternal, trackVehicles, detectPersons, maxTravelTime, minSamples, haltSpeed, vTypes, writeAttributes, edges, aggregate);
     527         1305 :     } else if (type == "emissions" || type == "hbefa") {
     528          873 :         if (type == "hbefa") {
     529           24 :             WRITE_WARNING(TL("The netstate type 'hbefa' is deprecated. Please use the type 'emissions' instead."));
     530              :         }
     531              :         det = new MSMeanData_Emissions(id, begin, end, useLanes, withEmpty,
     532          873 :                                        printDefaults, withInternal, trackVehicles, maxTravelTime, minSamples, vTypes, writeAttributes, edges, aggregate);
     533          432 :     } else if (type == "harmonoise") {
     534              :         det = new MSMeanData_Harmonoise(id, begin, end, useLanes, withEmpty,
     535          408 :                                         printDefaults, withInternal, trackVehicles, maxTravelTime, minSamples, vTypes, writeAttributes, edges, aggregate);
     536           24 :     } else if (type == "amitran") {
     537              :         det = new MSMeanData_Amitran(id, begin, end, useLanes, withEmpty,
     538           24 :                                      printDefaults, withInternal, trackVehicles, detectPersons, maxTravelTime, minSamples, haltSpeed, vTypes, writeAttributes, edges, aggregate);
     539              :     } else {
     540            0 :         throw InvalidArgument("Invalid type '" + type + "' for meandata dump '" + id + "'.");
     541              :     }
     542              :     if (det != nullptr) {
     543         4279 :         if (frequency < 0) {
     544          666 :             frequency = end - begin;
     545              :         } else {
     546        10839 :             checkStepLengthMultiple(frequency, " for meandata dump '" + id + "'");
     547              :         }
     548         4279 :         MSNet::getInstance()->getDetectorControl().add(det, device, frequency, begin);
     549              :     }
     550         4279 : }
     551              : 
     552              : 
     553              : 
     554              : 
     555              : // ------ Value checking/adapting methods ------
     556              : MSEdge*
     557          458 : NLDetectorBuilder::getEdgeChecking(const std::string& edgeID, SumoXMLTag type,
     558              :                                    const std::string& detid) {
     559              :     // get and check the lane
     560          458 :     MSEdge* edge = MSEdge::dictionary(edgeID);
     561          458 :     if (edge == nullptr) {
     562            0 :         throw InvalidArgument("The lane with the id '" + edgeID + "' is not known (while building " + toString(type) + " '" + detid + "').");
     563              :     }
     564          458 :     return edge;
     565              : }
     566              : 
     567              : 
     568              : MSLane*
     569        28292 : NLDetectorBuilder::getLaneChecking(const std::string& laneID, SumoXMLTag type,
     570              :                                    const std::string& detid) {
     571              :     // get and check the lane
     572        28292 :     MSLane* lane = MSLane::dictionary(laneID);
     573        28292 :     if (lane == nullptr) {
     574          120 :         throw InvalidArgument("The lane with the id '" + laneID + "' is not known (while building " + toString(type) + " '" + detid + "').");
     575              :     }
     576        28252 :     return lane;
     577              : }
     578              : 
     579              : 
     580              : void
     581        25627 : NLDetectorBuilder::checkSampleInterval(SUMOTime splInterval, SumoXMLTag type, const std::string& id) {
     582        25627 :     if (splInterval < 0) {
     583           40 :         throw InvalidArgument("Negative sampling frequency (in " + toString(type) + " '" + id + "').");
     584              :     }
     585        25607 :     if (splInterval == 0) {
     586           12 :         throw InvalidArgument("Sampling frequency must not be zero (in " + toString(type) + " '" + id + "').");
     587              :     }
     588        51202 :     checkStepLengthMultiple(splInterval, " (in " + toString(type) + " '" + id + "')");
     589        25601 : }
     590              : 
     591              : 
     592              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1