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 <vector>
00031 #include <string>
00032 #include <algorithm>
00033 #include <cassert>
00034 #include "NBEdgeCont.h"
00035 #include "NBNode.h"
00036 #include "NBNodeCont.h"
00037 #include "NBContHelper.h"
00038 #include "NBHelpers.h"
00039 #include <cmath>
00040 #include <iomanip>
00041 #include "NBTypeCont.h"
00042 #include <utils/geom/GeomHelper.h>
00043 #include <utils/common/MsgHandler.h>
00044 #include <utils/common/StringUtils.h>
00045 #include <utils/common/ToString.h>
00046 #include <utils/common/UtilExceptions.h>
00047 #include <utils/common/StdDefs.h>
00048 #include "NBEdge.h"
00049 #include <utils/options/OptionsCont.h>
00050 #include <utils/iodevices/OutputDevice.h>
00051
00052 #ifdef CHECK_MEMORY_LEAKS
00053 #include <foreign/nvwa/debug_new.h>
00054 #endif // CHECK_MEMORY_LEAKS
00055
00056
00057
00058
00059
00060
00061
00062
00063 void
00064 NBEdge::ToEdgeConnectionsAdder::execute(SUMOReal lane, SUMOReal virtEdge) throw() {
00065
00066 assert(virtEdge>=0);
00067 assert((unsigned int) myTransitions.size()>(unsigned int) virtEdge);
00068 assert(lane>=0&&lane<10);
00069
00070 NBEdge *succEdge = myTransitions[(int) virtEdge];
00071 std::vector<unsigned int> lanes;
00072
00073
00074
00075 std::map<NBEdge*, std::vector<unsigned int> >::iterator i=myConnections.find(succEdge);
00076 if (i!=myConnections.end()) {
00077
00078 lanes = (*i).second;
00079 }
00080
00081
00082
00083 std::vector<unsigned int>::iterator j=find(lanes.begin(), lanes.end(), (unsigned int) lane);
00084 if (j==lanes.end()) {
00085
00086 lanes.push_back((unsigned int) lane);
00087 }
00088
00089 myConnections[succEdge] = lanes;
00090 }
00091
00092
00093
00094
00095
00096
00097 NBEdge::MainDirections::MainDirections(const std::vector<NBEdge*> &outgoing,
00098 NBEdge *parent, NBNode *to) {
00099 if (outgoing.size()==0) {
00100 return;
00101 }
00102
00103 assert(outgoing.size()>0);
00104 if (outgoing[0]->getJunctionPriority(to)==1) {
00105 myDirs.push_back(MainDirections::DIR_RIGHTMOST);
00106 }
00107
00108 if (outgoing.back()->getJunctionPriority(to)==1) {
00109
00110
00111
00112 std::vector<NBEdge*> tmp(outgoing);
00113 sort(tmp.begin(), tmp.end(), NBContHelper::edge_similar_direction_sorter(parent));
00114 if (outgoing.back()->getPriority()>tmp[0]->getPriority()) {
00115 myDirs.push_back(MainDirections::DIR_LEFTMOST);
00116 } else {
00117 if (outgoing.back()->getNoLanes()>tmp[0]->getNoLanes()) {
00118 myDirs.push_back(MainDirections::DIR_LEFTMOST);
00119 }
00120 }
00121 }
00122
00123
00124 std::vector<NBEdge*> tmp(outgoing);
00125 sort(tmp.begin(), tmp.end(), NBContHelper::edge_similar_direction_sorter(parent));
00126 NBEdge *edge = *(tmp.begin());
00127
00128 if (edge->getJunctionPriority(to)==1 && to->getMMLDirection(parent, edge)==MMLDIR_STRAIGHT) {
00129 myDirs.push_back(MainDirections::DIR_FORWARD);
00130 }
00131 }
00132
00133
00134 NBEdge::MainDirections::~MainDirections() {}
00135
00136
00137 bool
00138 NBEdge::MainDirections::empty() const {
00139 return myDirs.empty();
00140 }
00141
00142
00143 bool
00144 NBEdge::MainDirections::includes(Direction d) const {
00145 return find(myDirs.begin(), myDirs.end(), d)!=myDirs.end();
00146 }
00147
00148
00149
00150
00151
00152
00153 NBEdge::NBEdge(const std::string &id, NBNode *from, NBNode *to,
00154 std::string type, SUMOReal speed, unsigned int nolanes,
00155 int priority, LaneSpreadFunction spread) throw(ProcessError) :
00156 myStep(INIT), myID(StringUtils::convertUmlaute(id)),
00157 myType(StringUtils::convertUmlaute(type)),
00158 myFrom(from), myTo(to), myAngle(0),
00159 myPriority(priority), mySpeed(speed),
00160 myTurnDestination(0),
00161 myFromJunctionPriority(-1), myToJunctionPriority(-1),
00162 myLaneSpreadFunction(spread),
00163 myLoadedLength(-1), myAmLeftHand(false), myAmTurningWithAngle(0), myAmTurningOf(0),
00164 myAmInnerEdge(false), myAmMacroscopicConnector(false) {
00165 init(nolanes, false);
00166 }
00167
00168
00169 NBEdge::NBEdge(const std::string &id, NBNode *from, NBNode *to,
00170 std::string type, SUMOReal speed, unsigned int nolanes,
00171 int priority, Position2DVector geom,
00172 LaneSpreadFunction spread, bool tryIgnoreNodePositions) throw(ProcessError) :
00173 myStep(INIT), myID(StringUtils::convertUmlaute(id)),
00174 myType(StringUtils::convertUmlaute(type)),
00175 myFrom(from), myTo(to), myAngle(0),
00176 myPriority(priority), mySpeed(speed),
00177 myTurnDestination(0),
00178 myFromJunctionPriority(-1), myToJunctionPriority(-1),
00179 myGeom(geom), myLaneSpreadFunction(spread),
00180 myLoadedLength(-1), myAmLeftHand(false), myAmTurningWithAngle(0), myAmTurningOf(0),
00181 myAmInnerEdge(false), myAmMacroscopicConnector(false) {
00182 init(nolanes, tryIgnoreNodePositions);
00183 }
00184
00185
00186 void
00187 NBEdge::reinit(NBNode *from, NBNode *to, std::string type,
00188 SUMOReal speed, unsigned int nolanes, int priority,
00189 Position2DVector geom, LaneSpreadFunction spread) throw(ProcessError) {
00190 if (myFrom!=from) {
00191 myFrom->removeOutgoing(this);
00192 }
00193 if (myTo!=to) {
00194 myTo->removeIncoming(this);
00195 }
00196 myType = StringUtils::convertUmlaute(type);
00197 myFrom = from;
00198 myTo = to;
00199 myPriority = priority;
00200 mySpeed = speed;
00201
00202
00203 myGeom = geom;
00204 myLaneSpreadFunction = spread;
00205 myLoadedLength = -1;
00206
00207
00208 init(nolanes, false);
00209 }
00210
00211
00212 void
00213 NBEdge::init(unsigned int noLanes, bool tryIgnoreNodePositions) throw(ProcessError) {
00214 if (noLanes==0) {
00215 throw ProcessError("Edge '" + myID + "' needs at least one lane.");
00216 }
00217 if (myFrom==0||myTo==0) {
00218 throw ProcessError("At least one of edge's '" + myID + "' nodes is not known.");
00219 }
00220
00221
00222
00223 myGeom.removeDoublePoints();
00224 if (!tryIgnoreNodePositions||myGeom.size()<2) {
00225 if (myGeom.size()==0) {
00226 myGeom.push_back(myTo->getPosition());
00227 myGeom.push_front(myFrom->getPosition());
00228 } else {
00229 Position2DVector v;
00230 v = myGeom;
00231 v.push_back_noDoublePos(myTo->getPosition());
00232 v.push_front_noDoublePos(myFrom->getPosition());
00233 if (v.size()<2) {
00234 myGeom.push_back(myTo->getPosition());
00235 myGeom.push_front(myFrom->getPosition());
00236 } else {
00237 myGeom = v;
00238 }
00239 }
00240 }
00241
00242 myAngle = NBHelpers::angle(
00243 myFrom->getPosition().x(), myFrom->getPosition().y(),
00244 myTo->getPosition().x(), myTo->getPosition().y()
00245 );
00246 myFrom->addOutgoingEdge(this);
00247 myTo->addIncomingEdge(this);
00248
00249 myLength = myFrom->getPosition().distanceTo(myTo->getPosition());
00250 assert(myGeom.size()>=2);
00251 myLanes.clear();
00252 for (unsigned int i=0; i<noLanes; i++) {
00253 Lane l;
00254 l.speed = mySpeed;
00255 myLanes.push_back(l);
00256 }
00257 computeLaneShapes();
00258 }
00259
00260
00261 NBEdge::~NBEdge() throw() {}
00262
00263
00264
00265 void
00266 NBEdge::setGeometry(const Position2DVector &s) throw() {
00267 myGeom = s;
00268 computeLaneShapes();
00269 }
00270
00271
00272 void
00273 NBEdge::computeEdgeShape() throw() {
00274 unsigned int i;
00275 for (i=0; i<myLanes.size(); i++) {
00276 Position2DVector &shape = myLanes[i].shape;
00277
00278 Line2D lb = Line2D(shape[0], shape[1]);
00279 Line2D le = Line2D(shape[-1], shape[-2]);
00280 lb.extrapolateBy(100.0);
00281 le.extrapolateBy(100.0);
00282
00283 Position2DVector old = shape;
00284 Position2D nb, ne;
00285
00286 if (myFrom->getShape().intersects(shape)) {
00287
00288 DoubleVector pbv = shape.intersectsAtLengths(myFrom->getShape());
00289 if (pbv.size()>0) {
00290 SUMOReal pb = VectorHelper<SUMOReal>::maxValue(pbv);
00291 if (pb>=0&&pb<=shape.length()) {
00292 shape = shape.getSubpart(pb, shape.length());
00293 }
00294 }
00295 } else if (myFrom->getShape().intersects(lb.p1(), lb.p2())) {
00296 DoubleVector pbv = lb.intersectsAtLengths(myFrom->getShape());
00297 if (pbv.size()>0) {
00298 SUMOReal pb = VectorHelper<SUMOReal>::maxValue(pbv);
00299 if (pb>=0) {
00300 shape.eraseAt(0);
00301 shape.push_front(lb.getPositionAtDistance(pb));
00302 }
00303 }
00304 }
00305
00306 if (myTo->getShape().intersects(shape)) {
00307
00308 DoubleVector pev = shape.intersectsAtLengths(myTo->getShape());
00309 if (pev.size()>0) {
00310 SUMOReal pe = VectorHelper<SUMOReal>::minValue(pev);
00311 if (pe>=0&&pe<=shape.length()) {
00312 shape = shape.getSubpart(0, pe);
00313 }
00314 }
00315 } else if (myTo->getShape().intersects(le.p1(), le.p2())) {
00316 DoubleVector pev = le.intersectsAtLengths(myTo->getShape());
00317 if (pev.size()>0) {
00318 SUMOReal pe = VectorHelper<SUMOReal>::maxValue(pev);
00319 if (pe>=0) {
00320 shape.eraseAt((int) shape.size()-1);
00321 shape.push_back(le.getPositionAtDistance(pe));
00322 }
00323 }
00324 }
00325 if (((int) shape.length())==0) {
00326 shape = old;
00327 } else {
00328 Line2D lc(shape[0], shape[-1]);
00329 Line2D lo(old[0], old[-1]);
00330 if (135<GeomHelper::getMinAngleDiff(lc.atan2DegreeAngle(), lo.atan2DegreeAngle())) {
00331 shape = shape.reverse();
00332 }
00333 }
00334 }
00335
00336 SUMOReal length = 0;
00337 for (i=0; i<myLanes.size(); i++) {
00338 assert(myLanes[i].shape.length()>0);
00339 length += myLanes[i].shape.length();
00340 }
00341 myLength = length / (SUMOReal) myLanes.size();
00342 }
00343
00344
00345 const Position2DVector &
00346 NBEdge::getLaneShape(unsigned int i) const throw() {
00347 return myLanes[i].shape;
00348 }
00349
00350
00351 void
00352 NBEdge::setLaneSpreadFunction(LaneSpreadFunction spread) throw() {
00353 myLaneSpreadFunction = spread;
00354 }
00355
00356
00357 void
00358 NBEdge::addGeometryPoint(int index, const Position2D &p) throw() {
00359 myGeom.insertAt(index, p);
00360 }
00361
00362
00363 void
00364 NBEdge::reshiftPosition(SUMOReal xoff, SUMOReal yoff) throw() {
00365 myGeom.reshiftRotate(xoff, yoff, 0);
00366 for (unsigned int i=0; i<myLanes.size(); i++) {
00367 myLanes[i].shape.reshiftRotate(xoff, yoff, 0);
00368 }
00369 }
00370
00371
00372
00373 bool
00374 NBEdge::addEdge2EdgeConnection(NBEdge *dest) throw() {
00375 if (myStep==INIT_REJECT_CONNECTIONS) {
00376 return true;
00377 }
00378
00379
00380
00381 if (dest!=0 && myTo!=dest->myFrom) {
00382 return false;
00383 }
00384 if (find_if(myConnections.begin(), myConnections.end(), connections_toedge_finder(dest))==myConnections.end()) {
00385 myConnections.push_back(Connection(-1, dest, -1));
00386 }
00387 if (myStep<EDGE2EDGES) {
00388 myStep = EDGE2EDGES;
00389 }
00390 return true;
00391 }
00392
00393
00394 bool
00395 NBEdge::addLane2LaneConnection(unsigned int from, NBEdge *dest,
00396 unsigned int toLane, Lane2LaneInfoType type,
00397 bool mayUseSameDestination,
00398 bool mayDefinitelyPass) throw() {
00399 if (myStep==INIT_REJECT_CONNECTIONS) {
00400 return true;
00401 }
00402
00403
00404
00405 if (myTo!=dest->myFrom) {
00406 return false;
00407 }
00408 if (!addEdge2EdgeConnection(dest)) {
00409 return false;
00410 }
00411 setConnection(from, dest, toLane, type, mayUseSameDestination, mayDefinitelyPass);
00412 return true;
00413 }
00414
00415
00416 bool
00417 NBEdge::addLane2LaneConnections(unsigned int fromLane,
00418 NBEdge *dest, unsigned int toLane,
00419 unsigned int no, Lane2LaneInfoType type,
00420 bool invalidatePrevious,
00421 bool mayDefinitelyPass) throw() {
00422 if (invalidatePrevious) {
00423 invalidateConnections(true);
00424 }
00425 bool ok = true;
00426 for (unsigned int i=0; i<no&&ok; i++) {
00427 ok &= addLane2LaneConnection(fromLane+i, dest, toLane+i, type, false, mayDefinitelyPass);
00428 }
00429 return ok;
00430 }
00431
00432
00433 void
00434 NBEdge::setConnection(unsigned int lane, NBEdge *destEdge,
00435 unsigned int destLane, Lane2LaneInfoType type,
00436 bool mayUseSameDestination,
00437 bool mayDefinitelyPass) throw() {
00438 if (myStep==INIT_REJECT_CONNECTIONS) {
00439 return;
00440 }
00441 assert(destLane<=10);
00442 assert(lane<=10);
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452 if (!mayUseSameDestination && hasConnectionTo(destEdge, destLane)) {
00453 return;
00454 }
00455 if (find_if(myConnections.begin(), myConnections.end(), connections_finder(lane, destEdge, destLane))!=myConnections.end()) {
00456 return;
00457 }
00458 if (myLanes.size()<=lane) {
00459 MsgHandler::getErrorInstance()->inform("Could not set connection from '" + myID + "_" + toString(lane) + "' to '" + destEdge->getID() + "_" + toString(destLane) + "'.");
00460 return;
00461 }
00462 for (std::vector<Connection>::iterator i=myConnections.begin(); i!=myConnections.end();) {
00463 if ((*i).toEdge==destEdge && ((*i).fromLane==-1 || (*i).toLane==-1)) {
00464 i = myConnections.erase(i);
00465 } else {
00466 ++i;
00467 }
00468 }
00469 myConnections.push_back(Connection(lane, destEdge, destLane));
00470 if (mayDefinitelyPass) {
00471 myConnections.back().mayDefinitelyPass = true;
00472 }
00473 if (type==L2L_USER) {
00474 myStep = LANES2LANES_USER;
00475 } else {
00476
00477 if (type==L2L_COMPUTED) {
00478
00479 myStep = LANES2LANES_RECHECK;
00480 } else {
00481
00482 if (myStep!=LANES2LANES_RECHECK) {
00483 myStep = LANES2LANES_DONE;
00484 }
00485 }
00486 }
00487 }
00488
00489
00490 std::vector<NBEdge::Connection>
00491 NBEdge::getConnectionsFromLane(unsigned int lane) const throw() {
00492 std::vector<NBEdge::Connection> ret;
00493 for (std::vector<Connection>::const_iterator i=myConnections.begin(); i!=myConnections.end(); ++i) {
00494 if ((*i).fromLane==lane) {
00495 ret.push_back(*i);
00496 }
00497 }
00498 return ret;
00499 }
00500
00501
00502 bool
00503 NBEdge::hasConnectionTo(NBEdge *destEdge, unsigned int destLane) const throw() {
00504 return destEdge!=0&&find_if(myConnections.begin(), myConnections.end(), connections_toedgelane_finder(destEdge, destLane))!=myConnections.end();
00505 }
00506
00507
00508
00509 int
00510 NBEdge::getJunctionPriority(const NBNode * const node) const {
00511 if (node==myFrom) {
00512 return myFromJunctionPriority;
00513 } else {
00514 return myToJunctionPriority;
00515 }
00516 }
00517
00518
00519 void
00520 NBEdge::setJunctionPriority(const NBNode * const node, int prio) {
00521 if (node==myFrom) {
00522 myFromJunctionPriority = prio;
00523 } else {
00524 myToJunctionPriority = prio;
00525 }
00526 }
00527
00528
00529 void
00530 NBEdge::computeTurningDirections() {
00531 myTurnDestination = 0;
00532 EdgeVector outgoing = myTo->getOutgoingEdges();
00533 for (EdgeVector::iterator i=outgoing.begin(); i!=outgoing.end(); i++) {
00534 NBEdge *outedge = *i;
00535 if (myConnections.size()!=0&&!isConnectedTo(outedge)) {
00536 continue;
00537 }
00538 SUMOReal relAngle =
00539 NBHelpers::relAngle(getAngle(*myTo), outedge->getAngle(*myTo));
00540
00541 if (fabs(relAngle)>160) {
00542 setTurningDestination(outedge);
00543 }
00544 }
00545 }
00546
00547
00548 SUMOReal
00549 NBEdge::getAngle(const NBNode &atNode) const {
00550 if (&atNode==myFrom) {
00551 return myGeom.getBegLine().atan2DegreeAngle();
00552 } else {
00553 assert(&atNode==myTo);
00554 return myGeom.getEndLine().atan2DegreeAngle();
00555 }
00556 }
00557
00558
00559 void
00560 NBEdge::setTurningDestination(NBEdge *e) {
00561 SUMOReal cur = fabs(NBHelpers::relAngle(getAngle(), e->getAngle()));
00562 SUMOReal old =
00563 myTurnDestination==0
00564 ? 0
00565 : fabs(NBHelpers::relAngle(getAngle(), myTurnDestination->getAngle()));
00566 if (cur>old
00567 &&
00568 e->acceptBeingTurning(this)) {
00569
00570 myTurnDestination = e;
00571 }
00572 }
00573
00574
00575 bool
00576 NBEdge::acceptBeingTurning(NBEdge *e) {
00577 if (e==myAmTurningOf) {
00578 return true;
00579 }
00580 SUMOReal angle = fabs(NBHelpers::relAngle(getAngle(), e->getAngle()));
00581 if (myAmTurningWithAngle>angle) {
00582 return false;
00583 }
00584 if (myAmTurningWithAngle==angle) {
00585 return false;
00586 }
00587 NBEdge *previous = myAmTurningOf;
00588 myAmTurningWithAngle = angle;
00589 myAmTurningOf = e;
00590 if (previous!=0) {
00591 previous->computeTurningDirections();
00592 }
00593 return true;
00594 }
00595
00596
00597 void
00598 NBEdge::writeXMLStep1(OutputDevice &into) {
00599
00600 into << " <edge id=\"" << myID <<
00601 "\" from=\"" << myFrom->getID() <<
00602 "\" to=\"" << myTo->getID() <<
00603 "\" priority=\"" << myPriority <<
00604 "\" type=\"" << myType;
00605 if (isMacroscopicConnector()) {
00606 into << "\" function=\"connector";
00607 } else {
00608 into << "\" function=\"normal";
00609 }
00610 if (myAmInnerEdge) {
00611 into << "\" inner=\"x";
00612 }
00613 into << "\">\n";
00614
00615 into << " <lanes>\n";
00616 for (unsigned int i=0; i<(unsigned int) myLanes.size(); i++) {
00617 writeLane(into, myLanes[i], i);
00618 }
00619 into << " </lanes>\n";
00620
00621 const std::vector<NBEdge*> *tmp = getConnectedSorted();
00622 std::vector<NBEdge*> sortedConnected = *tmp;
00623 if (getTurnDestination()!=0) {
00624 sortedConnected.push_back(getTurnDestination());
00625 }
00626 delete tmp;
00627 for (std::vector<NBEdge*>::iterator l=sortedConnected.begin(); l!=sortedConnected.end(); l++) {
00628 LaneVector lanes;
00629 for (std::vector<Connection>::const_iterator i=myConnections.begin(); i!=myConnections.end(); ++i) {
00630 if ((*i).toEdge==*l && find(lanes.begin(), lanes.end(), (*i).fromLane)==lanes.end()) {
00631 lanes.push_back((*i).fromLane);
00632 }
00633 }
00634 }
00635
00636 into << " </edge>\n\n";
00637 }
00638
00639
00640 void
00641 NBEdge::writeXMLStep2(OutputDevice &into, bool includeInternal) {
00642 for (unsigned int i=0; i<myLanes.size(); i++) {
00643 writeSucceeding(into, i, includeInternal);
00644 }
00645 }
00646
00647
00648 void
00649 NBEdge::writeLane(OutputDevice &into, NBEdge::Lane &lane, unsigned int index) const {
00650
00651 into << " <lane id=\"" << myID << '_' << index << "\"";
00652
00653 if (index==0) {
00654 into << " depart=\"1\"";
00655 } else {
00656 into << " depart=\"0\"";
00657 }
00658
00659 std::vector<SUMOVehicleClass>::const_iterator i;
00660 bool hadOne = false;
00661 if (lane.allowed.size() > 0) {
00662 into << " allow=\"";
00663 for (i=lane.allowed.begin(); i!=lane.allowed.end(); ++i) {
00664 if (hadOne) {
00665 into << ' ';
00666 }
00667 into << getVehicleClassName(*i);
00668 hadOne = true;
00669 }
00670 into << '\"';
00671 }
00672 if (lane.notAllowed.size() > 0) {
00673 hadOne = false;
00674 into << " disallow=\"";
00675 for (i=lane.notAllowed.begin(); i!=lane.notAllowed.end(); ++i) {
00676 if (hadOne) {
00677 into << ' ';
00678 }
00679 into << getVehicleClassName(*i);
00680 hadOne = true;
00681 }
00682 into << '\"';
00683 }
00684 if (lane.preferred.size() > 0) {
00685 hadOne = false;
00686 into << "\" prefer=\"";
00687 for (i=lane.preferred.begin(); i!=lane.preferred.end(); ++i) {
00688 if (hadOne) {
00689 into << ' ';
00690 }
00691 into << getVehicleClassName(*i);
00692 hadOne = true;
00693 }
00694 into << '\"';
00695 }
00696
00697 if (lane.speed==0) {
00698 WRITE_WARNING("Lane #" + toString(index) + " of edge '" + myID + "' has a maximum velocity of 0.");
00699 } else if (lane.speed<0) {
00700 throw ProcessError("Negative velocity (" + toString(lane.speed) + " on edge '" + myID + "' lane#" + toString(index) + ".");
00701
00702 }
00703 SUMOReal length = myLength;
00704 if (myLoadedLength>0) {
00705 length = myLoadedLength;
00706 }
00707 if (length<=0) {
00708 length = (SUMOReal) .1;
00709 }
00710 into << " maxspeed=\"" << lane.speed << "\" length=\"" << length << "\"";
00711 into << " shape=\"" << lane.shape << "\"/>\n";
00712 }
00713
00714
00715 void
00716 NBEdge::setLaneSpeed(unsigned int lane, SUMOReal speed) {
00717 myLanes[lane].speed = speed;
00718 }
00719
00720
00721 SUMOReal
00722 NBEdge::getLaneSpeed(unsigned int lane) const {
00723 return myLanes[lane].speed;
00724 }
00725
00726
00727 void
00728 NBEdge::computeLaneShapes() throw() {
00729
00730 if (myFrom==myTo) {
00731 return;
00732 }
00733
00734 for (unsigned int i=0; i<myLanes.size(); i++) {
00735 try {
00736 myLanes[i].shape = computeLaneShape(i);
00737 } catch (InvalidArgument &e) {
00738 MsgHandler::getWarningInstance()->inform("In edge '" + getID() + "': lane shape could not been determined (" + e.what() + ")");
00739 myLanes[i].shape = myGeom;
00740 }
00741 }
00742 }
00743
00744
00745 Position2DVector
00746 NBEdge::computeLaneShape(unsigned int lane) throw(InvalidArgument) {
00747 Position2DVector shape;
00748 bool haveWarned = false;
00749 for (int i=0; i<(int) myGeom.size(); i++) {
00750 if (i==0) {
00751 Position2D from = myGeom[i];
00752 Position2D to = myGeom[i+1];
00753 std::pair<SUMOReal, SUMOReal> offsets = laneOffset(from, to, SUMO_const_laneWidthAndOffset, (unsigned int)(myLanes.size()-1-lane));
00754 shape.push_back(
00755
00756 Position2D(from.x()-offsets.first, from.y()-offsets.second));
00757 } else if (i==myGeom.size()-1) {
00758 Position2D from = myGeom[i-1];
00759 Position2D to = myGeom[i];
00760 std::pair<SUMOReal, SUMOReal> offsets = laneOffset(from, to, SUMO_const_laneWidthAndOffset, (unsigned int)(myLanes.size()-1-lane));
00761 shape.push_back(
00762
00763 Position2D(to.x()-offsets.first, to.y()-offsets.second));
00764 } else {
00765 Position2D from = myGeom[i-1];
00766 Position2D me = myGeom[i];
00767 Position2D to = myGeom[i+1];
00768 std::pair<SUMOReal, SUMOReal> offsets = laneOffset(from, me, SUMO_const_laneWidthAndOffset, (unsigned int)(myLanes.size()-1-lane));
00769 std::pair<SUMOReal, SUMOReal> offsets2 = laneOffset(me, to, SUMO_const_laneWidthAndOffset, (unsigned int)(myLanes.size()-1-lane));
00770 Line2D l1(
00771 Position2D(from.x()-offsets.first, from.y()-offsets.second),
00772 Position2D(me.x()-offsets.first, me.y()-offsets.second));
00773 l1.extrapolateBy(100);
00774 Line2D l2(
00775 Position2D(me.x()-offsets2.first, me.y()-offsets2.second),
00776 Position2D(to.x()-offsets2.first, to.y()-offsets2.second));
00777 SUMOReal angle = GeomHelper::getCWAngleDiff(l1.atan2DegreeAngle(), l2.atan2DegreeAngle());
00778 if (angle<10.||angle>350.) {
00779 shape.push_back(
00780
00781 Position2D(me.x()-offsets.first, me.y()-offsets.second));
00782 continue;
00783 }
00784 l2.extrapolateBy(100);
00785 if (l1.intersects(l2)) {
00786 shape.push_back(l1.intersectsAt(l2));
00787 } else {
00788 if (!haveWarned) {
00789 MsgHandler::getWarningInstance()->inform("In lane '" + getID() + "_" + toString(lane) + "': Could not build shape.");
00790 haveWarned = true;
00791 }
00792 }
00793 }
00794 }
00795 return shape;
00796 }
00797
00798
00799 std::pair<SUMOReal, SUMOReal>
00800 NBEdge::laneOffset(const Position2D &from, const Position2D &to,
00801 SUMOReal lanewidth, unsigned int lane) throw(InvalidArgument) {
00802 std::pair<SUMOReal, SUMOReal> offsets =
00803 GeomHelper::getNormal90D_CW(from, to, lanewidth);
00804 SUMOReal xoff = offsets.first / (SUMOReal) 2.0;
00805 SUMOReal yoff = offsets.second / (SUMOReal) 2.0;
00806 if (myLaneSpreadFunction==LANESPREAD_RIGHT) {
00807 xoff += (offsets.first * (SUMOReal) lane);
00808 yoff += (offsets.second * (SUMOReal) lane);
00809 } else {
00810 xoff += (offsets.first * (SUMOReal) lane) - (offsets.first * (SUMOReal) myLanes.size() / (SUMOReal) 2.0);
00811 yoff += (offsets.second * (SUMOReal) lane) - (offsets.second * (SUMOReal) myLanes.size() / (SUMOReal) 2.0);
00812 }
00813 if (myAmLeftHand) {
00814 return std::pair<SUMOReal, SUMOReal>(-xoff, -yoff);
00815 } else {
00816 return std::pair<SUMOReal, SUMOReal>(xoff, yoff);
00817 }
00818 }
00819
00820
00821 void
00822 NBEdge::writeSucceeding(OutputDevice &into, unsigned int lane, bool includeInternal) {
00823 into << " <succ edge=\"" << myID << "\" lane=\"" << myID << "_" << lane << "\" junction=\"" << myTo->getID() << "\">\n";
00824
00825 unsigned int count = 0;
00826 for (std::vector<Connection>::const_iterator i=myConnections.begin(); i!=myConnections.end(); ++i) {
00827 if ((*i).fromLane==lane) {
00828 writeSingleSucceeding(into, *i, includeInternal);
00829 ++count;
00830 }
00831 }
00832
00833 if (count==0) {
00834 into << " <succlane lane=\"SUMO_NO_DESTINATION\" yield=\"1\"/>\n";
00835 }
00836 into << " </succ>\n\n";
00837 }
00838
00839
00840 void
00841 NBEdge::writeSingleSucceeding(OutputDevice &into, const NBEdge::Connection &c, bool includeInternal) {
00842
00843
00844 if (c.toEdge==0) {
00845 into << " <succlane lane=\"SUMO_NO_DESTINATION\"";
00846 if (c.tlID!="") {
00847 into << " tl=\"" << c.tlID << "\"";
00848 into << " linkno=\"" << c.tlLinkNo << "\"";
00849 }
00850 into << " yield=\"1\" " << "dir=\"s\" state=\"O\"/>\n";
00851 return;
00852 }
00853
00854 into << " <succlane lane=\"" << c.toEdge->getID() << '_' << c.toLane << '\"';
00855 if (includeInternal) {
00856 into << " via=\"" << myTo->getInternalLaneID(this, c.fromLane, c.toEdge, c.toLane) << "_0\"";
00857 }
00858
00859 if (c.tlID!="") {
00860 into << " tl=\"" << c.tlID << "\"";
00861 into << " linkno=\"" << c.tlLinkNo << "\"";
00862 }
00863
00864 if ((myAmInnerEdge||!myTo->mustBrake(this, c.toEdge, c.toLane)) || c.mayDefinitelyPass) {
00865 into << " yield=\"0\"";
00866 } else {
00867 into << " yield=\"1\"";
00868 }
00869
00870 NBMMLDirection dir = myTo->getMMLDirection(this, c.toEdge);
00871 into << " dir=\"";
00872 switch (dir) {
00873 case MMLDIR_STRAIGHT:
00874 into << "s";
00875 break;
00876 case MMLDIR_LEFT:
00877 into << "l";
00878 break;
00879 case MMLDIR_RIGHT:
00880 into << "r";
00881 break;
00882 case MMLDIR_TURN:
00883 into << "t";
00884 break;
00885 case MMLDIR_PARTLEFT:
00886 into << "L";
00887 break;
00888 case MMLDIR_PARTRIGHT:
00889 into << "R";
00890 break;
00891 default:
00892
00893 assert(false);
00894 break;
00895 }
00896 into << "\" ";
00897
00898 if (c.tlID!="") {
00899 into << "state=\"t";
00900 } else {
00901 into << "state=\"" << myTo->stateCode(this, c.toEdge, c.toLane, c.mayDefinitelyPass);
00902 }
00903 if (myTo->getCrossingPosition(this, c.fromLane, c.toEdge, c.toLane).first>=0) {
00904 into << "\" int_end=\"x";
00905 }
00906
00907
00908 into << "\"/>\n";
00909 }
00910
00911
00912 bool
00913 NBEdge::hasRestrictions() const {
00914 for (std::vector<Lane>::const_iterator i=myLanes.begin(); i!=myLanes.end(); ++i) {
00915 if ((*i).allowed.size()!=0 || (*i).notAllowed.size()!=0) {
00916 return true;
00917 }
00918 }
00919 return false;
00920 }
00921
00922
00923 void
00924 NBEdge::writeLanesPlain(OutputDevice &into) {
00925 for (unsigned int i=0; i<myLanes.size(); ++i) {
00926 into << " <lane id=\"" << i << "\"";
00927 const Lane &lane = myLanes[i];
00928
00929 if (lane.allowed.size()!=0) {
00930 bool hadOne = false;
00931 into << " allow=\"";
00932 std::vector<SUMOVehicleClass>::const_iterator i;
00933 for (i=lane.allowed.begin(); i!=lane.allowed.end(); ++i) {
00934 if (hadOne) {
00935 into << ' ';
00936 }
00937 into << getVehicleClassName(*i);
00938 hadOne = true;
00939 }
00940 into << "\"";
00941 }
00942 if (lane.notAllowed.size()!=0) {
00943 bool hadOne = false;
00944 into << " disallow=\"";
00945 std::vector<SUMOVehicleClass>::const_iterator i;
00946 for (i=lane.notAllowed.begin(); i!=lane.notAllowed.end(); ++i) {
00947 if (hadOne) {
00948 into << ' ';
00949 }
00950 into << getVehicleClassName(*i);
00951 hadOne = true;
00952 }
00953 into << "\"";
00954 }
00955 into << "/>\n";
00956 }
00957 }
00958
00959
00960 bool
00961 NBEdge::computeEdge2Edges() {
00962
00963
00964 if (myStep>=EDGE2EDGES) {
00965 return true;
00966 }
00967 if (myConnections.size()==0) {
00968 const EdgeVector &o = myTo->getOutgoingEdges();
00969 for (EdgeVector::const_iterator i=o.begin(); i!=o.end(); ++i) {
00970 myConnections.push_back(Connection(-1, *i, -1));
00971 }
00972 }
00973 myStep = EDGE2EDGES;
00974 return true;
00975 }
00976
00977
00978 bool
00979 NBEdge::computeLanes2Edges() {
00980
00981
00982 if (myStep>=LANES2EDGES) {
00983 return true;
00984 }
00985 assert(myStep==EDGE2EDGES);
00986
00987
00988 const std::vector<NBEdge*> *edges = getConnectedSorted();
00989 if (myConnections.size()!=0&&edges->size()==0) {
00990
00991 myConnections.clear();
00992 } else {
00993
00994 divideOnEdges(edges);
00995 }
00996 delete edges;
00997 myStep = LANES2EDGES;
00998 return true;
00999 }
01000
01001
01002 bool
01003 NBEdge::recheckLanes() {
01004 std::vector<unsigned int> connNumbersPerLane(myLanes.size(), 0);
01005 for (std::vector<Connection>::iterator i=myConnections.begin(); i!=myConnections.end();) {
01006 if ((*i).toEdge==0||(*i).fromLane<0||(*i).toLane<0) {
01007 i = myConnections.erase(i);
01008 } else {
01009 if ((*i).fromLane>=0) {
01010 ++connNumbersPerLane[(*i).fromLane];
01011 }
01012 ++i;
01013 }
01014 }
01015 if (myStep!=LANES2LANES_DONE&&myStep!=LANES2LANES_USER) {
01016
01017
01018
01019
01020
01021 for (unsigned int i=0; i<myLanes.size(); i++) {
01022 if (connNumbersPerLane[i]==0) {
01023 if (i>0&&connNumbersPerLane[i-1]>1) {
01024 moveConnectionToLeft(i-1);
01025 } else if (i<myLanes.size()-1&&connNumbersPerLane[i+1]>1) {
01026 moveConnectionToRight(i+1);
01027 }
01028 }
01029 }
01030 }
01031
01032
01033
01034
01035
01036
01037 for (unsigned int i=0; i<myLanes.size(); i++) {
01038 connNumbersPerLane[i] = 0;
01039 }
01040 for (std::vector<Connection>::iterator i=myConnections.begin(); i!=myConnections.end();) {
01041 if ((*i).toEdge==0||(*i).fromLane<0||(*i).toLane<0) {
01042 i = myConnections.erase(i);
01043 } else {
01044 if ((*i).fromLane>=0) {
01045 ++connNumbersPerLane[(*i).fromLane];
01046 }
01047 ++i;
01048 }
01049 }
01050 for (unsigned int i=0; i<myLanes.size(); i++) {
01051 if (connNumbersPerLane[i]==0) {
01052 setConnection(i, 0, 0, L2L_VALIDATED, false);
01053 }
01054 }
01055 return true;
01056 }
01057
01058
01059 void
01060 NBEdge::moveConnectionToLeft(unsigned int lane) {
01061 unsigned int index = 0;
01062 if (myAmLeftHand) {
01063 for (int i=(int) myConnections.size()-1; i>=0; --i) {
01064 if (myConnections[i].fromLane==lane&&getTurnDestination()!=myConnections[i].toEdge) {
01065 index = i;
01066 }
01067 }
01068 } else {
01069 for (unsigned int i=0; i<myConnections.size(); ++i) {
01070 if (myConnections[i].fromLane==lane) {
01071 index = i;
01072 }
01073 }
01074 }
01075 std::vector<Connection>::iterator i = myConnections.begin() + index;
01076 Connection c = *i;
01077 myConnections.erase(i);
01078 setConnection(lane+1, c.toEdge, c.toLane, L2L_VALIDATED, false);
01079 }
01080
01081
01082 void
01083 NBEdge::moveConnectionToRight(unsigned int lane) {
01084 if (myAmLeftHand) {
01085 for (int i=(int) myConnections.size()-1; i>=0; --i) {
01086 if (myConnections[i].fromLane==lane&&getTurnDestination()!=myConnections[i].toEdge) {
01087 Connection c = myConnections[i];
01088 myConnections.erase(myConnections.begin() + i);
01089 setConnection(lane-1, c.toEdge, c.toLane, L2L_VALIDATED, false);
01090 return;
01091 }
01092 }
01093 } else {
01094 for (std::vector<Connection>::iterator i=myConnections.begin(); i!=myConnections.end(); ++i) {
01095 if ((*i).fromLane==lane) {
01096 Connection c = *i;
01097 i = myConnections.erase(i);
01098 setConnection(lane-1, c.toEdge, c.toLane, L2L_VALIDATED, false);
01099 return;
01100 }
01101 }
01102 }
01103 }
01104
01105
01106 std::vector<int>
01107 NBEdge::getConnectionLanes(NBEdge *currentOutgoing) const {
01108 std::vector<int> ret;
01109 if (currentOutgoing!=myTurnDestination) {
01110 for (std::vector<Connection>::const_iterator i=myConnections.begin(); i!=myConnections.end(); ++i) {
01111 if ((*i).toEdge==currentOutgoing) {
01112 ret.push_back((*i).fromLane);
01113 }
01114 }
01115 }
01116 return ret;
01117 }
01118
01119
01120 const std::vector<NBEdge*> *
01121 NBEdge::getConnectedSorted() {
01122
01123 EdgeVector outgoing;
01124 if (myConnections.size()==0) {
01125 outgoing = myTo->getOutgoingEdges();
01126 } else {
01127 for (std::vector<Connection>::const_iterator i=myConnections.begin(); i!=myConnections.end(); ++i) {
01128 if (find(outgoing.begin(), outgoing.end(), (*i).toEdge)==outgoing.end()) {
01129 outgoing.push_back((*i).toEdge);
01130 }
01131 }
01132 }
01133
01134 unsigned int size = (unsigned int) outgoing.size();
01135 std::vector<NBEdge*> *edges = new std::vector<NBEdge*>();
01136 edges->reserve(size);
01137 for (EdgeVector::const_iterator i=outgoing.begin(); i!=outgoing.end(); i++) {
01138 NBEdge *outedge = *i;
01139 if (outedge!=0&&outedge!=myTurnDestination) {
01140 edges->push_back(outedge);
01141 }
01142 }
01143 sort(edges->begin(), edges->end(), NBContHelper::relative_edge_sorter(this, myTo));
01144 return edges;
01145 }
01146
01147
01148 void
01149 NBEdge::divideOnEdges(const std::vector<NBEdge*> *outgoing) {
01150 if (outgoing->size()==0) {
01151
01152 myConnections.clear();
01153 return;
01154 }
01155
01156
01157 std::vector<unsigned int> *priorities = preparePriorities(outgoing);
01158
01159
01160 unsigned int prioSum = computePrioritySum(priorities);
01161
01162
01163 unsigned int size = (unsigned int) outgoing->size();
01164 std::vector<SUMOReal> resultingLanes;
01165 resultingLanes.reserve(size);
01166 SUMOReal sumResulting = 0;
01167 SUMOReal minResulting = 10000;
01168 unsigned int i;
01169 for (i=0; i<size; i++) {
01170
01171
01172 SUMOReal res =
01173 (SUMOReal)(*priorities)[i] *
01174 (SUMOReal) myLanes.size() / (SUMOReal) prioSum;
01175
01176 if (res>myLanes.size()) {
01177 res = (SUMOReal) myLanes.size();
01178 }
01179
01180 resultingLanes.push_back(res);
01181 sumResulting += res;
01182 if (minResulting>res) {
01183 minResulting = res;
01184 }
01185 }
01186
01187
01188
01189
01190 sumResulting += minResulting / (SUMOReal) 2.;
01191 unsigned int noVirtual = (unsigned int)(sumResulting / minResulting);
01192
01193 std::vector<NBEdge*> transition;
01194 transition.reserve(size);
01195 for (i=0; i<size; i++) {
01196
01197
01198 assert(i<resultingLanes.size());
01199 SUMOReal tmpNo = (SUMOReal) resultingLanes[i] / (SUMOReal) minResulting;
01200 for (SUMOReal j=0; j<tmpNo; j++) {
01201 assert(outgoing->size()>i);
01202 transition.push_back((*outgoing)[i]);
01203 }
01204 }
01205
01206
01207
01208 ToEdgeConnectionsAdder adder(transition);
01209 Bresenham::compute(&adder, (SUMOReal) myLanes.size(), (SUMOReal) noVirtual);
01210 const std::map<NBEdge*, std::vector<unsigned int> > &l2eConns = adder.getBuiltConnections();
01211 myConnections.clear();
01212 for (std::map<NBEdge*, std::vector<unsigned int> >::const_iterator i=l2eConns.begin(); i!=l2eConns.end(); ++i) {
01213 const std::vector<unsigned int> lanes = (*i).second;
01214 for (std::vector<unsigned int>::const_iterator j=lanes.begin(); j!=lanes.end(); ++j) {
01215 if (myAmLeftHand) {
01216 myConnections.push_back(Connection(myLanes.size() - 1 - *j, (*i).first, -1));
01217 } else {
01218 myConnections.push_back(Connection(*j, (*i).first, -1));
01219 }
01220 }
01221 }
01222 delete priorities;
01223 }
01224
01225
01226 std::vector<unsigned int> *
01227 NBEdge::preparePriorities(const std::vector<NBEdge*> *outgoing) {
01228
01229 std::vector<unsigned int> *priorities = new std::vector<unsigned int>();
01230 if (outgoing->size()==0) {
01231 return priorities;
01232 }
01233 priorities->reserve(outgoing->size());
01234 std::vector<NBEdge*>::const_iterator i;
01235 for (i=outgoing->begin(); i!=outgoing->end(); i++) {
01236 int prio = (*i)->getJunctionPriority(myTo);
01237 assert((prio+1)*2>0);
01238 prio = (prio+1) * 2;
01239 priorities->push_back(prio);
01240 }
01241
01242
01243
01244 MainDirections mainDirections(*outgoing, this, myTo);
01245 std::vector<NBEdge*> tmp(*outgoing);
01246 sort(tmp.begin(), tmp.end(), NBContHelper::edge_similar_direction_sorter(this));
01247 i=find(outgoing->begin(), outgoing->end(), *(tmp.begin()));
01248 unsigned int dist = (unsigned int) distance(outgoing->begin(), i);
01249 if (dist!=0&&!mainDirections.includes(MainDirections::DIR_RIGHTMOST)) {
01250 assert(priorities->size()>0);
01251 (*priorities)[0] = (*priorities)[0] / 2;
01252 }
01253
01254
01255
01256 if (mainDirections.empty()) {
01257 assert(dist<priorities->size());
01258 (*priorities)[dist] = (*priorities)[dist] * 2;
01259 }
01260 if (mainDirections.includes(MainDirections::DIR_FORWARD)&&myLanes.size()>2) {
01261 (*priorities)[dist] = (*priorities)[dist] * 2;
01262 }
01263
01264 return priorities;
01265 }
01266
01267
01268 unsigned int
01269 NBEdge::computePrioritySum(std::vector<unsigned int> *priorities) {
01270 unsigned int sum = 0;
01271 for (std::vector<unsigned int>::iterator i=priorities->begin(); i!=priorities->end(); i++) {
01272 sum += (*i);
01273 }
01274 return sum;
01275 }
01276
01277
01278 void
01279 NBEdge::appendTurnaround(bool noTLSControlled) throw() {
01280
01281 if (myTurnDestination==0) {
01282 return;
01283 }
01284
01285
01286 if (noTLSControlled&&myTo->isTLControlled()) {
01287 return;
01288 }
01289 setConnection((unsigned int)(myLanes.size()-1), myTurnDestination, myTurnDestination->getNoLanes()-1, L2L_VALIDATED);
01290 }
01291
01292
01293 void
01294 NBEdge::sortOutgoingLanesConnections() {
01295 sort(myConnections.begin(), myConnections.end(), connections_relative_edgelane_sorter(this, myTo));
01296 }
01297
01298
01299 bool
01300 NBEdge::isTurningDirectionAt(const NBNode *n, const NBEdge * const edge) const throw() {
01301
01302 if (edge == myTurnDestination) {
01303 return true;
01304 } else if (myTurnDestination!=0) {
01305
01306 return false;
01307 }
01308
01309 if (myFrom==edge->myTo &&myTo==edge->myFrom) {
01310 return true;
01311 }
01312
01313
01314 SUMOReal thisFromAngle2 = getAngle(*n);
01315 SUMOReal otherToAngle2 = edge->getAngle(*n);
01316 if (thisFromAngle2<otherToAngle2) {
01317 std::swap(thisFromAngle2, otherToAngle2);
01318 }
01319 if (thisFromAngle2-otherToAngle2>170&&thisFromAngle2-otherToAngle2<190) {
01320 return true;
01321 }
01322 return false;
01323 }
01324
01325
01326
01327 NBNode *
01328 NBEdge::tryGetNodeAtPosition(SUMOReal pos, SUMOReal tolerance) const {
01329
01330 if (pos<tolerance) {
01331 return myFrom;
01332 }
01333
01334 if (pos>myLength-tolerance) {
01335 return myTo;
01336 }
01337 return 0;
01338 }
01339
01340
01341 void
01342 NBEdge::replaceInConnections(NBEdge *which, NBEdge *by, unsigned int laneOff) {
01343
01344 for (std::vector<Connection>::iterator i=myConnections.begin(); i!=myConnections.end(); ++i) {
01345 if ((*i).toEdge==which) {
01346 (*i).toEdge = by;
01347 }
01348 }
01349
01350 if (myTurnDestination==which) {
01351 myTurnDestination = by;
01352 }
01353 }
01354
01355
01356 void
01357 NBEdge::moveOutgoingConnectionsFrom(NBEdge *e, unsigned int laneOff) {
01358 unsigned int lanes = e->getNoLanes();
01359 for (unsigned int i=0; i<lanes; i++) {
01360 std::vector<NBEdge::Connection> elv = e->getConnectionsFromLane(i);
01361 for (std::vector<NBEdge::Connection>::iterator j=elv.begin(); j!=elv.end(); j++) {
01362 NBEdge::Connection el = *j;
01363 assert(el.tlID=="");
01364 bool ok = addLane2LaneConnection(i+laneOff, el.toEdge, el.toLane, L2L_COMPUTED);
01365 assert(ok);
01366 }
01367 }
01368 }
01369
01370
01371 bool
01372 NBEdge::isConnectedTo(NBEdge *e) {
01373 if (e==myTurnDestination) {
01374 return true;
01375 }
01376 return
01377 find_if(myConnections.begin(), myConnections.end(), connections_toedge_finder(e))
01378 !=
01379 myConnections.end();
01380
01381 }
01382
01383
01384 std::vector<NBEdge*>
01385 NBEdge::getConnectedEdges() const throw() {
01386 std::vector<NBEdge*> ret;
01387 for (std::vector<Connection>::const_iterator i=myConnections.begin(); i!=myConnections.end(); ++i) {
01388 if (find(ret.begin(), ret.end(), (*i).toEdge)==ret.end()) {
01389 ret.push_back((*i).toEdge);
01390 }
01391 }
01392 return ret;
01393 }
01394
01395
01396 void
01397 NBEdge::remapConnections(const EdgeVector &incoming) {
01398 std::vector<NBEdge*> connected = getConnectedEdges();
01399 for (EdgeVector::const_iterator i=incoming.begin(); i!=incoming.end(); i++) {
01400 NBEdge *inc = *i;
01401
01402 inc->myStep = EDGE2EDGES;
01403
01404 for (EdgeVector::iterator j=connected.begin(); j!=connected.end(); j++) {
01405 inc->addEdge2EdgeConnection(*j);
01406 }
01407 inc->removeFromConnections(this);
01408 }
01409 }
01410
01411
01412 void
01413 NBEdge::removeFromConnections(NBEdge *which, int lane) {
01414
01415 for (std::vector<Connection>::iterator i=myConnections.begin(); i!=myConnections.end();) {
01416 Connection &c = *i;
01417 if (c.toEdge==which && (lane<0 || c.fromLane==lane)) {
01418 i = myConnections.erase(i);
01419 } else {
01420 ++i;
01421 }
01422 }
01423
01424 if (myTurnDestination==which&&lane<0) {
01425 myTurnDestination = 0;
01426 }
01427 }
01428
01429
01430 void
01431 NBEdge::invalidateConnections(bool reallowSetting) {
01432 myTurnDestination = 0;
01433 myConnections.clear();
01434 if (reallowSetting) {
01435 myStep = INIT;
01436 } else {
01437 myStep = INIT_REJECT_CONNECTIONS;
01438 }
01439 }
01440
01441
01442 bool
01443 NBEdge::lanesWereAssigned() const {
01444 return myStep==LANES2LANES_DONE||myStep==LANES2LANES_USER;
01445 }
01446
01447
01448 SUMOReal
01449 NBEdge::getMaxLaneOffset() {
01450 return (SUMOReal) SUMO_const_laneWidthAndOffset * myLanes.size();
01451 }
01452
01453
01454 Position2D
01455 NBEdge::getMinLaneOffsetPositionAt(NBNode *node, SUMOReal width) const {
01456 const Position2DVector &shape0 = myLanes[0].shape;
01457 const Position2DVector &shapel = myLanes.back().shape;
01458 width = width < shape0.length()/(SUMOReal) 2.0
01459 ? width
01460 : shape0.length()/(SUMOReal) 2.0;
01461 if (node==myFrom) {
01462 Position2D pos = shapel.positionAtLengthPosition(width);
01463 GeomHelper::transfer_to_side(pos, shapel[0], shapel[-1], SUMO_const_halfLaneAndOffset);
01464 return pos;
01465 } else {
01466 Position2D pos = shape0.positionAtLengthPosition(shape0.length() - width);
01467 GeomHelper::transfer_to_side(pos, shape0[-1], shape0[0], SUMO_const_halfLaneAndOffset);
01468 return pos;
01469 }
01470 }
01471
01472
01473 Position2D
01474 NBEdge::getMaxLaneOffsetPositionAt(NBNode *node, SUMOReal width) const {
01475 const Position2DVector &shape0 = myLanes[0].shape;
01476 const Position2DVector &shapel = myLanes.back().shape;
01477 width = width < shape0.length()/(SUMOReal) 2.0
01478 ? width
01479 : shape0.length()/(SUMOReal) 2.0;
01480 if (node==myFrom) {
01481 Position2D pos = shape0.positionAtLengthPosition(width);
01482 GeomHelper::transfer_to_side(pos, shape0[0], shape0[-1], -SUMO_const_halfLaneAndOffset);
01483 return pos;
01484 } else {
01485 Position2D pos = shapel.positionAtLengthPosition(shapel.length() - width);
01486 GeomHelper::transfer_to_side(pos, shapel[-1], shapel[0], -SUMO_const_halfLaneAndOffset);
01487 return pos;
01488 }
01489 }
01490
01491
01492 bool
01493 NBEdge::mayBeTLSControlled(int fromLane, NBEdge *toEdge, int toLane) const throw() {
01494 TLSDisabledConnection tpl;
01495 tpl.fromLane = fromLane;
01496 tpl.to = toEdge;
01497 tpl.toLane = toLane;
01498 std::vector<TLSDisabledConnection>::const_iterator i = find_if(myTLSDisabledConnections.begin(), myTLSDisabledConnections.end(), tls_disable_finder(tpl));
01499 return i==myTLSDisabledConnections.end();
01500 }
01501
01502
01503 bool
01504 NBEdge::setControllingTLInformation(int fromLane, NBEdge *toEdge, int toLane,
01505 const std::string &tlID, unsigned int tlPos) {
01506
01507 TLSDisabledConnection tpl;
01508 tpl.fromLane = fromLane;
01509 tpl.to = toEdge;
01510 tpl.toLane = toLane;
01511 std::vector<TLSDisabledConnection>::iterator i = find_if(myTLSDisabledConnections.begin(), myTLSDisabledConnections.end(), tls_disable_finder(tpl));
01512 if (i!=myTLSDisabledConnections.end()) {
01513 return false;
01514 }
01515
01516 assert(fromLane<0||fromLane<(int) myLanes.size());
01517
01518 if (fromLane>=0&&toLane>=0) {
01519
01520 std::vector<Connection>::iterator i =
01521 find_if(myConnections.begin(), myConnections.end(), connections_finder(fromLane, toEdge, toLane));
01522
01523
01524 if (i!=myConnections.end()) {
01525
01526 Connection &connection = *i;
01527
01528 connection.tlID = tlID;
01529 connection.tlLinkNo = tlPos;
01530 return true;
01531 }
01532 }
01533
01534
01535 unsigned int no = 0;
01536 bool hadError = false;
01537 for (std::vector<Connection>::iterator i=myConnections.begin(); i!=myConnections.end(); ++i) {
01538 if ((*i).toEdge!=toEdge) {
01539 continue;
01540 }
01541 if (fromLane>=0&&fromLane!=(*i).fromLane) {
01542 continue;
01543 }
01544 if (toLane>=0&&toLane!=(*i).toLane) {
01545 continue;
01546 }
01547 if ((*i).tlID=="") {
01548 (*i).tlID = tlID;
01549 (*i).tlLinkNo = tlPos;
01550 no++;
01551 } else {
01552 if ((*i).tlID!=tlID&&(*i).tlLinkNo==tlPos) {
01553 WRITE_WARNING("The lane " + toString<int>((*i).fromLane)+ " on edge " + getID()+ " already had a traffic light signal.");
01554 hadError = true;
01555 }
01556 }
01557 }
01558 if (hadError&&no==0) {
01559 WRITE_WARNING("Could not set any signal of the traffic light '" + tlID + "' (unknown group)");
01560 }
01561 return true;
01562 }
01563
01564
01565 void
01566 NBEdge::disableConnection4TLS(int fromLane, NBEdge *toEdge, int toLane) {
01567 TLSDisabledConnection c;
01568 c.fromLane = fromLane;
01569 c.to = toEdge;
01570 c.toLane = toLane;
01571 myTLSDisabledConnections.push_back(c);
01572 }
01573
01574
01575 Position2DVector
01576 NBEdge::getCWBoundaryLine(const NBNode &n, SUMOReal offset) const {
01577 Position2DVector ret;
01578 if (myFrom==(&n)) {
01579
01580 ret = !myAmLeftHand ? myLanes[0].shape : myLanes.back().shape;
01581 } else {
01582
01583 ret = !myAmLeftHand ? myLanes.back().shape.reverse() : myLanes[0].shape.reverse();
01584 }
01585 ret.move2side(offset);
01586 return ret;
01587 }
01588
01589
01590 Position2DVector
01591 NBEdge::getCCWBoundaryLine(const NBNode &n, SUMOReal offset) const {
01592 Position2DVector ret;
01593 if (myFrom==(&n)) {
01594
01595 ret = !myAmLeftHand ? myLanes.back().shape : myLanes[0].shape;
01596 } else {
01597
01598 ret = !myAmLeftHand ? myLanes[0].shape.reverse() : myLanes.back().shape.reverse();
01599 }
01600 ret.move2side(-offset);
01601 return ret;
01602 }
01603
01604
01605 SUMOReal
01606 NBEdge::width() const {
01607 return (SUMOReal) myLanes.size() * SUMO_const_laneWidth + (SUMOReal)(myLanes.size()-1) * SUMO_const_laneOffset;
01608 }
01609
01610
01611 bool
01612 NBEdge::expandableBy(NBEdge *possContinuation) const {
01613
01614 if (myLanes.size()!=possContinuation->myLanes.size()) {
01615 return false;
01616 }
01617
01618 if (getPriority()!=possContinuation->getPriority()) {
01619 return false;
01620 }
01621
01622 if (mySpeed!=possContinuation->mySpeed) {
01623 return false;
01624 }
01625
01633
01634
01635
01636 switch (myStep) {
01637 case INIT_REJECT_CONNECTIONS:
01638 break;
01639 case INIT:
01640 break;
01641 case EDGE2EDGES: {
01642
01643 const EdgeVector &conn = getConnectedEdges();
01644 if (find(conn.begin(), conn.end(), possContinuation)
01645 ==conn.end()) {
01646
01647 return false;
01648 }
01649 }
01650 break;
01651 case LANES2EDGES:
01652 case LANES2LANES_RECHECK:
01653 case LANES2LANES_DONE:
01654 case LANES2LANES_USER: {
01655
01656 if (find_if(myConnections.begin(), myConnections.end(), connections_toedge_finder(possContinuation))==myConnections.end()) {
01657 return false;
01658 }
01659
01660 std::vector<int> conns = getConnectionLanes(possContinuation);
01661 if (conns.size()!=myLanes.size()) {
01662 return false;
01663 }
01664 }
01665 break;
01666 default:
01667 break;
01668 }
01669 return true;
01670 }
01671
01672
01673 void
01674 NBEdge::append(NBEdge *e) {
01675
01676 myGeom.appendWithCrossingPoint(e->myGeom);
01677 for (unsigned int i=0; i<myLanes.size(); i++) {
01678 myLanes[i].shape.appendWithCrossingPoint(e->myLanes[i].shape);
01679 }
01680
01681 myLength += e->myLength;
01682
01683 myStep = e->myStep;
01684 myConnections = e->myConnections;
01685 myTurnDestination = e->myTurnDestination;
01686
01687 myTo = e->myTo;
01688 }
01689
01690
01691
01692
01693
01694 bool
01695 NBEdge::hasSignalisedConnectionTo(const NBEdge * const e) const throw() {
01696 for (std::vector<Connection>::const_iterator i=myConnections.begin(); i!=myConnections.end(); ++i) {
01697 if ((*i).toEdge==e && (*i).tlID!="") {
01698 return true;
01699 }
01700 }
01701 return false;
01702 }
01703
01704
01705 NBEdge*
01706 NBEdge::getTurnDestination() const {
01707 return myTurnDestination;
01708 }
01709
01710
01711 std::string
01712 NBEdge::getLaneID(unsigned int lane) {
01713 assert(lane<myLanes.size());
01714 return myID + "_" + toString(lane);
01715 }
01716
01717
01718 bool
01719 NBEdge::isNearEnough2BeJoined2(NBEdge *e) {
01720 DoubleVector distances = myGeom.distances(e->getGeometry());
01721 if (distances.size()==0) {
01722 distances = e->getGeometry().distancesExt(myGeom);
01723 }
01724 SUMOReal max = VectorHelper<SUMOReal>::maxValue(distances);
01725 return max<7;
01726 }
01727
01728
01729 SUMOReal
01730 NBEdge::getNormedAngle(const NBNode &atNode) const {
01731 SUMOReal angle = getAngle(atNode);
01732 if (angle<0) {
01733 angle = 360 + angle;
01734 }
01735 assert(angle>=0&&angle<360);
01736 return angle;
01737 }
01738
01739
01740 SUMOReal
01741 NBEdge::getNormedAngle() const {
01742 SUMOReal angle = myAngle;
01743 if (angle<0) {
01744 angle = 360 + angle;
01745 }
01746 assert(angle>=0&&angle<360);
01747 return angle;
01748 }
01749
01750
01751 void
01752 NBEdge::incLaneNo(unsigned int by) {
01753 unsigned int newLaneNo = (unsigned int) myLanes.size() + by;
01754 while (myLanes.size()<newLaneNo) {
01755 Lane l;
01756 l.speed = mySpeed;
01757 myLanes.push_back(l);
01758 }
01759 computeLaneShapes();
01760 const EdgeVector &incs = myFrom->getIncomingEdges();
01761 for (EdgeVector::const_iterator i=incs.begin(); i!=incs.end(); ++i) {
01762 (*i)->invalidateConnections(true);
01763 }
01764 invalidateConnections(true);
01765 }
01766
01767
01768 void
01769 NBEdge::decLaneNo(unsigned int by, int dir) {
01770 unsigned int newLaneNo = (unsigned int) myLanes.size() - by;
01771 while (myLanes.size()>newLaneNo) {
01772 myLanes.pop_back();
01773 }
01774 computeLaneShapes();
01775 const EdgeVector &incs = myFrom->getIncomingEdges();
01776 for (EdgeVector::const_iterator i=incs.begin(); i!=incs.end(); ++i) {
01777 (*i)->invalidateConnections(true);
01778 }
01779 if (dir==0) {
01780 invalidateConnections(true);
01781 } else {
01782 const EdgeVector &outs = myTo->getOutgoingEdges();
01783 assert(outs.size()==1);
01784 NBEdge *out = outs[0];
01785 if (dir<0) {
01786 removeFromConnections(out, 0);
01787 } else {
01788 removeFromConnections(out, (int) myLanes.size());
01789 }
01790 }
01791 }
01792
01793
01794 void
01795 NBEdge::copyConnectionsFrom(NBEdge *src) {
01796 myStep = src->myStep;
01797 myConnections = src->myConnections;
01798 }
01799
01800
01801 void
01802 NBEdge::markAsInLane2LaneState() {
01803 assert(myTo->getOutgoingEdges().size()==0);
01804 myStep = LANES2LANES_DONE;
01805 }
01806
01807
01808 bool
01809 NBEdge::splitGeometry(NBEdgeCont &ec, NBNodeCont &nc) {
01810
01811 if (myGeom.size()<3) {
01812 return false;
01813 }
01814
01815 NBNode *newFrom = myFrom;
01816 NBNode *myLastNode = myTo;
01817 NBNode *newTo = 0;
01818 NBEdge *currentEdge = this;
01819 for (int i=1; i<(int) myGeom.size()-1; i++) {
01820
01821 if (i!=myGeom.size()-2) {
01822 std::string nodename = myID + "_in_between#" + toString(i);
01823 if (!nc.insert(nodename, myGeom[i])) {
01824 throw ProcessError("Error on adding in-between node '" + nodename + "'.");
01825 }
01826 newTo = nc.retrieve(nodename);
01827 } else {
01828 newTo = myLastNode;
01829 }
01830 if (i==1) {
01831 currentEdge->myTo->removeIncoming(this);
01832 currentEdge->myTo = newTo;
01833 newTo->addIncomingEdge(currentEdge);
01834 } else {
01835 std::string edgename = myID + "[" + toString(i-1) + "]";
01836 currentEdge = new NBEdge(edgename, newFrom, newTo, myType, mySpeed, (unsigned int) myLanes.size(),
01837 myPriority, myLaneSpreadFunction);
01838 if (!ec.insert(currentEdge, true)) {
01839 throw ProcessError("Error on adding splitted edge '" + edgename + "'.");
01840 }
01841 }
01842 newFrom = newTo;
01843 }
01844 myGeom.clear();
01845 myGeom.push_back(myFrom->getPosition());
01846 myGeom.push_back(myTo->getPosition());
01847 myStep = INIT;
01848 return true;
01849 }
01850
01851
01852 void
01853 NBEdge::allowVehicleClass(int lane, SUMOVehicleClass vclass) {
01854 if (lane<0) {
01855
01856 for (unsigned int i=0; i<myLanes.size(); i++) {
01857
01858 allowVehicleClass((int) i, vclass);
01859 }
01860 return;
01861 }
01862 assert(lane<(int) myLanes.size());
01863
01864 if (find(myLanes[lane].allowed.begin(), myLanes[lane].allowed.end(), vclass)==myLanes[lane].allowed.end()) {
01865 myLanes[lane].allowed.push_back(vclass);
01866 }
01867 }
01868
01869
01870 void
01871 NBEdge::disallowVehicleClass(int lane, SUMOVehicleClass vclass) {
01872 if (lane<0) {
01873
01874 for (unsigned int i=0; i<myLanes.size(); i++) {
01875
01876 disallowVehicleClass((int) i, vclass);
01877 }
01878 return;
01879 }
01880 assert(lane<(int) myLanes.size());
01881
01882 if (find(myLanes[lane].notAllowed.begin(), myLanes[lane].notAllowed.end(), vclass)==myLanes[lane].notAllowed.end()) {
01883 myLanes[lane].notAllowed.push_back(vclass);
01884 }
01885 }
01886
01887
01888 void
01889 NBEdge::preferVehicleClass(int lane, SUMOVehicleClass vclass) {
01890 if (lane<0) {
01891
01892 for (unsigned int i=0; i<myLanes.size(); i++) {
01893
01894 preferVehicleClass((int) i, vclass);
01895 }
01896 return;
01897 }
01898 assert(lane<(int) myLanes.size());
01899
01900 if (find(myLanes[lane].preferred.begin(), myLanes[lane].preferred.end(), vclass)==myLanes[lane].preferred.end()) {
01901 myLanes[lane].preferred.push_back(vclass);
01902 }
01903 }
01904
01905
01906 void
01907 NBEdge::setVehicleClasses(const std::vector<SUMOVehicleClass> &allowed, const std::vector<SUMOVehicleClass> &disallowed, int lane) {
01908 for (std::vector<SUMOVehicleClass>::const_iterator i=allowed.begin(); i!=allowed.end(); ++i) {
01909 allowVehicleClass(lane, *i);
01910 }
01911 for (std::vector<SUMOVehicleClass>::const_iterator i=disallowed.begin(); i!=disallowed.end(); ++i) {
01912 disallowVehicleClass(lane, *i);
01913 }
01914 }
01915
01916
01917 std::vector<SUMOVehicleClass>
01918 NBEdge::getAllowedVehicleClasses() const {
01919 std::vector<SUMOVehicleClass> ret;
01920 for (std::vector<Lane>::const_iterator i=myLanes.begin(); i!=myLanes.end(); ++i) {
01921 const std::vector<SUMOVehicleClass> &allowed = (*i).allowed;
01922 for (std::vector<SUMOVehicleClass>::const_iterator j=allowed.begin(); j!=allowed.end(); ++j) {
01923 if (find(ret.begin(), ret.end(), *j)==ret.end()) {
01924 ret.push_back(*j);
01925 }
01926 }
01927 }
01928 return ret;
01929 }
01930
01931
01932
01933
01934 int
01935 NBEdge::getMinConnectedLane(NBEdge *of) const {
01936 int ret = -1;
01937 for (std::vector<Connection>::const_iterator i=myConnections.begin(); i!=myConnections.end(); ++i) {
01938 if ((*i).toEdge==of && (ret==-1 || (*i).toLane<ret)) {
01939 ret = (*i).toLane;
01940 }
01941 }
01942 return ret;
01943 }
01944
01945
01946 int
01947 NBEdge::getMaxConnectedLane(NBEdge *of) const {
01948 int ret = -1;
01949 for (std::vector<Connection>::const_iterator i=myConnections.begin(); i!=myConnections.end(); ++i) {
01950 if ((*i).toEdge==of && (*i).toLane>ret) {
01951 ret = (*i).toLane;
01952 }
01953 }
01954 return ret;
01955 }
01956
01957
01958 void
01959 NBEdge::setLoadedLength(SUMOReal val) {
01960 myLoadedLength = val;
01961 }
01962
01963
01964 void
01965 NBEdge::dismissVehicleClassInformation() {
01966 for (std::vector<Lane>::iterator i=myLanes.begin(); i!=myLanes.end(); ++i) {
01967 (*i).allowed.clear();
01968 (*i).notAllowed.clear();
01969 (*i).preferred.clear();
01970 }
01971 }
01972
01973
01974