mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-27 20:20:49 +00:00
Polygons orderer by area
This commit is contained in:
parent
64cdf0577e
commit
16eaaba313
@ -222,12 +222,27 @@ void IPolygonDictionary::loadData()
|
|||||||
blockToAttributes(block);
|
blockToAttributes(block);
|
||||||
stream->readSuffix();
|
stream->readSuffix();
|
||||||
|
|
||||||
|
std::vector<double> areas;
|
||||||
areas.reserve(polygons.size());
|
areas.reserve(polygons.size());
|
||||||
for (auto & polygon : polygons)
|
|
||||||
{
|
std::vector<std::pair<Polygon, size_t>> polygon_ids;
|
||||||
|
polygon_ids.reserve(polygons.size());
|
||||||
|
for (size_t i = 0; i < polygons.size(); ++i) {
|
||||||
|
auto & polygon = polygons[i];
|
||||||
bg::correct(polygon);
|
bg::correct(polygon);
|
||||||
areas.push_back(bg::area(polygon));
|
areas.push_back(bg::area(polygon));
|
||||||
|
polygon_ids.emplace_back(polygon, i);
|
||||||
}
|
}
|
||||||
|
sort(polygon_ids.begin(), polygon_ids.end(), [& areas](const auto & lhs, const auto & rhs) {
|
||||||
|
return areas[lhs.second] < areas[rhs.second];
|
||||||
|
});
|
||||||
|
std::vector<size_t> correct_ids;
|
||||||
|
for (size_t i = 0; i < polygon_ids.size(); ++i) {
|
||||||
|
auto & polygon = polygon_ids[i];
|
||||||
|
correct_ids.emplace_back(ids[polygon.second]);
|
||||||
|
polygons[i] = polygon.first;
|
||||||
|
}
|
||||||
|
ids = correct_ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IPolygonDictionary::calculateBytesAllocated()
|
void IPolygonDictionary::calculateBytesAllocated()
|
||||||
|
@ -193,7 +193,6 @@ protected:
|
|||||||
virtual bool find(const Point & point, size_t & id) const = 0;
|
virtual bool find(const Point & point, size_t & id) const = 0;
|
||||||
|
|
||||||
std::vector<Polygon> polygons;
|
std::vector<Polygon> polygons;
|
||||||
std::vector<double> areas;
|
|
||||||
/** Since the original data may have been in the form of multi-polygons, an id is stored for each single polygon
|
/** Since the original data may have been in the form of multi-polygons, an id is stored for each single polygon
|
||||||
* corresponding to the row in which any other attributes for this entry are located.
|
* corresponding to the row in which any other attributes for this entry are located.
|
||||||
*/
|
*/
|
||||||
|
@ -39,18 +39,13 @@ std::shared_ptr<const IExternalLoadable> SimplePolygonDictionary::clone() const
|
|||||||
bool SimplePolygonDictionary::find(const Point &point, size_t & id) const
|
bool SimplePolygonDictionary::find(const Point &point, size_t & id) const
|
||||||
{
|
{
|
||||||
bool found = false;
|
bool found = false;
|
||||||
double area = 0;
|
|
||||||
for (size_t i = 0; i < polygons.size(); ++i)
|
for (size_t i = 0; i < polygons.size(); ++i)
|
||||||
{
|
{
|
||||||
if (bg::covered_by(point, polygons[i]))
|
if (bg::covered_by(point, polygons[i]))
|
||||||
{
|
{
|
||||||
double new_area = areas[i];
|
|
||||||
if (!found || new_area < area)
|
|
||||||
{
|
|
||||||
found = true;
|
|
||||||
id = i;
|
id = i;
|
||||||
area = new_area;
|
found = true;
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return found;
|
return found;
|
||||||
@ -65,16 +60,7 @@ GridPolygonDictionary::GridPolygonDictionary(
|
|||||||
InputType input_type_,
|
InputType input_type_,
|
||||||
PointType point_type_):
|
PointType point_type_):
|
||||||
IPolygonDictionary(database_, name_, dict_struct_, std::move(source_ptr_), dict_lifetime_, input_type_, point_type_),
|
IPolygonDictionary(database_, name_, dict_struct_, std::move(source_ptr_), dict_lifetime_, input_type_, point_type_),
|
||||||
grid(kMinIntersections, kMaxDepth, polygons)
|
grid(kMinIntersections, kMaxDepth, polygons) {}
|
||||||
{
|
|
||||||
std::vector<size_t> order(polygons.size());
|
|
||||||
std::iota(order.begin(), order.end(), 0);
|
|
||||||
std::sort(order.begin(), order.end(), [&](auto lhs, auto rhs)
|
|
||||||
{
|
|
||||||
return areas[lhs] < areas[rhs];
|
|
||||||
});
|
|
||||||
grid.init(order);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<const IExternalLoadable> GridPolygonDictionary::clone() const
|
std::shared_ptr<const IExternalLoadable> GridPolygonDictionary::clone() const
|
||||||
{
|
{
|
||||||
@ -119,13 +105,6 @@ SmartPolygonDictionary::SmartPolygonDictionary(
|
|||||||
: IPolygonDictionary(database_, name_, dict_struct_, std::move(source_ptr_), dict_lifetime_, input_type_, point_type_),
|
: IPolygonDictionary(database_, name_, dict_struct_, std::move(source_ptr_), dict_lifetime_, input_type_, point_type_),
|
||||||
grid(kMinIntersections, kMaxDepth, polygons)
|
grid(kMinIntersections, kMaxDepth, polygons)
|
||||||
{
|
{
|
||||||
std::vector<size_t> order(polygons.size());
|
|
||||||
std::iota(order.begin(), order.end(), 0);
|
|
||||||
std::sort(order.begin(), order.end(), [&](auto lhs, auto rhs)
|
|
||||||
{
|
|
||||||
return areas[lhs] < areas[rhs];
|
|
||||||
});
|
|
||||||
grid.init(order);
|
|
||||||
auto log = &Logger::get("BucketsPolygonIndex");
|
auto log = &Logger::get("BucketsPolygonIndex");
|
||||||
buckets.reserve(polygons.size());
|
buckets.reserve(polygons.size());
|
||||||
for (size_t i = 0; i < polygons.size(); ++i)
|
for (size_t i = 0; i < polygons.size(); ++i)
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
#include <numeric>
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
@ -38,12 +39,11 @@ const FinalCell * DividedCell::find(Float64 x, Float64 y) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
GridRoot::GridRoot(const size_t min_intersections_, const size_t max_depth_, const std::vector<Polygon> & polygons_):
|
GridRoot::GridRoot(const size_t min_intersections_, const size_t max_depth_, const std::vector<Polygon> & polygons_):
|
||||||
kMinIntersections(min_intersections_), kMaxDepth(max_depth_), polygons(polygons_) {}
|
kMinIntersections(min_intersections_), kMaxDepth(max_depth_), polygons(polygons_) {
|
||||||
|
|
||||||
void GridRoot::init(const std::vector<size_t> & order_)
|
|
||||||
{
|
|
||||||
setBoundingBox();
|
setBoundingBox();
|
||||||
root = makeCell(min_x, min_y, max_x, max_y, order_);
|
std::vector<size_t> order(polygons.size());
|
||||||
|
std::iota(order.begin(), order.end(), 0);
|
||||||
|
root = makeCell(min_x, min_y, max_x, max_y, order);
|
||||||
}
|
}
|
||||||
|
|
||||||
const FinalCell * GridRoot::find(Float64 x, Float64 y) const
|
const FinalCell * GridRoot::find(Float64 x, Float64 y) const
|
||||||
|
@ -60,10 +60,6 @@ class GridRoot : public ICell
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GridRoot(size_t min_intersections_, size_t max_depth_, const std::vector<Polygon> & polygons_);
|
GridRoot(size_t min_intersections_, size_t max_depth_, const std::vector<Polygon> & polygons_);
|
||||||
/** Initializes and builds the grid, saving the intersecting polygons for each cell accordingly.
|
|
||||||
* The order of indexes is always a subsequence of the order specified in this function call.
|
|
||||||
*/
|
|
||||||
void init(const std::vector<size_t> & order_);
|
|
||||||
/** Retrieves the cell containing a given point.
|
/** Retrieves the cell containing a given point.
|
||||||
* A null pointer is returned when the point falls outside the grid.
|
* A null pointer is returned when the point falls outside the grid.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user