Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add remaining h3 miscellaneous functions #34568

Merged
merged 21 commits into from
Mar 17, 2022
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
181 changes: 181 additions & 0 deletions docs/en/sql-reference/functions/geo/h3.md
Original file line number Diff line number Diff line change
Expand Up @@ -1026,4 +1026,185 @@ Result:
│ 41162 │
└─────────────┘
```

## h3PointDistM {#h3pointdistm}

Returns the "great circle" or "haversine" distance between pairs of GeoCoord points (latitude/longitude) pairs in meters.

**Syntax**

``` sql
h3PointDistM(lat1, lon1, lat2, lon2)
```

**Arguments**

- `lat1`, `lon1` — Latitude and Longitude of point1 in degrees. Type: [Float64](../../../sql-reference/data-types/float.md).
- `lat2`, `lon2` — Latitude and Longitude of point2 in degrees. Type: [Float64](../../../sql-reference/data-types/float.md).

**Returned values**

- Haversine or great circle distance in meters.

Type: [Float64](../../../sql-reference/data-types/float.md).

**Example**

Query:

``` sql
select h3PointDistM(-10.0 ,0.0, 10.0, 0.0) as h3PointDistM;
```

Result:

``` text
┌──────h3PointDistM─┐
│ 2223901.039504589 │
└───────────────────┘
```

## h3PointDistKm {#h3pointdistkm}

Returns the "great circle" or "haversine" distance between pairs of GeoCoord points (latitude/longitude) pairs in kilometers.

**Syntax**

``` sql
h3PointDistKm(lat1, lon1, lat2, lon2)
```

**Arguments**

- `lat1`, `lon1` — Latitude and Longitude of point1 in degrees. Type: [Float64](../../../sql-reference/data-types/float.md).
- `lat2`, `lon2` — Latitude and Longitude of point2 in degrees. Type: [Float64](../../../sql-reference/data-types/float.md).

**Returned values**

- Haversine or great circle distance in kilometers.

Type: [Float64](../../../sql-reference/data-types/float.md).

**Example**

Query:

``` sql
select h3PointDistKm(-10.0 ,0.0, 10.0, 0.0) as h3PointDistKm;
```

Result:

``` text
┌─────h3PointDistKm─┐
│ 2223.901039504589 │
└───────────────────┘
```

## h3PointDistRads {#h3pointdistrads}

Returns the "great circle" or "haversine" distance between pairs of GeoCoord points (latitude/longitude) pairs in radians.

**Syntax**

``` sql
h3PointDistRads(lat1, lon1, lat2, lon2)
```

**Arguments**

- `lat1`, `lon1` — Latitude and Longitude of point1 in degrees. Type: [Float64](../../../sql-reference/data-types/float.md).
- `lat2`, `lon2` — Latitude and Longitude of point2 in degrees. Type: [Float64](../../../sql-reference/data-types/float.md).

**Returned values**

- Haversine or great circle distance in radians.

Type: [Float64](../../../sql-reference/data-types/float.md).

**Example**

Query:

``` sql
select h3PointDistRads(-10.0 ,0.0, 10.0, 0.0) as h3PointDistRads;
```

Result:

``` text
┌────h3PointDistRads─┐
│ 0.3490658503988659 │
└────────────────────┘
```

## h3GetRes0Indexes {#h3getres0indexes}

Returns an array of all the resolution 0 H3 indexes.

**Syntax**

``` sql
h3GetRes0Indexes()
```

**Returned values**

- Array of all the resolution 0 H3 indexes.

Type: [Array](../../../sql-reference/data-types/array.md)([UInt64](../../../sql-reference/data-types/int-uint.md)).


**Example**

Query:

``` sql
select h3GetRes0Indexes as indexes ;
```

Result:

``` text
┌─indexes─────────────────────────────────────┐
│ [576495936675512319,576531121047601151,....]│
└─────────────────────────────────────────────┘
```

## h3GetPentagonIndexes {#h3getpentagonindexes}

Returns all the pentagon H3 indexes at the specified resolution.

**Syntax**

``` sql
h3GetPentagonIndexes(resolution)
```

**Parameter**

- `resolution` — Index resolution. Range: `[0, 15]`. Type: [UInt8](../../../sql-reference/data-types/int-uint.md).

**Returned value**

- Array of all pentagon H3 indexes.

Type: [Array](../../../sql-reference/data-types/array.md)([UInt64](../../../sql-reference/data-types/int-uint.md)).

**Example**

Query:

``` sql
SELECT h3GetPentagonIndexes(3) AS indexes;
```

Result:

``` text
┌─indexes────────────────────────────────────────────────────────┐
│ [590112357393367039,590464201114255359,590816044835143679,...] │
└────────────────────────────────────────────────────────────────┘
```

[Original article](https://clickhouse.com/docs/en/sql-reference/functions/geo/h3) <!--hide-->
115 changes: 115 additions & 0 deletions src/Functions/h3GetPentagonIndexes.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
#include "config_functions.h"

#if USE_H3

#include <Columns/ColumnArray.h>
#include <Columns/ColumnsNumber.h>
#include <DataTypes/DataTypeArray.h>
#include <DataTypes/DataTypesNumber.h>
#include <Functions/FunctionFactory.h>
#include <Functions/IFunction.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 FunctionH3GetPentagonIndexes : public IFunction
{
public:
static constexpr auto name = "h3GetPentagonIndexes";

static FunctionPtr create(ContextPtr) { return std::make_shared<FunctionH3GetPentagonIndexes>(); }

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<DataTypeArray>(std::make_shared<DataTypeUInt64>());
}

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 result_column_data = ColumnUInt64::create();
auto & result_data = result_column_data->getData();

auto result_column_offsets = ColumnArray::ColumnOffsets::create();
auto & result_offsets = result_column_offsets->getData();
result_offsets.resize(input_rows_count);

auto current_offset = 0;
std::vector<H3Index> hindex_vec;
result_data.reserve(input_rows_count);

bharatnc marked this conversation as resolved.
Show resolved Hide resolved

for (size_t row = 0; row < input_rows_count; ++row)
{
if (data[row] > 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(data[row]),
getName(),
MAX_H3_RES);

const auto vec_size = pentagonCount();
hindex_vec.resize(vec_size);
getPentagons(data[row], hindex_vec.data());

for (auto & i : hindex_vec)
{
++current_offset;
result_data.emplace_back(i);
}

result_offsets[row] = current_offset;
hindex_vec.clear();
}

return ColumnArray::create(std::move(result_column_data), std::move(result_column_offsets));
}
};

}

void registerFunctionH3GetPentagonIndexes(FunctionFactory & factory)
{
factory.registerFunction<FunctionH3GetPentagonIndexes>();
}

}

#endif
80 changes: 80 additions & 0 deletions src/Functions/h3GetRes0Indexes.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#include "config_functions.h"

#if USE_H3

#include <Columns/ColumnArray.h>
#include <Columns/ColumnsNumber.h>
#include <DataTypes/DataTypeArray.h>
#include <DataTypes/DataTypesNumber.h>
#include <DataTypes/DataTypeTuple.h>
#include <Functions/FunctionFactory.h>
#include <Functions/IFunction.h>
#include <IO/WriteHelpers.h>
#include <Common/typeid_cast.h>
#include <base/range.h>

#include <h3api.h>


namespace DB
{
namespace
{

class FunctionH3GetRes0Indexes final : public IFunction
{
public:
static constexpr auto name = "h3GetRes0Indexes";

static FunctionPtr create(ContextPtr) { return std::make_shared<FunctionH3GetRes0Indexes>(); }

std::string getName() const override { return name; }

size_t getNumberOfArguments() const override { return 0; }
bool useDefaultImplementationForConstants() const override { return true; }
bool isSuitableForShortCircuitArgumentsExecution(const DataTypesWithConstInfo & /*arguments*/) const override { return false; }

DataTypePtr getReturnTypeImpl(const DataTypes & /*arguments*/) const override
{
return std::make_shared<DataTypeArray>(std::make_shared<DataTypeUInt64>());
}

ColumnPtr executeImpl(const ColumnsWithTypeAndName & /*arguments*/, const DataTypePtr &, size_t input_rows_count) const override
{
auto dst = ColumnArray::create(ColumnUInt64::create());
auto & dst_data = dst->getData();
auto & dst_offsets = dst->getOffsets();
dst_offsets.resize(input_rows_count);
auto current_offset = 0;

const auto vec_size = res0CellCount();
bharatnc marked this conversation as resolved.
Show resolved Hide resolved
std::vector<H3Index> hindex_vec;

for (size_t row = 0; row < input_rows_count; ++row)
{
hindex_vec.resize(vec_size);
getRes0Cells(hindex_vec.data());
dst_data.reserve(input_rows_count);

for (auto & hindex : hindex_vec)
{
++current_offset;
dst_data.insert(hindex);
}
hindex_vec.clear();
dst_offsets[row] = current_offset;
}
return dst;
}
};

}

void registerFunctionH3GetRes0Indexes(FunctionFactory & factory)
{
factory.registerFunction<FunctionH3GetRes0Indexes>();
}

}

#endif
Loading