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 2001-2010 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/Position2D.h>
00037 #include <utils/geom/GeomHelper.h>
00038 #include <utils/geom/Position2DVector.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         Position2DVector 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         Position2D 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                 MsgHandler::getWarningInstance()->inform("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,
00243                                NBEdge::LANESPREAD_RIGHT);
00244                 if (!ec.insert(source)) { // !!! in den Konstruktor
00245                     throw 1; // !!!
00246                 }
00247                 SUMOReal percNormed =
00248                     c->myPercentages[(*k).first];
00249                 if (!district->addSource(source, percNormed)) {
00250                     throw 1;
00251                 }
00252             }
00253 
00254             // build the connection to the destination
00255             if (e->getToNode()==parkingPlace) {
00256                 id = "VissimToParkingplace"  + toString<int>((*k).first) + "-" + toString<int>(c->myID);
00257                 NBEdge *destination =
00258                     new NBEdge(id, parkingPlace, districtNode,
00259                                "Connection", (SUMOReal) 100/(SUMOReal) 3.6, 2, -1,
00260                                NBEdge::LANESPREAD_RIGHT);
00261                 if (!ec.insert(destination)) { // !!! (in den Konstruktor)
00262                     throw 1; // !!!
00263                 }
00264                 SUMOReal percNormed2 =
00265                     c->myPercentages[(*k).first];
00266                 if (!district->addSink(destination, percNormed2)) {
00267                     throw 1; // !!!
00268                 }
00269             }
00270 
00271             /*
00272             if(e->getToNode()==districtNode) {
00273             SUMOReal percNormed =
00274                 c->myPercentages[(*k).first];
00275             district->addSink(e, percNormed);
00276             }
00277             if(e->getFromNode()==districtNode) {
00278             SUMOReal percNormed =
00279                 c->myPercentages[(*k).first];
00280             district->addSource(e, percNormed);
00281             }
00282             */
00283         }
00284 
00285         /*
00286         // add them as sources and sinks to the current district
00287         for(IntVector::const_iterator l=connections.begin(); l!=connections.end(); l++) {
00288             // get the current connections
00289             NIVissimDistrictConnection *c = dictionary(*l);
00290             // get the edge to connect the parking place to
00291             NBEdge *e = NBEdgeCont::retrieve(toString<int>(c->myEdgeID));
00292             Position2D edgepos = c->geomPosition();
00293             NBNode *edgeend = e->tryGetNodeAtPosition(c->myPosition,
00294                 e->getLength()/4.0);
00295             if(edgeend==0) {
00296                 // Edge splitting omitted on build district connections by now
00297                 assert(false);
00298             }
00299 
00300             // build the district-node if not yet existing
00301             std::string id = "VissimParkingplace" + district->getID();
00302             NBNode *districtNode = nc.retrieve(id);
00303             assert(districtNode!=0);
00304 
00305             if(e->getToNode()==edgeend) {
00306                 // build the connection to the source
00307                 id = std::string("VissimFromParkingplace")
00308                     + toString<int>((*k).first) + "-"
00309                     + toString<int>(c->myID);
00310                 NBEdge *source =
00311                     new NBEdge(id, id, districtNode, edgeend,
00312                     "Connection", 100/3.6, 2, 100, 0,
00313                     NBEdge::EDGEFUNCTION_SOURCE);
00314                 NBEdgeCont::insert(source); // !!! (in den Konstruktor)
00315                 SUMOReal percNormed =
00316                     c->myPercentages[(*k).first];
00317                 district->addSource(source, percNormed);
00318             } else {
00319                 // build the connection to the destination
00320                 id = std::string("VissimToParkingplace")
00321                     + toString<int>((*k).first) + "-"
00322                     + toString<int>(c->myID);
00323                 NBEdge *destination =
00324                     new NBEdge(id, id, edgeend, districtNode,
00325                     "Connection", 100/3.6, 2, 100, 0,
00326                     NBEdge::EDGEFUNCTION_SINK);
00327                 NBEdgeCont::insert(destination); // !!! (in den Konstruktor)
00328 
00329                 // add both the source and the sink to the district
00330                 SUMOReal percNormed =
00331                     c->myPercentages[(*k).first];
00332                 district->addSink(destination, percNormed);
00333             }
00334         }
00335         */
00336     }
00337 }
00338 
00339 
00340 
00341 Position2D
00342 NIVissimDistrictConnection::geomPosition() const {
00343     NIVissimAbstractEdge *e = NIVissimEdge::dictionary(myEdgeID);
00344     return e->getGeomPosition(myPosition);
00345 }
00346 
00347 
00348 NIVissimDistrictConnection *
00349 NIVissimDistrictConnection::dict_findForEdge(int edgeid) {
00350     for (DictType::iterator i=myDict.begin(); i!=myDict.end(); i++) {
00351         if ((*i).second->myEdgeID==edgeid) {
00352             return (*i).second;
00353         }
00354     }
00355     return 0;
00356 }
00357 
00358 
00359 void
00360 NIVissimDistrictConnection::clearDict() {
00361     for (DictType::iterator i=myDict.begin(); i!=myDict.end(); i++) {
00362         delete(*i).second;
00363     }
00364     myDict.clear();
00365 }
00366 
00367 
00368 SUMOReal
00369 NIVissimDistrictConnection::getMeanSpeed(/*NBDistribution &dc*/) const {
00370     //assert(myAssignedVehicles.size()!=0);
00371     if (myAssignedVehicles.size()==0) {
00372         MsgHandler::getWarningInstance()->inform("No streams assigned at district'" + toString(myID) + "'.\n Using default speed 200km/h");
00373         return (SUMOReal) 200/(SUMOReal) 3.6;
00374     }
00375     SUMOReal speed = 0;
00376     std::vector<std::pair<int, int> >::const_iterator i;
00377     for (i=myAssignedVehicles.begin(); i!=myAssignedVehicles.end(); i++) {
00378         speed += getRealSpeed(/*dc, */(*i).second);
00379     }
00380     return speed / (SUMOReal) myAssignedVehicles.size();
00381 }
00382 
00383 
00384 SUMOReal
00385 NIVissimDistrictConnection::getRealSpeed(/*NBDistribution &dc, */int distNo) const {
00386     std::string id = toString<int>(distNo);
00387     Distribution *dist = NBDistribution::dictionary("speed", id);
00388     if (dist==0) {
00389         WRITE_WARNING("The referenced speed distribution '" + id + "' is not known.");
00390         WRITE_WARNING(". Using default.");
00391         return OptionsCont::getOptions().getFloat("vissim.default-speed");
00392     }
00393     assert(dist!=0);
00394     SUMOReal speed = dist->getMax();
00395     if (speed<0||speed>1000) {
00396         WRITE_WARNING(" False speed at district '" + id);
00397         WRITE_WARNING(". Using default.");
00398         speed = OptionsCont::getOptions().getFloat("vissim.default-speed");
00399     }
00400     return speed;
00401 }
00402 
00403 
00404 
00405 /****************************************************************************/
00406 

Generated on Wed May 5 00:06:34 2010 for Sumo - Simulation of Urban MObility by  doxygen 1.5.6