2022-10-20 22:46:17 +08:00
|
|
|
#include "Database.h"
|
|
|
|
|
using namespace db;
|
|
|
|
|
|
|
|
|
|
/***** Rectangle *****/
|
|
|
|
|
|
|
|
|
|
Rectangle& Rectangle::operator+=(const Rectangle& geo) {
|
2024-06-05 16:11:25 +08:00
|
|
|
lx = std::min(lx, geo.lx);
|
|
|
|
|
ly = std::min(ly, geo.ly);
|
|
|
|
|
hx = std::max(hx, geo.hx);
|
|
|
|
|
hy = std::max(hy, geo.hy);
|
2022-10-20 22:46:17 +08:00
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Rectangle::sliceH(vector<Rectangle>& rects) {
|
|
|
|
|
// sort all bottom and top bounds
|
|
|
|
|
vector<int> ys;
|
|
|
|
|
for (const Rectangle& rect : rects) {
|
|
|
|
|
ys.push_back(rect.ly);
|
|
|
|
|
ys.push_back(rect.hy);
|
|
|
|
|
}
|
|
|
|
|
sort(ys.begin(), ys.end());
|
|
|
|
|
|
|
|
|
|
// remove duplicated values
|
|
|
|
|
ys.erase(unique(ys.begin(), ys.end()), ys.end());
|
|
|
|
|
|
|
|
|
|
// cut each rect with the y values
|
|
|
|
|
vector<Rectangle> slices;
|
|
|
|
|
for (const Rectangle& rect : rects) {
|
|
|
|
|
vector<int>::iterator yi = lower_bound(ys.begin(), ys.end(), rect.ly);
|
|
|
|
|
vector<int>::iterator ye = upper_bound(yi, ys.end(), rect.hy);
|
|
|
|
|
int lasty = *(yi++);
|
|
|
|
|
for (; yi != ye; yi++) {
|
|
|
|
|
slices.push_back(Rectangle(rect.lx, lasty, rect.hx, *yi));
|
|
|
|
|
lasty = *yi;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// merge overlapping rect
|
|
|
|
|
sort(slices.begin(), slices.end(), [](const Rectangle& a, const Rectangle& b) -> bool {
|
|
|
|
|
return a.ly == b.ly ? a.lx < b.lx : a.ly < b.ly;
|
|
|
|
|
});
|
|
|
|
|
for (int i = 1; i < (int)slices.size(); ++i) {
|
|
|
|
|
Rectangle& L = slices[i - 1];
|
|
|
|
|
Rectangle& R = slices[i];
|
|
|
|
|
if (L.ly != R.ly || L.hy != R.hy) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (L.hx >= R.lx) {
|
2024-06-05 16:11:25 +08:00
|
|
|
R.lx = std::min(L.lx, R.lx);
|
|
|
|
|
R.hx = std::max(L.hx, R.hx);
|
2022-10-20 22:46:17 +08:00
|
|
|
L.hx = L.lx;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// remove empty rects
|
|
|
|
|
vector<Rectangle>::iterator sEnd = remove_if(slices.begin(), slices.end(), Rectangle::IsInvalid);
|
|
|
|
|
if (sEnd != slices.end()) {
|
|
|
|
|
slices.resize(distance(slices.begin(), sEnd));
|
|
|
|
|
}
|
|
|
|
|
rects.swap(slices);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Rectangle::sliceV(vector<Rectangle>& rects) {
|
|
|
|
|
// sort all left and right bounds
|
|
|
|
|
vector<int> xs;
|
|
|
|
|
for (const Rectangle& rect : rects) {
|
|
|
|
|
xs.push_back(rect.lx);
|
|
|
|
|
xs.push_back(rect.hx);
|
|
|
|
|
}
|
|
|
|
|
sort(xs.begin(), xs.end());
|
|
|
|
|
|
|
|
|
|
// remove duplicated values
|
|
|
|
|
xs.erase(unique(xs.begin(), xs.end()), xs.end());
|
|
|
|
|
|
|
|
|
|
// cut each rect with the y values
|
|
|
|
|
vector<Rectangle> slices;
|
|
|
|
|
for (const Rectangle& rect : rects) {
|
|
|
|
|
vector<int>::iterator xi = lower_bound(xs.begin(), xs.end(), rect.lx);
|
|
|
|
|
vector<int>::iterator xe = upper_bound(xi, xs.end(), rect.hx);
|
|
|
|
|
int lastx = *(xi++);
|
|
|
|
|
for (; xi != xe; xi++) {
|
|
|
|
|
slices.push_back(Rectangle(lastx, rect.ly, *xi, rect.hy));
|
|
|
|
|
lastx = *xi;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// merge overlapping rect
|
|
|
|
|
sort(slices.begin(), slices.end(), [](const Rectangle& a, const Rectangle& b) -> bool {
|
|
|
|
|
return a.lx == b.lx ? a.ly < b.ly : a.lx < b.lx;
|
|
|
|
|
});
|
|
|
|
|
for (int i = 1; i < (int)slices.size(); ++i) {
|
|
|
|
|
Rectangle& L = slices[i - 1];
|
|
|
|
|
Rectangle& R = slices[i];
|
|
|
|
|
if (L.lx != R.lx || L.hx != R.hx) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (L.hy >= R.ly) {
|
2024-06-05 16:11:25 +08:00
|
|
|
R.ly = std::min(L.ly, R.ly);
|
|
|
|
|
R.hy = std::max(L.hy, R.hy);
|
2022-10-20 22:46:17 +08:00
|
|
|
L.hy = L.ly;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// remove empty rects
|
|
|
|
|
vector<Rectangle>::iterator sEnd = remove_if(slices.begin(), slices.end(), Rectangle::IsInvalid);
|
|
|
|
|
if (sEnd != slices.end()) {
|
|
|
|
|
slices.resize(distance(slices.begin(), sEnd));
|
|
|
|
|
}
|
|
|
|
|
rects.swap(slices);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/***** Geometry *****/
|
|
|
|
|
|
|
|
|
|
bool Geometry::operator==(const Geometry& rhs) const { return layer == rhs.layer && Rectangle::operator==(rhs); };
|
|
|
|
|
|
|
|
|
|
/***** GeoMap *****/
|
|
|
|
|
|
|
|
|
|
void GeoMap::emplace(const int k, const Geometry& shape) {
|
|
|
|
|
if (_map.find(k) == _map.end()) {
|
|
|
|
|
_map.emplace(k, shape);
|
|
|
|
|
} else {
|
|
|
|
|
_map.at(k) += shape;
|
|
|
|
|
}
|
|
|
|
|
Rectangle::operator+=(shape);
|
|
|
|
|
}
|
|
|
|
|
|