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

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