#include <config.h>
#include <vector>
#include <map>
#include <cassert>
#include "NBContHelper.h"
#include <utils/geom/GeomHelper.h>
void
NBContHelper::nextCW(const EdgeVector& edges, EdgeVector::const_iterator& from) {
from++;
if (from == edges.end()) {
from = edges.begin();
}
}
void
NBContHelper::nextCCW(const EdgeVector& edges, EdgeVector::const_iterator& from) {
if (from == edges.begin()) {
from = edges.end() - 1;
} else {
--from;
}
}
std::ostream&
NBContHelper::out(std::ostream& os, const std::vector<bool>& v) {
for (std::vector<bool>::const_iterator i = v.begin(); i != v.end(); i++) {
os << *i;
}
return os;
}
NBEdge*
NBContHelper::findConnectingEdge(const EdgeVector& edges,
NBNode* from, NBNode* to) {
for (EdgeVector::const_iterator i = edges.begin(); i != edges.end(); i++) {
if ((*i)->getToNode() == to && (*i)->getFromNode() == from) {
return *i;
}
}
return nullptr;
}
double
NBContHelper::maxSpeed(const EdgeVector& ev) {
assert(ev.size() > 0);
double max = (*(ev.begin()))->getSpeed();
for (EdgeVector::const_iterator i = ev.begin() + 1; i != ev.end(); i++) {
max =
max > (*i)->getSpeed()
? max : (*i)->getSpeed();
}
return max;
}
NBContHelper::node_with_incoming_finder::node_with_incoming_finder(const NBEdge* const e)
: myEdge(e) {}
bool
NBContHelper::node_with_incoming_finder::operator()(const NBNode* const n) const {
const EdgeVector& incoming = n->getIncomingEdges();
return std::find(incoming.begin(), incoming.end(), myEdge) != incoming.end();
}
NBContHelper::node_with_outgoing_finder::node_with_outgoing_finder(const NBEdge* const e)
: myEdge(e) {}
bool
NBContHelper::node_with_outgoing_finder::operator()(const NBNode* const n) const {
const EdgeVector& outgoing = n->getOutgoingEdges();
return std::find(outgoing.begin(), outgoing.end(), myEdge) != outgoing.end();
}
NBContHelper::edge_with_destination_finder::edge_with_destination_finder(NBNode* dest)
: myDestinationNode(dest) {}
bool
NBContHelper::edge_with_destination_finder::operator()(NBEdge* e) const {
return e->getToNode() == myDestinationNode;
}
bool
NBContHelper::relative_outgoing_edge_sorter::operator()(const NBEdge* e1, const NBEdge* e2) const {
assert(e1 != nullptr && e2 != nullptr);
double relAngle1 = NBHelpers::normRelAngle(myAngle, e1->getStartAngle());
double relAngle2 = NBHelpers::normRelAngle(myAngle, e2->getStartAngle());
const double length1 = e1->getGeometry().length2D();
const double length2 = e2->getGeometry().length2D();
double lookAhead = 2 * NBEdge::ANGLE_LOOKAHEAD;
while (fabs(relAngle1 - relAngle2) < 3.0) {
const double offset1 = MAX2(0.0, MIN2(length1, lookAhead));
const double offset2 = MAX2(0.0, MIN2(length2, lookAhead));
const Position referencePos1 = e1->getGeometry().positionAtOffset2D(offset1);
const Position referencePos2 = e2->getGeometry().positionAtOffset2D(offset2);
const double angle1 = GeomHelper::legacyDegree(e1->getFromNode()->getPosition().angleTo2D(referencePos1), true);
const double angle2 = GeomHelper::legacyDegree(e2->getFromNode()->getPosition().angleTo2D(referencePos2), true);
relAngle1 = NBHelpers::normRelAngle(myAngle, angle1);
relAngle2 = NBHelpers::normRelAngle(myAngle, angle2);
if (lookAhead > MAX2(length1, length2)) {
break;
}
lookAhead *= 2;
}
if (fabs(relAngle1 - relAngle2) < NUMERICAL_EPS) {
return e1->getID() > e2->getID();
}
return relAngle1 > relAngle2;
}
bool
NBContHelper::relative_incoming_edge_sorter::operator()(const NBEdge* e1, const NBEdge* e2) const {
assert(e1 != nullptr && e2 != nullptr);
double relAngle1 = NBHelpers::normRelAngle(myAngle, e1->getEndAngle());
double relAngle2 = NBHelpers::normRelAngle(myAngle, e2->getEndAngle());
const double length1 = e1->getGeometry().length2D();
const double length2 = e2->getGeometry().length2D();
double lookAhead = 2 * NBEdge::ANGLE_LOOKAHEAD;
while (fabs(relAngle1 - relAngle2) < 3.0) {
const double offset1 = MAX2(0.0, MIN2(length1, length1 - lookAhead));
const double offset2 = MAX2(0.0, MIN2(length2, length2 - lookAhead));
const Position referencePos1 = e1->getGeometry().positionAtOffset2D(offset1);
const Position referencePos2 = e2->getGeometry().positionAtOffset2D(offset2);
const double angle1 = GeomHelper::legacyDegree(referencePos1.angleTo2D(e1->getToNode()->getPosition()), true);
const double angle2 = GeomHelper::legacyDegree(referencePos2.angleTo2D(e2->getToNode()->getPosition()), true);
relAngle1 = NBHelpers::normRelAngle(myAngle, angle1);
relAngle2 = NBHelpers::normRelAngle(myAngle, angle2);
if (lookAhead > MAX2(length1, length2)) {
break;
}
lookAhead *= 2;
}
if (fabs(relAngle1 - relAngle2) < NUMERICAL_EPS) {
return e1->getID() > e2->getID();
}
return relAngle1 > relAngle2;
}
std::ostream&
operator<<(std::ostream& os, const EdgeVector& ev) {
for (EdgeVector::const_iterator i = ev.begin(); i != ev.end(); i++) {
if (i != ev.begin()) {
os << ", ";
}
os << (*i)->getID();
}
return os;
}
double
NBContHelper::getMaxSpeed(const EdgeVector& edges) {
if (edges.size() == 0) {
return -1;
}
double ret = (*(edges.begin()))->getSpeed();
for (EdgeVector::const_iterator i = edges.begin() + 1; i != edges.end(); i++) {
if ((*i)->getSpeed() > ret) {
ret = (*i)->getSpeed();
}
}
return ret;
}
double
NBContHelper::getMinSpeed(const EdgeVector& edges) {
if (edges.size() == 0) {
return -1;
}
double ret = (*(edges.begin()))->getSpeed();
for (EdgeVector::const_iterator i = edges.begin() + 1; i != edges.end(); i++) {
if ((*i)->getSpeed() < ret) {
ret = (*i)->getSpeed();
}
}
return ret;
}
bool
NBContHelper::edge_by_angle_to_nodeShapeCentroid_sorter::operator()(const NBEdge* e1, const NBEdge* e2) const {
assert(e1->getFromNode() == myNode || e1->getToNode() == myNode);
assert(e2->getFromNode() == myNode || e2->getToNode() == myNode);
const double angle1 = e1->getAngleAtNodeToCenter(myNode);
const double angle2 = e2->getAngleAtNodeToCenter(myNode);
const double absDiff = fabs(angle1 - angle2);
if (absDiff < 2 || absDiff > (360 - 2)) {
const bool sameDir = ((e1->getFromNode() == myNode && e2->getFromNode() == myNode)
|| (e1->getToNode() == myNode && e2->getToNode() == myNode));
if (sameDir) {
const bool e1Peds = (e1->getPermissions() & SVC_PEDESTRIAN) != 0;
const bool e2Peds = (e2->getPermissions() & SVC_PEDESTRIAN) != 0;
if (e1->getToNode() == myNode) {
if (e1Peds && !e2Peds) {
return true;
} else if (!e1Peds && e2Peds) {
return false;
}
} else {
if (!e1Peds && e2Peds) {
return true;
} else if (e1Peds && !e2Peds) {
return false;
}
}
return e1->getID() < e2->getID();
} else {
return e1->getToNode() == myNode;
}
}
return angle1 < angle2;
}