SUMO - Simulation of Urban MObility

NIVissimDisturbance.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 
00031 #include <map>
00032 #include <string>
00033 #include <iostream>
00034 #include <cassert>
00035 #include <utils/common/ToString.h>
00036 #include <utils/common/MsgHandler.h>
00037 #include <utils/geom/GeomHelper.h>
00038 #include <utils/geom/Boundary.h>
00039 #include <netbuild/NBEdge.h>
00040 #include <netbuild/NBNode.h>
00041 #include <netbuild/NBEdgeCont.h>
00042 #include <netbuild/NBNodeCont.h>
00043 #include "NIVissimEdge.h"
00044 #include "NIVissimConnection.h"
00045 #include "NIVissimNodeDef.h"
00046 #include "NIVissimDisturbance.h"
00047 #include "NIVissimNodeParticipatingEdgeVector.h"
00048 
00049 #ifdef CHECK_MEMORY_LEAKS
00050 #include <foreign/nvwa/debug_new.h>
00051 #endif // CHECK_MEMORY_LEAKS
00052 // ===========================================================================
00053 // used namespaces
00054 // ===========================================================================
00055 
00056 using namespace std;
00057 
00058 NIVissimDisturbance::DictType NIVissimDisturbance::myDict;
00059 int NIVissimDisturbance::myRunningID = 100000000;
00060 
00061 int NIVissimDisturbance::refusedProhibits = 0;
00062 
00063 
00064 NIVissimDisturbance::NIVissimDisturbance(int id,
00065         const std::string& name,
00066         const NIVissimExtendedEdgePoint& edge,
00067         const NIVissimExtendedEdgePoint& by,
00068         SUMOReal timegap, SUMOReal waygap,
00069         SUMOReal vmax)
00070     : myID(id), myNode(-1), myName(name), myEdge(edge), myDisturbance(by),
00071       myTimeGap(timegap), myWayGap(waygap), myVMax(vmax) {}
00072 
00073 
00074 NIVissimDisturbance::~NIVissimDisturbance() {}
00075 
00076 
00077 
00078 bool
00079 NIVissimDisturbance::dictionary(int id,
00080                                 const std::string& name,
00081                                 const NIVissimExtendedEdgePoint& edge,
00082                                 const NIVissimExtendedEdgePoint& by,
00083                                 SUMOReal timegap, SUMOReal waygap, SUMOReal vmax) {
00084     UNUSED_PARAMETER(id);
00085     int nid = myRunningID++;
00086     NIVissimDisturbance* o =
00087         new NIVissimDisturbance(nid, name, edge, by, timegap, waygap, vmax);
00088     if (!dictionary(nid, o)) {
00089         delete o;
00090     }
00091     return true;
00092 }
00093 
00094 
00095 bool
00096 NIVissimDisturbance::dictionary(int id, NIVissimDisturbance* o) {
00097     DictType::iterator i=myDict.find(id);
00098     if (i==myDict.end()) {
00099         myDict[id] = o;
00100         return true;
00101     }
00102     return false;
00103 }
00104 
00105 
00106 NIVissimDisturbance*
00107 NIVissimDisturbance::dictionary(int id) {
00108     DictType::iterator i=myDict.find(id);
00109     if (i==myDict.end()) {
00110         return 0;
00111     }
00112     return (*i).second;
00113 }
00114 
00115 IntVector
00116 NIVissimDisturbance::getWithin(const AbstractPoly& poly) {
00117     IntVector ret;
00118     for (DictType::iterator i=myDict.begin(); i!=myDict.end(); i++) {
00119         if ((*i).second->crosses(poly)) {
00120             ret.push_back((*i).second->myID);
00121         }
00122     }
00123     return ret;
00124 }
00125 
00126 
00127 void
00128 NIVissimDisturbance::computeBounding() {
00129     assert(myBoundary==0);
00130     Boundary* bound = new Boundary();
00131     if (NIVissimAbstractEdge::dictionary(myEdge.getEdgeID())!=0) {
00132         bound->add(myEdge.getGeomPosition());
00133     }
00134     if (NIVissimAbstractEdge::dictionary(myDisturbance.getEdgeID())!=0) {
00135         bound->add(myDisturbance.getGeomPosition());
00136     }
00137     myBoundary = bound;
00138     assert(myBoundary!=0&&myBoundary->xmax()>=myBoundary->xmin());
00139 }
00140 
00141 
00142 
00143 bool
00144 NIVissimDisturbance::addToNode(NBNode* node, NBDistrictCont& dc,
00145                                NBNodeCont& nc, NBEdgeCont& ec) {
00146     myNode = 0;
00147     NIVissimConnection* pc =
00148         NIVissimConnection::dictionary(myEdge.getEdgeID());
00149     NIVissimConnection* bc =
00150         NIVissimConnection::dictionary(myDisturbance.getEdgeID());
00151     if (pc==0 && bc==0) {
00152         // This has not been tested completely, yet
00153         // Both competing abstract edges are normal edges
00154         // We have to find a crossing point, build a node here,
00155         //  split both edges and add the connections
00156         NIVissimEdge* e1 = NIVissimEdge::dictionary(myEdge.getEdgeID());
00157         NIVissimEdge* e2 = NIVissimEdge::dictionary(myDisturbance.getEdgeID());
00158         WRITE_WARNING("Ugly split to prohibit '" + toString<int>(e1->getID())+ "' by '" + toString<int>(e2->getID())+ "'.");
00159         Position pos = e1->crossesEdgeAtPoint(e2);
00160         std::string id1 = toString<int>(e1->getID()) + "x" + toString<int>(e2->getID());
00161         std::string id2 = toString<int>(e2->getID()) + "x" + toString<int>(e1->getID());
00162         NBNode* node1 = nc.retrieve(id1);
00163         NBNode* node2 = nc.retrieve(id2);
00164         NBNode* node = 0;
00165         assert(node1==0||node2==0);
00166         if (node1==0&&node2==0) {
00167             refusedProhibits++;
00168             return false;
00169             /*            node = new NBNode(id1, pos.x(), pos.y(), "priority");
00170                         if(!myNodeCont.insert(node)) {
00171                              "nope, NIVissimDisturbance" << endl;
00172                             throw 1;
00173                         }*/
00174         } else {
00175             node = node1==0 ? node2 : node1;
00176         }
00177         ec.splitAt(dc,
00178                    ec.retrievePossiblySplitted(
00179                        toString<int>(e1->getID()), myEdge.getPosition()),
00180                    node);
00181         ec.splitAt(dc,
00182                    ec.retrievePossiblySplitted(
00183                        toString<int>(e2->getID()), myDisturbance.getPosition()),
00184                    node);
00185         // !!! in some cases, one of the edges is not being build because it's too short
00186         // !!! what to do in these cases?
00187         NBEdge* mayDriveFrom = ec.retrieve(toString<int>(e1->getID()) + "[0]");
00188         NBEdge* mayDriveTo = ec.retrieve(toString<int>(e1->getID()) + "[1]");
00189         NBEdge* mustStopFrom = ec.retrieve(toString<int>(e2->getID()) + "[0]");
00190         NBEdge* mustStopTo = ec.retrieve(toString<int>(e2->getID()) + "[1]");
00191         if (mayDriveFrom!=0&&mayDriveTo!=0&&mustStopFrom!=0&&mustStopTo!=0) {
00192             node->addSortedLinkFoes(
00193                 NBConnection(mayDriveFrom, mayDriveTo),
00194                 NBConnection(mayDriveFrom, mayDriveTo));
00195         } else {
00196             refusedProhibits++;
00197             return false;
00198             // !!! warning
00199         }
00200 //        }
00201     } else if (pc!=0 && bc==0) {
00202         // The prohibited abstract edge is a connection, the other
00203         //  is not;
00204         // The connection will be prohibitesd by all connections
00205         //  outgoing from the "real" edge
00206 
00207         NBEdge* e = ec.retrievePossiblySplitted(toString<int>(myDisturbance.getEdgeID()), myDisturbance.getPosition());
00208         if (e==0) {
00209             WRITE_WARNING("Could not prohibit '"+ toString<int>(myEdge.getEdgeID()) + "' by '" + toString<int>(myDisturbance.getEdgeID())+ "'. Have not found disturbance.");
00210             refusedProhibits++;
00211             return false;
00212         }
00213         if (e->getFromNode()==e->getToNode()) {
00214             WRITE_WARNING("Could not prohibit '"+ toString<int>(myEdge.getEdgeID()) + "' by '" + toString<int>(myDisturbance.getEdgeID())+ "'. Disturbance connects same node.");
00215             refusedProhibits++;
00216             // What to do with dummy edges?
00217             return false;
00218         }
00219         // get the begin of the prohibited connection
00220         std::string id_pcoe = toString<int>(pc->getFromEdgeID());
00221         std::string id_pcie = toString<int>(pc->getToEdgeID());
00222         NBEdge* pcoe = ec.retrievePossiblySplitted(id_pcoe, id_pcie, true);
00223         NBEdge* pcie = ec.retrievePossiblySplitted(id_pcie, id_pcoe, false);
00224         // check whether it's ending node is the node the prohibited
00225         //  edge end at
00226         if (pcoe!=0&&pcie!=0&&pcoe->getToNode()==e->getToNode()) {
00227             // if so, simply prohibit the connections
00228             NBNode* node = e->getToNode();
00229             const EdgeVector& connected = e->getConnectedEdges();
00230             for (EdgeVector::const_iterator i=connected.begin(); i!=connected.end(); i++) {
00231                 node->addSortedLinkFoes(
00232                     NBConnection(e, *i),
00233                     NBConnection(pcoe, pcie));
00234             }
00235         } else {
00236             WRITE_WARNING("Would have to split edge '" + e->getID() + "' to build a prohibition");
00237             refusedProhibits++;
00238             // quite ugly - why was it not build?
00239             return false;
00240             /*
00241             std::string nid1 = e->getID() + "[0]";
00242             std::string nid2 = e->getID() + "[1]";
00243 
00244             if(ec.splitAt(e, node)) {
00245                 node->addSortedLinkFoes(
00246                         NBConnection(
00247                             ec.retrieve(nid1),
00248                             ec.retrieve(nid2)
00249                         ),
00250                         getConnection(node, myEdge.getEdgeID())
00251                     );
00252             }
00253             */
00254         }
00255     } else if (bc!=0 && pc==0) {
00256         // The prohibiting abstract edge is a connection, the other
00257         //  is not;
00258         // We have to split the other one and add the prohibition
00259         //  description
00260 
00261         NBEdge* e = ec.retrievePossiblySplitted(
00262                         toString<int>(myEdge.getEdgeID()), myEdge.getPosition());
00263         if (e==0) {
00264             WRITE_WARNING("Could not prohibit '" + toString<int>(myEdge.getEdgeID()) + "' - it was not built.");
00265             return false;
00266         }
00267         std::string nid1 = e->getID() + "[0]";
00268         std::string nid2 = e->getID() + "[1]";
00269         if (e->getFromNode()==e->getToNode()) {
00270             WRITE_WARNING("Could not prohibit '" + toString<int>(myEdge.getEdgeID()) + "' by '" + toString<int>(myDisturbance.getEdgeID())+ "'.");
00271             refusedProhibits++;
00272             // What to do with dummy edges?
00273             return false;
00274         }
00275         // get the begin of the prohibiting connection
00276         std::string id_bcoe = toString<int>(bc->getFromEdgeID());
00277         std::string id_bcie = toString<int>(bc->getToEdgeID());
00278         NBEdge* bcoe = ec.retrievePossiblySplitted(id_bcoe, id_bcie, true);
00279         NBEdge* bcie = ec.retrievePossiblySplitted(id_bcie, id_bcoe, false);
00280         // check whether it's ending node is the node the prohibited
00281         //  edge end at
00282         if (bcoe!=0&&bcie!=0&&bcoe->getToNode()==e->getToNode()) {
00283             // if so, simply prohibit the connections
00284             NBNode* node = e->getToNode();
00285             const EdgeVector& connected = e->getConnectedEdges();
00286             for (EdgeVector::const_iterator i=connected.begin(); i!=connected.end(); i++) {
00287                 node->addSortedLinkFoes(
00288                     NBConnection(bcoe, bcie),
00289                     NBConnection(e, *i));
00290             }
00291         } else {
00292             WRITE_WARNING("Would have to split edge '" + e->getID() + "' to build a prohibition");
00293             refusedProhibits++;
00294             return false;
00295             /*
00296             // quite ugly - why was it not build?
00297             if(ec.splitAt(e, node)) {
00298                 node->addSortedLinkFoes(
00299                         getConnection(node, myDisturbance.getEdgeID()),
00300                         NBConnection(
00301                             ec.retrieve(nid1),
00302                             ec.retrieve(nid2)
00303                         )
00304                     );
00305             }
00306             */
00307         }
00308     } else {
00309         // both the prohibiting and the prohibited abstract edges
00310         //  are connections
00311         // We can retrieve the conected edges and add the desription
00312         NBConnection conn1 = getConnection(node, myDisturbance.getEdgeID());
00313         NBConnection conn2 = getConnection(node, myEdge.getEdgeID());
00314         if (!conn1.check(ec)||!conn2.check(ec)) {
00315             refusedProhibits++;
00316             return false;
00317         }
00318         node->addSortedLinkFoes(conn1, conn2);
00319     }
00320     return true;
00321 }
00322 
00323 
00324 NBConnection
00325 NIVissimDisturbance::getConnection(NBNode* node, int aedgeid) {
00326     if (NIVissimEdge::dictionary(myEdge.getEdgeID())==0) {
00327         NIVissimConnection* c = NIVissimConnection::dictionary(aedgeid);
00328         NBEdge* from =
00329             node->getPossiblySplittedIncoming(toString<int>(c->getFromEdgeID()));
00330         NBEdge* to =
00331             node->getPossiblySplittedOutgoing(toString<int>(c->getToEdgeID()));
00332 
00333         // source is a connection
00334         return NBConnection(toString<int>(c->getFromEdgeID()), from,
00335                             toString<int>(c->getToEdgeID()), to);
00336     } else {
00337         WRITE_WARNING("NIVissimDisturbance: no connection");
00338         return NBConnection(0, 0);
00339 //        throw 1; // !!! what to do?
00340     }
00341 
00342 }
00343 
00344 void
00345 NIVissimDisturbance::clearDict() {
00346     for (DictType::iterator i=myDict.begin(); i!=myDict.end(); i++) {
00347         delete(*i).second;
00348     }
00349     myDict.clear();
00350 }
00351 
00352 
00353 void
00354 NIVissimDisturbance::dict_SetDisturbances() {
00355     for (DictType::iterator i=myDict.begin(); i!=myDict.end(); i++) {
00356         NIVissimDisturbance* d = (*i).second;
00357         NIVissimAbstractEdge::dictionary(d->myEdge.getEdgeID())->addDisturbance((*i).first);
00358         NIVissimAbstractEdge::dictionary(d->myDisturbance.getEdgeID())->addDisturbance((*i).first);
00359     }
00360     /*    for(DictType::iterator i=myDict.begin(); i!=myDict.end(); i++) {
00361             delete (*i).second;
00362         }
00363         */
00364 }
00365 
00366 
00367 void
00368 NIVissimDisturbance::reportRefused() {
00369     if (refusedProhibits>0) {
00370         WRITE_WARNING("Could not build " + toString<size_t>(refusedProhibits)+ " of " + toString<size_t>(myDict.size())+ " disturbances.");
00371     }
00372 }
00373 
00374 
00375 
00376 /****************************************************************************/
00377 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines