mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-22 09:40:49 +00:00
Add new files
This commit is contained in:
parent
ea13cc8964
commit
afb788310c
175
dbms/src/Dictionaries/PolygonDictionaryImplementations.cpp
Normal file
175
dbms/src/Dictionaries/PolygonDictionaryImplementations.cpp
Normal file
@ -0,0 +1,175 @@
|
||||
#include "PolygonDictionaryImplementations.h"
|
||||
#include "DictionaryFactory.h"
|
||||
#include <DataTypes/DataTypeArray.h>
|
||||
#include <DataTypes/DataTypeTuple.h>
|
||||
#include <DataTypes/DataTypesNumber.h>
|
||||
|
||||
#include <numeric>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
SimplePolygonDictionary::SimplePolygonDictionary(
|
||||
const std::string & database_,
|
||||
const std::string & name_,
|
||||
const DictionaryStructure & dict_struct_,
|
||||
DictionarySourcePtr source_ptr_,
|
||||
const DictionaryLifetime dict_lifetime_,
|
||||
InputType input_type_,
|
||||
PointType point_type_)
|
||||
: IPolygonDictionary(database_, name_, dict_struct_, std::move(source_ptr_), dict_lifetime_, input_type_, point_type_)
|
||||
{
|
||||
}
|
||||
|
||||
std::shared_ptr<const IExternalLoadable> SimplePolygonDictionary::clone() const
|
||||
{
|
||||
return std::make_shared<SimplePolygonDictionary>(
|
||||
this->database,
|
||||
this->name,
|
||||
this->dict_struct,
|
||||
this->source_ptr->clone(),
|
||||
this->dict_lifetime,
|
||||
this->input_type,
|
||||
this->point_type);
|
||||
}
|
||||
|
||||
bool SimplePolygonDictionary::find(const Point &point, size_t & id) const
|
||||
{
|
||||
bool found = false;
|
||||
double area = 0;
|
||||
for (size_t i = 0; i < polygons.size(); ++i)
|
||||
{
|
||||
if (bg::covered_by(point, polygons[i]))
|
||||
{
|
||||
double new_area = areas[i];
|
||||
if (!found || new_area < area)
|
||||
{
|
||||
found = true;
|
||||
id = i;
|
||||
area = new_area;
|
||||
}
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
GridPolygonDictionary::GridPolygonDictionary(
|
||||
const std::string & database_,
|
||||
const std::string & name_,
|
||||
const DictionaryStructure & dict_struct_,
|
||||
DictionarySourcePtr source_ptr_,
|
||||
const DictionaryLifetime dict_lifetime_,
|
||||
InputType input_type_,
|
||||
PointType point_type_):
|
||||
IPolygonDictionary(database_, name_, dict_struct_, std::move(source_ptr_), dict_lifetime_, input_type_, point_type_),
|
||||
grid(3, 5, 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
|
||||
{
|
||||
return std::make_shared<GridPolygonDictionary>(
|
||||
this->database,
|
||||
this->name,
|
||||
this->dict_struct,
|
||||
this->source_ptr->clone(),
|
||||
this->dict_lifetime,
|
||||
this->input_type,
|
||||
this->point_type);
|
||||
}
|
||||
|
||||
bool GridPolygonDictionary::find(const Point &point, size_t & id) const
|
||||
{
|
||||
bool found = false;
|
||||
auto cell = grid.find(point.get<0>(), point.get<1>());
|
||||
if (cell)
|
||||
{
|
||||
for (auto candidate : cell->polygon_ids)
|
||||
{
|
||||
if (bg::covered_by(point, polygons[candidate]))
|
||||
{
|
||||
found = true;
|
||||
id = candidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
template <class PolygonDictionary>
|
||||
DictionaryPtr createLayout(const std::string &,
|
||||
const DictionaryStructure & dict_struct,
|
||||
const Poco::Util::AbstractConfiguration & config,
|
||||
const std::string & config_prefix,
|
||||
DictionarySourcePtr source_ptr)
|
||||
{
|
||||
const String database = config.getString(config_prefix + ".database", "");
|
||||
const String name = config.getString(config_prefix + ".name");
|
||||
|
||||
if (!dict_struct.key)
|
||||
throw Exception{"'key' is required for a polygon dictionary", ErrorCodes::BAD_ARGUMENTS};
|
||||
if (dict_struct.key->size() != 1)
|
||||
throw Exception{"The 'key' should consist of a single attribute for a polygon dictionary",
|
||||
ErrorCodes::BAD_ARGUMENTS};
|
||||
IPolygonDictionary::InputType input_type;
|
||||
IPolygonDictionary::PointType point_type;
|
||||
const auto key_type = (*dict_struct.key)[0].type;
|
||||
const auto f64 = std::make_shared<DataTypeFloat64>();
|
||||
const auto multi_polygon_array = DataTypeArray(std::make_shared<DataTypeArray>(std::make_shared<DataTypeArray>(std::make_shared<DataTypeArray>(f64))));
|
||||
const auto multi_polygon_tuple = DataTypeArray(std::make_shared<DataTypeArray>(std::make_shared<DataTypeArray>(std::make_shared<DataTypeTuple>(std::vector<DataTypePtr>{f64, f64}))));
|
||||
const auto simple_polygon_array = DataTypeArray(std::make_shared<DataTypeArray>(f64));
|
||||
const auto simple_polygon_tuple = DataTypeArray(std::make_shared<DataTypeTuple>(std::vector<DataTypePtr>{f64, f64}));
|
||||
if (key_type->equals(multi_polygon_array))
|
||||
{
|
||||
input_type = IPolygonDictionary::InputType::MultiPolygon;
|
||||
point_type = IPolygonDictionary::PointType::Array;
|
||||
}
|
||||
else if (key_type->equals(multi_polygon_tuple))
|
||||
{
|
||||
input_type = IPolygonDictionary::InputType::MultiPolygon;
|
||||
point_type = IPolygonDictionary::PointType::Tuple;
|
||||
}
|
||||
else if (key_type->equals(simple_polygon_array))
|
||||
{
|
||||
input_type = IPolygonDictionary::InputType::SimplePolygon;
|
||||
point_type = IPolygonDictionary::PointType::Array;
|
||||
}
|
||||
else if (key_type->equals(simple_polygon_tuple))
|
||||
{
|
||||
input_type = IPolygonDictionary::InputType::SimplePolygon;
|
||||
point_type = IPolygonDictionary::PointType::Tuple;
|
||||
}
|
||||
else
|
||||
throw Exception{"The key type " + key_type->getName() +
|
||||
" is not one of the following allowed types for a polygon dictionary: " +
|
||||
multi_polygon_array.getName() + " " +
|
||||
multi_polygon_tuple.getName() + " " +
|
||||
simple_polygon_array.getName() + " " +
|
||||
simple_polygon_tuple.getName() + " ",
|
||||
ErrorCodes::BAD_ARGUMENTS};
|
||||
|
||||
if (dict_struct.range_min || dict_struct.range_max)
|
||||
throw Exception{name
|
||||
+ ": elements range_min and range_max should be defined only "
|
||||
"for a dictionary of layout 'range_hashed'",
|
||||
ErrorCodes::BAD_ARGUMENTS};
|
||||
|
||||
const DictionaryLifetime dict_lifetime{config, config_prefix + ".lifetime"};
|
||||
return std::make_unique<PolygonDictionary>(database, name, dict_struct, std::move(source_ptr), dict_lifetime, input_type, point_type);
|
||||
};
|
||||
|
||||
void registerDictionaryPolygon(DictionaryFactory & factory)
|
||||
{
|
||||
|
||||
factory.registerLayout("polygon", createLayout<SimplePolygonDictionary>, true);
|
||||
factory.registerLayout("grid-polygon", createLayout<GridPolygonDictionary>, true);
|
||||
}
|
||||
|
||||
}
|
52
dbms/src/Dictionaries/PolygonDictionaryImplementations.h
Normal file
52
dbms/src/Dictionaries/PolygonDictionaryImplementations.h
Normal file
@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
|
||||
#include "PolygonDictionary.h"
|
||||
#include "PolygonDictionaryUtils.h"
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
/** Simple implementation of the polygon dictionary. Doesn't generate anything during its construction.
|
||||
* Iterates over all stored polygons for each query, checking each of them in linear time.
|
||||
* Retrieves the polygon with the smallest area containing the given point. If there is more than one any such polygon
|
||||
* may be returned.
|
||||
*/
|
||||
class SimplePolygonDictionary : public IPolygonDictionary
|
||||
{
|
||||
public:
|
||||
SimplePolygonDictionary(
|
||||
const std::string & database_,
|
||||
const std::string & name_,
|
||||
const DictionaryStructure & dict_struct_,
|
||||
DictionarySourcePtr source_ptr_,
|
||||
DictionaryLifetime dict_lifetime_,
|
||||
InputType input_type_,
|
||||
PointType point_type_);
|
||||
|
||||
std::shared_ptr<const IExternalLoadable> clone() const override;
|
||||
|
||||
private:
|
||||
bool find(const Point & point, size_t & id) const override;
|
||||
};
|
||||
|
||||
class GridPolygonDictionary : public IPolygonDictionary
|
||||
{
|
||||
public:
|
||||
GridPolygonDictionary(
|
||||
const std::string & database_,
|
||||
const std::string & name_,
|
||||
const DictionaryStructure & dict_struct_,
|
||||
DictionarySourcePtr source_ptr_,
|
||||
DictionaryLifetime dict_lifetime_,
|
||||
InputType input_type_,
|
||||
PointType point_type_);
|
||||
|
||||
std::shared_ptr<const IExternalLoadable> clone() const override;
|
||||
|
||||
private:
|
||||
bool find(const Point & point, size_t & id) const override;
|
||||
|
||||
GridRoot grid;
|
||||
};
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user