SUMO - Simulation of Urban MObility
NIVissimConnection.cpp
Go to the documentation of this file.
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 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines