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