NIVissimEdge.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00007 // A temporary storage for edges imported from Vissim
00008 /****************************************************************************/
00009 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00010 // Copyright 2001-2010 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 <algorithm>
00032 #include <map>
00033 #include <cassert>
00034 #include <iomanip>
00035 #include <cmath>
00036 #include <iostream>
00037 #include <sstream>
00038 #include <utils/common/ToString.h>
00039 #include <utils/geom/Position2DVector.h>
00040 #include <utils/geom/GeomHelper.h>
00041 #include <utils/distribution/Distribution.h>
00042 #include <netbuild/NBDistribution.h>
00043 #include <netbuild/NBNode.h>
00044 #include <netbuild/NBNodeCont.h>
00045 #include <utils/options/OptionsCont.h>
00046 #include "NIVissimNodeCluster.h"
00047 #include "NIVissimDistrictConnection.h"
00048 #include "NIVissimClosedLanesVector.h"
00049 #include "NIVissimConnection.h"
00050 #include "NIVissimDisturbance.h"
00051 #include "NIVissimEdge.h"
00052 #include <utils/common/MsgHandler.h>
00053 
00054 #ifdef CHECK_MEMORY_LEAKS
00055 #include <foreign/nvwa/debug_new.h>
00056 #endif // CHECK_MEMORY_LEAKS
00057 
00058 
00059 // ===========================================================================
00060 // static members
00061 // ===========================================================================
00062 NIVissimEdge::DictType NIVissimEdge::myDict;
00063 int NIVissimEdge::myMaxID = 0;
00064 std::vector<std::string> NIVissimEdge::myLanesWithMissingSpeeds;
00065 
00066 
00067 // ===========================================================================
00068 // method definitions
00069 // ===========================================================================
00070 NIVissimEdge::connection_position_sorter::connection_position_sorter(int edgeid)
00071         : myEdgeID(edgeid) {}
00072 
00073 
00074 int
00075 NIVissimEdge::connection_position_sorter::operator()(int c1id,
00076         int c2id) const {
00077     NIVissimConnection *c1 = NIVissimConnection::dictionary(c1id);
00078     NIVissimConnection *c2 = NIVissimConnection::dictionary(c2id);
00079     SUMOReal pos1 =
00080         c1->getFromEdgeID()==myEdgeID
00081         ? c1->getFromPosition() : c1->getToPosition();
00082     SUMOReal pos2 =
00083         c2->getFromEdgeID()==myEdgeID
00084         ? c2->getFromPosition() : c2->getToPosition();
00085     return pos1<pos2;
00086 }
00087 
00088 
00089 
00090 
00091 
00092 
00093 
00094 
00095 NIVissimEdge::connection_cluster_position_sorter::connection_cluster_position_sorter(int edgeid)
00096         : myEdgeID(edgeid) {}
00097 
00098 
00099 int
00100 NIVissimEdge::connection_cluster_position_sorter::operator()(
00101     NIVissimConnectionCluster *cc1,
00102     NIVissimConnectionCluster *cc2) const {
00103     SUMOReal pos1 = cc1->getPositionForEdge(myEdgeID);
00104     SUMOReal pos2 = cc2->getPositionForEdge(myEdgeID);
00105     if (pos2<0||pos1<0) {
00106         cc1->getPositionForEdge(myEdgeID);
00107         cc2->getPositionForEdge(myEdgeID);
00108     }
00109     assert(pos1>=0&&pos2>=0);
00110     return pos1<pos2;
00111 }
00112 
00113 
00114 
00115 
00116 NIVissimEdge::NIVissimEdge(int id, const std::string &name,
00117                            const std::string &type, int noLanes,
00118                            SUMOReal zuschlag1, SUMOReal zuschlag2,
00119                            SUMOReal /*length*/, const Position2DVector &geom,
00120                            const NIVissimClosedLanesVector &clv)
00121         : NIVissimAbstractEdge(id, geom),
00122         myName(name), myType(type), myNoLanes(noLanes),
00123         myZuschlag1(zuschlag1), myZuschlag2(zuschlag2),
00124         myClosedLanes(clv), myAmWithinJunction(false) { //, mySpeed(-1)
00125     assert(noLanes>=0);
00126     if (myMaxID<myID) {
00127         myMaxID = myID;
00128     }
00129     for (int i=0; i<noLanes; i++) {
00130         myLaneSpeeds.push_back(-1);
00131     }
00132 }
00133 
00134 
00135 NIVissimEdge::~NIVissimEdge() {
00136     for (NIVissimClosedLanesVector::iterator i=myClosedLanes.begin(); i!=myClosedLanes.end(); i++) {
00137         delete(*i);
00138     }
00139     myClosedLanes.clear();
00140 }
00141 
00142 
00143 bool
00144 NIVissimEdge::dictionary(int id, const std::string &name,
00145                          const std::string &type, int noLanes,
00146                          SUMOReal zuschlag1, SUMOReal zuschlag2, SUMOReal length,
00147                          const Position2DVector &geom,
00148                          const NIVissimClosedLanesVector &clv) {
00149     NIVissimEdge *o = new NIVissimEdge(id, name, type, noLanes, zuschlag1,
00150                                        zuschlag2, length, geom, clv);
00151     if (!dictionary(id, o)) {
00152         delete o;
00153         return false;
00154     }
00155     return true;
00156 }
00157 
00158 
00159 
00160 bool
00161 NIVissimEdge::dictionary(int id, NIVissimEdge *o) {
00162     DictType::iterator i=myDict.find(id);
00163     if (i==myDict.end()) {
00164         myDict[id] = o;
00165         return true;
00166     }
00167     return false;
00168 }
00169 
00170 
00171 
00172 NIVissimEdge *
00173 NIVissimEdge::dictionary(int id) {
00174     DictType::iterator i=myDict.find(id);
00175     if (i==myDict.end()) {
00176         return 0;
00177     }
00178     return (*i).second;
00179 }
00180 
00181 
00182 void
00183 NIVissimEdge::buildConnectionClusters() throw() {
00184     const SUMOReal MAX_CLUSTER_DISTANCE = 10;
00185     // build clusters for all edges made up from not previously assigne
00186     //  connections
00187     for (DictType::iterator i=myDict.begin(); i!=myDict.end(); i++) {
00188         int edgeid = (*i).first;
00189         NIVissimEdge *edge = (*i).second;
00190         // get all connectors using this edge
00191         IntVector connectors = edge->myIncomingConnections;
00192         copy(edge->myOutgoingConnections.begin(), edge->myOutgoingConnections.end(), back_inserter(connectors));
00193         if (connectors.size()==0) {
00194             continue;
00195         }
00196         // sort the connectors by the place on the edge
00197         sort(connectors.begin(), connectors.end(), connection_position_sorter(edgeid));
00198         // try to cluster the connections participating within the current edge
00199         IntVector currentCluster;
00200         IntVector::iterator j=connectors.begin();
00201         bool outgoing = NIVissimConnection::dictionary(*j)->getFromEdgeID()==(*i).first;
00202         SUMOReal position = outgoing
00203                             ? NIVissimConnection::dictionary(*j)->getFromPosition()
00204                             : NIVissimConnection::dictionary(*j)->getToPosition();
00205 
00206         // skip connections already in a cluster
00207         // !!! (?)
00208         while (j!=connectors.end()&&NIVissimConnection::dictionary(*j)->hasNodeCluster()) {
00209             ++j;
00210         }
00211         if (j==connectors.end()) {
00212             continue;
00213         }
00214         currentCluster.push_back(*j);
00215         do {
00216             if (j+1!=connectors.end()&&!NIVissimConnection::dictionary(*j)->hasNodeCluster()) {
00217                 bool n_outgoing = NIVissimConnection::dictionary(*(j+1))->getFromEdgeID()==edgeid;
00218                 SUMOReal n_position = n_outgoing
00219                                       ? NIVissimConnection::dictionary(*(j+1))->getFromPosition()
00220                                       : NIVissimConnection::dictionary(*(j+1))->getToPosition();
00221                 if (n_outgoing==outgoing && fabs(n_position-position)<MAX_CLUSTER_DISTANCE) {
00222                     // ok, in same cluster as prior
00223                     currentCluster.push_back(*(j+1));
00224                 } else {
00225                     // start new cluster
00226                     VectorHelper<int>::removeDouble(currentCluster);
00227                     edge->myConnectionClusters.push_back(new NIVissimConnectionCluster(currentCluster, -1, edgeid));
00228                     currentCluster.clear();
00229                     currentCluster.push_back(*(j+1));
00230                 }
00231                 outgoing = n_outgoing;
00232                 position = n_position;
00233             }
00234             j++;
00235         } while (j!=connectors.end());
00236         // add last connection
00237         if (currentCluster.size()>0) {
00238             VectorHelper<int>::removeDouble(currentCluster);
00239             edge->myConnectionClusters.push_back(new NIVissimConnectionCluster(currentCluster, -1, edgeid));
00240         }
00241     }
00242 }
00243 
00244 
00245 void
00246 NIVissimEdge::dict_buildNBEdges(NBDistrictCont &dc, NBNodeCont &nc,
00247                                 NBEdgeCont &ec, SUMOReal offset) {
00248     for (DictType::iterator i=myDict.begin(); i!=myDict.end(); i++) {
00249         NIVissimEdge *edge = (*i).second;
00250         edge->buildNBEdge(dc, nc, ec, offset);
00251     }
00252 }
00253 
00254 
00255 void
00256 NIVissimEdge::dict_propagateSpeeds(/* NBDistribution &dc */) {
00257     DictType::iterator i;
00258     for (i=myDict.begin(); i!=myDict.end(); i++) {
00259         NIVissimEdge *edge = (*i).second;
00260         edge->setDistrictSpeed(/* dc */);
00261     }
00262     for (i=myDict.begin(); i!=myDict.end(); i++) {
00263         NIVissimEdge *edge = (*i).second;
00264         edge->propagateSpeed(/* dc */ -1, IntVector());
00265     }
00266     for (int j=0; j<3; j++) {
00267         for (i=myDict.begin(); i!=myDict.end(); i++) {
00268             NIVissimEdge *edge = (*i).second;
00269             edge->propagateOwn(/* dc */);
00270         }
00271         for (i=myDict.begin(); i!=myDict.end(); i++) {
00272             NIVissimEdge *edge = (*i).second;
00273             edge->checkUnconnectedLaneSpeeds(/* dc */);
00274         }
00275     }
00276 }
00277 
00278 
00279 void
00280 NIVissimEdge::checkUnconnectedLaneSpeeds(/* NBDistribution &dc */) {
00281     for (int i=0; i<(int) myLaneSpeeds.size(); i++) {
00282         if (myLaneSpeeds[i]==-1) {
00283             SUMOReal speed = -1;
00284             int j1 = i - 1; // !!! recheck - j1 may become negative?
00285             int j2 = i;
00286             while (j2!=(int) myLaneSpeeds.size()&&myLaneSpeeds[j2]==-1) {
00287                 j2++;
00288             }
00289             if (j1<0) {
00290                 if (j2<(int) myLaneSpeeds.size()) {
00291                     speed = myLaneSpeeds[j2];
00292                 }
00293             } else {
00294                 if (j2>=(int) myLaneSpeeds.size()) {
00295                     speed = myLaneSpeeds[j1];
00296                 } else {
00297                     speed = (myLaneSpeeds[j1] + myLaneSpeeds[j2]) / (SUMOReal) 2.0;
00298                 }
00299             }
00300             if (speed==-1) {
00301                 continue;
00302             }
00303             myLaneSpeeds[i] = speed;
00304             std::vector<NIVissimConnection*> connected = getOutgoingConnected(i);
00305             for (std::vector<NIVissimConnection*>::iterator j=connected.begin(); j!=connected.end(); j++) {
00306                 NIVissimConnection *c = *j;
00307                 NIVissimEdge *e = NIVissimEdge::dictionary(c->getToEdgeID());
00308                 // propagate
00309                 e->propagateSpeed(/*dc, */speed, c->getToLanes());
00310             }
00311         }
00312     }
00313 }
00314 
00315 
00316 void
00317 NIVissimEdge::propagateOwn(/* NBDistribution &dc */) {
00318     for (int i=0; i<(int) myLaneSpeeds.size(); i++) {
00319         if (myLaneSpeeds[i]==-1) {
00320             continue;
00321         }
00322         std::vector<NIVissimConnection*> connected = getOutgoingConnected(i);
00323         for (std::vector<NIVissimConnection*>::iterator j=connected.begin(); j!=connected.end(); j++) {
00324             NIVissimConnection *c = *j;
00325             NIVissimEdge *e = NIVissimEdge::dictionary(c->getToEdgeID());
00326             // propagate
00327             e->propagateSpeed(/*dc, */myLaneSpeeds[i], c->getToLanes());
00328         }
00329     }
00330 }
00331 
00332 
00333 void
00334 NIVissimEdge::propagateSpeed(/* NBDistribution &dc */ SUMOReal speed, IntVector forLanes) {
00335     // if no lane is given, all set be set
00336     if (forLanes.size()==0) {
00337         for (size_t i=0; i<myNoLanes; i++) {
00338             forLanes.push_back((int) i);
00339         }
00340     }
00341     // for the case of a first call
00342     // go through the lanes
00343     for (IntVector::const_iterator i=forLanes.begin(); i<forLanes.end(); i++) {
00344         // check whether a speed was set before
00345         if (myLaneSpeeds[*i]!=-1) {
00346             // do not reset it from incoming
00347             continue;
00348         }
00349         // check whether the lane has a new speed to set
00350         if ((int) myPatchedSpeeds.size()>*i&&myPatchedSpeeds[*i]!=-1) {
00351             // use it
00352             speed = getRealSpeed(/*dc, */myPatchedSpeeds[*i]);
00353         }
00354         // check whether a speed is given
00355         if (speed==-1) {
00356             // do nothing if not
00357             continue;
00358         }
00359         // set the lane's speed to the given
00360         myLaneSpeeds[*i] = speed;
00361         // propagate the speed further
00362         // get the list of connected edges
00363         std::vector<NIVissimConnection*> connected = getOutgoingConnected(*i);
00364         // go throught the list
00365         for (std::vector<NIVissimConnection*>::iterator j=connected.begin(); j!=connected.end(); j++) {
00366             NIVissimConnection *c = *j;
00367             NIVissimEdge *e = NIVissimEdge::dictionary(c->getToEdgeID());
00368             // propagate
00369             e->propagateSpeed(/*dc, */speed, c->getToLanes());
00370         }
00371     }
00372 }
00373 
00374 
00375 
00376 void
00377 NIVissimEdge::setDistrictSpeed(/* NBDistribution &dc */) {
00378     if (myDistrictConnections.size()>0) {
00379         SUMOReal pos = *(myDistrictConnections.begin());
00380         if (pos<getLength()-pos) {
00381             NIVissimDistrictConnection *d =
00382                 NIVissimDistrictConnection::dict_findForEdge(myID);
00383             if (d!=0) {
00384                 SUMOReal speed = d->getMeanSpeed(/*dc*/);
00385                 if (speed==-1) {
00386                     return;
00387                 }
00388                 for (unsigned int i=0; i<myNoLanes; i++) {
00389                     myLaneSpeeds[i] = speed;
00390                     // propagate the speed further
00391                     // get the list of connected edges
00392                     std::vector<NIVissimConnection*> connected = getOutgoingConnected(i);
00393                     // go throught the list
00394                     for (std::vector<NIVissimConnection*>::iterator j=connected.begin(); j!=connected.end(); j++) {
00395                         NIVissimConnection *c = *j;
00396                         NIVissimEdge *e = NIVissimEdge::dictionary(c->getToEdgeID());
00397                         // propagate
00398                         e->propagateSpeed(/*dc, */speed, c->getToLanes());
00399                     }
00400                 }
00401             }
00402         }
00403     }
00404 }
00405 
00406 
00407 std::vector<NIVissimConnection*>
00408 NIVissimEdge::getOutgoingConnected(int lane) const {
00409     std::vector<NIVissimConnection*> ret;
00410     for (IntVector::const_iterator i=myOutgoingConnections.begin(); i!=myOutgoingConnections.end(); i++) {
00411         NIVissimConnection *c = NIVissimConnection::dictionary(*i);
00412         const IntVector &lanes = c->getFromLanes();
00413         if (find(lanes.begin(), lanes.end(), lane)!=lanes.end()) {
00414             NIVissimEdge *e = NIVissimEdge::dictionary(c->getToEdgeID());
00415             if (e!=0) {
00416                 ret.push_back(c);
00417             }
00418         }
00419     }
00420     return ret;
00421 }
00422 
00423 
00424 void
00425 NIVissimEdge::buildNBEdge(NBDistrictCont &dc, NBNodeCont &nc, NBEdgeCont &ec,
00426                           SUMOReal sameNodesOffset) throw(ProcessError) {
00427     // build the edge
00428     std::pair<NIVissimConnectionCluster*, NBNode *> fromInf, toInf;
00429     NBNode *fromNode, *toNode;
00430     fromNode = toNode = 0;
00431     sort(myConnectionClusters.begin(), myConnectionClusters.end(), connection_cluster_position_sorter(myID));
00432     sort(myDistrictConnections.begin(), myDistrictConnections.end());
00433     ConnectionClusters tmpClusters = myConnectionClusters;
00434     if (tmpClusters.size()!=0) {
00435         sort(tmpClusters.begin(), tmpClusters.end(), connection_cluster_position_sorter(myID));
00436         // get or build the from-node
00437         //  A node may have to be build when the edge starts or ends at
00438         //  a parking place or something like this
00439         fromInf = getFromNode(nc, tmpClusters);
00440         fromNode = fromInf.second;
00441         // get or build the to-node
00442         //if(tmpClusters.size()>0) {
00443         toInf = getToNode(nc, tmpClusters);
00444         toNode = toInf.second;
00445         if (fromInf.first!=0&&toNode!=0&&fromInf.first->around(toNode->getPosition())) {
00446             MsgHandler::getWarningInstance()->inform("Will not build edge '" + toString(myID) + "'.");
00447             myAmWithinJunction = true;
00448             return;
00449         }
00450         //}
00451         // if both nodes are the same, resolve the problem otherwise
00452         if (fromNode==toNode) {
00453             std::pair<NBNode*, NBNode*> tmp = resolveSameNode(nc, sameNodesOffset, fromNode, toNode);
00454             if (fromNode!=tmp.first) {
00455                 fromInf.first = 0;
00456             }
00457             if (toNode!=tmp.second) {
00458                 toInf.first = 0;
00459             }
00460             fromNode = tmp.first;
00461             toNode = tmp.second;
00462         }
00463     }
00464 
00465     //
00466     if (fromNode==0) {
00467         fromInf.first = 0;
00468         Position2D pos = myGeom[0];
00469         fromNode = new NBNode(toString<int>(myID) + "-SourceNode", pos, NBNode::NODETYPE_NOJUNCTION);
00470         if (!nc.insert(fromNode)) {
00471             throw ProcessError("Could not insert node '" + fromNode->getID() + "' to nodes container.");
00472         }
00473     }
00474     if (toNode==0) {
00475         toInf.first = 0;
00476         Position2D pos = myGeom[-1];
00477         toNode = new NBNode(toString<int>(myID) + "-DestinationNode", pos, NBNode::NODETYPE_NOJUNCTION);
00478         if (!nc.insert(toNode)) {
00479             throw ProcessError("Could not insert node '" + toNode->getID() + "' to nodes container.");
00480         }
00481     }
00482 
00483     // build the edge
00484     SUMOReal avgSpeed = 0;
00485     int i;
00486     for (i=0; i<(int) myNoLanes; i++) {
00487         if (myLaneSpeeds.size()<=(size_t) i||myLaneSpeeds[i]==-1) {
00488             myLanesWithMissingSpeeds.push_back(toString(myID) + "_" + toString(i));
00489             avgSpeed += OptionsCont::getOptions().getFloat("vissim.default-speed");
00490         } else {
00491             avgSpeed += myLaneSpeeds[i];
00492         }
00493     }
00494     avgSpeed /= (SUMOReal) myLaneSpeeds.size();
00495     avgSpeed *= OptionsCont::getOptions().getFloat("vissim.speed-norm");
00496 
00497     if (fromNode==toNode) {
00498         MsgHandler::getWarningInstance()->inform("Could not build edge '" + toString(myID) + "'; would connect same node.");
00499         return;
00500     }
00501 
00502     NBEdge *buildEdge = new NBEdge(
00503         toString<int>(myID), fromNode, toNode, myType,
00504         avgSpeed/(SUMOReal) 3.6, myNoLanes, -1, myGeom,
00505         NBEdge::LANESPREAD_CENTER, true);
00506     for (i=0; i<(int) myNoLanes; i++) {
00507         if ((int) myLaneSpeeds.size()<=i||myLaneSpeeds[i]==-1) {
00508             buildEdge->setLaneSpeed(i, OptionsCont::getOptions().getFloat("vissim.default-speed")/(SUMOReal) 3.6);
00509         } else {
00510             buildEdge->setLaneSpeed(i, myLaneSpeeds[i]/(SUMOReal) 3.6);
00511         }
00512     }
00513     ec.insert(buildEdge);
00514     // check whether the edge contains any other clusters
00515     if (tmpClusters.size()>0) {
00516         bool cont = true;
00517         for (ConnectionClusters::iterator j = tmpClusters.begin(); cont && j!=tmpClusters.end(); ++j) {
00518             // split the edge at the previously build node
00519             std::string nextID = buildEdge->getID() + "[1]";
00520             cont = ec.splitAt(dc, buildEdge, (*j)->getNBNode());
00521             // !!! what to do if the edge could not be split?
00522             buildEdge = ec.retrieve(nextID);
00523         }
00524     }
00525 }
00526 
00527 
00528 SUMOReal
00529 NIVissimEdge::getRealSpeed(/* NBDistribution &dc */ int distNo) {
00530     std::string id = toString<int>(distNo);
00531     Distribution *dist = NBDistribution::dictionary("speed", id);
00532     if (dist==0) {
00533         WRITE_WARNING("The referenced speed distribution '" + id + "' is not known.");
00534         return -1;
00535     }
00536     assert(dist!=0);
00537     SUMOReal speed = dist->getMax();
00538     if (speed<0||speed>1000) {
00539         WRITE_WARNING("What about distribution '" + toString<int>(distNo) + "' ");
00540     }
00541     return speed;
00542 }
00543 
00544 /*
00545 bool
00546 NIVissimEdge::recheckSpeedPatches()
00547 {
00548 //    size_t speed_idx = -1;
00549     // check set speeds
00550     if(myPatchedSpeeds.size()!=0) {
00551         DoubleVector::iterator i =
00552             find(myPatchedSpeeds.begin(), myPatchedSpeeds.end(), -1);
00553         if(myPatchedSpeeds.size()!=myNoLanes||i!=myPatchedSpeeds.end()) {
00554             cot << "Warning! Not all lanes are patched! (edge:" << myID << ")." << endl;
00555         }
00556         //
00557         if(DoubleVectorHelper::maxValue(myPatchedSpeeds)!=DoubleVectorHelper::minValue(myPatchedSpeeds)) {
00558             cot << "Warning! Not all lanes have the same speed!! (edge:" << myID << ")." << endl;
00559         }
00560         //
00561 /        // !!! ist natürlich Quatsch - erst recht, wenn Edges zusammengefasst werden
00562         speed = DoubleVectorHelper::sum(myPatchedSpeeds);
00563         speed /= (SUMOReal) myPatchedSpeeds.size();*/
00564 /*        return true;
00565     }
00566     if(myDistrictConnections.size()>0) {
00567         SUMOReal pos = *(myDistrictConnections.begin());
00568 //        if(pos<10) {
00569             NIVissimDistrictConnection *d =
00570                 NIVissimDistrictConnection::dict_findForEdge(myID);
00571             if(d!=0) {
00572                 return true;
00573 //                speed = d->getMeanSpeed();
00574             }
00575 //        }
00576 //        return true;
00577     }
00578     return false;
00579 }
00580 */
00581 
00582 std::pair<NIVissimConnectionCluster*, NBNode*>
00583 NIVissimEdge::getFromNode(NBNodeCont &nc, ConnectionClusters &clusters) {
00584     const SUMOReal MAX_DISTANCE = 10.;
00585     assert(clusters.size()>=1);
00586     const Position2D &beg = myGeom.getBegin();
00587     NIVissimConnectionCluster *c = *(clusters.begin());
00588     // check whether the edge starts within a already build node
00589     if (c->around(beg, MAX_DISTANCE)) {
00590         clusters.erase(clusters.begin());
00591         return std::pair<NIVissimConnectionCluster*, NBNode*>
00592                (c, c->getNBNode());
00593     }
00594     // check for a parking place at the begin
00595     if (myDistrictConnections.size()>0) {
00596         SUMOReal pos = *(myDistrictConnections.begin());
00597         if (pos<10) {
00598             NBNode *node = new NBNode(toString<int>(myID) + "-begin", beg, NBNode::NODETYPE_NOJUNCTION);
00599             if (!nc.insert(node)) {
00600                 throw 1;
00601             }
00602             while (myDistrictConnections.size()>0&&*(myDistrictConnections.begin())<10) {
00603                 myDistrictConnections.erase(myDistrictConnections.begin());
00604             }
00605             return std::pair<NIVissimConnectionCluster*, NBNode*>(0, node);
00606         }
00607     }
00608     // build a new node for the edge's begin otherwise
00609     NBNode *node = new NBNode(toString<int>(myID) + "-begin", beg, NBNode::NODETYPE_NOJUNCTION);
00610     if (!nc.insert(node)) {
00611         throw 1;
00612     }
00613     return std::pair<NIVissimConnectionCluster*, NBNode*>(0, node);
00614 }
00615 
00616 
00617 std::pair<NIVissimConnectionCluster*, NBNode *>
00618 NIVissimEdge::getToNode(NBNodeCont &nc, ConnectionClusters &clusters) {
00619     const Position2D &end = myGeom.getEnd();
00620     if (clusters.size()>0) {
00621         const SUMOReal MAX_DISTANCE = 10.;
00622         assert(clusters.size()>=1);
00623         NIVissimConnectionCluster *c = *(clusters.end()-1);
00624         // check whether the edge ends within a already build node
00625         if (c->around(end, MAX_DISTANCE)) {
00626             clusters.erase(clusters.end()-1);
00627             return std::pair<NIVissimConnectionCluster*, NBNode *>(c, c->getNBNode());
00628         }
00629     }
00630     // check for a parking place at the end
00631     if (myDistrictConnections.size()>0) {
00632         SUMOReal pos = *(myDistrictConnections.end()-1);
00633         if (pos>myGeom.length()-10) {
00634             NBNode *node = new NBNode(toString<int>(myID) + "-end", end, NBNode::NODETYPE_NOJUNCTION);
00635             if (!nc.insert(node)) {
00636                 throw 1;
00637             }
00638             while (myDistrictConnections.size()>0&&*(myDistrictConnections.end()-1)<myGeom.length()-10) {
00639                 myDistrictConnections.erase(myDistrictConnections.end()-1);
00640             }
00641             return std::pair<NIVissimConnectionCluster*, NBNode*>(0, node);
00642         }
00643     }
00644 
00645     // build a new node for the edge's end otherwise
00646     NBNode *node = new NBNode(toString<int>(myID) + "-end", end, NBNode::NODETYPE_NOJUNCTION);
00647     if (!nc.insert(node)) {
00648         throw 1;
00649     }
00650     return std::pair<NIVissimConnectionCluster*, NBNode *>(0, node);
00651     /*
00652     if (clusters.size()>0) {
00653     NIVissimConnectionCluster *c = *(clusters.end()-1);
00654     clusters.erase(clusters.end()-1);
00655     return std::pair<NIVissimConnectionCluster*, NBNode*>(c, c->getNBNode());
00656     } else {
00657     // !!! dummy edge?!
00658     return std::pair<NIVissimConnectionCluster*, NBNode*>(0, (*(myConnectionClusters.begin()))->getNBNode());
00659     }
00660     */
00661 }
00662 
00663 
00664 std::pair<NBNode*, NBNode*>
00665 NIVissimEdge::remapOneOfNodes(NBNodeCont &nc,
00666                               NIVissimDistrictConnection *d,
00667                               NBNode *fromNode, NBNode *toNode) {
00668     std::string nid = "ParkingPlace" + toString<int>(d->getID());
00669     if (d->geomPosition().distanceTo(fromNode->getPosition())
00670             <
00671             d->geomPosition().distanceTo(toNode->getPosition())) {
00672 
00673         NBNode *newNode = new NBNode(nid,
00674                                      fromNode->getPosition(),
00675                                      NBNode::NODETYPE_NOJUNCTION);
00676         nc.erase(fromNode);
00677         nc.insert(newNode);
00678         return std::pair<NBNode*, NBNode*>(newNode, toNode);
00679     } else {
00680         NBNode *newNode = new NBNode(nid,
00681                                      toNode->getPosition(),
00682                                      NBNode::NODETYPE_NOJUNCTION);
00683         nc.erase(toNode);
00684         nc.insert(newNode);
00685         return std::pair<NBNode*, NBNode*>(fromNode, newNode);
00686     }
00687 }
00688 
00689 
00690 
00691 std::pair<NBNode*, NBNode*>
00692 NIVissimEdge::resolveSameNode(NBNodeCont &nc, SUMOReal offset,
00693                               NBNode *prevFrom, NBNode *prevTo) {
00694     // check whether the edge is connected to a district
00695     //  use it if so
00696     NIVissimDistrictConnection *d =
00697         NIVissimDistrictConnection::dict_findForEdge(myID);
00698     if (d!=0) {
00699         Position2D pos = d->geomPosition();
00700         SUMOReal position = d->getPosition();
00701         // the district is at the begin of the edge
00702         if (myGeom.length()-position>position) {
00703             std::string nid = "ParkingPlace" + toString<int>(d->getID());
00704             NBNode *node = nc.retrieve(nid);
00705             if (node==0) {
00706                 node = new NBNode(nid,
00707                                   pos, NBNode::NODETYPE_NOJUNCTION);
00708                 if (!nc.insert(node)) {
00709                     throw 1;
00710                 }
00711             }
00712             return std::pair<NBNode*, NBNode*>(node, prevTo);
00713         }
00714         // the district is at the end of the edge
00715         else {
00716             std::string nid = "ParkingPlace" + toString<int>(d->getID());
00717             NBNode *node = nc.retrieve(nid);
00718             if (node==0) {
00719                 node = new NBNode(nid,
00720                                   pos, NBNode::NODETYPE_NOJUNCTION);
00721                 if (!nc.insert(node)) {
00722                     throw 1;
00723                 }
00724             }
00725             assert(node!=0);
00726             return std::pair<NBNode*, NBNode*>(prevFrom, node);
00727         }
00728     }
00729     // otherwise, check whether the edge is some kind of
00730     //  a dead end...
00731     // check which end is nearer to the node centre
00732     if (myConnectionClusters.size()==1) {
00733         NBNode *node = prevFrom; // it is the same as getToNode()
00734 
00735         NIVissimConnectionCluster *c = *(myConnectionClusters.begin());
00736         // no end node given
00737         if (c->around(myGeom.getBegin(), offset) && !c->around(myGeom.getEnd(), offset)) {
00738             NBNode *end = new NBNode(
00739                 toString<int>(myID) + "-End",
00740                 myGeom.getEnd(),
00741                 NBNode::NODETYPE_NOJUNCTION);
00742             if (!nc.insert(end)) {
00743                 throw 1;
00744             }
00745             return std::pair<NBNode*, NBNode*>(node, end);
00746         }
00747 
00748         // no begin node given
00749         if (!c->around(myGeom.getBegin(), offset) && c->around(myGeom.getEnd(), offset)) {
00750             NBNode *beg = new NBNode(
00751                 toString<int>(myID) + "-Begin",
00752                 myGeom.getBegin(),
00753                 NBNode::NODETYPE_NOJUNCTION);
00754             if (!nc.insert(beg)) {
00755                 std::cout << "nope, NIVissimDisturbance" << std::endl;
00756                 throw 1;
00757             }
00758             return std::pair<NBNode*, NBNode*>(beg, node);
00759         }
00760 
00761         // "dummy edge" - both points lie within the same cluster
00762         if (c->around(myGeom.getBegin()) && c->around(myGeom.getEnd())) {
00763             return std::pair<NBNode*, NBNode*>(node, node);
00764         }
00765     }
00766     // what to do in other cases?
00767     //  It simply is a dummy edge....
00768     return std::pair<NBNode*, NBNode*>(prevFrom, prevTo);
00769 }
00770 
00771 
00772 
00773 
00774 void
00775 NIVissimEdge::setNodeCluster(int nodeid) {
00776     myNode = nodeid;
00777 }
00778 
00779 
00780 void
00781 NIVissimEdge::buildGeom() {}
00782 
00783 
00784 void
00785 NIVissimEdge::addIncomingConnection(int id) {
00786     myIncomingConnections.push_back(id);
00787 }
00788 
00789 
00790 void
00791 NIVissimEdge::addOutgoingConnection(int id) {
00792     myOutgoingConnections.push_back(id);
00793 }
00794 
00795 
00796 
00797 void
00798 NIVissimEdge::mergedInto(NIVissimConnectionCluster *old,
00799                          NIVissimConnectionCluster *act) {
00800     ConnectionClusters::iterator i=
00801         find(myConnectionClusters.begin(), myConnectionClusters.end(), old);
00802     if (i!=myConnectionClusters.end()) {
00803         myConnectionClusters.erase(i);
00804     }
00805     i = find(myConnectionClusters.begin(), myConnectionClusters.end(), act);
00806     if (i==myConnectionClusters.end()) {
00807         myConnectionClusters.push_back(act);
00808     }
00809 }
00810 
00811 
00812 
00813 void
00814 NIVissimEdge::removeFromConnectionCluster(NIVissimConnectionCluster *c) {
00815     ConnectionClusters::iterator i=
00816         find(myConnectionClusters.begin(), myConnectionClusters.end(), c);
00817     assert(i!=myConnectionClusters.end());
00818     myConnectionClusters.erase(i);
00819 }
00820 
00821 
00822 void
00823 NIVissimEdge::addToConnectionCluster(NIVissimConnectionCluster *c) {
00824     ConnectionClusters::iterator i=
00825         find(myConnectionClusters.begin(), myConnectionClusters.end(), c);
00826     if (i==myConnectionClusters.end()) {
00827         myConnectionClusters.push_back(c);
00828     }
00829 }
00830 
00831 
00832 Position2D // !!! reference?
00833 NIVissimEdge::getBegin2D() const {
00834     return myGeom[0];
00835 }
00836 
00837 
00838 Position2D // !!! reference?
00839 NIVissimEdge::getEnd2D() const {
00840     return myGeom[-1];
00841 }
00842 
00843 
00844 SUMOReal
00845 NIVissimEdge::getLength() const {
00846     return myGeom.length();
00847 }
00848 
00849 
00850 void
00851 NIVissimEdge::checkDistrictConnectionExistanceAt(SUMOReal pos) {
00852     if (find(myDistrictConnections.begin(), myDistrictConnections.end(), pos)==myDistrictConnections.end()) {
00853         myDistrictConnections.push_back(pos);
00854         /*        int id = NIVissimConnection::getMaxID() + 1;
00855                 IntVector currentCluster;
00856                 currentCluster.push_back(id);
00857                 myConnectionClusters.push_back(
00858                     new NIVissimConnectionCluster(currentCluster, -1, myID));*/
00859     }
00860 }
00861 
00862 
00863 void
00864 NIVissimEdge::setSpeed(size_t lane, int speedDist) {
00865     while (myPatchedSpeeds.size()<=lane) {
00866         myPatchedSpeeds.push_back(-1);
00867     }
00868     myPatchedSpeeds[lane] = speedDist;
00869 }
00870 
00871 
00872 void
00873 NIVissimEdge::dict_checkEdges2Join() {
00874     // go through the edges
00875     for (DictType::iterator i1=myDict.begin(); i1!=myDict.end(); i1++) {
00876         // retrieve needed values from the first edge
00877         NIVissimEdge *e1 = (*i1).second;
00878         const Position2DVector &g1 = e1->getGeometry();
00879         // check all other edges
00880         DictType::iterator i2=i1;
00881         i2++;
00882         for (; i2!=myDict.end(); i2++) {
00883             // retrieve needed values from the second edge
00884             NIVissimEdge *e2 = (*i2).second;
00885             const Position2DVector &g2 = e2->getGeometry();
00886             // get the connection description
00887             NIVissimConnection *c = e1->getConnectionTo(e2);
00888             if (c==0) {
00889                 c = e2->getConnectionTo(e1);
00890             }
00891             // the edge must not be a direct contiuation of the other
00892             if (c!=0) {
00893                 if ((c->getFromEdgeID()==e1->getID()&&fabs(c->getFromPosition()-e1->getGeometry().length())<5)
00894                         ||
00895                         (c->getFromEdgeID()==e2->getID()&&fabs(c->getFromPosition()-e2->getGeometry().length())<5)) {
00896 
00897                     continue;
00898                 }
00899             }
00900             // only parallel edges which do end at the same node
00901             //  should be joined
00902             // retrieve the "approximating" lines first
00903             Line2D l1 = Line2D(g1.getBegin(), g1.getEnd());
00904             Line2D l2 = Line2D(g2.getBegin(), g2.getEnd());
00905             // check for parallelity
00906             //  !!! the usage of an explicite value is not very fine
00907             if (fabs(l1.atan2DegreeAngle()-l2.atan2DegreeAngle())>2.0) {
00908                 // continue if the lines are not parallel
00909                 continue;
00910             }
00911 
00912             // check whether the same node is approached
00913             //  (the distance between the ends should not be too large)
00914             //  !!! the usage of an explicite value is not very fine
00915             if (l1.p2().distanceTo(l2.p2())>10) {
00916                 // continue if the lines do not end at the same length
00917                 continue;
00918             }
00919             // ok, seem to be different lanes for the same edge
00920             //  mark as possibly joined later
00921             e1->addToTreatAsSame(e2);
00922             e2->addToTreatAsSame(e1);
00923         }
00924     }
00925 }
00926 
00927 
00928 bool
00929 NIVissimEdge::addToTreatAsSame(NIVissimEdge *e) {
00930     if (e==this) {
00931         return false;
00932     }
00933     // check whether this edge already knows about the other
00934     if (find(myToTreatAsSame.begin(), myToTreatAsSame.end(), e)==myToTreatAsSame.end()) {
00935         myToTreatAsSame.push_back(e);
00936         return true;
00937     } else {
00938         return false; // !!! check this
00939     }
00940     //
00941     std::vector<NIVissimEdge*>::iterator i;
00942     // add to all other that shall be treated as same
00943     bool changed = true;
00944     while (changed) {
00945         changed = false;
00946         for (i=myToTreatAsSame.begin(); !changed&&i!=myToTreatAsSame.end(); i++) {
00947             changed |= (*i)->addToTreatAsSame(e);
00948         }
00949         for (i=myToTreatAsSame.begin(); !changed&&i!=myToTreatAsSame.end(); i++) {
00950             changed |= e->addToTreatAsSame(*i);
00951         }
00952     }
00953 }
00954 
00955 NIVissimConnection*
00956 NIVissimEdge::getConnectionTo(NIVissimEdge *e) {
00957     IntVector::iterator i;
00958     for (i=myIncomingConnections.begin(); i!=myIncomingConnections.end(); i++) {
00959         NIVissimConnection *c = NIVissimConnection::dictionary(*i);
00960         if (c->getFromEdgeID()==e->getID()) {
00961             return c;
00962         }
00963     }
00964     for (i=myOutgoingConnections.begin(); i!=myOutgoingConnections.end(); i++) {
00965         NIVissimConnection *c = NIVissimConnection::dictionary(*i);
00966         if (c->getToEdgeID()==e->getID()) {
00967             return c;
00968         }
00969     }
00970     return 0;
00971 }
00972 
00973 
00974 const std::vector<NIVissimEdge*> &
00975 NIVissimEdge::getToTreatAsSame() const {
00976     return myToTreatAsSame;
00977 }
00978 
00979 
00980 void
00981 NIVissimEdge::reportUnsetSpeeds() throw() {
00982     if (myLanesWithMissingSpeeds.size()==0) {
00983         return;
00984     }
00985     std::ostringstream str;
00986     str << "The following lanes have no explicite speed information:\n  ";
00987     for (std::vector<std::string>::iterator i=myLanesWithMissingSpeeds.begin(); i!=myLanesWithMissingSpeeds.end(); ++i) {
00988         if (i!=myLanesWithMissingSpeeds.begin()) {
00989             str << ", ";
00990         }
00991         str << *i;
00992     }
00993     MsgHandler::getWarningInstance()->inform(str.str());
00994 }
00995 
00996 
00997 NIVissimEdge *
00998 NIVissimEdge::getBestIncoming() const throw() {
00999     for (IntVector::const_iterator i=myIncomingConnections.begin(); i!=myIncomingConnections.end(); ++i) {
01000         NIVissimConnection *c = NIVissimConnection::dictionary(*i);
01001         return NIVissimEdge::dictionary(c->getFromEdgeID());
01002     }
01003     return 0;
01004 }
01005 
01006 
01007 NIVissimEdge *
01008 NIVissimEdge::getBestOutgoing() const throw() {
01009     for (IntVector::const_iterator i=myOutgoingConnections.begin(); i!=myOutgoingConnections.end(); ++i) {
01010         NIVissimConnection *c = NIVissimConnection::dictionary(*i);
01011         return NIVissimEdge::dictionary(c->getToEdgeID());
01012     }
01013     return 0;
01014 }
01015 
01016 
01017 
01018 /****************************************************************************/
01019 

Generated on Wed May 5 00:06:34 2010 for Sumo - Simulation of Urban MObility by  doxygen 1.5.6