From 9646bb0c91b07eb508c59046c47119afe6d72ffa Mon Sep 17 00:00:00 2001 From: bharatnc Date: Sun, 13 Feb 2022 09:52:59 -0800 Subject: [PATCH] add func h3PointDistRads --- src/Functions/h3PointDistRads.cpp | 129 +++++++++++++++++++++++++ src/Functions/registerFunctionsGeo.cpp | 2 + 2 files changed, 131 insertions(+) create mode 100644 src/Functions/h3PointDistRads.cpp diff --git a/src/Functions/h3PointDistRads.cpp b/src/Functions/h3PointDistRads.cpp new file mode 100644 index 00000000000..8b2cee2ed06 --- /dev/null +++ b/src/Functions/h3PointDistRads.cpp @@ -0,0 +1,129 @@ +#include "config_functions.h" + +#if USE_H3 + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + +namespace DB +{ +namespace ErrorCodes +{ +extern const int ILLEGAL_TYPE_OF_ARGUMENT; +extern const int ILLEGAL_COLUMN; +} + +namespace +{ + +class FunctionH3PointDistRads final : public IFunction +{ +public: + static constexpr auto name = "h3PointDistRads"; + + static FunctionPtr create(ContextPtr) { return std::make_shared(); } + + std::string getName() const override { return name; } + + size_t getNumberOfArguments() const override { return 4; } + bool useDefaultImplementationForConstants() const override { return true; } + bool isSuitableForShortCircuitArgumentsExecution(const DataTypesWithConstInfo & /*arguments*/) const override { return false; } + + DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override + { + for (size_t i = 0; i < getNumberOfArguments(); ++i) + { + const auto * arg = arguments[i].get(); + if (!WhichDataType(arg).isFloat64()) + throw Exception( + ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, + "Illegal type {} of argument {} of function {}. Must be Float64", + arg->getName(), i, getName()); + } + return std::make_shared(); + } + + ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override + { + const auto * col_lat1 = checkAndGetColumn(arguments[0].column.get()); + if (!col_lat1) + throw Exception( + ErrorCodes::ILLEGAL_COLUMN, + "Illegal type {} of argument {} of function {}. Must be Float64", + arguments[0].type->getName(), + 1, + getName()); + const auto & data_lat1 = col_lat1->getData(); + + const auto * col_lon1 = checkAndGetColumn(arguments[1].column.get()); + if (!col_lon1) + throw Exception( + ErrorCodes::ILLEGAL_COLUMN, + "Illegal type {} of argument {} of function {}. Must be Float64", + arguments[1].type->getName(), + 2, + getName()); + const auto & data_lon1 = col_lon1->getData(); + + const auto * col_lat2 = checkAndGetColumn(arguments[2].column.get()); + if (!col_lat2) + throw Exception( + ErrorCodes::ILLEGAL_COLUMN, + "Illegal type {} of argument {} of function {}. Must be Float64", + arguments[2].type->getName(), + 3, + getName()); + const auto & data_lat2 = col_lat2->getData(); + + const auto * col_lon2 = checkAndGetColumn(arguments[3].column.get()); + if (!col_lon2) + throw Exception( + ErrorCodes::ILLEGAL_COLUMN, + "Illegal type {} of argument {} of function {}. Must be Float64", + arguments[3].type->getName(), + 4, + getName()); + const auto & data_lon2 = col_lon2->getData(); + + auto dst = ColumnVector::create(); + auto & dst_data = dst->getData(); + dst_data.resize(input_rows_count); + + for (size_t row = 0; row < input_rows_count; ++row) + { + const double lat1 = data_lat1[row]; + const double lon1 = data_lon1[row]; + const auto lat2 = data_lat2[row]; + const auto lon2 = data_lon2[row]; + + LatLng point1 = {degsToRads(lat1), degsToRads(lon1)}; + LatLng point2 = {degsToRads(lat2), degsToRads(lon2)}; + + Float64 res = distanceRads(&point1, &point2); + dst_data[row] = res; + } + + return dst; + } +}; + +} + +void registerFunctionH3PointDistRads(FunctionFactory & factory) +{ + factory.registerFunction(); +} + +} + +#endif diff --git a/src/Functions/registerFunctionsGeo.cpp b/src/Functions/registerFunctionsGeo.cpp index fa73cb7e2ad..8de5dcf1ff3 100644 --- a/src/Functions/registerFunctionsGeo.cpp +++ b/src/Functions/registerFunctionsGeo.cpp @@ -54,6 +54,7 @@ void registerFunctionH3CellAreaRads2(FunctionFactory &); void registerFunctionH3NumHexagons(FunctionFactory &); void registerFunctionH3PointDistM(FunctionFactory &); void registerFunctionH3PointDistKm(FunctionFactory &); +void registerFunctionH3PointDistRads(FunctionFactory &); #endif @@ -122,6 +123,7 @@ void registerFunctionsGeo(FunctionFactory & factory) registerFunctionH3NumHexagons(factory); registerFunctionH3PointDistM(factory); registerFunctionH3PointDistKm(factory); + registerFunctionH3PointDistRads(factory); #endif #if USE_S2_GEOMETRY