#pragma once
#include <config.h>
#include <memory>
#include <vector>
#include <unordered_set>
#include <math.h>
#include <cmath>
#include <limits>
#include <stdexcept>
#include <string>
#include <cinttypes>
#include <utility>
#include <utils/common/SUMOTime.h>
#include <utils/common/SUMOVehicleClass.h>
#include "KDTreePartition.h"
#include "Node2EdgeRouter.h"
#include "FlippedEdge.h"
#include "AFCentralizedSPTree.h"
#ifdef AFBU_WRITE_QGIS_FILTERS
#include <fstream>
#include <sstream>
#endif
#ifdef AFBU_DEBUG_LEVEL_2
#define AFBU_DEBUG_LEVEL_1
#endif
#ifdef AFBU_DEBUG_LEVEL_1
#define AFBU_DEBUG_LEVEL_0
#endif
#include <cassert>
template<class E, class N, class V, class M>
class AFRouter;
template<class E, class N, class V, class M>
class AFBuild {
public:
const double EPS = 0.009;
typedef typename KDTreePartition<FlippedEdge<E, N, V>, FlippedNode<E, N, V>, V>::Cell Cell;
typedef typename AFInfo<FlippedEdge<E, N, V>>::ArcInfo ArcInfo;
typedef typename AFInfo<E>::FlagInfo FlagInfo;
typedef AbstractLookupTable<FlippedEdge<E, N, V>, V> FlippedLookupTable;
AFBuild(
const std::vector<FlippedEdge<E, N, V>*>& flippedEdges,
const KDTreePartition<FlippedEdge<E, N, V>, FlippedNode<E, N, V>, V>* const flippedPartition,
int numberOfLevels, bool unbuildIsWarning,
typename SUMOAbstractRouter<FlippedEdge<E, N, V>, V>::Operation flippedOperation,
const std::shared_ptr<const FlippedLookupTable> flippedLookup = nullptr,
const bool havePermissions = false, const bool haveRestrictions = false,
const std::map<const FlippedEdge<E, N, V>*, double>* toProhibit = nullptr) :
myFlippedEdges(flippedEdges),
myFlippedPartition(flippedPartition),
myNumberOfLevels(numberOfLevels),
myErrorMsgHandler(unbuildIsWarning ? MsgHandler::getWarningInstance() : MsgHandler::getErrorInstance()),
myFlippedOperation(flippedOperation),
myFlippedLookupTable(flippedLookup),
myHavePermissions(havePermissions),
myHaveRestrictions(haveRestrictions),
myProhibited(toProhibit),
myNode2EdgeRouter(new Node2EdgeRouter<FlippedEdge<E, N, V>, FlippedNode<E, N, V>, V, M>(myFlippedEdges,
unbuildIsWarning, myFlippedOperation, myFlippedLookupTable, myHavePermissions, myHaveRestrictions)) {
myCentralizedSPTree = new AFCentralizedSPTree<FlippedEdge<E, N, V>, FlippedNode<E, N, V>, V>(myFlippedEdges,
myArcInfos, unbuildIsWarning, myNode2EdgeRouter, myHavePermissions, myHaveRestrictions);
if (toProhibit) {
myNode2EdgeRouter->prohibit(*toProhibit);
}
}
~AFBuild() {
delete myCentralizedSPTree;
delete myNode2EdgeRouter;
}
typename SUMOAbstractRouter<FlippedEdge<E, N, V>, V>::Operation getFlippedOperation() {
return myFlippedOperation;
}
const std::shared_ptr<const FlippedLookupTable> getFlippedLookup() {
return myFlippedLookupTable;
}
void init(SUMOTime time, const V* const vehicle, std::vector<FlagInfo*>& flagInfos);
void setFlippedPartition(const KDTreePartition<FlippedEdge<E, N, V>, FlippedNode<E, N, V>, V>* flippedPartition) {
myFlippedPartition = flippedPartition;
}
int partitionLevel2SHARCLevel(int partitionLevel) {
return AFRouter<E, N, V, M>::partitionLevel2SHARCLevel(partitionLevel, myNumberOfLevels);
}
int sHARCLevel2PartitionLevel(int sHARCLevel) {
return AFRouter<E, N, V, M>::sHARCLevel2PartitionLevel(sHARCLevel, myNumberOfLevels);
}
protected:
void computeArcFlags(SUMOTime msTime, int sHARCLevel, const V* const vehicle);
void computeArcFlags(SUMOTime msTime, const int sHARCLevel, const Cell* cell, const V* const vehicle);
void computeArcFlagsNaive(SUMOTime msTime, const int sHARCLevel, const Cell* cell, const V* const vehicle);
void putArcFlag(ArcInfo* arcInfo, const int sHARCLevel, const bool isLeftOrLowerCell);
const std::vector<FlippedEdge<E, N, V>*>& myFlippedEdges;
const KDTreePartition<FlippedEdge<E, N, V>, FlippedNode<E, N, V>, V>* myFlippedPartition;
const int myNumberOfLevels;
MsgHandler* const myErrorMsgHandler;
typename SUMOAbstractRouter<FlippedEdge<E, N, V>, V>::Operation myFlippedOperation;
const std::shared_ptr<const FlippedLookupTable> myFlippedLookupTable;
const bool myHavePermissions;
const bool myHaveRestrictions;
const std::map<const FlippedEdge<E, N, V>*, double>* myProhibited;
Node2EdgeRouter<FlippedEdge<E, N, V>, FlippedNode<E, N, V>, V, M>* myNode2EdgeRouter;
AFCentralizedSPTree<FlippedEdge<E, N, V>, FlippedNode<E, N, V>, V>* myCentralizedSPTree;
std::vector<ArcInfo*> myArcInfos;
private:
void initBoundaryEdges(const std::unordered_set<const FlippedEdge<E, N, V>*>& boundaryEdges);
void initSupercellEdges(const Cell* supercell,
const std::unordered_set<const FlippedEdge<E, N, V>*>& boundaryEdges,
size_t numberOfBoundaryNodes);
void computeArcFlagsAux(SUMOTime msTime, const int sHARCLevel, const Cell* cell, const V* const vehicle);
};
template<class E, class N, class V, class M>
void AFBuild<E, N, V, M>::init(SUMOTime msTime, const V* const vehicle, std::vector<FlagInfo*>& flagInfos) {
if (myArcInfos.empty()) {
for (const FlippedEdge<E, N, V>* const flippedEdge : myFlippedEdges) {
myArcInfos.push_back(new ArcInfo(flippedEdge));
}
}
int sHARCLevel;
for (sHARCLevel = 0; sHARCLevel < myNumberOfLevels - 1; sHARCLevel++) {
#ifdef AFBU_DEBUG_LEVEL_0
std::cout << "Starting computation of flags of level " << sHARCLevel << " (levels run from 0 to "
<< myNumberOfLevels - 2 << ")." << std::endl;
#endif
#ifdef AFBU_DEBUG_LEVEL_2
if (sHARCLevel != 0) {
continue;
}
#endif
computeArcFlags(msTime, sHARCLevel, vehicle);
}
#ifdef AFBU_DEBUG_LEVEL_0
std::cout << "Copying arc flags from the arc infos... " << std::endl;
#endif
int index = 0;
for (const ArcInfo* arcInfo : myArcInfos) {
flagInfos[index++]->arcFlags = arcInfo->arcFlags;
delete arcInfo;
}
#ifdef AFBU_DEBUG_LEVEL_0
std::cout << "Arc flags copied from the arc infos. " << std::endl;
#endif
myArcInfos.clear();
}
template<class E, class N, class V, class M>
void AFBuild<E, N, V, M>::computeArcFlags(SUMOTime msTime, const int sHARCLevel, const V* const vehicle) {
try {
assert(myFlippedPartition);
const std::vector<const Cell*>& levelCells = myFlippedPartition->getCellsAtLevel(sHARCLevel2PartitionLevel(sHARCLevel));
#ifdef AFBU_DEBUG_LEVEL_0
int i = 0;
#endif
for (const Cell* cell : levelCells) {
#ifdef AFBU_DEBUG_LEVEL_0
std::cout << "Starting to compute core flags of the " << i++ << "th cell..." << std::endl;
#endif
#ifdef AFBU_DEBUG_LEVEL_2
if (cell->getNumber() == 4) {
#endif
computeArcFlags(msTime, sHARCLevel, cell, vehicle);
#ifdef AFBU_DEBUG_LEVEL_0
std::cout << "Cleaning up after computeArcFlags..." << std::endl;
#endif
for (ArcInfo* arcInfo : myArcInfos) {
arcInfo->effortsToBoundaryNodes.clear();
arcInfo->touched = false;
}
#ifdef AFBU_DEBUG_LEVEL_0
std::cout << "Cleaned up." << std::endl;
#endif
#ifdef AFBU_DEBUG_LEVEL_2
}
#endif
}
} catch (const std::invalid_argument& e) {
std::cerr << "Exception: " << e.what() << std::endl;
exit(-1);
}
}
template<class E, class N, class V, class M>
void AFBuild<E, N, V, M>::computeArcFlagsNaive(SUMOTime msTime, const int sHARCLevel, const Cell* cell, const V* const vehicle) {
const Cell* supercell = cell->getSupercell();
const std::unordered_set<const FlippedEdge<E, N, V>*>& boundaryEdges = cell->getOutgoingBoundaryEdges();
const std::vector<const FlippedNode<E, N, V>*>& boundaryNodes = cell->getBoundaryFromNodes();
#ifdef AFBU_DEBUG_LEVEL_1
std::cout << "Number of boundary edges: " << boundaryEdges.size() << std::endl;
std::cout << "Number of boundary nodes: " << boundaryNodes.size() << std::endl;
std::cout << "Cell number: " << cell->getNumber() << std::endl;
std::cout << "Supercell number: " << supercell->getNumber() << std::endl;
#endif
initBoundaryEdges(boundaryEdges);
#ifdef AFBU_DEBUG_LEVEL_0
long long int startTime = SysUtils::getCurrentMillis();
#endif
for (const FlippedNode<E, N, V>* boundaryNode : boundaryNodes) {
for (const FlippedEdge<E, N, V>* boundaryEdge : boundaryEdges) {
assert(!boundaryEdge->isInternal());
ArcInfo* arcInfo = myArcInfos[boundaryEdge->getNumericalID()];
if (boundaryNode == boundaryEdge->getFromJunction()) {
arcInfo->effortsToBoundaryNodes.push_back(0.);
continue;
}
std::vector<const FlippedEdge<E, N, V>*> into;
#ifdef AFBU_DEBUG_LEVEL_2
std::vector<const FlippedEdge<E, N, V>*> into2;
#endif
if (myNode2EdgeRouter->computeNode2Edge(boundaryNode, boundaryEdge, vehicle, msTime, into)) {
double recomputedEffort = myNode2EdgeRouter->recomputeCostsNoLastEdge(into, vehicle, msTime);
arcInfo->effortsToBoundaryNodes.push_back(recomputedEffort);
#ifdef AFBU_DEBUG_LEVEL_2
if (!into.empty() && myNode2EdgeRouter->compute(into[0], boundaryEdge, vehicle, msTime, into2)) {
double recomputedEffort2 = myNode2EdgeRouter->recomputeCosts(into2, vehicle, msTime);
std::cout << "node2Edge router succeeded, effort: " << recomputedEffort << ", effort incl. last edge: " << recomputedEffort2 << std::endl;
assert(recomputedEffort <= recomputedEffort2);
}
#endif
} else {
arcInfo->effortsToBoundaryNodes.push_back(UNREACHABLE);
#ifdef AFBU_DEBUG_LEVEL_2
std::cout << "UNREACHABLE!" << std::endl;
#endif
}
}
}
#ifdef AFBU_DEBUG_LEVEL_0
long long int timeSpent = SysUtils::getCurrentMillis() - startTime;
std::cout << "Initial distance computation spent " + elapsedMs2string(timeSpent) + "." << std::endl;
#endif
initSupercellEdges(supercell, boundaryEdges, boundaryNodes.size());
#ifdef AFBU_DEBUG_LEVEL_0
std::cout << "Initialization of all supercell edges' labels and arc flag vectors done. Starting the centralized shortest path tree algorithm..." << std::endl;
#endif
if (myCentralizedSPTree->computeCentralizedSPTree(msTime, cell, vehicle)) {
computeArcFlagsAux(msTime, sHARCLevel, cell, vehicle);
}
#ifdef AFBU_DEBUG_LEVEL_0
std::cout << "Centralized shortest path tree algorithm finished." << std::endl;
#endif
}
template<class E, class N, class V, class M>
void AFBuild<E, N, V, M>::computeArcFlags(SUMOTime msTime, const int sHARCLevel, const Cell* cell, const V* const vehicle) {
const Cell* supercell = cell->getSupercell();
const std::unordered_set<const FlippedEdge<E, N, V>*>& boundaryEdges = cell->getOutgoingBoundaryEdges();
const std::vector<const FlippedNode<E, N, V>*>& boundaryNodes = cell->getBoundaryFromNodes();
#ifdef AFBU_DEBUG_LEVEL_1
std::cout << "Number of boundary edges: " << boundaryEdges.size() << std::endl;
std::cout << "Number of boundary nodes: " << boundaryNodes.size() << std::endl;
std::cout << "Cell number: " << cell->getNumber() << std::endl;
std::cout << "Supercell number: " << supercell->getNumber() << std::endl;
#endif
initBoundaryEdges(boundaryEdges);
#ifdef AFBU_DEBUG_LEVEL_1
long long int startTime = SysUtils::getCurrentMillis();
#endif
std::map<const FlippedEdge<E, N, V>*, std::vector<const FlippedEdge<E, N, V>*>> incomingEdgesOfOutgoingBoundaryEdges;
size_t numberOfBoundaryNodes = boundaryNodes.size();
for (const FlippedEdge<E, N, V>* boundaryEdge : boundaryEdges) {
incomingEdgesOfOutgoingBoundaryEdges[boundaryEdge] = std::vector<const FlippedEdge<E, N, V>*>(numberOfBoundaryNodes);
}
int index = 0;
for (const FlippedNode<E, N, V>* boundaryNode : boundaryNodes) {
myNode2EdgeRouter->reset(vehicle);
if (myNode2EdgeRouter->computeNode2Edges(boundaryNode, boundaryEdges, vehicle, msTime)) {
#ifdef AFBU_DEBUG_LEVEL_2
std::cout << "Node-to-edge router succeeded." << std::endl;
#endif
}
for (const FlippedEdge<E, N, V>* boundaryEdge : boundaryEdges) {
assert(!boundaryEdge->isInternal());
ArcInfo* arcInfo = myArcInfos[boundaryEdge->getNumericalID()];
if (boundaryNode == boundaryEdge->getFromJunction()) {
arcInfo->effortsToBoundaryNodes.push_back(0.);
(incomingEdgesOfOutgoingBoundaryEdges[boundaryEdge])[index] = nullptr;
continue;
}
double effort = (myNode2EdgeRouter->edgeInfo(boundaryEdge))->effort;
const FlippedEdge<E, N, V>* incomingEdge
= (myNode2EdgeRouter->edgeInfo(boundaryEdge))->prev ?
(myNode2EdgeRouter->edgeInfo(boundaryEdge))->prev->edge : nullptr;
(incomingEdgesOfOutgoingBoundaryEdges[boundaryEdge])[index] = incomingEdge;
arcInfo->effortsToBoundaryNodes.push_back(effort == std::numeric_limits<double>::max() ? UNREACHABLE : effort);
}
index++;
}
#ifdef AFBU_DEBUG_LEVEL_0
long long int timeSpent = SysUtils::getCurrentMillis() - startTime;
std::cout << "Initial distance computation spent " + elapsedMs2string(timeSpent) + "." << std::endl;
#endif
initSupercellEdges(supercell, boundaryEdges, boundaryNodes.size());
#ifdef AFBU_DEBUG_LEVEL_0
std::cout << "Initialization of all supercell edges' labels and arc flag vectors done. Starting the centralized shortest path tree algorithm..." << std::endl;
#endif
#ifdef AFBU_DEBUG_LEVEL_0
startTime = SysUtils::getCurrentMillis();
#endif
if (myCentralizedSPTree->computeCentralizedSPTree(msTime, cell, vehicle, incomingEdgesOfOutgoingBoundaryEdges)) {
#ifdef AFBU_DEBUG_LEVEL_0
timeSpent = SysUtils::getCurrentMillis() - startTime;
std::cout << "Centralized SP tree computation spent " + elapsedMs2string(timeSpent) + "." << std::endl;
#endif
computeArcFlagsAux(msTime, sHARCLevel, cell, vehicle);
}
#ifdef AFBU_DEBUG_LEVEL_0
std::cout << "Centralized shortest path tree algorithm finished." << std::endl;
#endif
}
template<class E, class N, class V, class M>
void AFBuild<E, N, V, M>::computeArcFlagsAux(SUMOTime msTime, const int sHARCLevel, const Cell* cell, const V* const vehicle) {
const Cell* supercell = cell->getSupercell();
std::pair<typename std::vector<const FlippedNode<E, N, V>*>::const_iterator,
typename std::vector<const FlippedNode<E, N, V>*>::const_iterator> supercellNodeIterators = supercell->nodeIterators();
typename std::vector<const FlippedNode<E, N, V>*>::const_iterator first = supercellNodeIterators.first;
typename std::vector<const FlippedNode<E, N, V>*>::const_iterator last = supercellNodeIterators.second;
typename std::vector<const FlippedNode<E, N, V>*>::const_iterator iter;
std::unordered_set<ArcInfo*> arcInfosOnAShortestPath;
#ifdef AFBU_DEBUG_LEVEL_1
int numberOfSupercellEdges = 0;
#endif
for (iter = first; iter != last; iter++) {
const std::vector<const FlippedEdge<E, N, V>*> incomingEdges = (*iter)->getIncoming();
for (const FlippedEdge<E, N, V>* supercellEdge : incomingEdges) {
if (supercellEdge->isInternal()) {
continue;
}
if ((myNode2EdgeRouter->edgeInfo(supercellEdge))->prohibited
|| myNode2EdgeRouter->isProhibited(supercellEdge, vehicle)) {
continue;
}
#ifdef AFBU_DEBUG_LEVEL_1
numberOfSupercellEdges++;
#endif
ArcInfo* supercellArcInfo = myArcInfos[supercellEdge->getNumericalID()];
arcInfosOnAShortestPath.insert(supercellArcInfo);
}
}
#ifdef AFBU_DEBUG_LEVEL_1
std::cout << "Number of supercell edges: " << numberOfSupercellEdges << std::endl;
#endif
const SUMOVehicleClass vClass = vehicle == 0 ? SVC_IGNORING : vehicle->getVClass();
#ifdef AFBU_DEBUG_LEVEL_1
std::cout << "Identifying shortest paths..." << std::endl;
#endif
#ifdef AFBU_DEBUG_LEVEL_0
long long int startTime = SysUtils::getCurrentMillis();
#endif
std::unordered_set<ArcInfo*> erasedEdges;
for (auto iter2 = arcInfosOnAShortestPath.begin(); iter2 != arcInfosOnAShortestPath.end();) {
const ArcInfo* arcInfo = *iter2;
assert(!arcInfo->edge->isInternal());
assert(myNode2EdgeRouter);
assert(!(myNode2EdgeRouter->edgeInfo(arcInfo->edge))->prohibited
&& !myNode2EdgeRouter->isProhibited(arcInfo->edge, vehicle));
size_t numberOfBoundaryNodes = arcInfo->effortsToBoundaryNodes.size();
size_t index;
bool onShortestPath = false;
for (index = 0; index < numberOfBoundaryNodes; index++) {
double effort1ToBoundaryNode = arcInfo->effortsToBoundaryNodes[index];
if (effort1ToBoundaryNode == UNREACHABLE) {
continue;
}
if (effort1ToBoundaryNode == std::numeric_limits<double>::max()) {
continue;
}
double sTime = STEPS2TIME(msTime);
double edgeEffort = myNode2EdgeRouter->getEffort(arcInfo->edge, vehicle, sTime);
sTime += myNode2EdgeRouter->getTravelTime(arcInfo->edge, vehicle, sTime, edgeEffort);
double oldEdgeEffort = edgeEffort;
double oldSTime = sTime;
for (const std::pair<const FlippedEdge<E, N, V>*, const FlippedEdge<E, N, V>*>& follower : arcInfo->edge->getViaSuccessors(vClass)) {
assert(!follower.first->isInternal());
ArcInfo* followerInfo = myArcInfos[follower.first->getNumericalID()];
if ((myNode2EdgeRouter->edgeInfo(follower.first))->prohibited
|| myNode2EdgeRouter->isProhibited(follower.first, vehicle)) {
myErrorMsgHandler->inform("Vehicle '" + Named::getIDSecure(vehicle) + "' is not allowed on source edge '" + followerInfo->edge->getID() + "'.");
continue;
}
if (followerInfo->effortsToBoundaryNodes.empty()) {
continue;
}
double effort2ToBoundaryNode = followerInfo->effortsToBoundaryNodes[index];
if (effort2ToBoundaryNode == UNREACHABLE) {
continue;
}
if (effort2ToBoundaryNode == std::numeric_limits<double>::max()) {
continue;
}
double length = 0.;
myNode2EdgeRouter->updateViaEdgeCost(follower.second, vehicle,
sTime , edgeEffort, length);
if (effort1ToBoundaryNode + edgeEffort
<= effort2ToBoundaryNode
+ EPS && effort1ToBoundaryNode + edgeEffort >= effort2ToBoundaryNode - EPS) {
onShortestPath = true;
break;
}
edgeEffort = oldEdgeEffort;
sTime = oldSTime;
}
}
if (!onShortestPath) {
erasedEdges.insert(*iter2);
iter2 = arcInfosOnAShortestPath.erase(iter2);
} else {
++iter2;
}
}
#ifdef AFBU_DEBUG_LEVEL_0
std::cout << "Edges clearly not on a shortest path have been removed. Number of edges on a shortest path is now: "
<< arcInfosOnAShortestPath.size() << std::endl;
#endif
std::unordered_set<const FlippedEdge<E, N, V>*>* pEdgesInsideCell = cell->edgeSet(vehicle);
std::unordered_set<const FlippedEdge<E, N, V>*> edgesInsideCell = *pEdgesInsideCell;
#ifdef AFBU_DEBUG_LEVEL_0
std::cout << "Adding all edges completely inside the cell to set of edges on a shortest path, cell no:"
<< cell->getNumber() << std::endl;
#endif
for (const FlippedEdge<E, N, V>* edgeInsideCell : edgesInsideCell) {
ArcInfo* arcInfo = myArcInfos[edgeInsideCell->getNumericalID()];
if ((myNode2EdgeRouter->edgeInfo(edgeInsideCell))->prohibited
|| myNode2EdgeRouter->isProhibited(edgeInsideCell, vehicle)) {
continue;
}
arcInfosOnAShortestPath.insert(arcInfo);
}
delete pEdgesInsideCell;
#ifdef AFBU_DEBUG_LEVEL_0
std::cout << "Edges inside cell added." << std::endl;
long long int timeSpent = SysUtils::getCurrentMillis() - startTime;
std::cout << "Shortest path identification spent " + elapsedMs2string(timeSpent) + "." << std::endl;
#endif
#ifdef AFBU_WRITE_QGIS_FILTERS
std::string qgisFilterString = "id IN (";
std::unordered_set<const FlippedNode<E, N, V>*> nodesOnAShortestPath;
std::unordered_set<const FlippedNode<E, N, V>*> erasedNodes;
for (const ArcInfo* arcInfo : arcInfosOnAShortestPath) {
assert(!(myNode2EdgeRouter->edgeInfo(arcInfo->edge))->prohibited
&& !myNode2EdgeRouter->isProhibited(arcInfo->edge, vehicle));
nodesOnAShortestPath.insert(arcInfo->edge->getFromJunction());
nodesOnAShortestPath.insert(arcInfo->edge->getToJunction());
}
for (const ArcInfo* erasedEdgeArcInfo : erasedEdges) {
erasedNodes.insert(erasedEdgeArcInfo->edge->getFromJunction());
erasedNodes.insert(erasedEdgeArcInfo->edge->getToJunction());
}
size_t k = 0;
size_t numberOfNodesOnAShortestPath = nodesOnAShortestPath.size();
for (const FlippedNode<E, N, V>* node : nodesOnAShortestPath) {
k++;
qgisFilterString += node->getID() + (k < numberOfNodesOnAShortestPath ? ", " : "");
}
qgisFilterString += ")";
std::ostringstream pathAndFileName;
pathAndFileName << "./filter_superset_nodes_cell_" << cell->getNumber() << "_supercell_" << supercell->getNumber() << ".qqf";
std::ofstream file;
file.open(pathAndFileName.str());
std::ostringstream content;
content << "<Query>" << qgisFilterString << "</Query>";
file << content.str();
file.close();
k = 0;
qgisFilterString.clear();
qgisFilterString = "id IN (";
size_t numberOfErasedNodes = erasedNodes.size();
for (const FlippedNode<E, N, V>* node : erasedNodes) {
k++;
qgisFilterString += node->getID() + (k < numberOfErasedNodes ? ", " : "");
}
qgisFilterString += ")";
pathAndFileName.str("");
pathAndFileName.clear();
pathAndFileName << "./filter_erased_nodes_cell_" << cell->getNumber() << "_supercell_" << supercell->getNumber() << ".qqf";
file.clear();
file.open(pathAndFileName.str());
content.str("");
content.clear();
content << "<Query>" << qgisFilterString << "</Query>";
file << content.str();
file.close();
#endif
for (ArcInfo* arcInfo : arcInfosOnAShortestPath) {
putArcFlag(arcInfo, sHARCLevel, cell->isLeftOrLowerCell());
}
}
template<class E, class N, class V, class M>
void AFBuild<E, N, V, M>::putArcFlag(ArcInfo* arcInfo, const int sHARCLevel, const bool isLeftOrLowerCell) {
assert(arcInfo);
(arcInfo->arcFlags)[sHARCLevel * 2 + (isLeftOrLowerCell ? 0 : 1)] = 1;
}
template<class E, class N, class V, class M>
void AFBuild<E, N, V, M>::initBoundaryEdges(const std::unordered_set<const FlippedEdge<E, N, V>*>& boundaryEdges) {
for (const FlippedEdge<E, N, V>* boundaryEdge : boundaryEdges) {
assert(!boundaryEdge->isInternal());
ArcInfo* arcInfo;
arcInfo = myArcInfos[boundaryEdge->getNumericalID()];
if (arcInfo->arcFlags.empty()) {
std::fill_n(std::back_inserter(arcInfo->arcFlags),
myFlippedPartition->numberOfArcFlags(), false);
}
arcInfo->effortsToBoundaryNodes.clear();
}
}
template<class E, class N, class V, class M>
void AFBuild<E, N, V, M>::initSupercellEdges(
const Cell* supercell,
const std::unordered_set<const FlippedEdge<E, N, V>*>& boundaryEdges,
size_t numberOfBoundaryNodes) {
std::pair<typename std::vector<const FlippedNode<E, N, V>*>::const_iterator,
typename std::vector<const FlippedNode<E, N, V>*>::const_iterator> supercellNodeIterators = supercell->nodeIterators();
typename std::vector<const FlippedNode<E, N, V>*>::const_iterator first = supercellNodeIterators.first;
typename std::vector<const FlippedNode<E, N, V>*>::const_iterator last = supercellNodeIterators.second;
typename std::vector<const FlippedNode<E, N, V>*>::const_iterator iter;
for (iter = first; iter != last; iter++) {
const std::vector<const FlippedEdge<E, N, V>*> incomingEdges = (*iter)->getIncoming();
for (const FlippedEdge<E, N, V>* supercellEdge : incomingEdges) {
if (supercellEdge->isInternal()) {
continue;
}
if (boundaryEdges.count(supercellEdge)) {
continue;
}
ArcInfo* supercellArcInfo;
supercellArcInfo = myArcInfos[supercellEdge->getNumericalID()];
if (supercellArcInfo->arcFlags.empty()) {
std::fill_n(std::back_inserter(supercellArcInfo->arcFlags),
myFlippedPartition->numberOfArcFlags(), false);
}
supercellArcInfo->effortsToBoundaryNodes.clear();
std::fill_n(std::back_inserter(supercellArcInfo->effortsToBoundaryNodes),
numberOfBoundaryNodes, std::numeric_limits<double>::max());
}
}
}