mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-25 17:12:03 +00:00
Merge pull request #33621 from bharatnc/ncb/h3-misc-funcs
add h3 misc functions - part 2
This commit is contained in:
commit
4100512818
@ -156,6 +156,40 @@ Result:
|
||||
└─────────────┘
|
||||
```
|
||||
|
||||
## h3EdgeLengthKm {#h3edgelengthkm}
|
||||
|
||||
Calculates the average length of the [H3](#h3index) hexagon edge in kilometers.
|
||||
|
||||
**Syntax**
|
||||
|
||||
``` sql
|
||||
h3EdgeLengthKm(resolution)
|
||||
```
|
||||
|
||||
**Parameter**
|
||||
|
||||
- `resolution` — Index resolution. Type: [UInt8](../../../sql-reference/data-types/int-uint.md). Range: `[0, 15]`.
|
||||
|
||||
**Returned values**
|
||||
|
||||
- The average length of the [H3](#h3index) hexagon edge in kilometers. Type: [Float64](../../../sql-reference/data-types/float.md).
|
||||
|
||||
**Example**
|
||||
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
SELECT h3EdgeLengthKm(15) AS edgeLengthKm;
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
``` text
|
||||
┌─edgeLengthKm─┐
|
||||
│ 0.000509713 │
|
||||
└──────────────┘
|
||||
```
|
||||
|
||||
## geoToH3 {#geotoh3}
|
||||
|
||||
Returns [H3](#h3index) point index `(lon, lat)` with specified resolution.
|
||||
@ -849,4 +883,147 @@ Result:
|
||||
└────────────────────┘
|
||||
```
|
||||
|
||||
## h3ExactEdgeLengthM {#h3exactedgelengthm}
|
||||
|
||||
Returns the exact edge length of the unidirectional edge represented by the input h3 index in meters.
|
||||
|
||||
**Syntax**
|
||||
|
||||
``` sql
|
||||
h3ExactEdgeLengthM(index)
|
||||
```
|
||||
|
||||
**Parameter**
|
||||
|
||||
- `index` — Hexagon index number. Type: [UInt64](../../../sql-reference/data-types/int-uint.md).
|
||||
|
||||
**Returned value**
|
||||
|
||||
- Exact edge length in meters.
|
||||
|
||||
Type: [Float64](../../../sql-reference/data-types/float.md).
|
||||
|
||||
**Example**
|
||||
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
SELECT h3ExactEdgeLengthM(1310277011704381439) AS exactEdgeLengthM;;
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
``` text
|
||||
┌───exactEdgeLengthM─┐
|
||||
│ 195449.63163407316 │
|
||||
└────────────────────┘
|
||||
```
|
||||
|
||||
## h3ExactEdgeLengthKm {#h3exactedgelengthkm}
|
||||
|
||||
Returns the exact edge length of the unidirectional edge represented by the input h3 index in kilometers.
|
||||
|
||||
**Syntax**
|
||||
|
||||
``` sql
|
||||
h3ExactEdgeLengthKm(index)
|
||||
```
|
||||
|
||||
**Parameter**
|
||||
|
||||
- `index` — Hexagon index number. Type: [UInt64](../../../sql-reference/data-types/int-uint.md).
|
||||
|
||||
**Returned value**
|
||||
|
||||
- Exact edge length in kilometers.
|
||||
|
||||
Type: [Float64](../../../sql-reference/data-types/float.md).
|
||||
|
||||
**Example**
|
||||
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
SELECT h3ExactEdgeLengthKm(1310277011704381439) AS exactEdgeLengthKm;;
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
``` text
|
||||
┌──exactEdgeLengthKm─┐
|
||||
│ 195.44963163407317 │
|
||||
└────────────────────┘
|
||||
```
|
||||
|
||||
## h3ExactEdgeLengthRads {#h3exactedgelengthrads}
|
||||
|
||||
Returns the exact edge length of the unidirectional edge represented by the input h3 index in radians.
|
||||
|
||||
**Syntax**
|
||||
|
||||
``` sql
|
||||
h3ExactEdgeLengthRads(index)
|
||||
```
|
||||
|
||||
**Parameter**
|
||||
|
||||
- `index` — Hexagon index number. Type: [UInt64](../../../sql-reference/data-types/int-uint.md).
|
||||
|
||||
**Returned value**
|
||||
|
||||
- Exact edge length in radians.
|
||||
|
||||
Type: [Float64](../../../sql-reference/data-types/float.md).
|
||||
|
||||
**Example**
|
||||
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
SELECT h3ExactEdgeLengthRads(1310277011704381439) AS exactEdgeLengthRads;;
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
``` text
|
||||
┌──exactEdgeLengthRads─┐
|
||||
│ 0.030677980118976447 │
|
||||
└──────────────────────┘
|
||||
```
|
||||
|
||||
## h3NumHexagons {#h3numhexagons}
|
||||
|
||||
Returns the number of unique H3 indices at the given resolution.
|
||||
|
||||
**Syntax**
|
||||
|
||||
``` sql
|
||||
h3NumHexagons(resolution)
|
||||
```
|
||||
|
||||
**Parameter**
|
||||
|
||||
- `resolution` — Index resolution. Range: `[0, 15]`. Type: [UInt8](../../../sql-reference/data-types/int-uint.md).
|
||||
|
||||
**Returned value**
|
||||
|
||||
- Number of H3 indices.
|
||||
|
||||
Type: [Int64](../../../sql-reference/data-types/int-uint.md).
|
||||
|
||||
**Example**
|
||||
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
SELECT h3NumHexagons(3) AS numHexagons;
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
``` text
|
||||
┌─numHexagons─┐
|
||||
│ 41162 │
|
||||
└─────────────┘
|
||||
```
|
||||
[Original article](https://clickhouse.com/docs/en/sql-reference/functions/geo/h3) <!--hide-->
|
||||
|
@ -60,12 +60,14 @@ public:
|
||||
|
||||
for (size_t row = 0; row < input_rows_count; ++row)
|
||||
{
|
||||
const int resolution = col_hindex->getUInt(row);
|
||||
const UInt8 resolution = col_hindex->getUInt(row);
|
||||
if (resolution > MAX_H3_RES)
|
||||
throw Exception(
|
||||
ErrorCodes::ARGUMENT_OUT_OF_BOUND,
|
||||
"The argument 'resolution' ({}) of function {} is out of bounds because the maximum resolution in H3 library is ",
|
||||
resolution, getName(), MAX_H3_RES);
|
||||
toString(resolution),
|
||||
getName(),
|
||||
MAX_H3_RES);
|
||||
|
||||
// Numerical constant is 180 degrees / pi / Earth radius, Earth radius is from h3 sources
|
||||
Float64 res = 8.99320592271288084e-6 * getHexagonEdgeLengthAvgM(resolution);
|
||||
|
98
src/Functions/h3EdgeLengthKm.cpp
Normal file
98
src/Functions/h3EdgeLengthKm.cpp
Normal file
@ -0,0 +1,98 @@
|
||||
#include "config_functions.h"
|
||||
|
||||
#if USE_H3
|
||||
|
||||
#include <Columns/ColumnsNumber.h>
|
||||
#include <DataTypes/DataTypesNumber.h>
|
||||
#include <Functions/FunctionFactory.h>
|
||||
#include <Functions/IFunction.h>
|
||||
#include <IO/WriteHelpers.h>
|
||||
#include <Common/typeid_cast.h>
|
||||
#include <base/range.h>
|
||||
|
||||
#include <constants.h>
|
||||
#include <h3api.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
namespace ErrorCodes
|
||||
{
|
||||
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
||||
extern const int ARGUMENT_OUT_OF_BOUND;
|
||||
extern const int ILLEGAL_COLUMN;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
class FunctionH3EdgeLengthKm : public IFunction
|
||||
{
|
||||
public:
|
||||
static constexpr auto name = "h3EdgeLengthKm";
|
||||
|
||||
static FunctionPtr create(ContextPtr) { return std::make_shared<FunctionH3EdgeLengthKm>(); }
|
||||
|
||||
std::string getName() const override { return name; }
|
||||
|
||||
size_t getNumberOfArguments() const override { return 1; }
|
||||
bool useDefaultImplementationForConstants() const override { return true; }
|
||||
bool isSuitableForShortCircuitArgumentsExecution(const DataTypesWithConstInfo & /*arguments*/) const override { return false; }
|
||||
|
||||
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
|
||||
{
|
||||
const auto * arg = arguments[0].get();
|
||||
if (!WhichDataType(arg).isUInt8())
|
||||
throw Exception(
|
||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
|
||||
"Illegal type {} of argument {} of function {}. Must be UInt8",
|
||||
arg->getName(), 1, getName());
|
||||
|
||||
return std::make_shared<DataTypeFloat64>();
|
||||
}
|
||||
|
||||
ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
|
||||
{
|
||||
const auto * column = checkAndGetColumn<ColumnUInt8>(arguments[0].column.get());
|
||||
if (!column)
|
||||
throw Exception(
|
||||
ErrorCodes::ILLEGAL_COLUMN,
|
||||
"Illegal type {} of argument {} of function {}. Must be UInt8",
|
||||
arguments[0].type->getName(),
|
||||
1,
|
||||
getName());
|
||||
|
||||
const auto & data = column->getData();
|
||||
|
||||
auto dst = ColumnVector<Float64>::create();
|
||||
auto & dst_data = dst->getData();
|
||||
dst_data.resize(input_rows_count);
|
||||
|
||||
for (size_t row = 0; row < input_rows_count; ++row)
|
||||
{
|
||||
const UInt8 resolution = data[row];
|
||||
if (resolution > MAX_H3_RES)
|
||||
throw Exception(
|
||||
ErrorCodes::ARGUMENT_OUT_OF_BOUND,
|
||||
"The argument 'resolution' ({}) of function {} is out of bounds because the maximum resolution in H3 library is ",
|
||||
toString(resolution),
|
||||
getName(),
|
||||
MAX_H3_RES);
|
||||
Float64 res = getHexagonEdgeLengthAvgKm(resolution);
|
||||
dst_data[row] = res;
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
void registerFunctionH3EdgeLengthKm(FunctionFactory & factory)
|
||||
{
|
||||
factory.registerFunction<FunctionH3EdgeLengthKm>();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -20,6 +20,7 @@ namespace ErrorCodes
|
||||
{
|
||||
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
||||
extern const int ARGUMENT_OUT_OF_BOUND;
|
||||
extern const int ILLEGAL_COLUMN;
|
||||
}
|
||||
|
||||
namespace
|
||||
@ -57,7 +58,16 @@ public:
|
||||
|
||||
ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
|
||||
{
|
||||
const auto * col_hindex = arguments[0].column.get();
|
||||
const auto * column = checkAndGetColumn<ColumnUInt8>(arguments[0].column.get());
|
||||
if (!column)
|
||||
throw Exception(
|
||||
ErrorCodes::ILLEGAL_COLUMN,
|
||||
"Illegal type {} of argument {} of function {}. Must be UInt8",
|
||||
arguments[0].column->getName(),
|
||||
1,
|
||||
getName());
|
||||
|
||||
const auto & data = column->getData();
|
||||
|
||||
auto dst = ColumnVector<Float64>::create();
|
||||
auto & dst_data = dst->getData();
|
||||
@ -65,12 +75,12 @@ public:
|
||||
|
||||
for (size_t row = 0; row < input_rows_count; ++row)
|
||||
{
|
||||
const UInt64 resolution = col_hindex->getUInt(row);
|
||||
const UInt8 resolution = data[row];
|
||||
if (resolution > MAX_H3_RES)
|
||||
throw Exception(
|
||||
ErrorCodes::ARGUMENT_OUT_OF_BOUND,
|
||||
"The argument 'resolution' ({}) of function {} is out of bounds because the maximum resolution in H3 library is ",
|
||||
resolution, getName(), MAX_H3_RES);
|
||||
toString(resolution), getName(), MAX_H3_RES);
|
||||
|
||||
Float64 res = getHexagonEdgeLengthAvgM(resolution);
|
||||
|
||||
|
90
src/Functions/h3ExactEdgeLengthKm.cpp
Normal file
90
src/Functions/h3ExactEdgeLengthKm.cpp
Normal file
@ -0,0 +1,90 @@
|
||||
#include "config_functions.h"
|
||||
|
||||
#if USE_H3
|
||||
|
||||
#include <Columns/ColumnsNumber.h>
|
||||
#include <DataTypes/DataTypesNumber.h>
|
||||
#include <Functions/FunctionFactory.h>
|
||||
#include <Functions/IFunction.h>
|
||||
#include <IO/WriteHelpers.h>
|
||||
#include <Common/typeid_cast.h>
|
||||
#include <base/range.h>
|
||||
|
||||
#include <constants.h>
|
||||
#include <h3api.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
namespace ErrorCodes
|
||||
{
|
||||
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
||||
extern const int ILLEGAL_COLUMN;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
class FunctionH3ExactEdgeLengthKm : public IFunction
|
||||
{
|
||||
public:
|
||||
static constexpr auto name = "h3ExactEdgeLengthKm";
|
||||
|
||||
static FunctionPtr create(ContextPtr) { return std::make_shared<FunctionH3ExactEdgeLengthKm>(); }
|
||||
|
||||
std::string getName() const override { return name; }
|
||||
|
||||
size_t getNumberOfArguments() const override { return 1; }
|
||||
bool useDefaultImplementationForConstants() const override { return true; }
|
||||
bool isSuitableForShortCircuitArgumentsExecution(const DataTypesWithConstInfo & /*arguments*/) const override { return false; }
|
||||
|
||||
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
|
||||
{
|
||||
const auto * arg = arguments[0].get();
|
||||
if (!WhichDataType(arg).isUInt64())
|
||||
throw Exception(
|
||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
|
||||
"Illegal type {} of argument {} of function {}. Must be UInt64",
|
||||
arg->getName(), 1, getName());
|
||||
|
||||
return std::make_shared<DataTypeFloat64>();
|
||||
}
|
||||
|
||||
ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
|
||||
{
|
||||
const auto * column = checkAndGetColumn<ColumnUInt64>(arguments[0].column.get());
|
||||
if (!column)
|
||||
throw Exception(
|
||||
ErrorCodes::ILLEGAL_COLUMN,
|
||||
"Illegal type {} of argument {} of function {}. Must be UInt64",
|
||||
arguments[0].type->getName(),
|
||||
1,
|
||||
getName());
|
||||
|
||||
const auto & data = column->getData();
|
||||
|
||||
auto dst = ColumnVector<Float64>::create();
|
||||
auto & dst_data = dst->getData();
|
||||
dst_data.resize(input_rows_count);
|
||||
|
||||
for (size_t row = 0; row < input_rows_count; ++row)
|
||||
{
|
||||
const UInt64 index = data[row];
|
||||
Float64 res = exactEdgeLengthKm(index);
|
||||
dst_data[row] = res;
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
void registerFunctionH3ExactEdgeLengthKm(FunctionFactory & factory)
|
||||
{
|
||||
factory.registerFunction<FunctionH3ExactEdgeLengthKm>();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
90
src/Functions/h3ExactEdgeLengthM.cpp
Normal file
90
src/Functions/h3ExactEdgeLengthM.cpp
Normal file
@ -0,0 +1,90 @@
|
||||
#include "config_functions.h"
|
||||
|
||||
#if USE_H3
|
||||
|
||||
#include <Columns/ColumnsNumber.h>
|
||||
#include <DataTypes/DataTypesNumber.h>
|
||||
#include <Functions/FunctionFactory.h>
|
||||
#include <Functions/IFunction.h>
|
||||
#include <IO/WriteHelpers.h>
|
||||
#include <Common/typeid_cast.h>
|
||||
#include <base/range.h>
|
||||
|
||||
#include <constants.h>
|
||||
#include <h3api.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
namespace ErrorCodes
|
||||
{
|
||||
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
||||
extern const int ILLEGAL_COLUMN;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
class FunctionH3ExactEdgeLengthM : public IFunction
|
||||
{
|
||||
public:
|
||||
static constexpr auto name = "h3ExactEdgeLengthM";
|
||||
|
||||
static FunctionPtr create(ContextPtr) { return std::make_shared<FunctionH3ExactEdgeLengthM>(); }
|
||||
|
||||
std::string getName() const override { return name; }
|
||||
|
||||
size_t getNumberOfArguments() const override { return 1; }
|
||||
bool useDefaultImplementationForConstants() const override { return true; }
|
||||
bool isSuitableForShortCircuitArgumentsExecution(const DataTypesWithConstInfo & /*arguments*/) const override { return false; }
|
||||
|
||||
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
|
||||
{
|
||||
const auto * arg = arguments[0].get();
|
||||
if (!WhichDataType(arg).isUInt64())
|
||||
throw Exception(
|
||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
|
||||
"Illegal type {} of argument {} of function {}. Must be UInt64",
|
||||
arg->getName(), 1, getName());
|
||||
|
||||
return std::make_shared<DataTypeFloat64>();
|
||||
}
|
||||
|
||||
ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
|
||||
{
|
||||
const auto * column = checkAndGetColumn<ColumnUInt64>(arguments[0].column.get());
|
||||
if (!column)
|
||||
throw Exception(
|
||||
ErrorCodes::ILLEGAL_COLUMN,
|
||||
"Illegal type {} of argument {} of function {}. Must be UInt64",
|
||||
arguments[0].type->getName(),
|
||||
1,
|
||||
getName());
|
||||
|
||||
const auto & data = column->getData();
|
||||
|
||||
auto dst = ColumnVector<Float64>::create();
|
||||
auto & dst_data = dst->getData();
|
||||
dst_data.resize(input_rows_count);
|
||||
|
||||
for (size_t row = 0; row < input_rows_count; ++row)
|
||||
{
|
||||
const UInt64 index = data[row];
|
||||
Float64 res = exactEdgeLengthM(index);
|
||||
dst_data[row] = res;
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
void registerFunctionH3ExactEdgeLengthM(FunctionFactory & factory)
|
||||
{
|
||||
factory.registerFunction<FunctionH3ExactEdgeLengthM>();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
90
src/Functions/h3ExactEdgeLengthRads.cpp
Normal file
90
src/Functions/h3ExactEdgeLengthRads.cpp
Normal file
@ -0,0 +1,90 @@
|
||||
#include "config_functions.h"
|
||||
|
||||
#if USE_H3
|
||||
|
||||
#include <Columns/ColumnsNumber.h>
|
||||
#include <DataTypes/DataTypesNumber.h>
|
||||
#include <Functions/FunctionFactory.h>
|
||||
#include <Functions/IFunction.h>
|
||||
#include <IO/WriteHelpers.h>
|
||||
#include <Common/typeid_cast.h>
|
||||
#include <base/range.h>
|
||||
|
||||
#include <constants.h>
|
||||
#include <h3api.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
namespace ErrorCodes
|
||||
{
|
||||
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
||||
extern const int ILLEGAL_COLUMN;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
class FunctionH3ExactEdgeLengthRads : public IFunction
|
||||
{
|
||||
public:
|
||||
static constexpr auto name = "h3ExactEdgeLengthRads";
|
||||
|
||||
static FunctionPtr create(ContextPtr) { return std::make_shared<FunctionH3ExactEdgeLengthRads>(); }
|
||||
|
||||
std::string getName() const override { return name; }
|
||||
|
||||
size_t getNumberOfArguments() const override { return 1; }
|
||||
bool useDefaultImplementationForConstants() const override { return true; }
|
||||
bool isSuitableForShortCircuitArgumentsExecution(const DataTypesWithConstInfo & /*arguments*/) const override { return false; }
|
||||
|
||||
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
|
||||
{
|
||||
const auto * arg = arguments[0].get();
|
||||
if (!WhichDataType(arg).isUInt64())
|
||||
throw Exception(
|
||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
|
||||
"Illegal type {} of argument {} of function {}. Must be UInt64",
|
||||
arg->getName(), 1, getName());
|
||||
|
||||
return std::make_shared<DataTypeFloat64>();
|
||||
}
|
||||
|
||||
ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
|
||||
{
|
||||
const auto * column = checkAndGetColumn<ColumnUInt64>(arguments[0].column.get());
|
||||
if (!column)
|
||||
throw Exception(
|
||||
ErrorCodes::ILLEGAL_COLUMN,
|
||||
"Illegal type {} of argument {} of function {}. Must be UInt64",
|
||||
arguments[0].type->getName(),
|
||||
1,
|
||||
getName());
|
||||
|
||||
const auto & data = column->getData();
|
||||
|
||||
auto dst = ColumnVector<Float64>::create();
|
||||
auto & dst_data = dst->getData();
|
||||
dst_data.resize(input_rows_count);
|
||||
|
||||
for (size_t row = 0; row < input_rows_count; ++row)
|
||||
{
|
||||
const UInt64 index = data[row];
|
||||
Float64 res = exactEdgeLengthRads(index);
|
||||
dst_data[row] = res;
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
void registerFunctionH3ExactEdgeLengthRads(FunctionFactory & factory)
|
||||
{
|
||||
factory.registerFunction<FunctionH3ExactEdgeLengthRads>();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -70,12 +70,12 @@ public:
|
||||
|
||||
for (size_t row = 0; row < input_rows_count; ++row)
|
||||
{
|
||||
const UInt64 resolution = data[row];
|
||||
const UInt8 resolution = data[row];
|
||||
if (resolution > MAX_H3_RES)
|
||||
throw Exception(
|
||||
ErrorCodes::ARGUMENT_OUT_OF_BOUND,
|
||||
"The argument 'resolution' ({}) of function {} is out of bounds because the maximum resolution in H3 library is ",
|
||||
resolution,
|
||||
toString(resolution),
|
||||
getName(),
|
||||
MAX_H3_RES);
|
||||
|
||||
|
@ -20,6 +20,7 @@ namespace ErrorCodes
|
||||
{
|
||||
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
||||
extern const int ARGUMENT_OUT_OF_BOUND;
|
||||
extern const int ILLEGAL_COLUMN;
|
||||
}
|
||||
|
||||
namespace
|
||||
@ -52,7 +53,16 @@ public:
|
||||
|
||||
ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
|
||||
{
|
||||
const auto * col_hindex = arguments[0].column.get();
|
||||
const auto * column = checkAndGetColumn<ColumnUInt8>(arguments[0].column.get());
|
||||
if (!column)
|
||||
throw Exception(
|
||||
ErrorCodes::ILLEGAL_COLUMN,
|
||||
"Illegal type {} of argument {} of function {}. Must be UInt8",
|
||||
arguments[0].column->getName(),
|
||||
1,
|
||||
getName());
|
||||
|
||||
const auto & data = column->getData();
|
||||
|
||||
auto dst = ColumnVector<Float64>::create();
|
||||
auto & dst_data = dst->getData();
|
||||
@ -60,12 +70,14 @@ public:
|
||||
|
||||
for (size_t row = 0; row < input_rows_count; ++row)
|
||||
{
|
||||
const UInt64 resolution = col_hindex->getUInt(row);
|
||||
const UInt8 resolution = data[row];
|
||||
if (resolution > MAX_H3_RES)
|
||||
throw Exception(
|
||||
ErrorCodes::ARGUMENT_OUT_OF_BOUND,
|
||||
"The argument 'resolution' ({}) of function {} is out of bounds because the maximum resolution in H3 library is ",
|
||||
resolution, getName(), MAX_H3_RES);
|
||||
toString(resolution),
|
||||
getName(),
|
||||
MAX_H3_RES);
|
||||
|
||||
Float64 res = getHexagonAreaAvgM2(resolution);
|
||||
|
||||
|
95
src/Functions/h3NumHexagons.cpp
Normal file
95
src/Functions/h3NumHexagons.cpp
Normal file
@ -0,0 +1,95 @@
|
||||
#include "config_functions.h"
|
||||
|
||||
#if USE_H3
|
||||
|
||||
#include <Columns/ColumnsNumber.h>
|
||||
#include <DataTypes/DataTypesNumber.h>
|
||||
#include <Functions/FunctionFactory.h>
|
||||
#include <Functions/IFunction.h>
|
||||
#include <IO/WriteHelpers.h>
|
||||
#include <Common/typeid_cast.h>
|
||||
|
||||
#include <constants.h>
|
||||
#include <h3api.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
namespace ErrorCodes
|
||||
{
|
||||
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
||||
extern const int ILLEGAL_COLUMN;
|
||||
extern const int ARGUMENT_OUT_OF_BOUND;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
class FunctionH3NumHexagons : public IFunction
|
||||
{
|
||||
public:
|
||||
static constexpr auto name = "h3NumHexagons";
|
||||
|
||||
static FunctionPtr create(ContextPtr) { return std::make_shared<FunctionH3NumHexagons>(); }
|
||||
|
||||
std::string getName() const override { return name; }
|
||||
|
||||
size_t getNumberOfArguments() const override { return 1; }
|
||||
bool useDefaultImplementationForConstants() const override { return true; }
|
||||
bool isSuitableForShortCircuitArgumentsExecution(const DataTypesWithConstInfo & /*arguments*/) const override { return false; }
|
||||
|
||||
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
|
||||
{
|
||||
const auto * arg = arguments[0].get();
|
||||
if (!WhichDataType(arg).isUInt8())
|
||||
throw Exception(
|
||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
|
||||
"Illegal type {} of argument {} of function {}. Must be UInt8",
|
||||
arg->getName(), 1, getName());
|
||||
|
||||
return std::make_shared<DataTypeInt64>();
|
||||
}
|
||||
|
||||
ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
|
||||
{
|
||||
const auto * column = checkAndGetColumn<ColumnUInt8>(arguments[0].column.get());
|
||||
if (!column)
|
||||
throw Exception(
|
||||
ErrorCodes::ILLEGAL_COLUMN,
|
||||
"Illegal type {} of argument {} of function {}. Must be UInt8",
|
||||
arguments[0].type->getName(),
|
||||
1,
|
||||
getName());
|
||||
|
||||
const auto & data = column->getData();
|
||||
|
||||
auto dst = ColumnVector<Int64>::create();
|
||||
auto & dst_data = dst->getData();
|
||||
dst_data.resize(input_rows_count);
|
||||
|
||||
for (size_t row = 0; row < input_rows_count; ++row)
|
||||
{
|
||||
const UInt8 resolution = data[row];
|
||||
if (resolution > MAX_H3_RES)
|
||||
throw Exception(
|
||||
ErrorCodes::ARGUMENT_OUT_OF_BOUND,
|
||||
"The argument 'resolution' ({}) of function {} is out of bounds because the maximum resolution in H3 library is ",
|
||||
toString(resolution), getName(), MAX_H3_RES);
|
||||
Int64 res = getNumCells(resolution);
|
||||
dst_data[row] = res;
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
void registerFunctionH3NumHexagons(FunctionFactory & factory)
|
||||
{
|
||||
factory.registerFunction<FunctionH3NumHexagons>();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -30,6 +30,10 @@ void registerFunctionH3ToGeo(FunctionFactory &);
|
||||
void registerFunctionH3ToGeoBoundary(FunctionFactory &);
|
||||
void registerFunctionH3EdgeAngle(FunctionFactory &);
|
||||
void registerFunctionH3EdgeLengthM(FunctionFactory &);
|
||||
void registerFunctionH3EdgeLengthKm(FunctionFactory &);
|
||||
void registerFunctionH3ExactEdgeLengthM(FunctionFactory &);
|
||||
void registerFunctionH3ExactEdgeLengthKm(FunctionFactory &);
|
||||
void registerFunctionH3ExactEdgeLengthRads(FunctionFactory &);
|
||||
void registerFunctionH3GetResolution(FunctionFactory &);
|
||||
void registerFunctionH3IsValid(FunctionFactory &);
|
||||
void registerFunctionH3KRing(FunctionFactory &);
|
||||
@ -47,6 +51,7 @@ void registerFunctionH3GetFaces(FunctionFactory &);
|
||||
void registerFunctionH3HexAreaKm2(FunctionFactory &);
|
||||
void registerFunctionH3CellAreaM2(FunctionFactory &);
|
||||
void registerFunctionH3CellAreaRads2(FunctionFactory &);
|
||||
void registerFunctionH3NumHexagons(FunctionFactory &);
|
||||
|
||||
#endif
|
||||
|
||||
@ -91,6 +96,10 @@ void registerFunctionsGeo(FunctionFactory & factory)
|
||||
registerFunctionH3ToGeoBoundary(factory);
|
||||
registerFunctionH3EdgeAngle(factory);
|
||||
registerFunctionH3EdgeLengthM(factory);
|
||||
registerFunctionH3EdgeLengthKm(factory);
|
||||
registerFunctionH3ExactEdgeLengthM(factory);
|
||||
registerFunctionH3ExactEdgeLengthKm(factory);
|
||||
registerFunctionH3ExactEdgeLengthRads(factory);
|
||||
registerFunctionH3GetResolution(factory);
|
||||
registerFunctionH3IsValid(factory);
|
||||
registerFunctionH3KRing(factory);
|
||||
@ -108,6 +117,7 @@ void registerFunctionsGeo(FunctionFactory & factory)
|
||||
registerFunctionH3HexAreaKm2(factory);
|
||||
registerFunctionH3CellAreaM2(factory);
|
||||
registerFunctionH3CellAreaRads2(factory);
|
||||
registerFunctionH3NumHexagons(factory);
|
||||
#endif
|
||||
|
||||
#if USE_S2_GEOMETRY
|
||||
|
16
tests/queries/0_stateless/02165_h3_edge_length_km.reference
Normal file
16
tests/queries/0_stateless/02165_h3_edge_length_km.reference
Normal file
@ -0,0 +1,16 @@
|
||||
1107.712591
|
||||
418.6760055
|
||||
158.2446558
|
||||
59.81085794
|
||||
22.6063794
|
||||
8.544408276
|
||||
3.229482772
|
||||
1.220629759
|
||||
0.461354684
|
||||
0.174375668
|
||||
0.065907807
|
||||
0.024910561
|
||||
0.009415526
|
||||
0.003559893
|
||||
0.001348575
|
||||
0.000509713
|
18
tests/queries/0_stateless/02165_h3_edge_length_km.sql
Normal file
18
tests/queries/0_stateless/02165_h3_edge_length_km.sql
Normal file
@ -0,0 +1,18 @@
|
||||
-- Tags: no-fasttest
|
||||
|
||||
SELECT h3EdgeLengthKm(0);
|
||||
SELECT h3EdgeLengthKm(1);
|
||||
SELECT h3EdgeLengthKm(2);
|
||||
SELECT h3EdgeLengthKm(3);
|
||||
SELECT h3EdgeLengthKm(4);
|
||||
SELECT h3EdgeLengthKm(5);
|
||||
SELECT h3EdgeLengthKm(6);
|
||||
SELECT h3EdgeLengthKm(7);
|
||||
SELECT h3EdgeLengthKm(8);
|
||||
SELECT h3EdgeLengthKm(9);
|
||||
SELECT h3EdgeLengthKm(10);
|
||||
SELECT h3EdgeLengthKm(11);
|
||||
SELECT h3EdgeLengthKm(12);
|
||||
SELECT h3EdgeLengthKm(13);
|
||||
SELECT h3EdgeLengthKm(14);
|
||||
SELECT h3EdgeLengthKm(15);
|
@ -0,0 +1,16 @@
|
||||
489.55559989912314
|
||||
192.39078306095627
|
||||
66.91913220366439
|
||||
1263.6096633631134
|
||||
480.7440319163875
|
||||
195.44963163407317
|
||||
1263.6096633631118
|
||||
461.80697194406935
|
||||
190.08769842412468
|
||||
1263.6096633631123
|
||||
465.41972260404145
|
||||
64.81970466298482
|
||||
1263.6096633631116
|
||||
69.63641611246636
|
||||
195.6274718146093
|
||||
67.66085681290775
|
29
tests/queries/0_stateless/02165_h3_exact_edge_length_Km.sql
Normal file
29
tests/queries/0_stateless/02165_h3_exact_edge_length_Km.sql
Normal file
@ -0,0 +1,29 @@
|
||||
-- Tags: no-fasttest
|
||||
|
||||
DROP TABLE IF EXISTS h3_indexes;
|
||||
|
||||
CREATE TABLE h3_indexes (h3_index UInt64) ENGINE = Memory;
|
||||
|
||||
-- Test h3 indices selected from original test fixture: https://github.com/uber/h3/blob/master/src/apps/testapps/testH3CellAreaExhaustive.c
|
||||
|
||||
INSERT INTO h3_indexes VALUES (1298057039473278975);
|
||||
INSERT INTO h3_indexes VALUES (1370114633511206911);
|
||||
INSERT INTO h3_indexes VALUES (1442172227549134847);
|
||||
INSERT INTO h3_indexes VALUES (1514229821587062783);
|
||||
INSERT INTO h3_indexes VALUES (1232301846085763071);
|
||||
INSERT INTO h3_indexes VALUES (1304359440123691007);
|
||||
INSERT INTO h3_indexes VALUES (1376417034161618943);
|
||||
INSERT INTO h3_indexes VALUES (1448474628199546879);
|
||||
INSERT INTO h3_indexes VALUES (1598506838100279295);
|
||||
INSERT INTO h3_indexes VALUES (1238219417666453503);
|
||||
INSERT INTO h3_indexes VALUES (1310277011704381439);
|
||||
INSERT INTO h3_indexes VALUES (1382334605742309375);
|
||||
INSERT INTO h3_indexes VALUES (1458182628678041599);
|
||||
INSERT INTO h3_indexes VALUES (1530240222715969535);
|
||||
INSERT INTO h3_indexes VALUES (1602297816753897471);
|
||||
INSERT INTO h3_indexes VALUES (1242009915283734527);
|
||||
|
||||
SELECT h3ExactEdgeLengthKm(h3_index) FROM h3_indexes ORDER BY h3_index;
|
||||
|
||||
DROP TABLE h3_indexes;
|
||||
|
@ -0,0 +1,16 @@
|
||||
489555.59989912313
|
||||
192390.78306095628
|
||||
66919.13220366438
|
||||
1263609.6633631135
|
||||
480744.0319163875
|
||||
195449.63163407316
|
||||
1263609.663363112
|
||||
461806.9719440694
|
||||
190087.69842412468
|
||||
1263609.6633631124
|
||||
465419.72260404145
|
||||
64819.70466298482
|
||||
1263609.6633631117
|
||||
69636.41611246637
|
||||
195627.4718146093
|
||||
67660.85681290775
|
29
tests/queries/0_stateless/02165_h3_exact_edge_length_m.sql
Normal file
29
tests/queries/0_stateless/02165_h3_exact_edge_length_m.sql
Normal file
@ -0,0 +1,29 @@
|
||||
-- Tags: no-fasttest
|
||||
|
||||
DROP TABLE IF EXISTS h3_indexes;
|
||||
|
||||
CREATE TABLE h3_indexes (h3_index UInt64) ENGINE = Memory;
|
||||
|
||||
-- Test h3 indices selected from original test fixture: https://github.com/uber/h3/blob/master/src/apps/testapps/testH3CellAreaExhaustive.c
|
||||
|
||||
INSERT INTO h3_indexes VALUES (1298057039473278975);
|
||||
INSERT INTO h3_indexes VALUES (1370114633511206911);
|
||||
INSERT INTO h3_indexes VALUES (1442172227549134847);
|
||||
INSERT INTO h3_indexes VALUES (1514229821587062783);
|
||||
INSERT INTO h3_indexes VALUES (1232301846085763071);
|
||||
INSERT INTO h3_indexes VALUES (1304359440123691007);
|
||||
INSERT INTO h3_indexes VALUES (1376417034161618943);
|
||||
INSERT INTO h3_indexes VALUES (1448474628199546879);
|
||||
INSERT INTO h3_indexes VALUES (1598506838100279295);
|
||||
INSERT INTO h3_indexes VALUES (1238219417666453503);
|
||||
INSERT INTO h3_indexes VALUES (1310277011704381439);
|
||||
INSERT INTO h3_indexes VALUES (1382334605742309375);
|
||||
INSERT INTO h3_indexes VALUES (1458182628678041599);
|
||||
INSERT INTO h3_indexes VALUES (1530240222715969535);
|
||||
INSERT INTO h3_indexes VALUES (1602297816753897471);
|
||||
INSERT INTO h3_indexes VALUES (1242009915283734527);
|
||||
|
||||
SELECT h3ExactEdgeLengthM(h3_index) FROM h3_indexes ORDER BY h3_index;
|
||||
|
||||
DROP TABLE h3_indexes;
|
||||
|
@ -0,0 +1,16 @@
|
||||
0.07684116278590451
|
||||
0.03019786002394998
|
||||
0.010503697500779932
|
||||
0.19833750417794152
|
||||
0.07545808979092708
|
||||
0.030677980118976447
|
||||
0.19833750417794127
|
||||
0.0724857089044268
|
||||
0.029836365432681984
|
||||
0.19833750417794133
|
||||
0.07305277005463119
|
||||
0.010174169141909536
|
||||
0.19833750417794122
|
||||
0.010930205246202099
|
||||
0.030705894101096694
|
||||
0.010620119376973209
|
@ -0,0 +1,29 @@
|
||||
-- Tags: no-fasttest
|
||||
|
||||
DROP TABLE IF EXISTS h3_indexes;
|
||||
|
||||
CREATE TABLE h3_indexes (h3_index UInt64) ENGINE = Memory;
|
||||
|
||||
-- Test h3 indices selected from original test fixture: https://github.com/uber/h3/blob/master/src/apps/testapps/testH3CellAreaExhaustive.c
|
||||
|
||||
INSERT INTO h3_indexes VALUES (1298057039473278975);
|
||||
INSERT INTO h3_indexes VALUES (1370114633511206911);
|
||||
INSERT INTO h3_indexes VALUES (1442172227549134847);
|
||||
INSERT INTO h3_indexes VALUES (1514229821587062783);
|
||||
INSERT INTO h3_indexes VALUES (1232301846085763071);
|
||||
INSERT INTO h3_indexes VALUES (1304359440123691007);
|
||||
INSERT INTO h3_indexes VALUES (1376417034161618943);
|
||||
INSERT INTO h3_indexes VALUES (1448474628199546879);
|
||||
INSERT INTO h3_indexes VALUES (1598506838100279295);
|
||||
INSERT INTO h3_indexes VALUES (1238219417666453503);
|
||||
INSERT INTO h3_indexes VALUES (1310277011704381439);
|
||||
INSERT INTO h3_indexes VALUES (1382334605742309375);
|
||||
INSERT INTO h3_indexes VALUES (1458182628678041599);
|
||||
INSERT INTO h3_indexes VALUES (1530240222715969535);
|
||||
INSERT INTO h3_indexes VALUES (1602297816753897471);
|
||||
INSERT INTO h3_indexes VALUES (1242009915283734527);
|
||||
|
||||
SELECT h3ExactEdgeLengthRads(h3_index) FROM h3_indexes ORDER BY h3_index;
|
||||
|
||||
DROP TABLE h3_indexes;
|
||||
|
16
tests/queries/0_stateless/02165_h3_num_hexagons.reference
Normal file
16
tests/queries/0_stateless/02165_h3_num_hexagons.reference
Normal file
@ -0,0 +1,16 @@
|
||||
122
|
||||
842
|
||||
5882
|
||||
41162
|
||||
288122
|
||||
2016842
|
||||
14117882
|
||||
98825162
|
||||
691776122
|
||||
4842432842
|
||||
33897029882
|
||||
237279209162
|
||||
1660954464122
|
||||
11626681248842
|
||||
81386768741882
|
||||
569707381193162
|
19
tests/queries/0_stateless/02165_h3_num_hexagons.sql
Normal file
19
tests/queries/0_stateless/02165_h3_num_hexagons.sql
Normal file
@ -0,0 +1,19 @@
|
||||
-- Tags: no-fasttest
|
||||
|
||||
SELECT h3NumHexagons(0);
|
||||
SELECT h3NumHexagons(1);
|
||||
SELECT h3NumHexagons(2);
|
||||
SELECT h3NumHexagons(3);
|
||||
SELECT h3NumHexagons(4);
|
||||
SELECT h3NumHexagons(5);
|
||||
SELECT h3NumHexagons(6);
|
||||
SELECT h3NumHexagons(7);
|
||||
SELECT h3NumHexagons(8);
|
||||
SELECT h3NumHexagons(9);
|
||||
SELECT h3NumHexagons(10);
|
||||
SELECT h3NumHexagons(11);
|
||||
SELECT h3NumHexagons(12);
|
||||
SELECT h3NumHexagons(13);
|
||||
SELECT h3NumHexagons(14);
|
||||
SELECT h3NumHexagons(15);
|
||||
SELECT h3NumHexagons(16); -- { serverError 69 }
|
Loading…
Reference in New Issue
Block a user