190 lines
6.4 KiB
C++
190 lines
6.4 KiB
C++
|
|
/*
|
||
|
|
1 JoinEdge struct
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
#include "JoinEdge.h"
|
||
|
|
|
||
|
|
using namespace cdacspatialjoin;
|
||
|
|
using namespace std;
|
||
|
|
|
||
|
|
void JoinEdge::removeCompleteRectangles(
|
||
|
|
const JoinEdgeVec& left1, const JoinEdgeVec& right2,
|
||
|
|
JoinEdgeVec& leftSpan, JoinEdgeVec& rightSpan,
|
||
|
|
JoinEdgeVec& leftRight, const bool isNotLastMerge,
|
||
|
|
const EdgeIndex_t resultEdgeStart, const EdgeIndex_t resultEdgeEnd) {
|
||
|
|
|
||
|
|
// get some values frequently used in the loops below
|
||
|
|
const size_t size1 = left1.size();
|
||
|
|
const size_t size2 = right2.size();
|
||
|
|
|
||
|
|
// initialize indices
|
||
|
|
size_t index1 = 0;
|
||
|
|
size_t index2 = 0;
|
||
|
|
|
||
|
|
// copy entries from both vectors in sort order as given by operator<
|
||
|
|
while (index1 < size1 && index2 < size2) {
|
||
|
|
const JoinEdge& edge1 = left1[index1];
|
||
|
|
const JoinEdge& edge2 = right2[index2];
|
||
|
|
if (edge1.yMin < edge2.yMin) {
|
||
|
|
// inline version of "if (result->containsCounterPartOf(edge1))":
|
||
|
|
const EdgeIndex_t counterPart = edge1.isLeftAndCounterPart &
|
||
|
|
JoinEdge::COUNTER_PART_MASK;
|
||
|
|
if (counterPart >= resultEdgeStart && counterPart < resultEdgeEnd) {
|
||
|
|
if (isNotLastMerge) // in the last merge, leftRight is obsolete
|
||
|
|
leftRight.push_back(edge1);
|
||
|
|
} else {
|
||
|
|
leftSpan.push_back(edge1);
|
||
|
|
}
|
||
|
|
++index1;
|
||
|
|
} else {
|
||
|
|
// inline version of "if (result->containsCounterPartOf(edge2))":
|
||
|
|
const EdgeIndex_t counterPart = edge2.isLeftAndCounterPart &
|
||
|
|
JoinEdge::COUNTER_PART_MASK;
|
||
|
|
if (counterPart >= resultEdgeStart && counterPart < resultEdgeEnd) {
|
||
|
|
// do nothing: the left counterpart is in left1
|
||
|
|
// and therefore was (or will be) added to leftRight
|
||
|
|
} else {
|
||
|
|
rightSpan.push_back(edge2);
|
||
|
|
}
|
||
|
|
++index2;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// copy the remaining entries from left1, if any
|
||
|
|
while (index1 < size1) {
|
||
|
|
const JoinEdge& edge1 = left1[index1];
|
||
|
|
// inline version of "if (result->containsCounterPartOf(edge1))":
|
||
|
|
const EdgeIndex_t counterPart = edge1.isLeftAndCounterPart &
|
||
|
|
JoinEdge::COUNTER_PART_MASK;
|
||
|
|
if (counterPart >= resultEdgeStart && counterPart < resultEdgeEnd) {
|
||
|
|
if (isNotLastMerge) // in the last merge, leftRight is obsolete
|
||
|
|
leftRight.push_back(edge1);
|
||
|
|
} else {
|
||
|
|
leftSpan.push_back(edge1);
|
||
|
|
}
|
||
|
|
++index1;
|
||
|
|
}
|
||
|
|
|
||
|
|
// copy the remaining entries from right2, if any
|
||
|
|
while (index2 < size2) {
|
||
|
|
const JoinEdge& edge2 = right2[index2];
|
||
|
|
// inline version of "if (result->containsCounterPartOf(edge2))":
|
||
|
|
const EdgeIndex_t counterPart = edge2.isLeftAndCounterPart &
|
||
|
|
JoinEdge::COUNTER_PART_MASK;
|
||
|
|
if (counterPart >= resultEdgeStart && counterPart < resultEdgeEnd) {
|
||
|
|
// do nothing: the left counterpart is in left1
|
||
|
|
// and therefore was (or will be) added to leftRight
|
||
|
|
} else {
|
||
|
|
rightSpan.push_back(edge2);
|
||
|
|
}
|
||
|
|
++index2;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void JoinEdge::merge(
|
||
|
|
const JoinEdgeVec& source1, const size_t startIndex1,
|
||
|
|
const JoinEdgeVec& source2, const size_t startIndex2,
|
||
|
|
JoinEdgeVec& dest) {
|
||
|
|
|
||
|
|
// get some values frequently used in the loops below
|
||
|
|
const size_t size1 = source1.size();
|
||
|
|
const size_t size2 = source2.size();
|
||
|
|
|
||
|
|
// initialize indices
|
||
|
|
size_t index1 = startIndex1;
|
||
|
|
size_t index2 = startIndex2;
|
||
|
|
// assert (index1 <= size1 && index2 <= size2);
|
||
|
|
|
||
|
|
// reserve space in dest vector
|
||
|
|
dest.reserve(dest.size() + size1 - index1 + size2 - index2);
|
||
|
|
|
||
|
|
// copy entries from both vectors in sort order as given by operator<
|
||
|
|
if (index1 < size1 && index2 < size2) {
|
||
|
|
double yMin1 = source1[index1].yMin;
|
||
|
|
double yMin2 = source2[index2].yMin;
|
||
|
|
do {
|
||
|
|
if (yMin1 < yMin2) {
|
||
|
|
dest.push_back(source1[index1]);
|
||
|
|
if (++index1 == size1)
|
||
|
|
break;
|
||
|
|
yMin1 = source1[index1].yMin;
|
||
|
|
} else {
|
||
|
|
dest.push_back(source2[index2]);
|
||
|
|
if (++index2 == size2)
|
||
|
|
break;
|
||
|
|
yMin2 = source2[index2].yMin;
|
||
|
|
}
|
||
|
|
} while(true);
|
||
|
|
}
|
||
|
|
|
||
|
|
// copy the remaining entries from one vector
|
||
|
|
if (index1 < size1) {
|
||
|
|
dest.insert(dest.end(), source1.begin() + index1, source1.end());
|
||
|
|
} else if (index2 < size2) {
|
||
|
|
dest.insert(dest.end(), source2.begin() + index2, source2.end());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void JoinEdge::merge(const JoinEdgeVec& source1,
|
||
|
|
const JoinEdgeVec& source2,
|
||
|
|
const JoinEdgeVec& source3,
|
||
|
|
JoinEdgeVec& dest) {
|
||
|
|
|
||
|
|
// get some values frequently used in the loops below
|
||
|
|
const size_t size1 = source1.size();
|
||
|
|
const size_t size2 = source2.size();
|
||
|
|
const size_t size3 = source3.size();
|
||
|
|
|
||
|
|
// initialize indices
|
||
|
|
size_t index1 = 0;
|
||
|
|
size_t index2 = 0;
|
||
|
|
size_t index3 = 0;
|
||
|
|
|
||
|
|
// reserve space in dest vector
|
||
|
|
dest.reserve(dest.size() + size1 + size2 + size3);
|
||
|
|
|
||
|
|
// copy entries from all three vectors in sort order as given by operator<
|
||
|
|
if (size1 != 0 && size2 != 0 && size3 != 0) {
|
||
|
|
// rather than using array access for each comparison
|
||
|
|
// "if (source1[index1].yMin < source2[index2].yMin)",
|
||
|
|
// yMin values are copied to local variables which are only updated
|
||
|
|
// when necessary (i.e. when index1 etc. changes)
|
||
|
|
double yMin1 = source1[index1].yMin;
|
||
|
|
double yMin2 = source2[index2].yMin;
|
||
|
|
double yMin3 = source3[index3].yMin;
|
||
|
|
do {
|
||
|
|
if (yMin1 < yMin2) {
|
||
|
|
if (yMin1 < yMin3) {
|
||
|
|
dest.push_back(source1[index1]);
|
||
|
|
if (++index1 == size1)
|
||
|
|
break;
|
||
|
|
yMin1 = source1[index1].yMin;
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
} else { // yMin2 <= yMin1
|
||
|
|
if (yMin2 < yMin3) {
|
||
|
|
dest.push_back(source2[index2]);
|
||
|
|
if (++index2 == size2)
|
||
|
|
break;
|
||
|
|
yMin2 = source2[index2].yMin;
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
// yMin3 is smallest
|
||
|
|
dest.push_back(source3[index3]);
|
||
|
|
if (++index3 == size3)
|
||
|
|
break;
|
||
|
|
yMin3 = source3[index3].yMin;
|
||
|
|
} while(true);
|
||
|
|
}
|
||
|
|
|
||
|
|
// copy entries from the remaining two vectors
|
||
|
|
if (index1 == size1)
|
||
|
|
merge(source2, index2, source3, index3, dest);
|
||
|
|
else if (index2 == size2)
|
||
|
|
merge(source1, index1, source3, index3, dest);
|
||
|
|
else
|
||
|
|
merge(source1, index1, source2, index2, dest);
|
||
|
|
}
|