SUMO - Simulation of Urban MObility

NIVissimDistrictConnection.cpp

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