00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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 <cassert>
00033 #include <algorithm>
00034 #include <vector>
00035 #include <deque>
00036 #include <set>
00037 #include <cmath>
00038 #include <utils/common/UtilExceptions.h>
00039 #include <utils/common/StringUtils.h>
00040 #include <utils/options/OptionsCont.h>
00041 #include <utils/geom/Line2D.h>
00042 #include <utils/geom/GeomHelper.h>
00043 #include <utils/geom/bezier.h>
00044 #include <utils/common/MsgHandler.h>
00045 #include <utils/common/StdDefs.h>
00046 #include <utils/common/ToString.h>
00047 #include <utils/geom/GeoConvHelper.h>
00048 #include <utils/iodevices/OutputDevice.h>
00049 #include <iomanip>
00050 #include "NBNode.h"
00051 #include "NBNodeCont.h"
00052 #include "NBNodeShapeComputer.h"
00053 #include "NBEdgeCont.h"
00054 #include "NBTypeCont.h"
00055 #include "NBJunctionLogicCont.h"
00056 #include "NBHelpers.h"
00057 #include "NBDistrict.h"
00058 #include "NBContHelper.h"
00059 #include "NBRequest.h"
00060 #include "NBOwnTLDef.h"
00061 #include "NBTrafficLightLogicCont.h"
00062
00063 #ifdef CHECK_MEMORY_LEAKS
00064 #include <foreign/nvwa/debug_new.h>
00065 #endif // CHECK_MEMORY_LEAKS
00066
00067
00068
00069
00070
00072 #define NO_INTERNAL_POINTS 5
00073
00074
00075
00076
00077
00078
00079
00080
00081 NBNode::ApproachingDivider::ApproachingDivider(
00082 std::vector<NBEdge*> *approaching, NBEdge *currentOutgoing) throw()
00083 : myApproaching(approaching), myCurrentOutgoing(currentOutgoing) {
00084
00085 assert(myApproaching!=0);
00086 }
00087
00088
00089 NBNode::ApproachingDivider::~ApproachingDivider() throw() {}
00090
00091
00092 void
00093 NBNode::ApproachingDivider::execute(SUMOReal src, SUMOReal dest) throw() {
00094 assert(myApproaching->size()>src);
00095
00096 NBEdge *incomingEdge = (*myApproaching)[(int) src];
00097 if (incomingEdge->getStep()==NBEdge::LANES2LANES_DONE||incomingEdge->getStep()==NBEdge::LANES2LANES_USER) {
00098 return;
00099 }
00100 std::vector<int> approachingLanes =
00101 incomingEdge->getConnectionLanes(myCurrentOutgoing);
00102 assert(approachingLanes.size()!=0);
00103 std::deque<int> *approachedLanes = spread(approachingLanes, dest);
00104 assert(approachedLanes->size()<=myCurrentOutgoing->getNoLanes());
00105
00106 for (unsigned int i=0; i<approachedLanes->size(); i++) {
00107 unsigned int approached = (*approachedLanes)[i];
00108 assert(approachedLanes->size()>i);
00109 assert(approachingLanes.size()>i);
00110 incomingEdge->setConnection((unsigned int) approachingLanes[i], myCurrentOutgoing,
00111 approached, NBEdge::L2L_COMPUTED);
00112 }
00113 delete approachedLanes;
00114 }
00115
00116
00117 std::deque<int> *
00118 NBNode::ApproachingDivider::spread(const std::vector<int> &approachingLanes,
00119 SUMOReal dest) const {
00120 std::deque<int> *ret = new std::deque<int>();
00121 unsigned int noLanes = (unsigned int) approachingLanes.size();
00122
00123
00124 if (noLanes==1) {
00125 if ((int)(dest+0.5)>dest) {
00126 ret->push_back((int)(dest+1));
00127 } else {
00128 ret->push_back((int) dest);
00129 }
00130 return ret;
00131 }
00132
00133 unsigned int noOutgoingLanes = myCurrentOutgoing->getNoLanes();
00134
00135 ret->push_back((int) dest);
00136 unsigned int noSet = 1;
00137 SUMOReal roffset = 1;
00138 SUMOReal loffset = 1;
00139 while (noSet<noLanes) {
00140
00141
00142
00143
00144
00145 if (noOutgoingLanes==noSet)
00146 return ret;
00147
00148
00149
00150
00151
00152
00153 if (((size_t) dest+loffset)>=noOutgoingLanes) {
00154 loffset -= 1;
00155 roffset += 1;
00156 for (unsigned int i=0; i<ret->size(); i++) {
00157 (*ret)[i] = (*ret)[i] - 1;
00158 }
00159 }
00160
00161
00162 ret->push_back((int)(dest+loffset));
00163 noSet++;
00164 loffset += 1;
00165
00166
00167 if (noOutgoingLanes==noSet)
00168 return ret;
00169
00170
00171 if (noSet<noLanes) {
00172
00173
00174 if (((size_t) dest-roffset)<0) {
00175 loffset += 1;
00176 roffset -= 1;
00177 for (unsigned int i=0; i<ret->size(); i++) {
00178 (*ret)[i] = (*ret)[i] + 1;
00179 }
00180 }
00181 ret->push_front((int)(dest-roffset));
00182 noSet++;
00183 roffset += 1;
00184 }
00185 }
00186 return ret;
00187 }
00188
00189
00190
00191
00192
00193
00194
00195 NBNode::NBNode(const std::string &id, const Position2D &position) throw()
00196 : myID(StringUtils::convertUmlaute(id)), myPosition(position),
00197 myType(NODETYPE_UNKNOWN), myDistrict(0), myRequest(0) {
00198 myIncomingEdges = new EdgeVector();
00199 myOutgoingEdges = new EdgeVector();
00200 }
00201
00202
00203 NBNode::NBNode(const std::string &id, const Position2D &position,
00204 BasicNodeType type) throw()
00205 : myID(StringUtils::convertUmlaute(id)), myPosition(position),
00206 myType(type), myDistrict(0), myRequest(0) {
00207 myIncomingEdges = new EdgeVector();
00208 myOutgoingEdges = new EdgeVector();
00209 }
00210
00211
00212 NBNode::NBNode(const std::string &id, const Position2D &position, NBDistrict *district) throw()
00213 : myID(StringUtils::convertUmlaute(id)), myPosition(position),
00214 myType(NODETYPE_DISTRICT), myDistrict(district), myRequest(0) {
00215 myIncomingEdges = new EdgeVector();
00216 myOutgoingEdges = new EdgeVector();
00217 }
00218
00219
00220 NBNode::~NBNode() throw() {
00221 delete myIncomingEdges;
00222 delete myOutgoingEdges;
00223 delete myRequest;
00224 }
00225
00226
00227 void
00228 NBNode::reinit(const Position2D &position, BasicNodeType type) throw() {
00229 myPosition = position;
00230
00231 myType = type;
00232 if (myType!=NODETYPE_TRAFFIC_LIGHT) {
00233 removeTrafficLights();
00234 }
00235 }
00236
00237
00238
00239
00240 void
00241 NBNode::addTrafficLight(NBTrafficLightDefinition *tld) throw() {
00242 myTrafficLights.insert(tld);
00243 }
00244
00245
00246 void
00247 NBNode::removeTrafficLights() throw() {
00248 for (std::set<NBTrafficLightDefinition*>::const_iterator i=myTrafficLights.begin(); i!=myTrafficLights.end(); ++i) {
00249 (*i)->removeNode(this);
00250 }
00251 myTrafficLights.clear();
00252 }
00253
00254
00255 bool
00256 NBNode::isJoinedTLSControlled() const throw() {
00257 if (!isTLControlled()) {
00258 return false;
00259 }
00260 for (std::set<NBTrafficLightDefinition*>::const_iterator i=myTrafficLights.begin(); i!=myTrafficLights.end(); ++i) {
00261 if ((*i)->getID().find("joined")==0) {
00262 return true;
00263 }
00264 }
00265 return false;
00266 }
00267
00268
00269
00270 void
00271 NBNode::addIncomingEdge(NBEdge *edge) {
00272 assert(edge!=0);
00273 if (find(myIncomingEdges->begin(), myIncomingEdges->end(), edge)==myIncomingEdges->end()) {
00274 myIncomingEdges->push_back(edge);
00275 myAllEdges.push_back(edge);
00276 }
00277 }
00278
00279
00280 void
00281 NBNode::addOutgoingEdge(NBEdge *edge) {
00282 assert(edge!=0);
00283 if (find(myOutgoingEdges->begin(), myOutgoingEdges->end(), edge)==myOutgoingEdges->end()) {
00284 myOutgoingEdges->push_back(edge);
00285 myAllEdges.push_back(edge);
00286 }
00287 }
00288
00289
00290 bool
00291 NBNode::swapWhenReversed(bool leftHand,
00292 const std::vector<NBEdge*>::iterator &i1,
00293 const std::vector<NBEdge*>::iterator &i2) {
00294 NBEdge *e1 = *i1;
00295 NBEdge *e2 = *i2;
00296 if (leftHand) {
00297 if (e1->getToNode()==this && e1->isTurningDirectionAt(this, e2)) {
00298 std::swap(*i1, *i2);
00299 return true;
00300 }
00301 } else {
00302 if (e2->getToNode()==this && e2->isTurningDirectionAt(this, e1)) {
00303 std::swap(*i1, *i2);
00304 return true;
00305 }
00306 }
00307 return false;
00308 }
00309
00310 void
00311 NBNode::setPriorities() {
00312
00313 std::vector<NBEdge*>::iterator i;
00314
00315 if (myIncomingEdges->size()==1&&myOutgoingEdges->size()==1) {
00316 for (i=myAllEdges.begin(); i!=myAllEdges.end(); i++) {
00317 (*i)->setJunctionPriority(this, 1);
00318 }
00319 return;
00320 }
00321
00322 for (i=myAllEdges.begin(); i!=myAllEdges.end(); i++) {
00323 (*i)->setJunctionPriority(this, 0);
00324 }
00325
00326 if (myType!=NODETYPE_RIGHT_BEFORE_LEFT) {
00327 setPriorityJunctionPriorities();
00328 }
00329 }
00330
00331
00332 NBNode::BasicNodeType
00333 NBNode::computeType(const NBTypeCont &tc) const {
00334
00335 if (myType!=NODETYPE_UNKNOWN) {
00336 return myType;
00337 }
00338
00339 if (myIncomingEdges->size()==1) {
00340 return NODETYPE_PRIORITY_JUNCTION;
00341 }
00342 if (isSimpleContinuation()) {
00343 return NODETYPE_PRIORITY_JUNCTION;
00344 }
00345
00346 BasicNodeType type = NODETYPE_RIGHT_BEFORE_LEFT;
00347
00348 for (std::vector<NBEdge*>::const_iterator i=myIncomingEdges->begin(); i!=myIncomingEdges->end(); i++) {
00349 for (std::vector<NBEdge*>::const_iterator j=i+1; j!=myIncomingEdges->end(); j++) {
00350 bool isOpposite = false;
00351 if (getOppositeIncoming(*j)==*i&&myIncomingEdges->size()>2) {
00352 isOpposite = true;
00353 }
00354
00355
00356
00357
00358 BasicNodeType tmptype = type;
00359 if (!isOpposite) {
00360 tmptype = tc.getJunctionType((*i)->getSpeed(), (*j)->getSpeed());
00361 if (tmptype<type&&tmptype!=NODETYPE_UNKNOWN&&tmptype!=NODETYPE_NOJUNCTION) {
00362 type = tmptype;
00363 }
00364 }
00365 }
00366 }
00367 return type;
00368 }
00369
00370
00371 bool
00372 NBNode::isSimpleContinuation() const {
00373
00374 if (myIncomingEdges->size()==1&&myOutgoingEdges->size()==1) {
00375
00376 return (*(myIncomingEdges->begin()))->getNoLanes()==(*(myOutgoingEdges->begin()))->getNoLanes();
00377 }
00378
00379 if (myIncomingEdges->size()==2&&myOutgoingEdges->size()==2) {
00380 for (EdgeVector::const_iterator i=myIncomingEdges->begin(); i!=myIncomingEdges->end(); i++) {
00381 NBEdge *in = *i;
00382 EdgeVector::const_iterator opposite = find_if(myOutgoingEdges->begin(), myOutgoingEdges->end(), NBContHelper::opposite_finder(in, this));
00383
00384 if (opposite==myOutgoingEdges->end()) {
00385 return false;
00386 }
00387
00388 NBContHelper::nextCW(myOutgoingEdges, opposite);
00389 if (in->getNoLanes()!=(*opposite)->getNoLanes()) {
00390 return false;
00391 }
00392 }
00393 return true;
00394 }
00395
00396 return false;
00397 }
00398
00399
00400 bool
00401 samePriority(NBEdge *e1, NBEdge *e2) {
00402 if (e1==e2) {
00403 return true;
00404 }
00405 if (e1->getPriority()!=e2->getPriority()) {
00406 return false;
00407 }
00408 if ((int) e1->getSpeed()!=(int) e2->getSpeed()) {
00409 return false;
00410 }
00411 return (int) e1->getNoLanes()==(int) e2->getNoLanes();
00412 }
00413
00414
00415 void
00416 NBNode::setPriorityJunctionPriorities() {
00417 if (myIncomingEdges->size()==0||myOutgoingEdges->size()==0) {
00418 return;
00419 }
00420 std::vector<NBEdge*> incoming(*myIncomingEdges);
00421 std::vector<NBEdge*> outgoing(*myOutgoingEdges);
00422
00423
00424
00425 std::sort(incoming.begin(), incoming.end(), NBContHelper::edge_by_priority_sorter());
00426 std::vector<NBEdge*> bestIncoming;
00427 NBEdge *best = incoming[0];
00428 while (incoming.size()>0&&samePriority(best, incoming[0])) {
00429 bestIncoming.push_back(*incoming.begin());
00430 incoming.erase(incoming.begin());
00431 }
00432
00433 assert(outgoing.size()!=0);
00434 sort(outgoing.begin(), outgoing.end(), NBContHelper::edge_by_priority_sorter());
00435 std::vector<NBEdge*> bestOutgoing;
00436 best = outgoing[0];
00437 while (outgoing.size()>0&&samePriority(best, outgoing[0])) {
00438 bestOutgoing.push_back(*outgoing.begin());
00439 outgoing.erase(outgoing.begin());
00440 }
00441
00442
00443
00444 std::vector<NBEdge*>::iterator i;
00445 std::map<NBEdge*, NBEdge*> counterIncomingEdges;
00446 std::map<NBEdge*, NBEdge*> counterOutgoingEdges;
00447 incoming = *myIncomingEdges;
00448 outgoing = *myOutgoingEdges;
00449 for (i=bestIncoming.begin(); i!=bestIncoming.end(); ++i) {
00450 std::sort(incoming.begin(), incoming.end(), NBContHelper::edge_opposite_direction_sorter(*i));
00451 counterIncomingEdges[*i] = *incoming.begin();
00452 std::sort(outgoing.begin(), outgoing.end(), NBContHelper::edge_opposite_direction_sorter(*i));
00453 counterOutgoingEdges[*i] = *outgoing.begin();
00454 }
00455
00456
00457 if (bestIncoming.size()==1) {
00458
00459 NBEdge *best1 = extractAndMarkFirst(bestIncoming);
00460 if (bestOutgoing.size()!=0) {
00461
00462 sort(bestOutgoing.begin(), bestOutgoing.end(), NBContHelper::edge_similar_direction_sorter(best1));
00463 extractAndMarkFirst(bestOutgoing);
00464 }
00465 return;
00466 }
00467
00468
00469
00470
00471
00472
00473
00474 SUMOReal bestAngle = 0;
00475 NBEdge *bestFirst = 0;
00476 NBEdge *bestSecond = 0;
00477 bool hadBest = false;
00478 for (i=bestIncoming.begin(); i!=bestIncoming.end(); ++i) {
00479 std::vector<NBEdge*>::iterator j;
00480 NBEdge *t1 = *i;
00481 SUMOReal angle1 = t1->getAngle()+180;
00482 if (angle1>=360) {
00483 angle1 -= 360;
00484 }
00485 for (j=i+1; j!=bestIncoming.end(); ++j) {
00486 NBEdge *t2 = *j;
00487 SUMOReal angle2 = t2->getAngle()+180;
00488 if (angle2>=360) {
00489 angle2 -= 360;
00490 }
00491 SUMOReal angle = GeomHelper::getMinAngleDiff(angle1, angle2);
00492 if (!hadBest||angle>bestAngle) {
00493 bestAngle = angle;
00494 bestFirst = *i;
00495 bestSecond = *j;
00496 hadBest = true;
00497 }
00498 }
00499 }
00500 bestFirst->setJunctionPriority(this, 1);
00501 sort(bestOutgoing.begin(), bestOutgoing.end(), NBContHelper::edge_similar_direction_sorter(bestFirst));
00502 if (bestOutgoing.size()!=0) {
00503 extractAndMarkFirst(bestOutgoing);
00504 }
00505 bestSecond->setJunctionPriority(this, 1);
00506 sort(bestOutgoing.begin(), bestOutgoing.end(), NBContHelper::edge_similar_direction_sorter(bestSecond));
00507 if (bestOutgoing.size()!=0) {
00508 extractAndMarkFirst(bestOutgoing);
00509 }
00510 }
00511
00512
00513 NBEdge*
00514 NBNode::extractAndMarkFirst(std::vector<NBEdge*> &s) {
00515 if (s.size()==0) {
00516 return 0;
00517 }
00518 NBEdge *ret = s.front();
00519 s.erase(s.begin());
00520 ret->setJunctionPriority(this, 1);
00521 return ret;
00522 }
00523
00524
00525 unsigned int
00526 NBNode::countInternalLanes(bool includeSplits) {
00527 unsigned int lno = 0;
00528 EdgeVector::iterator i;
00529 for (i=myIncomingEdges->begin(); i!=myIncomingEdges->end(); i++) {
00530 unsigned int noLanesEdge = (*i)->getNoLanes();
00531 for (unsigned int j=0; j<noLanesEdge; j++) {
00532 std::vector<NBEdge::Connection> elv = (*i)->getConnectionsFromLane(j);
00533 for (std::vector<NBEdge::Connection>::iterator k=elv.begin(); k!=elv.end(); ++k) {
00534 if ((*k).toEdge==0) {
00535 continue;
00536 }
00537 lno++;
00538
00539 if (includeSplits) {
00540 std::pair<SUMOReal, std::vector<unsigned int> > cross = getCrossingPosition(*i, j, (*k).toEdge, (*k).toLane);
00541 if (cross.first>=0) {
00542 lno++;
00543 }
00544 }
00545 }
00546 }
00547 }
00548 return lno;
00549 }
00550
00551
00552 void
00553 NBNode::writeXMLInternalLinks(OutputDevice &into) {
00554 unsigned int noInternalNoSplits = countInternalLanes(false);
00555 if (noInternalNoSplits==0) {
00556 return;
00557 }
00558 std::string id = ":" + myID;
00559 unsigned int lno = 0;
00560 unsigned int splitNo = 0;
00561 EdgeVector::iterator i;
00562 for (i=myIncomingEdges->begin(); i!=myIncomingEdges->end(); i++) {
00563 unsigned int noLanesEdge = (*i)->getNoLanes();
00564 for (unsigned int j=0; j<noLanesEdge; j++) {
00565 std::vector<NBEdge::Connection> elv = (*i)->getConnectionsFromLane(j);
00566 for (std::vector<NBEdge::Connection>::iterator k=elv.begin(); k!=elv.end(); ++k) {
00567 if ((*k).toEdge==0) {
00568 continue;
00569 }
00570
00571
00572 SUMOReal vmax = (SUMOReal) 0.3 * (SUMOReal) 9.80778 *
00573 (*i)->getLaneShape(j).getEnd().distanceTo(
00574 (*k).toEdge->getLaneShape((*k).toLane).getBegin())
00575 / (SUMOReal) 2.0 / (SUMOReal) PI;
00576 vmax = MIN2(vmax, (((*i)->getSpeed()+(*k).toEdge->getSpeed())/(SUMOReal) 2.0));
00577 vmax = ((*i)->getSpeed()+(*k).toEdge->getSpeed())/(SUMOReal) 2.0;
00578
00579 std::string id = ":" + myID + "_" + toString(lno);
00580 Position2D end = (*k).toEdge->getLaneShape((*k).toLane).getBegin();
00581 Position2D beg = (*i)->getLaneShape(j).getEnd();
00582
00583 Position2DVector shape = computeInternalLaneShape(*i, j, (*k).toEdge, (*k).toLane);
00584 if (shape.size()==1) {
00585 shape.push_back(shape[0]);
00586 }
00587 SUMOReal length = MAX2(shape.length(), (SUMOReal) .1);
00588
00589
00590 std::pair<SUMOReal, std::vector<unsigned int> > cross = getCrossingPosition(*i, j, (*k).toEdge, (*k).toLane);
00591 if (cross.first>=0) {
00592 std::pair<Position2DVector, Position2DVector> split;
00593
00594
00595
00596 if (shape.length()!=0) {
00597 split = shape.splitAt(cross.first);
00598 } else {
00599 split = std::pair<Position2DVector, Position2DVector>(shape, shape);
00600 }
00601 if (split.first.size()==1) {
00602 split.first.push_back(split.first[0]);
00603 }
00604 if (split.second.size()==1) {
00605 split.second.push_back(split.second[0]);
00606 }
00607
00608 into << " <edge id=\"" << id << "\" function=\"internal\">\n";
00609 into << " <lanes>\n";
00610 into << " <lane id=\"" << id << "_0\" depart=\"0\" "
00611 << "maxspeed=\"" << vmax << "\" length=\""
00612 << toString<SUMOReal>(cross.first) << "\""
00613 << " shape=\"" << split.first << "\"/>\n"
00614 << " </lanes>\n"
00615 << " </edge>\n\n";
00616 lno++;
00617
00618 std::string id = ":" + myID + "_" + toString(splitNo+noInternalNoSplits);
00619 into << " <edge id=\"" << id
00620 << "\" function=\"internal\">\n";
00621 into << " <lanes>\n";
00622 into << " <lane id=\"" << id << "_0\" depart=\"0\" "
00623 << "maxspeed=\"" << vmax << "\" length=\""
00624 << toString<SUMOReal>(length-cross.first) << "\""
00625 << " shape=\"" << split.second << "\"/>\n"
00626 << " </lanes>\n"
00627 << " </edge>\n\n";
00628 splitNo++;
00629 } else {
00630 into << " <edge id=\"" << id
00631 << "\" function=\"internal\">\n";
00632 into << " <lanes>\n";
00633 into << " <lane id=\"" << id << "_0\" depart=\"0\" "
00634 << "maxspeed=\"" << vmax << "\" length=\""
00635 << toString<SUMOReal>(length) << "\""
00636 << " shape=\"" << shape << "\"/>\n"
00637 << " </lanes>\n"
00638 << " </edge>\n\n";
00639 lno++;
00640 }
00641 }
00642 }
00643 }
00644 }
00645
00646
00647 Position2DVector
00648 NBNode::computeInternalLaneShape(NBEdge *fromE, int fromL,
00649 NBEdge *toE, int toL) {
00650 if (fromL>=(int) fromE->getNoLanes()) {
00651 throw ProcessError("Connection '" + fromE->getID() + "_" + toString(fromL) + "->" + toE->getID() + "_" + toString(toL) + "' starts at a not existing lane.");
00652 }
00653 if (toL>=(int) toE->getNoLanes()) {
00654 throw ProcessError("Connection '" + fromE->getID() + "_" + toString(fromL) + "->" + toE->getID() + "_" + toString(toL) + "' yields in a not existing lane.");
00655 }
00656 bool noSpline = false;
00657 Position2DVector ret;
00658 Position2DVector init;
00659 Position2D beg = fromE->getLaneShape(fromL).getEnd();
00660 Position2D end = toE->getLaneShape(toL).getBegin();
00661 Position2D intersection;
00662 unsigned int noInitialPoints = 0;
00663 if (beg==end) {
00664 noSpline = true;
00665 } else {
00666 if (fromE->getTurnDestination()==toE) {
00667
00668
00669
00670
00671 noInitialPoints = 3;
00672 init.push_back(beg);
00673 Line2D straightConn(fromE->getLaneShape(fromL)[-1],toE->getLaneShape(toL)[0]);
00674 Position2D straightCenter = straightConn.getPositionAtDistance((SUMOReal) straightConn.length() / (SUMOReal) 2.);
00675 Position2D center = straightCenter;
00676 Line2D cross(straightConn);
00677 cross.sub(cross.p1().x(), cross.p1().y());
00678 cross.rotateAtP1(PI/2);
00679 center.sub(cross.p2());
00680 init.push_back(center);
00681 init.push_back(end);
00682 } else {
00683
00684 SUMOReal angle1 = fromE->getLaneShape(fromL).getEndLine().atan2DegreeAngle();
00685 SUMOReal angle2 = toE->getLaneShape(toL).getBegLine().atan2DegreeAngle();
00686 SUMOReal angle = GeomHelper::getMinAngleDiff(angle1, angle2);
00687 if (angle<45) {
00688
00689 noInitialPoints = 4;
00690 init.push_back(beg);
00691 Line2D begL = fromE->getLaneShape(fromL).getEndLine();
00692 begL.extrapolateSecondBy(100);
00693 Line2D endL = toE->getLaneShape(toL).getBegLine();
00694 endL.extrapolateFirstBy(100);
00695 SUMOReal distance = beg.distanceTo(end);
00696 if (distance>10) {
00697 {
00698 SUMOReal off1 = fromE->getLaneShape(fromL).getEndLine().length() + (SUMOReal) 5. * (SUMOReal) fromE->getNoLanes();
00699 off1 = MIN2(off1, (SUMOReal)(fromE->getLaneShape(fromL).getEndLine().length()+distance/2.));
00700 Position2D tmp = begL.getPositionAtDistance(off1);
00701 init.push_back(tmp);
00702 }
00703 {
00704 SUMOReal off1 = (SUMOReal) 100. - (SUMOReal) 5. * (SUMOReal) toE->getNoLanes();
00705 off1 = MAX2(off1, (SUMOReal)(100.-distance/2.));
00706 Position2D tmp = endL.getPositionAtDistance(off1);
00707 init.push_back(tmp);
00708 }
00709 } else {
00710 noSpline = true;
00711 }
00712 init.push_back(end);
00713 } else {
00714
00715
00716
00717
00718
00719 noInitialPoints = 3;
00720 init.push_back(beg);
00721 Line2D begL = fromE->getLaneShape(fromL).getEndLine();
00722 Line2D endL = toE->getLaneShape(toL).getBegLine();
00723 bool check = !begL.p1().almostSame(begL.p2()) && !endL.p1().almostSame(endL.p2());
00724 if (check) {
00725 begL.extrapolateSecondBy(100);
00726 endL.extrapolateFirstBy(100);
00727 } else {
00728 MsgHandler::getWarningInstance()->inform("Could not use edge geometry for internal lane, node '" + getID() + "'.");
00729 }
00730 if (!check||!begL.intersects(endL)) {
00731 noSpline = true;
00732 } else {
00733 init.push_back(begL.intersectsAt(endL));
00734 }
00735 init.push_back(end);
00736 }
00737 }
00738 }
00739
00740 if (noSpline) {
00741 ret.push_back(fromE->getLaneShape(fromL).getEnd());
00742 ret.push_back(toE->getLaneShape(toL).getBegin());
00743 return ret;
00744 }
00745
00746 SUMOReal *def = new SUMOReal[1+noInitialPoints*3];
00747 for (int i=0; i<(int) init.size(); ++i) {
00748
00749 def[i*3+1] = init[i].x();
00750 def[i*3+2] = 0;
00751 def[i*3+3] = init[i].y();
00752 }
00753 SUMOReal ret_buf[NO_INTERNAL_POINTS*3+1];
00754 bezier(noInitialPoints, def, NO_INTERNAL_POINTS, ret_buf);
00755 delete[] def;
00756 Position2D prev;
00757
00758 for (int i=0; i<(int) NO_INTERNAL_POINTS; i++) {
00759 Position2D current(ret_buf[i*3+1], ret_buf[i*3+3]);
00760 if (prev!=current) {
00761 ret.push_back(current);
00762 }
00763 prev = current;
00764 }
00765 return ret;
00766 }
00767
00768
00769 std::pair<SUMOReal, std::vector<unsigned int> >
00770 NBNode::getCrossingPosition(NBEdge *fromE, unsigned int fromL, NBEdge *toE, unsigned int toL) {
00771 std::pair<SUMOReal, std::vector<unsigned int> > ret(-1, std::vector<unsigned int>());
00772 NBMMLDirection dir = getMMLDirection(fromE, toE);
00773 switch (dir) {
00774 case MMLDIR_LEFT:
00775 case MMLDIR_PARTLEFT:
00776 case MMLDIR_TURN: {
00777 Position2DVector thisShape = computeInternalLaneShape(fromE, fromL, toE, toL);
00778 unsigned int index = 0;
00779 for (EdgeVector::iterator i2=myIncomingEdges->begin(); i2!=myIncomingEdges->end(); i2++) {
00780 unsigned int noLanesEdge = (*i2)->getNoLanes();
00781 for (unsigned int j2=0; j2<noLanesEdge; j2++) {
00782 std::vector<NBEdge::Connection> elv = (*i2)->getConnectionsFromLane(j2);
00783 for (std::vector<NBEdge::Connection>::iterator k2=elv.begin(); k2!=elv.end(); k2++) {
00784 if ((*k2).toEdge==0) {
00785 continue;
00786 }
00787 if (fromE!=(*i2)&&forbids(*i2, (*k2).toEdge, fromE, toE, true)) {
00788
00789 ret.second.push_back(index);
00790 Position2DVector otherShape = computeInternalLaneShape(*i2, j2, (*k2).toEdge, (*k2).toLane);
00791 if (thisShape.intersects(otherShape)) {
00792 DoubleVector dv = thisShape.intersectsAtLengths(otherShape);
00793 SUMOReal minDV = dv[0];
00794 if (minDV<thisShape.length()-.1&&minDV>.1) {
00795 assert(minDV>=0);
00796 if (ret.first<0||ret.first>minDV) {
00797 ret.first = minDV;
00798 }
00799 }
00800 }
00801 }
00802 index++;
00803 }
00804 }
00805 }
00806 if (dir==MMLDIR_TURN&&ret.first<0&&ret.second.size()!=0) {
00807
00808 ret.first = (SUMOReal) POSITION_EPS;
00809 }
00810 }
00811 break;
00812 default:
00813 break;
00814 }
00815 return ret;
00816 }
00817
00818
00819 std::string
00820 NBNode::getCrossingNames_dividedBySpace(NBEdge *fromE, unsigned int fromL,
00821 NBEdge *toE, unsigned int toL) {
00822 std::string ret;
00823 NBMMLDirection dir = getMMLDirection(fromE, toE);
00824 switch (dir) {
00825 case MMLDIR_LEFT:
00826 case MMLDIR_PARTLEFT:
00827 case MMLDIR_TURN: {
00828 Position2DVector thisShape = computeInternalLaneShape(fromE, fromL, toE, toL);
00829 unsigned int index = 0;
00830 for (EdgeVector::iterator i2=myIncomingEdges->begin(); i2!=myIncomingEdges->end(); i2++) {
00831 unsigned int noLanesEdge = (*i2)->getNoLanes();
00832 for (unsigned int j2=0; j2<noLanesEdge; j2++) {
00833 std::vector<NBEdge::Connection> elv = (*i2)->getConnectionsFromLane(j2);
00834 for (std::vector<NBEdge::Connection>::iterator k2=elv.begin(); k2!=elv.end(); k2++) {
00835 if ((*k2).toEdge==0) {
00836 continue;
00837 }
00838 NBEdge *e = fromE->getToNode()->getOppositeIncoming(fromE);
00839 if (e!=*i2) {
00840 index++;
00841 continue;
00842 }
00843 NBMMLDirection dir2 = getMMLDirection(*i2, (*k2).toEdge);
00844 bool left = dir2==MMLDIR_LEFT || dir2==MMLDIR_PARTLEFT || dir2==MMLDIR_TURN;
00845 left = false;
00846 if (!left&&fromE!=(*i2)&&forbids(*i2, (*k2).toEdge, fromE, toE, true)) {
00847 if (ret.length()!=0) {
00848 ret += " ";
00849 }
00850 ret += (":" + myID + "_" + toString(index) + "_0");
00851 }
00852 index++;
00853 }
00854 }
00855 }
00856 }
00857 break;
00858 default:
00859 break;
00860 }
00861 return ret;
00862 }
00863
00864
00865 std::string
00866 NBNode::getCrossingSourcesNames_dividedBySpace(NBEdge *fromE, unsigned int fromL,
00867 NBEdge *toE, unsigned int toL) {
00868 std::string ret;
00869 std::vector<std::string> tmp;
00870 NBMMLDirection dir = getMMLDirection(fromE, toE);
00871 switch (dir) {
00872 case MMLDIR_LEFT:
00873 case MMLDIR_PARTLEFT:
00874 case MMLDIR_TURN: {
00875 Position2DVector thisShape = computeInternalLaneShape(fromE, fromL, toE, toL);
00876 unsigned int index = 0;
00877 for (EdgeVector::iterator i2=myIncomingEdges->begin(); i2!=myIncomingEdges->end(); i2++) {
00878 unsigned int noLanesEdge = (*i2)->getNoLanes();
00879 for (unsigned int j2=0; j2<noLanesEdge; j2++) {
00880 std::vector<NBEdge::Connection> elv = (*i2)->getConnectionsFromLane(j2);
00881 for (std::vector<NBEdge::Connection>::iterator k2=elv.begin(); k2!=elv.end(); k2++) {
00882 if ((*k2).toEdge==0) {
00883 continue;
00884 }
00885 NBEdge *e = fromE->getToNode()->getOppositeIncoming(fromE);
00886 if (e!=*i2) {
00887 index++;
00888 continue;
00889 }
00890 NBMMLDirection dir2 = getMMLDirection(*i2, (*k2).toEdge);
00891 bool left = dir2==MMLDIR_LEFT || dir2==MMLDIR_PARTLEFT || dir2==MMLDIR_TURN;
00892 left = false;
00893 if (!left&&fromE!=(*i2)&&forbids(*i2, (*k2).toEdge, fromE, toE, true)) {
00894 std::string nid = (*i2)->getID() + "_" + toString(j2);
00895 if (find(tmp.begin(), tmp.end(), nid)==tmp.end()) {
00896 tmp.push_back(nid);
00897 }
00898 }
00899 index++;
00900 }
00901 }
00902 }
00903 }
00904 break;
00905 default:
00906 break;
00907 }
00908 for (std::vector<std::string>::iterator i=tmp.begin(); i!=tmp.end(); ++i) {
00909 if (ret.length()>0) {
00910 ret = ret + " ";
00911 }
00912 ret = ret + *i;
00913 }
00914 return ret;
00915 }
00916
00917
00918 void
00919 NBNode::writeXMLInternalSuccInfos(OutputDevice &into) {
00920 unsigned int noInternalNoSplits = countInternalLanes(false);
00921 if (noInternalNoSplits==0) {
00922 return;
00923 }
00924 unsigned int lno = 0;
00925 unsigned int splitNo = 0;
00926 for (EdgeVector::iterator i=myIncomingEdges->begin(); i!=myIncomingEdges->end(); i++) {
00927 unsigned int noLanesEdge = (*i)->getNoLanes();
00928 for (unsigned int j=0; j<noLanesEdge; j++) {
00929 std::vector<NBEdge::Connection> elv = (*i)->getConnectionsFromLane(j);
00930 for (std::vector<NBEdge::Connection>::iterator k=elv.begin(); k!=elv.end(); ++k) {
00931 if ((*k).toEdge==0) {
00932 continue;
00933 }
00934 std::string id = ":" + myID + "_" + toString(lno);
00935 std::string sid = ":" + myID + "_" + toString(splitNo+noInternalNoSplits);
00936 std::pair<SUMOReal, std::vector<unsigned int> > cross = getCrossingPosition(*i, j, (*k).toEdge, (*k).toLane);
00937
00938
00939 into << " <succ edge=\"" << id << "\" "
00940 << "lane=\"" << id << "_"
00941 << 0 << "\" junction=\"" << myID << "\">\n";
00942 if (cross.first>=0) {
00943 into << " <succlane lane=\""
00944
00945 << (*k).toEdge->getID() << "_" << (*k).toLane << "\""
00946 << " via=\"" << sid << "_" << 0 << "\""
00947 << " tl=\"" << "" << "\" linkno=\""
00948 << "" << "\" yield=\"1\" dir=\"s\" state=\"M\"";
00949 } else {
00950 into << " <succlane lane=\""
00951 << (*k).toEdge->getID() << "_" << (*k).toLane
00952 << "\" tl=\"" << "" << "\" linkno=\""
00953 << "" << "\" yield=\"0\" dir=\"s\" state=\"M\"";
00954 }
00955 into << "/>\n";
00956 into << " </succ>\n";
00957
00958 if (cross.first>=0) {
00959 into << " <succ edge=\"" << sid << "\" "
00960 << "lane=\"" << sid << "_" << 0
00961 << "\" junction=\"" << sid << "\">\n";
00962 into << " <succlane lane=\""
00963 << (*k).toEdge->getID() << "_" << (*k).toLane
00964 << "\" tl=\"" << "" << "\" linkno=\""
00965 << "0" << "\" yield=\"0\" dir=\"s\" state=\"M\"";
00966 into << "/>\n";
00967 into << " </succ>\n";
00968 splitNo++;
00969 }
00970 lno++;
00971 }
00972 }
00973 }
00974 }
00975
00976
00977 void
00978 NBNode::writeXMLInternalNodes(OutputDevice &into) {
00979 unsigned int noInternalNoSplits = countInternalLanes(false);
00980 if (noInternalNoSplits==0) {
00981 return;
00982 }
00983 unsigned int lno = 0;
00984 unsigned int splitNo = 0;
00985 for (EdgeVector::iterator i=myIncomingEdges->begin(); i!=myIncomingEdges->end(); i++) {
00986 unsigned int noLanesEdge = (*i)->getNoLanes();
00987 for (unsigned int j=0; j<noLanesEdge; j++) {
00988 std::vector<NBEdge::Connection> elv = (*i)->getConnectionsFromLane(j);
00989 for (std::vector<NBEdge::Connection>::iterator k=elv.begin(); k!=elv.end(); ++k) {
00990 if ((*k).toEdge==0) {
00991 continue;
00992 }
00993 std::pair<SUMOReal, std::vector<unsigned int> > cross = getCrossingPosition(*i, j, (*k).toEdge, (*k).toLane);
00994 if (cross.first<=0) {
00995 lno++;
00996 continue;
00997 }
00998
00999 std::string sid = ":" + myID + "_" + toString(splitNo+noInternalNoSplits) + "_0";
01000 std::string iid = ":" + myID + "_" + toString(lno) + "_0";
01001 Position2DVector shape = computeInternalLaneShape(*i, j, (*k).toEdge, (*k).toLane);
01002 Position2D pos = shape.positionAtLengthPosition(cross.first);
01003 into << " <junction id=\"" << sid << '\"';
01004 into << " type=\"" << "internal\"";
01005 into << " x=\"" << pos.x() << "\" y=\"" << pos.y() << "\"";
01006 into << " incLanes=\"";
01007 std::string furtherIncoming = getCrossingSourcesNames_dividedBySpace(*i, j, (*k).toEdge, (*k).toLane);
01008 if (furtherIncoming.length()!=0) {
01009 into << iid << " " << furtherIncoming;
01010 } else {
01011 into << iid;
01012 }
01013 into << "\"";
01014 into << " intLanes=\"" << getCrossingNames_dividedBySpace(*i, j, (*k).toEdge, (*k).toLane) << "\"";
01015 into << " shape=\"\"/>\n\n";
01016 splitNo++;
01017 lno++;
01018 }
01019 }
01020 }
01021 }
01022
01023
01024 void
01025 NBNode::writeinternal(EdgeVector *myIncomingEdges, OutputDevice &into, const std::string &id) {
01026 unsigned int l = 0;
01027 unsigned int o = countInternalLanes(false);
01028 for (EdgeVector::iterator i=myIncomingEdges->begin(); i!=myIncomingEdges->end(); i++) {
01029 unsigned int noLanesEdge = (*i)->getNoLanes();
01030 for (unsigned int j=0; j<noLanesEdge; j++) {
01031 std::vector<NBEdge::Connection> elv = (*i)->getConnectionsFromLane(j);
01032 for (std::vector<NBEdge::Connection>::iterator k=elv.begin(); k!=elv.end(); ++k) {
01033 if ((*k).toEdge==0) {
01034 continue;
01035 }
01036 if (l!=0) {
01037 into << ' ';
01038 }
01039 std::pair<SUMOReal, std::vector<unsigned int> > cross = getCrossingPosition(*i, j, (*k).toEdge, (*k).toLane);
01040 if (cross.first<=0) {
01041 into << ':' << id << '_' << l << "_0";
01042 } else {
01043 into << ':' << id << '_' << o << "_0";
01044 o++;
01045 }
01046 l++;
01047 }
01048 }
01049 }
01050 }
01051
01052
01053 void
01054 NBNode::writeXML(OutputDevice &into) {
01055
01056 into << " <junction id=\"" << myID << '\"';
01057 if (myIncomingEdges->size()!=0&&myOutgoingEdges->size()!=0) {
01058
01059 switch (myType) {
01060 case NODETYPE_NOJUNCTION:
01061 into << " type=\"" << "unregulated\"";
01062 break;
01063 case NODETYPE_PRIORITY_JUNCTION:
01064 case NODETYPE_TRAFFIC_LIGHT:
01065 into << " type=\"" << "priority\"";
01066 break;
01067 case NODETYPE_RIGHT_BEFORE_LEFT:
01068 into << " type=\"" << "right_before_left\"";
01069 break;
01070 case NODETYPE_DISTRICT:
01071 into << " type=\"" << "district\"";
01072 break;
01073 default:
01074 throw ProcessError("An unknown junction type occured (" + toString(myType) + ")");
01075 }
01076 } else {
01077 into << " type=\"DEAD_END\"";
01078 }
01079 into << " x=\"" << myPosition.x() << "\" y=\"" << myPosition.y() << "\"";
01080 into << " incLanes=\"";
01081
01082 EdgeVector::iterator i;
01083 for (i=myIncomingEdges->begin(); i!=myIncomingEdges->end(); i++) {
01084 unsigned int noLanes = (*i)->getNoLanes();
01085 std::string id = (*i)->getID();
01086 for (unsigned int j=0; j<noLanes; j++) {
01087 into << id << '_' << j;
01088 if (i!=myIncomingEdges->end()-1 || j<noLanes-1) {
01089 into << ' ';
01090 }
01091 }
01092 }
01093 into << "\"";
01094
01095 into << " intLanes=\"";
01096 if (!OptionsCont::getOptions().getBool("no-internal-links")) {
01097 writeinternal(myIncomingEdges, into, myID);
01098 }
01099 into << "\"";
01100
01101 into << " shape=\"" << myPoly << "\"/>\n\n";
01102 }
01103
01104
01105 void
01106 NBNode::computeLogic(const NBEdgeCont &ec, NBJunctionLogicCont &jc,
01107 OptionsCont &) {
01108 if (myIncomingEdges->size()==0||myOutgoingEdges->size()==0) {
01109
01110 myType = NODETYPE_NOJUNCTION;
01111 return;
01112 }
01113
01114 if (OptionsCont::getOptions().getBool("keep-unregulated")
01115 ||
01116 OptionsCont::getOptions().isInStringVector("keep-unregulated.nodes", getID())
01117 ||
01118 (OptionsCont::getOptions().getBool("keep-unregulated.district-nodes")&&(isNearDistrict()||isDistrict()))) {
01119
01120 myType = NODETYPE_NOJUNCTION;
01121 return;
01122 }
01123
01124 if (myType!=NODETYPE_NOJUNCTION&&myType!=NODETYPE_DISTRICT) {
01125
01126 myRequest = new NBRequest(ec, this,
01127 static_cast<const EdgeVector * const>(&myAllEdges),
01128 static_cast<const EdgeVector * const>(myIncomingEdges),
01129 static_cast<const EdgeVector * const>(myOutgoingEdges),
01130 myBlockedConnections);
01131
01132 if (myRequest->getSizes().second>=64) {
01133
01134 MsgHandler::getWarningInstance()->inform("Junction '" + getID() + "' is too complicated (#links>64); will be set to unregulated.");
01135 delete myRequest;
01136 myRequest = 0;
01137 myType = NODETYPE_NOJUNCTION;
01138 } else {
01139 myRequest->buildBitfieldLogic(ec.isLeftHanded(), jc, myID);
01140 }
01141 }
01142 }
01143
01144
01145 void
01146 NBNode::sortNodesEdges(bool leftHand, const NBTypeCont &tc) {
01147
01148 sort(myAllEdges.begin(), myAllEdges.end(), NBContHelper::edge_by_junction_angle_sorter(this));
01149 sort(myIncomingEdges->begin(), myIncomingEdges->end(), NBContHelper::edge_by_junction_angle_sorter(this));
01150 sort(myOutgoingEdges->begin(), myOutgoingEdges->end(), NBContHelper::edge_by_junction_angle_sorter(this));
01151 if (myAllEdges.size()==0) {
01152 return;
01153 }
01154 std::vector<NBEdge*>::iterator i;
01155 for (i=myAllEdges.begin(); i!=myAllEdges.end()-1&&i!=myAllEdges.end(); i++) {
01156 swapWhenReversed(leftHand ,i, i+1);
01157 }
01158 if (myAllEdges.size()>1 && i!=myAllEdges.end()) {
01159 swapWhenReversed(leftHand, myAllEdges.end()-1, myAllEdges.begin());
01160 }
01161 if (myType==NODETYPE_UNKNOWN) {
01162 myType = computeType(tc);
01163 }
01164 setPriorities();
01165
01166 if (OptionsCont::getOptions().isSet("node-type-output")) {
01167 std::string col;
01168 switch (myType) {
01169 case NODETYPE_NOJUNCTION:
01170 col = ".5,.5,.5";
01171 break;
01172 case NODETYPE_PRIORITY_JUNCTION:
01173 col = "0,1,0";
01174 break;
01175 case NODETYPE_RIGHT_BEFORE_LEFT:
01176 col = "0,0,1";
01177 break;
01178 case NODETYPE_DISTRICT:
01179 col = "1,0,0";
01180 break;
01181 case NODETYPE_TRAFFIC_LIGHT:
01182 col = "1,1,0";
01183 break;
01184 }
01185 OutputDevice::getDeviceByOption("node-type-output") << " <poi id=\"type_" << myID
01186 << "\" type=\"node_type\" color=\"" << col << "\""
01187 << " x=\"" << getPosition().x() << "\" y=\"" << getPosition().y() << "\"/>\n";
01188 }
01189 }
01190
01191
01192 void
01193 NBNode::computeNodeShape(bool leftHand) {
01194 if (myIncomingEdges->size()==0&&myOutgoingEdges->size()==0) {
01195 return;
01196 }
01197 try {
01198 NBNodeShapeComputer computer(*this);
01199 myPoly = computer.compute(leftHand);
01200 } catch (InvalidArgument &) {
01201 MsgHandler::getWarningInstance()->inform("For node '" + getID() + "': could not compute shape.");
01202 }
01203 }
01204
01205
01206 void
01207 NBNode::computeLanes2Lanes() {
01208
01209
01210 if (myIncomingEdges->size()==1&&myOutgoingEdges->size()==1
01211 &&(*myIncomingEdges)[0]->getNoLanes()==(*myOutgoingEdges)[0]->getNoLanes()-1
01212 &&(*myIncomingEdges)[0]!=(*myOutgoingEdges)[0]
01213 &&(*myIncomingEdges)[0]->isConnectedTo((*myOutgoingEdges)[0])) {
01214
01215 NBEdge *incoming = (*myIncomingEdges)[0];
01216 NBEdge *outgoing = (*myOutgoingEdges)[0];
01217
01218 if (incoming->getTurnDestination()==outgoing) {
01219
01220 return;
01221 }
01222 for (int i=0; i<(int) incoming->getNoLanes(); ++i) {
01223 incoming->setConnection(i, outgoing, i+1, NBEdge::L2L_COMPUTED);
01224 }
01225 incoming->setConnection(0, outgoing, 0, NBEdge::L2L_COMPUTED);
01226 return;
01227 }
01228
01229
01230
01231
01232 bool check = false;
01233 if (myIncomingEdges->size()==2&&myOutgoingEdges->size()==1) {
01234 check = (*myIncomingEdges)[0]->getNoLanes()+(*myIncomingEdges)[1]->getNoLanes()==(*myOutgoingEdges)[0]->getNoLanes();
01235 check &= ((*myIncomingEdges)[0]->getStep() <= NBEdge::LANES2EDGES);
01236 check &= ((*myIncomingEdges)[1]->getStep() <= NBEdge::LANES2EDGES);
01237 }
01238 if (check
01239 &&(*myIncomingEdges)[0]!=(*myOutgoingEdges)[0]
01240 &&(*myIncomingEdges)[0]->isConnectedTo((*myOutgoingEdges)[0])) {
01241 NBEdge *inc1 = (*myIncomingEdges)[0];
01242 NBEdge *inc2 = (*myIncomingEdges)[1];
01243
01244 SUMOReal a1 = inc1->getAngle(*this);
01245 SUMOReal a2 = inc2->getAngle(*this);
01246 SUMOReal ccw = GeomHelper::getCCWAngleDiff(a1, a2);
01247 SUMOReal cw = GeomHelper::getCWAngleDiff(a1, a2);
01248 if (ccw<cw) {
01249 std::swap(inc1, inc2);
01250 }
01251
01252 inc1->addLane2LaneConnections(0, (*myOutgoingEdges)[0], 0, inc1->getNoLanes(), NBEdge::L2L_VALIDATED, true, true);
01253 inc2->addLane2LaneConnections(0, (*myOutgoingEdges)[0], inc1->getNoLanes(), inc2->getNoLanes(), NBEdge::L2L_VALIDATED, true, true);
01254 return;
01255 }
01256
01257
01258
01259
01260
01261 std::vector<NBEdge*>::reverse_iterator i;
01262 for (i=myOutgoingEdges->rbegin(); i!=myOutgoingEdges->rend(); i++) {
01263 NBEdge *currentOutgoing = *i;
01264
01265 std::vector<NBEdge*> *approaching = getEdgesThatApproach(currentOutgoing);
01266 if (approaching->size()!=0) {
01267 ApproachingDivider divider(approaching, currentOutgoing);
01268 Bresenham::compute(÷r, (SUMOReal) approaching->size(),
01269 (SUMOReal) currentOutgoing->getNoLanes());
01270 }
01271 delete approaching;
01272 }
01273
01274
01275
01276 if (myOutgoingEdges->size()==0) {
01277 for (i=myIncomingEdges->rbegin(); i!=myIncomingEdges->rend(); i++) {
01278 (*i)->markAsInLane2LaneState();
01279 }
01280 }
01281 }
01282
01283
01284 std::vector<NBEdge*> *
01285 NBNode::getEdgesThatApproach(NBEdge *currentOutgoing) {
01286
01287 std::vector<NBEdge*>::const_iterator i = find(myAllEdges.begin(),
01288 myAllEdges.end(), currentOutgoing);
01289
01290 NBContHelper::nextCW(&myAllEdges, i);
01291
01292 std::vector<NBEdge*> *approaching = new std::vector<NBEdge*>();
01293 for (; *i!=currentOutgoing;) {
01294
01295 if ((*i)->getToNode()==this&&(*i)->getTurnDestination()!=currentOutgoing) {
01296 std::vector<int> connLanes = (*i)->getConnectionLanes(currentOutgoing);
01297 if (connLanes.size()!=0) {
01298 approaching->push_back(*i);
01299 }
01300 }
01301 NBContHelper::nextCW(&myAllEdges, i);
01302 }
01303 return approaching;
01304 }
01305
01306
01307 void
01308 NBNode::reshiftPosition(SUMOReal xoff, SUMOReal yoff) {
01309 myPosition.reshiftRotate(xoff, yoff, 0);
01310 myPoly.reshiftRotate(xoff, yoff, 0);
01311 }
01312
01313
01314 void
01315 NBNode::replaceOutgoing(NBEdge *which, NBEdge *by, unsigned int laneOff) {
01316
01317 std::vector<NBEdge*>::iterator i=find(myOutgoingEdges->begin(), myOutgoingEdges->end(), which);
01318 if (i!=myOutgoingEdges->end()) {
01319 (*i) = by;
01320 i = find(myAllEdges.begin(), myAllEdges.end(), which);
01321 (*i) = by;
01322 }
01323
01324 for (i=myIncomingEdges->begin(); i!=myIncomingEdges->end(); ++i) {
01325 (*i)->replaceInConnections(which, by, laneOff);
01326 }
01327
01328 replaceInConnectionProhibitions(which, by, 0, laneOff);
01329 }
01330
01331
01332 void
01333 NBNode::replaceOutgoing(const EdgeVector &which, NBEdge *by) {
01334
01335 unsigned int laneOff = 0;
01336 for (EdgeVector::const_iterator i=which.begin(); i!=which.end(); i++) {
01337 replaceOutgoing(*i, by, laneOff);
01338 laneOff += (*i)->getNoLanes();
01339 }
01340
01341 removeDoubleEdges();
01342
01343
01344 if (myDistrict!=0) {
01345 myDistrict->replaceOutgoing(which, by);
01346 }
01347 }
01348
01349
01350 void
01351 NBNode::replaceIncoming(NBEdge *which, NBEdge *by, unsigned int laneOff) {
01352
01353 std::vector<NBEdge*>::iterator i=find(myIncomingEdges->begin(), myIncomingEdges->end(), which);
01354 if (i!=myIncomingEdges->end()) {
01355 (*i) = by;
01356 i = find(myAllEdges.begin(), myAllEdges.end(), which);
01357 (*i) = by;
01358 }
01359
01360 replaceInConnectionProhibitions(which, by, laneOff, 0);
01361 }
01362
01363
01364 void
01365 NBNode::replaceIncoming(const EdgeVector &which, NBEdge *by) {
01366
01367 unsigned int laneOff = 0;
01368 for (EdgeVector::const_iterator i=which.begin(); i!=which.end(); i++) {
01369 replaceIncoming(*i, by, laneOff);
01370 laneOff += (*i)->getNoLanes();
01371 }
01372
01373 removeDoubleEdges();
01374
01375
01376 if (myDistrict!=0) {
01377 myDistrict->replaceIncoming(which, by);
01378 }
01379 }
01380
01381
01382
01383 void
01384 NBNode::replaceInConnectionProhibitions(NBEdge *which, NBEdge *by,
01385 unsigned int whichLaneOff, unsigned int byLaneOff) {
01386
01387 NBConnectionProhibits::iterator j = myBlockedConnections.begin();
01388 while (j!=myBlockedConnections.end()) {
01389 bool changed = false;
01390 NBConnection c = (*j).first;
01391 if (c.replaceFrom(which, whichLaneOff, by, byLaneOff)) {
01392 changed = true;
01393 }
01394 if (c.replaceTo(which, whichLaneOff, by, byLaneOff)) {
01395 changed = true;
01396 }
01397 if (changed) {
01398 myBlockedConnections[c] = (*j).second;
01399 myBlockedConnections.erase(j);
01400 j = myBlockedConnections.begin();
01401 } else {
01402 j++;
01403 }
01404 }
01405
01406 for (j=myBlockedConnections.begin(); j!=myBlockedConnections.end(); j++) {
01407 NBConnectionVector &prohibiting = (*j).second;
01408 for (NBConnectionVector::iterator k=prohibiting.begin(); k!=prohibiting.end(); k++) {
01409 NBConnection &sprohibiting = *k;
01410 sprohibiting.replaceFrom(which, whichLaneOff, by, byLaneOff);
01411 sprohibiting.replaceTo(which, whichLaneOff, by, byLaneOff);
01412 }
01413 }
01414 }
01415
01416
01417
01418 void
01419 NBNode::removeDoubleEdges() {
01420 unsigned int i, j;
01421
01422 for (i=0; myIncomingEdges->size()>0&&i<myIncomingEdges->size()-1; i++) {
01423 j = i + 1;
01424 while (j<myIncomingEdges->size()) {
01425 if ((*myIncomingEdges)[i]==(*myIncomingEdges)[j]) {
01426 myIncomingEdges->erase(myIncomingEdges->begin()+j);
01427 } else {
01428 j++;
01429 }
01430 }
01431 }
01432
01433 for (i=0; myOutgoingEdges->size()>0&&i<myOutgoingEdges->size()-1; i++) {
01434 j = i + 1;
01435 while (j<myOutgoingEdges->size()) {
01436 if ((*myOutgoingEdges)[i]==(*myOutgoingEdges)[j]) {
01437 myOutgoingEdges->erase(myOutgoingEdges->begin()+j);
01438 } else {
01439 j++;
01440 }
01441 }
01442 }
01443
01444 for (i=0; myAllEdges.size()>0&&i<myAllEdges.size()-1; i++) {
01445 j = i + 1;
01446 while (j<myAllEdges.size()) {
01447 if (myAllEdges[i]==myAllEdges[j]) {
01448 myAllEdges.erase(myAllEdges.begin()+j);
01449 } else {
01450 j++;
01451 }
01452 }
01453 }
01454 }
01455
01456
01457 bool
01458 NBNode::hasIncoming(const NBEdge * const e) const throw() {
01459 return find(myIncomingEdges->begin(), myIncomingEdges->end(), e)!=myIncomingEdges->end();
01460 }
01461
01462
01463 bool
01464 NBNode::hasOutgoing(const NBEdge * const e) const throw() {
01465 return find(myOutgoingEdges->begin(), myOutgoingEdges->end(), e)!=myOutgoingEdges->end();
01466 }
01467
01468
01469 NBEdge *
01470 NBNode::getOppositeIncoming(NBEdge *e) const {
01471 EdgeVector edges(*myIncomingEdges);
01472 if (find(edges.begin(), edges.end(), e)!=edges.end()) {
01473 edges.erase(find(edges.begin(), edges.end(), e));
01474 }
01475 if (e->getToNode()==this) {
01476 sort(edges.begin(), edges.end(), NBContHelper::edge_opposite_direction_sorter(e));
01477 } else {
01478 sort(edges.begin(), edges.end(), NBContHelper::edge_similar_direction_sorter(e));
01479 }
01480 return edges[0];
01481 }
01482
01483
01484 void
01485 NBNode::addSortedLinkFoes(const NBConnection &mayDrive,
01486 const NBConnection &mustStop) {
01487 if (mayDrive.getFrom()==0 ||
01488 mayDrive.getTo()==0 ||
01489 mustStop.getFrom()==0 ||
01490 mustStop.getTo()==0) {
01491
01492 WRITE_WARNING("Something went wrong during the building of a connection...");
01493 return;
01494 }
01495 NBConnectionVector conn = myBlockedConnections[mustStop];
01496 conn.push_back(mayDrive);
01497 myBlockedConnections[mustStop] = conn;
01498 }
01499
01500
01501 NBEdge *
01502 NBNode::getPossiblySplittedIncoming(const std::string &edgeid) {
01503 unsigned int size = (unsigned int) edgeid.length();
01504 for (EdgeVector::iterator i=myIncomingEdges->begin(); i!=myIncomingEdges->end(); i++) {
01505 std::string id = (*i)->getID();
01506 if (id.substr(0, size)==edgeid) {
01507 return *i;
01508 }
01509 }
01510 return 0;
01511 }
01512
01513
01514 NBEdge *
01515 NBNode::getPossiblySplittedOutgoing(const std::string &edgeid) {
01516 unsigned int size = (unsigned int) edgeid.length();
01517 for (EdgeVector::iterator i=myOutgoingEdges->begin(); i!=myOutgoingEdges->end(); i++) {
01518 std::string id = (*i)->getID();
01519 if (id.substr(0, size)==edgeid) {
01520 return *i;
01521 }
01522 }
01523 return 0;
01524 }
01525
01526
01527 unsigned int
01528 NBNode::eraseDummies(NBDistrictCont &dc, NBEdgeCont &ec, NBTrafficLightLogicCont &tc) {
01529 unsigned int ret = 0;
01530 if (myOutgoingEdges==0||myIncomingEdges==0) {
01531 return ret;
01532 }
01533 unsigned int pos = 0;
01534 EdgeVector::const_iterator j=myIncomingEdges->begin();
01535 while (j!=myIncomingEdges->end()) {
01536
01537 if (find(myOutgoingEdges->begin(), myOutgoingEdges->end(), *j)==myOutgoingEdges->end()) {
01538 j++;
01539 pos++;
01540 continue;
01541 }
01542
01543
01544 NBEdge *dummy = *j;
01545 WRITE_WARNING(" Removing dummy edge '" + dummy->getID() + "'");
01546
01547 EdgeVector incomingConnected;
01548 EdgeVector::const_iterator i;
01549 for (i=myIncomingEdges->begin(); i!=myIncomingEdges->end(); i++) {
01550 if ((*i)->isConnectedTo(dummy)&&*i!=dummy) {
01551 incomingConnected.push_back(*i);
01552 }
01553 }
01554
01555 EdgeVector outgoingConnected;
01556 for (i=myOutgoingEdges->begin(); i!=myOutgoingEdges->end(); i++) {
01557 if (dummy->isConnectedTo(*i)&&*i!=dummy) {
01558 outgoingConnected.push_back(*i);
01559 }
01560 }
01561
01562 dummy->remapConnections(incomingConnected);
01563 remapRemoved(tc, dummy, incomingConnected, outgoingConnected);
01564
01565 ec.erase(dc, dummy);
01566 j = myIncomingEdges->begin() + pos;
01567 ret++;
01568 }
01569 return ret;
01570 }
01571
01572
01573 void
01574 NBNode::removeOutgoing(NBEdge *edge) {
01575 EdgeVector::iterator i = find(myOutgoingEdges->begin(), myOutgoingEdges->end(), edge);
01576 if (i!=myOutgoingEdges->end()) {
01577 myOutgoingEdges->erase(i);
01578 i = find(myAllEdges.begin(), myAllEdges.end(), edge);
01579 myAllEdges.erase(i);
01580 for (i=myAllEdges.begin(); i!=myAllEdges.end(); ++i) {
01581 (*i)->removeFromConnections(edge);
01582 }
01583 }
01584 }
01585
01586
01587 void
01588 NBNode::removeIncoming(NBEdge *edge) {
01589 EdgeVector::iterator i = find(myIncomingEdges->begin(), myIncomingEdges->end(), edge);
01590 if (i!=myIncomingEdges->end()) {
01591 myIncomingEdges->erase(i);
01592 i = find(myAllEdges.begin(), myAllEdges.end(), edge);
01593 myAllEdges.erase(i);
01594 for (i=myAllEdges.begin(); i!=myAllEdges.end(); ++i) {
01595 (*i)->removeFromConnections(edge);
01596 }
01597 }
01598 }
01599
01600
01601
01602
01603 Position2D
01604 NBNode::getEmptyDir() const {
01605 Position2D pos(0, 0);
01606 EdgeVector::const_iterator i;
01607 for (i=myIncomingEdges->begin(); i!=myIncomingEdges->end(); i++) {
01608 NBNode *conn = (*i)->getFromNode();
01609 Position2D toAdd = conn->getPosition();
01610 toAdd.sub(myPosition);
01611 toAdd.mul((SUMOReal) 1.0/sqrt(toAdd.x()*toAdd.x()+toAdd.y()*toAdd.y()));
01612 pos.add(toAdd);
01613 }
01614 for (i=myOutgoingEdges->begin(); i!=myOutgoingEdges->end(); i++) {
01615 NBNode *conn = (*i)->getToNode();
01616 Position2D toAdd = conn->getPosition();
01617 toAdd.sub(myPosition);
01618 toAdd.mul((SUMOReal) 1.0/sqrt(toAdd.x()*toAdd.x()+toAdd.y()*toAdd.y()));
01619 pos.add(toAdd);
01620 }
01621 pos.mul((SUMOReal) -1.0/(myIncomingEdges->size()+myOutgoingEdges->size()));
01622 if (pos.x()==0&&pos.y()==0) {
01623 pos = Position2D(1, 0);
01624 }
01625 pos.norm();
01626 return pos;
01627 }
01628
01629
01630
01631 void
01632 NBNode::invalidateIncomingConnections() {
01633 for (EdgeVector::const_iterator i=myIncomingEdges->begin(); i!=myIncomingEdges->end(); i++) {
01634 (*i)->invalidateConnections();
01635 }
01636 }
01637
01638
01639 void
01640 NBNode::invalidateOutgoingConnections() {
01641 for (EdgeVector::const_iterator i=myOutgoingEdges->begin(); i!=myOutgoingEdges->end(); i++) {
01642 (*i)->invalidateConnections();
01643 }
01644 }
01645
01646
01647 bool
01648 NBNode::mustBrake(const NBEdge * const from, const NBEdge * const to, int toLane) const throw() {
01649
01650
01651
01652
01653 if (myTrafficLights.size()!=0) {
01654
01655
01656 return true;
01657 }
01658
01659 if (myRequest==0) {
01660 return false;
01661 }
01662
01663 if (to==0) {
01664 return true;
01665 }
01666
01667 bool try1 = myRequest->mustBrake(from, to);
01668 if (!try1||toLane==-1) {
01669 return try1;
01670 }
01671 if (from->getSpeed()<70./3.6) {
01672 return try1;
01673 }
01674
01675
01676 for (EdgeVector::const_iterator i=myIncomingEdges->begin(); i!=myIncomingEdges->end(); i++) {
01677 if ((*i)==from) {
01678 continue;
01679 }
01680 const std::vector<NBEdge::Connection> &connections = (*i)->getConnections();
01681 for (std::vector<NBEdge::Connection>::const_iterator j=connections.begin(); j!=connections.end(); ++j) {
01682 if ((*j).toEdge==to&&((*j).toLane<0||(*j).toLane==toLane)) {
01683 return true;
01684 }
01685 }
01686 }
01687 return false;
01688 }
01689
01690
01691
01692 bool
01693 NBNode::isLeftMover(const NBEdge * const from, const NBEdge * const to) const throw() {
01694
01695
01696 if (myIncomingEdges->size()==1) {
01697 return false;
01698 }
01699 SUMOReal ccw = GeomHelper::getCCWAngleDiff(from->getAngle(*this), to->getAngle(*this));
01700 SUMOReal cw = GeomHelper::getCWAngleDiff(from->getAngle(*this), to->getAngle(*this));
01701 return cw<ccw;
01702 }
01703
01704
01705 bool
01706 NBNode::forbids(const NBEdge * const possProhibitorFrom, const NBEdge * const possProhibitorTo,
01707 const NBEdge * const possProhibitedFrom, const NBEdge * const possProhibitedTo,
01708 bool regardNonSignalisedLowerPriority) const throw() {
01709 return myRequest!=0&&myRequest->forbids(possProhibitorFrom, possProhibitorTo,
01710 possProhibitedFrom, possProhibitedTo,
01711 regardNonSignalisedLowerPriority);
01712 }
01713
01714
01715 bool
01716 NBNode::foes(const NBEdge * const from1, const NBEdge * const to1,
01717 const NBEdge * const from2, const NBEdge * const to2) const throw() {
01718 return myRequest!=0&&myRequest->foes(from1, to1, from2, to2);
01719 }
01720
01721
01722 void
01723 NBNode::remapRemoved(NBTrafficLightLogicCont &tc,
01724 NBEdge *removed, const EdgeVector &incoming,
01725 const EdgeVector &outgoing) {
01726 assert(find(incoming.begin(), incoming.end(), removed)==incoming.end());
01727 bool changed = true;
01728 while (changed) {
01729 changed = false;
01730 NBConnectionProhibits blockedConnectionsTmp = myBlockedConnections;
01731 NBConnectionProhibits blockedConnectionsNew;
01732
01733 for (NBConnectionProhibits::iterator i=blockedConnectionsTmp.begin(); i!=blockedConnectionsTmp.end(); i++) {
01734 const NBConnection &blocker = (*i).first;
01735 const NBConnectionVector &blocked = (*i).second;
01736
01737
01738 bool blockedChanged = false;
01739 NBConnectionVector newBlocked;
01740 NBConnectionVector::const_iterator j;
01741 for (j=blocked.begin(); j!=blocked.end(); j++) {
01742 const NBConnection &sblocked = *j;
01743 if (sblocked.getFrom()==removed||sblocked.getTo()==removed) {
01744 blockedChanged = true;
01745 }
01746 }
01747
01748 for (j=blocked.begin(); blockedChanged&&j!=blocked.end(); j++) {
01749 const NBConnection &sblocked = *j;
01750 if (sblocked.getFrom()==removed&&sblocked.getTo()==removed) {
01751
01752
01753
01754 } else if (sblocked.getFrom()==removed) {
01755 assert(sblocked.getTo()!=removed);
01756 for (EdgeVector::const_iterator k=incoming.begin(); k!=incoming.end(); k++) {
01757 newBlocked.push_back(NBConnection(*k, sblocked.getTo()));
01758 }
01759 } else if (sblocked.getTo()==removed) {
01760 assert(sblocked.getFrom()!=removed);
01761 for (EdgeVector::const_iterator k=outgoing.begin(); k!=outgoing.end(); k++) {
01762 newBlocked.push_back(NBConnection(sblocked.getFrom(), *k));
01763 }
01764 } else {
01765 newBlocked.push_back(NBConnection(sblocked.getFrom(), sblocked.getTo()));
01766 }
01767 }
01768 if (blockedChanged) {
01769 blockedConnectionsNew[blocker] = newBlocked;
01770 changed = true;
01771 }
01772
01773 else {
01774 if (blocker.getFrom()==removed&&blocker.getTo()==removed) {
01775 changed = true;
01776
01777
01778
01779 } else if (blocker.getFrom()==removed) {
01780 assert(blocker.getTo()!=removed);
01781 changed = true;
01782 for (EdgeVector::const_iterator k=incoming.begin(); k!=incoming.end(); k++) {
01783 blockedConnectionsNew[NBConnection(*k, blocker.getTo())] = blocked;
01784 }
01785 } else if (blocker.getTo()==removed) {
01786 assert(blocker.getFrom()!=removed);
01787 changed = true;
01788 for (EdgeVector::const_iterator k=outgoing.begin(); k!=outgoing.end(); k++) {
01789 blockedConnectionsNew[NBConnection(blocker.getFrom(), *k)] = blocked;
01790 }
01791 } else {
01792 blockedConnectionsNew[blocker] = blocked;
01793 }
01794 }
01795 }
01796 myBlockedConnections = blockedConnectionsNew;
01797 }
01798
01799 tc.remapRemoved(removed, incoming, outgoing);
01800 }
01801
01802
01803 NBMMLDirection
01804 NBNode::getMMLDirection(const NBEdge * const incoming, const NBEdge * const outgoing) const throw() {
01805
01806 if (outgoing==0) {
01807 return MMLDIR_NODIR;
01808 }
01809
01810 if (incoming->isTurningDirectionAt(this, outgoing)) {
01811 return MMLDIR_TURN;
01812 }
01813
01814 SUMOReal angle =
01815 NBHelpers::normRelAngle(incoming->getAngle(*this), outgoing->getAngle(*this));
01816
01817 if (abs((int) angle)+1<45) {
01818 return MMLDIR_STRAIGHT;
01819 }
01820
01821
01822 if (angle>0) {
01823
01824 EdgeVector::const_iterator i =
01825 find(myAllEdges.begin(), myAllEdges.end(), outgoing);
01826 NBContHelper::nextCW(&myAllEdges, i);
01827 while ((*i)!=incoming) {
01828 if ((*i)->getFromNode()==this) {
01829 return MMLDIR_PARTRIGHT;
01830 }
01831 NBContHelper::nextCW(&myAllEdges, i);
01832 }
01833 return MMLDIR_RIGHT;
01834 }
01835
01836 EdgeVector::const_iterator i =
01837 find(myAllEdges.begin(), myAllEdges.end(), outgoing);
01838 NBContHelper::nextCCW(&myAllEdges, i);
01839 while ((*i)!=incoming) {
01840 if ((*i)->getFromNode()==this&&!incoming->isTurningDirectionAt(this, *i)) {
01841 return MMLDIR_PARTLEFT;
01842 }
01843 NBContHelper::nextCCW(&myAllEdges, i);
01844 }
01845 return MMLDIR_LEFT;
01846 }
01847
01848
01849 char
01850 NBNode::stateCode(NBEdge *incoming, NBEdge *outgoing, int fromlane, bool mayDefinitelyPass) const throw() {
01851 if (outgoing==0) {
01852 return 'O';
01853 }
01854 if (myType==NODETYPE_RIGHT_BEFORE_LEFT) {
01855 return '=';
01856 }
01857 if ((!incoming->isInnerEdge()&&mustBrake(incoming, outgoing, fromlane)) && !mayDefinitelyPass) {
01858 return 'm';
01859 }
01860
01861 return 'M';
01862 }
01863
01864
01865 bool
01866 NBNode::checkIsRemovable() const {
01867
01868 if (myTrafficLights.size()!=0) {
01869 return false;
01870 }
01871 EdgeVector::const_iterator i;
01872
01873 if (myOutgoingEdges->size()==1&&myIncomingEdges->size()==1) {
01874
01875 if (!(*myIncomingEdges)[0]->expandableBy((*myOutgoingEdges)[0])) {
01876 return false;
01877 }
01878
01879 return (*myIncomingEdges)[0]->getFromNode()!=(*myOutgoingEdges)[0]->getToNode();
01880 }
01881
01882 if (myOutgoingEdges->size()==2&&myIncomingEdges->size()==2) {
01883
01884 std::set<NBNode*> origSet;
01885 for (i=myIncomingEdges->begin(); i!=myIncomingEdges->end(); i++) {
01886 origSet.insert((*i)->getFromNode());
01887 }
01888 if (origSet.size()<2) {
01889 return false;
01890 }
01891
01892
01893 for (i=myIncomingEdges->begin(); i!=myIncomingEdges->end(); i++) {
01894
01895 NBNode *origin = (*i)->getFromNode();
01896
01897 EdgeVector::const_iterator j =
01898 find_if(myOutgoingEdges->begin(), myOutgoingEdges->end(),
01899 NBContHelper::edge_with_destination_finder(origin));
01900
01901 if (j!=myOutgoingEdges->end()) {
01902
01903
01904 NBContHelper::nextCCW(myOutgoingEdges, j);
01905
01906 if (!(*i)->expandableBy(*j)) {
01907 return false;
01908 }
01909 } else {
01910
01911
01912 return false;
01913 }
01914 }
01915 return true;
01916 }
01917
01918 return false;
01919 }
01920
01921
01922 std::vector<std::pair<NBEdge*, NBEdge*> >
01923 NBNode::getEdgesToJoin() const {
01924 assert(checkIsRemovable());
01925 std::vector<std::pair<NBEdge*, NBEdge*> > ret;
01926
01927 if (myOutgoingEdges->size()==1&&myIncomingEdges->size()==1) {
01928 ret.push_back(
01929 std::pair<NBEdge*, NBEdge*>(
01930 (*myIncomingEdges)[0], (*myOutgoingEdges)[0]));
01931 return ret;
01932 }
01933
01934 for (EdgeVector::const_iterator i=myIncomingEdges->begin(); i!=myIncomingEdges->end(); i++) {
01935 NBNode *origin = (*i)->getFromNode();
01936 EdgeVector::const_iterator j =
01937 find_if(myOutgoingEdges->begin(), myOutgoingEdges->end(),
01938 NBContHelper::edge_with_destination_finder(origin));
01939 NBContHelper::nextCCW(myOutgoingEdges, j);
01940 ret.push_back(std::pair<NBEdge*, NBEdge*>(*i, *j));
01941 }
01942 return ret;
01943 }
01944
01945
01946 const Position2DVector &
01947 NBNode::getShape() const {
01948 return myPoly;
01949 }
01950
01951 std::string
01952 NBNode::getInternalLaneID(NBEdge *from, unsigned int fromlane,
01953 NBEdge *to, unsigned int tolane) const {
01954 unsigned int l = 0;
01955 for (EdgeVector::const_iterator i=myIncomingEdges->begin(); i!=myIncomingEdges->end(); i++) {
01956 unsigned int noLanesEdge = (*i)->getNoLanes();
01957 for (unsigned int j=0; j<noLanesEdge; j++) {
01958 std::vector<NBEdge::Connection> elv = (*i)->getConnectionsFromLane(j);
01959 for (std::vector<NBEdge::Connection>::iterator k=elv.begin(); k!=elv.end(); ++k) {
01960 if ((*k).toEdge==0) {
01961 continue;
01962 }
01963 if ((from==*i)&&(j==fromlane)&&((*k).toEdge==to)&&((*k).toLane==tolane)) {
01964 return ":" + myID + "_" + toString(l);
01965 }
01966 l++;
01967 }
01968 }
01969 }
01970 throw 1;
01971 }
01972
01973
01974 SUMOReal
01975 NBNode::getMaxEdgeWidth() const {
01976 EdgeVector::const_iterator i=myAllEdges.begin();
01977 assert(i!=myAllEdges.end());
01978 SUMOReal ret = (*i)->width();
01979 ++i;
01980 for (; i!=myAllEdges.end(); i++) {
01981 ret = ret > (*i)->width()
01982 ? ret
01983 : (*i)->width();
01984 }
01985 return ret;
01986 }
01987
01988
01989 NBEdge *
01990 NBNode::getConnectionTo(NBNode *n) const {
01991 std::vector<NBEdge*>::iterator i;
01992 for (i=myOutgoingEdges->begin(); i!=myOutgoingEdges->end(); i++) {
01993 if ((*i)->getToNode()==n) {
01994 return (*i);
01995 }
01996 }
01997 return 0;
01998 }
01999
02000
02001 bool
02002 NBNode::isNearDistrict() const {
02003 if (isDistrict()) {
02004 return false;
02005 }
02006 EdgeVector edges;
02007 copy(getIncomingEdges().begin(), getIncomingEdges().end(),
02008 back_inserter(edges));
02009 copy(getOutgoingEdges().begin(), getOutgoingEdges().end(),
02010 back_inserter(edges));
02011 for (EdgeVector::const_iterator j=edges.begin(); j!=edges.end(); ++j) {
02012 NBEdge *t = *j;
02013 NBNode *other = 0;
02014 if (t->getToNode()==this) {
02015 other = t->getFromNode();
02016 } else {
02017 other = t->getToNode();
02018 }
02019 EdgeVector edges2;
02020 copy(other->getIncomingEdges().begin(), other->getIncomingEdges().end(), back_inserter(edges2));
02021 copy(other->getOutgoingEdges().begin(), other->getOutgoingEdges().end(), back_inserter(edges2));
02022 for (EdgeVector::const_iterator k=edges2.begin(); k!=edges2.end(); ++k) {
02023 if ((*k)->getFromNode()->isDistrict()||(*k)->getToNode()->isDistrict()) {
02024 return true;
02025 }
02026 }
02027 }
02028 return false;
02029 }
02030
02031
02032 bool
02033 NBNode::isDistrict() const {
02034 return myType==NODETYPE_DISTRICT;
02035 }
02036
02037
02038
02039
02040