#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace DB { template class FunctionPolygonsIntersection : public IFunction { public: static inline const char * name; explicit FunctionPolygonsIntersection() = default; static FunctionPtr create(const Context &) { return std::make_shared(); } 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 { return DataTypeCustomMultiPolygonSerialization::nestedDataType(); } ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & /*result_type*/, size_t input_rows_count) const override { checkColumnTypeOrThrow(arguments[0]); auto first_parser = MultiPolygonFromColumnParser(std::move(arguments[0].column->convertToFullColumnIfConst())); checkColumnTypeOrThrow(arguments[1]); auto second_parser = MultiPolygonFromColumnParser(std::move(arguments[1].column->convertToFullColumnIfConst())); MultiPolygonSerializer serializer; MultiPolygon intersection{}; auto first = first_parser.parse(0, 0); auto second = second_parser.parse(0, 0); /// 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) { MultiPolygon first_container = first[i]; MultiPolygon second_container = second[i]; /// Orient the polygons correctly. boost::geometry::correct(first_container); boost::geometry::correct(second_container); /// Main work here. boost::geometry::intersection(first_container[0], second_container[0], intersection); serializer.add(intersection); } return serializer.finalize(); } bool useDefaultImplementationForConstants() const override { return true; } }; template <> const char * FunctionPolygonsIntersection::name = "polygonsIntersectionCartesian"; template <> const char * FunctionPolygonsIntersection::name = "polygonsIntersectionGeographic"; void registerFunctionPolygonsIntersection(FunctionFactory & factory) { factory.registerFunction>(); factory.registerFunction>(); } }