ClickHouse

Форк
0
/
polygonsSymDifference.cpp 
122 строки · 3.6 Кб
1
#include <Functions/FunctionFactory.h>
2
#include <Functions/geometryConverters.h>
3

4
#include <boost/geometry.hpp>
5
#include <boost/geometry/geometries/point_xy.hpp>
6
#include <boost/geometry/geometries/polygon.hpp>
7

8
#include <Common/logger_useful.h>
9

10
#include <Columns/ColumnArray.h>
11
#include <Columns/ColumnTuple.h>
12
#include <Columns/ColumnConst.h>
13
#include <DataTypes/DataTypeArray.h>
14
#include <DataTypes/DataTypeTuple.h>
15
#include <DataTypes/DataTypeCustomGeo.h>
16

17
#include <memory>
18
#include <utility>
19

20
namespace DB
21
{
22

23
namespace ErrorCodes
24
{
25
    extern const int ILLEGAL_TYPE_OF_ARGUMENT;
26
}
27

28
namespace
29
{
30

31
template <typename Point>
32
class FunctionPolygonsSymDifference : public IFunction
33
{
34
public:
35
    static const char * name;
36

37
    explicit FunctionPolygonsSymDifference() = default;
38

39
    static FunctionPtr create(ContextPtr)
40
    {
41
        return std::make_shared<FunctionPolygonsSymDifference>();
42
    }
43

44
    String getName() const override
45
    {
46
        return name;
47
    }
48

49
    bool isVariadic() const override
50
    {
51
        return false;
52
    }
53

54
    size_t getNumberOfArguments() const override
55
    {
56
        return 2;
57
    }
58

59
    DataTypePtr getReturnTypeImpl(const DataTypes &) const override
60
    {
61
        return DataTypeFactory::instance().get("MultiPolygon");
62
    }
63

64
    bool isSuitableForShortCircuitArgumentsExecution(const DataTypesWithConstInfo & /*arguments*/) const override { return true; }
65

66
    ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & /*result_type*/, size_t input_rows_count) const override
67
    {
68
        MultiPolygonSerializer<Point> serializer;
69

70
        callOnTwoGeometryDataTypes<Point>(arguments[0].type, arguments[1].type, [&](const auto & left_type, const auto & right_type)
71
        {
72
            using LeftConverterType = std::decay_t<decltype(left_type)>;
73
            using RightConverterType = std::decay_t<decltype(right_type)>;
74

75
            using LeftConverter = typename LeftConverterType::Type;
76
            using RightConverter = typename RightConverterType::Type;
77

78
            if constexpr (std::is_same_v<ColumnToPointsConverter<Point>, LeftConverter> || std::is_same_v<ColumnToPointsConverter<Point>, RightConverter>)
79
                throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Any argument of function {} must not be Point", getName());
80
            else
81
            {
82
                auto first = LeftConverter::convert(arguments[0].column->convertToFullColumnIfConst());
83
                auto second = RightConverter::convert(arguments[1].column->convertToFullColumnIfConst());
84

85
                /// NOLINTNEXTLINE(clang-analyzer-core.uninitialized.Assign)
86
                for (size_t i = 0; i < input_rows_count; ++i)
87
                {
88
                    boost::geometry::correct(first[i]);
89
                    boost::geometry::correct(second[i]);
90

91
                    MultiPolygon<Point> sym_difference{};
92
                    boost::geometry::sym_difference(first[i], second[i], sym_difference);
93

94
                    serializer.add(sym_difference);
95
                }
96
            }
97
        });
98

99
        return serializer.finalize();
100
    }
101

102
    bool useDefaultImplementationForConstants() const override
103
    {
104
        return true;
105
    }
106
};
107

108
template <>
109
const char * FunctionPolygonsSymDifference<CartesianPoint>::name = "polygonsSymDifferenceCartesian";
110

111
template <>
112
const char * FunctionPolygonsSymDifference<SphericalPoint>::name = "polygonsSymDifferenceSpherical";
113

114
}
115

116
REGISTER_FUNCTION(PolygonsSymDifference)
117
{
118
    factory.registerFunction<FunctionPolygonsSymDifference<CartesianPoint>>();
119
    factory.registerFunction<FunctionPolygonsSymDifference<SphericalPoint>>();
120
}
121

122
}
123

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.