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