|
SUMO - Simulation of Urban MObility
|
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