#include <config.h>
#include <algorithm>
#include <utils/common/RandHelper.h>
#include <netbuild/NBNode.h>
#include <netbuild/NBNodeCont.h>
#include <netbuild/NBEdge.h>
#include <netbuild/NBOwnTLDef.h>
#include <netbuild/NBTypeCont.h>
#include <netbuild/NBTrafficLightLogicCont.h>
#include <netbuild/NBNetBuilder.h>
#include <utils/common/UtilExceptions.h>
#include <utils/common/ToString.h>
#include <utils/geom/GeoConvHelper.h>
#include <utils/options/OptionsCont.h>
#include <utils/options/Option.h>
#include "NGEdge.h"
#include "NGNode.h"
NGEdge::NGEdge(const std::string& id, NGNode* startNode, NGNode* endNode, const std::string& reverseID) :
Named(id), myStartNode(startNode), myEndNode(endNode), myReverseID(reverseID == "" ? "-" + id : reverseID) {
myStartNode->addLink(this);
myEndNode->addLink(this);
}
NGEdge::~NGEdge() {
myStartNode->removeLink(this);
myEndNode->removeLink(this);
}
NBEdge*
NGEdge::buildNBEdge(NBNetBuilder& nb, std::string type, const bool reversed) const {
const OptionsCont& oc = OptionsCont::getOptions();
if (oc.getBool("random-type") && nb.getTypeCont().size() > 1) {
auto it = nb.getTypeCont().begin();
std::advance(it, RandHelper::rand((int)nb.getTypeCont().size()));
type = it->first;
}
int priority = nb.getTypeCont().getEdgeTypePriority(type);
if (priority > 1 && oc.getBool("rand.random-priority")) {
priority = RandHelper::rand(priority) + 1;
}
int lanenumber = nb.getTypeCont().getEdgeTypeNumLanes(type);
if (lanenumber > 1 && oc.getBool("rand.random-lanenumber")) {
lanenumber = RandHelper::rand(lanenumber) + 1;
}
SVCPermissions permissions = nb.getTypeCont().getEdgeTypePermissions(type);
LaneSpreadFunction lsf = nb.getTypeCont().getEdgeTypeSpreadType(type);
if (isRailway(permissions) && nb.getTypeCont().getEdgeTypeIsOneWay(type)) {
lsf = LaneSpreadFunction::CENTER;
}
const double maxSegmentLength = oc.getFloat("geometry.max-segment-length");
NBNode* from = nb.getNodeCont().retrieve(reversed ? myEndNode->getID() : myStartNode->getID());
NBNode* to = nb.getNodeCont().retrieve(reversed ? myStartNode->getID() : myEndNode->getID());
PositionVector shape;
if (maxSegmentLength > 0) {
shape.push_back(from->getPosition());
shape.push_back(to->getPosition());
NBNetBuilder::addGeometrySegments(shape, PositionVector(shape), maxSegmentLength);
}
NBEdge* result = new NBEdge(
reversed ? myReverseID : myID,
from, to,
type, nb.getTypeCont().getEdgeTypeSpeed(type), NBEdge::UNSPECIFIED_FRICTION, lanenumber,
priority, nb.getTypeCont().getEdgeTypeWidth(type), NBEdge::UNSPECIFIED_OFFSET, shape, lsf);
result->setPermissions(permissions);
return result;
}