Skip to content

Commit 8cb2f1f

Browse files
committed
feat(query): Support Geometry and Geography aggregate functions
1 parent 0e7c856 commit 8cb2f1f

34 files changed

Lines changed: 7519 additions & 3010 deletions

File tree

Cargo.lock

Lines changed: 9 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ futures = "0.3.24"
267267
futures-async-stream = { version = "0.2.7" }
268268
futures-util = "0.3.24"
269269
geo = { version = "0.32.0", features = ["use-serde"] }
270-
geo-index = "0.3.2"
270+
geo-index = "0.3.4"
271271
geohash = "0.13.1"
272272
geozero = { version = "0.15.1", features = ["with-geo", "with-geojson", "with-wkb", "with-wkt"] }
273273
gimli = "0.31.0"
@@ -397,7 +397,7 @@ pprof = { git = "https://github.com/datafuse-extras/pprof-rs", rev = "edecd74",
397397
] }
398398
pretty_assertions = "1.3.0"
399399
procfs = { version = "0.17.0" }
400-
proj4rs = { version = "0.1.9", features = ["geo-types", "crs-definitions"] }
400+
proj4rs = { version = "0.1.10", features = ["geo-types", "crs-definitions"] }
401401
proptest = { version = "1", default-features = false, features = ["std"] }
402402
prost = { version = "0.13" }
403403
prost-build = { version = "0.13" }

THIRD-PARTY-NOTICES.txt

Lines changed: 860 additions & 0 deletions
Large diffs are not rendered by default.

src/common/io/src/geography.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,13 @@ use geozero::geojson::GeoJson;
2727
use geozero::wkb::Ewkb;
2828

2929
use crate::ewkb_to_geo;
30+
use crate::geometry::GeometryDataType;
3031
use crate::geometry::ewkt_str_to_geo;
32+
use crate::geometry::geo_to_ewkb;
33+
use crate::geometry::geo_to_ewkt;
34+
use crate::geometry::geo_to_json;
35+
use crate::geometry::geo_to_wkb;
36+
use crate::geometry::geo_to_wkt;
3137

3238
pub const LONGITUDE_MIN: f64 = -180.0;
3339
pub const LONGITUDE_MAX: f64 = 180.0;
@@ -69,6 +75,34 @@ pub fn geography_from_geojson(json_str: &str) -> Result<Vec<u8>> {
6975
.map_err(|e| ErrorCode::GeometryError(e.to_string()))
7076
}
7177

78+
pub fn geography_format(ewkb: &[u8], format_type: GeometryDataType) -> Result<String> {
79+
let geo = Ewkb(ewkb)
80+
.to_geo()
81+
.map_err(|e| ErrorCode::GeometryError(e.to_string()))?;
82+
83+
match format_type {
84+
GeometryDataType::WKB => {
85+
let bytes = geo_to_wkb(geo)?;
86+
Ok(bytes
87+
.iter()
88+
.map(|b| format!("{:02X}", b))
89+
.collect::<Vec<_>>()
90+
.join(""))
91+
}
92+
GeometryDataType::EWKB => {
93+
let bytes = geo_to_ewkb(geo, Some(GEOGRAPHY_SRID))?;
94+
Ok(bytes
95+
.iter()
96+
.map(|b| format!("{:02X}", b))
97+
.collect::<Vec<_>>()
98+
.join(""))
99+
}
100+
GeometryDataType::WKT => geo_to_wkt(geo),
101+
GeometryDataType::EWKT => geo_to_ewkt(geo, Some(GEOGRAPHY_SRID)),
102+
GeometryDataType::GEOJSON => geo_to_json(geo),
103+
}
104+
}
105+
72106
pub fn check_srid(srid: Option<i32>) -> Result<()> {
73107
if let Some(srid) = srid
74108
&& srid != GEOGRAPHY_SRID

src/common/io/src/geometry.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ use databend_common_exception::ErrorCode;
1919
use databend_common_exception::Result;
2020
use geo::BoundingRect;
2121
use geo::Geometry;
22+
use geo::LineString;
2223
use geo::Point;
24+
use geo::Polygon;
25+
use geo::Rect;
2326
use geohash::encode;
2427
use geozero::CoordDimensions;
2528
use geozero::GeomProcessor;
@@ -258,6 +261,19 @@ pub fn geo_to_ewkt(geo: Geometry, srid: Option<i32>) -> Result<String> {
258261
.map_err(|e| ErrorCode::GeometryError(e.to_string()))
259262
}
260263

264+
pub fn rect_to_polygon(rect: Rect<f64>) -> Polygon<f64> {
265+
let min = rect.min();
266+
let max = rect.max();
267+
let exterior = LineString::from(vec![
268+
(min.x, min.y),
269+
(max.x, min.y),
270+
(max.x, max.y),
271+
(min.x, max.y),
272+
(min.x, min.y),
273+
]);
274+
Polygon::new(exterior, vec![])
275+
}
276+
261277
/// Process EWKB input and return SRID.
262278
pub fn read_srid<B: AsRef<[u8]>>(ewkb: &mut Ewkb<B>) -> Option<i32> {
263279
let mut srid_processor = SridProcessor::new();

src/common/io/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ pub use decimal::display_decimal_256_trimmed;
6262
pub use escape::escape_string;
6363
pub use escape::escape_string_with_quote;
6464
pub use geography::GEOGRAPHY_SRID;
65+
pub use geography::geography_format;
6566
pub use geometry::Axis;
6667
pub use geometry::Extremum;
6768
pub use geometry::GeometryDataType;

src/query/expression/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ ethnum = { workspace = true }
3939
futures = { workspace = true }
4040
geo = { workspace = true }
4141
geozero = { workspace = true }
42+
proj4rs = { workspace = true }
4243
hex = { workspace = true }
4344
hyper-util = { workspace = true }
4445
itertools = { workspace = true }

0 commit comments

Comments
 (0)