Skip to content

Commit 4ab44bf

Browse files
authored
Merge pull request ClickHouse#78852 from pratimapatel2008/geotoh3_lat_lon_input_order
Change geoToH3 function input order to (lat,lon,res) from (lon,lat,res)
2 parents 979a47d + a87f03b commit 4ab44bf

File tree

9 files changed

+70
-30
lines changed

9 files changed

+70
-30
lines changed

docs/en/sql-reference/functions/geo/h3.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -191,31 +191,33 @@ Result:
191191

192192
## geoToH3 {#geotoh3}
193193

194-
Returns [H3](#h3-index) point index `(lon, lat)` with specified resolution.
194+
Returns [H3](#h3-index) point index `(lat, lon)` with specified resolution.
195195

196196
**Syntax**
197197

198198
```sql
199-
geoToH3(lon, lat, resolution)
199+
geoToH3(lat, lon, resolution)
200200
```
201201

202202
**Arguments**
203203

204-
- `lon` — Longitude. [Float64](../../data-types/float.md).
205204
- `lat` — Latitude. [Float64](../../data-types/float.md).
205+
- `lon` — Longitude. [Float64](../../data-types/float.md).
206206
- `resolution` — Index resolution. Range: `[0, 15]`. [UInt8](../../data-types/int-uint.md).
207207

208208
**Returned values**
209209

210210
- Hexagon index number. [UInt64](../../data-types/int-uint.md).
211211
- 0 in case of error. [UInt64](../../data-types/int-uint.md).
212212

213+
Note: In ClickHouse v25.4 or older, `geoToH3()` takes values in order `(lon, lat)`. As per ClickHouse v25.5, the input values are in order `(lat, lon)`. The previous behaviour can be restored using setting `geotoh3_lon_lat_input_order = true`.
214+
213215
**Example**
214216

215217
Query:
216218

217219
```sql
218-
SELECT geoToH3(37.79506683, 55.71290588, 15) AS h3Index;
220+
SELECT geoToH3(55.71290588, 37.79506683, 15) AS h3Index;
219221
```
220222

221223
Result:

src/Core/Settings.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3614,6 +3614,9 @@ If enabled, functions 'least' and 'greatest' return NULL if one of their argumen
36143614
)", 0) \
36153615
DECLARE(Bool, h3togeo_lon_lat_result_order, false, R"(
36163616
Function 'h3ToGeo' returns (lon, lat) if true, otherwise (lat, lon).
3617+
)", 0) \
3618+
DECLARE(Bool, geotoh3_lon_lat_input_order, false, R"(
3619+
Function 'geoToH3' accepts (lon, lat) if true, otherwise (lat, lon).
36173620
)", 0) \
36183621
DECLARE(UInt64, max_partitions_per_insert_block, 100, R"(
36193622
Limits the maximum number of partitions in a single inserted block

src/Core/SettingsChangesHistory.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ const VersionToSettingsChangesMap & getSettingsChangesHistory()
6868
/// Note: please check if the key already exists to prevent duplicate entries.
6969
addSettingsChanges(settings_changes_history, "25.5",
7070
{
71+
{"geotoh3_lon_lat_input_order", true, false, "A new setting for legacy behaviour to set lon and lat order"},
7172
{"secondary_indices_enable_bulk_filtering", false, true, "A new algorithm for filtering by data skipping indices"},
7273
{"implicit_table_at_top_level", "", "", "A new setting, used in clickhouse-local"},
7374
});

src/Functions/geoToH3.cpp

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
#include <DataTypes/DataTypesNumber.h>
99
#include <Functions/FunctionFactory.h>
1010
#include <Functions/IFunction.h>
11-
#include <Common/typeid_cast.h>
11+
#include <Interpreters/Context.h>
12+
#include <Core/Settings.h>
1213
#include <base/range.h>
1314

1415
#include <constants.h>
@@ -17,6 +18,10 @@
1718

1819
namespace DB
1920
{
21+
namespace Setting
22+
{
23+
extern const SettingsBool geotoh3_lon_lat_input_order;
24+
}
2025
namespace ErrorCodes
2126
{
2227
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
@@ -32,10 +37,16 @@ namespace
3237
/// and returns h3 index of this point
3338
class FunctionGeoToH3 : public IFunction
3439
{
40+
const bool geotoh3_lon_lat_input_order;
3541
public:
3642
static constexpr auto name = "geoToH3";
3743

38-
static FunctionPtr create(ContextPtr) { return std::make_shared<FunctionGeoToH3>(); }
44+
static FunctionPtr create(ContextPtr context) { return std::make_shared<FunctionGeoToH3>(context); }
45+
46+
explicit FunctionGeoToH3(ContextPtr context)
47+
: geotoh3_lon_lat_input_order(context->getSettingsRef()[Setting::geotoh3_lon_lat_input_order])
48+
{
49+
}
3950

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

@@ -80,26 +91,39 @@ class FunctionGeoToH3 : public IFunction
8091
for (auto & argument : non_const_arguments)
8192
argument.column = argument.column->convertToFullColumnIfConst();
8293

83-
const auto * col_lon = checkAndGetColumn<ColumnFloat64>(non_const_arguments[0].column.get());
84-
if (!col_lon)
85-
throw Exception(
86-
ErrorCodes::ILLEGAL_COLUMN,
87-
"Illegal type {} of argument {} of function {}. Must be Float64.",
88-
arguments[0].type->getName(),
89-
1,
90-
getName());
91-
const auto & data_lon = col_lon->getData();
94+
const ColumnFloat64 * col_lat = nullptr;
95+
const ColumnFloat64 * col_lon = nullptr;
96+
97+
if (geotoh3_lon_lat_input_order)
98+
{
99+
col_lon = checkAndGetColumn<ColumnFloat64>(non_const_arguments[0].column.get());
100+
col_lat = checkAndGetColumn<ColumnFloat64>(non_const_arguments[1].column.get());
101+
}
102+
else
103+
{
104+
col_lat = checkAndGetColumn<ColumnFloat64>(non_const_arguments[0].column.get());
105+
col_lon = checkAndGetColumn<ColumnFloat64>(non_const_arguments[1].column.get());
106+
}
92107

93-
const auto * col_lat = checkAndGetColumn<ColumnFloat64>(non_const_arguments[1].column.get());
94108
if (!col_lat)
95109
throw Exception(
96-
ErrorCodes::ILLEGAL_COLUMN,
97-
"Illegal type {} of argument {} of function {}. Must be Float64.",
98-
arguments[1].type->getName(),
99-
2,
100-
getName());
110+
ErrorCodes::ILLEGAL_COLUMN,
111+
"Illegal type {} of argument {} of function {}. Must be Float64.",
112+
arguments[1].type->getName(),
113+
2,
114+
getName());
115+
101116
const auto & data_lat = col_lat->getData();
102117

118+
if (!col_lon)
119+
throw Exception(
120+
ErrorCodes::ILLEGAL_COLUMN,
121+
"Illegal type {} of argument {} of function {}. Must be Float64.",
122+
arguments[0].type->getName(),
123+
1,
124+
getName());
125+
const auto & data_lon = col_lon->getData();
126+
103127
const auto * col_res = checkAndGetColumn<ColumnUInt8>(non_const_arguments[2].column.get());
104128
if (!col_res)
105129
throw Exception(
@@ -154,3 +178,4 @@ REGISTER_FUNCTION(GeoToH3)
154178
}
155179

156180
#endif
181+

tests/queries/0_stateless/00926_geo_to_h3.sql

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ INSERT INTO table1 VALUES(55.72076200, 37.59813500, 15);
1010
INSERT INTO table1 VALUES(55.72076201, 37.59813500, 15);
1111
INSERT INTO table1 VALUES(55.72076200, 37.59813500, 14);
1212

13-
select geoToH3(37.63098076, 55.77922738, 15);
14-
select geoToH3(37.63098076, 55.77922738, 24); -- { serverError ARGUMENT_OUT_OF_BOUND }
15-
select geoToH3(lon, lat, resolution) from table1 order by lat, lon, resolution;
16-
select geoToH3(lon, lat, resolution) AS k from table1 order by lat, lon, k;
17-
select lat, lon, geoToH3(lon, lat, resolution) AS k from table1 order by lat, lon, k;
18-
select geoToH3(lon, lat, resolution) AS k, count(*) from table1 group by k order by k;
13+
select geoToH3(55.77922738, 37.63098076, 15);
14+
select geoToH3(55.77922738, 37.63098076, 24); -- { serverError ARGUMENT_OUT_OF_BOUND }
15+
select geoToH3(lat, lon, resolution) from table1 order by lat, lon, resolution;
16+
select geoToH3(lat, lon, resolution) AS k from table1 order by lat, lon, k;
17+
select lat, lon, geoToH3(lat, lon, resolution) AS k from table1 order by lat, lon, k;
18+
select geoToH3(lat, lon, resolution) AS k, count(*) from table1 group by k order by k;
1919

2020
DROP TABLE table1

tests/queries/0_stateless/01906_h3_to_geo.sql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ DROP TABLE IF EXISTS h3_indexes;
55
CREATE TABLE h3_indexes (h3_index UInt64) ENGINE = Memory;
66

77
-- Random geo coordinates were generated using the H3 tool: https://github.com/ClickHouse-Extras/h3/blob/master/src/apps/testapps/mkRandGeo.c at various resolutions from 0 to 15.
8-
-- Corresponding H3 index values were in turn generated with those geo coordinates using `geoToH3(lon, lat, res)` ClickHouse function for the following test.
8+
-- Corresponding H3 index values were in turn generated with those geo coordinates using `geoToH3(lat, lon, res)` ClickHouse function for the following test.
99

1010
INSERT INTO h3_indexes VALUES (579205133326352383);
1111
INSERT INTO h3_indexes VALUES (581263419093549055);
@@ -55,7 +55,7 @@ INSERT INTO h3_geo VALUES (8.19906334981474, 67.69370966550179, 15);
5555
SELECT result FROM (
5656
SELECT
5757
(lon, lat) AS input_geo,
58-
h3ToGeo(geoToH3(lat, lon, res)) AS output_geo,
58+
h3ToGeo(geoToH3(lon, lat, res)) AS output_geo,
5959
if(abs(input_geo.1 - output_geo.1) < 0.001 AND abs(input_geo.2 - output_geo.2) < 0.001, 'ok', 'fail') AS result
6060
FROM h3_geo
6161
);

tests/queries/0_stateless/02223_h3_test_const_columns.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
-- Tags: no-fasttest
22

3-
select round(geoToH3(toFloat64(0),toFloat64(1),arrayJoin([1,2])), 2);
3+
select round(geoToH3(toFloat64(1),toFloat64(0),arrayJoin([1,2])), 2);
44
select h3ToParent(641573946153969375, arrayJoin([1,2]));
55
SELECT round(h3HexAreaM2(arrayJoin([1,2])), 2);
66
SELECT round(h3HexAreaKm2(arrayJoin([1,2])), 2);
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
644325524701193974
2+
644325524701193974
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
-- Tags: no-fasttest
2+
-- no-fasttest: h3ToGeo needs binary with Uber H3 libary
3+
4+
-- Test for setting 'geotoh3_lon_lat_input_order'
5+
6+
SELECT geoToH3(37.79506683, 55.71290588, 15) AS h3Index SETTINGS geotoh3_lon_lat_input_order = true;
7+
SELECT geoToH3(55.71290588, 37.79506683, 15) AS h3Index SETTINGS geotoh3_lon_lat_input_order = false;

0 commit comments

Comments
 (0)