LCOV - code coverage report
Current view: top level - src/od - ODMatrix.h (source / functions) Coverage Total Hit
Test: lcov.info Lines: 100.0 % 11 11
Test Date: 2024-12-21 15:45:41 Functions: 100.0 % 1 1

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2006-2024 German Aerospace Center (DLR) and others.
       4              : // This program and the accompanying materials are made available under the
       5              : // terms of the Eclipse Public License 2.0 which is available at
       6              : // https://www.eclipse.org/legal/epl-2.0/
       7              : // This Source Code may also be made available under the following Secondary
       8              : // Licenses when the conditions for such availability set forth in the Eclipse
       9              : // Public License 2.0 are satisfied: GNU General Public License, version 2
      10              : // or later which is available at
      11              : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
      12              : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
      13              : /****************************************************************************/
      14              : /// @file    ODMatrix.h
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Michael Behrisch
      17              : /// @author  Yun-Pang Floetteroed
      18              : /// @date    05. Apr. 2006
      19              : ///
      20              : // An O/D (origin/destination) matrix
      21              : /****************************************************************************/
      22              : #pragma once
      23              : #include <config.h>
      24              : 
      25              : #include <iostream>
      26              : #include <sstream>
      27              : #include <fstream>
      28              : #include <vector>
      29              : #include <cstdlib>
      30              : #include <ctime>
      31              : #include <algorithm>
      32              : #include <set>
      33              : #include <string>
      34              : #include <utils/common/SUMOTime.h>
      35              : #include "ODCell.h"
      36              : #include "ODDistrictCont.h"
      37              : #include <utils/distribution/Distribution_Points.h>
      38              : #include <utils/importio/LineReader.h>
      39              : #include <utils/common/SUMOTime.h>
      40              : #include <utils/xml/SAXWeightsHandler.h>
      41              : 
      42              : // ===========================================================================
      43              : // class declarations
      44              : // ===========================================================================
      45              : class OptionsCont;
      46              : class OutputDevice;
      47              : class SUMOSAXHandler;
      48              : 
      49              : 
      50              : // ===========================================================================
      51              : // class definitions
      52              : // ===========================================================================
      53              : /**
      54              :  * @class ODMatrix
      55              :  * @brief An O/D (origin/destination) matrix
      56              :  *
      57              :  * This class is the internal representation of a loaded O/D-matrix. Beside
      58              :  *  being the storage for ODCells, the matrix also contains information about
      59              :  *  the numbers of loaded, discarded, and written vehicles.
      60              :  *
      61              :  * The matrix has a reference to the container of districts stored. This allows
      62              :  *  to validate added cell descriptions in means that using existing origins/
      63              :  *  destinations only is assured.
      64              :  *
      65              :  * In addition of being a storage, the matrix is also responsible for writing
      66              :  *  the results and contains methods for splitting the entries over time.
      67              :  */
      68              : class ODMatrix : public SAXWeightsHandler::EdgeFloatTimeLineRetriever {
      69              : 
      70              : public:
      71              :     /** @brief Constructor
      72              :      *
      73              :      * @param[in] dc The district container to obtain referenced districts from
      74              :      */
      75              :     ODMatrix(const ODDistrictCont& dc, double scale);
      76              : 
      77              : 
      78              :     /// Destructor
      79              :     ~ODMatrix();
      80              : 
      81              : 
      82              :     /** @brief Builds a single cell from the given values, verifying them
      83              :      *
      84              :      * At first, the number of loaded vehicles (myNoLoaded) is incremented
      85              :      *  by vehicleNumber.
      86              :      *
      87              :      * It is checked whether both the origin and the destination exist within
      88              :      *  the assigned district container (myDistricts). If one of them is missing,
      89              :      *  an error is generated, if both, a warning, because in the later case
      90              :      *  the described flow may lay completely beside the processed area. In both
      91              :      *  cases the given number of vehicles (vehicleNumber) is added to myNoDiscarded.
      92              :      *
      93              :      * If the origin/destination districts are known, a cell is built using the
      94              :      *  given values. This cell is added to the list of known cells (myContainer).
      95              :      *
      96              :      * @param[in] vehicleNumber The number of vehicles to store within the cell
      97              :      * @param[in] beginEnd The begin and the end of the interval the cell is valid for
      98              :      * @param[in] origin The origin district to use for the cell's flows
      99              :      * @param[in] destination The destination district to use for the cell's flows
     100              :      * @param[in] vehicleType The vehicle type to use for the cell's flows
     101              :      * @return whether the cell could be added
     102              :      */
     103              :     bool add(double vehicleNumber, const std::pair<SUMOTime, SUMOTime>& beginEnd,
     104              :              const std::string& origin, const std::string& destination,
     105              :              const std::string& vehicleType,
     106              :              const bool originIsEdge = false, const bool destinationIsEdge = false,
     107              :              bool noScaling = false);
     108              : 
     109              :     /** @brief Adds a single vehicle with departure time
     110              :      *
     111              :      * If there is no existing ODCell for the given parameters one is generated
     112              :      * using add(...)
     113              :      *
     114              :      * @param[in] id The id of the vehicle
     115              :      * @param[in] depart The departure time of the vehicle
     116              :      * @param[in] od The origin and destination district to use for the cell's flows
     117              :      * @param[in] vehicleType The vehicle type to use for the cell's flows
     118              :      * @return whether the vehicle could be added
     119              :      */
     120              :     bool add(const SUMOVehicleParameter& veh, bool originIsEdge = false, bool destinationIsEdgeconst = false);
     121              : 
     122              :     /** @brief Helper function for flow and trip output writing the depart
     123              :      *   and arrival attributes
     124              :      *
     125              :      * @param[in] dev The stream to write the generated vehicle trips to
     126              :      * @param[in] noVtype Whether vtype information shall not be written
     127              :      * @param[in] cell The OD cell containing the vtype
     128              :      */
     129              :     void writeDefaultAttrs(OutputDevice& dev, const bool noVtype,
     130              :                            const ODCell* const cell);
     131              : 
     132              :     /** @brief Writes the vehicles stored in the matrix assigning the sources and sinks
     133              :      *
     134              :      * The cells stored in myContainer are sorted, first. Then, for each time
     135              :      *  step to generate vehicles for, it is checked whether the topmost cell
     136              :      *  is valid for this time step. If so, vehicles are generated from this
     137              :      *  cell's description using "computeDeparts" and stored in an internal vector.
     138              :      *  The pointer is moved and the check is repeated until the current cell
     139              :      *  is not valid for the current time or no further cells exist.
     140              :      *
     141              :      * Then, for the current time step, the internal list of vehicles is sorted and
     142              :      *  all vehicles that start within this time step are written.
     143              :      *
     144              :      * The left fraction of vehicles to insert is saved for each O/D-dependency
     145              :      *  over time and the number of vehicles to generate is increased as soon
     146              :      *  as this value is larger than 1, decrementing it.
     147              :      *
     148              :      * @param[in] begin The begin time to generate vehicles for
     149              :      * @param[in] end The end time to generate vehicles for
     150              :      * @param[in] dev The stream to write the generated vehicle trips to
     151              :      * @param[in] uniform Information whether departure times shallbe uniformly spread or random
     152              :      * @param[in] differSourceSink whether source and sink shall be different edges
     153              :      * @param[in] noVtype Whether vtype information shall not be written
     154              :      * @param[in] prefix A prefix for the vehicle names
     155              :      * @param[in] stepLog Whether processed time shall be written
     156              :      * @param[in] pedestrians Writes trips for pedestrians
     157              :      * @param[in] persontrips Writes trips for persontrips
     158              :      */
     159              :     void write(SUMOTime begin, const SUMOTime end,
     160              :                OutputDevice& dev, const bool uniform,
     161              :                const bool differSourceSink, const bool noVtype,
     162              :                const std::string& prefix, const bool stepLog,
     163              :                bool pedestrians, bool persontrips,
     164              :                const std::string& modes);
     165              : 
     166              : 
     167              :     /** @brief Writes the flows stored in the matrix
     168              :      *
     169              :      * @param[in] begin The begin time to generate vehicles for
     170              :      * @param[in] end The end time to generate vehicles for
     171              :      * @param[in] dev The stream to write the generated vehicle trips to
     172              :      * @param[in] noVtype Whether vtype information shall not be written
     173              :      * @param[in] prefix A prefix for the flow names
     174              :      * @param[in] asProbability Write probability to spawn per second instead of number of vehicles
     175              :      * @param[in] pedestrians Writes flows for pedestrians
     176              :      * @param[in] persontrips Writes flows for persontrips
     177              :      */
     178              :     void writeFlows(const SUMOTime begin, const SUMOTime end,
     179              :                     OutputDevice& dev, const bool noVtype,
     180              :                     const std::string& prefix,
     181              :                     bool asProbability = false, bool pedestrians = false, bool persontrips = false,
     182              :                     const std::string& modes = "");
     183              : 
     184              : 
     185              :     /** @brief Returns the number of loaded vehicles
     186              :      *
     187              :      * Returns the value of myNoLoaded
     188              :      *
     189              :      * @return The number of loaded vehicles
     190              :      */
     191              :     double getNumLoaded() const;
     192              : 
     193              : 
     194              :     /** @brief Returns the number of written vehicles
     195              :      *
     196              :      * Returns the value of myNoWritten
     197              :      *
     198              :      * @return The number of written vehicles
     199              :      */
     200              :     double getNumWritten() const;
     201              : 
     202              : 
     203              :     /** @brief Returns the number of discarded vehicles
     204              :      *
     205              :      * Returns the value of myNoDiscarded
     206              :      *
     207              :      * @return The number of discarded vehicles
     208              :      */
     209              :     double getNumDiscarded() const;
     210              : 
     211              : 
     212              :     /** @brief Splits the stored cells dividing them on the given time line
     213              :      * @todo Describe
     214              :      */
     215              :     void applyCurve(const Distribution_Points& ps);
     216              : 
     217              : 
     218              :     /** @brief read a VISUM-matrix with the O Format
     219              :      *  @todo Describe
     220              :      */
     221              :     void readO(LineReader& lr, double scale,
     222              :                std::string vehType, bool matrixHasVehType);
     223              : 
     224              :     /** @brief read a VISUM-matrix with the V Format
     225              :      *  @todo Describe
     226              :      */
     227              :     void readV(LineReader& lr, double scale,
     228              :                std::string vehType, bool matrixHasVehType);
     229              : 
     230              :     /** @brief read a matrix in one of several formats
     231              :      *  @todo Describe
     232              :      */
     233              :     void loadMatrix(OptionsCont& oc);
     234              : 
     235              :     /** @brief read SUMO routes
     236              :      *  @todo Describe
     237              :      */
     238              :     void loadRoutes(OptionsCont& oc, SUMOSAXHandler& handler);
     239              : 
     240              :     /** @brief split the given timeline
     241              :      *  @todo Describe
     242              :      */
     243              :     Distribution_Points parseTimeLine(const std::vector<std::string>& def, bool timelineDayInHours);
     244              : 
     245              :     const std::vector<ODCell*>& getCells() {
     246              :         return myContainer;
     247              :     }
     248              : 
     249              :     void sortByBeginTime();
     250              : 
     251              :     SUMOTime getBegin() const {
     252          122 :         return myBegin;
     253              :     }
     254              : 
     255              :     SUMOTime getEnd() const {
     256           61 :         return myEnd;
     257              :     }
     258              : 
     259              :     void addTazRelWeight(const std::string intervalID, const std::string& from, const std::string& to,
     260              :                          double val, double beg, double end);
     261              : 
     262              : protected:
     263              :     /**
     264              :      * @struct ODVehicle
     265              :      * @brief An internal representation of a single vehicle
     266              :      */
     267              :     struct ODVehicle {
     268              :         /// @brief The id of the vehicle
     269              :         std::string id;
     270              :         /// @brief The departure time of the vehicle
     271              :         SUMOTime depart;
     272              :         /// @brief The cell of the ODMatrix which generated the vehicle
     273              :         ODCell* cell;
     274              :         /// @brief The edge the vehicles shall start at
     275              :         std::string from;
     276              :         /// @brief The edge the vehicles shall end at
     277              :         std::string to;
     278              : 
     279              :     };
     280              : 
     281              : 
     282              :     /** @brief Computes the vehicle departs stored in the given cell and saves them in "into"
     283              :      *
     284              :      * At first, the number of vehicles to insert is computed using the
     285              :      *  integer value of the vehicleNumber information from the given cell.
     286              :      *  In the case vehicleNumber has a fraction, an additional vehicle
     287              :      *  may be added in the case a chosen random number is lower than this fraction.
     288              :      *
     289              :      * If uniform is true, the departure times of the generated vehicles
     290              :      *  are spread uniformly, otherwise the departure time are chosen randomly from
     291              :      *  the interval.
     292              :      *
     293              :      * The vehicle names are generated by putting the value of vehName after the
     294              :      *  given prefix. The value of vehName is incremented with each generated vehicle.
     295              :      *
     296              :      * The number of left vehicles (the fraction if no additional vehicle was
     297              :      *  generated) is returned.
     298              :      *
     299              :      * @param[in] cell The cell to use
     300              :      * @param[in,out] vehName An incremented index of the generated vehicle
     301              :      * @param[out] into The storage to put generated vehicles into
     302              :      * @param[in] uniform Information whether departure times shallbe uniformly spread or random
     303              :      * @param[in] differSourceSink whether source and sink shall be different edges
     304              :      * @param[in] prefix A prefix for the vehicle names
     305              :      * @return The number of left vehicles to insert
     306              :      */
     307              :     double computeDeparts(ODCell* cell,
     308              :                           int& vehName, std::vector<ODVehicle>& into,
     309              :                           const bool uniform, const bool differSourceSink,
     310              :                           const std::string& prefix);
     311              : 
     312              : 
     313              :     /** @brief Splits the given cell dividing it on the given time line and
     314              :      *          storing the results in the given container
     315              :      *
     316              :      * For the given cell, a list of clones is generated. The number of these
     317              :      *  is equal to the number of "areas" within the given distribution
     318              :      *  description (time line in this case) and each clone's vehicleNumber
     319              :      *  is equal to the given cell's vehicle number multiplied with the area's
     320              :      *  probability. The clones are stored in the given cell vector.
     321              :      *
     322              :      * @see Distribution_Points
     323              :      * @param[in] ps The time line to apply
     324              :      * @param[in] cell The cell to split
     325              :      * @param[out] newCells The storage to put generated cells into
     326              :      * @todo describe better!!!
     327              :      */
     328              :     void applyCurve(const Distribution_Points& ps, ODCell* cell,
     329              :                     std::vector<ODCell*>& newCells);
     330              : 
     331              : 
     332              : private:
     333              :     /** @used in the functions readV and readO
     334              :      * @todo Describe
     335              :      */
     336              :     std::string getNextNonCommentLine(LineReader& lr);
     337              : 
     338              :     /** @used in the functions readV and readO
     339              :      * @todo Describe
     340              :      */
     341              :     SUMOTime parseSingleTime(const std::string& time);
     342              : 
     343              :     /** @used in the functions readV and readO
     344              :      * @todo Describe
     345              :      */
     346              :     std::pair<SUMOTime, SUMOTime> readTime(LineReader& lr);
     347              : 
     348              :     /** @used in the functions readV and readO
     349              :      * @todo Describe
     350              :      */
     351              :     double readFactor(LineReader& lr, double scale);
     352              : 
     353              : 
     354              : private:
     355              :     /// @brief The loaded cells
     356              :     std::vector<ODCell*> myContainer;
     357              : 
     358              :     /// @brief The loaded cells indexed by origin and destination
     359              :     std::map<const std::pair<const std::string, const std::string>, std::vector<ODCell*> > myShortCut;
     360              : 
     361              :     /// @brief The districts to retrieve sources/sinks from
     362              :     const ODDistrictCont& myDistricts;
     363              : 
     364              :     /// @brief The missing districts already warned about
     365              :     std::set<std::string> myMissingDistricts;
     366              : 
     367              :     /// @brief Number of loaded vehicles
     368              :     double myNumLoaded;
     369              : 
     370              :     /// @brief Number of written vehicles
     371              :     double myNumWritten;
     372              : 
     373              :     /// @brief Number of discarded vehicles
     374              :     double myNumDiscarded;
     375              : 
     376              :     /// @brief parsed time bounds
     377              :     SUMOTime myBegin, myEnd;
     378              : 
     379              :     /// @brief user-defined vType
     380              :     std::string myVType;
     381              : 
     382              :     /// @brief the scaling factor for traffic
     383              :     double myScale;
     384              : 
     385              :     /**
     386              :      * @class cell_by_begin_comparator
     387              :      * @brief Used for sorting the cells by the begin time they describe
     388              :      */
     389              :     class cell_by_begin_comparator {
     390              :     public:
     391              :         /// @brief constructor
     392              :         explicit cell_by_begin_comparator() { }
     393              : 
     394              : 
     395              :         /** @brief Comparing operator
     396              :          *
     397              :          * Compares two cells by the begin of the time they describe. The sort is stabilized
     398              :          * (with secondary sort keys being origin and destination) to get comparable results
     399              :          * with different platforms / compilers.
     400              :          *
     401              :          * @param[in] p1 First cell to compare
     402              :          * @param[in] p2 Second cell to compare
     403              :          * @return Whether the begin time of the first cell is lower than the one of the second
     404              :          */
     405       124840 :         int operator()(ODCell* p1, ODCell* p2) const {
     406       124840 :             if (p1->begin == p2->begin) {
     407        66420 :                 if (p1->origin == p2->origin) {
     408        25144 :                     return p1->destination < p2->destination;
     409              :                 }
     410        41276 :                 return p1->origin < p2->origin;
     411              :             }
     412        58420 :             return p1->begin < p2->begin;
     413              :         }
     414              : 
     415              :     };
     416              : 
     417              : 
     418              :     /**
     419              :      * @class descending_departure_comperator
     420              :      * @brief Used for sorting vehicles by their departure (latest first)
     421              :      *
     422              :      * A reverse operator to what may be expected is used in order to allow
     423              :      *  prunning the sorted vector from its tail.
     424              :      */
     425              :     class descending_departure_comperator {
     426              :     public:
     427              :         /// @brief constructor
     428              :         descending_departure_comperator() { }
     429              : 
     430              : 
     431              :         /** @brief Comparing operator
     432              :          *
     433              :          * Compares two vehicles by their departure time
     434              :          *
     435              :          * @param[in] p1 First vehicle to compare
     436              :          * @param[in] p2 Second vehicle to compare
     437              :          * @return Whether the departure time of the first vehicle is larger than the one of the second
     438              :          */
     439              :         bool operator()(const ODVehicle& p1, const ODVehicle& p2) const {
     440       170767 :             if (p1.depart == p2.depart) {
     441            7 :                 return p1.id > p2.id;
     442              :             }
     443       170760 :             return p1.depart > p2.depart;
     444              :         }
     445              : 
     446              :     };
     447              : 
     448              : private:
     449              :     /** @brief invalid copy constructor */
     450              :     ODMatrix(const ODMatrix& s);
     451              : 
     452              :     /** @brief invalid assignment operator */
     453              :     ODMatrix& operator=(const ODMatrix& s) = delete;
     454              : 
     455              : };
        

Generated by: LCOV version 2.0-1