From 835b4d65b051749d7bc09bb1b1cef728b3a38228 Mon Sep 17 00:00:00 2001 From: Arthur Petukhovsky Date: Thu, 14 May 2020 02:20:06 +0300 Subject: [PATCH] Create float type Coord --- dbms/src/Dictionaries/PolygonDictionary.cpp | 4 +- dbms/src/Dictionaries/PolygonDictionary.h | 4 +- .../Dictionaries/PolygonDictionaryUtils.cpp | 40 +++++++++---------- .../src/Dictionaries/PolygonDictionaryUtils.h | 33 +++++++-------- 4 files changed, 39 insertions(+), 42 deletions(-) diff --git a/dbms/src/Dictionaries/PolygonDictionary.cpp b/dbms/src/Dictionaries/PolygonDictionary.cpp index a5027f88ebf..79f821a70a6 100644 --- a/dbms/src/Dictionaries/PolygonDictionary.cpp +++ b/dbms/src/Dictionaries/PolygonDictionary.cpp @@ -528,7 +528,7 @@ struct Data ids.push_back((ids.empty() ? 0 : ids.back() + new_multi_polygon)); } - void addPoint(Float64 x, Float64 y) + void addPoint(IPolygonDictionary::Coord x, IPolygonDictionary::Coord y) { auto & last_polygon = dest.back(); auto & last_ring = (last_polygon.inners().empty() ? last_polygon.outer() : last_polygon.inners().back()); @@ -536,7 +536,7 @@ struct Data } }; -void addNewPoint(Float64 x, Float64 y, Data & data, Offset & offset) +void addNewPoint(IPolygonDictionary::Coord x, IPolygonDictionary::Coord y, Data & data, Offset & offset) { if (offset.atLastPointOfRing()) { diff --git a/dbms/src/Dictionaries/PolygonDictionary.h b/dbms/src/Dictionaries/PolygonDictionary.h index 1951bef2de1..69dff07df37 100644 --- a/dbms/src/Dictionaries/PolygonDictionary.h +++ b/dbms/src/Dictionaries/PolygonDictionary.h @@ -178,8 +178,10 @@ public: // TODO: Refactor the whole dictionary design to perform stronger checks, i.e. make this an override. void has(const Columns & key_columns, const DataTypes & key_types, PaddedPODArray & out) const; + /** Single coordinate type. */ + using Coord = Float32; /** A two-dimensional point in Euclidean coordinates. */ - using Point = bg::model::d2::point_xy; + using Point = bg::model::d2::point_xy; /** A polygon in boost is a an outer ring of points with zero or more cut out inner rings. */ using Polygon = bg::model::polygon; /** A ring in boost used for describing the polygons. */ diff --git a/dbms/src/Dictionaries/PolygonDictionaryUtils.cpp b/dbms/src/Dictionaries/PolygonDictionaryUtils.cpp index 49b807fe7ba..43ff7344f04 100644 --- a/dbms/src/Dictionaries/PolygonDictionaryUtils.cpp +++ b/dbms/src/Dictionaries/PolygonDictionaryUtils.cpp @@ -22,14 +22,14 @@ polygon_ids(std::move(polygon_ids_)) }); } -const FinalCell * FinalCell::find(Float64, Float64) const +const FinalCell * FinalCell::find(Coord, Coord) const { return this; } DividedCell::DividedCell(std::vector> children_): children(std::move(children_)) {} -const FinalCell * DividedCell::find(Float64 x, Float64 y) const +const FinalCell * DividedCell::find(Coord x, Coord y) const { auto x_ratio = x * GridRoot::kSplit; auto y_ratio = y * GridRoot::kSplit; @@ -47,7 +47,7 @@ kMinIntersections(min_intersections_), kMaxDepth(max_depth_), polygons(polygons_ root = makeCell(min_x, min_y, max_x, max_y, order); } -const FinalCell * GridRoot::find(Float64 x, Float64 y) const +const FinalCell * GridRoot::find(Coord x, Coord y) const { if (x < min_x || x >= max_x) return nullptr; @@ -56,7 +56,7 @@ const FinalCell * 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(Float64 current_min_x, Float64 current_min_y, Float64 current_max_x, Float64 current_max_y, std::vector possible_ids, size_t depth) +std::unique_ptr GridRoot::makeCell(Coord current_min_x, Coord current_min_y, Coord current_max_x, Coord current_max_y, std::vector possible_ids, size_t 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) @@ -72,7 +72,7 @@ std::unique_ptr GridRoot::makeCell(Float64 current_min_x, Float64 current std::vector threads; for (size_t i = 0; i < kSplit; current_min_x += x_shift, ++i) { - auto handle_row = [this, &children, &y_shift, &x_shift, &possible_ids, &depth, i](Float64 x, Float64 y) + auto handle_row = [this, &children, &y_shift, &x_shift, &possible_ids, &depth, i](Coord x, Coord y) { for (size_t j = 0; j < kSplit; y += y_shift, ++j) { @@ -114,7 +114,7 @@ void GridRoot::setBoundingBox() BucketsPolygonIndex::BucketsPolygonIndex( const std::vector & polygons, - const std::vector & splits) + const std::vector & splits) : log(&Logger::get("BucketsPolygonIndex")), sorted_x(splits) { @@ -129,9 +129,9 @@ BucketsPolygonIndex::BucketsPolygonIndex( indexBuild(polygons); } -std::vector BucketsPolygonIndex::uniqueX(const std::vector & polygons) +std::vector BucketsPolygonIndex::uniqueX(const std::vector & polygons) { - std::vector all_x; + std::vector all_x; for (size_t i = 0; i < polygons.size(); ++i) { for (auto & point : polygons[i].outer()) @@ -203,8 +203,8 @@ void BucketsPolygonIndex::indexBuild(const std::vector & polygons) size_t edges_it = 0; for (size_t l = 0, r = 1; r < this->sorted_x.size(); ++l, ++r) { - const Float64 lx = this->sorted_x[l]; - const Float64 rx = this->sorted_x[r]; + const Coord lx = this->sorted_x[l]; + const Coord rx = this->sorted_x[r]; /** removing edges where right_point.x < lx */ while (!interesting_edges.empty() && interesting_edges.begin()->r.x() < lx) @@ -347,8 +347,8 @@ bool BucketsPolygonIndex::find(const Point & point, size_t & id) const return false; } - Float64 x = point.x(); - Float64 y = point.y(); + Coord x = point.x(); + Coord y = point.y(); if (x < this->sorted_x[0] || x > this->sorted_x.back()) { @@ -391,7 +391,7 @@ bool BucketsPolygonIndex::find(const Point & point, size_t & id) const continue; } - Float64 edge_y = l.y() + (r.y() - l.y()) / (r.x() - l.x()) * (x - l.x()); + Coord edge_y = l.y() + (r.y() - l.y()) / (r.x() - l.x()) * (x - l.x()); if (edge_y > y) { continue; @@ -427,9 +427,9 @@ BucketsSinglePolygonIndex::BucketsSinglePolygonIndex( indexBuild(polygon); } -std::vector BucketsSinglePolygonIndex::uniqueX(const Polygon & polygon) +std::vector BucketsSinglePolygonIndex::uniqueX(const Polygon & polygon) { - std::vector all_x; + std::vector all_x; for (auto & point : polygon.outer()) { @@ -492,8 +492,8 @@ void BucketsSinglePolygonIndex::indexBuild(const Polygon & polygon) size_t edges_it = 0; for (size_t l = 0, r = 1; r < this->sorted_x.size(); ++l, ++r) { - const Float64 lx = this->sorted_x[l]; - const Float64 rx = this->sorted_x[r]; + const Coord lx = this->sorted_x[l]; + const Coord rx = this->sorted_x[r]; /** removing edges where right_point.x < lx */ while (!interesting_edges.empty() && interesting_edges.begin()->r.x() < lx) @@ -607,8 +607,8 @@ bool BucketsSinglePolygonIndex::find(const Point & point) const return false; } - Float64 x = point.x(); - Float64 y = point.y(); + Coord x = point.x(); + Coord y = point.y(); if (x < this->sorted_x[0] || x > this->sorted_x.back()) { @@ -644,7 +644,7 @@ bool BucketsSinglePolygonIndex::find(const Point & point) const continue; } - Float64 edge_y = l.y() + (r.y() - l.y()) / (r.x() - l.x()) * (x - l.x()); + Coord edge_y = l.y() + (r.y() - l.y()) / (r.x() - l.x()) * (x - l.x()); if (edge_y > y) { continue; diff --git a/dbms/src/Dictionaries/PolygonDictionaryUtils.h b/dbms/src/Dictionaries/PolygonDictionaryUtils.h index ddc17c28894..597c0742f87 100644 --- a/dbms/src/Dictionaries/PolygonDictionaryUtils.h +++ b/dbms/src/Dictionaries/PolygonDictionaryUtils.h @@ -15,8 +15,10 @@ namespace DB namespace bg = boost::geometry; +using Coord = IPolygonDictionary::Coord; using Point = IPolygonDictionary::Point; using Polygon = IPolygonDictionary::Polygon; +using Ring = IPolygonDictionary::Ring; using Box = bg::model::box; class FinalCell; @@ -25,14 +27,14 @@ class ICell { public: virtual ~ICell() = default; - [[nodiscard]] virtual const FinalCell * find(Float64 x, Float64 y) const = 0; + [[nodiscard]] virtual const FinalCell * find(Coord x, Coord y) const = 0; }; class DividedCell : public ICell { public: explicit DividedCell(std::vector> children_); - [[nodiscard]] const FinalCell * find(Float64 x, Float64 y) const override; + [[nodiscard]] const FinalCell * find(Coord x, Coord y) const override; private: std::vector> children; @@ -46,7 +48,7 @@ public: std::vector is_covered_by; private: - [[nodiscard]] const FinalCell * find(Float64 x, Float64 y) const override; + [[nodiscard]] const FinalCell * find(Coord x, Coord y) const override; }; /** A recursively built grid containing information about polygons intersecting each cell. @@ -63,7 +65,7 @@ public: /** Retrieves the cell containing a given point. * A null pointer is returned when the point falls outside the grid. */ - [[nodiscard]] const FinalCell * find(Float64 x, Float64 y) const override; + [[nodiscard]] const FinalCell * find(Coord x, Coord y) const override; /** When a cell is split every side is split into kSplit pieces producing kSplit * kSplit equal smaller cells. */ static constexpr size_t kSplit = 4; @@ -71,14 +73,14 @@ public: private: std::unique_ptr root = nullptr; - Float64 min_x = 0, min_y = 0; - Float64 max_x = 0, max_y = 0; + Coord min_x = 0, min_y = 0; + Coord max_x = 0, max_y = 0; const size_t kMinIntersections; const size_t kMaxDepth; const std::vector & polygons; - std::unique_ptr makeCell(Float64 min_x, Float64 min_y, Float64 max_x, Float64 max_y, std::vector intersecting_ids, size_t depth = 0); + std::unique_ptr makeCell(Coord min_x, Coord min_y, Coord max_x, Coord max_y, std::vector intersecting_ids, size_t depth = 0); void setBoundingBox(); }; @@ -99,7 +101,7 @@ public: using Ring = IPolygonDictionary::Ring; /** Builds an index by splitting all edges with provided sorted x coordinates. */ - BucketsPolygonIndex(const std::vector & polygons, const std::vector & splits); + BucketsPolygonIndex(const std::vector & polygons, const std::vector & splits); /** Builds an index by splitting all edges with all points x coordinates. */ BucketsPolygonIndex(const std::vector & polygons); @@ -109,7 +111,7 @@ public: private: /** Returns unique x coordinates among all points. */ - std::vector uniqueX(const std::vector & polygons); + std::vector uniqueX(const std::vector & polygons); /** Builds indexes described above. */ void indexBuild(const std::vector & polygons); @@ -134,7 +136,7 @@ private: Poco::Logger * log; /** Sorted distinct coordinates of all vertexes. */ - std::vector sorted_x; + std::vector sorted_x; std::vector all_edges; /** Edges from all polygons, classified by sorted_x borders. @@ -163,13 +165,6 @@ private: class BucketsSinglePolygonIndex { public: - /** A two-dimensional point in Euclidean coordinates. */ - using Point = IPolygonDictionary::Point; - /** A polygon in boost is a an outer ring of points with zero or more cut out inner rings. */ - using Polygon = IPolygonDictionary::Polygon; - /** A ring in boost used for describing the polygons. */ - using Ring = IPolygonDictionary::Ring; - /** Builds an index by splitting all edges with all points x coordinates. */ BucketsSinglePolygonIndex(const Polygon & polygon); @@ -178,7 +173,7 @@ public: private: /** Returns unique x coordinates among all points. */ - std::vector uniqueX(const Polygon & polygon); + std::vector uniqueX(const Polygon & polygon); /** Builds indexes described above. */ void indexBuild(const Polygon & polygon); @@ -207,7 +202,7 @@ private: }; /** Sorted distinct coordinates of all vertexes. */ - std::vector sorted_x; + std::vector sorted_x; std::vector all_edges; /** Edges from all polygons, classified by sorted_x borders.