LCOV - code coverage report
Current view: top level - src/netimport/vissim/tempstructs - NIVissimDistrictConnection.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 12.5 % 120 15
Test Date: 2024-11-22 15:46:21 Functions: 33.3 % 15 5

            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    NIVissimDistrictConnection.cpp
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Jakob Erdmann
      17              : /// @author  Michael Behrisch
      18              : /// @date    Sept 2002
      19              : ///
      20              : // -------------------
      21              : /****************************************************************************/
      22              : #include <config.h>
      23              : 
      24              : #include <map>
      25              : #include <string>
      26              : #include <algorithm>
      27              : #include <cassert>
      28              : #include <utils/common/VectorHelper.h>
      29              : #include <utils/common/ToString.h>
      30              : #include <utils/geom/Position.h>
      31              : #include <utils/geom/GeomHelper.h>
      32              : #include <utils/geom/PositionVector.h>
      33              : #include <utils/options/OptionsCont.h>
      34              : #include "NIVissimAbstractEdge.h"
      35              : #include "NIVissimEdge.h"
      36              : #include <netbuild/NBEdge.h>
      37              : #include <netbuild/NBEdgeCont.h>
      38              : #include <netbuild/NBNode.h>
      39              : #include <netbuild/NBNodeCont.h>
      40              : #include <netbuild/NBDistrict.h>
      41              : #include <netbuild/NBDistrictCont.h>
      42              : #include "NIVissimDistrictConnection.h"
      43              : #include <utils/distribution/DistributionCont.h>
      44              : #include <utils/common/MsgHandler.h>
      45              : 
      46              : 
      47              : // ===========================================================================
      48              : // static member definitions
      49              : // ===========================================================================
      50              : NIVissimDistrictConnection::DictType NIVissimDistrictConnection::myDict;
      51              : std::map<int, std::vector<int> > NIVissimDistrictConnection::myDistrictsConnections;
      52              : 
      53              : 
      54              : // ===========================================================================
      55              : // method definitions
      56              : // ===========================================================================
      57            0 : NIVissimDistrictConnection::NIVissimDistrictConnection(int id,
      58              :         const std::string& name,
      59              :         const std::vector<int>& districts, const std::vector<double>& percentages,
      60              :         int edgeid, double position,
      61            0 :         const std::vector<std::pair<int, int> >& assignedVehicles)
      62            0 :     : myID(id), myName(name), myDistricts(districts),
      63            0 :       myEdgeID(edgeid), myPosition(position),
      64            0 :       myAssignedVehicles(assignedVehicles) {
      65              :     std::vector<int>::iterator i = myDistricts.begin();
      66              :     std::vector<double>::const_iterator j = percentages.begin();
      67            0 :     while (i != myDistricts.end()) {
      68            0 :         myPercentages[*i] = *j;
      69              :         i++;
      70              :         j++;
      71              :     }
      72            0 : }
      73              : 
      74              : 
      75            0 : NIVissimDistrictConnection::~NIVissimDistrictConnection() {}
      76              : 
      77              : 
      78              : 
      79              : bool
      80            0 : NIVissimDistrictConnection::dictionary(int id, const std::string& name,
      81              :                                        const std::vector<int>& districts, const std::vector<double>& percentages,
      82              :                                        int edgeid, double position,
      83              :                                        const std::vector<std::pair<int, int> >& assignedVehicles) {
      84              :     NIVissimDistrictConnection* o =
      85              :         new NIVissimDistrictConnection(id, name, districts, percentages,
      86            0 :                                        edgeid, position, assignedVehicles);
      87            0 :     if (!dictionary(id, o)) {
      88            0 :         delete o;
      89            0 :         return false;
      90              :     }
      91              :     return true;
      92              : }
      93              : 
      94              : 
      95              : bool
      96            0 : NIVissimDistrictConnection::dictionary(int id, NIVissimDistrictConnection* o) {
      97              :     DictType::iterator i = myDict.find(id);
      98            0 :     if (i == myDict.end()) {
      99            0 :         myDict[id] = o;
     100            0 :         return true;
     101              :     }
     102              :     return false;
     103              : }
     104              : 
     105              : 
     106              : NIVissimDistrictConnection*
     107            0 : NIVissimDistrictConnection::dictionary(int id) {
     108              :     DictType::iterator i = myDict.find(id);
     109            0 :     if (i == myDict.end()) {
     110              :         return nullptr;
     111              :     }
     112            0 :     return (*i).second;
     113              : }
     114              : 
     115              : void
     116            9 : NIVissimDistrictConnection::dict_BuildDistrictConnections() {
     117              :     //  pre-assign connections to districts
     118            9 :     for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
     119            0 :         NIVissimDistrictConnection* c = (*i).second;
     120              :         const std::vector<int>& districts = c->myDistricts;
     121            0 :         for (std::vector<int>::const_iterator j = districts.begin(); j != districts.end(); j++) {
     122              :             // assign connection to district
     123            0 :             myDistrictsConnections[*j].push_back((*i).first);
     124              :         }
     125              :     }
     126            9 : }
     127              : 
     128              : 
     129              : void
     130            9 : NIVissimDistrictConnection::dict_CheckEdgeEnds() {
     131            9 :     for (std::map<int, std::vector<int> >::iterator k = myDistrictsConnections.begin(); k != myDistrictsConnections.end(); k++) {
     132              :         const std::vector<int>& connections = (*k).second;
     133            0 :         for (std::vector<int>::const_iterator j = connections.begin(); j != connections.end(); j++) {
     134            0 :             NIVissimDistrictConnection* c = dictionary(*j);
     135            0 :             c->checkEdgeEnd();
     136              :         }
     137              :     }
     138            9 : }
     139              : 
     140              : 
     141              : void
     142            0 : NIVissimDistrictConnection::checkEdgeEnd() {
     143            0 :     NIVissimEdge* edge = NIVissimEdge::dictionary(myEdgeID);
     144              :     assert(edge != 0);
     145            0 :     edge->checkDistrictConnectionExistanceAt(myPosition);
     146            0 : }
     147              : 
     148              : 
     149              : void
     150            9 : NIVissimDistrictConnection::dict_BuildDistrictNodes(NBDistrictCont& dc,
     151              :         NBNodeCont& nc) {
     152            9 :     for (std::map<int, std::vector<int> >::iterator k = myDistrictsConnections.begin(); k != myDistrictsConnections.end(); k++) {
     153              :         // get the connections
     154              :         const std::vector<int>& connections = (*k).second;
     155              :         // retrieve the current district
     156            0 :         std::string dsid = toString<int>((*k).first);
     157            0 :         NBDistrict* district = new NBDistrict(dsid);
     158            0 :         dc.insert(district);
     159              :         // compute the middle of the district
     160            0 :         PositionVector pos;
     161            0 :         for (std::vector<int>::const_iterator j = connections.begin(); j != connections.end(); j++) {
     162            0 :             NIVissimDistrictConnection* c = dictionary(*j);
     163            0 :             pos.push_back(c->geomPosition());
     164              :         }
     165            0 :         Position distCenter = pos.getPolygonCenter();
     166            0 :         if (connections.size() == 1) { // !!! ok, ok, maybe not the best way just to add an offset
     167              :             distCenter.add(10, 10);
     168              :         }
     169            0 :         district->setCenter(distCenter);
     170              :         // build the node
     171            0 :         std::string id = "District" + district->getID();
     172              :         NBNode* districtNode =
     173            0 :             new NBNode(id, district->getPosition(), district);
     174            0 :         if (!nc.insert(districtNode)) {
     175            0 :             throw 1;
     176              :         }
     177            0 :     }
     178            9 : }
     179              : 
     180              : void
     181            9 : NIVissimDistrictConnection::dict_BuildDistricts(NBDistrictCont& dc,
     182              :         NBEdgeCont& ec,
     183              :         NBNodeCont& nc) {
     184              :     // add the sources and sinks
     185              :     //  their normalised probability is computed within NBDistrict
     186              :     //   to avoid double code writing and more securty within the converter
     187              :     //  go through the district table
     188            9 :     for (std::map<int, std::vector<int> >::iterator k = myDistrictsConnections.begin(); k != myDistrictsConnections.end(); k++) {
     189              :         // get the connections
     190              :         const std::vector<int>& connections = (*k).second;
     191              :         // retrieve the current district
     192              :         NBDistrict* district =
     193            0 :             dc.retrieve(toString<int>((*k).first));
     194            0 :         NBNode* districtNode = nc.retrieve("District" + district->getID());
     195              :         assert(district != 0 && districtNode != 0);
     196              : 
     197            0 :         for (std::vector<int>::const_iterator l = connections.begin(); l != connections.end(); l++) {
     198            0 :             NIVissimDistrictConnection* c = dictionary(*l);
     199              :             // get the edge to connect the parking place to
     200            0 :             NBEdge* e = ec.retrieve(toString<int>(c->myEdgeID));
     201            0 :             if (e == nullptr) {
     202            0 :                 e = ec.retrievePossiblySplit(toString<int>(c->myEdgeID), c->myPosition);
     203              :             }
     204            0 :             if (e == nullptr) {
     205            0 :                 WRITE_WARNINGF(TL("Could not build district '%' - edge '%' is missing."), toString<int>((*k).first), toString<int>(c->myEdgeID));
     206            0 :                 continue;
     207              :             }
     208            0 :             std::string id = "ParkingPlace" + toString<int>(*l);
     209            0 :             NBNode* parkingPlace = nc.retrieve(id);
     210            0 :             if (parkingPlace == nullptr) {
     211              :                 double pos = c->getPosition();
     212            0 :                 if (pos < e->getLength() - pos) {
     213              :                     parkingPlace = e->getFromNode();
     214            0 :                     parkingPlace->invalidateIncomingConnections();
     215              :                 } else {
     216              :                     parkingPlace = e->getToNode();
     217            0 :                     parkingPlace->invalidateOutgoingConnections();
     218              :                 }
     219              :             }
     220              :             assert(
     221              :                 e->getToNode() == parkingPlace
     222              :                 ||
     223              :                 e->getFromNode() == parkingPlace);
     224              : 
     225              :             // build the connection to the source
     226            0 :             if (e->getFromNode() == parkingPlace) {
     227            0 :                 id = "VissimFromParkingplace" + toString<int>((*k).first) + "-" + toString<int>(c->myID);
     228              :                 NBEdge* source =
     229              :                     new NBEdge(id, districtNode, parkingPlace,
     230            0 :                                "Connection", c->getMeanSpeed(/*distc*/) / 3.6, NBEdge::UNSPECIFIED_FRICTION, 3, -1,
     231            0 :                                NBEdge::UNSPECIFIED_WIDTH, NBEdge::UNSPECIFIED_OFFSET, LaneSpreadFunction::RIGHT);
     232            0 :                 if (!ec.insert(source)) { // !!! in den Konstruktor
     233            0 :                     throw 1; // !!!
     234              :                 }
     235              :                 double percNormed =
     236            0 :                     c->myPercentages[(*k).first];
     237            0 :                 if (!district->addSource(source, percNormed)) {
     238            0 :                     throw 1;
     239              :                 }
     240              :             }
     241              : 
     242              :             // build the connection to the destination
     243            0 :             if (e->getToNode() == parkingPlace) {
     244            0 :                 id = "VissimToParkingplace"  + toString<int>((*k).first) + "-" + toString<int>(c->myID);
     245              :                 NBEdge* destination =
     246              :                     new NBEdge(id, parkingPlace, districtNode,
     247              :                                "Connection", 100. / 3.6, NBEdge::UNSPECIFIED_FRICTION, 2, -1,
     248            0 :                                NBEdge::UNSPECIFIED_WIDTH, NBEdge::UNSPECIFIED_OFFSET, LaneSpreadFunction::RIGHT);
     249            0 :                 if (!ec.insert(destination)) { // !!! (in den Konstruktor)
     250            0 :                     throw 1; // !!!
     251              :                 }
     252              :                 double percNormed2 =
     253            0 :                     c->myPercentages[(*k).first];
     254            0 :                 if (!district->addSink(destination, percNormed2)) {
     255            0 :                     throw 1; // !!!
     256              :                 }
     257              :             }
     258              : 
     259              :             /*
     260              :             if(e->getToNode()==districtNode) {
     261              :             double percNormed =
     262              :                 c->myPercentages[(*k).first];
     263              :             district->addSink(e, percNormed);
     264              :             }
     265              :             if(e->getFromNode()==districtNode) {
     266              :             double percNormed =
     267              :                 c->myPercentages[(*k).first];
     268              :             district->addSource(e, percNormed);
     269              :             }
     270              :             */
     271              :         }
     272              : 
     273              :         /*
     274              :         // add them as sources and sinks to the current district
     275              :         for(std::vector<int>::const_iterator l=connections.begin(); l!=connections.end(); l++) {
     276              :             // get the current connections
     277              :             NIVissimDistrictConnection *c = dictionary(*l);
     278              :             // get the edge to connect the parking place to
     279              :             NBEdge *e = NBEdgeCont::retrieve(toString<int>(c->myEdgeID));
     280              :             Position edgepos = c->geomPosition();
     281              :             NBNode *edgeend = e->tryGetNodeAtPosition(c->myPosition,
     282              :                 e->getLength()/4.0);
     283              :             if(edgeend==0) {
     284              :                 // Edge splitting omitted on build district connections by now
     285              :                 assert(false);
     286              :             }
     287              : 
     288              :             // build the district-node if not yet existing
     289              :             std::string id = "VissimParkingplace" + district->getID();
     290              :             NBNode *districtNode = nc.retrieve(id);
     291              :             assert(districtNode!=0);
     292              : 
     293              :             if(e->getToNode()==edgeend) {
     294              :                 // build the connection to the source
     295              :                 id = std::string("VissimFromParkingplace")
     296              :                     + toString<int>((*k).first) + "-"
     297              :                     + toString<int>(c->myID);
     298              :                 NBEdge *source =
     299              :                     new NBEdge(id, id, districtNode, edgeend,
     300              :                     "Connection", 100/3.6, 2, 100, 0,
     301              :                     NBEdge::EDGEFUNCTION_SOURCE);
     302              :                 NBEdgeCont::insert(source); // !!! (in den Konstruktor)
     303              :                 double percNormed =
     304              :                     c->myPercentages[(*k).first];
     305              :                 district->addSource(source, percNormed);
     306              :             } else {
     307              :                 // build the connection to the destination
     308              :                 id = std::string("VissimToParkingplace")
     309              :                     + toString<int>((*k).first) + "-"
     310              :                     + toString<int>(c->myID);
     311              :                 NBEdge *destination =
     312              :                     new NBEdge(id, id, edgeend, districtNode,
     313              :                     "Connection", 100/3.6, 2, 100, 0,
     314              :                     NBEdge::EDGEFUNCTION_SINK);
     315              :                 NBEdgeCont::insert(destination); // !!! (in den Konstruktor)
     316              : 
     317              :                 // add both the source and the sink to the district
     318              :                 double percNormed =
     319              :                     c->myPercentages[(*k).first];
     320              :                 district->addSink(destination, percNormed);
     321              :             }
     322              :         }
     323              :         */
     324              :     }
     325            9 : }
     326              : 
     327              : 
     328              : 
     329              : Position
     330            0 : NIVissimDistrictConnection::geomPosition() const {
     331            0 :     NIVissimAbstractEdge* e = NIVissimEdge::dictionary(myEdgeID);
     332            0 :     return e->getGeomPosition(myPosition);
     333              : }
     334              : 
     335              : 
     336              : NIVissimDistrictConnection*
     337            0 : NIVissimDistrictConnection::dict_findForEdge(int edgeid) {
     338            0 :     for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
     339            0 :         if ((*i).second->myEdgeID == edgeid) {
     340              :             return (*i).second;
     341              :         }
     342              :     }
     343              :     return nullptr;
     344              : }
     345              : 
     346              : 
     347              : void
     348            9 : NIVissimDistrictConnection::clearDict() {
     349            9 :     for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
     350            0 :         delete (*i).second;
     351              :     }
     352              :     myDict.clear();
     353            9 : }
     354              : 
     355              : 
     356              : double
     357            0 : NIVissimDistrictConnection::getMeanSpeed() const {
     358              :     //assert(myAssignedVehicles.size()!=0);
     359            0 :     if (myAssignedVehicles.size() == 0) {
     360            0 :         WRITE_WARNINGF(TL("No streams assigned at district'%'.\n Using default speed 200km/h"), toString(myID));
     361            0 :         return (double) 200 / (double) 3.6;
     362              :     }
     363              :     double speed = 0;
     364              :     std::vector<std::pair<int, int> >::const_iterator i;
     365            0 :     for (i = myAssignedVehicles.begin(); i != myAssignedVehicles.end(); i++) {
     366            0 :         speed += getRealSpeed((*i).second);
     367              :     }
     368            0 :     return speed / (double) myAssignedVehicles.size();
     369              : }
     370              : 
     371              : 
     372              : double
     373            0 : NIVissimDistrictConnection::getRealSpeed(int distNo) const {
     374            0 :     std::string id = toString<int>(distNo);
     375            0 :     Distribution* dist = DistributionCont::dictionary("speed", id);
     376            0 :     if (dist == nullptr) {
     377            0 :         WRITE_WARNINGF(TL("The referenced speed distribution '%' is not known."), id);
     378            0 :         WRITE_WARNING(TL(". Using default."));
     379            0 :         return OptionsCont::getOptions().getFloat("vissim.default-speed");
     380              :     }
     381              :     assert(dist != 0);
     382            0 :     double speed = dist->getMax();
     383            0 :     if (speed < 0 || speed > 1000) {
     384            0 :         WRITE_WARNING(" False speed at district '" + id);
     385            0 :         WRITE_WARNING(TL(". Using default."));
     386            0 :         speed = OptionsCont::getOptions().getFloat("vissim.default-speed");
     387              :     }
     388              :     return speed;
     389              : }
     390              : 
     391              : 
     392              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1