SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00011 // ------------------- 00012 /****************************************************************************/ 00013 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/ 00014 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors 00015 /****************************************************************************/ 00016 // 00017 // This file is part of SUMO. 00018 // SUMO is free software: you can redistribute it and/or modify 00019 // it under the terms of the GNU General Public License as published by 00020 // the Free Software Foundation, either version 3 of the License, or 00021 // (at your option) any later version. 00022 // 00023 /****************************************************************************/ 00024 00025 00026 // =========================================================================== 00027 // included modules 00028 // =========================================================================== 00029 #ifdef _MSC_VER 00030 #include <windows_config.h> 00031 #else 00032 #include <config.h> 00033 #endif 00034 00035 #include <string> 00036 #include <map> 00037 #include <iostream> 00038 #include <cassert> 00039 #include <utils/common/VectorHelper.h> 00040 #include <utils/common/MsgHandler.h> 00041 #include <utils/common/ToString.h> 00042 #include "NIVissimExtendedEdgePoint.h" 00043 #include <utils/geom/PositionVector.h> 00044 #include <utils/geom/Boundary.h> 00045 #include <utils/geom/GeomHelper.h> 00046 #include <netbuild/NBEdge.h> 00047 #include <netbuild/NBNode.h> 00048 #include <netbuild/NBEdgeCont.h> 00049 #include "NIVissimEdge.h" 00050 #include "NIVissimClosedLanesVector.h" 00051 #include "NIVissimNodeDef.h" 00052 #include "NIVissimConnection.h" 00053 #include <utils/common/UtilExceptions.h> 00054 00055 #ifdef CHECK_MEMORY_LEAKS 00056 #include <foreign/nvwa/debug_new.h> 00057 #endif // CHECK_MEMORY_LEAKS 00058 00059 00060 // =========================================================================== 00061 // static members 00062 // =========================================================================== 00063 NIVissimConnection::DictType NIVissimConnection::myDict; 00064 int NIVissimConnection::myMaxID; 00065 00066 00067 // =========================================================================== 00068 // method definitions 00069 // =========================================================================== 00070 NIVissimConnection::NIVissimConnection(int id, 00071 const std::string& name, const NIVissimExtendedEdgePoint& from_def, 00072 const NIVissimExtendedEdgePoint& to_def, 00073 const PositionVector& geom, Direction direction, 00074 SUMOReal dxnothalt, SUMOReal dxeinordnen, 00075 SUMOReal zuschlag1, SUMOReal zuschlag2, SUMOReal /*seglength*/, 00076 const std::vector<int>& assignedVehicles, const NIVissimClosedLanesVector& clv) 00077 : NIVissimAbstractEdge(id, geom), 00078 myName(name), myFromDef(from_def), myToDef(to_def), 00079 myDirection(direction), 00080 myDXNothalt(dxnothalt), myDXEinordnen(dxeinordnen), 00081 myZuschlag1(zuschlag1), myZuschlag2(zuschlag2), 00082 myAssignedVehicles(assignedVehicles), myClosedLanes(clv) {} 00083 00084 00085 NIVissimConnection::~NIVissimConnection() { 00086 for (NIVissimClosedLanesVector::iterator i = myClosedLanes.begin(); i != myClosedLanes.end(); i++) { 00087 delete(*i); 00088 } 00089 myClosedLanes.clear(); 00090 } 00091 00092 00093 bool 00094 NIVissimConnection::dictionary(int id, const std::string& name, 00095 const NIVissimExtendedEdgePoint& from_def, 00096 const NIVissimExtendedEdgePoint& to_def, 00097 const PositionVector& geom, 00098 Direction direction, 00099 SUMOReal dxnothalt, SUMOReal dxeinordnen, 00100 SUMOReal zuschlag1, SUMOReal zuschlag2, 00101 SUMOReal seglength, 00102 const std::vector<int>& assignedVehicles, 00103 const NIVissimClosedLanesVector& clv) { 00104 NIVissimConnection* o = new NIVissimConnection(id, name, from_def, to_def, 00105 geom, direction, dxnothalt, dxeinordnen, zuschlag1, zuschlag2, 00106 seglength, assignedVehicles, clv); 00107 if (!dictionary(id, o)) { 00108 delete o; 00109 return false; 00110 } 00111 if (myMaxID < id) { 00112 myMaxID = id; 00113 } 00114 return true; 00115 } 00116 00117 00118 00119 bool 00120 NIVissimConnection::dictionary(int id, NIVissimConnection* o) { 00121 DictType::iterator i = myDict.find(id); 00122 if (i == myDict.end()) { 00123 myDict[id] = o; 00124 return true; 00125 } 00126 return false; 00127 } 00128 00129 00130 00131 NIVissimConnection* 00132 NIVissimConnection::dictionary(int id) { 00133 DictType::iterator i = myDict.find(id); 00134 if (i == myDict.end()) { 00135 return 0; 00136 } 00137 return (*i).second; 00138 } 00139 00140 00141 void 00142 NIVissimConnection::buildNodeClusters() { 00143 for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) { 00144 NIVissimConnection* e = (*i).second; 00145 if (!e->clustered()) { 00146 assert(e->myBoundary != 0 && e->myBoundary->xmax() > e->myBoundary->xmin()); 00147 std::vector<int> connections = 00148 NIVissimConnection::getWithin(*(e->myBoundary)); 00149 NIVissimNodeCluster::dictionary(-1, -1, connections, 00150 std::vector<int>(), true); // 19.5.!!! should be on a single edge 00151 } 00152 } 00153 } 00154 00155 00156 00157 00158 00159 std::vector<int> 00160 NIVissimConnection::getWithin(const AbstractPoly& poly) { 00161 std::vector<int> ret; 00162 for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) { 00163 if ((*i).second->crosses(poly)) { 00164 ret.push_back((*i).second->myID); 00165 } 00166 } 00167 return ret; 00168 } 00169 00170 00171 void 00172 NIVissimConnection::computeBounding() { 00173 Boundary* bound = new Boundary(); 00174 bound->add(myFromDef.getGeomPosition()); 00175 bound->add(myToDef.getGeomPosition()); 00176 assert(myBoundary == 0); 00177 myBoundary = bound; 00178 } 00179 00180 00181 std::vector<int> 00182 NIVissimConnection::getForEdge(int edgeid, bool /*omitNodeAssigned*/) { 00183 std::vector<int> ret; 00184 for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) { 00185 int connID = (*i).first; 00186 if ((*i).second->myFromDef.getEdgeID() == edgeid 00187 || 00188 (*i).second->myToDef.getEdgeID() == edgeid) { 00189 if (!(*i).second->hasNodeCluster()) { 00190 ret.push_back(connID); 00191 } 00192 } 00193 } 00194 return ret; 00195 } 00196 00197 00198 int 00199 NIVissimConnection::getFromEdgeID() const { 00200 return myFromDef.getEdgeID(); 00201 } 00202 00203 00204 int 00205 NIVissimConnection::getToEdgeID() const { 00206 return myToDef.getEdgeID(); 00207 } 00208 00209 00210 SUMOReal 00211 NIVissimConnection::getFromPosition() const { 00212 return myFromDef.getPosition(); 00213 } 00214 00215 00216 SUMOReal 00217 NIVissimConnection::getToPosition() const { 00218 return myToDef.getPosition(); 00219 } 00220 00221 00222 Position 00223 NIVissimConnection::getFromGeomPosition() const { 00224 return myFromDef.getGeomPosition(); 00225 } 00226 00227 00228 00229 Position 00230 NIVissimConnection::getToGeomPosition() const { 00231 return myToDef.getGeomPosition(); 00232 } 00233 00234 00235 void 00236 NIVissimConnection::setNodeCluster(int nodeid) { 00237 assert(myNode == -1); 00238 myNode = nodeid; 00239 } 00240 00241 00242 void 00243 NIVissimConnection::buildGeom() { 00244 if (myGeom.size() > 0) { 00245 return; 00246 } 00247 myGeom.push_back(myFromDef.getGeomPosition()); 00248 myGeom.push_back(myToDef.getGeomPosition()); 00249 } 00250 00251 00252 unsigned int 00253 NIVissimConnection::buildEdgeConnections(NBEdgeCont& ec) { 00254 unsigned int unsetConnections = 0; 00255 // try to determine the connected edges 00256 NBEdge* fromEdge = 0; 00257 NBEdge* toEdge = 0; 00258 NIVissimEdge* vissimFrom = NIVissimEdge::dictionary(getFromEdgeID()); 00259 if (vissimFrom->wasWithinAJunction()) { 00260 // this edge was not built, try to get one that approaches it 00261 vissimFrom = vissimFrom->getBestIncoming(); 00262 if (vissimFrom != 0) { 00263 fromEdge = ec.retrievePossiblySplitted(toString(vissimFrom->getID()), toString(getFromEdgeID()), true); 00264 } 00265 } else { 00266 // this edge was built, try to get the proper part 00267 fromEdge = ec.retrievePossiblySplitted(toString(getFromEdgeID()), toString(getToEdgeID()), true); 00268 } 00269 NIVissimEdge* vissimTo = NIVissimEdge::dictionary(getToEdgeID()); 00270 if (vissimTo->wasWithinAJunction()) { 00271 vissimTo = vissimTo->getBestOutgoing(); 00272 if (vissimTo != 0) { 00273 toEdge = ec.retrievePossiblySplitted(toString(vissimTo->getID()), toString(getToEdgeID()), true); 00274 } 00275 } else { 00276 toEdge = ec.retrievePossiblySplitted(toString(getToEdgeID()), toString(getFromEdgeID()), false); 00277 } 00278 00279 // try to get the edges the current connection connects 00280 /* 00281 NBEdge *fromEdge = ec.retrievePossiblySplitted(toString(getFromEdgeID()), toString(getToEdgeID()), true); 00282 NBEdge *toEdge = ec.retrievePossiblySplitted(toString(getToEdgeID()), toString(getFromEdgeID()), false); 00283 */ 00284 if (fromEdge == 0 || toEdge == 0) { 00285 WRITE_WARNING("Could not build connection between '" + toString(getFromEdgeID()) + "' and '" + toString(getToEdgeID()) + "'."); 00286 return 1; // !!! actually not 1 00287 } 00288 recheckLanes(fromEdge, toEdge); 00289 const std::vector<int>& fromLanes = getFromLanes(); 00290 const std::vector<int>& toLanes = getToLanes(); 00291 if (fromLanes.size() != toLanes.size()) { 00292 WRITE_WARNING("Lane sizes differ for connection '" + toString(getID()) + "'."); 00293 } else { 00294 for (unsigned int index = 0; index < fromLanes.size(); ++index) { 00295 if (fromEdge->getNumLanes() <= static_cast<unsigned int>(fromLanes[index])) { 00296 WRITE_WARNING("Could not set connection between '" + fromEdge->getID() + "_" + toString(fromLanes[index]) + "' and '" + toEdge->getID() + "_" + toString(toLanes[index]) + "'."); 00297 ++unsetConnections; 00298 } else if (!fromEdge->addLane2LaneConnection(fromLanes[index], toEdge, toLanes[index], NBEdge::L2L_VALIDATED)) { 00299 WRITE_WARNING("Could not set connection between '" + fromEdge->getID() + "_" + toString(fromLanes[index]) + "' and '" + toEdge->getID() + "_" + toString(toLanes[index]) + "'."); 00300 ++unsetConnections; 00301 } 00302 } 00303 } 00304 return unsetConnections; 00305 } 00306 00307 00308 void 00309 NIVissimConnection::dict_buildNBEdgeConnections(NBEdgeCont& ec) { 00310 unsigned int unsetConnections = 0; 00311 // go through connections 00312 for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) { 00313 unsetConnections += (*i).second->buildEdgeConnections(ec); 00314 } 00315 if (unsetConnections != 0) { 00316 WRITE_WARNING(toString<size_t>(unsetConnections) + " of " + toString<size_t>(myDict.size()) + " connections could not be assigned."); 00317 } 00318 } 00319 00320 00321 const std::vector<int>& 00322 NIVissimConnection::getFromLanes() const { 00323 return myFromDef.getLanes(); 00324 } 00325 00326 00327 const std::vector<int>& 00328 NIVissimConnection::getToLanes() const { 00329 return myToDef.getLanes(); 00330 } 00331 00332 00333 void 00334 NIVissimConnection::recheckLanes(const NBEdge* const fromEdge, const NBEdge* const toEdge) { 00335 myFromDef.recheckLanes(fromEdge); 00336 myToDef.recheckLanes(toEdge); 00337 } 00338 00339 00340 const Boundary& 00341 NIVissimConnection::getBoundingBox() const { 00342 assert(myBoundary != 0 && myBoundary->xmax() >= myBoundary->xmin()); 00343 return *myBoundary; 00344 } 00345 00346 00347 void 00348 NIVissimConnection::dict_assignToEdges() { 00349 for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) { 00350 NIVissimConnection* c = (*i).second; 00351 NIVissimEdge::dictionary(c->getFromEdgeID())->addOutgoingConnection((*i).first); 00352 NIVissimEdge::dictionary(c->getToEdgeID())->addIncomingConnection((*i).first); 00353 } 00354 } 00355 00356 00357 int 00358 NIVissimConnection::getMaxID() { 00359 return myMaxID; 00360 } 00361 00362 00363 /****************************************************************************/ 00364 00365