26#include <unordered_set>
35#define KDTP_EXCLUDE_INTERNAL_EDGES
38#define KDTP_KEEP_OUTGOING_BOUNDARY_EDGES
40#define KDTP_KEEP_INCOMING_BOUNDARY_EDGES
45#define KDTP_KEEP_BOUNDARY_FROM_NODES
51#ifdef KDTP_WRITE_QGIS_FILTERS
60#ifdef KDTP_DEBUG_LEVEL_2
61#define KDTP_DEBUG_LEVEL_1
64#ifdef KDTP_DEBUG_LEVEL_1
65#define KDTP_DEBUG_LEVEL_0
85template<
class E,
class N,
class V>
105 bool operator()(
const N* firstNode,
const N* secondNode)
const {
106 if (firstNode->getPosition().x() == secondNode->getPosition().x()) {
107 std::string str = firstNode->getID();
108 std::intmax_t firstValue = std::strtoimax(str.c_str(),
nullptr, 10);
109 str = secondNode->getID();
110 std::intmax_t secondValue = std::strtoimax(str.c_str(),
nullptr, 10);
111 return firstValue < secondValue;
113 return firstNode->getPosition().x() < secondNode->getPosition().x();
129 bool operator()(
const N* firstNode,
const N* secondNode)
const {
130 if (firstNode->getPosition().y() == secondNode->getPosition().y()) {
131 std::string str = firstNode->getID();
132 std::intmax_t firstValue = std::strtoimax(str.c_str(),
nullptr, 10);
133 str = secondNode->getID();
134 std::intmax_t secondValue = std::strtoimax(str.c_str(),
nullptr, 10);
135 return firstValue < secondValue;
137 return firstNode->getPosition().y() < secondNode->getPosition().y();
147#ifdef KDTP_FOR_SYNTHETIC_NETWORKS
173 Cell(std::vector<const Cell*>* cells, std::vector<std::vector<const Cell*>>* levelCells, std::vector<const N*>* sortedNodes,
int numberOfLevels,
174 int level,
Axis axis,
size_t fromInclusive,
size_t toExclusive,
Cell* supercell,
double minX,
double maxX,
double minY,
double maxY,
175 std::unordered_set<const N*>* northernConflictNodes, std::unordered_set<const N*>* easternConflictNodes,
176 std::unordered_set<const N*>* southernConflictNodes, std::unordered_set<const N*>* westernConflictNodes,
177 bool isLeftOrLowerCell,
const V*
const vehicle,
const bool havePermissions,
const bool haveRestrictions);
200 Cell(std::vector<const Cell*>* cells, std::vector<std::vector<const Cell*>>* levelCells, std::vector<const N*>* sortedNodes,
201 int numberOfLevels,
int level,
Axis axis,
size_t fromInclusive,
size_t toExclusive,
Cell* supercell,
double minX,
double maxX,
202 double minY,
double maxY,
bool isLeftOrLowerCell,
const V*
const vehicle,
const bool havePermissions,
const bool haveRestrictions);
219 std::unordered_set<const E*>*
edgeSet(
const V*
const vehicle)
const;
248 std::pair<typename std::vector<const N*>::const_iterator,
253 std::vector<const N*>*
nodes()
const;
254#ifdef KDTP_KEEP_BOUNDARY_NODES
256 const std::vector<const N*>& getBoundaryNodes()
const {
257 return myBoundaryNodes;
260#ifdef KDTP_KEEP_BOUNDARY_FROM_NODES
266#ifdef KDTP_KEEP_BOUNDARY_TO_NODES
268 const std::vector<const N*>& getBoundaryToNodes()
const {
269 return myBoundaryToNodes;
272#ifdef KDTP_KEEP_BOUNDARY_EDGES
274 const std::unordered_set<const E*>& getBoundaryEdges()
const {
275 return myBoundaryEdges;
278#ifdef KDTP_KEEP_INCOMING_BOUNDARY_EDGES
284#ifdef KDTP_KEEP_OUTGOING_BOUNDARY_EDGES
354#ifdef KDTP_FOR_SYNTHETIC_NETWORKS
359 std::pair<std::unordered_set<const N*>*, std::unordered_set<const N*>*> spatialConflictNodes(
size_t medianIndex)
const;
404#if defined(KDTP_KEEP_BOUNDARY_NODES) || defined(KDTP_WRITE_QGIS_FILTERS)
406 std::vector<const N*> myBoundaryNodes;
408#ifdef KDTP_KEEP_BOUNDARY_FROM_NODES
412#ifdef KDTP_KEEP_BOUNDARY_TO_NODES
414 std::vector<const N*> myBoundaryToNodes;
416#ifdef KDTP_KEEP_INCOMING_BOUNDARY_EDGES
421#ifdef KDTP_KEEP_OUTGOING_BOUNDARY_EDGES
426#ifdef KDTP_KEEP_BOUNDARY_EDGES
428 std::unordered_set<const E*> myBoundaryEdges;
450#ifdef KDTP_FOR_SYNTHETIC_NETWORKS
452 std::unordered_set<const N*>* myNorthernConflictNodes;
454 std::unordered_set<const N*>* myEasternConflictNodes;
456 std::unordered_set<const N*>* mySouthernConflictNodes;
458 std::unordered_set<const N*>* myWesternConflictNodes;
475 const bool havePermissions,
const bool haveRestrictions);
480 std::vector<const Cell*>().swap(
myCells);
481 std::vector<std::vector<const Cell*>>().swap(
myLevelCells);
488 void init(
const V*
const vehicle);
493 void reset(
const V*
const vehicle) {
510 const Cell*
cell(
int number)
const;
572 void cellNumbersAux(
const N* node,
const Cell*
cell,
int level, std::vector<int>* nodeCellNumbers)
const;
597template<
class E,
class N,
class V>
599 const bool havePermissions,
const bool haveRestrictions) :
605 if (numberOfLevels <= 0) {
606 throw std::invalid_argument(
"KDTreePartition::KDTreePartition: zero or negative number of levels has been passed!");
610template<
class E,
class N,
class V>
612 size_t edgeCounter = 0;
613 std::unordered_set<const N*> nodeSet;
616#ifdef KDTP_DEBUG_LEVEL_1
617 std::cout <<
"Extracting nodes from edges..." << std::endl;
624 const N* node = edge->getFromJunction();
625 typename std::unordered_set<const N*>::const_iterator it = nodeSet.find(node);
626 if (it == nodeSet.end()) {
627 nodeSet.insert(node);
631 node = edge->getToJunction();
632 it = nodeSet.find(node);
633 if (it == nodeSet.end()) {
634 nodeSet.insert(node);
640#ifdef KDTP_DEBUG_LEVEL_1
641 std::cout <<
"Nodes extracted from edges." << std::endl;
647#ifdef KDTP_DEBUG_LEVEL_1
648 std::cout <<
"Calling root cell constructor..." << std::endl;
650#ifdef KDTP_FOR_SYNTHETIC_NETWORKS
651 myRoot =
new Cell(&
myCells, &
myLevelCells, &
mySortedNodes,
myNumberOfLevels, 0,
Axis::Y, 0,
mySortedNodes.size(),
nullptr, -1, -1, -1, -1,
652 nullptr,
nullptr,
nullptr,
nullptr,
false, vehicle, havePermissions, haveRestrictions);
654 myRoot =
new Cell(&
myCells, &
myLevelCells, &
mySortedNodes,
myNumberOfLevels, 0,
Axis::Y, 0,
mySortedNodes.size(),
nullptr, -1, -1, -1, -1,
657#ifdef KDTP_DEBUG_LEVEL_1
658 std::cout <<
"Done." << std::endl;
661 assert(
myRoot->getNumber() == 0);
663#ifdef KDTP_DEBUG_LEVEL_0
668 std::cout <<
"Cell numbers of test node: " << (*numbers)[i] << std::endl;
673 size_t size = levelCells.size();
674 std::cout <<
"Level " << i <<
" has " << size <<
" cells." << std::endl;
675 std::cout <<
"The numbers of the cells are: " << std::endl;
677 for (
const Cell*
cell : levelCells) {
678 std::cout <<
cell->getNumber() << (k++ < size ?
", " :
"") << std::endl;
685template<
class E,
class N,
class V>
689 if (
cell->getNumber() == number) {
696template<
class E,
class N,
class V>
701 (*nodeCellNumbers)[i] = -1;
704#ifdef KDTP_DEBUG_LEVEL_1
705 std::cout <<
"The following entries in nodeCellNumbers should all be set (!=-1): " << std::endl;
707 assert((*nodeCellNumbers)[i] != -1);
708 std::cout <<
"nodeCellNumbers[" << i <<
"]:" << (*nodeCellNumbers)[i] << std::endl;
711 return nodeCellNumbers;
714template<
class E,
class N,
class V>
716#ifdef KDTP_DEBUG_LEVEL_1
717 std::cout <<
"Call ...aux, level: " << level <<
", cell->getAxis(): " << (
cell->getAxis() ==
Axis::X ?
"X" :
"Y") << std::endl;
720#ifdef KDTP_DEBUG_LEVEL_1
722 double nodeAxisValue = flippedCellAxis ==
Axis::Y ? node->getPosition().y() : node->getPosition().x();
723 std::cout <<
"Flipped axis of cell (=parent cell axis): " << (flippedCellAxis ==
Axis::X ?
"X" :
"Y")
724 <<
", cell min axis value in flipped axis: " << (flippedCellAxis ==
Axis::X ?
cell->getMinX() :
cell->getMinY())
725 <<
", node axis value in flipped axis: " << nodeAxisValue <<
", cell max axis value in flipped axis: "
726 << (flippedCellAxis ==
Axis::X ?
cell->getMaxX() :
cell->getMaxY()) << std::endl;
728 if (
cell->contains(node)) {
730 (*nodeCellNumbers)[level] =
cell->getNumber();
731#ifdef KDTP_DEBUG_LEVEL_1
732 std::cout <<
"Just filled nodeCellNumbers[" << level <<
"]:" << (*nodeCellNumbers)[level] << std::endl;
735 const Cell* leftOrLowerSubcell =
cell->getLeftOrLowerSubcell();
736 if (leftOrLowerSubcell) {
737 cellNumbersAux(node, leftOrLowerSubcell, level + 1, nodeCellNumbers);
739 const Cell* rightOrUpperSubcell =
cell->getRightOrUpperSubcell();
740 if (rightOrUpperSubcell) {
741 cellNumbersAux(node, rightOrUpperSubcell, level + 1, nodeCellNumbers);
744#ifdef KDTP_DEBUG_LEVEL_1
746 std::cout <<
"Not inside cell, do nothing." << std::endl;
751template<
class E,
class N,
class V>
752#ifdef KDTP_FOR_SYNTHETIC_NETWORKS
753KDTreePartition<E, N, V>::Cell::Cell(std::vector<const Cell*>* cells, std::vector<std::vector<const Cell*>>* levelCells, std::vector<const N*>* sortedNodes,
int numberOfLevels,
int level,
754 Axis axis,
size_t fromInclusive,
size_t toExclusive,
Cell* supercell,
double minX,
double maxX,
double minY,
double maxY, std::unordered_set<const N*>* northernConflictNodes,
755 std::unordered_set<const N*>* easternConflictNodes, std::unordered_set<const N*>* southernConflictNodes, std::unordered_set<const N*>* westernConflictNodes,
const V*
const vehicle,
756 const bool havePermissions,
const bool haveRestrictions) :
758 myLevelCells(levelCells),
759 mySortedNodes(sortedNodes),
760 myNumberOfLevels(numberOfLevels),
761 myLevel(level), myNumber(cellCounter()++),
763 myFromInclusive(fromInclusive),
764 myToExclusive(toExclusive),
765 mySupercell(supercell),
770 myNorthernConflictNodes(northernConflictNodes),
771 myEasternConflictNodes(easternConflictNodes),
772 mySouthernConflictNodes(southernConflictNodes),
773 myWesternConflictNodes(westernConflictNodes),
774 myIsLeftOrLowerCell(isLeftOrLowerCell),
775 myHavePermissions(havePermissions),
776 myHaveRestrictions(haveRestrictions),
777 myMedianCoordinate(-1.) {
780 Axis axis,
size_t fromInclusive,
size_t toExclusive,
Cell* supercell,
double minX,
double maxX,
double minY,
double maxY,
bool isLeftOrLowerCell,
const V*
const vehicle,
781 const bool havePermissions,
const bool haveRestrictions) :
803 throw std::invalid_argument(
"Cell::Cell: myFromInclusive greater than or equal to myToExclusive!");
808 (*myLevelCells)[
myLevel].push_back(
this);
809#ifdef KDTP_DEBUG_LEVEL_1
810 std::cout <<
"Cell number: " <<
myNumber <<
", cell's extent: minX=" <<
myMinX <<
", maxX="
812 std::vector<const N*>* cellNodes =
nodes();
814 for (
const N* node : *cellNodes) {
815 if (++cnt % 10000 == 0) {
816 std::cout <<
"Testing node " << cnt << std::endl;
824 typename std::vector<const N*>::const_iterator iter;
825#ifdef KDTP_WRITE_QGIS_FILTERS
828 std::string qgisFilterString =
"id IN (";
830 for (iter = first; iter != last; iter++) {
832 qgisFilterString += (*iter)->getID() + (k < numberOfNodes ?
", " :
"");
834 qgisFilterString +=
")";
835 std::ostringstream pathAndFileName;
836 pathAndFileName <<
"./filter_nodes_of_cell_" <<
myNumber <<
".qqf";
838 file.open(pathAndFileName.str());
839 std::ostringstream content;
840 content <<
"<Query>" << qgisFilterString <<
"</Query>";
841 file << content.str();
845#ifdef KDTP_DEBUG_LEVEL_1
846 std::cout <<
"Computing the set of of edges inside the cell..." << std::endl;
849#ifdef KDTP_DEBUG_LEVEL_1
850 std::cout <<
"Done. Now collecting boundary edges..." << std::endl;
854 for (iter = first; iter != last; iter++) {
855#if defined(KDTP_KEEP_BOUNDARY_EDGES) || defined(KDTP_KEEP_BOUNDARY_NODES) || defined(KDTP_WRITE_QGIS_FILTERS)
856 std::unordered_set<const E*> nodeEdgeSet;
858#ifdef KDTP_DEBUG_LEVEL_1
859 if ((i++ % 10000) == 0) {
860 std::cout << i <<
" cell nodes processed..." << std::endl;
863#if defined(KDTP_KEEP_BOUNDARY_EDGES) || defined(KDTP_KEEP_BOUNDARY_NODES) || defined(KDTP_WRITE_QGIS_FILTERS)
864 const std::vector<const E*>& incomingEdges = (*iter)->getIncoming();
865 for (
const E* incomingEdge : incomingEdges) {
869#ifdef KDTP_EXCLUDE_INTERNAL_EDGES
870 if (incomingEdge->isInternal()) {
874 nodeEdgeSet.insert(incomingEdge);
876 const std::vector<const E*>& outgoingEdges = (*iter)->getOutgoing();
877 for (
const E* outgoingEdge : outgoingEdges) {
881#ifdef KDTP_EXCLUDE_INTERNAL_EDGES
882 if (outgoingEdge->isInternal()) {
886 nodeEdgeSet.insert(outgoingEdge);
888 bool containsAll =
true;
889 for (
const E* nodeEdge : nodeEdgeSet) {
892#ifndef KDTP_KEEP_BOUNDARY_EDGES
895 myBoundaryEdges.insert(nodeEdge);
899#if defined(KDTP_KEEP_BOUNDARY_NODES) || defined(KDTP_WRITE_QGIS_FILTERS)
901 myBoundaryNodes.push_back(*iter);
905#if defined(KDTP_KEEP_INCOMING_BOUNDARY_EDGES) || defined(KDTP_KEEP_BOUNDARY_TO_NODES)
906 const std::vector<const E*>& incoming = (*iter)->getIncoming();
907 std::unordered_set<const N*> boundaryToNodesSet;
908 for (
const E* nodeEdge : incoming) {
912#ifdef KDTP_EXCLUDE_INTERNAL_EDGES
913 if (nodeEdge->isInternal()) {
917 assert(nodeEdge->getToJunction() == *iter);
919#ifdef KDTP_KEEP_INCOMING_BOUNDARY_EDGES
922#ifdef KDTP_KEEP_BOUNDARY_TO_NODES
923 boundaryToNodesSet.insert(*iter); ;
927#ifdef KDTP_KEEP_BOUNDARY_TO_NODES
928 std::copy(boundaryToNodesSet.begin(), boundaryToNodesSet.end(),
929 std::back_inserter(myBoundaryToNodes));
932#if defined(KDTP_KEEP_OUTGOING_BOUNDARY_EDGES) || defined(KDTP_KEEP_BOUNDARY_FROM_NODES)
933 const std::vector<const E*>& outgoing = (*iter)->getOutgoing();
934 std::unordered_set<const N*> boundaryFromNodesSet;
935 for (
const E* nodeEdge : outgoing) {
939#ifdef KDTP_EXCLUDE_INTERNAL_EDGES
940 if (nodeEdge->isInternal()) {
944 assert(nodeEdge->getFromJunction() == *iter);
946#ifdef KDTP_KEEP_OUTGOING_BOUNDARY_EDGES
949#ifdef KDTP_KEEP_BOUNDARY_FROM_NODES
950 boundaryFromNodesSet.insert(*iter);
954#ifdef KDTP_KEEP_BOUNDARY_FROM_NODES
955 std::copy(boundaryFromNodesSet.begin(), boundaryFromNodesSet.end(),
961#if defined(KDTP_KEEP_BOUNDARY_NODES) || defined(KDTP_WRITE_QGIS_FILTERS)
962 size_t numberOfBoundaryNodes = myBoundaryNodes.size();
963#ifdef KDTP_DEBUG_LEVEL_1
964 std::cout <<
"Number of boundary nodes: " << numberOfBoundaryNodes << std::endl;
967#ifdef KDTP_KEEP_BOUNDARY_FROM_NODES
968#ifdef KDTP_DEBUG_LEVEL_1
970 std::cout <<
"Number of boundary from nodes: " << numberOfBoundaryFromNodes << std::endl;
973#ifdef KDTP_KEEP_BOUNDARY_TO_NODES
974 size_t numberOfBoundaryToNodes = myBoundaryToNodes.size();
975#ifdef KDTP_DEBUG_LEVEL_1
976 std::cout <<
"Number of boundary to nodes: " << numberOfBoundaryToNodes << std::endl;
979#ifdef KDTP_KEEP_BOUNDARY_EDGES
980 size_t numberOfBoundaryEdges = myBoundaryEdges.size();
981#ifdef KDTP_DEBUG_LEVEL_1
982 std::cout <<
"Number of boundary edges: " << numberOfBoundaryEdges << std::endl;
985#ifdef KDTP_KEEP_INCOMING_BOUNDARY_EDGES
986#ifdef KDTP_DEBUG_LEVEL_1
988 std::cout <<
"Number of incoming boundary edges: " << numberOfIncomingBoundaryEdges << std::endl;
991#ifdef KDTP_KEEP_OUTGOING_BOUNDARY_EDGES
992#ifdef KDTP_DEBUG_LEVEL_1
994 std::cout <<
"Number of outgoing boundary edges: " << numberOfOutgoingBoundaryEdges << std::endl;
997#ifdef KDTP_WRITE_QGIS_FILTERS
999 qgisFilterString.clear();
1000 qgisFilterString =
"id IN (";
1002 for (
const N* node : myBoundaryNodes) {
1004 qgisFilterString += node->getID() + (k < numberOfBoundaryNodes ?
", " :
"");
1006#ifndef KDTP_KEEP_BOUNDARY_NODES
1007 myBoundaryNodes.clear();
1009 qgisFilterString +=
")";
1010 pathAndFileName.str(
"");
1011 pathAndFileName.clear();
1012 pathAndFileName <<
"./filter_boundary_nodes_of_cell_" <<
myNumber <<
".qqf";
1014 file.open(pathAndFileName.str());
1017 content <<
"<Query>" << qgisFilterString <<
"</Query>";
1018 file << content.str();
1021#ifdef KDTP_DEBUG_LEVEL_1
1022 std::cout <<
"Done. Now calling the constructor recursively to instantiate the subcells (left or lower one first)..." << std::endl;
1029 double passMinX = -1, passMaxX = -1, passMinY = -1, passMaxY = -1;
1032 passMaxX = (*mySortedNodes)[medianIndex]->getPosition().x();
1039 passMaxY = (*mySortedNodes)[medianIndex]->getPosition().y();
1041#ifdef KDTP_FOR_SYNTHETIC_NETWORKS
1049 std::pair<std::unordered_set<const N*>*, std::unordered_set<const N*>*> conflictNodes = spatialConflictNodes(medianIndex);
1051 std::unordered_set<const N*>* passNorthernConflictNodes;
1052 std::unordered_set<const N*>* passEasternConflictNodes;
1053 std::unordered_set<const N*>* passSouthernConflictNodes;
1054 std::unordered_set<const N*>* passWesternConflictNodes;
1056 passNorthernConflictNodes = myNorthernConflictNodes;
1057 passEasternConflictNodes = conflictNodes.first;
1058 passSouthernConflictNodes = mySouthernConflictNodes;
1059 passWesternConflictNodes = myWesternConflictNodes;
1061 passNorthernConflictNodes = conflictNodes.first;
1062 passEasternConflictNodes = myEasternConflictNodes;
1063 passSouthernConflictNodes = mySouthernConflictNodes;
1064 passWesternConflictNodes = myWesternConflictNodes;
1067 passMinX, passMaxX, passMinY, passMaxY, passNorthernConflictNodes, passEasternConflictNodes, passSouthernConflictNodes, passWesternConflictNodes,
true,
1073#ifdef KDTP_DEBUG_LEVEL_1
1074 std::cout <<
"Left or lower call done. Now calling it for the right or upper subcell..." << std::endl;
1077 passMinX = -1, passMaxX = -1, passMinY = -1, passMaxY = -1;
1079 passMinX = (*mySortedNodes)[medianIndex + 1]->getPosition().x();
1086 passMinY = (*mySortedNodes)[medianIndex + 1]->getPosition().y();
1089#ifdef KDTP_FOR_SYNTHETIC_NETWORKS
1092 passNorthernConflictNodes = myNorthernConflictNodes;
1093 passEasternConflictNodes = myEasternConflictNodes;
1094 passSouthernConflictNodes = mySouthernConflictNodes;
1095 passWesternConflictNodes = conflictNodes.second;
1097 passNorthernConflictNodes = myNorthernConflictNodes;
1098 passEasternConflictNodes = myEasternConflictNodes;
1099 passSouthernConflictNodes = conflictNodes.second;
1100 passWesternConflictNodes = myWesternConflictNodes;
1103 passMinX, passMaxX, passMinY, passMaxY, passNorthernConflictNodes, passEasternConflictNodes, passSouthernConflictNodes, passWesternConflictNodes,
false,
1109#ifdef KDTP_DEBUG_LEVEL_1
1110 std::cout <<
"Right or upper call done. Returning from constructor..." << std::endl;
1119template<
class E,
class N,
class V>
1121#ifdef KDTP_DEBUG_LEVEL_1
1122 double returnValue = -1;
1125#ifndef KDTP_DEBUG_LEVEL_1
1133 double minAxisValue = std::numeric_limits<double>::max();
1136 typename std::vector<const N*>::const_iterator iter;
1138 for (iter = first; iter != last; iter++) {
1139 double nodeAxisValue;
1140 nodeAxisValue = (axis ==
Axis::Y ? (*iter)->getPosition().y() : (*iter)->getPosition().x());
1145 assert(
minAxisValue < std::numeric_limits<double>::max());
1146#ifdef KDTP_DEBUG_LEVEL_1
1152template<
class E,
class N,
class V>
1157template<
class E,
class N,
class V>
1159#ifdef KDTP_DEBUG_LEVEL_1
1160 double returnValue = -1;
1163#ifndef KDTP_DEBUG_LEVEL_1
1175 typename std::vector<const N*>::const_iterator iter;
1177 for (iter = first; iter != last; iter++) {
1178 double nodeAxisValue;
1179 nodeAxisValue = (axis ==
Axis::Y ? (*iter)->getPosition().y() : (*iter)->getPosition().x());
1185#ifdef KDTP_DEBUG_LEVEL_1
1191template<
class E,
class N,
class V>
1196template<
class E,
class N,
class V>
1211 size_t medianIndex =
myFromInclusive + (length % 2 == 0 ? length / 2 - 1 : (length + 1) / 2 - 1);
1212#ifndef KDTP_FOR_SYNTHETIC_NETWORKS
1223 const N* medianNode = (*mySortedNodes)[medianIndex];
1224 const N* afterMedianNode = (*mySortedNodes)[medianIndex + 1];
1225 double medianNodeCoordinate =
myAxis ==
Axis::X ? medianNode->getPosition().x()
1226 : medianNode->getPosition().y();
1227 double afterMedianNodeCoordinate =
myAxis ==
Axis::X ? afterMedianNode->getPosition().x()
1228 : afterMedianNode->getPosition().y();
1229 while (medianNodeCoordinate == afterMedianNodeCoordinate && medianIndex <
myToExclusive - 3) {
1230#ifdef KDTP_DEBUG_LEVEL_2
1231 std::cout <<
"Found spatially conflicting nodes." << std::endl;
1234 medianNode = (*mySortedNodes)[medianIndex];
1235 afterMedianNode = (*mySortedNodes)[medianIndex + 1];
1236 medianNodeCoordinate =
myAxis ==
Axis::X ? medianNode->getPosition().x()
1237 : medianNode->getPosition().y();
1238 afterMedianNodeCoordinate =
myAxis ==
Axis::X ? afterMedianNode->getPosition().x()
1239 : afterMedianNode->getPosition().y();
1246template<
class E,
class N,
class V>
1264template<
class E,
class N,
class V>
1266 std::unordered_set<const E*>*
edgeSet =
new std::unordered_set<const E*>();
1269 typename std::vector<const N*>::const_iterator iter;
1270 for (iter = first; iter != last; iter++) {
1272 const std::vector<const E*>& incomingEdges = (*iter)->getIncoming();
1273 for (
const E* incomingEdge : incomingEdges) {
1277#ifdef KDTP_EXCLUDE_INTERNAL_EDGES
1278 if (incomingEdge->isInternal()) {
1282 edgeNode = incomingEdge->getFromJunction();
1284 edgeSet->insert(incomingEdge);
1287 const std::vector<const E*>& outgoingEdges = (*iter)->getOutgoing();
1288 for (
const E* outgoingEdge : outgoingEdges) {
1292#ifdef KDTP_EXCLUDE_INTERNAL_EDGES
1293 if (outgoingEdge->isInternal()) {
1297 edgeNode = outgoingEdge->getToJunction();
1299 edgeSet->insert(outgoingEdge);
1306template<
class E,
class N,
class V>
1310 typename std::vector<const N*>::const_iterator iter;
1311 size_t edgeCounter = 0;
1312 for (iter = first; iter != last; iter++) {
1313 const std::vector<const E*>& incomingEdges = (*iter)->getIncoming();
1314 for (
const E* incomingEdge : incomingEdges) {
1318#ifdef KDTP_EXCLUDE_INTERNAL_EDGES
1319 if (incomingEdge->isInternal()) {
1330template<
class E,
class N,
class V>
1334 typename std::vector<const N*>::const_iterator iter;
1335 size_t edgeCounter = 0;
1336 for (iter = first; iter != last; iter++) {
1337 const std::vector<const E*>& outgoingEdges = (*iter)->getOutgoing();
1338 for (
const E* outgoingEdge : outgoingEdges) {
1342#ifdef KDTP_EXCLUDE_INTERNAL_EDGES
1343 if (outgoingEdge->isInternal()) {
1354template<
class E,
class N,
class V>
1355std::pair<typename std::vector<const N*>::const_iterator,
1359 std::pair<typename std::vector<const N*>::const_iterator,
1360 typename std::vector<const N*>::const_iterator> iterators = std::make_pair(first, last);
1364template<
class E,
class N,
class V>
1368 std::vector<const N*>*
nodes =
new std::vector<const N*>(first, last);
1372#ifdef KDTP_FOR_SYNTHETIC_NETWORKS
1373template<
class E,
class N,
class V>
1374std::pair<std::unordered_set<const N*>*,
1376 std::unordered_set<const N*>* leftOrLowerSpatialConflictNodes =
new std::unordered_set<const N*>();
1377 std::unordered_set<const N*>* rightOrUpperSpatialConflictNodes =
new std::unordered_set<const N*>();
1378 std::pair<std::unordered_set<const N*>*, std::unordered_set<const N*>*> spatialConflictNodes
1379 = std::make_pair(leftOrLowerSpatialConflictNodes, rightOrUpperSpatialConflictNodes);
1380 std::vector<const N*>::const_iterator iter, prev;
1383 double sharedCoordinate = (*mySortedNodes)[medianIndex]->getPosition().x();
1384 std::vector<const N*>::iterator firstLeftOrLower =
mySortedNodes->begin() + medianIndex;
1386 std::vector<const N*>::iterator last =
mySortedNodes->begin() + myFromInclusive - 1;
1387 for (iter = firstLeftOrLower; ((*iter)->getPosition().x() == sharedCoordinate) && (iter != last); iter--) {
1388 leftOrLowerSpatialConflictNodes->insert(*iter);
1393 double sharedCoordinate = (*mySortedNodes)[medianIndex]->getPosition().y();
1394 std::vector<const N*>::iterator firstRightOrUpper =
mySortedNodes->begin() + medianIndex + 1;
1395 std::vector<const N*>::const_iterator last =
mySortedNodes->begin() + myToExclusive;
1396 for (iter = firstRightOrUpper; ((*iter)->getPosition().y() == sharedCoordinate) && (iter != last); iter++) {
1397 rightOrUpperSpatialConflictNodes->insert(*iter);
1401 return spatialConflictNodes;
1405template<
class E,
class N,
class V>
1407 double nodeX = node->getPosition().x();
1408 double nodeY = node->getPosition().y();
1409 if (nodeX < myMinX || nodeX >
myMaxX || nodeY < myMinY || nodeY >
myMaxY) {
1415template<
class E,
class N,
class V>
1421#ifdef KDTP_DEBUG_LEVEL_2
1422 std::cout <<
"Not in bounds, nX: " << node->getPosition().x() <<
", nY: " << node->getPosition().y() << std::endl;
1426#ifdef KDTP_DEBUG_LEVEL_2
1428 std::cout <<
"Node is in bounds!" << std::endl;
1431#ifdef KDTP_FOR_SYNTHETIC_NETWORKS
1433 double nodeX = node->getPosition().x();
1434 double nodeY = node->getPosition().y();
1435#ifdef KDTP_DEBUG_LEVEL_2
1436 std::cout <<
"Entered contains, nodeX: " << nodeX <<
", nodeY: " << nodeY << std::endl;
1439 if (myNorthernConflictNodes && !myNorthernConflictNodes->empty()) {
1440 northY = (*(myNorthernConflictNodes->begin()))->getPosition().y();
1443 if (myEasternConflictNodes && !myEasternConflictNodes->empty()) {
1444 eastX = (*(myEasternConflictNodes->begin()))->getPosition().x();
1447 if (mySouthernConflictNodes && !mySouthernConflictNodes->empty()) {
1448 southY = (*(mySouthernConflictNodes->begin()))->getPosition().y();
1451 if (myWesternConflictNodes && !myWesternConflictNodes->empty()) {
1452 westX = (*(myWesternConflictNodes->begin()))->getPosition().x();
1454#ifdef KDTP_DEBUG_LEVEL_2
1455 std::cout <<
"northY: " << northY <<
", eastX: " << eastX <<
", southY: " << southY <<
", westX: " << westX << std::endl;
1457 if (nodeX == eastX) {
1458#ifdef KDTP_DEBUG_LEVEL_2
1459 std::cout <<
"On eastern bound, nX: " << node->getPosition().x() <<
", nY: " << node->getPosition().y() << std::endl;
1461 return myEasternConflictNodes->find(node) != myEasternConflictNodes->end();
1463 if (nodeX == westX) {
1464#ifdef KDTP_DEBUG_LEVEL_2
1465 std::cout <<
"On western bound, nX: " << node->getPosition().x() <<
", nY: " << node->getPosition().y() << std::endl;
1467 return myWesternConflictNodes->find(node) != myWesternConflictNodes->end();
1469 if (nodeY == northY) {
1470#ifdef KDTP_DEBUG_LEVEL_2
1471 std::cout <<
"On northern bound, nX: " << node->getPosition().x() <<
", nY: " << node->getPosition().y() << std::endl;
1473 return myNorthernConflictNodes->find(node) != myNorthernConflictNodes->end();
1475 if (nodeY == southY) {
1476#ifdef KDTP_DEBUG_LEVEL_2
1477 std::cout <<
"On southern bound, nX: " << node->getPosition().x() <<
", nY: " << node->getPosition().y() << std::endl;
1479 return mySouthernConflictNodes->find(node) != myEasternConflictNodes->end();
1482#ifdef KDTP_DEBUG_LEVEL_2
1483 std::cout <<
"Node does not lie on a border!" << std::endl;
1488template<
class E,
class N,
class V>
1491 if (!
myRoot->contains(node)) {
1496 double nodeCoordinate =
cell->getAxis() ==
Axis::X ? node->getPosition().x() : node->getPosition().y();
1498 cell->getLeftOrLowerSubcell() :
cell->getRightOrUpperSubcell();
1499 if (nextCell ==
nullptr) {
Represents an element of the node partition (i.e. a node set).
const Cell * getRightOrUpperSubcell() const
Returns the right (cell's axis is X) or upper (cell's axis is Y) subcell.
Cell * myRightOrUpperSubcell
The right (cell's axis is X) or upper (cell's axis is Y) subcell.
virtual ~Cell()
Destructor.
std::unordered_set< const E * > myIncomingBoundaryEdges
The incoming edges on the cell boundary.
std::unordered_set< const E * > * edgeSet(const V *const vehicle) const
Returns all edges situated inside the cell.
const std::vector< const N * > & getBoundaryFromNodes() const
Returns the vector of boundary nodes which are from-nodes of outgoing boundary edges.
size_t numberOfEdgesEndingInCell(const V *const vehicle) const
Returns the number of edges ending in the cell.
double getMinX() const
Returns the minimum coordinate of a cell node in X-direction (aka left border coordinate).
std::vector< const N * > myBoundaryFromNodes
Those nodes on the cell boundary, which are from-nodes of outgoing boundary edges.
double myMinX
The minimum x-value of a node in the cell.
const std::unordered_set< const E * > & getIncomingBoundaryEdges() const
Returns the set of incoming boundary edges.
size_t partition()
Performs one partition step on the set of nodes sorted wrt to the k-d tree subdivision scheme.
double myMedianCoordinate
The coordinate in the axis' direction of the node at the median index.
double minAxisValue() const
Returns the minimum coordinate of the cell nodes' positions, in the direction of the cell's axis (X o...
std::unordered_set< const E * > myOutgoingBoundaryEdges
The outgoing edges on the cell boundary.
bool isProhibited(const E *const edge, const V *const vehicle) const
Returns true iff driving the given vehicle on the given edge is prohibited.
double myMinY
The minimum y-value of a node in the cell.
const Axis myAxis
The axis of the spatial extension.
bool contains(const N *node) const
Tests whether the given node belongs to the cell.
double myMaxX
The maximum x-value of a node in the cell.
const size_t myToExclusive
The to-index (exclusive).
void completeSpatialInfo()
Completes the information about the spatial extent.
const int myNumberOfLevels
The total number of levels of the k-d tree.
bool myHasNodesSortedWrtToMyAxis
The boolean flag indicating whether the cell's nodes are sorted wrt to the cell's axis or not.
double myMaxY
The maximum y-value of a node in the cell.
double getMaxY() const
Returns the maximum coordinate of a cell node in Y-direction (aka upper border coordinate).
int getNumberOfCells() const
Returns the number of cells.
Cell * myLeftOrLowerSubcell
The left (cell's axis is X) or lower (cell's axis is Y) subcell.
std::vector< std::vector< const Cell * > > * myLevelCells
The cells of all partitions at all levels of the k-d tree subdivisional scheme.
const int myNumber
The number.
size_t numberOfEdgesStartingInCell(const V *const vehicle) const
Returns the number of edges starting in the cell.
bool myHasCompleteSpatialInfo
The boolean flag indicating whether the information about the cell's spatial extent is complete or no...
std::pair< typename std::vector< const N * >::const_iterator, typename std::vector< const N * >::const_iterator > nodeIterators() const
Returns a pair of iterators (first, last) to iterate over the nodes of the cell.
std::vector< const Cell * > * myCells
The cells.
bool isInBounds(const N *node) const
Tests whether a given node is situated within the spatial bounds of the cell.
int getNumber() const
Returns the cell's number.
double getMinY() const
Returns the minimum coordinate of a cell node in Y-direction (aka lower border coordinate).
double getMaxX() const
Returns the maximum coordinate of a cell node in X-direction (aka right border coordinate).
bool myIsLeftOrLowerCell
The boolean flag indicating whether this cell is a left/lower cell or not.
const int myLevel
The level.
const Cell * getLeftOrLowerSubcell() const
Returns the left (cell's axis is X) or lower (cell's axis is Y) subcell.
const bool myHaveRestrictions
The boolean flag indicating whether edge restrictions need to be considered or not.
static int & cellCounter()
Returns the global cell counter.
double minAxisValue(Axis axis) const
Returns the minimum coordinate of the cell nodes' positions, in the direction of the given axis (X or...
const std::unordered_set< const E * > & getOutgoingBoundaryEdges() const
Returns the set of outgoing boundary edges.
double maxAxisValue() const
Returns the maximum coordinate of the cell nodes' positions, in the direction of the cell's axis (X o...
Axis getAxis() const
Returns the axis of the cell's spatial extension (x or y).
std::vector< const N * > * nodes() const
Returns a new vector of nodes in the cell.
const bool myHavePermissions
The boolean flag indicating whether edge permissions need to be considered or not.
double getMedianCoordinate() const
Returns the median coordinate.
Cell * mySupercell
The super cell.
const Cell * getSupercell() const
Returns the supercell.
double maxAxisValue(Axis axis) const
Returns the maximum coordinate of the cell nodes' positions, in the direction of the given axis (X or...
Cell(std::vector< const Cell * > *cells, std::vector< std::vector< const Cell * > > *levelCells, std::vector< const N * > *sortedNodes, int numberOfLevels, int level, Axis axis, size_t fromInclusive, size_t toExclusive, Cell *supercell, double minX, double maxX, double minY, double maxY, bool isLeftOrLowerCell, const V *const vehicle, const bool havePermissions, const bool haveRestrictions)
Constructor.
bool isLeftOrLowerCell() const
Returns the boolean flag indicating whether this cell is a left or lower cell or not.
int getLevel() const
Returns the cell's level.
std::vector< const N * > * mySortedNodes
The container with all nodes, sorted wrt to the k-d tree subdivisional scheme.
const size_t myFromInclusive
The from-index (inclusive).
bool operator()(const N *firstNode, const N *secondNode) const
Comparing method for X-axis.
bool operator()(const N *firstNode, const N *secondNode) const
Comparing method for Y-axis.
void reset(const V *const vehicle)
Delete the k-d tree, and create a new one param[in] vehicle The vehicle.
std::vector< int > * cellNumbers(const N *node) const
Returns the numbers of the cells which the given node is situated in.
void cellNumbersAux(const N *node, const Cell *cell, int level, std::vector< int > *nodeCellNumbers) const
Helper method for cellNumbers().
const std::vector< E * > & myEdges
std::vector< std::vector< const Cell * > > myLevelCells
const bool myHavePermissions
const std::vector< const Cell * > & getCells()
Returns all cells.
const Cell * searchNode(const N *node) const
Search a node in the bottom cells (i.e., return the respective cell).
static Axis flip(Axis axis)
Returns the conjugated 2D axis.
const std::vector< const Cell * > & getCellsAtLevel(int level) const
Returns all cells of a level.
void init(const V *const vehicle)
Initialize the k-d tree wrt to the given vehicle's permissions.
size_t numberOfRegions() const
Returns the number of regions, i.e. the number of cells at the shallowest (bottom/leaf) level.
const Cell * getRoot() const
Returns the root of the k-d tree.
std::vector< const Cell * > myCells
int getNumberOfLevels() const
Returns the number of levels L incl. the zeroth level.
const bool myHaveRestrictions
~KDTreePartition()
Destructor.
const int myNumberOfLevels
Axis
Enum type for cell axis.
int numberOfArcFlags() const
Returns the number of arc flags required in a multi-level approach.
const Cell * cell(int number) const
Returns the cell with the given number.
size_t numberOfCells() const
Returns the number of cells at all levels.
bool isClean()
Returns true iff the k-d tree is uninitialized.
KDTreePartition(int numberOfLevels, const std::vector< E * > &edges, const bool havePermissions, const bool haveRestrictions)
Constructor.
std::vector< const N * > mySortedNodes