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