SUMO - Simulation of Urban MObility
NIVissimDistrictConnection.cpp
Go to the documentation of this file.
00001 /****************************************************************************/
00009 // -------------------
00010 /****************************************************************************/
00011 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00012 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
00013 /****************************************************************************/
00014 //
00015 //   This file is part of SUMO.
00016 //   SUMO is free software: you can redistribute it and/or modify
00017 //   it under the terms of the GNU General Public License as published by
00018 //   the Free Software Foundation, either version 3 of the License, or
00019 //   (at your option) any later version.
00020 //
00021 /****************************************************************************/
00022 
00023 
00024 // ===========================================================================
00025 // included modules
00026 // ===========================================================================
00027 #ifdef _MSC_VER
00028 #include <windows_config.h>
00029 #else
00030 #include <config.h>
00031 #endif
00032 
00033 #include <map>
00034 #include <string>
00035 #include <algorithm>
00036 #include <cassert>
00037 #include <utils/common/VectorHelper.h>
00038 #include <utils/common/ToString.h>
00039 #include <utils/geom/Position.h>
00040 #include <utils/geom/GeomHelper.h>
00041 #include <utils/geom/PositionVector.h>
00042 #include <utils/options/OptionsCont.h>
00043 #include "NIVissimAbstractEdge.h"
00044 #include "NIVissimEdge.h"
00045 #include <netbuild/NBEdge.h>
00046 #include <netbuild/NBEdgeCont.h>
00047 #include <netbuild/NBNode.h>
00048 #include <netbuild/NBNodeCont.h>
00049 #include <netbuild/NBDistrict.h>
00050 #include <netbuild/NBDistrictCont.h>
00051 #include "NIVissimDistrictConnection.h"
00052 #include <utils/distribution/Distribution.h>
00053 #include <netbuild/NBDistribution.h>
00054 #include <utils/common/MsgHandler.h>
00055 
00056 #ifdef CHECK_MEMORY_LEAKS
00057 #include <foreign/nvwa/debug_new.h>
00058 #endif // CHECK_MEMORY_LEAKS
00059 
00060 
00061 // ===========================================================================
00062 // static member definitions
00063 // ===========================================================================
00064 NIVissimDistrictConnection::DictType NIVissimDistrictConnection::myDict;
00065 std::map<int, std::vector<int> > NIVissimDistrictConnection::myDistrictsConnections;
00066 
00067 
00068 // ===========================================================================
00069 // method definitions
00070 // ===========================================================================
00071 NIVissimDistrictConnection::NIVissimDistrictConnection(int id,
00072         const std::string& name,
00073         const std::vector<int>& districts, const std::vector<SUMOReal>& percentages,
00074         int edgeid, SUMOReal position,
00075         const std::vector<std::pair<int, int> > &assignedVehicles)
00076     : myID(id), myName(name), myDistricts(districts),
00077       myEdgeID(edgeid), myPosition(position),
00078       myAssignedVehicles(assignedVehicles) {
00079     std::vector<int>::iterator i = myDistricts.begin();
00080     std::vector<SUMOReal>::const_iterator j = percentages.begin();
00081     while (i != myDistricts.end()) {
00082         myPercentages[*i] = *j;
00083         i++;
00084         j++;
00085     }
00086 }
00087 
00088 
00089 NIVissimDistrictConnection::~NIVissimDistrictConnection() {}
00090 
00091 
00092 
00093 bool
00094 NIVissimDistrictConnection::dictionary(int id, const std::string& name,
00095                                        const std::vector<int>& districts, const std::vector<SUMOReal>& percentages,
00096                                        int edgeid, SUMOReal position,
00097                                        const std::vector<std::pair<int, int> > &assignedVehicles) {
00098     NIVissimDistrictConnection* o =
00099         new NIVissimDistrictConnection(id, name, districts, percentages,
00100                                        edgeid, position, assignedVehicles);
00101     if (!dictionary(id, o)) {
00102         delete o;
00103         return false;
00104     }
00105     return true;
00106 }
00107 
00108 
00109 bool
00110 NIVissimDistrictConnection::dictionary(int id, NIVissimDistrictConnection* o) {
00111     DictType::iterator i = myDict.find(id);
00112     if (i == myDict.end()) {
00113         myDict[id] = o;
00114         return true;
00115     }
00116     return false;
00117 }
00118 
00119 
00120 NIVissimDistrictConnection*
00121 NIVissimDistrictConnection::dictionary(int id) {
00122     DictType::iterator i = myDict.find(id);
00123     if (i == myDict.end()) {
00124         return 0;
00125     }
00126     return (*i).second;
00127 }
00128 
00129 void
00130 NIVissimDistrictConnection::dict_BuildDistrictConnections() {
00131     //  pre-assign connections to districts
00132     for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
00133         NIVissimDistrictConnection* c = (*i).second;
00134         const std::vector<int>& districts = c->myDistricts;
00135         for (std::vector<int>::const_iterator j = districts.begin(); j != districts.end(); j++) {
00136             // assign connection to district
00137             myDistrictsConnections[*j].push_back((*i).first);
00138         }
00139     }
00140 }
00141 
00142 
00143 void
00144 NIVissimDistrictConnection::dict_CheckEdgeEnds() {
00145     for (std::map<int, std::vector<int> >::iterator k = myDistrictsConnections.begin(); k != myDistrictsConnections.end(); k++) {
00146         const std::vector<int>& connections = (*k).second;
00147         for (std::vector<int>::const_iterator j = connections.begin(); j != connections.end(); j++) {
00148             NIVissimDistrictConnection* c = dictionary(*j);
00149             c->checkEdgeEnd();
00150         }
00151     }
00152 }
00153 
00154 
00155 void
00156 NIVissimDistrictConnection::checkEdgeEnd() {
00157     NIVissimEdge* edge = NIVissimEdge::dictionary(myEdgeID);
00158     assert(edge != 0);
00159     edge->checkDistrictConnectionExistanceAt(myPosition);
00160 }
00161 
00162 
00163 void
00164 NIVissimDistrictConnection::dict_BuildDistrictNodes(NBDistrictCont& dc,
00165         NBNodeCont& nc) {
00166     for (std::map<int, std::vector<int> >::iterator k = myDistrictsConnections.begin(); k != myDistrictsConnections.end(); k++) {
00167         // get the connections
00168         const std::vector<int>& connections = (*k).second;
00169         // retrieve the current district
00170         std::string dsid = toString<int>((*k).first);
00171         NBDistrict* district = new NBDistrict(dsid);
00172         dc.insert(district);
00173         // compute the middle of the district
00174         PositionVector pos;
00175         for (std::vector<int>::const_iterator j = connections.begin(); j != connections.end(); j++) {
00176             NIVissimDistrictConnection* c = dictionary(*j);
00177             pos.push_back(c->geomPosition());
00178         }
00179         Position distCenter = pos.getPolygonCenter();
00180         if (connections.size() == 1) { // !!! ok, ok, maybe not the best way just to add an offset
00181             distCenter.add(10, 10);
00182         }
00183         district->setCenter(distCenter);
00184         // build the node
00185         std::string id = "District" + district->getID();
00186         NBNode* districtNode =
00187             new NBNode(id, district->getPosition(), district);
00188         if (!nc.insert(districtNode)) {
00189             throw 1;
00190         }
00191     }
00192 }
00193 
00194 void
00195 NIVissimDistrictConnection::dict_BuildDistricts(NBDistrictCont& dc,
00196         NBEdgeCont& ec,
00197         NBNodeCont& nc/*,
00198                                                                                 NBDistribution &distc*/) {
00199     // add the sources and sinks
00200     //  their normalised probability is computed within NBDistrict
00201     //   to avoid SUMOReal code writing and more securty within the converter
00202     //  go through the district table
00203     for (std::map<int, std::vector<int> >::iterator k = myDistrictsConnections.begin(); k != myDistrictsConnections.end(); k++) {
00204         // get the connections
00205         const std::vector<int>& connections = (*k).second;
00206         // retrieve the current district
00207         NBDistrict* district =
00208             dc.retrieve(toString<int>((*k).first));
00209         NBNode* districtNode = nc.retrieve("District" + district->getID());
00210         assert(district != 0 && districtNode != 0);
00211 
00212         for (std::vector<int>::const_iterator l = connections.begin(); l != connections.end(); l++) {
00213             NIVissimDistrictConnection* c = dictionary(*l);
00214             // get the edge to connect the parking place to
00215             NBEdge* e = ec.retrieve(toString<int>(c->myEdgeID));
00216             if (e == 0) {
00217                 e = ec.retrievePossiblySplitted(toString<int>(c->myEdgeID), c->myPosition);
00218             }
00219             if (e == 0) {
00220                 WRITE_WARNING("Could not build district '" + toString<int>((*k).first) + "' - edge '" + toString<int>(c->myEdgeID) + "' is missing.");
00221                 continue;
00222             }
00223             std::string id = "ParkingPlace" + toString<int>(*l);
00224             NBNode* parkingPlace = nc.retrieve(id);
00225             if (parkingPlace == 0) {
00226                 SUMOReal pos = c->getPosition();
00227                 if (pos < e->getLength() - pos) {
00228                     parkingPlace = e->getFromNode();
00229                     parkingPlace->invalidateIncomingConnections();
00230                 } else {
00231                     parkingPlace = e->getToNode();
00232                     parkingPlace->invalidateOutgoingConnections();
00233                 }
00234             }
00235             assert(
00236                 e->getToNode() == parkingPlace
00237                 ||
00238                 e->getFromNode() == parkingPlace);
00239 
00240             // build the connection to the source
00241             if (e->getFromNode() == parkingPlace) {
00242                 id = "VissimFromParkingplace" + toString<int>((*k).first) + "-" + toString<int>(c->myID);
00243                 NBEdge* source =
00244                     new NBEdge(id, districtNode, parkingPlace,
00245                                "Connection", c->getMeanSpeed(/*distc*/) / (SUMOReal) 3.6, 3, -1, -1, LANESPREAD_RIGHT);
00246                 if (!ec.insert(source)) { // !!! in den Konstruktor
00247                     throw 1; // !!!
00248                 }
00249                 SUMOReal percNormed =
00250                     c->myPercentages[(*k).first];
00251                 if (!district->addSource(source, percNormed)) {
00252                     throw 1;
00253                 }
00254             }
00255 
00256             // build the connection to the destination
00257             if (e->getToNode() == parkingPlace) {
00258                 id = "VissimToParkingplace"  + toString<int>((*k).first) + "-" + toString<int>(c->myID);
00259                 NBEdge* destination =
00260                     new NBEdge(id, parkingPlace, districtNode,
00261                                "Connection", (SUMOReal) 100 / (SUMOReal) 3.6, 2, -1, -1, LANESPREAD_RIGHT);
00262                 if (!ec.insert(destination)) { // !!! (in den Konstruktor)
00263                     throw 1; // !!!
00264                 }
00265                 SUMOReal percNormed2 =
00266                     c->myPercentages[(*k).first];
00267                 if (!district->addSink(destination, percNormed2)) {
00268                     throw 1; // !!!
00269                 }
00270             }
00271 
00272             /*
00273             if(e->getToNode()==districtNode) {
00274             SUMOReal percNormed =
00275                 c->myPercentages[(*k).first];
00276             district->addSink(e, percNormed);
00277             }
00278             if(e->getFromNode()==districtNode) {
00279             SUMOReal percNormed =
00280                 c->myPercentages[(*k).first];
00281             district->addSource(e, percNormed);
00282             }
00283             */
00284         }
00285 
00286         /*
00287         // add them as sources and sinks to the current district
00288         for(std::vector<int>::const_iterator l=connections.begin(); l!=connections.end(); l++) {
00289             // get the current connections
00290             NIVissimDistrictConnection *c = dictionary(*l);
00291             // get the edge to connect the parking place to
00292             NBEdge *e = NBEdgeCont::retrieve(toString<int>(c->myEdgeID));
00293             Position edgepos = c->geomPosition();
00294             NBNode *edgeend = e->tryGetNodeAtPosition(c->myPosition,
00295                 e->getLength()/4.0);
00296             if(edgeend==0) {
00297                 // Edge splitting omitted on build district connections by now
00298                 assert(false);
00299             }
00300 
00301             // build the district-node if not yet existing
00302             std::string id = "VissimParkingplace" + district->getID();
00303             NBNode *districtNode = nc.retrieve(id);
00304             assert(districtNode!=0);
00305 
00306             if(e->getToNode()==edgeend) {
00307                 // build the connection to the source
00308                 id = std::string("VissimFromParkingplace")
00309                     + toString<int>((*k).first) + "-"
00310                     + toString<int>(c->myID);
00311                 NBEdge *source =
00312                     new NBEdge(id, id, districtNode, edgeend,
00313                     "Connection", 100/3.6, 2, 100, 0,
00314                     NBEdge::EDGEFUNCTION_SOURCE);
00315                 NBEdgeCont::insert(source); // !!! (in den Konstruktor)
00316                 SUMOReal percNormed =
00317                     c->myPercentages[(*k).first];
00318                 district->addSource(source, percNormed);
00319             } else {
00320                 // build the connection to the destination
00321                 id = std::string("VissimToParkingplace")
00322                     + toString<int>((*k).first) + "-"
00323                     + toString<int>(c->myID);
00324                 NBEdge *destination =
00325                     new NBEdge(id, id, edgeend, districtNode,
00326                     "Connection", 100/3.6, 2, 100, 0,
00327                     NBEdge::EDGEFUNCTION_SINK);
00328                 NBEdgeCont::insert(destination); // !!! (in den Konstruktor)
00329 
00330                 // add both the source and the sink to the district
00331                 SUMOReal percNormed =
00332                     c->myPercentages[(*k).first];
00333                 district->addSink(destination, percNormed);
00334             }
00335         }
00336         */
00337     }
00338 }
00339 
00340 
00341 
00342 Position
00343 NIVissimDistrictConnection::geomPosition() const {
00344     NIVissimAbstractEdge* e = NIVissimEdge::dictionary(myEdgeID);
00345     return e->getGeomPosition(myPosition);
00346 }
00347 
00348 
00349 NIVissimDistrictConnection*
00350 NIVissimDistrictConnection::dict_findForEdge(int edgeid) {
00351     for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
00352         if ((*i).second->myEdgeID == edgeid) {
00353             return (*i).second;
00354         }
00355     }
00356     return 0;
00357 }
00358 
00359 
00360 void
00361 NIVissimDistrictConnection::clearDict() {
00362     for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
00363         delete(*i).second;
00364     }
00365     myDict.clear();
00366 }
00367 
00368 
00369 SUMOReal
00370 NIVissimDistrictConnection::getMeanSpeed(/*NBDistribution &dc*/) const {
00371     //assert(myAssignedVehicles.size()!=0);
00372     if (myAssignedVehicles.size() == 0) {
00373         WRITE_WARNING("No streams assigned at district'" + toString(myID) + "'.\n Using default speed 200km/h");
00374         return (SUMOReal) 200 / (SUMOReal) 3.6;
00375     }
00376     SUMOReal speed = 0;
00377     std::vector<std::pair<int, int> >::const_iterator i;
00378     for (i = myAssignedVehicles.begin(); i != myAssignedVehicles.end(); i++) {
00379         speed += getRealSpeed(/*dc, */(*i).second);
00380     }
00381     return speed / (SUMOReal) myAssignedVehicles.size();
00382 }
00383 
00384 
00385 SUMOReal
00386 NIVissimDistrictConnection::getRealSpeed(/*NBDistribution &dc, */int distNo) const {
00387     std::string id = toString<int>(distNo);
00388     Distribution* dist = NBDistribution::dictionary("speed", id);
00389     if (dist == 0) {
00390         WRITE_WARNING("The referenced speed distribution '" + id + "' is not known.");
00391         WRITE_WARNING(". Using default.");
00392         return OptionsCont::getOptions().getFloat("vissim.default-speed");
00393     }
00394     assert(dist != 0);
00395     SUMOReal speed = dist->getMax();
00396     if (speed < 0 || speed > 1000) {
00397         WRITE_WARNING(" False speed at district '" + id);
00398         WRITE_WARNING(". Using default.");
00399         speed = OptionsCont::getOptions().getFloat("vissim.default-speed");
00400     }
00401     return speed;
00402 }
00403 
00404 
00405 
00406 /****************************************************************************/
00407 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines