diff options
| author | vitalyisaev <[email protected]> | 2023-11-14 09:58:56 +0300 |
|---|---|---|
| committer | vitalyisaev <[email protected]> | 2023-11-14 10:20:20 +0300 |
| commit | c2b2dfd9827a400a8495e172a56343462e3ceb82 (patch) | |
| tree | cd4e4f597d01bede4c82dffeb2d780d0a9046bd0 /contrib/clickhouse/src/Functions/polygonsIntersection.cpp | |
| parent | d4ae8f119e67808cb0cf776ba6e0cf95296f2df7 (diff) | |
YQ Connector: move tests from yql to ydb (OSS)
Перенос папки с тестами на Коннектор из папки yql в папку ydb (синхронизируется с github).
Diffstat (limited to 'contrib/clickhouse/src/Functions/polygonsIntersection.cpp')
| -rw-r--r-- | contrib/clickhouse/src/Functions/polygonsIntersection.cpp | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/contrib/clickhouse/src/Functions/polygonsIntersection.cpp b/contrib/clickhouse/src/Functions/polygonsIntersection.cpp new file mode 100644 index 00000000000..84e5fe0d4b7 --- /dev/null +++ b/contrib/clickhouse/src/Functions/polygonsIntersection.cpp @@ -0,0 +1,124 @@ +#include <Functions/FunctionFactory.h> +#include <Functions/geometryConverters.h> + +#include <boost/geometry.hpp> +#include <boost/geometry/geometries/point_xy.hpp> +#include <boost/geometry/geometries/polygon.hpp> + +#include <Common/logger_useful.h> + +#include <Columns/ColumnArray.h> +#include <Columns/ColumnTuple.h> +#include <Columns/ColumnConst.h> +#include <DataTypes/DataTypeArray.h> +#include <DataTypes/DataTypeTuple.h> +#include <DataTypes/DataTypeCustomGeo.h> + +#include <memory> +#include <utility> +#include <chrono> + +namespace DB +{ + +namespace ErrorCodes +{ + extern const int ILLEGAL_TYPE_OF_ARGUMENT; +} + +template <typename Point> +class FunctionPolygonsIntersection : public IFunction +{ +public: + static inline const char * name; + + explicit FunctionPolygonsIntersection() = default; + + static FunctionPtr create(ContextPtr) + { + return std::make_shared<FunctionPolygonsIntersection>(); + } + + String getName() const override + { + return name; + } + + bool isVariadic() const override + { + return false; + } + + size_t getNumberOfArguments() const override + { + return 2; + } + + DataTypePtr getReturnTypeImpl(const DataTypes &) const override + { + /// Intersection of each with figure with each could be easily represent as MultiPolygon. + return DataTypeFactory::instance().get("MultiPolygon"); + } + + bool isSuitableForShortCircuitArgumentsExecution(const DataTypesWithConstInfo & /*arguments*/) const override { return true; } + + ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & /*result_type*/, size_t input_rows_count) const override + { + MultiPolygonSerializer<Point> serializer; + + callOnTwoGeometryDataTypes<Point>(arguments[0].type, arguments[1].type, [&](const auto & left_type, const auto & right_type) + { + using LeftConverterType = std::decay_t<decltype(left_type)>; + using RightConverterType = std::decay_t<decltype(right_type)>; + + using LeftConverter = typename LeftConverterType::Type; + using RightConverter = typename RightConverterType::Type; + + if constexpr (std::is_same_v<ColumnToPointsConverter<Point>, LeftConverter> || std::is_same_v<ColumnToPointsConverter<Point>, RightConverter>) + throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Any argument of function {} must not be Point", getName()); + else + { + auto first = LeftConverter::convert(arguments[0].column->convertToFullColumnIfConst()); + auto second = RightConverter::convert(arguments[1].column->convertToFullColumnIfConst()); + + /// We are not interested in some pitfalls in third-party libraries + /// NOLINTNEXTLINE(clang-analyzer-core.uninitialized.Assign) + for (size_t i = 0; i < input_rows_count; ++i) + { + /// Orient the polygons correctly. + boost::geometry::correct(first[i]); + boost::geometry::correct(second[i]); + + MultiPolygon<Point> intersection{}; + /// Main work here. + boost::geometry::intersection(first[i], second[i], intersection); + + serializer.add(intersection); + } + } + }); + + return serializer.finalize(); + } + + bool useDefaultImplementationForConstants() const override + { + return true; + } +}; + + +template <> +const char * FunctionPolygonsIntersection<CartesianPoint>::name = "polygonsIntersectionCartesian"; + +template <> +const char * FunctionPolygonsIntersection<SphericalPoint>::name = "polygonsIntersectionSpherical"; + + +REGISTER_FUNCTION(PolygonsIntersection) +{ + factory.registerFunction<FunctionPolygonsIntersection<CartesianPoint>>(); + factory.registerFunction<FunctionPolygonsIntersection<SphericalPoint>>(); +} + +} |
