From d7533367617597c252a4971c2da640f235799242 Mon Sep 17 00:00:00 2001 From: achulkov2 Date: Mon, 17 Feb 2020 22:42:39 +0300 Subject: [PATCH] More work --- .../Dictionaries/PolygonDictionaryUtils.cpp | 35 +++++++++---------- .../src/Dictionaries/PolygonDictionaryUtils.h | 19 +++++----- 2 files changed, 26 insertions(+), 28 deletions(-) diff --git a/dbms/src/Dictionaries/PolygonDictionaryUtils.cpp b/dbms/src/Dictionaries/PolygonDictionaryUtils.cpp index a060e291c1d..388071bd3f2 100644 --- a/dbms/src/Dictionaries/PolygonDictionaryUtils.cpp +++ b/dbms/src/Dictionaries/PolygonDictionaryUtils.cpp @@ -13,7 +13,7 @@ const ICell * FinalCell::find(Float64, Float64) const return this; } -DividedCell::DividedCell(std::vector children_): children(std::move(children_)) {} +DividedCell::DividedCell(std::vector> children_): children(std::move(children_)) {} const ICell * DividedCell::find(Float64 x, Float64 y) const { @@ -24,19 +24,19 @@ const ICell * DividedCell::find(Float64 x, Float64 y) const return children[x_bin + y_bin * GridRoot::kSplit]->find(x_ratio - x_bin, y_ratio - y_bin); } -GridRoot::GridRoot(const std::vector & polygons_): box(getBoundingBox(polygons_)), polygons(polygons_) +GridRoot::GridRoot(const size_t min_intersections_, const size_t max_depth_, const std::vector & polygons_): +kMinIntersections(min_intersections_), +kMaxDepth(max_depth_), +polygons(polygons_) { + setBoundingBox(); std::vector ids(polygons.size()); std::iota(ids.begin(), ids.end(), 0); - root = makeCell(box, ids); + root = makeCell(min_x, min_y, max_x, max_y, ids); } const ICell * GridRoot::find(Float64 x, Float64 y) const { - auto min_x = box.min_corner().get<0>(); - auto min_y = box.min_corner().get<1>(); - auto max_x = box.max_corner().get<0>(); - auto max_y = box.max_corner().get<1>(); if (x < min_x || x >= max_x) return nullptr; if (y < min_y || y >= max_y) @@ -44,34 +44,32 @@ const ICell * GridRoot::find(Float64 x, Float64 y) const return root->find((x - min_x) / (max_x - min_x), (y - min_y) / (max_y - min_y)); } -std::unique_ptr GridRoot::makeCell(const DB::Box & current_box, std::vector possible_ids, size_t depth) +std::unique_ptr GridRoot::makeCell(Float64 current_min_x, Float64 current_min_y, Float64 current_max_x, Float64 current_max_y, std::vector possible_ids, size_t depth) { ++depth; + auto current_box = Box(Point(current_min_x, current_min_y), Point(current_max_x, current_max_y)); possible_ids.erase(std::remove_if(possible_ids.begin(), possible_ids.end(), [&](const auto & id) { - return !bg::intersects(box, polygons[id]); + return !bg::intersects(current_box, polygons[id]); }), possible_ids.end()); if (possible_ids.size() <= kMinIntersections || depth == kMaxDepth) return std::make_unique(possible_ids); - auto min_x = current_box.min_corner().get<0>(); - auto min_y = current_box.min_corner().get<1>(); - auto x_shift = (current_box.max_corner().get<0>() - min_x) / kSplit; - auto y_shift = (current_box.max_corner().get<1>() - min_y) / kSplit; + auto x_shift = (current_max_x - current_min_x) / kSplit; + auto y_shift = (current_max_y - current_min_y) / kSplit; std::vector> children; children.reserve(kSplit * kSplit); - for (size_t i = 0; i < kSplit; min_x += x_shift, ++i) + for (size_t i = 0; i < kSplit; current_min_x += x_shift, ++i) { - for (size_t j = 0; j < kSplit; min_y += y_shift, ++j) + for (size_t j = 0; j < kSplit; current_min_y += y_shift, ++j) { - children.push_back(makeCell(Box(Point(min_x, min_y), Point(min_x + x_shift, min_y + y_shift)), possible_ids, depth + 1)); + children.push_back(makeCell(current_min_x, current_min_y, current_min_x + x_shift, current_min_y + y_shift, possible_ids, depth + 1)); } } return std::make_unique(children); } -Box GridRoot::getBoundingBox(const std::vector & polygons) +void GridRoot::setBoundingBox() { bool first = true; - Float64 min_x = 0, min_y = 0, max_x = 0, max_y = 0; std::for_each(polygons.begin(), polygons.end(), [&](const auto & polygon) { bg::for_each_point(polygon, [&](const Point & point) { auto x = point.get<0>(); @@ -87,7 +85,6 @@ Box GridRoot::getBoundingBox(const std::vector & polygons) first = false; }); }); - return Box(Point(min_x, min_y), Point(max_x, max_y)); } } \ No newline at end of file diff --git a/dbms/src/Dictionaries/PolygonDictionaryUtils.h b/dbms/src/Dictionaries/PolygonDictionaryUtils.h index 711da5a50f5..d193b9d8df9 100644 --- a/dbms/src/Dictionaries/PolygonDictionaryUtils.h +++ b/dbms/src/Dictionaries/PolygonDictionaryUtils.h @@ -29,8 +29,8 @@ public: class DividedCell : public ICell { public: - DividedCell(std::vector> children_); - const ICell * find(Float64 x, Float64 y) const override; + explicit DividedCell(std::vector> children_); + [[nodiscard]] const ICell * find(Float64 x, Float64 y) const override; private: std::vector> children; }; @@ -38,32 +38,33 @@ private: class FinalCell : public ICell { public: - FinalCell(std::vector polygon_ids_); + explicit FinalCell(std::vector polygon_ids_); private: std::vector polygon_ids; - const ICell * find(Float64 x, Float64 y) const override; + [[nodiscard]] const ICell * find(Float64 x, Float64 y) const override; }; class GridRoot : public ICell { public: - GridRoot(const std::vector & polygons_); - const ICell * find(Float64 x, Float64 y) const override; + explicit GridRoot(const size_t min_intersections_, const size_t max_depth_, const std::vector & polygons_); + [[nodiscard]] const ICell * find(Float64 x, Float64 y) const override; static constexpr size_t kSplit = 10; private: std::unique_ptr root = nullptr; - Box box; + Float64 min_x = 0, min_y = 0; + Float64 max_x = 0, max_y = 0; const size_t kMinIntersections = 3; const size_t kMaxDepth = 3; const std::vector & polygons; - std::unique_ptr makeCell(const Box & box, std::vector intersecting_ids, size_t depth = 0); + std::unique_ptr makeCell(Float64 min_x, Float64 min_y, Float64 max_x, Float64 max_y, std::vector intersecting_ids, size_t depth = 0); - static Box getBoundingBox(const std::vector & polygons); + void setBoundingBox(); }; } \ No newline at end of file